TowardsDataScience-博客中文翻译-2019-三十-

TowardsDataScience 博客中文翻译 2019(三十)

原文:TowardsDataScience Blog

协议:CC BY-NC-SA 4.0

数据科学项目包管理工具选择指南

原文:https://towardsdatascience.com/guide-of-choosing-package-management-tool-for-data-science-project-809a093efd46?source=collection_archive---------11-----------------------

从 pipenv,conda,anaconda project,docker 等选择合适的工具。

Photo by Clem Onojeghuo on Unsplash

如果您曾经从事过数据科学项目,您一定问过这个问题。

如何管理包、依赖、环境?

谷歌了一段时间,应该会看到一些关键词,康达,巨蟒,迷你康达,巨蟒-项目,Pipenv,木星,木星实验室,Docker …

这个列表可以更长。这样的调查很无聊,可能会占用你一整天的时间。为了节省您的时间,我写这篇文章作为一个总结,帮助您为您的项目选择最好的工具。

工具的快速总结

Python 世界中有许多工具可以进行不同种类的包管理,但是没有一种工具是万能的。我们应该根据自己的需要选择合适的。

  • pip 可以管理 Python 包。pip 包是一个源包。安装后还得编译,经常因为系统 OS 原因编译失败。此外,pip 不会检查与已安装软件包的冲突。
  • pyenv 可以管理 Python 版本
  • Virtualenvvenv 可以创建不同的虚拟 Python 环境。您可以为特定项目选择不同的环境。
  • pipenv 将 pip、pyenv 和 virtualenv 组合在一起。但是仍然不能解决 pip 的编译问题。
  • 康达是一个环境管理体系。它支持二进制包,这意味着我们不需要在安装后编译源代码。
  • Anaconda 是由 conda 管理的 Python 科学计算发行版,包含 Conda、numpy、scipy、ipython notebook 等百个包,
  • Conda Forge 是另一个比 Anaconda 更通用的 Python 发行版。但是这里有个坑。康达锻炉和蟒蛇并不完全兼容。如果您有一个同时使用 Anaconda 和 Conda Forge 包的项目,这可能会导致冲突。
  • Anaconda 项目可以在一个项目中创建多个虚拟环境,同时管理 conda 依赖和 pip 依赖,但是缺少 CUDA 等系统包和一些命令行工具。
  • Apt 这样的系统包管理工具可以安装系统包,但是受到操作系统发行版的限制。比如 Ubuntu 14.04 不能安装 CUDA 9。
  • Docker 可以在容器中安装一个操作系统发行版,方便切换操作系统版本。但是容器和主机必须共享相同的操作系统内核,所以没有办法直接在 macOS 上运行 Linux 发行版的 docker 容器。
  • nvidia-docker 可以将 GPU 设备文件和驱动挂载到 docker 容器,但只支持 Linux。

一些建议

  1. 如果您临时编写了几行项目中没有的代码,请使用 Anaconda 环境。
  2. 如果您需要创建多个数据挖掘或科学计算项目,那么使用 Anaconda 项目来隔离这些项目,而不是使用 pipenv。
  3. 如果你需要使用 Python 为网站创建多个项目,那么用 pipenv 而不是 conda 来隔离这些项目。
  4. 对于 Anaconda 项目管理的那些项目,如果需要安装纯 Python 库,先用 pip 包。如果是需要额外编译的库,先用 conda 包。
  5. 如果需要隔离系统环境,使用 Docker 的 Linux 版本在容器中安装系统依赖项。
  6. conda 和 Linux 发行版都有二进制包,我们更喜欢使用 conda。因为 Linux 发行版的发布周期很慢,而且版本很旧。

查看我的其他帖子 一个分类查看
GitHub:
bramble Xu LinkedIn:徐亮 博客:bramble Xu

参考

AWS Textract 设置指南

原文:https://towardsdatascience.com/guide-on-aws-textract-set-up-8cddb8a3b3a3?source=collection_archive---------9-----------------------

如何使用 AWS 的 OCR 即服务准确处理 PDF 文件

Photo by Raphael Schaller on Unsplash

异步 API 响应

最近,异步 API 响应的新范例变得非常突出。它通过返回 Job-ID 而不是 API 响应来工作。然后,为了检查状态,用户需要使用作业 ID 向 API 提交第二次调用。这里有一个很好的指南。

Sync vs. Async API responses in Flask

异步 API 响应通常用于重量级机器学习应用程序或移动大量数据的应用程序,即任何需要花费很长时间才能将结果同步返回给用户的应用程序。

AWS Textract 可以检测和分析 PDF 格式的多页文档中的文本。Textract 对其 API 使用异步响应。在后台,每个 PDF 被分成单页格式并发送到处理引擎,以便每个页面可以独立于 PDF 文档进行处理,并且系统可以水平扩展。此外,异步操作允许用户提交超过 1,000 页的 PDF 文件进行处理,并在稍后返回以检查结果,而不是等待请求。

在 EC2 上使用 Python 设置 Textract 的分步说明

让我们来看一下设置 EC2 机器来用 Python 调用 Textract 所需的步骤:

1 — 设置一个 AWS 角色从 EC2 实例访问 Amazon Textract。

Create a role for an EC2 in IAM

a)创建角色页面上,将使用该角色的服务—选择 EC2 并转到下一步:权限

b) 我们将需要授予以下 4 个权限来设置 text ract—AmazonTextractFullAccess
amazonsreadonlyaccess
amazonsfnfullaccess
AmazonSQSFullAccess

(一旦设置了 SNS、SQS 和 Textract 配置,您可能需要降低访问权限)

c) 跳过标签,进入审核。称之为爽快的东西。

d) 转到 EC2 页面,在实例下选择将调用 Textract 的机器,并附加您从 a) 创建的角色,如下图所示

Associate newly created role with an EC2 Instance

2 — 登录到您添加了角色的 EC2 机器,安装 Python-boto 3 所需的 AWS SDK

> pip install boto3

3 — 创建一个 IAM 服务角色,授予 Amazon Textract 访问您的 Amazon SNS 主题的权限。这将允许 Textract 在文件分析完成时通知您。
参见 授予亚马逊 Textract 访问您的亚马逊社交网络主题 的详细访问权限。保存服务角色的亚马逊资源名称(ARN) ,因为您需要将它提供给 Textract。

根据上述参考,您创建的角色将在策略声明中指出以下内容—

{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Effect": "Allow",
      "Principal": {
        "Service": "ec2.amazonaws.com"
      },
      "Action": "sts:AssumeRole"
    }
  ]
}

你需要把它替换成—

{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Effect": "Allow",
      "Principal": {
        "Service": "textract.amazonaws.com"
      },
      "Action": "sts:AssumeRole"
    }
  ]
}

4 — 在 EC2 实例中运行以下代码,使用 Textract 分析 pdf。pdf 必须位于您的 S3 存储桶中。

结论

我们已经通过上面提供的代码介绍了如何在您的 S3 中的图像和 pdf 上使用 AWS Textract。

设置 Textract 有点复杂,但是如果您查看一下代码,就会明白为什么会这样。该代码创建了一个新的 SQS 队列和一个新的 SNS 主题,并为该队列订阅了我们创建的主题。

接下来,在代码中,我们指示要处理的所需 PDF 的 Textract 位置,以及进行通信的 SNS 通道。

用 Python 构建大学篮球机器学习模型指南

原文:https://towardsdatascience.com/guide-to-building-a-college-basketball-machine-learning-model-in-python-1c70b83acb51?source=collection_archive---------2-----------------------

Photo by Martin Sanchez on Unsplash

让我们比较神经网络性能和 Vegas 线精度。

介绍

感恩节假期,我有一些空闲时间,偶然发现了由罗伯特·克拉克创建的伟大的 Python 公共 API 。这个 API 允许用户从 sports-reference.com 的非常容易地获得美国主要体育项目的任何统计数据。通常,任何数据科学工作中最困难的部分是收集和清理数据。虽然仍有一些工作要做,但我自然会被那些最难的部分变得简单的项目所吸引。我的目标是快速创建一个接近众所周知的公开可用系统质量的模型。赌博市场真的很难击败,他们将提供一个很好的准确性的衡量标准。尽管赛季初的大学篮球经常被认为是一个疲软的市场,但这种模式在拉斯维加斯不太可能盈利——有几个关键因素超出了它的范围。我这个项目的代码可以在 Github 上找到

概述

我的计划是找到与预测大学篮球比赛结果相关的最重要的统计数据。然后我可以利用两个强大的模型,一个光梯度推进机(LGBM),一个神经网络来预测大学篮球传播。神经网络和 LGBM 模型都有不同的优点和缺点,通常两者的组合优于各自。他们都在 Kaggle 上的机器学习比赛中人气极高。如果我即将失去你,这里的是一个关于神经网络的很好的讲解视频。另一方面,LGBM 模型具有线性回归的优势,但也可以很好地处理非线性数据和空值。下面深入解释一下它为什么会在 Kaggle 上流行。这些模型虽然比简单的线性回归器复杂得多,但可能不会明显优于线性回归器(我们将测试它!).

收集数据

我们需要在大学篮球比赛开始前找到最有预见性的特征。这可能会很棘手,因为样本量会随着季节的变化而变化。进入赛季,我们只能使用季前赛的功能。在赛季后期,季前赛的特点不太可能是重要的,我们可以依靠 20+场比赛的样本量。

为了组装这些功能,我们需要每个游戏的游戏日志。这样,我们就可以汇总游戏开始时的赛季统计数据。我用以下代码编译了一个 box score URLs 列表:

import numpy as np
import pandas as pdfrom sportsreference.ncaab.teams import Teams
from tqdm import tqdmseasons = range(2011, 2020) # python is odd, this is 2011 - 2019master_array = []for season in tqdm(seasons): #tqdm shows progress bar
    # a couple of teams don't have links for every season, thus    #"try/except"
    try:
        season_team_list = Teams(str(season))
        for team in season_team_list: 
            team_schedule = team.schedule
            for game in team_schedule:
               boxscore = game.boxscore_index
               master_array.append([str(season),team.name,boxscore])
    except:
        continue

schedule_df = pd.DataFrame(master_array, columns=['Season','TeamName','BoxscoreIndex'])schedule_df.to_csv('./output/schedule.csv',index=None)

所有这些 API 调用总共需要大约 30 分钟。出于这个原因,我把数据集发布在 Kaggle 上,这样你就可以下载了。

现在我们有了 boxscore 链接,我们可以遍历 box score 并捕获几乎所有内容。因为我还不知道什么是有用的,所以我会全部下载下来。幸运的是,令人惊讶的运动参考 API 有一个简单的命令来做到这一点。我一次跑了大约 4 季,仍然花了几个小时。所以,再一次,你可能只想从 Kaggle 下载它。花名册数据可以单独收集(这样做的说明可以在 API 文档中找到)。

from sportsreference.ncaab.boxscore import Boxscoreseason = 2011 # will run once for each season
box_df = Noneschedule_df = pd.read_csv('./output/schedule.csv')season_df = schedule_df.loc[schedule_df.Season==season]
for index, row in tqdm(season_df.iterrows()):
    box_link = row['BoxscoreIndex']
    _df = Boxscore(box_link).dataframe

    if box_df is not None:
        box_df = pd.concat([box_df,_df],axis=0)
    else:
        box_df = _dfbox_df.to_csv('./output/{}_boxscores.csv'.format(season),index=None)

数据清理

从 2011 年到 2019 年,我们总共有大约 50,000 场比赛和票房成绩。数据清理可能非常混乱,但也非常重要。让我们向数据科学之神祈祷好运,然后首先检查空值:

print(df.isnull().sum(axis=0).sort_values(ascending=False))away_ranking                              95468
home_ranking                              92529
location                                  14172
away_offensive_rebound_percentage          2329
home_minutes_played                        2329
away_turnover_percentage                   2329
away_true_shooting_percentage              2329
away_total_rebound_percentage              2329
away_steal_percentage                      2329
away_assist_percentage                     2329
away_offensive_rating                      2329
away_free_throw_attempt_rate               2329
away_effective_field_goal_percentage       2329
away_defensive_rebound_percentage          2329
away_defensive_rating                      2329
away_block_percentage                      2329
away_three_point_attempt_rate              2329
home_offensive_rebound_percentage            81
home_assist_percentage                       81
home_defensive_rating                        81
...
date                                          0
away_wins                                     0
away_win_percentage                           0
away_two_point_field_goals                    0
away_two_point_field_goal_percentage          0
away_two_point_field_goal_attempts            0
away_turnovers                                0
home_total_rebounds                           0
home_offensive_rebounds                       0
away_three_point_field_goals                  0
winning_name                                  0

首先,很多重要的列没有空值!考虑到我们依靠公共 API 和网站来收集 100,000 个 boxscore,这是令人兴奋的(上面的代码收集每个 box score 两次,每个团队一次)。

让我们继续前进。因为一次只有 25 个团队被排名,所以许多团队的排名列为空是有道理的。如果我们没有太多的数据,我会依赖排名列作为输入。但是,我认为我们可以安全地删除这些列。在某些情况下,地点也很难确定。我不打算将旅行合并到这个模型中,因此我将忽略该列。旅行,或在一段时间内的累积旅行,将是一个有趣的补充!

在进一步的检查中,很明显高级统计数据只在 I 级团队中被追踪。这就是为什么客场高级统计比主场高级统计有更多的空值——二级球队通常必须在一级竞技场比赛。我们其实并不关心二级的高级属性,所以这不是问题。这次数据清理比我预期的要顺利得多。

除了检查空值之外,数据清理还有其他步骤。我浏览了一些关键栏目(得分、助攻、胜场等)。)并检查它们的最小值和最大值,同时使用 seaborn 的 distplot 来检查它们是否有意义。目前一切似乎都很好!

特征创建

简单的得分统计将帮助我们预测 NCAA 篮球队未来的成功。有不同的方法将团队质量输入到我们的模型中。我们可以使用过去 10 场比赛的平均得分。我们可以使用过去 5 个赛季的平均得分。我们只需输入前 25 名的排名,模型就会知道排名 1-5 的团队是真正的好团队。我试图合理地限制这个项目的范围,但有近乎无限的组合可以尝试。

作为题外话,我想谈谈指数加权平均(EWA)。不要对过去的 X 个游戏进行平均统计,有时更好的方法是对最近的游戏进行加权(甚至稍微)使其比旧游戏更重。我将使用 EWA 和赛季平均版本的盒子得分统计数据。具有高游戏间差异的统计数据(3 分命中率,失误)将从长期样本中受益。

另外,我必须坦白。我已经做了大量的特征选择工作。如果下面的统计数据看起来特别具体,那是因为我已经排除了相似但不太有用的特性。有这么多的组合可以尝试,我不想浪费读者宝贵的时间去经历整个过程。我将添加一些未经测试的、可能无用的特性来展示我如何测试重要性。

我将从长期特征开始。我们谈的是非常长远的计划。对于以下特性,我采用了过去 5 季的指数加权平均值:

  1. 获胜%
  2. 进攻等级(每 100 次进攻得分)
  3. 进攻篮板百分比(导致进攻篮板的可用进攻篮板百分比)
  4. 允许对手 FG%
  5. 节奏
  6. 罚球得分的百分比
  7. 投篮命中率
  8. 三分球得分的百分比
  9. 三分球命中率
  10. 失误百分比(导致失误的进攻型进攻的百分比)
  11. 抢断百分比(导致抢断的防守控球百分比)

我们已经有 11 个功能了。然而,我们也需要同样的 11 个特征给对手。所以我们有 22 个功能。太多了!你可以看到这很容易失控。

好的,所以我们还需要比过去五年更多的样本。下面的统计数据我将使用一个季度的样本。

  1. 防御等级
  2. 获胜%
  3. Opp 3PT 拍摄%
  4. 犯规了
  5. 三分球得分的百分比
  6. 节奏
  7. 罚球命中率%

最后但同样重要的是,我们需要统计过去几场比赛的数据:

  1. 攻击性评级
  2. 偷窃百分比
  3. 辅助百分比
  4. 块百分比
  5. 两分投篮命中率
  6. 允许的助攻百分比

所以每支球队有 24 个特色,或者每场比赛有 48 个特色。告诉我们的模型赛季进行到什么程度以及主队是谁也是非常重要的。

上下文特征:

  1. 季节的某一天
  2. 主场/客场

现在我们有一个很好的,甚至 50 个功能。你能找到可以添加到模型中的特性吗?绝对的!这个模型是你玩的。出于演示的目的,我将添加几个可能没有用的。我其实还没测试过,所以不能排除!

  1. 本赛季平均个人犯规数
  2. 赛季罚球百分比
  3. 季节更替百分比

功能重要性和选择

我喜欢用三种主要方法来测试特性的重要性。按照从最懒到最不懒的顺序:

  1. LGBM 增益——我们的 LGBM 模型可以指出它认为最重要的特征。虽然这给出了一个粗略的重要性的概念,但是只使用增益也有缺点。我将在整篇文章中谈到所有这些方法的缺点。
  2. LOFO 重要性—“去掉一个特征”,这种方法通过每次运行去掉一个特征来测试模型。明显的缺点是要花很多时间。这个缺点被它非常广泛地适用于不同的模型和输入数据的事实所抵消。我最近才知道这种方法,我想感谢艾哈迈德·艾尔丹姆开源了这种方法并使其易于使用。
  3. 皮尔逊、斯皮尔曼和赫夫丁的 D 相关性——假设,在现实世界中,有时你不得不捍卫你的工作。在这种情况下,说“我把它扔进了一个黑盒机器学习模型,这就是我得到的结果”是不够的。谢天谢地,统计学家为我们做了繁重的工作。皮尔逊相关性衡量线性关系,斯皮尔曼相关性衡量单调关系,赫夫丁衡量非线性关系。我们可以针对模型中的每个特征和目标运行这些相关性,并计算出相对有用性。这些在寻找某些参数时也非常有用。例如,如果我想知道我的助攻百分比指数加权平均值衰减多少,我可以优化 Spearman 相关来找到最佳衰减值。

Pearson’s would estimate the first well, Spearman’s the first and second, and Hoeffding’s D the third. You can read more about these correlations here or here. If I had to guess, Spearman’s would work on almost all of these college basketball features.

基线结果

我们如何给我们的模型评分?这个模型试图预测维加斯的扩散。所以如果一个好的队和一个差的队比赛,这个模型会给出一个预期的胜率。假设模型预测好的队伍赢 10 分,但他们实际上赢了 8 分。那么我们的平均绝对误差是 2。同样,如果好队赢了 12 分,而我们的模型再次预测 10 分,我们的平均绝对误差也是 2。

这是我的模型代码。你会注意到我正在使用五重交叉验证来帮助给出一个可靠的模型误差估计,并且我还记录了特征的重要性。

平均绝对误差,使用上述 56 个特征:

Sklearn's Linear Regressor: 9.17 LightGBM model: 9.09

这意味着平均而言,我们的预测大约有 9 个百分点的误差。这样好吗?谁知道呢!让我们把它和维加斯的利差比较一下。前几天发现历史线和结果。很抱歉链接我自己的 twitter 帖子,但我谈论的是赛季与赛季之间的错误和赛季过程中的错误:

TL;DR:维加斯的开盘价误差约为 8.48,收盘价格误差约为 8.41。一方面,我们离得很远。那是可以预料的。如果线性模型能打败拉斯维加斯,我就不会写中等水平的文章了。我可能会离开意大利海岸。另一方面,我确实认为这显示了简单线性回归的力量,平均误差已经在维加斯 0.75 分之内。这也展示了 LightGBM 的威力。它以与线性回归相似的速度消除了十分之一的误差。

特征选择

让我们用我上面提到的最懒惰的方法,更仔细地看看我们的特性有什么贡献:

LGBM Feature Importance, using the ‘gain’ setting

我很抱歉,上面的 y 轴有点难以阅读,因为有超过 50 个功能。LGBM 模型喜欢的两组特征是加权赛季进攻等级和五年加权胜率。它也真的很喜欢整个赛季的防守评分。这对那些熟悉篮球的人来说是有意义的。

需要注意的一点是,每个特性都有一点贡献。情况并非总是如此。有时,该图中有一些明显的特征,但没有任何贡献。如果我制造一列随机噪声,它将显示为无用的(否则我们就有问题了)。我还不小心给了 LGBM 两份同一专栏的副本——在这种情况下,其中一份将显示为没有贡献任何内容。这些特性是可以安全丢弃的。

之前我提到了只使用 LGBM 增益的缺点。开始放弃增益图底部显示的特性不一定安全。“在家”是最清晰、最有用的特征之一。然而,它位于增益图的中间。有时特征可能是共线的,这可能会混淆甚至阻碍模型。“赛季罚球百分比”与“赛季罚球得分百分比”非常相似——即,在一个方面做得好的球队可能在另一个方面也做得好。该模型可能很难区分使用哪一个。让我们看看 LOFO 方法是否能帮助我们。下面是使用 LOFO 方法的重要性图表:

LOFO highlights “At home” — because it’s telling us something no other feature is!

好多红色啊!回购协议的作者表示,删除任何红色特征都是安全的。然而,在这种情况下,误差线延伸到绿色区域。可能只有两个确定的下降——季节英尺%和季节到%。这两个特性都是我为了演示我的特性选择过程而添加的。你会注意到一些红色的特征与我们添加的相似。例如,五年英尺百分比和五年到百分比。这些可能是红色的,因为我添加了共线要素。最后,赛季平均个人犯规只有一点红色,但绝对没有帮助。我不一定会在这一批中放弃这个功能,但它也是 LGBM 增益图上的最后一个。因此,我认为这也是安全的下降。让我们再试一次,这次只有 50 个原始功能:

好多了!全绿!

但是,我们牺牲了性能吗?不,两种型号实际上得分完全相同,但少了 6 个特征:

Sklearn's Linear Regressor: 9.17LightGBM model: 9.09

使用的数据更少,性能差异很小。我每次都会做这个交易。使用太多的特征会导致过度拟合,这意味着你的模型不能推广到未来的篮球比赛。事实上,我可能会添加大约 20 个类似于现有的 50 个功能,也许会提高 CV 分数。02。问题是这是否值得。对我来说,不是这样的。

也就是说,有一些特性可以显著提高性能。稍后会详细介绍。

神经网络

既然我们已经剔除了可能导致过度拟合的特征,是时候给神经网络(NN)一个机会了。实际上我对这里的期望很低。我们没有处理大量的非线性特征,我们也无法受益于像卷积这样的神经网络特定层。因此,轻型 GBM 是绰绰有余的。我们还优化了我们的功能选择,以提高 LGBM 的性能。从神经网络中分别增加和减少一些特征是值得的。

除了典型的密集神经网络层,我将利用辍学。脱落层随机“脱落”一定比例的神经元。这防止了对单个神经元的过度依赖,从而防止了过度拟合和局部极小值。由于我们几乎所有的功能都是有用的,而且我们有一个基本的神经网络,我们不需要大量的辍学。然而,如果你创建了自己的网络,我建议你使用 dropout 值(尤其是在添加了一些功能之后)。这是我使用的普通前馈网络:

使用五折交叉验证重复五次,这花了 15 分钟训练!增加的复杂性和性能不是免费的。最终结果:

Neural Network: 9.22Sklearn's Linear Regressor: 9.17LightGBM model: 9.09Vegas Open: 8.4833Vegas Close: 8.4110

等等,一个 NN 花了 15 分钟训练还打不过一个线性回归器?没错。这部分是由于优化了线性模型的特征。这部分也是由于我们的特征的线性性质。最后,我们的神经网络可以更深,这将提高性能。因为我爱我的读者,我尝试了这个模式:

def get_model():
    x = keras.layers.Input(shape=[X.shape[1]])
    fc1 = keras.layers.Dense(units=450, input_shape=[X.shape[1]])(x)
    act1 = keras.layers.PReLU()(fc1)
    bn1 = keras.layers.BatchNormalization()(act1)
    dp1 = keras.layers.Dropout(0.45)(bn1)
    gn1 = keras.layers.GaussianNoise(0.15)(dp1)
    concat1 = keras.layers.Concatenate()([x, gn1])
    fc2 = keras.layers.Dense(units=600)(concat1)
    act2 = keras.layers.PReLU()(fc2)
    bn2 = keras.layers.BatchNormalization()(act2)
    dp2 = keras.layers.Dropout(0.45)(bn2)
    gn2 = keras.layers.GaussianNoise(0.15)(dp2)
    concat2 = keras.layers.Concatenate()([concat1, gn2])
    fc3 = keras.layers.Dense(units=400)(concat2)
    act3 = keras.layers.PReLU()(fc3)
    bn3 = keras.layers.BatchNormalization()(act3)
    dp3 = keras.layers.Dropout(0.45)(bn3)
    gn3 = keras.layers.GaussianNoise(0.15)(dp3)
    concat3 = keras.layers.Concatenate([concat2, gn3])
    output = keras.layers.Dense(units=1)(concat2)
    model = keras.models.Model(inputs=[x], outputs=[output])
    return model

这是由布鲁诺·梅洛在 Kaggle 上发现的竞争性神经网络的修改。我还在模型中添加了一些我之前已经删除的特性。用了 4 个多小时(!)来训练,并且得了 9.05 分。

未来方向

敏锐的读者,或者至少是那些有广泛篮球知识的读者,会指出我遗漏了一些非常重要的特征。时间表的力量是最明显和最有用的。事实上,有一个很棒的讲解者讲述了如何将阿洛克·帕蒂和艾丽莎·勒纳的时间表的力量结合起来。伤病、招募排名和教练变动也会有所帮助。最后,基本的球员名单特征,比如身高,或者休赛期特征,比如“上个赛季的篮板数占总篮板数的百分比”也可以提高球员的表现。

我非常乐观地认为,使用这些基础知识和上述一些特性的组合,您可以朝着令人垂涎的 Vegas 误差值前进。我会更新这篇文章,增加一些功能吗?如果我开始接近维加斯错误,我会分享我的代码吗?没有人知道,尤其是我。

TensorFlow Core 中自定义卷积神经网络编码指南

原文:https://towardsdatascience.com/guide-to-coding-a-custom-convolutional-neural-network-in-tensorflow-bec694e36ad3?source=collection_archive---------4-----------------------

低级 API 开发教程

下面演示了如何使用低级 TensorFlow 内核创建卷积神经网络(ConvNet)模型,而无需 Keras 等高级 API。本教程的目标是更好地理解深度神经网络中的后台进程,并演示如何使用 TensorFlow 创建自定义代码的概念。

本教程将展示如何将 MNIST 手写数字数据集加载到数据迭代器中,使用图形和会话,创建一个新颖的 ConvNet 架构,用不同的选项训练模型,进行预测,并保存训练好的模型。然后,将提供完整的代码以及 Keras 中的等效模型,以允许直接比较,从而为使用 Keras 的人提供进一步的见解,并显示高级 API 对于创建神经网络是多么强大。

MNIST 数据集

MNIST 是一组手写数字的 28x28 灰度图像,训练集中有 60,000 幅图像,测试集中有 10,000 幅图像。首先,我将加载并处理 MNIST 图像。

模型将期望输入形状是[batch_size, height, width, channels]。由于图像是灰度的(单通道),它们有形状[60000,28,28],所以它们需要增加一个通道尺寸来获得形状[60000,28,28,1]。它们还具有 uint8 类型(像素值范围为 0–255),因此需要通过除以 255 将其缩放至 0–1 之间的范围。然后显示第一幅图像作为示例。

标签是整数值(例如,0,1,2),但是标签是分类值,因此它们需要被一热编码(例如,[1,0,0],[0,1,0],[0,0,1])用于训练。Keras 有一个编码器to _ categorial,我将使用它来转换标签(Scikit-learn 也有 OneHotEncoder 作为另一个选项)。

正如下面将要看到的,我们不需要将测试标签转换为一键编码。

图表和会话

使用 TensorFlow 制作模型有两个部分:创建一个,并在一个会话中运行该图。

该图概述了计算数据流。它组织何时以及如何对张量(多维数据数组)执行操作。该图形可以在会话内部或外部创建,但只能在会话内部使用。在会话中,张量被初始化,操作被执行,模型被训练。

数据迭代器

为了演示数据流图和会话,我将创建一个数据集迭代器。由于 MNIST 图像和地面实况标签是 NumPy 数组的切片,因此可以通过将数组传递给方法TF . data . dataset . from _ tensor _ slices来创建数据集。然后我们可以为数据集创建一个迭代器。我们希望它在每次运行时返回batch_size数量的图像和标签,并在不确定的时期内重复

我们现在已经定义了一个数据流图,为了获得一批新的图像和标签,我们可以在一个会话中运行data_batch

但是,还没有。数据流图已经完成,但是图像还没有真正传入。为此,迭代器需要在会话中初始化。

现在一个会话正在运行,只需运行data_batch就可以检索到第一批图像。图像将具有形状[batch_size, height, width, channels],标签具有形状[batch_size, classes]。我们可以通过以下方式检查这一点:

Images shape: (128, 28, 28, 1)
Labels shape: (128, 10)

我们可以通过运行两次data_batch来显示前两批中的第一幅图像。

在第一批中,第一张图片是 5。在第二批中,第一张图片是 1。

然后,会话可以在sess.close()前关闭。但是,请记住,当会话关闭时,信息将会丢失。例如,如果我们如下所示关闭并重新启动会话,数据迭代器将从头开始重新启动。(注意迭代器需要在每个会话中初始化。)

因为会话被关闭并且创建了一个新的会话,所以数据迭代器从头重新启动并再次显示相同的图像。

同“同”

会话也可以通过“with”语句启动和自动关闭。在“with”块的末尾,会话被关闭,如下所示。

ConvNet 模型

下面将演示如何使用 TensorFlow 构建所示的基本 ConvNet:

该架构有四个卷积层。前两层有 16 个滤镜,后两层有 32 个滤镜,所有滤镜的大小都是 3x3。四个卷积层中的每一个都添加了偏置和一个 relu 激活。最后两层是全连接(密集)层。

权重和偏差

ConvNet 中的初始权重需要是对称破缺的随机值,这样网络将能够学习xavier_initializer “旨在保持所有层中渐变的比例大致相同”,通常用于初始化模型的权重。我们可以通过使用这个带有 tf.get_variable 的初始化器来创建层的权重。每个卷积层都有形状为[filter_height, filter_width, in_channels, out_channels]的过滤器。由于密集层是完全连接的,并且没有 3×3 的过滤器,所以它们的形状简单地是[in_channels, out_channels]。还会创建偏差,每个偏差的大小与相应层的out_channels相同,并且用零初始化。

为了组织和简化,我将创建weightsbiases字典。

因为 MNIST 图像是灰度的,所以第一层的in_channels是 1。输出层需要将out_channels设为 10,因为有 10 个类。其他层中的过滤器数量可以根据性能或速度进行调整,但每个in_channels需要与前一层的out_channels相同。下面创建 ConvNet 时将解释第一个密集层的大小为 7732。

卷积层

TensorFlow 有一个 tf.nn.conv2d 函数,可用于将张量与权重进行卷积。为了简化卷积层,我将创建一个函数,它接受输入数据x,应用带权重的 2D 卷积W,添加偏差b,使用 relu 激活。

模型图

另一个函数可以用来制作模型图。这将采用 MNIST 图像作为data,并使用不同层的权重和偏差。

如体系结构所示,在第二和第四卷积层之后,各层的高度和宽度会减小。最大汇集将滑动一个窗口,仅使用该区域内的单个最大值。通过使用 2×2 的窗口(ksize=[1,2,2,1])和 2 的跨距(strides=[1,2,2,1]),尺寸将减少一半。这有助于减小模型尺寸,同时保留最重要的特征。对于奇数输入大小,输出形状由除以 2 后的上限确定(例如 7/2 = 4)。

在第四个卷积层之后,张量需要在完全连接的层之前整形,这样它就变平了。全连接层的权重不用于 2D 卷积,而是仅用于矩阵乘法,因此不使用conv2d函数。

在最后两层之间添加一个示例下降层,以帮助减少过拟合,其中下降权重的概率为 0.2。只应在训练期间使用丢弃层,因此如果模型用于预测,则包含一个training标志来绕过该层。如果在预测过程中包含了下降图层,则由于随机下降的权重,模型的输出将会不一致且精度较低。

不同层的形状在代码注释中给出。从一个 28x28 的图像开始,大小被两个最大池层缩小了一半,因此其宽度和高度都减小到大小(28/2)/2 = 7。在用于密集图层之前,权重需要通过整形来展平。由于第四个卷积层中有 32 个滤波器,所以展平层的第一个形状维度的大小为 7x7x32(这就是为什么使用它来获得weights['d1']的形状)。

构建 ConvNet 图

接下来,我们可以构建将用于训练模型的数据流图。

一个重要的概念是使用占位符,所以我将首先使用它们创建 ConvNet。但是,我还将展示如何在没有占位符的情况下制作模型(参见下面的无占位符培训)。

占位符

我们需要定义如何将数据迭代器中的数据输入到模型图中。为此,我们可以创建一个占位符,指示形状为[batch_size, height, width, channels]的张量将被输入到conv_net函数中。我们可以将heightwidth设置为 28,将channels设置为 1,并通过将其设置为None来保持批量大小不变。

我们现在可以使用带有weightsbiases字典的Xtrain占位符作为conv_net函数的输入来获取输出逻辑。

这一步将允许我们通过向Xtrain占位符中输入一个或一批图像来训练模型(参见下面的输入图像)。

失败

该模型基于 10 个互斥的类别对图像进行分类。在训练期间,可以通过使用 softmax 将 logits 转换为图像属于每个类别的相对概率,然后可以通过 softmax 的交叉熵来计算损失。这些都可以使用 TensorFlow 的 softmax 交叉熵一步完成。由于我们正在测量一批图像的损失,我们可以使用 tf.reduce_mean 来获得该批图像的平均损失。

我们可以再次为图表使用占位符ytrain,它将用于输入 MNIST 标签。回想一下标签是一个热编码的,批次中的每个图像都有一个标签,所以形状应该是[batch_size, n_classes]

优化器

该损失用于通过网络反向传播该损失来更新模型权重和偏差。学习率用于按比例缩小更新,这防止了权重偏离最优值或在最优值附近跳跃。

Adam 优化器源自 Adagrad 和 RMSProp 与 momentum 的组合,并且已经证明与 ConvNets 一起工作一直很好。这里我使用 Adam 优化器,学习率为 1e-4。然后计算梯度,并通过运行最小化方法来更新权重。

train_op现在是训练模型的关键,因为它运行optimizer.minimize。为了训练模型,只需要将图像输入图表,然后运行train_op来根据损失更新权重。

训练模型

精度

我们可以在训练期间使用测试图像来测量准确度。对于每个图像,我们执行模型推断,并使用具有最大 logit 值的类作为预测。准确度就是正确预测的比例。我们需要使用整数值而不是独热编码来比较预测和标签,所以我们需要通过使用 argmax 来转换它们(这就是为什么test_labels没有被转换为独热编码,否则它必须被转换回来)。

精度可以用 TensorFlow 的精度算子来测量,该算子有两个输出。第一个输出是没有更新指标的准确性,第二个输出是我们将使用的返回具有更新指标的准确性的输出。

初始化变量

需要初始化局部变量(临时变量,如精度中的totalcount度量)和全局变量(如模型权重和偏差),以便在会话中使用。

输送图像

回想一下,对于每一批,需要创建一组新的图像和基本事实,并输入占位符Xtrainytrain。如上图所示,我们可以从data_batch得到batch_imagesbatch_labels。然后,通过创建一个将占位符作为键、将数据作为值的字典,然后在sess.run()中运行train_op时将字典传递给feed_dict参数,可以将它们输入到占位符中。

培训课程

通过调用会话中的train_op,图形中的所有步骤都将如上所述运行。我将使用 tqdm 查看每个时期的训练进度。在每个历元之后,测量精度并打印出来。

该模型将继续训练给定的时期数。在 5 个时期之后,该模型具有大约 0.97 的准确度。

没有占位符的培训

上面的例子演示了用于输入图像的占位符,但是如果直接在conv_net中使用batch_images,在tf.nn.softmax_cross_entropy_with_logits_v2labels参数中使用batch_labels,这个图形会变得更加简洁。然后,可以训练模型,而不必像这里所示的那样将任何张量输入到图形中。

访问其他节点

图中的不同节点可以通过在会话中调用它们来访问,可以是单独的,也可以是列表形式的。如果运行了一个节点列表,那么将会给出一个输出列表。例如,假设我们想要查看训练期间每个图像批次的损失。这可以通过在带有train_op的列表中运行会话中的loss来完成。在这里,我将使用 tqdm 来打印该时期内每批的损失。

预言

测试预测

我们可以使用测试精度中的test_predictions来可视化分类一些示例图像的性能。在这里,我将显示前 25 个测试图像,并使用整数预测作为标题。

预测新的图像批次

如果您想要预测一组新的图像,只需在会话中对一批图像运行conv_net功能即可进行预测。例如,以下内容可用于获得测试集中前 25 幅图像的预测:

然后predictions可以像上面一样用于显示图像。

预测单个图像

回想一下,模型期望输入具有形状[batch_size, height, width, channels]。这意味着,如果正在对单个图像进行预测,则该图像需要将其维度扩展到第一维度(即batch_size)作为一个维度。这里预测了测试集中的第 1000 幅图像。

预测概率

预测的标准化概率分布可使用 softmax 对来自conv_net模型的对数进行计算。

该模型预测该数字为 9 的概率很高。

对于模型来说,有些数字不容易预测。例如,这里是测试集中的另一个图像(idx=3062)。

虽然模型预测 8 是最有可能的类别,但它的概率只有 0.48,而且还有其他几个数字的概率在增加。

下面是一个不正确预测的例子(idx=259):

该模型错误地预测了 0,数字 6 是第二高的预测值。

保存模型

正如所讨论的,只要会话仍然打开,就可以进行预测。如果会话关闭,训练的权重和偏差将会丢失。通过使用 tf.train.Saver ,可以将会话和模型图以及训练好的权重和偏差保存为检查点。

完整的代码示例

结合上面的信息,下面是一个创建、训练和保存 ConvNet 并显示手写数字样本预测的示例脚本。

Keras 中的等效模型

Keras 是一个高级 API,可以通过使用其顺序模型 API 来极大地简化上述代码。功能 API 也是更复杂的神经网络的一个选项。对于那些有使用该 API 经验的人来说,这是一个有用的比较,并向那些没有使用过它的人展示它的价值。

请注意,不需要使用会话。此外,模型权重和偏差不需要在模型之外定义。它们是在添加层时创建的,并且它们的形状是自动计算的。

摘要

张量流图为如何训练模型创建计算数据流,会话用于进行实际训练。本文演示了在培训会话中创建图表和运行图表时使用的不同步骤和选项。当您大致了解如何创建图表并在会话中使用它们时,开发自定义神经网络并使用 TensorFlow Core 来满足您的特定需求将变得更加容易。

此外,可以看出,Keras 更加简洁,这也是为什么这个 API 更适合测试新的神经网络的原因。然而,对于新的 AI 开发者来说,许多步骤可能是黑盒,本教程旨在帮助展示后台发生的事情。

机器学习文件格式指南:列式、训练、推理和特征存储

原文:https://towardsdatascience.com/guide-to-file-formats-for-machine-learning-columnar-training-inferencing-and-the-feature-store-2e0c3d18d4f9?source=collection_archive---------0-----------------------

TLDR;大多数机器学习模型都是使用文件中的数据进行训练的。这篇文章是 Python 中机器学习开源框架中使用的流行文件格式的指南,包括 TensorFlow/Keras、PyTorch、Scikit-Learn 和 PySpark。我们还将描述特性存储如何在选择的文件系统上以选择的文件格式生成训练/测试数据,从而使数据科学家的工作变得更加轻松。

文件格式定义了存储在其中的数据的结构和编码,通常由文件扩展名来标识,例如,以结尾的文件名。txt 表示该文件是一个文本文件。然而,尽管文件被用来存储世界上的大部分数据,但是大部分数据并不是可以直接用于训练 ML 模型的格式。

这篇文章主要关注的是结构化数据的文件格式,我们将讨论 Hopsworks 特性库如何以 ML 的流行文件格式轻松创建训练数据,例如。tfrecords,。csv,。npy 还有。petastorm,以及用于存储模型的文件格式,如。pb 和。pkl。我们将不涉及其他众所周知的文件格式,如图像文件格式(例如。png,。jpeg)、视频文件格式(例如. mp4、.mkv 等)、档案文件格式(例如,zip,。gz,。tar、. bzip2)、文档文件格式(例如,docx,。pdf,。txt)或网络文件格式(例如,html)。

数据源

文件存储在文件系统上,并且在云中,越来越多地存储在对象存储上。文件系统有不同的风格。本地文件系统(POSIX)通常将其数据存储在一个或多个磁盘上(磁盘(硬盘)、SSD(固态存储)或 NVMe 驱动器)。这种文件系统可以通过网络(例如 NFS)访问,或者如果需要大量的容量,可以使用分布式文件系统,可以扩展到在数千个服务器上存储数百 Pb 的数据,如 HDFS、HopsFS 和 CephFS。在云中,对象存储是最便宜的文件存储选项,应用程序可以以合理的性能读取/写入文件。

文件格式与其文件系统相关联。例如,如果您在 Nvidia V100 GPU 上运行 TensorFlow/Pytorch 应用程序来训练 ImageNet 处理存储在 S3(对象存储)中的图像,您可能能够每秒处理 100 张图像,因为这是单个客户端可以从 S3 读取的数据。但是,V100 可能每秒处理 1000 个图像——这是文件系统的 I/O 瓶颈。新的文件格式似乎可以解决这类问题。例如,petastorm 文件格式是由优步开发的,用于存储存储在 HDFS 的自动驾驶车辆的 PBs 数据。petastorm 文件很大,可拆分,并使用 TensorFlow 和 PyTorch 的阅读器进行压缩,使它们能够并行处理大量 V100,确保它们不会成为文件 I/O 的瓶颈,如果在较慢的网络文件系统上使用传统的多媒体文件格式,就会出现这种情况。另一个替代方案是在由数百或数千个 NVMe 磁盘组成的存储设备上使用传统的文件格式,但这要昂贵得多。

机器学习框架希望将训练数据作为样本序列来使用,因此用于训练 ML 模型的文件格式应该具有易于使用的布局,并且与存储平台或用于读/写文件的语言没有阻抗不匹配。此外,分布式训练(同时在许多 GPU 上训练 ML 模型以使训练进行得更快)要求文件是可拆分的,并且可以通过分布式文件系统或对象存储来访问,以便不同的 GPU 可以从不同的服务器并行读取不同的数据碎片(分区)。

大数据—从二进制数据到结构化数据

机器学习在许多领域取得了技术突破,如图像分类、语音识别、语音合成、自然语言处理和神经机器翻译。这些系统中使用的文件格式类型通常是压缩的二进制或明文数据格式。

机器学习的影响已经超出了这些最初的领域,现在正在应用于企业数据,以解决可以建模为监督机器学习问题的业务问题。然而,许多企业数据是以结构化数据的形式提供的,这些数据来自数据仓库、数据库、文档存储库和数据湖。结构化企业数据还可以用于各种基于文本的二进制文件格式。通常,如果您有大量数据,那么您应该考虑使用二进制文件格式(而不是传统的基于文本的格式,如 CSV),因为二进制文件格式可以显著提高导入管道的吞吐量,有助于减少模型训练时间。二进制文件格式需要更少的磁盘空间,从磁盘读取所需的时间也更少。二进制文件格式意义重大,因为机器学习的另一个主要趋势是深度学习的使用越来越多。深度学习对数据如饥似渴——它在上训练的数据越多,它就会变得越好——随着数据量的增加,高效的压缩文件格式将在未来的深度学习战争中发挥作用。

机器学习框架中的文件格式

较旧的文件格式(例如,csv)可能不被压缩,可能不可分割(例如,HDF5 和 netCDF)以便它们在与许多工作者并行训练时可以无缝地工作,并且可能使得难以组合多个数据集。然而,如果您用于机器学习的框架,如 TensorFlow、PyTorch、ScikitLearn,不提供与那些文件格式功能和数据源无缝集成的数据导入和预处理功能,那么您可能无法获得更好的文件格式的好处。例如,TFRecord 文件格式是为 TensorFlow 设计的,在 tf.data 中有完整的支持,而 PyTorch 的 DataLoader 首先是围绕 Numpy 文件设计的,然后扩展到其他文件格式。类似地,ScikitLearn 最初设计用于 CSV 和 Pandas,然后扩展用于其他文件格式。因此,尽管很明显您应该使用更现代的文件格式来进行机器学习,但您仍然面临着将数据转换为这种格式的挑战,并且关于如何做到这一点的可用文档可能有限。幸运的是,Feature Store(稍后介绍)使您可以轻松地将数据转换为最重要的文件格式,以便进行机器学习。

文件格式

本节介绍了最广泛使用的 ML 文件格式,将它们分为众所周知的文件格式类型:柱状、表格、嵌套、基于数组和分层。还有为模型服务设计的新文件格式,如下所述。

柱状数据文件格式

除了可能的 Excel 之外,企业数据最常见的位置是数据仓库或数据湖。通常使用结构化查询语言(SQL)来访问这些数据,并且这些数据可以以面向行的格式(通常是提供低延迟访问、高写入吞吐量的 OLTP 数据库)或者更常见的面向列的格式(可以从 TB 扩展到 PBs 并提供更快的查询和聚合的 OLTP 列数据库)来存储。在数据湖中,结构化数据可以存储为文件(。拼花地板和。orc ),仍然可以使用 SparkSQL、Hive 和 Presto 等可伸缩的 SQL 引擎通过 SQL 访问。这些柱状数据文件和后端数据库通常是企业 ML 模型的训练数据的来源,对它们的特征工程通常需要数据并行处理框架(Spark、Beam 和 Flink ),以使特征工程能够在许多服务器上横向扩展。这种可伸缩的处理之所以能够实现,是因为 parquet/orc/petastorm 数据中的数据路径实际上是一个目录——而不是一个文件。该目录包含许多可以并行处理的文件。因此,当您想要读取列文件格式的数据时,通常需要提供基本路径(目录),处理引擎会计算出要读取的文件。如果您只想从表中读取列的子集,则不会从磁盘中读取包含排除列的文件,并且如果您执行范围扫描,文件中的统计信息(文件中列的最大/最小值)会启用数据跳过-如果您的查询要求值超出文件中存储的值范围的列,则跳过此文件。

虽然 parquet 和 orc 具有相似的属性,但 Petastorm 是为支持 ML 数据而独特设计的,它是唯一一种本地支持多维数据的列式文件格式。列式文件格式通常假设二维关系数据,但是张量可以具有比一维向量或二维关系数据源更高的维数。Petastorm 通过使用自己的 Unischema 扩展 Parquet 来提供多维数据能力,Unischema 是专门为机器学习用例设计的。Unischema 支持 petastorm 文件在 Parquet 中本地存储多维张量。unischema 还与 PyTorch 和 TensorFlow 兼容,因此您可以将 petastorm 架构直接转换为 TensorFlow 架构或 PyTorch 架构,从而为 petastorm 启用本机 TensorFlow/PyTorch 读取器。

列式文件格式是为分布式文件系统(HDFS、霍普斯福斯)和对象存储(S3、GCS、ADL)设计的,在这些系统中,工作人员可以并行读取不同的文件。

  • 文件格式:。拼花地板。兽人、. petastorm.
  • 特色工程 : PySpark,Beam,Flink。
  • 训练:。petastorm 在 TensorFlow 和 PyTorch 有原生读者;
    。兽人,。Spark 的拼花地板有本地读者;由 Spark 支持的 JDBC/Hive 源

基于表格文本的文件格式

用于机器学习的表格数据通常在。csv 文件。Csv 文件是基于文本的文件,包含逗号分隔值(csv)。Csv 文件在 ML 中很流行,因为它们易于查看/调试,并且易于从程序中读取/写入(没有压缩/索引)。但是,它们不支持列类型,文本列和数字列之间没有区别,并且它们的性能很差,当数据量增长到 GB 或更大时,这一点更加明显—它们不可拆分,没有索引,并且不支持列过滤。。csv 文件可以使用 GZIP 压缩以节省空间。ML 中通常不使用的其他流行表格格式是电子表格文件格式(例如。xlsx 和。xls)和非结构化文本格式(。txt)。

  • 文件格式:。csv,。xslx
  • 特色工程:熊猫、Scikit-Learn、PySpark、Beam 等等
  • 训练:。csv 在 TensorFlow、PyTorch、Scikit-Learn、Spark 中有本地读者

嵌套文件格式

嵌套文件格式以 n 级分层格式存储它们的记录(条目),并有一个模式来描述它们的结构。分层格式意味着一个记录可以有一个父记录(或者是根记录,没有父记录),但也可以有子记录。嵌套文件格式模式能够被扩展(在保持向后兼容性的同时添加属性),并且属性的顺序通常并不重要。的。json 和。xml 文件格式是最著名的纯文本嵌套文件格式,而二进制嵌套文件格式包括协议缓冲区(。pb)和 avro(。avro)。

TFRecords 是二进制记录的序列,通常是带有模式“Example”或“SequenceExample”的 protobuf。开发人员决定是将样本存储为“示例”还是“序列示例”。如果您的要素是相同类型数据的列表,请选择序列示例。TFRecords 文件可以是一个目录(包含许多。tfrecords 文件),并且支持用 Gzip 压缩。关于如何使用 TFRecords 的更多细节可以在官方文档和这篇好博文中找到。

  • 文件格式:。tfrecords,。json,。xml,。avro
  • 特征工程:熊猫、Scikit-Learn、PySpark、Beam 等等
  • 培训:。tfrecords 是 TensorFlow 的本机文件格式;
    。json 在 TensorFlow、PyTorch、Scikit-Learn、Spark
    都有原生阅读器。avro 文件可以用 LinkedIn 的库作为 TensorFlow 中的训练数据。

基于数组的格式

Numpy 是 Numerical Python 的缩写,是一个非常流行的科学计算和数据分析库。通过对矢量化的支持,Numpy(。npy)也是一种高性能的文件格式。Numpy 数组是具有相同类型元素的密集数组。文件格式。npy 是一种二进制文件格式,存储单个 NumPy 数组(包括嵌套的记录数组和对象数组)。

  • 文件格式:。npy
  • 特色工程 : PyTorch、Numpy、Scikit-Learn、TensorFlow
  • 训练:。npy 在 PyTorch、TensorFlow、Scikit-Learn 都有原生读者。

分层数据格式

HDF5 (.h5 或. HDF5)和 NetCDF(。nc)是流行的分层数据文件格式(HDF ),旨在支持大型、异构和复杂的数据集。特别是,HDF 格式适用于不能很好地映射到像 parquet 这样的列格式的高维数据(尽管 petastorm 既是列格式的,也支持高维数据)。许多医疗设备数据以 HDF 文件或相关文件格式存储,如 VCF BAM 的基因组数据。在内部,HDF5 和 NetCDF 以压缩布局存储数据。NetCDF 在气候科学和天文学等领域很受欢迎。HDF5 在 GIS 系统等领域广受欢迎。它们是不可分割的,因此不适合分布式处理(使用 Spark 这样的引擎)。

  • 文件格式 : .h5 (HDF5),。nc (NetCDF)
  • 特色工程:熊猫、Dask、XArray
  • Training : .h5 在 TensorFlowPyTorch 中没有原生阅读器;
    。据我们所知,nc 没有本地阅读器。

模型文件格式

在监督机器学习中,训练后创建的用于对新数据进行预测的人工制品称为模型。例如,在训练深度神经网络(DNN)之后,训练的模型基本上是包含 DNN 中的层和权重的文件。通常,模型可以保存在一个可能被压缩的文件中,因此模型文件通常具有二进制文件格式。TensorFlow 将模型保存为协议缓冲文件,带有。pb 文件扩展名。Keras 将模型原生保存为 .h5 文件。Scikit-Learn 将模型保存为 pickled python 对象,带有一个。pkl 文件扩展名。基于 XML 的模型服务的旧格式,预测模型标记语言()。pmml ),在一些框架上仍然可用,比如 Scikit-Learn。

模型文件用于对新数据进行预测,通过(1)通常将模型作为文件读入的批处理应用程序,或(2)将模型读入内存的实时模型服务服务器(如 TensorFlow 服务服务器),甚至可能在内存中有模型的多个版本用于 AB 测试。

使用的其他模型文件格式包括 SparkML 模型,这些模型可以保存为 MLleap 文件格式,并使用 ml leap 模型服务器进行实时服务(文件打包在中)。zip 格式)。苹果公司开发了。mlmodel 文件格式,用于存储嵌入 iOS 应用程序的模型,作为其核心 ML 框架的一部分(该框架对 ObjectiveC 和 Swift 语言具有卓越的支持)。受过 TensorFlow、Scikit-Learn 和其他框架培训的应用程序需要将其模型文件转换为。iOS 上使用的 mlmodel 文件格式,可以使用 coremltools 和 Tensorflow converter 等工具帮助文件格式转换。ONNX 是一种独立于 ML 框架的文件格式,由微软、脸书和亚马逊支持。理论上,任何 ML 框架都应该能够将其模型导出到。onnx 文件格式,因此它为跨不同框架的统一模型服务提供了很大的希望。然而,截至 2019 年末,ONNX 并不支持最流行的 ML 框架(TensorFlow、PyTorch、Scikit-Learn)的所有操作,因此 ONNX 对于那些框架还不实用。在 PyTorch 中,推荐的服务模型的方式是使用 Torch 脚本跟踪并保存一个模型作为一个。pt 文件,并从 C++应用程序中提供它。

这里要提到的最后一个文件格式是 YAML,用于打包模型,作为 Spark 上 ML 管道的 MLFlow 框架的一部分。MLFlow 存储一个 YAML 文件,该文件描述了它为模型服务而打包的文件,以便部署工具可以理解模型文件格式并知道要部署什么文件。

  • 文件格式:。pb,。onnx,。pkl,。mlmodel,。zip,。pmml,。pt
  • 推论:。pb 文件由 TensorFlowServing 服务器提供服务;
    。onnx 文件由微软的商业模式服务平台提供服务;
    。pkl 文件用于 Scikit-Learn 模型,通常在 Flask 服务器上;
    。mlmodel 文件由 iOS 平台提供服务;
    。zip 文件用于打包在 MLeap 运行时提供的 MLeap 文件;
    。pt 文件用于封装 PyTorch 模型,这些模型可以在 C++应用程序中使用。

ML 数据文件格式摘要

下表总结了不同 ML 管道阶段(特征工程/数据准备、培训和服务)的不同文件格式:

获胜者是…

用于深度学习的训练数据的文件格式中,功能最完整、语言独立且可扩展的是 petastorm 。它不仅支持高维数据,并在 TensorFlow 和 PyTorch 中具有本机读取器,而且它还可针对并行工作机进行扩展,而且它还支持下推索引扫描(仅从磁盘中读取您请求的那些列,甚至跳过文件中的值不在所请求的值范围内的文件),并可扩展到存储许多 TB 的数据。

对于模型服务,我们真的找不到任何优于其他文件格式的文件格式。部署和操作最简单的模型服务解决方案是协议缓冲区和 TensorFlow 服务服务器。虽然 ONNX 和 Torch Script 都有潜力,但服务于服务器的开源模型还不适合它们。同样,上菜。flask 服务器上的 pkl 文件虽然在生产中大量使用,但仍然需要 ML 操作工程师做更多的工作——您必须编写自己的 Python 服务程序、管理安全性、负载平衡等等。

Hopsworks 和 ML 文件格式

在本节中,我们将讨论使用 Hopsworks 功能库将 ML 功能数据转换为您选择的文件格式的支持,以及使用 HopsFS 文件系统在 Hopsworks 中对主要 ML 框架文件格式的支持。Hopsworks 是一个开源企业平台,用于大规模开发和运营机器学习(ML)管道,基于业界第一个 ML 功能商店。

用于文件格式转换的特征存储

Hopsworks 功能存储可以在您选择的数据存储(S3、HDFS、HopsFS)上以您选择的文件格式创建训练/测试数据。

Hopsworks 功能存储是一个仓库,用于存储 ML 的可重用功能。它旨在充当要素数据的缓存。特征数据是特征工程的输出,特征工程将来自后端系统的原始数据转换成可直接用于训练 ML 模型的特征。数据科学家通过浏览可用的功能与功能库进行交互,然后,在找到构建预测模型所需的功能后,他们会在自己选择的存储平台上以自己选择的文件格式生成训练/测试数据。在上图所示的示例中,我们可以看到我们有 3 个特征和一个来自 Titanic 数据集的目标变量,然后我们可以选择一种文件格式(从 10 多种可用的文件格式中)和一个将创建训练/测试数据的目标文件系统。功能存储使团队能够通过使用不同方法(例如,TensorFlow 和 PyTorch 上的深度学习和 Scikit-Learn 上的决策树)在不同框架中轻松尝试解决方案,从而轻松协作解决问题,而无需将训练/测试数据转换为各自框架的最高效、易用的文件格式。

Hopsworks 中的文件格式示例

Hopsworks 提供 HopsFS(下一代 HDFS 文件系统)作为其默认的分布式文件系统。HopsFS 是一个很好的用于机器学习的分布式文件系统,因为它具有高吞吐量和低延迟,并且在 ML 的流行框架中有广泛的原生 HDFS 阅读器:Spark、TensorFlow、Pandas (Scikit-Learn)和 PyTorch(通过 petastorm)。

这里包含了一些在 Hopsworks 中使用不同文件格式的笔记本的例子,接着是 Python 中 ML 的流行框架的具体例子(PySpark,TensorFlow/Keras,PyTorch,Scikit-Learn):

在接下来的部分中,我们将简要概述主要 python ML 框架的推荐文件格式:PySpark、TensorFlow/Keras、PyTorch 和 Scikit-Learn,以及一个示例代码片段和一个来自 Hopsworks 的 python 笔记本链接。

PySpark

文件格式:。csv,。拼花地板。兽人,。json,。avro,。佩塔斯托姆

数据来源:本地文件系统,HDFS,S3
模型服务文件格式:。zip (MLeap)

柱状文件格式与 PySpark(.拼花地板。兽人,。petastorm),因为它们压缩得更好,可拆分,并支持列的选择性读取(只有那些指定的列才会从磁盘上的文件中读取)。当您需要使用 PySpark 快速编写时,经常会使用 Avro 文件,因为它们是面向行的并且是可拆分的。PySpark 可以从本地文件系统、HDFS 和 S3 数据源读取文件。

打开 例子 PySpark 笔记本

熊猫/Scikit-学习

文件格式:。csv,。npy,。拼花、. h5、。json,。xlsx
数据来源:本地文件系统,HDFS,S3
模型服务文件格式:。pkl

熊猫可以在本地读取文件。csv,。拼花、. hdf5、.json,。xlsx,也来自 SQL 源代码。熊猫可以从本地文件系统、HDFS、S3、http 和 ftp 数据源读取文件。在 Hopsworks 中,您可以使用 Panda 自带的 HDFS 阅读器和一个助手类来读取 HopsFS 中的文件:

打开示例熊猫笔记本

张量流/Keras

文件格式:。csv,。npy,。tfrecords,。佩塔斯托姆

数据来源:本地文件系统,S3 HDFS
模型服务文件格式:。平装书

Tensorflow 的原生文件格式是。如果您的数据集不是很大,并且您不需要从数据集中只读取列的子集,那么这是我们推荐的文件格式。但是,如果您只想从数据集中读取列的子集(数据库术语中的投影),那么。petastorm 是要使用的文件格式。TensorFlow 可以从本地文件系统、HDFS 和 S3 数据源读取文件。

打开 例子 TensorFlow 笔记本

PyTorch

培训文件格式:。csv,。npy,。佩塔斯托姆

数据来源:本地文件系统,HDFS ( petastorm),S3
模型服务文件格式:。元素铂的符号

PyTorch 与 Numpy 紧密集成,并且。npy 是 PyTorch 的本地文件格式。然而,np.load()本身并不与 HopsFS 一起工作,所以您必须使用我们在库中包含的包装器函数,该函数首先将来自 HopsFS 的数据具体化到本地文件系统,然后将其作为 numpy 数组读入。如果您有大型数据集,我们建议使用。petastorm 通过自己的阅读器与 PyTorch 一起工作。

打开范例 PyTorch 笔记本

Numpy/Scikit-Learn

文件格式:。神经肽 y

数据来源:本地文件系统
模型服务文件格式:。pkl

Scikit-Learn 的原生数据格式是数字数据,通常存储为 numpy 数组或 pandas 数据帧(可转换为 numpy 数组)。PyTorch 也直接构建在 numpy 数组上。就此而论。npy 是用 Scikit-Learn 训练数据的常用文件格式。在 Hopsworks 中,我们提供了一个 numpy_helper 来读取。来自 HopsFS 的 npy 文件。

打开示例 Scikit-学习笔记本

参考

https://www.neonscience.org/about-hdf5

[numpy]https://towards data science . com/why-you-should-start-using-npy-file-more-frequency-df 2 a 13 cc 0161

https://www.tensorflow.org/tfx/transform/get_started

https://www.logicalclocks.com/featurestore

[TF records]https://medium . com/mosely-ai/tensor flow-records-what-them-and-how-to-use-them-c 46 BC 4 BBB 564

https://luminousmen.com/post/big-data-file-formats

【PETA storm】https://qcon . ai/system/files/presentation-slides/yevgeni - PETA storm _ 16 日 _2019 年 4 月 _ 日。pdf

初学者财务报表分析指南

原文:https://towardsdatascience.com/guide-to-financial-statement-analysis-for-beginners-835d551b8e29?source=collection_archive---------3-----------------------

很多刚入门财务的人,经常会觉得处理财务报表是一件很头疼的事情。其实做财务报表分析,只需要掌握“思路+内容+工具”这个公式就可以了。明确报表分析的思路,知道分析什么,确定指标,最后选择好的报表工具,达到最终的分析结果。

1.财务报表分析的目的

不同的人出于不同的目的进行财务分析,但共同的目的是从财务报表中获取对其经济决策有用的信息。因此,财务报表分析的对象有三个:财务状况经营成果现金流量。基于此,我们需要做的偿债能力分析盈利能力分析营运能力分析构成了财务报表分析的总体框架。

比如企业主管部门、母公司、财务部门重点分析检查企业相关资源的配置情况、对财经政策和财务制度的遵守情况、资本保值增值情况等。

投资者重点分析盈利能力、运营能力和资金使用情况,了解投资收益和投资风险。

债权人重点分析企业的偿债能力,评价企业的财务安全或风险程度,等等。

考虑到内部管理的不同要求,财务报表分析的内容非常广泛。它有助于报表使用者总结和评价企业的财务状况和经营成果,为经济预测和决策提供可靠的依据。

2.财务报表分析的思路

2.1 基本思想

  • 捕获

报表每一项的具体数据只是表面,结构(各种比率或指标)是骨架,趋势才是核心。结构比价值更重要,趋势比结构更重要。

  • 比较

财务报表只有通过比较阅读才有意义。

  • 掌握

各种会计原则都有天然的局限性。不能局限于报告分析就妄下结论。

2.2 分析方法

  • 结构分析

理清报表的各种核对关系,这是基本功。

对报表结构进行横向比较,找出与同业公司的主要指标差异并分析原因。重要的指标有毛利率、净利润率、∑经营活动现金流量/∑销售收入、销售收入/固定资产、流动资产/非流动资产、存货/固定资产、负债/总资产等等。不必拘泥于课本上的经典指标。根据行业特点创建自己的比率。

结构差异罗列出来之后,就需要从竞争力、产品细分、商业模式、规模、地域等方面进行推理。如果没有正确的理由,我们可能会怀疑报告的真实性。

  • 趋势分析

趋势分析的重要内容是资产收入利润

分析资产的增加是来自债务还是权益(利润还是股东投入)。此外,关注每个资产账户比例的变化,这往往反映了企业模式的变化。

弄清楚收入的增加是因为合并范围的扩大还是自身业务的扩大。并关注毛利率和市场份额的变化。总的来说,在毛利率小幅度波动的前提下,市场份额的逐步提升是最可靠、最可持续的情况。

利润的增加应该是综合资产和收入增长的逻辑推理,但利润经过多次加减后在报表末尾,客观性最弱。要辩证地认识权责发生制的缺陷和漏洞。

你要考虑资产和收入的增加来分析利润的增加。但是经过一系列的数据操作,利润是最不客观的。你应该深入了解权责发生制的缺陷和弱点,然后辩证地分析利润。

3.三大财务报表的内容

3.1 资产负债表

资产负债表主要告诉我们公司的资产和负债在那种现状下是怎样的。所以,报告的关键是看到的时间。而且时间对报告影响很大。最重要的检验关系是负债加权益等于资产。在会计上,我目前拥有的叫资产,借来的钱叫负债,自己的钱叫股权。

3.2 利润表

损益表或利润表主要告诉我们公司在一段时间内的利润和亏损。利润表的重点是看这个周期有多长,一般是一个月,一个季度或者一年。在损益表中,最重要的核对关系是收入减去成本等于利润。

3.3 现金流量表

现金流量表主要告诉我们公司在一段时间内收到了多少现金,付出了多少现金,银行里还剩多少现金。这个报表的关键也是看这个周期有多长,和利润表一样。现金流量表最重要的核对关系是现金流入减去现金流出等于剩余现金。这个关系也很简单,就不多解释了。

Cash Flow Analysis Made with FineReport

4.财务报表分析工具

如果数据量不够大,不能用数据库,可以用 excel 做财务报表。当然,如果你写的是 VB 语言,excel 也可以连接数据库。专业统计软件如 SPSSSASStata 适用于线性回归、f 统计、抽样、假设检验等。

但是,如果财务分析涉及到数据库,就要选择专业的软件。首先,Excel 对数据的处理性能有限,很难实现数据的实时更新。在具体报表工具的选择上, PowerBITableauCrystal Repor t、 QlikviewFineReport 都是不错的选择。下面我使用零编码工具 FineReport 来演示各种财务报告风格。FineReport 采用的是拖拽操作,类似 excel 的界面,财务新手很容易上手。比如我们可以用 FineReport 做一个仪表盘,形成一个财务管理驾驶舱。操作是拖拽数据字段生成分析图表,合并成一个主题分析。

财务管理仪表板

标准福利审查

杜邦分析

每日运费

产品成本分析

2020 年指导如何学习和掌握计算机视觉

原文:https://towardsdatascience.com/guide-to-learn-computer-vision-in-2020-36f19d92c934?source=collection_archive---------5-----------------------

这篇文章将关注资源,我相信这将最大程度地提高你在计算机视觉方面的知识,并且主要基于我自己的经验。

在开始学习计算机视觉之前,了解机器学习和 python 的基础知识将会很有帮助。

看看我的机器和深度学习博客https://diyago.github.io/

结构

Star Wars: Luke Skywalker & Darth Vader

你不必一开始就选择它,但应用新获得的知识是必要的。

没有太多可选项: pytorch 或者keras(tensor flow)。Pytorch 可能需要编写更多的代码,但是它提供了很大的灵活性,所以请使用它。除此之外,大部分深度学习的研究者开始使用 pytoch。

albumination(图像增强)和 catalyst (框架,pytorch 上面的高级 API)可能也有用,用它们吧,尤其是第一个。

五金器具

  • Nvidia GPU 10xx+会绰绰有余(300 美元以上)
  • Kaggle 内核 —每周仅 30 小时(免费)
  • Google Colab — 12 小时会话限制,未知周限制(免费)

理论&实践

在线课程

  • CS231n 是顶级在线,涵盖了计算机视觉中所有必要的基础知识。Youtube 在线视频。他们甚至有练习,但我不能建议解决它们。(免费)
  • Fast.ai 是你应该注意的下一道菜。还有,fast.ai 是 pytorch 上面的高层框架,但是他们改变自己的 API 太频繁,文档的缺乏让它用起来不靠谱。然而,理论和有用的技巧只是花时间观看本课程的幻想。(免费)

在学习这些课程的时候,我鼓励你将理论付诸实践,将它应用到一个框架中。

商品和编码

  • ArXiv.org——所有最近的信息都会在这里。(免费)
  • https://paperswithcode.com/sota——最常见的深度学习任务的最新水平,不仅仅是计算机视觉。(免费)
  • Github —如果有什么东西被实现了,你可以在这里找到它。(免费)

没什么可读的,但我相信这两本书会有用,不管你选择用 pytorch 还是 keras

  • 用 Python 进行深度学习Keras 创造者、谷歌人工智能研究员弗朗索瓦·乔莱(Franç ois Chollet)。易于使用,并可能获得一些你以前不知道的洞察力。(不免费)
  • py torch 深度学习py torch 团队 Eli Stevens & Luca Antiga(免费)

卡格尔

竞赛 — kaggle 是一个知名的在线平台,提供各种机器学习竞赛,其中许多都是关于计算机视觉的。您甚至可以在没有完成课程的情况下开始参与,因为从比赛开始,将会有许多开放的内核(端到端代码),您可以直接从浏览器运行这些内核。(免费)

强硬(绝地)方式

Star Wars`s Jedi: Yoda

另一条路可能会很艰难,但你将获得所需的知识,不仅可以进行拟合预测,还可以进行自己的研究。谢尔盖·别洛乌索夫又名贝斯。

你只需要阅读并实现下面所有的文章(免费)。光是阅读它们也会很棒。

结构

语义分割

生成对抗网络 Generative adversarial Networks

对象检测 Object Detection

实例 Segmentation

姿势估计

一本 Jupyter 笔记本中的 R 和 Python 指南

原文:https://towardsdatascience.com/guide-to-r-and-python-in-a-single-jupyter-notebook-ff12532eb3ba?source=collection_archive---------4-----------------------

当你可以同时使用两者时,为什么要选择一个?

r 主要用于统计分析,而 Python 为数据科学提供了更通用的方法。r 和 Python 是面向对象面向数据科学的编程语言。学习这两者是一个理想的解决方案。Python 是一种具有可读语法的通用语言。——

Image Source

本文基于哈佛大学 AC209b 讲座,大部分内容由 IACS 大学的威尔·克莱博撰写和教授。

R 和 Python 用户之间的战争已经肆虐了好几年。由于大多数老派的统计学家都是在 R 上接受培训的,而且大多数大学的计算机科学和数据科学系都更喜欢 Python,所以两者都有利有弊。我在实践中注意到的主要缺点是每种语言都有可用的软件包。

截至 2019 年,聚类分析和样条的 R 包优于同类型的 Python 包。在本文中,我将通过编码示例向您展示如何获取 R 函数和数据集,然后在基于 Python 的 Jupyter 笔记本中导入和利用它们。

本文的主题是:

  • 导入(基本)R 函数
  • 导入 R 库函数
  • 填充向量 R 理解
  • 填充数据帧 R 理解
  • 填充公式 R 理解
  • R 中的运行模式
  • 将结果返回给 Python
  • 获取 R 中的模型预测
  • 在 R 中绘图
  • 阅读 R 的文档

在我的 GitHub 页面上可以找到这篇文章的附带笔记本。

* [## 龙熊先生/文章

这个存储库包含与我的媒体文章相关的代码相关内容。此存储库是主存储库…

github.com](https://github.com/mrdragonbear/Articles)*

线性/多项式回归

首先,我们将看看使用导入的 R 函数执行基本的线性和多项式回归。我们将研究一个关于糖尿病的数据集,其中包含 C 肽浓度和酸度变量的信息。不要担心模型的内容,这是广义可加模型领域中一个常用的例子,我们将在本文的后面讨论。

*diab = pd.read_csv("data/diabetes.csv")print("""
# Variables are:
#   subject:   subject ID number
#   age:       age diagnosed with diabetes
#   acidity:   a measure of acidity called base deficit
#   y:         natural log of serum C-peptide concentration
#
# Original source is Sockett et al. (1987)
# mentioned in Hastie and Tibshirani's book 
# "Generalized Additive Models".
""")display(diab.head())
display(diab.dtypes)
display(diab.describe())*

然后我们可以绘制数据:

*ax0 = diab.plot.scatter(x='age',y='y',c='Red',title="Diabetes data") #plotting direclty from pandas!
ax0.set_xlabel("Age at Diagnosis")
ax0.set_ylabel("Log C-Peptide Concentration");*

statsmodel进行线性回归。你可能需要安装这个包来遵循代码,你可以用pip install statsmodel来完成。

  • 在 Python 中,我们从目标值的向量和我们自己构建的设计矩阵(例如,从多项式特征)开始工作。
  • 现在,statsmodel的公式界面可以帮助您构建目标值和设计矩阵。
*#Using statsmodels
import statsmodels.formula.api as sm

model1 = sm.ols('y ~ age',data=diab)
fit1_lm = model1.fit()*

现在,我们构建一个数据框架来预测值(有时这只是测试或验证集)

  • 对于制作模型预测的漂亮图表非常有用-预测大量值,而不仅仅是训练集中的任何值
*x_pred = np.linspace(0,16,100)

predict_df = pd.DataFrame(data={"age":x_pred})
predict_df.head()*

使用get_prediction(<data>).summary_frame()获得模型的预测(和误差线!)

*prediction_output = fit1_lm.get_prediction(predict_df).summary_frame()
prediction_output.head()*

绘制模型和误差线

*ax1 = diab.plot.scatter(x='age',y='y',c='Red',title="Diabetes data with least-squares linear fit")
ax1.set_xlabel("Age at Diagnosis")
ax1.set_ylabel("Log C-Peptide Concentration")

ax1.plot(predict_df.age, prediction_output['mean'],color="green")
ax1.plot(predict_df.age, prediction_output['mean_ci_lower'], color="blue",linestyle="dashed")
ax1.plot(predict_df.age, prediction_output['mean_ci_upper'], color="blue",linestyle="dashed");

ax1.plot(predict_df.age, prediction_output['obs_ci_lower'], color="skyblue",linestyle="dashed")
ax1.plot(predict_df.age, prediction_output['obs_ci_upper'], color="skyblue",linestyle="dashed");*

我们还可以拟合三次多项式模型,并以两种方式绘制模型误差线:

  • Route1:为ageage**2age**3各建一个设计 df
*fit2_lm = sm.ols(formula="y ~ age + np.power(age, 2) + np.power(age, 3)",data=diab).fit()

poly_predictions = fit2_lm.get_prediction(predict_df).summary_frame()
poly_predictions.head()*

  • 方法 2:编辑公式
*ax2 = diab.plot.scatter(x='age',y='y',c='Red',title="Diabetes data with least-squares cubic fit")
ax2.set_xlabel("Age at Diagnosis")
ax2.set_ylabel("Log C-Peptide Concentration")

ax2.plot(predict_df.age, poly_predictions['mean'],color="green")
ax2.plot(predict_df.age, poly_predictions['mean_ci_lower'], color="blue",linestyle="dashed")
ax2.plot(predict_df.age, poly_predictions['mean_ci_upper'], color="blue",linestyle="dashed");

ax2.plot(predict_df.age, poly_predictions['obs_ci_lower'], color="skyblue",linestyle="dashed")
ax2.plot(predict_df.age, poly_predictions['obs_ci_upper'], color="skyblue",linestyle="dashed");*

这没有使用 R 编程语言的任何特性。现在,我们可以使用 r 中的函数重复分析。

线性/多项式回归,但使其为 R

在这一节之后,我们将了解使用 R 模型所需的一切。实验室的其余部分只是应用这些概念来运行特定的模型。因此,这一节是你在 r 中工作的“备忘单”。

我们需要知道的是:

  • 导入(基本)R 函数
  • 导入 R 库函数
  • 填充向量 R 理解
  • 填充 R 理解的数据帧
  • 填充 R 理解的公式
  • 在 R 中运行模型
  • 将结果返回给 Python
  • 在 R 中获取模型预测
  • 在 R 中绘图
  • 阅读 R 的文档

导入 R 函数

为了导入 R 函数,我们需要rpy2包。根据您的环境,您可能还需要指定 R 主目录的路径。下面我举了一个例子来说明如何指定这一点。

*# if you're on JupyterHub you may need to specify the path to R

#import os
#os.environ['R_HOME'] = "/usr/share/anaconda3/lib/R"

import rpy2.robjects as robjects*

要指定一个 R 函数,只需使用robjects.r后跟方括号中的包名作为字符串。为了防止混淆,我喜欢对从 r 导入的函数、库和其他对象使用r_

*r_lm = robjects.r["lm"]
r_predict = robjects.r["predict"]
#r_plot = robjects.r["plot"] # more on plotting later

#lm() and predict() are two of the most common functions we'll use*

导入 R 库

我们可以导入单个函数,但也可以导入整个库。要导入整个库,您可以从rpy2.robjects.packages中提取importr包。

*from rpy2.robjects.packages import importr
#r_cluster = importr('cluster')
#r_cluster.pam;*

填充向量 R 理解

要指定一个可以与 Python 包接口的浮点向量,我们可以使用robjects.FloatVector函数。这个函数的参数引用了您希望转换成 R 对象的数据数组,在我们的例子中,是来自糖尿病数据集中的agey变量。

*r_y = robjects.FloatVector(diab['y'])
r_age = robjects.FloatVector(diab['age'])
# What happens if we pass the wrong type?
# How does r_age display?
# How does r_age print?*

填充数据帧 R 理解

我们可以指定单独的向量,也可以指定整个数据帧。这是通过使用robjects.DataFrame功能完成的。这个函数的参数是一个字典,它指定了名称和与名称相关的向量(从robjects.FloatVector获得)。

*diab_r = robjects.DataFrame({"y":r_y, "age":r_age})
# How does diab_r display?
# How does diab_r print?*

填充公式 R 理解

例如,要指定一个回归公式,我们可以使用robjects.Formula函数。这遵循 R 语法dependent variable ~ independent variables。在我们的例子中,输出y被建模为age变量的函数。

*simple_formula = robjects.Formula("y~age")
simple_formula.environment["y"] = r_y #populate the formula's .environment, so it knows what 'y' and 'age' refer to
simple_formula.environment["age"] = r_age*

注意,在上面的公式中,我们必须指定与公式中每个变量相关的 FloatVector。我们必须这样做,因为公式不会自动将我们的变量名与我们之前指定的变量相关联——它们还没有与robjects.Formula对象相关联。

R 中的运行模式

要指定一个模型,在本例中是一个使用我们之前导入的r_lm函数的线性回归模型,我们需要将我们的公式变量作为参数传递(除非我们传递一个 R 公式对象,否则这将不起作用)。

*diab_lm = r_lm(formula=simple_formula) # the formula object is storing all the needed variables*

我们可以在公式本身中引用数据集,而不是指定与robjects.Formula对象相关的每个单独的浮点向量(只要它已经成为 R 对象本身)。

*simple_formula = robjects.Formula("y~age") # reset the formula
diab_lm = r_lm(formula=simple_formula, data=diab_r) #can also use a 'dumb' formula and pass a dataframe*

将结果返回给 Python

使用 R 函数和库是很棒的,但是我们也可以分析我们的结果,并将它们返回给 Python 进行进一步的处理。要查看输出:

*diab_lm #the result is already 'in' python, but it's a special object*

我们还可以检查输出中的名称:

*print(diab_lm.names) # view all names*

以我们输出的第一个元素为例:

*diab_lm[0] #grab the first element*

要计算系数:

*diab_lm.rx2("coefficients") #use rx2 to get elements by name!*

要将系数放入 Numpy 数组中:

*np.array(diab_lm.rx2("coefficients")) #r vectors can be converted to numpy (but rarely needed)*

得到预测

为了使用我们的 R 模型获得预测,我们可以创建一个预测数据帧并使用r_predict函数,类似于使用 Python 的方式。

*# make a df to predict on (might just be the validation or test dataframe)
predict_df = robjects.DataFrame({"age": robjects.FloatVector(np.linspace(0,16,100))})# call R's predict() function, passing the model and the data 
predictions = r_predict(diab_lm, predict_df)*

我们可以使用rx2函数提取“年龄”值:

*x_vals = predict_df.rx2("age")*

我们还可以使用 Python 绘制数据:

*ax = diab.plot.scatter(x='age',y='y',c='Red',title="Diabetes data")
ax.set_xlabel("Age at Diagnosis")
ax.set_ylabel("Log C-Peptide Concentration");ax.plot(x_vals,predictions); #plt still works with r vectors as input!*

我们也可以使用 R 来绘图,尽管这稍微复杂一些。

在 R 中绘图

要在 R 中绘图,我们需要使用以下命令打开%R magic 函数:

*%load_ext rpy2.ipython*
  • 以上开启了%R“魔法”。
  • r 的 plot()命令根据您传递给它的内容做出不同的响应;不同的模式得到不同的剧情!
  • 对于任何特定的模型,搜索 plot.modelname。例如,对于 GAM 模型,搜索plot.gam以获得绘制 GAM 模型的任何细节。
  • %R“magic”在“笔记本”模式下运行 R 代码,所以数字显示得很好
  • plot(<model>)代码之前,我们传入 R 需要了解的变量(-i代表“输入”)
*%R -i diab_lm plot(diab_lm);*

阅读 R 的文档

lm()功能的文档在这里是,一个更漂亮的版本(相同内容)在这里是。谷歌搜索时,尽可能选择 rdocumentation.org。部分:

  • 用法:给出函数签名,包括所有可选参数
  • 参数:每个功能输入控制什么
  • 细节:关于函数做什么以及参数如何交互的附加信息。经常从正确的地方开始阅读
  • :函数返回的对象的结构
  • 参考文献:相关学术论文
  • 参见:其他感兴趣的功能

示例

作为测试我们新获得的知识的例子,我们将尝试以下内容:

  • 将 R 中计算的置信区间添加到上面的线性回归图中。使用interval=参数到r_predict()(文档此处)。你必须处理一个由 r 返回的矩阵。
  • 用一个 5 次多项式拟合 r 中的糖尿病数据。在网上搜索一个比用所有 5 个多项式项写出一个公式更简单的方法。

置信区间:

*CI_matrix = np.array(r_predict(diab_lm, predict_df, interval="confidence"))

ax = diab.plot.scatter(x='age',y='y',c='Red',title="Diabetes data")
ax.set_xlabel("Age at Diagnosis")
ax.set_ylabel("Log C-Peptide Concentration");

ax.plot(x_vals,CI_matrix[:,0], label="prediction")
ax.plot(x_vals,CI_matrix[:,1], label="95% CI", c='g')
ax.plot(x_vals,CI_matrix[:,2], label="95% CI", c='g')
plt.legend();*

五次多项式:

*ploy5_formula = robjects.Formula("y~poly(age,5)") # reset the formula
diab5_lm = r_lm(formula=ploy5_formula, data=diab_r) #can also use a 'dumb' formula and pass a dataframe

predictions = r_predict(diab5_lm, predict_df, interval="confidence")

ax = diab.plot.scatter(x='age',y='y',c='Red',title="Diabetes data")
ax.set_xlabel("Age at Diagnosis")
ax.set_ylabel("Log C-Peptide Concentration");

ax.plot(x_vals,predictions);*

洛斯平滑

现在我们知道了如何在 Python 中使用 R 对象和函数,我们可以看看我们可能想要这样做的情况。第一个例子是 Lowess 平滑。

Lowess smoothing 在 Python 和 r 中都实现了。我们将在转换语言时使用它作为另一个例子。

Python

在 Python 中,我们使用statsmodel.nonparametric.smoothers_lowess来执行 lowess 平滑。

*from statsmodels.nonparametric.smoothers_lowess import lowess as lowessss1 = lowess(diab['y'],diab['age'],frac=0.15)
ss2 = lowess(diab['y'],diab['age'],frac=0.25)
ss3 = lowess(diab['y'],diab['age'],frac=0.7)
ss4 = lowess(diab['y'],diab['age'],frac=1)ss1[:10,:] # we get back simple a smoothed y value for each x value in the data*

请注意绘制不同模型的清晰代码。一会儿我们会看到更干净的代码。

*for cur_model, cur_frac in zip([ss1,ss2,ss3,ss4],[0.15,0.25,0.7,1]): ax = diab.plot.scatter(x='age',y='y',c='Red',title="Lowess Fit, Fraction = {}".format(cur_frac))
    ax.set_xlabel("Age at Diagnosis")
    ax.set_ylabel("Log C-Peptide Concentration")
    ax.plot(cur_model[:,0],cur_model[:,1],color="blue")

    plt.show()*

R

要在 R 中实现 Lowess 平滑,我们需要:

  • 导入黄土功能。
  • 把数据发给 r。
  • 调用函数并获得结果。
*r_loess = robjects.r['loess.smooth'] #extract R function
r_y = robjects.FloatVector(diab['y'])
r_age = robjects.FloatVector(diab['age'])ss1_r = r_loess(r_age,r_y, span=0.15, degree=1)ss1_r #again, a smoothed y value for each x value in the data*

可变跨度
接下来,一些非常干净的代码,以适应和绘制具有各种参数设置的模型。(尽管之前看到的zip()方法在标签和参数不同时非常有用)

*for cur_frac in [0.15,0.25,0.7,1]:

    cur_smooth = r_loess(r_age,r_y, span=cur_frac) ax = diab.plot.scatter(x='age',y='y',c='Red',title="Lowess Fit, Fraction = {}".format(cur_frac))
    ax.set_xlabel("Age at Diagnosis")
    ax.set_ylabel("Log C-Peptide Concentration")
    ax.plot(cur_smooth[0], cur_smooth[1], color="blue")

    plt.show()*

我们要看的下一个例子是平滑样条,Python 不太支持这些模型,所以最好使用 R 函数。

平滑样条

从现在开始,我们将使用 R 函数;Python 不(很好地)支持这些模型。

为了清楚起见:这是一个奇特的样条模型

跨越所有可能的功能 f 。获胜者将始终是一个连续的三次多项式,在每个数据点都有一个结。

需要考虑的一些事情是:

  • 知道为什么赢家是立方吗?
  • 这个模型的可解释性如何?
  • 有哪些可调参数?

为了实现平滑样条,我们只需要两条线。

*r_smooth_spline = robjects.r['smooth.spline'] #extract R function# run smoothing function
spline1 = r_smooth_spline(r_age, r_y, spar=0)*

平滑样条交叉验证

r 的smooth_spline函数有一个内置的交叉验证来为 lambda 找到一个好的值。参见包文档

*spline_cv = r_smooth_spline(r_age, r_y, cv=True) lambda_cv = spline_cv.rx2("lambda")[0]ax19 = diab.plot.scatter(x='age',y='y',c='Red',title="smoothing spline with $\lambda=$"+str(np.round(lambda_cv,4))+", chosen by cross-validation")
ax19.set_xlabel("Age at Diagnosis")
ax19.set_ylabel("Log C-Peptide Concentration")
ax19.plot(spline_cv.rx2("x"),spline_cv.rx2("y"),color="darkgreen")*

自然样条和基本样条

这里,我们在模型复杂性上后退了一步,但在编码复杂性上前进了一步。我们将再次使用 R 的公式接口,所以我们需要填充公式和数据框架。

更多值得思考的问题:

  • 自然样条和基本样条在哪些方面不如我们刚刚使用的样条复杂?
  • 是什么让样条曲线变得“自然”?
  • 什么使样条成为“基础”?
  • 调优参数是什么?
*#We will now work with a new dataset, called GAGurine.
#The dataset description (from the R package MASS) is below:
#Data were collected on the concentration of a chemical GAG 
# in the urine of 314 children aged from zero to seventeen years. 
# The aim of the study was to produce a chart to help a paediatrican
# to assess if a child's GAG concentration is ‘normal’.#The variables are:
# Age: age of child in years.
# GAG: concentration of GAG (the units have been lost).*

首先,我们导入并绘制数据集:

*GAGurine = pd.read_csv("data/GAGurine.csv")
display(GAGurine.head())

ax31 = GAGurine.plot.scatter(x='Age',y='GAG',c='black',title="GAG in urine of children")
ax31.set_xlabel("Age");
ax31.set_ylabel("GAG");*

标准的东西:导入函数,将变量转换成 R 格式,调用函数

*from rpy2.robjects.packages import importr
r_splines = importr('splines')# populate R variables
r_gag = robjects.FloatVector(GAGurine['GAG'].values)
r_age = robjects.FloatVector(GAGurine['Age'].values)
r_quarts = robjects.FloatVector(np.quantile(r_age,[.25,.5,.75])) #woah, numpy functions run on R objects*

当我们从 r_splines 调用 ns 或 bs 函数时会发生什么?

*ns_design = r_splines.ns(r_age, knots=r_quarts)
bs_design = r_splines.bs(r_age, knots=r_quarts)print(ns_design)*

nsbs返回设计矩阵,而不是模型对象!这是因为它们应该与lm的公式接口一起工作。为了得到一个模型对象,我们填充一个包含ns(<var>,<knots>)的公式,并拟合数据。

*r_lm = robjects.r['lm']
r_predict = robjects.r['predict']

# populate the formula
ns_formula = robjects.Formula("Gag ~ ns(Age, knots=r_quarts)")
ns_formula.environment['Gag'] = r_gag
ns_formula.environment['Age'] = r_age
ns_formula.environment['r_quarts'] = r_quarts

# fit the model
ns_model = r_lm(ns_formula*

像往常一样预测:构建一个数据框架进行预测并调用predict()

*# predict
predict_frame = robjects.DataFrame({"Age": robjects.FloatVector(np.linspace(0,20,100))})ns_out = r_predict(ns_model, predict_frame)ax32 = GAGurine.plot.scatter(x='Age',y='GAG',c='grey',title="GAG in urine of children")
ax32.set_xlabel("Age")
ax32.set_ylabel("GAG")
ax32.plot(predict_frame.rx2("Age"),ns_out, color='red')
ax32.legend(["Natural spline, knots at quartiles"]);*

例题

让我们看两个实现基样条的例子。

  1. 用相同的结拟合一个基本样条模型,并将其添加到上面的图中。
*bs_formula = robjects.Formula("Gag ~ bs(Age, knots=r_quarts)")
bs_formula.environment['Gag'] = r_gag
bs_formula.environment['Age'] = r_age
bs_formula.environment['r_quarts'] = r_quarts

bs_model = r_lm(bs_formula)
bs_out = r_predict(bs_model, predict_frame)ax32 = GAGurine.plot.scatter(x='Age',y='GAG',c='grey',title="GAG in urine of children")
ax32.set_xlabel("Age")
ax32.set_ylabel("GAG")
ax32.plot(predict_frame.rx2("Age"),ns_out, color='red')
ax32.plot(predict_frame.rx2("Age"),bs_out, color='blue')
ax32.legend(["Natural spline, knots at quartiles","B-spline, knots at quartiles"]);*

2.在[2,4,6…14,16]处用 8 个节点拟合一个基本样条,并将其添加到上面的图中。

*overfit_formula = robjects.Formula("Gag ~ bs(Age, knots=r_quarts)")
overfit_formula.environment['Gag'] = r_gag
overfit_formula.environment['Age'] = r_age
overfit_formula.environment['r_quarts'] = robjects.FloatVector(np.array([2,4,6,8,10,12,14,16]))

overfit_model = r_lm(overfit_formula)
overfit_out = r_predict(overfit_model, predict_frame)ax32 = GAGurine.plot.scatter(x='Age',y='GAG',c='grey',title="GAG in urine of children")
ax32.set_xlabel("Age")
ax32.set_ylabel("GAG")
ax32.plot(predict_frame.rx2("Age"),ns_out, color='red')
ax32.plot(predict_frame.rx2("Age"),bs_out, color='blue')
ax32.plot(predict_frame.rx2("Age"),overfit_out, color='green')
ax32.legend(["Natural spline, knots at quartiles", "B-spline, knots at quartiles", "B-spline, lots of knots"]);*

GAMs

最后,我们来看看我们最先进的模型。这里的编码并不比我们以前做的更复杂,尽管幕后工作很棒。

首先,让我们得到我们的多元数据。

*kyphosis = pd.read_csv("data/kyphosis.csv")print("""
# kyphosis - wherther a particular deformation was present post-operation
# age - patient's age in months
# number - the number of vertebrae involved in the operation
# start - the number of the topmost vertebrae operated on""")
display(kyphosis.head())
display(kyphosis.describe(include='all'))
display(kyphosis.dtypes)#If there are errors about missing R packages, run the code below:

#r_utils = importr('utils')
#r_utils.install_packages('codetools')
#r_utils.install_packages('gam')*

为了适应游戏,我们

  • 导入gam
  • 在我们想要平滑的变量上填充包含s(<var>)的公式。
  • 调用gam(formula, family=<string>),其中family是一个命名概率分布的字符串,根据响应变量被认为如何出现来选择。

粗略的family指导方针:

  • 响应是二进制的或“M 次尝试中的 N 次”,例如,患疾病的实验鼠(10 只中的)数量:选择"binomial"
  • 响应是没有逻辑上限的计数,例如售出的冰淇淋数量:选择"poisson"
  • 响应是真实的,有正态分布的噪声,如人的身高:选择"gaussian"(默认)
*#There is a Python library in development for using GAMs (https://github.com/dswah/pyGAM)
# but it is not yet as comprehensive as the R GAM library, which we will use here instead.

# R also has the mgcv library, which implements some more advanced/flexible fitting methods

r_gam_lib = importr('gam')
r_gam = r_gam_lib.gam

r_kyph = robjects.FactorVector(kyphosis[["Kyphosis"]].values)
r_Age = robjects.FloatVector(kyphosis[["Age"]].values)
r_Number = robjects.FloatVector(kyphosis[["Number"]].values)
r_Start = robjects.FloatVector(kyphosis[["Start"]].values)

kyph1_fmla = robjects.Formula("Kyphosis ~ s(Age) + s(Number) + s(Start)")
kyph1_fmla.environment['Kyphosis']=r_kyph
kyph1_fmla.environment['Age']=r_Age
kyph1_fmla.environment['Number']=r_Number
kyph1_fmla.environment['Start']=r_Start

kyph1_gam = r_gam(kyph1_fmla, family="binomial")*

拟合的 gam 模型包含许多有趣的数据:

*print(kyph1_gam.names)*

还记得密谋吗?在 gam 模型上调用 R 的plot()是查看拟合样条的最简单方法

在[ ]:

*%R -i kyph1_gam plot(kyph1_gam, residuals=TRUE,se=TRUE, scale=20);*

预测像正常情况一样工作(建立一个数据框进行预测,如果您还没有数据框,并调用predict())。但是,“预测”总是报告单个变量效果的总和。如果family为非默认,这可能与该点的实际预测不同。

例如,我们正在进行“逻辑回归”,因此原始预测是对数概率,但我们可以通过使用 in predict(..., type="response")获得概率

*kyph_new = robjects.DataFrame({'Age': robjects.IntVector((84,85,86)), 
                               'Start': robjects.IntVector((5,3,1)), 
                               'Number': robjects.IntVector((1,6,10))})print("Raw response (so, Log odds):")
display(r_predict(kyph1_gam, kyph_new))
print("Scaled response (so, probabilty of kyphosis):")
display(r_predict(kyph1_gam, kyph_new, type="response"))*

最终意见

一旦您熟悉了这个过程,在 Python 中使用 R 函数就相对容易了,如果您需要使用 R 包来执行数据分析,或者您是一个已经获得了 R 代码的 Python 用户,那么它可以省去很多麻烦。

我希望你喜欢这篇文章,并发现它的信息和有用的。对于那些希望在 Jupyter 环境中体验 R 和 Python 函数和对象之间的接口的人来说,这本笔记本中使用的所有代码都可以在我的 GitHub 页面上找到。

时事通讯

关于新博客文章和额外内容的更新,请注册我的时事通讯。

* [## 时事通讯订阅

丰富您的学术之旅,加入一个由科学家,研究人员和行业专业人士组成的社区,以获得…

mailchi.mp](https://mailchi.mp/6304809e49e7/matthew-stewart)*

制导摄像头坏了。显著图的健全性检查

原文:https://towardsdatascience.com/guided-grad-cam-is-broken-sanity-checks-for-saliency-maps-73a9b7a2145c?source=collection_archive---------26-----------------------

某些理解 CNN 在看什么的技术不起作用。它们与模型的权重或训练数据没有关系,可能仅仅充当边缘检测器。

在本帖中,我们将讨论 NeurIPS 2018 年的论文“显著性图的健全性检查”,该论文证明了几种流行的显著性图方法实际上并没有提供对模型正在做什么的洞察。具有随机权重的模型和基于具有随机标签的数据训练的模型仍然会对某些显著性图技术产生看起来令人信服的“解释”,包括导向梯度图和导向反向传播,这意味着这些显著性图方法与模型的参数或训练数据无关。

论文

下面的文章应用了几个聪明的健全性检查来确定特定的技术是否提供了对模型的洞察:

Adebayo J,Gilmer J,Muelly M,Goodfellow I,Hardt M,Kim B .显著图的健全性检查。神经信息处理系统进展 2018(第 9505–9515 页)。

除非另有说明,本文中的任何引用都来自本文。

CNN 显著图(热图)技术

以下是本文评估的显著图技术:

  • 渐变:在这种技术中,我们可视化每个输入像素的变化对最终预测的改变程度。梯度是分数相对于输入图像的导数,有时被称为“显著性”或“反向传播”有关更多详细信息,请参见 CNN 热点图:显著性/反向传播CNN 热点图:梯度与去显著性和导向反向传播
  • SmoothGrad (SG): 这是一种通过对从输入的噪声拷贝产生的显著性图进行平均来平滑显著性图的技术。
  • 渐变 x 输入:这是输入和渐变的元素乘积。
  • 综合梯度(IG) :这种基于梯度的技术对输入的缩放版本求和。
  • 导向反向传播(GBP): 这种方法与梯度方法的区别仅在于 ReLU 非线性。详细解释见 CNN 热图:梯度 vs .去配置 vs .引导反向传播
  • grad cam:“grad cam 解释对应于类得分(logit)相对于最后一个卷积单元的特征图的梯度。”GradCAM 是基于 CAM 构建的。关于 CAM 的细节见 CNN 热图:职业激活映射
  • 引导式 GradCAM :这是一个带有引导式反向传播的 GradCAM 的元素级产品。

通过或未通过健全性检查

作者的简短总结:“在我们测试的方法中,梯度和梯度相机通过了健全性检查,而导向后投影和导向梯度相机失败了。”

这是个大新闻。制导 GradCAM 是一种特别流行的技术。第一篇介绍 GradCAM 和引导 GradCAM 的论文被引用了一千多次。

在接下来的章节中,我们将深入研究 Adebayo 等人设计的健全性检查的细节,以评估这些 CNN 显著图技术。

健全性检查 1:模型参数随机化测试

如果我们要使用显著性图来了解模型如何进行预测或为什么会出错,那么我们希望显著性图与模型在训练期间学习的参数有关。因此,第一组健全性检查包括随机化模型的权重:我们破坏模型已经学习的内容,并检查这种破坏是否影响显著性图。

如果随机化权重“破坏”了显著性图,这意味着显著性图取决于模型已经学习了什么(好)。如果随机化权重对显著性图没有影响,那么这意味着显著性图与模型已经学习的内容无关(坏。)

有两个子实验:(1)随机化模型中的所有权重,(2)一次随机化一层。

健全性检查 1 结果:

  • 通过:渐变,GradCAM
  • 失败:导向反向传播,导向梯度摄像

这是论文中的图 2:

这里,每一行对应不同的显著图方法。随着 CNN 的权重从顶层到底层逐渐随机化,我们看到了由不同方法产生的显著图解释。在最右边,已经实现了所有权重的完全随机化,我们希望显著图解释已经被破坏。

Adebayo 等人强调,显著图的定性视觉评估不足以理解显著图是否被破坏。因此,它们在图 3 和图 4 中提供了定量评估(未示出),报告了原始显著性图和随机化模型显著性图之间的等级相关性、HOGs 相似性和 SSIM。详见论文。

健全性检查 2:数据随机化测试

在数据随机化测试中,模型根据随机化的训练数据进行训练,对于这些数据,所有训练标签都已被置换,即,模型根据数据内容和数据标签之间没有关系的数据进行训练。也许一个狗的图像被标记为“鸟”,另一个狗的图像被标记为“飞机”,而一个飞机的图像被标记为“人”。

Adebayo 等人解释了这项测试的动机:

我们的数据随机化测试评估了解释方法对实例和标签之间关系的敏感性。对随机化标签不敏感的解释方法不可能解释依赖于数据生成过程中存在的实例和标签之间的关系的机制。

神经网络能够在标签已经被随机化的任务上做得很好的唯一方法是,如果网络记忆了训练数据集。在这种健全性检查中,模型被训练,直到它们已经记住足够的训练数据,以获得大于 95%的训练准确度。然而,他们的测试准确性永远不会比随机猜测更好,因为他们没有学到任何可概括的原则(在标签被随机化的数据集中没有可概括的原则可学。)

最后,使用刚刚描述的模型(在随机置换标签上训练的模型)和在真实标签上训练的不同模型,为测试集中的所有示例计算显著图解释。如果显著性图解释完全依赖于神经网络学习的可概括原则来解决任务,那么它应该看起来不同,这取决于模型是在真实标签上训练的还是在随机标签上训练的。

健全性检查 2 结果:

  • 通过/正常:渐变、渐变-SG、渐变-CAM
  • 失败:导向反向传播、导向梯度凸轮、集成梯度、梯度 x 输入

下面是图 5 所示的显著性图的定性比较:

在该图中,我们可以看到 CNN 在真实标签(顶行)和随机标签(底行)上对 MNIST 训练的数字 0 的显著性图解释。)对于有效的显著性方法,我们希望顶行(“真实标签”)看起来不错,底行(“随机标签”)看起来很糟糕。

和以前一样,重要的是不要仅仅依赖主观视觉评估。因此,作者也提供了定量的比较。在图 5 的另一部分中,我们可以看到在真实标签上训练的模型的显著性图与在随机标签上训练的模型的显著性图之间的等级相关性:

在这种情况下,我们希望等级相关性尽可能接近 0。等级相关的高值是不好的,因为它们意味着在真实标签上训练的模型和在随机标签上训练的模型之间的显著图是相似的。请注意,“Abs”意味着我们采用了显著性图解释的绝对值,而“无 Abs”意味着我们保持显著性图解释不变。我们可以看到,梯度在两种情况下都具有低相关性(好),而积分梯度在 Abs 情况下具有极高的相关性(差)。

边缘检测

在讨论中,Adebayo 等人提供了一个单层和池 CNN 模型的案例研究。这个案例研究表明,一些显著性方法可能像边缘检测器一样工作,因为图像中对应于边缘的区域具有与周围像素不同的激活模式,因此将在视觉上“突出”他们注意到,

当将突出显示的边缘解释为类别预测的解释时,人类观察者有确认偏差的风险。[……]根据我们的发现,将一些显著性方法解释为隐式实现无监督图像处理技术(类似于边缘检测)并非不合理。

总结

如果你在工作中使用显著图解释,请坚持使用梯度或普通梯度图,因为这些方法似乎依赖于训练模型的权重以及训练示例和它们的标签之间的关系。可能最好避免引导反向传播和引导梯度摄像,因为这些方法可能仅仅起到边缘检测器的作用,而不是可靠的解释。

特色图像

特色图片结合了罗丹的这幅《思想者》维基百科图片该知识库中的显著图。

原载于 2019 年 10 月 12 日http://glassboxmedicine.com

引导健忘的机器

原文:https://towardsdatascience.com/guiding-forgetful-machines-72d1b8949138?source=collection_archive---------17-----------------------

在说机器之前,先说人类。更像是孩子。

还记得学校里的乘法表吗?老实说,我很害怕。每天数学老师都会出现,开始背诵数字和它们的倍数。每天一张新桌子!几个星期后,我开始忘记基础知识。即使我能说出 12 * 5 是多少,我也没记住 5 * 2!然后,老师介绍了“躲避桌子”的概念——更可怕,但它帮助我比以前更好地记住了桌子。

为什么会这样?我现在意识到她确保了旧桌子的记忆不会离开我的小脑袋,即使我正在学习新的更复杂的东西。最终目标是让一个人能够“不断学习”。

持续学习是从一系列数据中连续学习的能力,建立在以前所学的基础上,并且能够记住那些所学的任务。这是人类能够做到的,也是人工智能机器的最终目标。在我们的大脑中,新皮层依赖于突触巩固&突触中编码的先前任务的知识,这些知识是不可改变的,因此在很长一段时间内是稳定的。

所以我想让我们来谈谈如何引导智能机器不要忘记!

我们可以从数据入手,假设有一个我们搭建的猫狗图像识别器(分类器)。现在,如果我们想给它添加一个‘dear’类(我们已经有了这个类的支持数据集图像),我们该如何着手呢?

We let the Task A (cat&dog) train, and weights are updated as inferred by the machine.

Now we put in the set 2 — Dear images to train & as the machine learns, it updates the weights

太好了,现在我们的机器可以识别三种东西了!一只猫/狗/亲爱的

希望一切正常,我们测试我们的模型…

And as expected the model predicts a fine result

正如预期的那样,模型预测了一个很好的结果!

现在让我们测试一些猫的图像🤞

但是这个失败了!怎么会?为什么?

原因:当添加新任务时,典型的深度神经网络容易出现灾难性遗忘。

我们需要的是能够随着时间的推移吸收新记忆的网络,我们需要努力克服这种限制,训练网络能够在他们很长时间没有经历过的任务上保持专业知识。我们基本上是在努力实现一般的智能 &它需要特工们记住许多不同的任务。持续学习是一项挑战,因为随着新任务/当前任务相关信息的临近,先前学习任务的知识有突然丢失的趋势。当一个网络在多项任务上按顺序训练时,会发生这种情况,导致网络中对任务 A 重要的权重发生变化,以满足最近任务 b 的目标。简单的方法是,我们可以-

  • 让所有数据在培训期间同时可用。
  • 交错数据又名多任务学习

为什么我们不能继续培训和再培训模特?—因为一个合适的算法将比每次需要学习新任务时从头重新训练模型更有效,而这是非常昂贵的$$$!!!也不是可扩展的解决方案。

哺乳动物的新大脑皮层依赖于特定任务 突触整合和先前任务的知识。它被编码在可塑性较小的突触中,因此长期稳定。科学家和研究人员做了大量的实验来了解我们大脑的内部运作。

oooh Brainnyy stuffz!

所以从聪明人那里得到了帮助,我指的是神经学家&把他们的知识与酷孩子、ML 的人结合起来

-生->神经网络突触巩固!

突触巩固(在人工神经网络中)意味着,随着机器学习更多的任务,对先前任务至关重要的突触的可塑性(或修改能力)会降低。这就引出了我们将要讨论的第一个解决方案!

弹性重量合并[EWC]

这种算法(用外行的话来说)减缓了对某些权重的学习,这些权重是基于它们对之前看到的任务的重要性。它使用贝叶斯网络和寻找局部最小值的概念。像 EWC 这样的许多方法使用类似的方法,如无遗忘学习、增量矩匹配等。

对 EWC 来说,的诀窍就是在为下一个任务训练时 锁定 用于解决第一个任务的权重。通过锁定,神经网络能够学习新的任务,而不会忘记以前的任务。

https://deepmind.com/blog/enabling-continual-learning-in-neural-networks/

嗯,不是字面上锁定权重,而是收敛到一个点,在这个点上,两个任务的 A & B 都有一个低误差,使用下面的损失函数—

cool looking loss function

EWC 确实有一个很大的缺点。如前所述,它是基于贝叶斯学习的,因此这些方法将任务 B 的参数限制在任务 A 的最优值周围的局部区域,以便最小程度地干扰任务 A 已经学习的内容。这可能会阻止神经网络在参数空间的偏远区域找到其他区域, 这可能包含任务 A & B 的联合问题分配的损失函数的更好的最小值。我们可以采取一种变通办法,例如存储大部分工作存储器,并在训练新任务时在训练期间重放它,但是这样会占用大量存储器以及大量训练时间。 考虑到图像处理大部分是在 GPU 上完成的,这是不会省钱的!

现在在神经生物学中,我们知道我们的大脑制造记忆——短期的(就像你脑中的声音为你朗读的),储存在一个地方。现在,当我们睡觉时,对你影响最大的事件的重要记忆将存储在大脑的其他部分,这些神经元以这种方式保持无弹性(不可修改),因此帮助我们记住学到的知识,并在必要时应用它们。

brain stuff for cool kids

让我们混合 EWC 和记忆细胞的牵连吧!(耶?!)

对抗性记忆网络

这是代表长期记忆的对立子空间的交集,网络中的长期记忆是为每个任务独立存储在记忆单元中的

任务相关记忆单元(浮点张量)。

https://www.ijcai.org/proceedings/2017/0311.pdf

记忆单元

  • 扮演类似于对抗性输入图像的角色
  • 抓住每堂课的精髓
  • 跨越网络参数空间中高级空间的交集

使用这些记忆单元,我们就有了一个针对每个任务的不同类的联合抽象长期记忆。

结论将是看不到最容易做到的解决方案,因为它可能有主要围绕 GPU 使用和内存和成本的缺点!而且,这对环境也不好。看这个

原来如此!你很好地理解了避免灾难性遗忘的重要性和方法。

如果您有任何问题,请随时向我发送 推文。

关注我 随时更新我的帖子。祝您愉快!🎉

H2O 无人驾驶人工智能:端到端的机器学习(对任何人!)

原文:https://towardsdatascience.com/h2o-driverless-ai-data-science-without-coding-43c0b43d9d20?source=collection_archive---------11-----------------------

Photo by Markus Spiske on Unsplash

做人工智能的人工智能——今天就开发你的第一个模型。

任何人都可以成为数据科学。不需要编码。

一. ||简介||

Photo by Frank Albrecht on Unsplash

当今世界,成为数据科学家并不局限于没有技术知识的人。虽然了解一点代码是推荐的,有时也是很重要的,但是你可以只凭直觉就能搞定。尤其是如果你在 H2O 的无人驾驶人工智能平台上。

如果你没有听说过 H2O.ai,它是创建开源机器学习平台 H2O 的公司,该平台被许多财富 500 强使用。H2O 旨在通过利用其用户友好的界面和模块化功能来创建效率驱动的机器学习环境。

注意 : 不要把 开源的 H2O AI 平台 无人驾驶 AI 混为一谈。 他们是两个独立的东西。我建议通读每一项的文档以了解更多信息。

H2O Open Source vs H2O DAI

H2O 3(开源)是 python/R 上的一个免费库,包含许多 ML 算法、模型和调优功能,使机器学习更加高效。
另一方面,无人驾驶人工智能是一种企业产品,拥有自己的平台、UI 和 UX。它就像一个 web 应用程序,可以使用旋钮和其他调整参数的可视化设备来创建和配置模型,本质上取代了实际编码模型的繁琐过程。

H2O 戴可以从头开始建立和验证人工智能模型,唯一需要的就是你的数据集。数据甚至不必进行清理或特征工程,因为 H2O DAI 可以处理这些任务,并允许您配置重要步骤的自动化,如特征缩放或对变量应用分类编码
事不宜迟,我将开始 H2O 无人驾驶人工智能教程。

二。||安装||

H2O 无人驾驶 AI 是一款企业产品,因此不建议个人购买。相反,您的公司应该在本地部署 H2O,并允许员工利用其强大的界面。然而,你和我都是独立的个体,出于本教程的目的,我使用 H2O 的 21 天免费试用版。如果你想跟进,但还没有准备好购买产品,你也可以这样做。

注意: 在你的机器上运行 h2o 有一些要求。建议您在 Linux 或 Windows 上运行 h2o,但是,您可以使用 docker 在 Mac 上运行它。你可以在这里学习如何使用*。我将详细介绍 Windows 的要求,因为这是我在本教程中使用的。如果你在 Linux (prod。环境推荐),遵循* 这些指令

从访问 h2o.ai 开始。寻找无人驾驶 AI 产品,填写表格,下载最新稳定版无人驾驶 AI DEB

visit the website and install H2O driverless AI

在 Windows 上,有 2 个附加要求:

所以,你需要首先安装 Ubuntu 18.04 for WSL(如果你“以管理员身份运行”(第一个链接中的说明)就可以激活)。完成后,在 Ubuntu 18.04 LTS 中运行以下命令来安装和运行 H2O-戴:

*# Install Driverless AI.  Expect installation of the .deb file to take several minutes on WSL.sudo dpkg -i dai_VERSION.deb

# Run Driverless AI.sudo -H -u dai /opt/h2oai/dai/run-dai.sh*

在 windows 上安装 H2O 戴的另一种方法是通过 Docker。你可以在这里找到那个的具体说明

三。||推出 H2O 无人驾驶 AI ||

在你的浏览器上,在 URL 框中输入下面的
localhost:12345

如果您在本地机器上安装了 H2O,这应该可以工作。运行实例的一般语法是
<服务器> :12345

在本地服务器上使用“localhost”。然后,它应该会自动启动登录页面,如下所示。

对于试用用户,登录 ID 和密码都是“h2oai”。登录详细信息,然后单击登录。您现在应该看到数据集页面,其中 H2O 将向您显示任何过去上传的数据或存储在系统上的其他文件。

四。||上传数据||

H2O 无人驾驶人工智能在获取数据集方面非常灵活。由于其大多数应用程序都基于实时/系列数据,H2O 有能力从许多来源提取信息,如亚马逊 S3 服务器、Hadoop 文件系统(通过本地上传)或 H2O 文件系统。

我从我的电脑上传了一个文件,这是电信客户流失数据库(来自 Kaggle)。该文件包含客户数据,每一列(除了客户 ID)都考虑了客户流失预测。

动词 (verb 的缩写)|| Autoviz ||

我的数据集一上传,我就可以访问 Autoviz 选项卡。当你通过 Autoviz 可视化一个数据集时,它会给你不同种类的可能的图表来总结你的数据。你所要做的就是上传你的数据,Autoviz 就可以使用了。

有些图形也是交互式的,可以像在 Plotly 中一样移动。所有的视频都是可以下载的,所以你可以把它们保存在你的服务器或者文件系统中。

Interactive graphs on Autoviz

不及物动词||项目||

要开始任何实验或活动,你需要有一个项目。因此,转到“项目”选项卡,它应该是这样的:

现在,您需要创建一个新项目,只需选择一个名称和描述即可。一旦完成,你将会有一个像下面这样的屏幕。这是您管理项目、数据和实验的地方。

使用链接数据集按钮将您的文件链接到该项目。我已经附上了我的客户流失数据集,它显示在左侧的培训下。如果右键单击数据集,我可以选择分割它。我需要分割数据集以进行训练和测试,因此我单击“分割”并获得以下选项:

我选择两个不同数据集的名称,选择一个目标列(我们想要预测的列),折叠和时间列(如果需要的话),并选择拆分比率。我选择 0.75,因为这将使我的测试集中有 2500 个值,这足以测试模型。

七。||实验||

每次你在一个数据集上运行一个特定的模型,就叫做实验。有了这个功能,H2O 使型号选择过程变得更加容易。你可以通过多次实验来选择合适的模型。转到您项目的仪表板,然后单击“新建实验”。

实验设置助手应该会打开。你现在可以开始填写这个实验的细节了。从名称开始,然后选择训练集。更多的细节将会显示出来(正如你在上面的 GIF 中看到的)。现在,您可以选择您的目标列、测试数据集,并且可以根据您的需要更改培训设置。根据您选择的设置,该型号的个性化描述将显示在屏幕的左侧。你甚至可以点击专家设置来更深入地改变其他参数。

Experiments on H2O Driverless AI

一旦你点击启动实验,一个新的屏幕将出现。你会看到类似这样的东西,如果你看到了,那就意味着 H2O 正在运行你的实验——直播!

随着实验的进行,它将开始显示模型的迭代数据,以及最重要的变量(可能会随着模型的进展而改变)。在右下角,您还可以在屏幕之间切换,以查看:

*~ ROC 曲线
Precision-Recall
Gain/Lift 图表
K-S 测试图(Kolmogorov-Smirnov)
CPU 使用率。*

一旦您的实验完成,您应该能够看到这样的屏幕,您的 CPU 使用选项卡将更改为摘要:

在变量重要性的正上方,有一个可供选择的操作菜单。屏幕上唯一不可用的选项是部署。这是有原因的。这是因为我们还没有下载我们的 MOJO/POJO 文件。我们将在最后做那件事。首先,我们来解读一下这个模型。

八。||解释模型||

导航回实验选项卡并找到您的实验。再次打开它,点击按钮解释这个模型。 翻译窗口将开始加载,可能需要一些时间。它应该是这样的:

一旦解释页面被加载到 100%,您将会得到一个解释模型的菜单。也可以通过 MLI 选项卡访问该页面。正如你在下面的 gif 图中看到的,页面左侧有许多标签。

  • 摘要:向我们概述了 MLI(机器学习解释器)以及模型的一些参数,例如其最重要的变量及其定义、所使用的石灰聚类的数量、代理模型的摘要。下面的 GIF 显示了一个示例摘要页面:

Summary of MLI

  • 戴模型:这里可以看到无人驾驶 AI 开发的模型。在 DAI 模型中,您可以看到该模型中功能重要性的全貌,当您将鼠标悬停在变量上时,每个变量都会弹出解释。它还可以向您显示合同变量的部分依赖关系图,此外,您可以从我们的实验中看到带有完整混淆矩阵的不同影响分析。

  • 代理模型:除了 DAI 模型分析,我们还可以获得关于代理模型的信息。这些位于代理选项卡中,允许我们查看来自其他模型的参数和数据,如 K-Lime 聚类、决策树模型和随机森林模型。
    在随机森林中,我们还可以看到特征重要性、部分相关性和局部相关性。

  • 仪表盘:下面是 MLI 仪表盘的样子。它在一个页面上包含了我们所有重要的图表和参数,因此我们可以快速导航到我们想要的位置。

九。||诊断||

Diagnostics 选项卡包含一个页面,其中包含某些准确性指标和图形,可用于在运行实验后诊断模型。它包含了 ROC 曲线、精确回忆曲线、收益/提升、K-S 图和真/假阳性/阴性混淆矩阵的所有内容。
诊断页面如下所示:

X.||部署||

正如我上面提到的,部署是不可能的,因为我们没有 MOJO 文件。要在本地或云服务器上部署您的模型,您首先需要创建 MOJO 文件。根据他们的网站,“ H2O 生成的 MOJO 和 POJO 模型旨在方便地嵌入任何 Java 环境。

因此,回到实验选项卡并加载您的实验。您将再次看到带有绿色选项按钮的菜单。继续点击按钮建立 MOJO 评分管道。它现在会在你的左边显示屏幕,并开始建立你的 MOJO 管道。

一旦您的 MOJO Pipeline 可用,您将可以选择部署您的模型。你可以选择把它放在 Amazon Lambda 服务器上,也可以使用 REST API 服务器。一旦你选择了你的目的地,H2O 将自动部署你的模型,并给你它的位置。

XI。||资源和结论||

“资源”选项卡有许多选项可用于。首先,它会有一个选项带你去无人驾驶人工智能文档。它还包含下载用于 R 和 Python 的 H2O 无人驾驶 AI 客户端 API 的链接。如果你想了解更多关于无人驾驶人工智能的能力,并在你的业务中使用它,这是非常有用的。

最后,我只想提一下,我与开发该产品的 H2O 公司没有任何关系。我是他们产品的用户,我认为发布这个教程是个好主意,因为目前还没有很多这样的产品。我花了一段时间来学习 H2O 无人驾驶人工智能,我想我会通过这个教程让其他人更容易。
欢迎对这篇文章发表评论,问我关于我的工作的任何问题,或者我打算如何在我的个人/工作项目中使用 H2O。我可能会在未来写另一篇帖子,将无人驾驶人工智能与 H2O 3(开源)进行比较,任何对此的反馈都将是巨大的。

感谢阅读。我希望这能以难以想象的方式帮助你。

更多关于 H2O 无人驾驶 AI 的信息和教程,请访问 h2o.ai

Catch H2O.ai on Twitter!

Photo by Borna Bevanda on Unsplash

十二。||参考资料||

H2O 适合没有经验的用户

原文:https://towardsdatascience.com/h2o-for-inexperienced-users-7bc064124264?source=collection_archive---------10-----------------------

一些背景:我是一名高三学生,2018 年夏天,我在 H2O.ai 实习。除了吴恩达在 Coursera 上的机器学习入门课程和他的几门深度学习课程之外,我没有任何 ML 经验,最初我发现自己有点被 H2O 在其开源和企业软件中提供的各种新算法所淹没。但是通过探索各种资源,到夏天结束时,我已经能够在 Kaggle 上的 TGS 盐识别挑战中使用无人驾驶人工智能和 H2O-3 算法。在这篇博文中,我将讲述我在 H2O.ai 工作期间的经历和收获,以及为那些新手提供的学习 H2O 和数据科学的资源。

入门

H2O-3

为了开始使用 H2O,我首先下载了 H2O-3 包以及 Python 客户端。尽管安装说明很简单,但在安装和使用 Python 客户端时,请确保:

  1. H2O Python 安装和下载的包版本匹配。
  2. H2O 运行的是 Java 8

如果你不希望使用 Python,H2O 3 有一个 GUI API,H2O 流,可以在浏览器上访问;python 客户端易于使用且灵活,具有直观的命令和其他 python 优势,如 numpy、pandas 和 opencv。

让 H2O 3 号运行起来后,下一个任务是熟悉它的功能。对此有用的资源包括:

  • 文档:侧边栏中的页面绝对值得一读(随意跳过或浏览)。该文件提供了一个全面的看法,你可以做什么与 H2O-3,以及细节和解释有关的实施。在 R 和 Python 的一些页面上都可以找到示例代码。如果示例代码在某些页面上不可用——例如,在深度学习页面上——它可能在 GitHub 存储库中可用(很可能在 tutorials 文件夹中;如果不容易找到,您可以搜索整个存储库)
  • H2O-3 GitHub :浏览你心目中项目的教程。再看一些,看看你能包括的其他函数和算法。我发现教程中的示例代码对于学习如何使用每个函数非常有用。源代码读起来很有趣。如果你想了解每件事是如何实现的,读一读它;尽管要理解如何使用所有的东西,浏览文档会更容易,因为源代码阅读和解释起来相当长。
  • Coursera : H2O 在 Coursera 上有一门课程,你可以免费获取资料,但需要为作业付费。虽然我没有尝试过,但是如果您喜欢更结构化的方法,可以尝试一下。

随着我对 H2O-3 越来越熟悉,我浏览了打印到终端窗口的日志,在那里,当我运行各种算法时,H2O 实例通过 Java 启动。这也非常有助于理解它在做什么,监控进展,并在数据或模型超参数中找到潜在的改进。

从 H2O 无人驾驶 AI 开始

我开始使用无人驾驶 AI(戴)的方式与 3 相同。我按照安装说明下载安装了戴。这非常简单,但是值得注意的是,如果您的机器上没有足够的 RAM(指令要求 DAI 至少运行 10 gb),那么无论如何都要尝试运行 DAI,它仍然可以工作。我在一台内存为 8 gb 的 Mac 上分配了 4 gb,它仍然能够运行。

为了熟悉戴,首先浏览一下文档侧栏中的所有页面。模型解释和转换是戴所独有的。为了理解模型解释,我试图通过查看其 GitHub 库本文来理解 LIME。原文也值得一读。

戴使用起来很直观。很容易理解如何使用它。毕竟,它是为非数据科学家打造的!

组装

H2O-3 AutoML(以及一些固有集合模型)和 DAI 集合模型来提高性能。在 Kaggle 上也经常使用集合模型。这篇文章从概念上解释了集成,这篇博文展示了如何实现它。相关:【mlwave.com是一个从顶级 Kagglers 和数据科学家那里学习机器学习概念、用途和工作流的绝佳资源。强烈推荐阅读;这些文章非常有趣,可能对您的数据科学项目有所帮助。

小项目

我从印度国家股票交易所下载了塔塔钢铁 24 个月的股票数据,开始用戴和 3 做日内交易的实验。我打算使用前一天的标记和当天的开盘价来预测当天的收盘价。

我第一次处理这个数据集是通过在某一天移动标记列中的元素,使得当天的收盘价与前一天的标记在同一行中——这不是处理时间序列的正确方法;戴的时间序列特征对数据进行了适当的自动处理。然后我在这个数据集上运行了 DAI。由于 H2O-3 算法运行得更快,当戴运行时,我也能够在这个数据集上训练多个 H2O-3 模型。使用 3 算法的训练分数约为 10,使用戴算法的训练分数约为 9.1,在小型测试数据集上的测试分数约为 213,这使得该模型对任何日内交易应用程序都没有用。

Initial DAI model without time series

在寻找提高模型性能的想法时,我找到了 Marios Michailidis 关于如何在 Kaggle 上使用戴的视频。他使用 DAI 和如下所示的其他算法来堆叠模型,并充分利用 DAI 的特征工程:

在试图遵循这一点,我首先饲料戴衍生数据与额外的功能(但与地面真实价格值即。来自原始数据集的接近价格列)到显示更多多样性的各种 3 模型,然后将它们的预测馈送到戴(最终模型)。这在训练阶段更有希望,RMSE 约为 3.5,但在得分约为 288 的测试数据集上表现较差。这是不正确的堆叠。翻翻前面提到的博文,看看怎么做才正确。

后来,我在未编辑的数据集上尝试了戴的时间序列特性,其性能显著提高到约 0.05 训练和约 6 测试。然而,即使性能有所提高,模型在测试集上的显著性能下降表明它没有足够的数据来创建准确的模型。

DAI model with time series

卡格尔

在试用并熟悉了 3 和戴之后,由于我无法找到足够的数据让塔塔钢铁做出更好的模型,所以我转向了数据科学竞赛平台【】Kaggle 。TGS 盐鉴定竞赛看起来很有趣,而且是一个相当大的数据集。这场比赛涉及在给定地震数据(以图像的形式)和每个图像的深度的情况下,识别地下目标是否是盐,换句话说,就是盐在地震图像上的位置和边界。

我强烈建议你看看 Kaggle,即使你不打算参加比赛,因为它为数据科学新手提供了大量资源,包括数据集讨论(初学者的部分)、计算资源和代码(内核)。

有用的 Python 模块

Python 有各种各样的模块,使得数据操作更加容易。看看 numpypandas 进行计算和数据操作, csv 进行 csv 读写,以及 opencv 处理图像。

数据集生成

因为 H2O 不接受图像数据,所以我生成了以下列格式的数据集,其中每一行都对应于图像上的一个像素,使用的是这个脚本:

Id(字符串)

深度(真实)

灰度像素值(实数)

盐地真相(布尔/枚举)

将这些数据提供给戴非常简单;我刚刚用上传文件按钮上传了它。然而,对于 H2O-3,它需要被压缩,否则 Python 会抛出[Errno 22]无效参数。注意: Python 3 似乎很难处理超过 2–4gb 的文件;H2O.ai 会通过升级他们的导入库来修复这个 bug。

python 脚本创建了 3600 个图像像素的训练集、400 个图像像素的验证集和 18000 个图像像素的测试集;这些测试预测将被提交到 Kaggle 上。

戴和 3 算法

为了防止算法记住数据,在训练之前删除了 id 列。由于训练和测试数据集相当大(分别约 4100 万和 1.83 亿行),在没有 GPU 的情况下,戴花了很长时间进行训练。这次,我尝试了 H2O-3 深度学习估计器。对于两者,我都使用 AUC 指标作为计分器,并为 DAI 最终管道启用 Tensorflow 模型和 RuleFit 支持(在专家设置菜单中)。戴获得了大约 0.75 训练 AUC,而 3 深度学习获得了大约 0.72。

预测的像素值被转换成映射到 id 的 RLE 编码,如比赛计分员使用这个脚本所要求的。在这里找到的 numpy 数组到 rle 函数的功劳拉赫林。由 Kaggle 评分的深度学习和 DAI 模型在测试数据集上的交集(IoU) 分数如下:

模型:H2O-3 深度学习,IoU: 0.263

型号:戴,借据:0.176

First salt detection DAI model trained on 2 features

缺乏特色

潜在的模型准确性的最大障碍是缺乏特征。数据集的每个像素只有两个要素(因为 id 已被删除)。通过增加更多的特征,包括像素位置、相邻像素灰度值以及图片灰度最大值、最小值和平均值,这一点得到了弥补。

然而,随着训练、验证和测试文件(尤其是测试文件)从 4 列膨胀到 13 列,这暴露了更多的硬件限制。戴运行时间长,我的笔记本电脑 RAM 用完,Python 不支持上传大文件,都拖慢进度。

资源

Kaggle 论坛对于改进模型的可能途径非常有用,无论是通过理解和扩充数据,探索更合适的模型,还是精炼模型。除此之外,每当出现问题时,谷歌搜索通常会让我找到有一些答案(或至少有趣)的研究论文、Stackoverflow 或 Kaggle 讨论。

我还从 H2O 的 Megan 那里得到了很多关于如何提高模型性能的想法和建议,包括额外的特性和自动编码(见下文)。H2O 也是您学习数据科学和改进模型的绝佳资源。

向前发展的想法

特征工程通常是 Kaggle 竞赛的关键部分(正如我从 Kaggle 论坛上了解到的那样),因此包含更多的特征很可能会提高模型性能。这些特征可以包括到沙簇的像素距离、沙簇的一般形状,或者可能是更多邻居的盐真相。尝试找到更多功能。

自动编码器或 GLRM 也可以用于对输入图像和/或预测进行去噪。在检查初始(2 个特征)DAI 序列预测时,我注意到有很多噪声,特别是在应该是空的图像上。Kaggle 已经实现了 IoU 指标,因此如果在应该为空的图像上预测到任何 salt,则该图像将得到 0 分。通过在训练预测和训练集上训练的 H2OAutoEncoderEstimator 运行测试预测应该减少噪声并去除否则为空的图像上的杂散像素。

空图像也可以通过让输入图像通过另一个模型来捕捉,该模型首先检查它是否是空的。如果预测为空,而不是冒几个像素的风险,则在该图像上将有 0 个真实像素被预测。

更适合图像的其他模型也可能提供更好的解决方案。从论坛可以看出,UNets 在竞争中似乎相当成功。其他卷积网络也应该在性能和速度上提供超过常规深度神经网络模型的提升。正如 Sri 所建议的,GAN 方法也可以工作,因为模型需要生成掩模图像。

就速度而言, Cython 似乎是加速数据集处理的一个有前途的途径。更高的效率和更少的硬件限制也将使集合(堆叠/混合)成为提高模型性能的更可行的途径。

如果您有时间、愿望和计算资源,请拿起指挥棒,参加竞赛!

杂学

命令行技巧

熟悉命令行虽然不是使用 H2O 所必需的,但可以使大多数任务变得更容易。对我来说,知道如何浏览文件、启动 Java、使用 Python 和 pip、连接到远程机器并在其上运行任务就足够了。

远程机器

如果您在远程机器上使用 DAI 或 H2O(或其他任何东西),这些命令可能会有所帮助:

下载到机器上

ssh:连接到机器的命令行

Byobu 可以用来保存远程会话(即使在断开连接的情况下,你也可以让 DAI 或 H2O-3 在远程机器上运行),并且非常易于使用。

用于机器学习的机器

如前所述,我在生存能力和速度方面遇到了许多硬件限制。为机器学习设置一台机器将使一切变得更容易和更快。这篇文章可能会对你有所帮助。GPU 注意:GPU 的指数级加速 H2O 性能,但 H2O 的 GPU 并行化是使用 CUDA 构建的(ML 中使用的许多其他脚本也是如此),所以当决定使用 GPU 时,请使用 CUDA。

前进

在熟悉 H2O 之后,下一个好的步骤是探索和理解更多的算法,这样你就可以将合适的算法应用到用例中。这也可以改善模型集合的结果。此外,研究更多的数据科学可以更好地理解和操作数据集,这也将提高模型性能。最后,只是阅读论文、Kaggle 讨论和跟上 H2O 文档将是学习更多和产生新想法的有趣和有趣的方式。

管理数据科学代码库中复杂性的更好习惯

原文:https://towardsdatascience.com/habits-for-managing-complexity-in-data-science-codebases-5a16314c3737?source=collection_archive---------33-----------------------

现实世界中的 DS

如何通过更好的编码习惯变得更加敏捷和高效

Photo credit: https://www.pexels.com/@fox-58267

如果你尝试过机器学习或数据科学,你会知道代码会很快变得混乱。

Actual footage of me writing data science code

通常,训练 ML 模型的代码是在 Jupyter 笔记本中编写的,它充满了(I)副作用(例如打印语句、漂亮打印的数据帧、数据可视化)和(ii)没有任何抽象、模块化和自动化测试的粘合代码。

虽然这对于旨在教授人们机器学习过程的笔记本电脑来说可能没什么问题,但在实际项目中,这可能会导致难以维护的混乱。缺乏良好的编码习惯使得代码难以理解,因此修改代码变得痛苦且容易出错。这使得数据科学家和开发人员越来越难以发展他们的 ML 解决方案来适应业务需求。

复杂性是不可避免的,但它是可以划分的。在我们的家中,如果我们不积极组织和合理安排物品摆放的位置、原因和方式,就会造成混乱,原本简单的任务(如找钥匙)就会变得不必要的耗时和令人沮丧。这同样适用于我们的代码库。

每当我们以添加另一个移动部分的方式编写代码时,我们就增加了复杂性,并且在我们的头脑中增加了更多的东西。虽然我们不能——也不应该试图——逃避问题的本质复杂性,但我们经常通过糟糕的编码实践增加不必要的意外复杂性和不必要的认知负荷。

如果我们可以通过应用下面列出的原则来控制复杂性,我们的大脑就可以解放出来解决我们想要解决的实际问题。以此为背景,我们将与分享一些识别增加代码复杂性的坏习惯****以及帮助我们管理复杂性的习惯的技巧。

管理复杂性的五个习惯

“管理软件复杂性的最重要的技术之一是设计系统,使得开发人员在任何给定的时间只需要面对整体复杂性的一小部分。” ( 约翰·奥特)

1.保持代码整洁

不干净的代码使代码难以理解和修改,从而增加了复杂性。因此,更改代码以响应业务需求变得越来越困难,有时甚至是不可能的。

一个常见的坏习惯(或“代码味”)是在代码库中留下死代码。死代码是被执行的代码,但是它的结果从来没有在任何其他计算中使用过。死代码是开发人员在编码时必须记住的另一个不相关的东西。例如,比较以下两个代码示例:

See how much easier it is to read the second code sample?

干净的代码实践已经被广泛地用几种语言写成,包括 T2、Python 和 T3。我们将这些干净的代码原则用于机器学习环境,你可以在这个 干净代码-ml 报告 中找到它们。

2.使用函数来抽象复杂性

函数通过抽象出复杂的实现细节并用一个更简单的表示——它的名字——来代替它们,从而简化了我们的代码。

想象你在一家餐馆里。给你一份菜单。这份菜单不是告诉你菜名,而是详细说明每一道菜的烹饪方法。例如,这样的一道菜是:

What dinner menus look like without abstraction

如果菜单隐藏了菜谱中的所有步骤(即实现细节),而是给我们一道菜的名字(即一个接口,一道菜的抽象),那对我们来说就容易多了。(回答:那是扁豆汤

为了说明这一点,这里有一个代码样本,来自 Kaggle 的 Titanic competition 中的一个笔记本,在重构到一个函数之前和之后。

通过将复杂性抽象成函数,我们使代码可读、可测试和可重用。

当我们重构功能时,我们的整个笔记本都可以简化,变得更加优雅:

Life is happier when you read code that tells you what they do, and not how they do it

我们的精神开销现在大大减少了。我们不再被迫处理许多许多行的实现细节来理解整个流程。相反,抽象(即函数)抽象掉了复杂性,告诉我们它们做了什么 ,让我们不必花心思去弄清楚它们是如何做的。****

3.尽快从 Jupyter 的笔记本里偷出代码

在室内设计中,有一个概念(“平面定律”),即“家庭或办公室中的任何平面都容易积聚杂物。”Jupyter 笔记本是 ML 世界的平面。

当然,Jupyter 笔记本对于快速原型制作非常有用。但是我们倾向于把很多东西放在这里——粘合代码、打印语句、美化的打印语句(df.describe()df.plot())、未使用的导入语句甚至堆栈跟踪(🙈).尽管我们的意图是好的,但是只要笔记本还在,脏乱就会越积越多。

笔记本很有用,因为它们能给我们快速的反馈,当我们得到新的数据集和新的问题时,这通常是我们想要的。然而,笔记本变得越长,就越难得到关于我们的改变是否奏效的反馈****

例如,当我们更改一行代码时,确保一切正常的唯一方法是重启并重新运行整个笔记本。我们被迫承担整个代码库的复杂性,即使我们只想做其中的一小部分。

相比之下,如果我们将代码提取到函数和 Python 模块中,并且如果我们有单元测试,测试运行程序将在几秒钟内给我们反馈我们的更改,即使有数百个函数。

The more code we have, the harder it is for Jupyter notebooks to give us fast feedback on whether everything is working as expected.

因此,我们的目标是尽早将代码从笔记本转移到 Python 模块和包中。这样,他们可以在单元测试和领域边界的安全范围内休息。这将有助于通过提供一个逻辑地组织代码和测试的结构来管理复杂性,并使我们更容易发展我们的 ML 解决方案。

****那么,我们如何将代码从 Jupyter 笔记本中移出呢?假设您已经在 Jupyter 笔记本中编写了代码,您可以遵循以下流程:

The refactoring cycle for Jupyter notebooks

这个过程中每一步的细节可以在clean-code-ml repo中找到。

4.应用测试驱动开发

到目前为止,我们已经讨论了在代码已经写在笔记本上之后编写测试。这个建议并不理想,但是它仍然比没有单元测试好得多。

有一种神话认为我们不能将测试驱动开发(TDD)应用于机器学习项目。对我们来说,这完全是不真实的。在任何机器学习项目中,大部分代码都与数据转换有关(例如,数据清理、特征工程),一小部分代码库是实际的机器学习。这种数据转换可以写成纯函数,为相同的输入返回相同的输出,这样,我们可以应用 TDD 并获得的好处。例如,TDD 可以帮助我们将大而复杂的数据转换分解成较小的问题,这样我们就可以一次解决一个问题。

至于测试代码的实际机器学习部分是否如我们预期的那样工作,我们可以编写功能测试来断言模型的度量(例如,准确度、精确度等)高于我们预期的阈值。换句话说,这些测试断言模型按照我们的期望运行(因此得名,功能测试)。这里有一个测试的例子:****

Example of a automated functional test for ML models

当我们写完这些单元测试和功能测试后,我们可以让它们在团队成员推送代码时在持续集成(CI)管道上运行。这将允许我们在错误被引入我们的代码库时就捕捉它们,而不是在几天或几周后。

5.小而频繁地提交

当我们不进行小而频繁的 git 提交时,我们增加了不必要的精神开销。当我们正在处理一个问题时,对早期问题的更改仍然显示为未提交。这在视觉和潜意识上分散了我们的注意力;这让我们更难专注于当前的问题。

例如,看看下面的第一个和第二个图像。你能找出我们在做哪个功能吗?哪个图像给了你更轻松的时间?

**********

当我们频繁地进行小规模提交时,我们会获得以下好处:

  • 减少视觉干扰和认知负荷。
  • 如果工作代码已经提交,我们就不必担心会意外破坏它。
  • 除了红绿重构,我们还可以红绿红绿还原。如果我们无意中破坏了一些东西,我们可以很容易地退回到最近的提交,并再次尝试。这样我们就不用浪费时间去解决我们在试图解决本质问题时无意中制造的问题。

那么,多小的提交才算足够小呢?当有一组逻辑上相关的变更并通过测试时,尝试提交。一种技术是在我们的提交消息中寻找单词“and ”,例如“添加探索性数据分析,将句子拆分成标记,重构模型训练代码”。这三个更改中的每一个都可以分成三个逻辑提交。在这种情况下,您可以使用 git add -p 将代码分成小批提交。

结论

我们希望这篇文章对你有所帮助。这些习惯帮助我们管理机器学习和数据科学项目中的复杂性,并且帮助我们在项目中保持敏捷和高效。

如果您对此有其他想法和建议,请随时发表评论:-)

P.S .原贴 ThoughtWorks Insights:https://www . ThoughtWorks . com/Insights/blog/coding-habits-data-scientists

P.P.S .如果你对组织如何采用连续交付实践来帮助机器学习实践者和项目变得敏捷的例子感兴趣,你可以查看我们关于 机器学习连续交付(CD4ML) 的文章。

P.P.P.S .特别感谢 Aditi、Chandni、Danilo、Gareth 和 Jonathan 对本文的反馈!

黑客马拉松!和我一起准备🤓😎

原文:https://towardsdatascience.com/hackathon-get-ready-with-me-3192c7690cb7?source=collection_archive---------13-----------------------

尤其是对于一个有抱负的数据科学家来说

黑客马拉松是一项竞赛,包括程序员、开发人员和图形设计师在内的各种人在短时间内合作设计软件项目。黑客马拉松的目标是在活动结束时创造一个功能产品。

上个月,我有机会参加由 Junction Ltd .举办的 JunctionX Seoul Hackathon。我们的团队开发了一个 iOS 应用程序,通过图像搜索引擎为韩国美容产品带来了优化的购物服务体验。该应用程序可以帮助那些想探索韩国美容产品,但由于明显的语言障碍而不知道该尝试什么的旅行者。用户只需扫描产品就能找到有用的数据,这些信息会被翻译成当地语言。还有一个搜索历史页面,可用于进一步定制服务。你可以在这里找到更多关于的信息。

The app, Skana

然而,我不想谈论我做了什么,我想分享我在这个过程中学到的东西。所以今天,我要谈谈你应该申请参加黑客马拉松的 4 个原因(尤其是如果你是一名有抱负的数据科学家),你应该如何准备以及我的一些建议。我希望这篇文章能激励你像我一样走出自己的舒适区,获得一些深刻的启发。

1.为什么是黑客马拉松

如果你之前没有尝试过黑客马拉松或者编程比赛,说你问我是否值得一试,我会毫不犹豫的点头。以下是你应该参加黑客马拉松的 4 个理由。

超越“建模”

我们,数据科学学习者,倾向于单独工作或单独学习。我们倾向于将大部分时间投入到数据预处理和搜索中。而我们把大部分精力都倾注在研究机器学习或者深度学习算法上。我们的项目通常从导入数据开始(或者有时我们自己构建数据),以评估预测结束。

可悲的是,世界上几乎所有现实世界的项目都不是这样的。我们不是单独行动的。我们和其他团队成员一起工作。从数据库到部署和产品管理,所有的过程都应该通过协作来完成。拥有超越“建模”领域的工具包对有志之士来说是一大优势。(许多文章都指出了这一点,你也可以在这里找到一个)现在重要的问题是,我们在哪里可以学习和体验这一点?****

“Un 像比赛,没人给你两个。csv 文件称为培训和测试和一个很好的书面评估指标。几乎 80%的工作都花在了定义问题、获取和处理数据上。剩下的 20%的精力用于纯粹的建模和部署。”

黑客马拉松可以是一个与他人合作并进行真实项目的好机会。虽然有一些限制,但你仍然可以学习如何与他人交流(他们不像你一样有很多机器学习方面的知识),并了解发布实际产品的整体工作流程。如果你有机会和一个在机器学习方面比你懂得更多的人在一起,我相信这也是一个挑战你极限的好时机。

商业思维比你想象的更重要

这个项目的第一步将是决定建造什么。而且我可以说一半的胜算都是在这里决定的。你应该有个好的开始。实施也是一个关键点,但业务价值起着重要作用。如果它被忽视了,你的工作只能是炫耀你的技术能力。

"L ikewise,数据科学家是被雇佣来创造商业价值的,而不仅仅是建立模型。问问你自己:我的工作成果将如何影响公司的决策?我要怎么做才能让这种效果最大化?凭借这种创业精神,第三次浪潮数据科学家不仅能产生可操作的见解,还能寻求带来真正的变化。”

你会看到很多人已经指出了商业思维的重要性。发现用户隐藏的需求,观察市场中的一个问题。用你的技术知识提出解决方案。开发一项可以盈利的服务。在黑客马拉松上,你被要求带着这个观点进行深入的思考和讨论。

我听说过一个家伙赢得了超过 15 次的编程比赛。在赢得谷歌的一场比赛后,他退出了自己的“猎奖”生涯。你知道他的秘密是什么吗?这只是商业意识和一点点智慧。通过制造一个聪明而有创意的产品,他让人们大喊“太棒了!”这肯定会在面板上留下印象。因此,如果你正在寻找一个额外的获胜秘诀,拥有一些机智的商业价值观会是一个很好的奖励。

处理极端压力的绝佳机会

黑客马拉松的目标是在短时间内(通常是 2 到 3 天)创造一个功能产品。在这些日子里,你被要求展示你的产品的原型或演示。都是时间有限,资源有限,精力有限的问题。有时,你可能会遇到事情出错的情况,你必须立即找到解决方案。有时候你必须优先考虑你的工作,这意味着什么先来,什么时候停下来。你会感受到完成所有任务和不成为团队负担的巨大压力。和久而久之,变得完全饥饿和疲惫是不可避免的!(更像是能量耗尽或耗尽,直到最终“入睡”)。

如果你和我一样,在极度紧张的时刻会冻僵,你甚至会被比赛大厅的空气淹没。这是我第一次参加黑客马拉松,所以我经历了几次大脑瘫痪。我不得不呼吸一些新鲜空气,放松一下来缓解紧张。但这也成为我学习如何应对压力的一个好机会。因为在工作场所不可避免地会遇到一些意想不到的问题,我们必须处理好这些棘手的问题。

“你好,世界”的实时性

认识新朋友也是一大乐事,尤其是如果是志同道合的人。在黑客马拉松上,你可以遇到来自不同地区、有不同专业但有相同兴趣的各种人。他们可以是网页开发人员、应用程序开发人员或设计师,但他们是愿意在周末开发一些很酷的东西的人。

我遇到了从俄罗斯来韩国参加这个活动的人。我还遇到了一位在韩国学习计算机科学的乌克兰女士。有来自丹麦、法国、中国和日本的人。认识新朋友本身就是一大乐事。但更重要的是,我可以听到他们有什么样的痛点,他们真正热衷的是什么。通过与其他参与者聊天,我可以在编程方面开阔眼界。这就是为什么我认为你应该尝试一个主题丰富的黑客马拉松,而不是专注于数据科学领域。

此外,关心别人做什么也是件好事。尽管你会忙得没有时间去额外照顾别人,但这将帮助你理解我上面提到的整个过程。不管怎样,我们是来学习新东西的!

Photos by JunctionXSeoul and Me giving a presentation (on the right bottom)

2.如何准备

那么,现在黑客马拉松听起来值得一试吗?如果是这样,那么你的下一个问题可能是你应该如何准备。实际上,没什么。只管去做吧。不管你有什么技能,不要犹豫去申请。黑客马拉松不仅仅是专业人士的舞台。但是如果你想在这一天之前准备一些东西,那么我想列出一些我认为有用和适用的技巧。

后端和部署

这不是一个以导入数据开始,以一些评估图结束的项目。您需要根据您的团队项目收集数据并构建数据库。在您完成数据分析或建模部分后,您必须将您的模型传递给前端。或者你可能需要自己在网上发布你的作品。因此,在你的工具包中有数据库和 Flask 对于这个活动来说是一个巨大的资产。

如果你对数据库完全陌生,你可以从理解SQL 和NoSQL 的区别开始学习。这里有一个针对初学者的简洁的 SQL 课程 但是除此之外还有很多关于数据库的教程。所以去根据自己的口味挑选吧。

Flask 是用 Python 编写的微框架,简单易学,对模型部署非常有用。这里有一个关于 如何用 Flask 部署 Keras 深度学习模型的优秀教程,作者是本·韦伯。你也可以在这里找到烧瓶 的 系列视频课程。

API 和云服务

每个黑客马拉松的条件可能不同,但我参加的那个高度依赖于 API 和云服务。有几个子轨道,参与者被要求使用特定的 API 来参与给定的轨道。但是除了这个条件之外,你还需要自己收集数据。你将从哪里获得数据?而用于训练的计算能力呢?你可能会把装有 GPU 的“超级计算机”留在家里。

因此,最好有从 API 获取数据并以 JSON 格式处理数据的经验。如果你是 API 新手, 这篇文章 可以向你解释 API 是怎么一回事。

能够使用像 AWS 或谷歌云 GPU 的云服务也是必要的。这里是 AWS EC2 的官方指南 但是这里是 AI 学院的 一个友好的视频 。你还可以找到更详细的初学者教程 作者迈克尔·加拉内克

充满能量的你

睡眠充足。控制你的状况。这不是开玩笑。比赛期间,我总共睡了 4 个小时。睡得少可能是一个好策略,但你需要在进入大厅时保持良好的状态。此外,一个颈枕和一条用来小睡的毯子可以和“烧瓶”或“AWS”一样有用。😂😂

Photos by JunctionXSeoul

3.我最后的小建议

最后,这里是我的一些小技巧。

如何组建你的团队

如果你是一个人申请,你必须从底层建立你的团队。可以有一个像 Slack 这样的社交网络平台,你可以从其他申请人那里获得信息,并在活动开始前组建一个团队。你可能有机会加入一个有空缺的预制团队。

如果你有一个关于你想开发什么的想法,把它分成几个部分,然后寻找能承担每个部分的成员。你需要找到一个与我们技能不同的人(比如数据建模)。你需要具备的成员通常是后端工程师、web/app 开发者和 UI/UX 设计师。

诚实面对你能做的事情

你可能认为你的能力不足以做这件事。所以你可能想隐藏你的水平或者假装比你知道的更多。但是你真的不需要。黑客马拉松对所有人开放。不管你对编程了解多少,总有一部分只能由你来填补!旁边的人比你懂得多吗?厉害!你有更多的机会学习。寻求帮助是“帮助”你的团队的更好方式,而不是独自奋斗,浪费宝贵的时间。

享受,享受,享受!

不仅仅是赢。虽然你应该在这段时间里尽你所能,但不要失去你脸上的笑容。享受学习的时间,结识新朋友,和他们一起工作。享受创造和开发世界上不存在的新事物的时间。享受压力和超越极限的时光。要求会非常高。然而,在活动结束时,即使你没有获奖,你也会带着新的想法和教训回家。你会发现自己像我一样期待着下一次黑客马拉松。😉

这个故事引起你的共鸣了吗?请与我们分享您的见解。我总是乐于交谈,所以请在下面留下评论,分享你的想法。我还在 LinkedIn 上分享有趣和有用的资源,所以请随时关注并联系我。下次我会带来另一个有趣的故事。一如既往,敬请期待!

黑客马拉松故事

原文:https://towardsdatascience.com/hackathon-story-fa2aed2cf4c2?source=collection_archive---------28-----------------------

我受邀在俄罗斯最大的数据科学和机器学习会议 DataFest 6 上讲述我在数据科学黑客马拉松中的经历。我决定讨论组织此类活动时常见的错误以及如何避免它们。我的演讲录音最近发表了(俄语演讲,有英语字幕)。我注意到了视频的如下评论(从俄语翻译过来):

这个家伙找到我们,建议我们合并解决方案,然后平分奖金。我们拒绝了,然后他赢了,我们没有_(ツ)_/

其实这背后有一个很酷的故事。

故事

这次黑客马拉松是在莫斯科举行的,之前由同一组织者在圣彼得堡成功举办了几次,我是远程参与者(当时我在芬兰学习)。像往常一样,这次它被允许从另一个城市参加,但我决定下线。

它开始于周五晚上,截止日期定在周日中午。“Moscow AI Hack”的总奖金池约为 6k 美元,以下每条赛道的冠军可获得 15k 美元奖金:

  • 预测俄罗斯各地区汽油价格(时序表格数据,Gazprom 的 Kaggle 竞争);
  • 用表格数据和汽车图片预测特定汽车对给定用户的“适用性”(莫斯科初创公司 True North 举办的 Kaggle 竞赛);
  • 检测 Gazprom 横幅中的错误和“异常”(计算机视觉任务;没有提供明确的指标,尽管数据集包含大量高分辨率照片);
  • 最佳商业解决方案(开放式课程,前提是必须使用数据集才有资格获奖)。

在浏览了所有数据集并仔细阅读了所有任务后,我决定专注于第二个——来自正北的轨迹。我在周五创建了一个基线解决方案,回家后花了一整天设计新功能,训练不同的模型,并在周六远程调整它们的超参数。一天下来,我完全筋疲力尽,没有主意了。不过,我在 26 支队伍中名列前三。

前三名的所有三支队伍都是单人参赛。我和第二个家伙只差几分,而第一名的参与者不知何故得到了比其他任何人都好得多的分数。鉴于“赢家通吃”的政策,我知道我没有机会独自赢得它,因为分数的差距,时间的缺乏,以及竞争的动态。策略很简单:我应该和排行榜首位的人合并;如果我们的解决方案足够多样化,这样的合并将提高我们的共同得分。

我问排在第二位的那个人,他是否愿意合作,整合我们的解决方案。他想了一会儿,然后回答说他第二天会给我答案。我去睡觉,第二天早上我看到 top1 和 top2 已经合并成一个团队。

我获胜的机会大大减少了。这有点令人沮丧,但我不想放弃,现在还不想。我不得不另找一支队伍。

我去黑客马拉松的地方找人合作。我向前十名中的几乎所有人提议合并我们的团队并分享奖金,但没有人同意。回想起来,我认为这可能有多种原因:部分原因是最后期限越来越近,他们失去了获胜的希望;部分原因是分成比例(无论团队大小,奖金的 50%归我,50%归他们团队)对他们来说似乎不公平(但实际上,这非常公平);部分原因是我看起来不像一个有经验的数据科学家,所以也许他们认为我只是一个普通人(黑客马拉松上有很多这样的人);也许我不够有说服力;也许他们在等待排行榜的大变动;也许原因在于“未知的未知”。不管怎样,这没关系。

That’s what I looked like at that time. It was hard to believe that such a guy could be an experienced Data Scientist (even for me, even right now)

当我意识到我没有机会获胜的时候,一位来自 True North 的高级数据科学家来到了我工作的地方。我们讨论了任务、排行榜、方法和其他东西。我们聊得很愉快,当时我问他,他们将如何通过这种模式赚钱?经过一番讨论后,发现任务的目标并不是最优的,也就是说,他们做了一个回归任务,但实际上,他们需要某种推荐。此外,预测的目标没有选对。

我提出了另一个管道,这可以提高其中一个流程的效率。我们讨论了要做的实验的设置、度量标准、成功的衡量标准以及其他一些东西。我看得出他非常喜欢我的思维方式,我喜欢他喜欢这一点。

我尽可能快地运行了我们讨论的所有实验——大约花了我一个小时。截止日期前 15 分钟,我开始准备演示文稿。我勉强在时间结束前完成了它。在做那个演讲的时候,我很紧张,因为我的演示设计并不完美。然而,我成功地克服了这一点,因为我牢记,尽管我的幻灯片并不漂亮,但它们对公司是有价值的。

最终,我没有赢得 Kaggle 比赛(我获得了第 3 名),但我的解决方案被评为“最佳商业解决方案”,我赢得了“开放解决方案”赛道。我也收到了面试的邀请。在两周内,我作为真北的数据科学家继续这个项目。

回首过去总是很有趣。

如果那天有人同意和我合并,我们会在 Kaggle 比赛中获得第二或第三名。我不会赢,也不会得到我的第一份工作。事实上,我很幸运被每个人拒绝。接下来的事件对我来说会有所不同,但毫无疑问无论如何都会很酷。

评估分类模型

原文:https://towardsdatascience.com/hackcvilleds-4636c6c1ba53?source=collection_archive---------12-----------------------

在 Python 中使用 Sci-Kit Learn 的引导式演练

作者:Ishaan Dey,Evan Heitman,& Jagerynn T. Verano

分类介绍

医生想知道他的病人是否有病。信用卡公司有兴趣确定某项交易是否是欺诈。一个研究生院的候选人感兴趣的是她是否有可能被她的项目录取。许多应用模型对预测二元事件的结果感兴趣,二元事件是可以通过简单的是或否问题来回答的任何事件。这被称为二元分类问题,不同于多类分类,在多类分类中,我们感兴趣的是预测某个人会患哪种疾病,或者某个顾客会从选择中购买哪种产品

概述

回归模型通常会报告熟悉的指标,如 R2,以显示拟合优度,或模型与数据的吻合程度。对于离散的结果,我们不能应用相同的公式,因此在这篇文章中,我们将通过分解模型可能出错的错误类型和可以总结模型按照我们的预期执行的能力的定量测量,来研究如何评估分类器模型的性能。

在本文中,我们使用信用卡交易数据集,目标是标记欺诈交易(二元结果,1 表示欺诈)。鉴于欺诈发生率较低,该数据集被欠采样,以创建一个 90:10 的非欺诈与欺诈观察值的新分布。该数据被进一步分割成 70:30 的序列以测试分割。我们拟合了一个逻辑回归模型,并使用 0.5 的阈值来预测欺诈值。您可以使用下面链接的交互式 python 笔记本来跟进。

https://github . com/is handey/Classification _ Evaluation _ walk through

基础知识:混淆矩阵

Confusion Matrix from a Binary Classification Model

对于任何包含二元结果的数据集,我们可以用 1(表示事件的发生)或 0(事件的不存在)来标记所有的观察值。我们可以将模型拟合到特征变量,并在给定特征变量集的情况下对每个观察值进行预测。被模型正确分类的值被标记为真(T),而不正确的预测为假(F)。正(P)和负(N)指的是模型的预测,而不是实际的观察值。例如,一个负值被错误地归类为正值,就称为假阳性。

作为题外话,许多读者将熟悉分别作为α和β的假阳性和假阴性。假阳性用α表示,而假阴性用β表示。因此,当我们建议统计的概率小于 0.05 的α时,我们说错误地将结果标记为显著的概率是 0.05。

我们的模型,用下面的函数产生,产生了下面的混淆矩阵。

Confusion Matrix from Logistic Regression Classifier (Threshold = 0.5)

confusion_matrix(y_test, y_pred)

准确性有什么问题?

假设我们遇到了一种用于检测癌症的诊断工具,该工具可以以 99.8%的准确率正确预测结果。这真的令人印象深刻吗?据 CDC 估计,一般人群的癌症死亡率约为 0.16%。如果我们制作一个虚拟模型,并说不管我们可获得的特征信息如何,每一个结果都应被归类为负面情况,我们将以 99.84%的准确率执行,因为我们样本中 99.84%的观察结果都是负面的。我们可能会错过对每一个癌症患者的诊断,但我们仍然可以如实地报告,我们的模型具有 99.84%的准确率。显然,一个好的模型应该能够区分什么是阳性案例,什么不是阳性案例。

从更专业的角度来说,准确性的值可以很容易地从混淆矩阵中获得,因为真阳性和真阴性的数量除以测试的观察总数。简单来说,就是观察值被正确分类的比例。

准确度= (TP + TN) / (TP + TN + FP + FN)

回顾我们的欺诈检测数据,我们的逻辑回归模型预测准确率为 97.7%。但是这比虚拟分类器好多少呢?让我们看看结果的实际分布。

Target Class Distribution of Full Dataset

sns.countplot(x=fraud['Class'])

在这里,阶级不平衡,或者说结果的倾斜分布是显而易见的。使用快速检查。value_counts()函数显示,我们的数据中有 137 个欺诈案例,1339 个非欺诈案例,这意味着我们的测试案例中有 9.3%是欺诈的。如果我们要应用一个虚拟模型,盲目地预测所有的观察结果为非欺诈案例,就像可以用 sklearn.dummy 包完成的那样,我们可以看到我们报告的 90.7%的准确性与我们的频率分布(90.7:9.3)相匹配。因此,即使我们的虚拟模型毫无用处,我们仍然可以报告它的执行准确率达到 90%。下面的混淆矩阵进一步显示了这种无法区分的细节。

y_test.value_counts() / len(y_test)
dum = DummyClassifier(strategy='most_frequent')

Confusion Matrix from Dummy Classifier

我们可以用什么措施来代替呢?

使用混淆矩阵的最大好处是,我们可以很容易地得出各种其他值,这些值反映了我们的模型相对于我们对虚拟模型的预期运行得有多好。

敏感度(或回忆,或真阳性率)

正如我们在上面的例子中看到的,一个好的模型应该能够成功地检测到几乎所有的实际欺诈案件,因为没有发现欺诈案件的成本要比通过错误地暗示这是一个欺诈案件来审查一个非欺诈交易的成本高得多。敏感度,也称为回忆,量化了这种直觉,并反映了正确分类的阳性与实际阳性病例的比率。

灵敏度= TP / (TP + FN)

敏感性的解释相当简单。所有值的范围都在 0 到 1 之间,其中值 1 表示模型检测到了每一个欺诈案例,而值 0 表示没有检测到所有实际的欺诈案例。使用我们的逻辑回归模型,我们的灵敏度为 108 / 137 = 0.788。

特异性

特异性有助于我们确定在所有真正的非欺诈案例中,有多少被正确归类为非欺诈案例。假阳性率或假警报率与特异性相反。在我们的欺诈检测模型中,我们的特异性为 1334/1339 = 0.996

特异性= TN / (TN + FP)

假阳性率= 1 —特异性

在这种特殊情况下,特异性是一个不太相关的指标,因为将非欺诈案件归类为欺诈案件的成本低于完全遗漏欺诈案件的成本。但是在有些情况下,错误警报同样是不可取的,例如在疾病检测中,误诊会导致不必要的后续程序。

精度

另一方面,我们可能想要测试我们预测的确定性,例如,我们可能对我们的模型所发现的欺诈案例中有多少是真正的欺诈案例感兴趣。Precision 就是这样做的,它提供了真实阳性相对于预测阳性的比例。直觉上,低精度意味着我们让很多客户头疼,因为我们对欺诈交易的分类多于实际欺诈交易。使用逻辑回归模型,我们的精度是 108/113 = 0.956

精度= TP / (TP + FP)

我们应该最大化特异性还是敏感性?

在我们的欺诈数据集中,更重要的是我们要最大限度地减少未被发现的欺诈案件的数量,即使这样做的代价是将非欺诈案件错误地归类为欺诈案件,因为前一个案件给公司带来的成本要高得多(潜在的数千美元的收入损失或客户验证其交易的几分钟时间)。换句话说,我们宁愿犯第一类错误,也不愿犯第二类错误。尽管我们更倾向于最大化敏感性和特异性的模型,我们更倾向于最大化敏感性的模型,因为它最小化了 II 型错误的发生。

F1 比分

最后但同样重要的是,F1 分数总结了精确度和召回率,并且可以被理解为这两个度量的调和平均值。f 1 值为 1 表示完美的精确度和召回率,因此 F1 值越高,模型越好。我们的逻辑模型显示 F1 值为 0.864。

F1 = 2 (精度灵敏度)/(精度+灵敏度)

当我们改变概率截止值时会发生什么?

我们到底是如何得出我们的预测的?从我们的逻辑回归,我们计算出一个给定的观察是欺诈性的预测概率落在 0 到 1 之间。我们说,所有大于 0.5 的概率都应该表示欺诈预测,而所有小于 0.5 的值都返回合法交易的预测。

但是考虑到我们更愿意犯第一类错误,即使只有很小的可能性,把一个案例归类为欺诈不是更好吗?换句话说,如果我们降低区分欺诈和非欺诈的门槛,让我们抓住更多的欺诈,从橙色线转移到绿色线,会怎么样?

Orange = Discrimination Threshold of 0.5; Green = Discrimination Threshold of 0.1

根据我们之前讨论的定义,模型的特异性会增加,因为我们现在分类了更多的阳性,但同时,我们增加了将非欺诈案件错误地标记为欺诈的可能性,从而随着假阴性数量的增加而降低了灵敏度。这是一个不断的权衡,灵敏度从降低特异性增加的速率是每个模型特有的属性。

到目前为止,我们报告的指标来自于以 0.5 为阈值计算的混淆矩阵(橙色线),但是如果我们将区分阈值降低到 0.1(绿线),灵敏度将从 0.788 增加到 0.883,而特异性将从 0.996 下降到 0.823。

classification_report(y_test, y_pred)

ROC 曲线

我们可以使用受试者操作特征或 ROC 曲线来查看所有阈值下这些值的变化,ROC 曲线绘制了每个阈值的真阳性率对假阳性率,或灵敏度对 1 特异性。我们可以在这里看到我们的逻辑分类器的 ROC 曲线,其中不同的阈值应用于预测的概率,以产生不同的真阳性和假阳性率。

我们的虚拟模型是蓝色曲线上(0,0)处的一个点,在该点处,判别阈值使得任何小于 1.0 的概率都被预测为非欺诈案例。这表明,尽管我们正确地分类了所有非欺诈案例,但我们错误地分类了所有非欺诈案例。另一方面,一个完美的区分模型将在曲线上的(0,1)处有一个点,这将表明我们的模型完美地分类了所有欺诈案件以及非欺诈案件。这两个模型的线将作为阈值水平的函数生成。

fpr, tpr, thresholds = roc_curve(y_test, y_pred_prob[:,1])

对角线显示了真阳性率与假阳性率相同的情况,其中正确检测欺诈案件和将非欺诈案件检测为欺诈案件的机会相等。这意味着任何高于对角线的 ROC 曲线都比预测结果的随机机会更好,假设 50/50 类平衡。

因此,我们将在该领域中遇到的所有 ROC 曲线将被绘制在 y=x 线之上,垂直向上到(0,1),然后水平穿过(1,1)的线之下。我们可以通过观察曲线下面积或 AUC ROC 来量化 ROC 曲线的表现程度。该值将采用介于 0.5(对角线)和 1.0(完美模型)之间的值。我们的欺诈检测模型的 AUC ROC 为 0.934,对于开箱即用的模型来说还不错。

from sklearn.metrics import auc
auc = roc_auc_score(y_test,logis_pred_prob[:,1])

PRC 曲线

回到 logit 模型,当我们将辨别阈值从橙色转移到绿色时,精确度和召回率会发生什么变化?当我们从阈值 0.5 移动到 0.1 时,召回率从 0.788 增加到 0.883,因为正确检测到的欺诈在实际欺诈数量中的比例增加,而精确度从 0.956 下降到 0.338,因为真实欺诈案例在预测欺诈案例数量中的比例下降。正如我们对 ROC 曲线所做的那样,我们可以将精确度和召回率之间的权衡绘制为阈值的函数,并获得精确度-召回率曲线,或 PRC。

precision, recall, thresholds = precision_recall_curve(y_test, y_pred_prob[:,1])

通常,PRC 更适合在高度不平衡的数据集上训练的模型,因为 ROC 曲线的假阳性率公式中使用的高真负值会“夸大”模型表现如何的感觉。PRC 曲线避免了这个值,因此可以反映模型性能的偏差较小的度量。

我们可以使用平均精度值或平均 F1 分数(每个阈值的平均值)来简洁地总结这条曲线,理想值接近 1。

from sklearn.metrics import f1_score
from sklearn.metrics import average_precision_scoref1 = f1_score(y_test, y_pred_prob)
ap = average_precision_score(y_test, y_pred_prob)

离别的思绪

公式快速回顾:

TPR = True Positive Rate; FPR = False Positive Rate

在这篇文章中,我们讨论了如何超越精度来衡量二元分类器的性能。我们讨论了灵敏度、特异性、精确度和召回率。我们研究了当我们改变决策阈值时会发生什么,以及我们如何可视化灵敏度和特异性之间的权衡,以及精确度和召回率之间的权衡。提醒一下,所有生成的可视化和模型都可以在交互式 python 笔记本上找到,链接如下。

https://github . com/is handey/class ification _ Evaluation _ walk through

这个帖子到此为止。如果您有任何问题,请告诉我们!

黑客谷歌珊瑚边缘 TPU:运动模糊和 Lanczos 调整大小

原文:https://towardsdatascience.com/hacking-google-coral-edge-tpu-motion-blur-and-lanczos-resize-9b60ebfaa552?source=collection_archive---------9-----------------------

谷歌的珊瑚项目最近已经停止测试。根据基准测试,Coral 设备为 DIY 创客提供了出色的神经网络推理加速。这些设备基于专门的张量处理单元 ASIC (Edge TPU),这被证明是有点棘手的工作,但强制限制和怪癖是值得的。我渴望探索 TensorFlow 和 Edge TPU 之间互操作的深层内部机制,并对两者进行破解,以做一些很酷的、非标准的、疯狂的事情。

以下期望你熟悉张量流和边缘 TPU 基础知识。官方文档很好,所以通过查看边缘 TPU 和边缘 TPU 编译器 上的 TensorFlow 模型应该足以继续。重复我的实验需要 Ubuntu Linux 和一个外部 Coral USB 加速器。

首先,Edge TPU 软件不是完全开源的。最“美味”的部分、edgetpu_compiler可执行文件和libedgetpu.so共享库是专有的。这一事实增加了潜在的黑客复杂性,但也使它更有趣!例如,查看哪些 API 被libedgetpu.so公开的唯一方法是用objdump转储导出的符号:

$ objdump -TCj .text /usr/lib/x86_64-linux-gnu/libedgetpu.so.1/usr/lib/x86_64-linux-gnu/libedgetpu.so.1:     file format elf64-x86-64DYNAMIC SYMBOL TABLE:
000000000006baa0 g    DF .text 000000000000000d  VER_1.0     edgetpu::RegisterCustomOp()
0000000000072b40 g    DF .text 000000000000001f  VER_1.0     edgetpu::EdgeTpuContext::~EdgeTpuContext()
0000000000072ad0 g    DF .text 0000000000000006  VER_1.0     edgetpu::EdgeTpuContext::~EdgeTpuContext()
0000000000072ad0 g    DF .text 0000000000000006  VER_1.0     edgetpu::EdgeTpuContext::~EdgeTpuContext()
000000000006dc10 g    DF .text 000000000000000a  VER_1.0     tflite_plugin_destroy_delegate
000000000006be50 g    DF .text 00000000000001dd  VER_1.0     edgetpu_list_devices
000000000006bb80 g    DF .text 0000000000000107  VER_1.0     edgetpu_version
000000000006bab0 g    DF .text 000000000000000a  VER_1.0     edgetpu::EdgeTpuManager::GetSingleton()
000000000006d090 g    DF .text 0000000000000b7c  VER_1.0     tflite_plugin_create_delegate
000000000006bb20 g    DF .text 0000000000000012  VER_1.0     edgetpu_free_devices
000000000006bac0 g    DF .text 000000000000005e  VER_1.0     edgetpu::operator<<(std::ostream&, edgetpu::DeviceType)
000000000006c030 g    DF .text 0000000000000c1a  VER_1.0     edgetpu_create_delegate
000000000006bb40 g    DF .text 000000000000000a  VER_1.0     edgetpu_free_delegate
000000000006bb50 g    DF .text 0000000000000024  VER_1.0     edgetpu_verbosity

该输出明确暗示 Edge TPU API 是用又长又粗的钉子钉在 TensorFlow Lite 上的。根本不可能以任何其他方式使用该设备。如果你期望看到像“将这个矩阵乘以 TPU 边缘的那个向量”这样的低级 API,那就不走运了。

让我们快速回顾一下面向 Edge TPU 的 TensorFlow Lite API 是如何工作的:

  1. 使用常规张量流生成计算图。比如训练一个深度神经网络。
  2. 将其转换为 TensorFlow Lite 格式,这是 flatbuffers 而不是 protobuf,并且具有不同的模式。新图必须是特殊的,使 TPU 边缘的朋友。值得注意的是,包含的操作(ops)必须量化为 [uint8](https://www.tensorflow.org/lite/performance/quantization_spec),因为边缘 TPU 只能处理无符号字节。
  3. 交叉手指再转换一次,这次用edgetpu_compiler。底层格式保持不变,但是支持的操作被融合并编译成一个神奇的 Edge TPU 块。
  4. 确保 Coral 设备已连接,使用 Edge TPU 操作代理创建一个新的 TensorFlow Lite 解释器,并调用

因此,如果不调用外部程序并随时读写文件,在 Edge TPU 上运行任意计算是不可能的。

这个多步骤过程中的关键细节是可以为 Edge TPU 编译的操作列表。TensorFlow Lite 不支持它的哥哥的所有功能,Edge TPU 只支持剩下的一小部分。比如没有矩阵乘法(惊喜!我根据经验检查了“输出张量是一维的”完全连通)。这些限制使得除了卷积和全连接神经网络之外的边缘 TPU 推理变得非常困难。但并非不可能。这就是《邮报》变得有趣的地方。

边缘 TPU 上的运动模糊

运动模糊效果是图像与“半径”内核的 2D 卷积的结果。

Horizontal motion blur. Left: original photo. Right: photo after applying the effect. Source: Wikipedia.

在张量流术语中,该操作被称为 DepthwiseConv2d,它被广泛用于深度卷积神经网络中,并得到边缘 TPU 的支持。图像像素可以用 RGB 格式表示,每个通道一个字节——这正是 Edge TPU 所需要的。让我们穿越所有的坑和危险,并基准如何快速运动模糊图像过滤边缘 TPU 与 Python!

0 →传递函数

在本节中,忘记 TensorFlow Lite 和 Edge TPU 的存在。让我们熟悉一下主要的逻辑。以下代码创建卷积内核。dim是尺寸,angle是平面上的运动角度,单位为弧度。

当涉及到肮脏的视觉效果时,它总是很方便。

下一步是用常规的 TensorFlow 2.0 测试我们的运动模糊效果。我们利用[tf.nn.depthwise_conv2d](https://www.tensorflow.org/api_docs/python/tf/nn/depthwise_conv2d)来计算图像与内核的 2D 卷积。所有步幅都等于 1,因此图像尺寸不会改变。

在 Jupyter 中,人们可以使用%timeit motion_blur(images)快速测量运动模糊性能。在我的 4x2(HT)英特尔 i7–8565 u CPU 上,它产生了大约 5.30 秒±0.09 秒的结果。

tf.function → tflite

既然我们已经确定了整体方法是可行的,那么是时候将其移植到 TensorFlow Lite 了。

我们必须在create_motion_blur_func中指定tf.function的输入签名,因为 TensorFlow Lite 目前不允许除第一个“批处理”维度之外的可变形状。因此,我们的运动模糊只能处理相同大小的图像。

create_motion_blur_func_lite是围绕create_motion_blur_func的包装器,将后者转换为 TensorFlow Lite。generate_lite_model从属于tf.function的计算图中初始化tf.lite.TFLiteConverter——我们的运动模糊算法——并将转换结果写入磁盘。create_func_lite加载它,设置一个新的tf.lite.Interpreter并返回调用闭包。

根据%timeit,新的实现速度更快:3.50 秒 0.24 秒对 5.3 秒。这种性能提升令人惊讶,因为根据系统监视器,执行只利用了我的八个 CPU 核心中的一个。我们可以想象结果。带[netron](https://github.com/lutzroeder/netron)的 tflite 型号:

TensorFlow Lite motion blur graph visualized with netron.

tflite →边缘 TPU

最后,我们需要从香草 TensorFlow Lite 过渡到边缘 TPU。这一步是迄今为止最棘手和最复杂的。我们将继续在现有代码的基础上构建,一次添加一个特性。

边缘 TPU 需要uint8操作数据类型(dtype)而不是float32。不幸的是,我们不能让tf.nn.depthwise_conv2d直接与uint8一起工作:只支持float64float32bfloat16float16。因此,我们不得不求助于“训练后量化”,这意味着伪造数据类型并给所有运算增加量化属性。gen_input_samples模拟从 0 到 255 的像素值范围,这就是 TensorFlow Lite 中量化参数化的方式。我们进一步调用量化模型上的edgetpu_compiler来用边缘 TPU 的优化代码替换 2D 卷积 op。tf.lite.Interpreter必须增加experimental_delegates=[load_delegate("libedgetpu.so.1.0")]以让它知道如何处理优化的边缘 TPU 运算

edgetpu_compiler支持 TensorFlow 2.0 的理想世界中,上面的代码应该可以工作。让我们运行代码看看。

Edge TPU Compiler version 2.0.267685300Model compiled successfully in 231 ms.Input model: motion_blur_1_1920_1058_3_25_1.57.tflite
Input size: 3.03KiB
Output model: motion_blur_1_1920_1058_3_25_1.57_edgetpu.tflite
Output size: 296.85KiB
On-chip memory available for caching model parameters: 1.73MiB
On-chip memory used for caching model parameters: 10.00KiB
Off-chip memory used for streaming uncached model parameters: 0.00B
Number of Edge TPU subgraphs: 1
Total number of operations: 3
Operation log: motion_blur_1_1920_1058_3_25_1.57_edgetpu.logModel successfully compiled but not all operations are supported by the Edge TPU. A percentage of the model will instead run on the CPU, which is slower. If possible, consider updating your model to use only operations supported by the Edge TPU. For details, visit g.co/coral/model-reqs.
Number of operations that will run on Edge TPU: 1
Number of operations that will run on CPU: 2Operator                       Count      StatusDEPTHWISE_CONV_2D              1          Mapped to Edge TPU
DEQUANTIZE                     1          Operation is working on an unsupported data type
QUANTIZE                       1          Operation is otherwise supported, but not mapped due to some unspecified limitation

DEPTHWISE_CONV_2D成功编译,但是有奇怪的DEQUANTIZEQUANTIZE操作没有成功。它们是编译器不支持的 TensorFlow 2.0 工件,是从motion_blur_func签名中的强制float32 dtype 产生的。netron可视化应该让一切都变得清晰。

Quantized TensorFlow Lite model (left) and compiled Edge TPU model (right) visualized with netron.

因此,我们必须做四次多余的工作:

  1. 将像素值从uint8切换到float32,将其传递给 TensorFlow Lite 引擎。
  2. TensorFlow Lite 执行QUANTIZE并切换回uint8
  3. 计算完卷积后,我们返回到DEQUANTIZE中的float32
  4. TensorFlow Lite 将控制权交还给调用者,我们转换到uint8以保存图像。

将原来的QUANTIZEDEQUANTIZE去掉。tflite 将使模型再次变得伟大。不幸的是,要做到这一点并不容易。根本没有官方 API 来操作 TensorFlow Lite 模型。我们需要深入挖掘。

深入挖掘

我提到 TensorFlow Lite 模型格式是 flatbuffers 。这是一种相对较新的通用序列化格式,我敢打赌它会在 Google 内部与 protobuf 竞争。flatbuffers 的 Python API 不允许修改现有文件,bummer。幸运的是,flatbuffers 展示了一个对象的两种不同表示:binary 和 JSON,并支持它们之间的无损转换。有flatc -jflatc -b命令可以分别转换。tflite 到 JSON 以及向后。我们将使用它们从模型中去除冗余的操作,由提供。模式是公共的。其实这就是 TensorFlow Lite 开发者自己用来升级的方法。tflite 型号

密码显示原始的。tflite 模型具有错误的 dtypes: int8而不是uint8。TensorFlow 2.0 在没有被要求的情况下尝试应用多声道量化;Edge TPU 不支持多声道量化,我们也必须解决这个问题。

第二次尝试更成功:

Edge TPU Compiler version 2.0.267685300Model compiled successfully in 171 ms.Input model: motion_blur_1_1920_1058_3_25_1.57.tflite
Input size: 2.71KiB
Output model: motion_blur_1_1920_1058_3_25_1.57_edgetpu.tflite
Output size: 296.56KiB
On-chip memory available for caching model parameters: 1.73MiB
On-chip memory used for caching model parameters: 10.00KiB
Off-chip memory used for streaming uncached model parameters: 0.00B
Number of Edge TPU subgraphs: 1
Total number of operations: 1
Operation log: motion_blur_1_1920_1058_3_25_1.57_edgetpu.logOperator                       Count      StatusDEPTHWISE_CONV_2D              1          Mapped to Edge TPU

Patched mother TensorFlow Lite model (left) and compiled Edge TPU model (right) visualized with netron.

现在是承诺的基准。我安装了不限制工作频率的libedgetpu-max。我的结果是 5.00s 0.25 和 0.262s 0.001 的原始和边缘 TPU 版本,相应地。 Edge TPU 比我的 CPU 上最快的float32实现快 10-20 倍!当然,这种比较是不公平的,因为只有一个 CPU 内核被用来运行原来的处理器。tflite,我不能在 Python 中更改它(在 C++ 中看起来可能)。我预计真正的性能加速在 2-4 倍之间。此外,一个合适的矢量化uint8 CPU 实现应该比float32快 4 倍——例如 pillow-simd 。所以边缘 TPU 已经没有公平至上。从好的方面来看,Coral 设备的功耗至少降低了 20 倍。

边缘 TPU 上生成的图像看起来与地面真实情况相同,但由于精度损失而不是字节精确的。

Motion blur effect comparison. Left: canonical tf.function with float32. Right: Edge TPU.

Lanczos 在边缘 TPU 调整大小

模糊图像很有趣,但tf.nn.depthwise_conv2d还有更实际的应用。可以说,调整图像大小的最佳方法也是由卷积实现的。卷积在像素重采样之前充当低通滤波器。有各种各样的像素平均内核,Lanczos 可能是最著名的。我们的计划是在 TensorFlow 中定义一个新的 Lanczos 内核,并生成边缘 TPU 模型以将图像缩小 2 倍。

我们重用之前设计的函数:create_func_edgetpugenerate_edgetpu_model。代码中最有趣的地方是我们如何利用卷积核在同一操作中实现像素子采样。我们来看看结果。

Lanczos resize with TensorFlow’s depthwise_conv2d. Left: canonical tf.function with float32. Right: Edge TPU.

展示鹦鹉

哎呀。普通白色矩形。出事了。原因隐藏在 Lanczos 内核的外观中。让我们像在运动模糊部分一样想象它。

Lanczos 2D kernel, “hot” color scheme.

你在颜色栏里看到“-0.006”了吗?没错,Lanczos 内核含有负值。如您所知,内置量化将float32更改为int8,我的“JSON 后处理”将 dtypes 设置为uint8。因此内核被错误地应用,我们因大量溢出而遇难。我们必须从零开始提升量化零点,并更新所有的核权重。

Lanczos resize with TensorFlow’s depthwise_conv2d. Left: canonical tf.function with float32. Right: Edge TPU after the fix.

屏蔽溢出

我们的内核并不完美:由于舍入误差和整体不精确,一小部分像素通道看起来大于 256。这就是为什么在天气是白色的地方,蓝绿色的人工制品会出现在鹦鹉的眼睛附近。类似地,最暗的区域可能变成负值。我们需要价值剪裁。

Lanczos resize comparison. Left: canonical tf.function with float32. Right: Edge TPU after all the fixes.

基准测试结果:tf.function/float32150 ms 2,TF lite/float32165 ms 3,TF lite/uint8220 ms 3,Edge TPU 47.8 ms 0.1。也就是说, Edge TPU 快了 3 倍。使用 pillow-simd 调整相同图像的大小需要 4.9 毫秒 0.1 秒,因此 Edge TPU 比我的 CPU 上最快的 Lanczos resize 实现慢了大约 10 倍。我使用了以下代码:

from PIL import Image
img = Image.open("parrot.jpg")
%timeit img.resize((529, 960), Image.LANCZOS)

我不知道 pillow-simd 中使用的确切内核大小,可能是 5x5 而不是我们的 11x11。将内核大小更改为 5x5 会在边缘 TPU 上产生 40 毫秒。如此微妙的时间变化表明,更大的内核尺寸释放了 Edge TPU 的全部能量。

所以我用不同的内核大小进行了测试。edgetpu_compiler内核大小大于或等于 28 时崩溃。

Lanczos resize time for different kernel sizes on Edge TPU.

显然,在张量流/Python 方面有一个巨大的常数因子,它先于边缘 TPU 的优势。25x25 内核导致 25 倍以上的计算,但运行时间仅增加两倍。这个事实与 Coral 文档中关于尽可能避免 CPU 边缘 TPU 通信的陈述一致。

结论

  1. 只有在 TensorFlow Lite 中才能使用边缘 TPU。
  2. 除了在边缘 TPU 上进行卷积神经网络推理之外,很难编写任何程序。但有可能。比如使用tf.nn.depthwise_conv2d的通用图像滤波。
  3. Edge TPU 不喜欢 TensorFlow 2.0。最好还是坚持文档说的,用 1.x,用 2.0 还是有可能黑掉的。
  4. TensorFlow Lite 模型可以在 JSON 表示中自由编辑和黑客攻击。
  5. 边缘 TPU 上的变换将被绑定到特定的图像大小。不过,预先生成模型是可能的。
  6. 运动模糊或其他卷积滤波器可以在具有微小视觉差异的边缘 TPU 上计算。性能与现代 4x2HT 英特尔 CPU 相当,或者在更大的内核尺寸上更好。
  7. Lanczos 在 Edge TPU 上调整大小的速度很快,但仍然比一个伟大的矢量化 CPU 实现慢 10 倍。
  8. 演示的图像处理技巧应该作为包含在 CNN 模型中的增强管道的一部分工作得最好。
  9. 当主机 io 不占优势时,边缘 TPU 显示出最大功率。

我鼓励读者在 Edge TPU 上尝试其他卷积核。各种模糊、线条检测、边缘检测、锐化等。等。搜索“图像卷积示例”

神经网络的安全漏洞

原文:https://towardsdatascience.com/hacking-neural-networks-2b9f461ffe0b?source=collection_archive---------5-----------------------

当你的网络认为一切都是鸵鸟的时候怎么办。

神经网络无处不在,它们是可以被黑客攻击的。本文将深入研究神经网络和机器学习模型的对抗性机器学习和网络安全。

本文借用了哈佛大学 AC 209 b 讲座的内容,很大程度上归功于哈佛大学 IACS 系的讲师帕夫洛斯·普罗托帕帕斯

“人们担心计算机会变得太聪明并接管世界,但真正的问题是它们太笨了,它们已经接管了世界。”佩德罗·多明戈斯

神经网络在现代世界中变得越来越普遍,并且它们的实现经常没有考虑到它们潜在的安全缺陷。这导致了一个新的网络安全领域,它着眼于神经网络的脆弱性,以及我们如何保护它们免受黑客的攻击。虽然这是一个相对严肃的问题,但在本文中,我将采用幽默的方式概述神经网络的弱点,希望读者会觉得有趣并有所收获。

Adding strategic noise to an image can be used to fool neural networks. Source: Goodfellow et al., 2015.

概观

在这篇文章中,我将向读者全面介绍 对抗性机器学习 领域,其中试图愚弄、毒害或操纵机器学习模型,以规避其内在目的,通常是出于恶意目的。

我在本教程中要回答的问题是:

  • 什么是对抗性机器学习?
  • 我的机器学习模型怎么会被攻击?
  • 我如何保护我的模型免受攻击?
  • 这些攻击在现实世界中会产生什么后果?

由于神经网络的基础架构和学习过程,这个问题是神经网络最关心的问题,因此本文的大部分内容都集中在这些网络上,尽管也给出了其他示例。

现实世界中的神经网络

你可能从来不知道,但你可能每天都在不假思索地使用神经网络。问过 Siri 一个问题吗?有一个神经网络。自动驾驶汽车?神经网络。你相机上的人脸识别?更多的神经网络。Alexa?再一次,神经网络…

这些只是有形的应用,人们每天都在使用神经网络的大量无形应用。无论是你在工作中使用的软件程序,还是仅仅为了寻找那天晚上去吃饭的地方,你都可能使用某种形式的神经网络(我这样说是因为有大量不同类型的网络)。

Some of the most common uses of neural networks today.

这些网络的普及性只会增加,这是有充分理由的。神经网络是 通用函数逼近器 。那是什么意思?这意味着,如果我的神经网络有足够大的容量(即足够多的节点——权重和偏差——可以修改),那么我就能够使用神经网络逼近任何非线性函数。这是一个非常有力的陈述,因为我基本上可以学习任何函数,不管它有多复杂。

然而,我们为此付出了代价,那就是网络可能对你给它们的输入相当敏感。因此,可以说,如果你知道按哪个按钮是对的,就比较容易愚弄网络。通过操纵图像的某些节点,很容易激活与特定特征相关的神经元,这可以使网络给出虚假的输出。

这可能看起来相对无辜,毕竟,正如 Ian Goodfellow 在他的开创性论文中所示,看到神经网络随机将熊猫变成长臂猿是非常滑稽的。然而,这类攻击的实际应用可能会令人望而生畏。

我们以 Alexa 为例,假设你定期使用 Alexa 买东西。有一天,一个特别聪明的黑客坐在你的房子外面(在网络安全世界中通常被称为 wardriving ),入侵你的 Wifi——如果你没有妥善保护你的路由器或者仍然有默认密码,使用 aircrack-ng 这出奇地容易。

黑客现在可以访问 Alexa,它具有代表你进行交易的安全特权,给予你口头批准。如果黑客足够聪明,可以想象他们可以欺骗 Alexa 把你所有的钱都给黑客,只要按下神经网络上的正确按钮。

这可能会吓到你,你可能会去扔掉 Alexa。然而,仅仅因为这是可能的,并不意味着它是容易的。有些“攻击”可以在神经网络上实施,大多数拥有聪明工程师的公司至少已经考虑到这可能是一个问题。

我们现在将深入探讨如何攻击神经网络,可能的攻击类型,以及工程师和数据科学家如何帮助保护他们的网络免受这些潜在漏洞的影响。

对抗性攻击

在这一节中,我将向读者介绍对抗性攻击的分类。

白盒攻击与黑盒攻击

从本质上讲,对神经网络的攻击包括引入策略性放置的噪声,旨在通过错误地刺激对产生特定结果很重要的激活电位来欺骗网络。为了真正理解我说的“有策略地放置噪音”是什么意思,请考虑以下由谷歌大脑开发的图像,以展示同样的效果如何愚弄人类。你以为左边和右边的图都是猫吗?还是狗?还是各一个?

就具有决策边界的分类算法而言,这里是网络如何被引入的策略噪声破坏的图示。

Illustration of an adversarial attack in the feature space. Source: Panda et al. 2019

有两种主要类型的攻击是可能的:白盒攻击和黑盒攻击。灰箱攻击出现在网络安全领域,但不存在于神经攻击中。

当有人能够访问底层网络时,就会发生白盒攻击。因此,他们会知道网络的架构。这类似于对公司 IT 网络的白盒渗透测试——这是企业界测试公司 IT 基础设施防御能力的常规测试。一旦黑客了解了您的 IT 网络是如何构建的,就更容易进行破坏。在这种情况下,“知识就是力量”这句话尤其适用,因为了解网络的结构可以帮助您选择最具破坏性的攻击来执行,也有助于揭示与网络结构相关的弱点。

White box attack. Architecture is known and individual neurons can be manipulated.

当攻击者对底层网络一无所知时,就会发生黑盒攻击。在神经网络的意义上,该架构可以被认为是一个黑盒。虽然对黑盒进行攻击更加困难,但它仍然不是不受影响的。黑盒攻击的底层程序首先由 Papernot et al. (2015) 描述。

假设我们能够在网络上测试尽可能多的样本,我们可以通过将一组训练样本传入网络并获得输出来开发一个推断网络。然后,我们可以使用这些标记的训练样本作为我们的训练数据,并训练一个新的模型,以获得与原始模型相同的输出。

一旦我们有了新的网络,我们可以为我们推断的网络开发对抗性的例子,然后使用这些例子对原始模型进行对抗性攻击。

该模型不依赖于对网络体系结构的了解,尽管这将使攻击更容易进行。

物理攻击

您可能已经意识到,这些攻击都是软件攻击,但实际上也有可能是物理攻击网络。我不知道这种情况是否真的发生过,但是一些研究已经在研究使用“敌对标签”来欺骗网络。下面是一个例子。

Physical attacks on neural networks using adversarial stickers.

显然,这给自动驾驶汽车的大规模采用带来了一个潜在问题。没有人会希望自己的车无视停车标志,继续驶向另一辆车、一栋建筑或一个人。不过,不要太惊慌,有一些方法可以保护网络免受所有这些类型的攻击,我将在后面介绍。

闪避和毒药攻击

到目前为止,我们讨论的所有攻击都是规避攻击,即它们涉及“愚弄”系统。一个很好的例子是欺骗垃圾邮件检测器来保护电子邮件帐户,这样你就可以将垃圾邮件发送到某人的收件箱中。垃圾邮件检测器通常使用某种形式的机器学习模型(如朴素贝叶斯分类器),可用于单词过滤。如果一封电子邮件包含太多通常与垃圾邮件相关的“流行语”(给定你的电子邮件历史作为训练数据),那么它将被归类为垃圾邮件。然而,如果我知道这些单词,我可以故意改变它们,使检测器不太可能将我的电子邮件视为垃圾邮件,我将能够欺骗系统。

另一个很好的例子是在计算机安全领域,机器学习算法通常在入侵检测系统(IDSs)或入侵防御系统(IPSs)中实现。当一个网络数据包到达我的电脑时,如果它带有恶意软件的特征签名,我的算法就会在它做出任何恶意行为之前阻止它。然而,黑客可以使用混淆代码来“迷惑”网络,使其无法发现问题。

最后一个例子是,麻省理工学院的一些研究人员开发了一只 3D 打印的乌龟,它的纹理能够骗过谷歌的物体检测算法,并使其将乌龟归类为步枪。鉴于谷歌的算法目前在许多行业用于商业目的,最后一个问题有点令人担忧。

中毒攻击包括损害算法的学习过程。这是一个比规避攻击稍微微妙和阴险的过程,但只对参与在线学习的模型有效,即他们在工作中学习,并在新的经验(数据)对他们可用时重新训练自己。这听起来可能不是太大的问题,直到我们考虑一些中毒攻击的例子。

回到我们的 IDSs 示例,由于新的病毒总是在开发中,所以这些都是通过在线学习不断更新的。如果希望防止零日攻击,有必要让这些系统具备在线学习的能力。攻击者可以通过注入精心设计的样本来破坏训练数据,最终危及整个学习过程。一旦发生这种情况,您的 IDS 基本上就变得毫无用处,您面临着更大的潜在病毒风险,甚至可能意识不到这一点。因此,中毒可被视为训练数据的敌对污染。我们的垃圾邮件检测器示例也是如此。

这一节给了我们一个大概的概述,介绍了我们可能会遇到的各种问题。在下一节中,我们将更仔细地研究如何处理白盒和黑盒攻击,最常见的敌对攻击类型,以及人们可以在其神经网络中使用的防御措施,以改善这些安全问题。

具体攻击类型

Ian Goodfellow(生成对抗网络的创始人,也是创造这个术语的人)发表了第一篇研究神经网络潜在安全漏洞的论文。他决定把这叫做‘对抗性机器学习’,相对容易和生成性对抗性网络混淆。先说清楚,它们不一样。

伊恩描述了第一种攻击,快速梯度步进法。正如我们到目前为止所讨论的,这通过引入策略噪声来操纵分类器所使用的清晰的决策边界。

When your neural network suddenly thinks everything is an ostrich… Source: Szegedy et al. (2013)

后 Goodfellow 2015 攻击

在过去几年中,出现了许多新的攻击媒介,主要有:

为了避免这篇文章拖得太长,我将不深入讨论每个算法的具体细节。但是,如果您希望我在以后的文章中更详细地介绍这些内容,请随意发表评论。

网络防御

已经开发了许多方法来保护神经网络免受我们已经讨论过的各种类型的攻击媒介。

对抗训练

防御对抗性攻击的最好方法是通过对抗性训练。也就是说,你主动生成对立的例子,调整它们的标签,并把它们添加到训练集中。然后,您可以在这个更新的训练集上训练新的网络,这将有助于使您的网络在对抗实例中更加健壮。

Adversarial training in action.

平滑决策边界

正规化永远是答案。从这个意义上说,我们正则化的是数据的导数。这有助于平滑类之间的决策边界,并使使用策略噪声注入来操纵网络分类变得不那么容易。

(Left) Hard decision boundary, (right) smoothened decision boundary.

搞混了

Mixup 是一个简单的过程,乍一看似乎有点奇怪,它涉及通过某个因子λ混合两个训练样本,该因子介于 0 和 1 之间,并为这些训练样本分配非整数分类值。这有助于增加训练集,并降低网络的乐观分类倾向。它本质上扩散和平滑了类别之间的边界,并减少了分类对少量神经元激活电位的依赖。

[## 混淆:超越经验风险最小化

大型深度神经网络是强大的,但表现出不良行为,如记忆和敏感性…

arxiv.org](https://arxiv.org/abs/1710.09412)

挂钩

对于那些不熟悉聪明的汉斯的故事的人,我建议你谷歌一下。主要的故事是关于一匹马,据说它能够通过跺一定次数的脚来做基本的算术。但后来发现,这匹马其实是在作弊,是在回应周围人群的言语和视觉线索。

[## 张量流/cleverhans

一个用于构建攻击、构建防御和基准测试的对抗性示例库…

github.com](https://github.com/tensorflow/cleverhans) [## 欢迎来到 cleverhans 博客

与 cleverhans 相关的 Jekyll 博客

www.cleverhans.io](http://www.cleverhans.io/)

本着同样的精神,CleverHans 是一个 Python 库,它被开发来测试机器学习系统对敌对例子的脆弱性。如果你正在开发一个神经网络,想看看它有多健壮,用 CleverHans 测试一下,你会发现对它的脆弱程度有一个概念。这类似于使用 Burp 套件来测试代码注入漏洞。

渗透测试

就像任何形式的网络安全一样,你总是可以花钱请人来黑你,看看他们造成了多大的破坏。然而,你可以让他们签署一份文件,规定限制攻击者可以做什么。这让你知道自己在实际网络攻击中的脆弱程度。我不知道渗透测试公司目前是否提供这些类型的服务,但这不会让我感到惊讶。

最终意见

我希望你喜欢这篇文章,现在对这个有趣的网络安全新子领域有了更好的理解,它涉及通过各种攻击媒介损害机器学习模型。

这个领域仍然非常新,可以找到大量的研究论文,其中大部分可以在 arxiv 上找到,这意味着公众可以免费查看它们。我建议你读一读其中的一些——参考资料中的文章是一个很好的起点。

时事通讯

关于新博客文章和额外内容的更新,请注册我的时事通讯。

[## 时事通讯订阅

丰富您的学术之旅,加入一个由科学家,研究人员和行业专业人士组成的社区,以获得…

mailchi.mp](https://mailchi.mp/6304809e49e7/matthew-stewart)

参考

[1] Panda,p .,Chakraborty,I .,和 Roy,k .,针对对抗性攻击的安全机器学习的离散化解决方案。2019.

[2]张,h .,西塞,m .,多芬,y .,洛佩兹-帕兹,d .2017.

[3] Goodfellow,I .,Shlens,j .,和 Szegedy,c.《解释和利用对立的例子》。2014.

[4]n . paper not,p . McDaniel,I . good fellow,Jha,s .和 z .切利克,Swami,a .对机器学习的实用黑盒攻击。2015.

[5] Papernot,n .,McDaniel,p .,Jha,s .,弗雷德里克松,m .,切利克,Z.B .,和 Swami,a.《对抗环境中深度学习的局限性》。《第一届 IEEE 欧洲安全与隐私研讨会论文集》,第 372–387 页,2016 年。

[6] Kurakin,a .,Goodfellow,I .,和 Bengio,s,《大规模的对抗性机器学习》。2016.

[7] Tramer `,f ,, Kurakin,a ,, paper not,n ,, good fellow,I ,, Boneh,d ,,和 McDaniel,p,《整体对抗训练:攻击和防御》。2018.

深度学习的黑魔法

原文:https://towardsdatascience.com/hacks-for-doing-black-magic-of-deep-learning-ab5be5ff5f56?source=collection_archive---------24-----------------------

机器学习

建议,这将有助于你掌握 CNN 的培训

Photo by Greg Rakozy on Unsplash

总是超负荷

深度神经网络被称为“黑盒”,在那里很难进行调试。编写完训练脚本后,您无法确定脚本中没有任何错误,也无法预见您的模型是否有足够的参数来学习您需要的转换。

安德烈·卡帕西(Andrej Karpathy)关于过度饮食的建议就来自这里。

在训练开始时,在将所有数据输入到你的网络之前,试着在一个固定的批次上过量,没有任何增加,学习率非常小。如果它不会被过度拟合,这意味着,要么你的模型没有足够的学习能力来进行你需要的转换,要么你的代码中有一个 bug。

只有成功过拟合后,才合理的开始对整个数据进行训练。

选择您的标准化

归一化是一种强有力的技术,用于克服消失梯度并以更高的学习速率训练网络,而无需仔细的参数初始化。最初在 S.Ioffe 的论文中,提出了对整个批次的特征进行归一化,并且将激活转向单位高斯分布,以学习一个用于所有数据分布(包括测试数据)的通用均值和方差。当您需要预测影像的一个(或多个,如果是多标签分类)标签时,这种方法适用于所有分类任务。但是当你进行图像到图像的翻译任务时,情况就不同了。在这里,对整个数据集学习一个移动平均线和一个移动平均线可能会导致失败。在这种情况下,对于每一幅图像,作为网络的一个输出,你要获得独一无二的结果。
这就是实例规范化的由来。相反,在实例标准化中,为批中的每个图像独立计算统计数据。这种独立性有助于成功地训练网络,以完成图像超分辨率、神经风格转换、图像修复等任务。
所以要小心,不要在图像转换任务中使用迁移学习的常见做法,最著名的预训练网络有 ResNet、MobileNet、Inception。

越大(不总是)越好

众所周知,在训练深度神经网络的过程中,批量越大,收敛越快。而且,经验表明,在某个点之后,批量大小的增加会损害模型的最终性能。在工作中,N.S. Keskar 等人。艾尔。这与以下事实有关:在大批量的情况下,训练倾向于收敛到训练函数的尖锐极小值,而在小批量的情况下,收敛到平坦极小值。因此,在第一种情况下,来自训练函数的灵敏度很高,数据分布的微小变化将损害测试阶段的性能。

A Conceptual Sketch of Flat and Sharp Minima. The Y-axis indicates the value of the loss function and the X-axis the parameters.

但是 P. Goyal 等人。艾尔。⁴在论文《精确、大型迷你批处理 SGD:在 1 小时内训练 ImageNet》中表明,可以用高达 8K 的批处理大小训练 ImageNet,而性能不会下降。正如作者所说,优化困难是大型迷你批处理的主要问题,而不是泛化能力差(至少在 ImageNet 上)。作者提出了一个线性比例规则的学习率,取决于批量大小。规则如下

当小批量乘以 k 时,将学习率乘以 k。

ImageNet top-1 validation error vs. minibatch size.

小批量也可以被认为是正则化的形式,因为在这种情况下,您将有嘈杂的更新,这有助于避免快速收敛到局部最小值并提高泛化能力。

深度方向可分卷积并不总是你的救星

近年来,随着性能的提高,神经网络中的参数数量急剧增加,设计高效、低成本的神经网络成为当今的一个课题。
作为 Tensorflow⁵框架的一部分,谷歌提出的解决方案之一是深度方向可分离卷积,这是传统卷积层的一种修改,需要的参数更少。

让我们假设,我们有一层

fi - 输入过滤器

fo-输出滤波器

KH-内核的高度

kw-内核宽度

在卷积的情况下,层中的参数数量将为

N = kh * kw * fi * fo

我们按照输出滤波器的次数对每个输入滤波器进行卷积,然后求和。

在深度方向可分离卷积的情况下,它将是

N = kh * kw * fi + 1 * 1 * fo

我们用内核 (kh,kw) 对每个输入滤波器进行一次卷积,然后用内核 (1,1)按照输出滤波器的次数对这些中间滤波器进行卷积。

现在,让我们来看两个例子。

示例 1

假设该层有以下值

fi = 128

fo = 256

kh = 3

kw = 3

卷积层中的参数数量将是

3 * 3 * 128 * 256 = 294.912

深度方向可分离卷积中的参数数量为

3 * 3 * 128 + 1 * 1 * 256 = 99.456

在深度方向可分离卷积的情况下优势是明显的!!!

示例 2

现在让我们假设该层有其他值

fi = 128

fo = 256

kh = 1

kw = 1

卷积层中的参数数量将是

1 * 1 128 * 256 = 32.768*

深度方向可分离卷积中的参数数量为

1 * 1 128 + 1 * 1 * 256 = 32.896*

因此,我们可以看到,在第二种情况下,我们没有减少,而是增加了参数的数量。

参考

[1]安德烈·卡帕西博客,http://karpathy.github.io/2019/04/25/recipe/

[2]S.Ioffe,C. Szegedy 批量归一化:通过减少内部协变量移位加速深度网络训练,2015,第 32 届机器学习国际会议论文集,

[3]N. S. Keskar,D. Mudigere,J. Nocedal,M. Smelyanskiy,和 P. T. P. Tang,关于深度学习的大批量训练:泛化差距和尖锐极小值,2017,

[4]P. Goyal,P. Dollar,R. Girshick,P. Noordhuis,L. Wesolowski,A. Kyrola,,Y. Jia,K. He .,精准,大迷你批量 SGD:1 小时训练 ImageNet,2017,arXiv:1706.02677

[5] Tensorflow 官网

手部关键点检测

原文:https://towardsdatascience.com/hand-keypoints-detection-ec2dca27973e?source=collection_archive---------7-----------------------

用小训练数据集检测手部图像上的关键点位置。

H 训练一个网络来准确预测手指和手掌线的位置需要多少标记图像?我受到了这篇博文的启发,在这篇博文中,作者报告了 97.5%的分类准确率来分类一个人是否戴着眼镜,而每类只有 135 张训练图像。对于我的任务,从 15 个不同的人那里得到的 60 张带标签的图片能有多准确?

12 points to detect.

目的是在给定未标记的手部图像的情况下,精确估计 12 个点的 x 和 y 坐标。8 个点位于指尖和四个手指的根部,另外 4 个点沿手掌的中心线等距分布,第一个点和最后一个点正好位于中心线的起点和终点。

这些图片是我的朋友们的,他们友好地同意参加,每人最多 6 张图片,左手 3 张,右手 3 张。这些照片是用不同的智能手机在不同的白色背景和不同的光照条件下拍摄的。60 张图片都是我手动标注的。

对于神经网络处理,我使用了基于 PyTorch 的 fastai 库 v1.0.42。Jupyter 笔记本做 IDE,我笔记本的 NVidia GTX 960M 4Gb VRAM 做训练用。我下面分享的结果的总训练时间是 25 小时,非常合理的时间,因为这种 GPU 远远不是当今市场上最好的硬件!

该项目的主题是数据增强,幸运的是 fastai 提供了高效的图像转换算法,以及定义这些算法的干净 API。让我们深入细节。

数据和模型

标记的数据被分成 51 个训练图像和 9 个验证图像。验证包括出现在列车组中的人的 3 个图像,但也包括既不出现在列车组中也不与列车中的任何人共享相同背景\摄像机的两个人的 6 个图像。在预处理中,所有右侧图像都水平翻转。

All train images with labels.

在如此小的数据集上进行训练,数据增强是必要的,我对进入神经网络的每张图像都使用了随机缩放、包裹、旋转、亮度和对比度转换。fastai 库允许很容易地定义它,并且同样的仿射变换也应用于标签点。根据训练集的样本均值和方差对图像进行归一化,分别针对每个 RGB 通道进行归一化,并将其大小调整为 4:3 的比例,更具体地说是 384×288 像素。听起来要定义很多东西?令人惊讶的是,整个数据定义可以归结为下面一小段代码。

transforms = get_transforms(do_flip=False, max_zoom=1.05, max_warp=0.05, max_rotate=5, p_affine=1, p_lighting=1)data = (PointsItemList.from_folder(path=PATH/'train', recurse=False)
   .split_by_idxs(train_idx, valid_idx)
   .label_from_func(get_y_func, label_cls=PointsLabelList)
   .transform(transforms, tfm_y=True, size=(384,288),
              padding_mode='border', resize_method=ResizeMethod.PAD)
   .databunch(bs=6, num_workers=0, no_check=True)
   .normalize(stats))

该型号是带有定制头标准 resnet34 主干。从 resnet34 中删除了最后两个分类层,取而代之的是,我添加了 1x1 卷积以减少通道数,然后是两个完全连接的层。第二个完全连接的层输出 24 个激活,在通过 tanh 激活函数后,这些激活表示 12 个关键点的 x 和 y 坐标。

但有时用暗语说更好:

head_reg = nn.Sequential(
    nn.Conv2d(512,64,kernel_size=(1,1)),
    nn.BatchNorm2d(64),
    nn.ReLU(),
    Flatten(),
    nn.Linear(64 * 12 * 9, 6144),
    nn.ReLU(),
    nn.Linear(6144, 24),
    Reshape(-1,12,2),
    nn.Tanh())
learn = create_cnn(data, arch, metrics=[my_acc,my_accHD], loss_func=F.l1_loss, custom_head=head_reg)

上面的自定义头定义使用常规 PyTorch 语法和模块,除了我写的整形模块,它只是…嗯,整形张量。这种整形是必需的,因为我的标签坐标由 fastai 内部表示为 12 乘 2 张量,它需要匹配。此外,标签被重新调整为[-1;1]范围,这就是为什么 tanh 激活函数在这里是合适的。

优化目标是最小化列车组的 L1 损失。

还有两个额外的准确性指标来判断网络的性能和进度。在验证集上测量,这两个度量计算预测坐标落在实际标签的 0.1 和 0.01 误差内(分别对于第一和第二度量)的比例。这里标签的范围也是[-1;1],并且给定 384×288 像素的图像尺寸,可以容易地计算出第二(高精度)度量允许高度和宽度的最大误差分别为 1.92 和 1.44 像素。

神经网络训练

NN 训练是通过运行这行代码 40 次来完成的:

learn.fit_one_cycle(cyc_len = 100, max_lr = 1e-4)

除了使用 Adam optimizer 运行 100 个时期的常规训练之外,该 fastai 方法具有有趣的学习速率和动量策略,fastai 使用该策略在广泛的应用中提供更快的收敛。在 Sylvain Gugger 的博客文章中可以看到更多的细节。我发现它对于我的模型来说开箱即用。对于每 100 个历元周期,50 个历元后的误差比开始时高,但在周期结束时总是有所改善。看看下图中的典型错误发展。

Learning rate (left) and momentum (right) changing across 100 epochs, 8 batches in every epoch.

Losses for epochs 2500 to 2600, 8 batches per epoch. More data were added at epoch 2500.

这个学习速率和动量过程被称为 1 周期策略。据称,它也有助于对抗过度拟合,而且它似乎比我尝试的其他(公认有限的)选项收敛得更快。

为了理解不同变化的影响,我将培训分为 5 个步骤:

  1. 1500 个时期,resnet34 个主干层冻结在 ImageNet 预训练值上,并且仅训练自定义头层。仅使用 35 个训练图像的子集。
  2. 300 个纪元,解冻骨干层。
  3. 700 个纪元,增加了更多数据增强。具体来说,最大缩放 5%到 10%,最大扭曲 5%到 20%,最大旋转 5 度到 10 度。
  4. 500 个历元,从 4 个额外的人添加 16 个图像到训练集。使总的训练集大小达到 51。
  5. 1000 个周期,每个周期降低 20%的学习率,最后一个周期达到 1e-5 左右的学习率。记住,每个周期是 100 个纪元。

下图总结了进度:

Loss and accuracy metrics during the training on 4000 epochs.

这 5 个步骤中的每一步都对模型进行了额外的改进。数据扩充中的更多转换尤其重要,对验证集误差的改善有显著贡献。解冻和更多的数据也为验证集提供了很好的改进。另一方面,学习率的降低显著改善了训练集误差,而验证集误差则停滞不前。过度适应在这里是一个真正的问题,使用较小的学习率会使情况变得更糟。

总的来说,在训练期间,网络看到了 147k 个不同的变换图像,并且训练花费了 25.5 小时。

讨论结果

虽然训练集的最终平均 L1 误差是 0.46 像素,但是验证集的最终平均误差是 1.90 像素。此外,训练集的这个分数是针对经变换的图像的,而验证图像是未经变换的(更容易)。这是一个明显的过度拟合。

尽管如此,结果还是相当不错的,下图显示了验证集推理。请注意,绿点是实际的标签,红点是最终模型的预测。观察结果,似乎该模型使其预测更加全局化,并且在点之间更加相互依赖,而不是给予局部边缘更多的权重。

Validation set final results. Images 1, 2 and 3 are of people present in the train set, but different images. Images 4 to 6 and 7 to 9 are two people not appearing in the train set. Green points are actual labels and red points are predicted ones.

模型改进的明确方向是更多的数据和更智能的数据增强。平均误差仍然需要小 4-5 倍,才能达到良好的/生产水平的质量。

什么没用?

在不同位置添加下降层和应用权重衰减没有用。这可能是因为 1 周期策略的高学习率本身就是一种正则化形式,不需要更多的正则化。

替代 Adam 的其他优化方法没有显示出任何改进,或者取得了更差的结果。为不同的层组选择不同的学习速率也是一个死胡同。

如果从自定义头中删除 BatchNorm 层,即使学习率为 1e-5,模型也不再是可训练的。

我尝试了另外两种主干模型架构, DarknetU-Net ,它们有不同的定制头,但在我的实验中,它们的效果不如更简单的 resnet34。

最后,fastai 库在这一点上只有仿射变换(平行线映射成平行线)和透视变换(直线映射成直线)。鉴于数据扩充在这个项目中的重要性,我实现了一个额外的转换,见图片。然而,由于某种原因,它并没有导致改善。

结论

仅用 51 幅训练图像,所讨论的模型在独立图像上达到了相当好的预测精度。更多的数据和更多的数据扩充被证明可以提高精度,并在某种程度上成功地对抗过拟合。

Fastai 库是这个项目的合适工具,它提供了以下好处:

  1. 简洁但灵活的数据和模型定义
  2. 一系列用于数据扩充的内置仿射和透视变换,也可以自动变换标注点
  3. 智能学习率和动量策略似乎给出了更快的收敛并减少了过拟合

使用 Turi Create 和 Core ML 进行手动跟踪

原文:https://towardsdatascience.com/hand-tracking-with-turi-create-and-core-ml-f3f9d3b60f7a?source=collection_archive---------14-----------------------

在移动设备上进行实时手部跟踪的任务既有趣又具有挑战性。手是身体中较难检测和跟踪的部分之一。原因是手可能看起来非常不同,无论是形状(尽管这也适用于身体的其他部位)还是手指的位置。一手牌可以在几分钟内从出拳变成击掌。这意味着很难从不同的手状态、不同的角度收集带有适当注释的数据集。在这篇文章中,我们将看到如何使用 Turi Create 实现这一点的方法,Turi Create 是苹果用于创建核心 ML 模型的框架。

https://www.youtube.com/watch?v=q7cBgyssAg8

目标跟踪

这里我们需要的机器学习任务是物体检测。对象检测使您不仅可以检测当前相机帧中是否存在对象,还可以检测该对象的位置。这使您能够绘制一些视觉指示(如矩形)或在检测到的地方呈现一个虚拟模型。一旦找到该对象,您就可以使用视觉的跟踪功能,在感兴趣的对象移动时更新视觉指示。

如果你只想知道物体是否在图片上,你需要图像分类。为此,您可以使用 Create ML,这是苹果公司用于创建机器学习模型的另一个框架。

Turi 创建

Turi Create 是一个简化定制机器学习模型创建的工具,可以轻松导出为苹果的核心 ML 格式。这意味着,你不必成为机器学习专家,就可以在你的应用程序中添加一些智能。Turi Create 支持的任务有推荐、图像分类、对象检测、风格转换、活动分类等等。虽然它需要一点 Python 代码,但它仍然很容易上手,正如我们在这篇文章中看到的。

你可以在他们的 GitHub repo 上找到如何安装 Turi Create 的细节。基本上,您需要从终端执行以下操作:

pip install -U turicreate

一旦安装了 Turi Create,我们的下一个任务就是找到并准备数据。

准备数据

机器学习的最大挑战之一是找到足够的数据来训练机器学习模型。正如我们在开始时讨论的,检测一手牌的正确界限可能有点棘手。这就是为什么我们需要非常好的数据集。让我们看看我发现了什么。

我使用的数据集可以在找到。我试过几种选择,这一种被证明是最好的。它相当大,大约 6 GB,对于没有 GPU 的 Mac 机器来说,训练模型是相当具有挑战性的。我发现的其他选项有 EgoHandsOxford Hand 数据集。我在考虑将这三者结合起来,建立一个更好的机器学习模型,但我的 Mac 无法处理这一点。

现在,让我们看看数据。我使用的 VIVA 手部检测挑战的数据被分成两个文件夹,pos 和 posGt,都在 train 文件夹下。pos 文件夹包含所有图像,而 posGt 包含 csv 格式的所有注释,以及关于手(左手或右手)的信息。每个 csv 条目包含关于手的边界框的信息,使用 2D 图像平面中的左上角点、宽度和高度[x y w h]来描述。

Turi Create 期望什么?

另一方面,Turi Create 需要 SFrame,这是一种表格数据结构,可以将图像和相应的注释放入其中。注释是 JSON 格式的。每个图像都有一个对象数组,其中有键坐标和标签。坐标值包含边界框的信息,而标签则包含什么是边界框。在我们的例子中,不是左手就是右手。

[ {'coordinates': {'height': 104, 'width': 110, 'x': 115, 'y': 216}, 'label': 'left'}, ...]

坐标代表矩形的中心,以及宽度和高度,这与手部数据集中的数据组织方式不同(这里是左上角,而不是矩形的中心)。

为了创建该数据结构,我们将进行一些 Python 编码。以下脚本将把数据集的图像和 csv 文件转换成 SFrame,然后可用于创建 Turi Create 模型。

import turicreate as tc
import os
from os import listdir
from os.path import isfile, joinpath = 'train/posGt'
imagesDir = "train/pos"
files = [f for f in listdir(path) if isfile(join(path, f))]
annotations = []
labels = []
for fname in files:
 if fname != ".DS_Store":
  lines = tuple(open(path + "/" + fname, 'r'))
  count = 0
  entries = []
  for line in lines:
   if count > 0:
    words = line.split()
    passengerLabel = words[0]
    label = "left"
    if passengerLabel.find("left") == -1:
     label = "right"
    x = int(words[1])
    y = int(words[2])
    width = int(words[3])
    height = int(words[4])
    xCenter = x + width / 2
    yCenter = y + height / 2
    coordinates = {'height': height, 'width': width, 'x': xCenter, 'y': yCenter}
    entry = { 'coordinates' : coordinates, 'label' : label }
    entries.append(entry)
   count = count + 1
  annotations.append(entries)
sf_images = tc.image_analysis.load_images(imagesDir, random_order=False, with_path=False)
sf_images["annotations"] = annotations
sf_images['image_with_ground_truth'] = \
    tc.object_detector.util.draw_bounding_boxes(sf_images['image'], sf_images['annotations'])
sf_images.save('handsFrame.sframe')

为了实现这一点,我们首先浏览注释,解析 CSV 并创建坐标 JSON,同时还将左上坐标转换为中心坐标。接下来,我们使用 turicreate 包中的辅助函数加载图像。然后我们简单地放置注释,同时保持顺序。然后,将 SFrame 保存到手帧数据结构中。

还可以调用 sf_images.explore()来可视化边界框和图像。然而,你应该用少量的图片来测试,否则它会永远加载。

下一步是使用 SFrame 创建核心 ML 模型。这意味着我们应该进行另一轮 Python 编码。

import turicreate as tc# Load the data
data =  tc.SFrame('handsFrame.sframe')# Make a train-test split
train_data, test_data = data.random_split(0.8)# Create a model
model = tc.object_detector.create(train_data, feature='image', max_iterations=120)# Save predictions to an SArray
predictions = model.predict(test_data)# Evaluate the model and save the results into a dictionary
metrics = model.evaluate(test_data)# Export for use in Core ML
model.export_coreml('Hands.mlmodel')

我们在这里做的是首先加载我们用第一个脚本创建的 SFrame。然后,我们创建训练和测试数据,以 80–20%的比例随机分割。然后,使用 Turi Create 中的 object_detector.create 方法,我们用训练数据创建模型。您可以使用 max_iterations 属性(我的机器在 150 时崩溃,所以 120 是我能做的最好的)。之后,我们进行预测并评估模型。在最后一步中,我们以核心 ML 格式导出模型。

iOS 实施

现在我们有了核心 ML 模型,很容易将其集成到 iOS 应用程序中,只需将其拖放到 Xcode 项目中。

让我们检查一下创建的模型。这种模式被称为 Pipeline,它与苹果从 iOS 12 开始的愿景非常契合。它接受 416×416 大小的图像作为输入。作为输出,它提供了两个 MLMultiArrays,其中包含关于检测到的对象的置信度和坐标。

好消息是,您不必处理这些复杂的多维数组 Vision 框架会自动为您完成这项工作(针对使用 Turi Create 创建的管道模型),并为您提供一个VNRecognizedObjectObservation。该类型包含关于边界框的信息(作为一个 CGRect ),以及置信度。现在,当您运行 Vision 会话时,您只需要检查结果是否属于该类型,并绘制适当的边界框。

func handleNewHands(request: VNRequest, error: Error?) {
        DispatchQueue.main.async {
            //perform all the UI updates on the main queue
            guard let results = request.results as? [VNRecognizedObjectObservation] else { return }
            for result in results {
                print("confidence=\(result.confidence)")
                if result.confidence >= self.confidence {
                    self.shouldScanNewHands = false
                    let trackingRequest = VNTrackObjectRequest(detectedObjectObservation: result, completionHandler: self.handleHand)
                    trackingRequest.trackingLevel = .accurate
                    self.trackingRequests.append(trackingRequest)
                }

            }
        }
    }

一旦物体被检测到,我们可以告诉视觉跟踪它。为此,我们正在创建类型为 VNTrackObjectRequest 的对象,在这里我们通过已识别的对象观察并开始跟踪。每次调用完成处理程序 handleHand 时,我们都会更新跟踪矩形。

源代码

这是 iOS 实施中最重要的部分。你可以在这里找到完整的源代码,以及所有的视觉检测和跟踪细节。

结论

对我来说,这是一个非常有趣的机器学习练习。Turi Create 是一个非常强大的创建机器学习模型的工具。它创建了与 iOS 应用程序无缝协作的模型。

这个项目有很大的改进空间。首先,该模型应该用更多的数据进行训练,这样它就可以在所有光线条件和手的位置下正确地工作。此外,可以改进 iOS 代码,以更好地处理跟踪请求。现在,同一只手可能会识别出多个矩形。

另一件很酷的事情是不仅跟踪整只手,还跟踪手指。

这就是这篇文章的全部内容。你认为检测身体部位对我们未来的应用程序有用吗?一般来说机器学习怎么样?在下面的部分省去任何注释。

原载于 2019 年 1 月 19 日【martinmitrevski.com】

手工制作人工神经网络

原文:https://towardsdatascience.com/handcrafting-an-artificial-neural-network-e0b663e88a53?source=collection_archive---------11-----------------------

在这篇文章中,我已经实现了一个完全矢量化的人工神经网络代码,具有辍学和 L2 正则化。

Photo by JJ Ying on Unsplash

在本文中,我实现了一个在多个数据集上测试的人工神经网络的全矢量化 python 代码。此外,辍学和 L2 正则化技术的实施和详细解释。

强烈建议您完成人工神经网络的基本工作、前向传播和反向传播。

本文分为 10 个部分:

  1. 介绍
  2. 先决条件
  3. 导入我们的库
  4. 编码我们的激活函数和它们的导数
  5. 我们的神经网络课
  6. 初始化权重和偏差
  7. 正向传播
  8. 价值函数
  9. 反向传播
  10. 预测新数据集的标注

还有,

非常感谢任何形式的反馈。

1.介绍

人工神经网络是最美的监督的深度学习的基本概念之一。它可以用于执行多种任务,如二元或分类。看起来很容易理解和实现,除非你开始编写代码。在编写这样一个网络的过程中,小问题会突然出现,导致大错误并帮助你理解你之前错过的概念。因此,在本文中,我试图实现一个人工神经网络,它可能会帮助您节省正确编码和理解该主题的每个概念所需的几天时间。我会在文章中使用标准的符号和记号。

这篇文章太密集了,所以如果你对神经网络和它们的符号不熟悉,你可能会发现很难理解所有的东西。所以,我建议给它一些时间,慢慢来,参考我在文章中提供的资源。

Github 上有的完整代码

[## tirthasheshpatel/神经网络

演示和教学用手工制作的神经网络

github.com](https://github.com/tirthasheshpatel/Neural-Network)

2.先决条件

我假设你知道什么是神经网络,以及它们是如何学习的。如果你熟悉 Python 和像 numpy 这样的库,这很容易理解。此外,要轻松通过正向反向传播部分,还需要具备线性代数微积分的良好知识。此外,我强烈建议浏览一下吴恩达Coursera 上的课程视频。

3.导入我们的库

现在,我们可以开始编码一个神经网络。第一件事是导入我们实现网络所需的所有库。

我们将使用 pandas 来导入和清理我们的数据集。 Numpy执行矩阵代数和复杂计算最重要的库。像警告时间系统操作系统这样的库很少使用。

4.编码我们的激活函数和它们的导数

我们将在本文后面需要激活函数来执行正向传播。同样,我们需要在反向传播过程中激活函数的导数。所以,让我们编写一些激活函数。

我们已经编写了四个最流行的激活函数。首先是常规的老式乙状结肠激活功能。

Source

然后我们有 ReLU整流线性单元。我们将主要使用这个激活功能。注意,我们将保持 ReLU 0 在点 0 的导数。

Source

我们还有一个 ReLU 的扩展版本,叫做 Leaky ReLU 。它的工作方式就像 ReLU 一样,可以在一些数据集(不一定是所有数据集)上提供更好的结果。

然后我们有 tanh (双曲正切)激活函数。它也被广泛使用,并且几乎总是优于s 形

Source

另外, PHIPHI_PRIME 是分别包含激活函数及其衍生函数的 python 字典

5.我们的神经网络课

在本节中,我们将创建并初始化我们的神经网络类。首先,我们将决定在初始化期间使用哪些参数。我们需要:

  1. 每层中的神经元数量
  2. 我们希望在每一层中使用的激活函数
  3. 我们的特征矩阵( X ),特征沿行,示例沿列)。
  4. 标签对应特征矩阵(y 为行向量)
  5. 初始化我们的权重和偏差的方法
  6. 要使用的损失函数

记住这一点,让我们开始编码我们的神经网络的类:

现在我们有了一个正确记录的神经网络类,我们可以开始初始化网络的其他变量。

如图所示,我们将使用' self.m' 来存储数据集中的个示例self.n 会存储每层个神经元的信息。 self.ac_funcs 是各层激活函数的 python 列表。 self.cost 将在我们训练网络时存储成本函数的记录值。 self.acc 将存储训练后数据集达到的记录的精度。已经初始化了我们网络的所有变量,让我们进一步初始化我们网络的权重和偏差。

6.初始化权重和偏差

有趣的部分现在开始。我们知道权重不能初始化为零,因为每个神经元的假设变得相同,并且网络从不学习。所以我们必须有一些方法来打破对称性,让我们的神经网络学习。我们可以使用高斯正态分布来得到我们的随机值。由于这些分布的平均值为零,权重以零为中心,并且非常小。因此,网络开始快速有效地学习。我们可以使用 np.random.randn() 函数从正态分布中生成随机值。下面两行代码足以初始化我们的权重和偏差。

我们已经将权重初始化为来自正态分布的随机值。偏差已经被初始化为零。

7.正向传播

首先,让我们了解一下没有任何正则化的前向传播。

Source

我们有 Z 作为从一层到另一层的每个神经元连接的假设。一旦我们计算出Z ,我们将激活函数f 应用于Z 值,得到每层中每个神经元的激活 y 。这就是'纯香草'正向传播。但是正如 N.Shrivastava 等人在论文中所说的。艾尔。,2014 ,辍学是一项惊人的技术,可以提高神经网络的泛化能力,使其更加健壮。所以,我们先来对退学正规化有一些直觉。

辍学正规化的本质

Dropout,顾名思义,指的是“去激活我们神经网络中的一些神经元,并训练其余的神经元。

Source

为了提高性能,我们可以用不同的超参数值来训练数十或数百个神经网络,获得所有网络的输出,并取它们的平均值来获得我们的最终结果。这个过程是 计算上非常昂贵的 并且实际上不能实现。因此,我们需要一种更优化、计算成本更低的方法来做类似的事情。辍学调整以一种非常便宜和简单的方式做着完全类似的事情。事实上,辍学是优化性能的一种非常容易和简单的方式,最近它获得了很多关注,并且几乎在许多其他深度学习模型中到处使用。

为了实现辍学,我们将使用以下方法:

Source

我们将首先从伯努利分布中抽取随机值,如果概率高于特定阈值,则保留神经元,然后执行规则的正向传播。请注意,在预测新数据集的值或测试期间,我们不会应用 dropout。

实现辍学的代码

我们将 keep_prob 作为每层神经元存活的概率。我们将只保留概率高于存活概率或 keep_prob 的神经元。假设,它的值是 0.8。这意味着我们将停用每层中 20%的神经元,并训练其余 80%的神经元。请注意,我们在每次迭代后都会停用随机选择的神经元。这有助于神经元学习在更大的数据集上概括的特征。文[1]给出了一个非常直观的证明。

我们首先初始化列表,它将存储 ZA 的值。我们首先在 Z 中添加第一层的线性值,然后在 A 中添加第一层神经元的激活。这里, PHI 是一个 python 字典,包含了我们之前编写的激活函数。我们同样使用循环的计算所有其他层的 ZA 的值。注意,我们没有在输入层应用 dropout。我们最后返回 ZA 的计算值。**

8.价值函数

我们将使用标准的二元/分类交叉熵成本函数

我们已经用 L2 正则化 编码了我们的成本函数。参数λ被称为惩罚参数。这有助于权重值不会快速增加,从而更好地进行概化。这里,' a' 包含输出层的激活值。我们还有函数 _cost_derivative 来计算关于输出层激活的成本函数的导数。我们将在反向传播中用到它。**

9.反向传播

这里有一些公式,我们将需要执行反向传播。

Source

我们将在深度神经网络上实现这一点。右边的公式是完全矢量化的,因此我们将使用它们。一旦你理解了这些公式,我们就可以开始编码了。

我们将历元alpha (学习率)、 _lambdakeep_probinterval 作为我们函数的参数来实现反向传播。在文档注释中给出了它们的描述。

我们从正向传播开始。然后我们计算我们的成本函数的导数为 delta 。现在,对于每一层,我们计算 delta_wdelta_b ,其包含关于我们网络的权重和偏差的成本函数的导数。然后我们根据各自的公式更新 delta权重、偏差。在从最后一层到第二层更新权重和偏差之后,我们更新第一层的权重和偏差。我们这样做几次迭代,直到权重和偏差的值收敛。**

重要提示:这里可能的一个大错误是在更新权重和偏差之后更新德尔塔。这样做会导致非常糟糕的情况 消失/爆炸渐变问题****

我们的大部分工作都在这里完成了,但我们仍然需要编写能够预测新数据集结果的函数。因此,作为我们的最后一步,我们将编写一个函数来预测新数据集的标签。

10.预测新数据集的标注

这一步非常简单。我们只需要执行前向传播,而没有丢失正则化。我们在测试期间不应用退出正则化,因为我们需要所有层的所有神经元为我们提供正确的结果,而不仅仅是一些随机值。

如图所示,我们将返回输出层的激活结果。

整个代码

这是你自己实现一个人工神经网络的全部代码。我添加了一些代码,用于打印我们训练网络时的成本和准确性。除此之外,一切都一样。

恭喜你!我们终于完成了神经网络的编码。现在,我们可以在不同的数据集上测试我们的网络。

测试我们的神经网络

我们将在著名的 MNIST 数字分类数据集上测试我们的网络。我们将只使用 8000 张图像来训练我们的网络,并在 2000 张其他图像上进行预测。可以在 Kaggle 上获取数据集。

我训练了两个 32 和 16 个神经元的隐层神经网络。我在两层都使用了 ReLU 激活函数。在用惩罚参数 1.0* 和学习率 0.1 训练网络 2500 个时期后,我们得到:*

成本与时代的关系图如下所示:

我们在训练集和测试集上都取得了相当好的准确率。通过使用像网格搜索随机网格搜索等技术来调整超参数,我们可以获得更高的精度。

此外,可以随意尝试超参数、激活函数和数据集的不同值。如果你认为代码还有改进的地方,请在 GitHub 或评论区分享。非常感谢任何形式的反馈。

对你来说有些挑战

如果你已经理解了我上面提供的神经网络的代码,那么这里有一些你可以做的更好的改变。

  1. 尝试编码 softmax 激活功能 并使其工作。
  2. 比方说,我想停用第一层 30%的神经元,第二层 50%的神经元。尝试编码一个网络,在其中,我可以为每一层使用不同的 keep_prob 值。
  3. 尝试执行 小批量梯度下降 算法。它对于手写数字分类非常有用。

我希望你喜欢这篇文章和挑战。祝你数据科学之旅愉快!

使用专门为其制作的损失来处理类不平衡数据

原文:https://towardsdatascience.com/handling-class-imbalanced-data-using-a-loss-specifically-made-for-it-6e58fd65ffab?source=collection_archive---------4-----------------------

这篇文章是对 Google 在 CVPR 19 年会上发表的一篇名为基于有效样本数的等级平衡损失的论文的评论。

TL;DR——它针对最常用的损失(softmax 交叉熵、焦点损失等)提出了一种分类加权方案。)快速提高准确性,尤其是在处理类别高度不平衡的数据时。

链接到本文的实现(使用 py torch)——GitHub

有效样本数

在处理长尾数据集(大部分样本属于很少的几个类,而许多其他类的支持度很低)时,决定如何对不同类的损失进行加权可能会很棘手。通常,权重被设置为类支持的倒数或类支持的平方根的倒数。

Traditional re-weighting vs proposed re-weighting

然而,如上图所示,这是过冲的,因为随着样本数量的增加,新数据点的额外好处会减少。新添加的样本很有可能是现有样本的近似副本,主要是在大量数据扩充(如重新缩放、随机裁剪、翻转等)时。)在训练神经网络时使用。通过样本的有效数量重新加权给出了更好的结果。

样本的有效数量可以想象为N 个样本将覆盖的实际体积,其中总体积 N 由总样本数表示。

Effective number of samples

形式上,我们把它写成:

Effective number of samples

这里,我们假设新样本只会以两种方式与先前采样的数据量进行交互:要么完全覆盖,要么完全在外(如上图所示)。有了这个假设,利用归纳法就可以很容易地证明上面的表达式(证明参考论文)。

我们也可以这样写:

Contribution of every sample

这意味着第 j 个样本对样本的有效数量贡献了 Beta^(j-1。

上式的另一个含义是,如果β= 0,则 En = 1。还有,En → n 为β→1。后者可以很容易地用洛必达法则来证明。这意味着当 N 很大时,有效样本数与样本数 N 相同。在这种情况下,唯一原型数 N 很大,每个样本都是唯一的。然而,如果 N=1,这意味着所有数据都可以用一个原型来表示。

类别平衡损失

在没有额外信息的情况下,我们无法为每个类别设置单独的β值,因此,使用整个数据,我们将它设置为特定值(通常设置为 0.9、0.99、0.999、0.9999 中的一个)。

因此,类平衡损失可以写成:

CB Loss

这里, L(p,y) 可以是任意损失函数。

类别平衡焦点损失

Class-Balanced Focal Loss

焦点丢失的原始版本有一个 alpha 平衡变体。相反,我们将使用每个类别的有效样本数对其进行重新加权。

类似地,这样的重新加权项也可以应用于其他著名的损失(sigmoid 交叉熵、softmax 交叉熵等)。)

履行

在开始实施之前,在使用基于 sigmoid 的损失进行训练时需要注意一点——使用 b = -log(C-1)初始化最后一层的偏差,其中 C 是类的数量而不是 0。这是因为设置 b=0 会在训练开始时导致巨大的损失,因为每个类的输出概率接近 0.5。因此,我们可以假设类 prior 是 1/C,并相应地设置 b 的值。

类别的权重计算

calculating normalised weights

上面几行代码是一个简单的实现,用于获取权重并将其归一化。

getting PyTorch tensor for one-hot labels

这里,我们得到了权重的一个热点值,这样它们可以分别与每个类的损失值相乘。

实验

类平衡提供了显著的好处,尤其是当数据集高度不平衡时(不平衡= 200,100)。

结论

使用有效样本数的概念,我们可以解决数据重叠的问题。由于我们不对数据集本身做出任何假设,因此重新加权条款通常适用于多个数据集和多个损失函数。因此,类不平衡的问题可以通过更合适的结构来解决,这一点很重要,因为大多数真实世界的数据集都存在大量的数据不平衡。

参考

[1]基于有效样本数的类平衡损失:【https://arxiv.org/abs/1901.05555

处理不平衡的数据:

原文:https://towardsdatascience.com/handling-imbalanced-data-4fb691e23fe9?source=collection_archive---------23-----------------------

预测客户取消电话服务

在这个项目中,我试图预测取消电话服务的客户,以便采取措施留住这些客户。
我使用的数据集来自openml.org,你可以点击这里直接链接到这个数据集。

不平衡数据集

这个数据集是不平衡的,这给它带来了一些挑战。首先让我们来看看不平衡:

Amount of customers staying or cancelling

为了解决这个问题,我使用了 SMOTE 方法对数据进行上采样。我也试着用 ADYSN,但是效果不太好。这可能是由于 ADYSN 也产生随机噪声,对于这个问题,只是降低了模型预测结果的能力。

由于数据集的情况,我决定优化召回率,同时在一定程度上仍然考虑准确性。这是因为希望正确预测尽可能多的客户离开,同时尽可能降低误报率。

我用成本收益分析给模型打分。计算方法如下:根据我掌握的资料,平均每月账单是 60 美元。然后我计算了 24 个月合同的长度,结果是 1440 美元。然后,我决定促销金额为 500 美元,这只是为了便于计算。
任何真正的否定,或被正确预测为留下的客户,不加或减任何东西。
任何假阴性,或者将取消但被预测为留下的客户,每个都将损失 1,440 美元。
任何真阳性,或将要取消并被预测为取消的客户,将被提供促销,因此收益将是$1,440 - $500 = $940。
任何误报,或预测离开但没有离开的客户,将被提供促销,因此将损失 500 美元。

特征的相关性

我在开始时注意到的另一件事是关于特性的相关性:

与目标没有太多的相关性,这是“类”的特征,一些在大约 0.2,分钟和费用也几乎%100 相关。这是有道理的,因为在当时,这些数据是账单中最重要的部分。

建模

当我在考虑功能的数量和相关性问题时,一方面在费用和分钟之间有很多相关性,但另一方面没有多少主要功能。因此,我认为随机森林最适合这种类型的数据,因为它对每棵树的特征和数据进行随机化,然后对整个森林进行预测。我用基本的默认超级参数测试了几种不同的方法,随机森林确实表现最好。在对测试数据进行了几次优化后,我得到的结果是这样的:

这样做的成本效益是 71,320 美元,或者说,如果我们预测要离开的 121 个客户都留下来,那么留住将要离开的客户的实际收益将是每个先前实际离开的客户 589 美元。
在进行 5 次交叉验证后,测试集的平均成本收益为 51,152 美元。

交叉验证

在处理不平衡数据时,只需注意交叉验证。因为你应该只对训练数据进行 smote,然后对真实的测试数据进行预测,这就限制了你如何进行交叉验证。常规的交叉验证方法对此不起作用。
为了解决这个问题,我使用了分层的 K 型折叠,它从每个类别中提取相同的数量,因此每个折叠的结果都是相似的。
然后我得到每一个分裂,对训练数据应用 SMOTE,在此基础上训练模型。保存每次折叠的分数,然后进行平均。

下面是示例代码:

skf = StratifiedKFold(n_splits=5) # Set up the splitsX_trains2 = {} # Make dictionaries for each train and test split
X_tests2 = {}
y_trains2 = {}
y_tests2 = {}
for i, (train_index, test_index) in enumerate(skf.split(X, y)):# Get the folds and make the index number the key in each dict
 X_trains2[i] = X.loc[train_index]
 X_tests2[i] = X.loc[test_index]
 y_trains2[i] = y[train_index]
 y_tests2[i] = y[test_index]scores2 = [] # Make a list to put all scores into 
train = 0 # Setup to save all train scores 
test = 0 # Setup to save all test scores
cb = 0 # Cost-Benefit numbersfor i in range(5):
 smoted_x, smoted_y = sm.fit_sample(X_trains3[i], y_trains3[i])     # SMOTE the training splits
 rf5.fit(smoted_x, smoted_y) # Fit the model
 trainpred = rf5.predict(X_trains3[i]) # Predict train (not Smoted)
 testpred = rf5.predict(X_tests3[i]) # Predict test
 train += recall_score(y_trains3[i], trainpred) # Total all train recall scores for each loop
 test += recall_score(y_tests3[i], testpred) # Total all train recall scores for each loop

 cb += cost_benefit(y_tests3[i], testpred) # Total the Cost-benefit scores scores2.append((i, recall_score(y_trains3[i], trainpred), recall_score(y_tests3[i], testpred))) # Append a tuple of index, train recall total and test recall total) print(f’\n{recall_score(y_tests3[i], testpred)}’)
 cm(y_tests2[i], testpred) # Print a confusion matrix
 print(classification_report(y_tests3[i], testpred))
print(train/5, test/5, cb/5) # Print the total scores / # of Folds

特征重要性

有了一个好的工作模型后,我就可以查看特性的重要性,看看我能从中找出什么来改善模型的解释能力,然后就能在未来的业务决策中使用它。

我做了一些功能工程,将所有的分钟和所有的费用合并成两个功能。因为这两个特性高度相关,所以我删除了分钟列。我还删除了所有的 call number 列,以及 state 和 account_length 列,因为它们的特性重要性接近于 0。
我还放弃了 number_vmail_messages,因为它与语音邮件计划高度相关。
我总结了 4 个特征,它们具有相应的重要性:

Top Features

运行仅具有这些特征的模型,并进行 5 次交叉验证,可带来 56,964 美元的成本效益。
这向我展示了通过基于特征重要性组合和删除特征,模型变得更好。

基于重要性的特征分析

在研究了特征关系后,我发现的最重要的事情是,任何账单超过 72 美元的人都更有可能离开。从这个视频中可以看出:

超过 72 美元钞票的数字如下:
离开:315
留下:247

考虑到一般数据中有 85%到 15%的离职率,让更多的人以更高的离职率离开是非常重要的。在检查账单超过 72 美元的顾客如何与其他特征交叉时,这也是一致的。
如果我们向平均账单超过 72 美元的每个人提供 500 美元的促销活动,那么每位入住的顾客将获得 547 美元,这与我们从整个数据集获得的金额相似。
我建议对此进行更多的调查,看看如何最好地处理账单较高的客户,以留住更多的客户。

推荐

我最后的建议是向顾客提供某种形式的促销。
弄清楚应该提供多少优惠,什么样的促销最能成功留住顾客。
多研究如何用更高的账单留住顾客。

请留下反馈,如果你对此有想法,如果你想看到它的代码,可以在这里看到。

使用重采样处理不平衡数据

原文:https://towardsdatascience.com/handling-imbalanced-data-using-re-sampling-872b6db4fe67?source=collection_archive---------48-----------------------

不平衡数据是高级分析解决方案中普遍存在的问题。

Photo By Lauraljstc from Pixabay

介绍

不平衡类数据是机器学习中常见的问题。除非以适当的方式处理,否则它可能会导致一个假装为最佳执行模型的模型,同时偏向于特定的类。

例如,考虑以下包含 10 个类的数据集,但是每个类的出现是不均匀分布的。使用此数据集训练的模型偏向于 C1、C2、C4 和 C5,但很少预测 C7、C8、C9 和 C10 类。

Imbalanced classes— Image by Author

重新取样

合成少数过采样技术(SMOTE) [1]

这是一种流行且成功的方法,它创造了少数民族阶层的新样本,而不仅仅是复制样本。考虑前面的场景,其中我们只有 C10 的 3 个样本(C10_D_1、C10_D_2 和 C10_D_3)(因为我们只有 3 个样本,所以这三个样本都被视为邻居),SMOTE 在 3 个数据点之间创建线,并从线中选取合成数据点(C10_S_1 和 C10_S_2)。下图说明了我们所讨论内容的图形解释。

Features Space— Image by Author

这可以使用名为“ scikit-learn-contribscikit-learn 的扩展版本来执行,下面的代码段显示了使用 scikit-learn-contrib 使用 SMOTE。

SMOTE 算法有一些属性值需要优化;不幸的是,由于 SMOTE 的评分和转换方法的不变性,流水线和随机化搜索 CV 不能用于执行自动优化。因此,我们需要手动阻止和播放属性值来进行优化。有关 SMOTE 和属性的更多详细信息,请参考[2]。

过采样[3]、[4]

这种方法为少数民族班级复制一个样本以平衡班级。这里我们逐步讨论如何实现过采样。

步骤 1 :识别数据中优势类的频率(frequency _ of _ majority _ class)。

第二步:将数据集一分为二(数据集包含优势类(DF_FOR_MAJORITY)和次要类(DF_FOR_MINORITY))。

第三步:获取辅修课列表。

步骤 4 :使用重采样方法复制少数类样本。

这里我们使用n _ samples=frequency _ of _ majority _ class来指定要生成的样本数。

步骤 5 :连接 DF_FOR_MAJORITY 和过采样数据(DF_FOR_MINORITY_OVERSAMPLED)。

下表是由于过采样而产生的输出。

Balanced classes — Image by Author

欠采样[3]

这种方法移除多数类的样本,并尝试与少数类的样本数量相匹配。

不同之处在于,在步骤 1 中,考虑次要类别的频率,而不是识别主要类别的频率。

注意: 这种方法通常不被推荐,因为它会丢失大多数类的有用行为。

最后的想法

我们讨论了解决不平衡数据问题的三种方法,根据问题的背景,我们应该选择正确的方法。它确保高级分析解决方案是有意义的,而不是有偏见的特定行为。

参考

[1] N. V. Chawla,K. W .鲍耶,L. O.Hall,W. P. Kegelmeyer,“SMOTE:合成少数过采样技术”,人工智能研究杂志,321–357,2002 年。

[2]勒迈特 g .,诺盖拉 f .,和阿迪达斯 C. (2016)。“不平衡学习:一个 Python 工具箱来解决机器学习中不平衡数据集的诅咒”。更正 abs/1609.06570。

[3]m .库巴特和 s .马特温(1997 年)。解决不平衡训练集的诅咒:单边选择。收录于:第十四届机器学习国际会议论文集,第 179-186 页,田纳西州纳什维尔。摩根·考夫曼。

[4]凌和李(1998 年)。直接营销中的数据挖掘问题及解决方案。《第四届知识发现和数据挖掘国际会议(KDD-98)会议录》。AAAI 出版社。

机器学习中不平衡数据集的处理

原文:https://towardsdatascience.com/handling-imbalanced-datasets-in-machine-learning-7a0e84220f28?source=collection_archive---------0-----------------------

入门

面对不平衡的班级问题,应该做什么,不应该做什么?

本帖与 约瑟夫·罗卡 共同撰写。

介绍

假设你在一家特定的公司工作,你被要求创建一个模型,根据你所掌握的各种测量结果,预测一个产品是否有缺陷。你决定使用你最喜欢的分类器,对数据进行训练,瞧,你得到了 96.2%的准确率!你的老板很惊讶,决定使用你的模型,不做任何进一步的测试。几周后,他走进你的办公室,强调你的模型毫无用处。事实上,您创建的模型从用于生产时起就没有发现任何缺陷产品。
经过一些调查,您发现贵公司生产的产品中只有大约 3.8%有缺陷,而您的模型总是回答“无缺陷”,因此准确率为 96.2%。你得到的那种“幼稚”的结果是由于你正在处理的不平衡的数据集。本文的目标是回顾不同的方法,这些方法可以用来处理不平衡类的分类问题。

概述

首先,我们将概述不同的评估指标,这些指标有助于发现“幼稚行为”。然后,我们将讨论一大堆重新处理数据集的方法,并说明这些方法可能会产生误导。最后,我们将展示返工问题在大多数情况下是继续进行的最佳方式。

一些由(∞)符号表示的小节包含了更多的数学细节,可以跳过而不影响对这篇文章的整体理解。还要注意,在接下来的大部分内容中,我们将考虑两类分类问题,但是推理可以很容易地扩展到多类情况。

发现“幼稚行为”

在第一部分中,我们想提醒不同的方法来评估一个训练过的分类器,以确保检测到任何类型的“幼稚行为”。正如我们在简介示例中看到的,准确性虽然是一个重要且不可避免的指标,但可能会产生误导,因此应该谨慎使用,并与其他指标一起使用。让我们看看还可以使用哪些其他工具。

混淆矩阵、精确度、回忆和 F1

在处理分类问题时,一个好的简单的度量标准是混淆矩阵。这个指标给出了一个模型表现如何的有趣概述。因此,它是任何分类模型评估的一个很好的起点。我们在下图中总结了可以从混淆矩阵中得出的大多数指标

The confusion matrix and the metrics that can be derived from it.

让我们简单描述一下这些指标。模型的准确性基本上是正确预测的总数除以预测的总数。类别的精度定义了当模型回答一个点属于该类别时结果的可信度。类别的召回表示模型能够多好地检测该类别。一个类的 F1 值由精度和召回率的调和平均值(2×精度×召回率/(精度+召回率))给出,它将一个类的精度和召回率结合在一个度量中。

对于给定的类,召回率和精确度的不同组合具有以下含义:

  • 高召回率+高精度:该类被模型完美处理
  • 低召回率+高精确度:模型不能很好地检测类,但是当它检测到类时是高度可信的
  • 高召回率+低精确度:该类被很好地检测到,但是该模型还包括其他类的点
  • 低召回率+低精确度:模型对类的处理很差

在我们的介绍性示例中,我们有以下 10000 种产品的混淆矩阵。

The confusion matrix of our introductory example. Notice that the “defective” precision can’t be computed.

如前所述,准确率为 96.2%。无缺陷类别精度为 96.2%,缺陷类别精度不可计算。无缺陷类别的召回率为 1.0,这是完美的(所有无缺陷产品都被贴上了这样的标签)。但是缺陷类的召回率是 0.0,这是最差的情况(没有检测到缺陷产品)。因此,我们可以得出结论,我们的模型对于这个类做得不好。有缺陷产品的 F1 分数不可计算,无缺陷产品的 F1 分数为 0.981。在本例中,查看混淆矩阵可能会导致重新思考我们的模型或目标(正如我们将在以下部分看到的)。它可以避免使用无用的模型。

ROC 和 AUROC

另一个有趣的度量是 ROC 曲线(代表接收器工作特性),它是根据给定的类别定义的(在下文中我们将表示为 C)。

假设对于给定的点 x,我们有一个模型,输出这个点属于 C 的概率:P(C | x)。基于这种概率,我们可以定义一个判定规则,即当且仅当 P(C | x)≥T 时,x 属于 C 类,其中 T 是定义我们的判定规则的给定阈值。如果 T=1,只有当模型 100%确信某个点属于 C 时,该点才被标记为属于 C。如果 T=0,每个点都被标记为属于 c。

阈值 T 的每个值产生一个点(假阳性、真阳性),然后,ROC 曲线是当 T 从 1 变化到 0 时产生的点的集合所描述的曲线。这条曲线从点(0,0)开始,到点(1,1)结束,并且是递增的。一个好的模型会有一条从 0 到 1 快速增加的曲线(意味着只需要牺牲一点点精度就可以获得高召回率)。

Illustration of possible ROC curves depending on the effectiveness of the model. On the left, the model has to sacrifice a lot of precision to get a high recall. On the right, the model is highly effective: it can reach a high recall while keeping a high precision.

基于 ROC 曲线,我们可以建立另一个更容易使用的指标来评估模型:AUROC,即 ROC 曲线下的面积。AUROC 有点像总结整个 ROC 曲线的标量值。可以看出,AUROC 在最佳情况下趋向于 1.0,在最差情况下趋向于 0.5。
同样,好的 AUROC 分数意味着我们正在评估的模型不会牺牲很多精度来获得对观察类(通常是少数类)的良好召回。

真正的问题是什么?

在试图解决这个问题之前,让我们试着更好地理解它。为此,我们将考虑一个非常简单的例子,它将允许我们快速回顾两类分类的一些基本方面,并更好地掌握不平衡数据集的基本问题。这个例子也将在下面的章节中使用。

不平衡的例子

让我们假设我们有两个班级:C0 和 C1。来自 C0 类的点遵循均值为 0、方差为 4 的一维高斯分布。来自 C1 类的点遵循均值为 2、方差为 1 的一维高斯分布。假设在我们的问题中,C0 类代表了数据集的 90%(因此,C1 类代表了剩下的 10%)。在下图中,我们描绘了一个包含 50 个点的代表性数据集,以及两个类按正确比例的理论分布

Illustration of our imbalanced example. Dotted lines represent the probability densities of each class independently. Solid lines also take into account the proportions.

在这个例子中,我们可以看到 C0 类的曲线总是在 C1 类的曲线之上,因此,对于任何给定点,该点从 C0 类中提取的概率总是大于从 C1 类中提取的概率。数学上,使用基本的贝叶斯规则,我们可以写

我们可以清楚地看到先验的影响,以及它如何导致一个类总是比另一个类更有可能的情况。

所有这些意味着,即使从完美的理论角度来看,我们知道,如果我们必须在这些数据上训练一个分类器,当总是回答 C0 时,分类器的准确性将是最大的。因此,如果目标是训练一个分类器以获得尽可能好的准确性,那么这不应该被视为一个问题,而只是一个事实:有了这些特征,我们能做的最好的事情(就准确性而言)就是总是回答 C0。我们必须接受它。

关于可分性

在给定的例子中,我们可以观察到这两个类是不可分的(它们彼此相距不远)。然而,我们可以注意到,面对不平衡的数据集并不一定意味着这两个类不能很好地分离,因此,分类器不能在少数类上做得很好。例如,假设我们仍然有两个类 C0 (90%)和 C1 (10%)。C0 的数据遵循均值为 0、方差为 4 的一维高斯分布,而 C1 的数据遵循均值为 10、方差为 1 的一维高斯分布。如果我们像以前一样绘制数据,那么我们有

In our Gaussian example, if the means are different enough with respect to the variances, even imbalanced classes can be well separable.

这里我们看到,与前一种情况相反,C0 曲线并不总是高于 C1 曲线,因此,有些点更可能来自 C1 类而不是 C0 类。在这种情况下,这两个类足够分开以补偿不平衡:一个分类器不一定总是回答 C0。

理论最小误差概率(∞)

最后,我们应该记住一个分类器有一个理论上最小的错误概率。对于这种分类器(一个特征,两个类别),我们可以提到,在图形上,理论上的最小误差概率是由两条曲线的最小值下面的面积给出的。

Illustration of the theoretical minimal error for different degree of separability of two classes.

我们可以用数学方法恢复这种直觉。实际上,从理论的角度来看,最好的可能分类器将为每个点 x 选择两个类别中最可能的一个。这自然意味着,对于给定的点 x,最佳理论误差概率由这两类中可能性较小的一类给出

然后我们可以表示总的错误概率

该面积是上述两条曲线中最小值下方的面积。

返工数据集并不总是一个解决方案

首先,当面对不平衡的数据集时,第一个可能的反应是认为数据不代表现实:如果是这样,我们假设真实数据几乎是平衡的,但在收集的数据中存在比例偏差(例如,由于收集方法)。在这种情况下,尝试收集更具代表性的数据几乎是强制性的。现在,让我们看看,当数据集不平衡时,我们能做些什么,因为现实就是如此。在接下来的两节中,我们将介绍一些经常被提及的处理不平衡类和处理数据集本身的方法。特别是,我们讨论了与欠采样、过采样和生成合成数据相关的风险,以及获得更多功能的好处。

欠采样、过采样和生成合成数据

这些方法通常被认为是在数据集上安装分类器之前平衡数据集的好方法。简言之,这些方法对数据集的作用如下:

  • 欠采样包括从多数类中采样,以便只保留这些点的一部分
  • 过采样包括从少数类中复制一些点,以增加其基数
  • 生成合成数据包括从少数类创建新的合成点(例如参见 SMOTE 方法)以增加其基数

所有这些方法都旨在重新平衡(部分或全部)数据集。但是我们应该重新平衡数据集,使两个类的数据一样多吗?还是多数阶级应该保持最具代表性?如果是这样,我们应该以什么样的比例进行再平衡?

Illustration of the effect that different degrees of majority class undersampling have on the model decisions.

当使用重采样方法时(例如,从 C0 获得的数据与从 C1 获得的数据一样多),我们在训练期间向分类器显示了两个类别的错误比例。以这种方式学习的分类器在未来的真实测试数据上将比在未改变的数据集上训练的分类器具有更低的准确度。事实上,了解类的真实比例对于分类新点非常重要,而在对数据集进行重采样时,这些信息已经丢失。

因此,如果这些方法不能被完全拒绝,它们应该被谨慎地使用:如果有目的地选择新的比例(我们将在下一节看到这一点),它可以导致一个相关的方法,但是仅仅重新平衡类而不进一步考虑这个问题也可能是一个没有意义的事情。总结这一小节,让我们假设用类似重采样的方法修改数据集正在改变现实,因此需要小心并记住这对我们分类器的输出结果意味着什么。

获取附加功能

我们在上一小节中讨论了这样一个事实,即对训练数据集进行重采样(修改类的比例)是不是一个好主意取决于分类器的真正目的。我们特别看到,如果两个类别不平衡,不能很好地分离,并且我们的目标是一个尽可能准确的分类器,那么得到一个总是回答同一个类别的分类器不一定是一个问题,而只是一个事实:没有什么比这些变量更好的了。

但是,通过使用附加要素(或更多要素)丰富数据集,仍有可能获得更好的精度结果。让我们回到我们的第一个例子,在这个例子中,类是不可分的:也许我们可以找到一个新的附加特征来帮助区分这两个类,从而提高分类器的准确性。

Looking for additional features can help separate two classes that were not initially separable.

与前一小节中提到的建议改变数据的真实性的方法相比,这种用更多来自现实的信息来丰富数据的方法是一个更好的想法。

返工问题更好

到目前为止,结论是相当令人失望的:如果数据集是真实数据的代表,如果我们不能获得任何额外的特征,如果我们的目标是具有最佳可能准确性的分类器,那么“幼稚行为”(回答总是相同的类)不一定是问题,应该被接受为事实(当然,如果幼稚行为不是由于所选分类器的有限能力)。

那么如果我们对这些结果仍然不满意呢?在这种情况下,这意味着,以这样或那样的方式,我们的问题没有被很好地陈述(否则我们应该照原样接受结果),并且我们应该重新工作以便获得更令人满意的结果。让我们看一个例子。

基于成本的分类

感觉得到的结果不好可能是因为目标函数没有被很好地定义。到目前为止,我们假设我们的目标是一个具有高精度的分类器,同时假设两种错误(“假阳性”和“假阴性”)具有相同的成本。在我们的例子中,这意味着我们假设当真实标签是 C1 时预测 C0 和当真实标签是 C0 时预测 C1 一样糟糕。误差是对称的。

让我们考虑一下有缺陷(C1)和无缺陷(C0)产品的介绍性例子。在这种情况下,我们可以想象,与错误地将一个没有缺陷的产品贴上有缺陷的标签(生产成本损失)相比,没有检测到一个有缺陷的产品会给公司带来更大的成本(客户服务成本,如果有危险的缺陷,可能的司法成本……)。现在,当真正的标签是 C1 时预测 C0 比当真正的标签是 C0 时预测 C1 要糟糕得多。误差不再是对称的。

然后更具体地考虑我们有以下成本:

  • 当真实标签为 C1 时预测 C0 的成本为 P01
  • 当真实标注为 C0 时,预测 C1 的成本为 P10(0 < P10 < < P01)

然后,我们可以重新定义我们的目标函数:我们不再以最佳精度为目标,而是寻找更低的预测成本。

理论最小成本(∞)

从理论的角度来看,我们不想最小化上面定义的误差概率,但是预期的预测成本由下式给出

其中 C(。)定义了分类器函数。因此,如果我们想要最小化预期的预测成本,理论上的最佳分类器 C(。)最小化

或者等价地,除以 x 的密度,C(。)最小化

因此,利用这个目标函数,从理论角度来看,最佳分类器将是这样的:

请注意,当成本相等时,我们恢复了“经典”分类器的表达式(侧重于准确性)。

概率阈值

在我们的分类器中考虑成本的第一种可能的方法是在训练之后进行。这个想法是,首先,训练一个分类器的基本方法是输出以下概率

无需承担任何成本。那么,预测的类将是 C0 if

C1 则不然。

在这里,我们使用哪个分类器并不重要,只要它输出给定点的每个类的概率。在我们的主要示例中,我们可以在数据上拟合一个贝叶斯分类器,然后我们可以重新加权获得的概率,以调整带有成本误差的分类器,如上所述。

Illustration of the probability threshold approach: the outputted probabilities are reweighted such that costs are taken into account in the final decision rule.

等级重新加权

类重新加权的思想是在分类器训练期间直接考虑成本误差的不对称性。这样做,每个类别的输出概率将已经嵌入成本误差信息,然后可以用于定义具有简单的 0.5 阈值的分类规则。

对于一些模型(例如神经网络分类器),在训练期间考虑成本可以在于调整目标函数。我们仍然希望我们的分类器输出

但这一次,它被训练成最小化以下成本函数

对于其他一些模型(例如贝叶斯分类器),可以使用重采样方法来偏置类比例,以便在类比例中输入成本误差信息。如果我们考虑成本 P01 和 P10(这样 P01 > P10),我们可以:

  • 以因子 P01/P10 对少数民族类进行过采样(少数民族类的基数应乘以 P01/P10)
  • 通过因子 P10/P01 对多数类进行欠采样(多数类的基数应乘以 P10/P01)

Illustration of the class reweight approach: the majority class is undersampled with a proportion that is chosen carefully to introduce the cost information directly inside the class proportions.

外卖食品

这篇文章的主要观点是:

  • 无论何时使用机器学习算法,都必须谨慎地选择模型的评估指标:我们必须使用能够最好地概括我们的模型相对于我们的目标表现如何的指标
  • 当处理不平衡的数据集时,如果类与给定的变量不能很好地分离,并且如果我们的目标是获得尽可能好的准确性,那么最好的分类器可能是一个总是回答多数类的“幼稚”分类器
  • 可以使用重采样方法,但必须仔细考虑:它们不应该作为独立的解决方案使用,而是必须与问题的返工相结合,以达到特定的目标
  • 返工问题本身通常是解决不平衡类问题的最佳方式:分类器和决策规则必须根据精心选择的目标来设置,例如,最小化成本

我们应该注意到,我们根本没有讨论像“分层抽样”这样在批量训练分类器时有用的技术。当面临不平衡的类问题时,这种技术确保训练期间更大的稳定性(通过消除批内的比例差异)。

最后,姑且说这篇文章的主要关键词是“目标”。准确地知道您想要获得什么将有助于克服不平衡的数据集问题,并确保获得最佳结果。完美地定义目标应该永远是要做的第一件事,也是为了创建机器学习模型而必须做的任何选择的起点。

感谢阅读!

与约瑟夫·罗卡一起写的最后一篇文章:

[## 理解生成敌对网络(GANs)

一步一步地建立导致 GANs 的推理。

towardsdatascience.com](/understanding-generative-adversarial-networks-gans-cd6e4651a29)

处理杂乱的 CSV 文件

原文:https://towardsdatascience.com/handling-messy-csv-files-2ef829aa441d?source=collection_archive---------14-----------------------

为什么它们是一个问题以及如何解决

Photo by Jan Kolar on Unsplash.

如果你是一名工作数据科学家,CSV 文件很可能是你的面包和黄油。它们对于人类和计算机来说都很容易阅读,可以在版本控制中被跟踪,并且可以很容易地通过电子邮件发送和压缩!但是,如果您已经工作了一段时间,您可能也熟悉 CSV 文件的黑暗面:不常见的单元格分隔符、不均匀的行长度、双引号、转义字符、注释行等等!😱

这个问题有一个非常简单的原因:“逗号分隔值”文件不是一种标准的文件格式,但实际上更像是一种人们尚未完全同意的约定。因此,您可能在互联网上遇到的 CSV 文件格式的变体数量是巨大的!作为示例,以下是一些真实世界的 CSV 文件示例:

Examples of real-world CSV files: (a) includes comment lines at the top, prefixed with the # character, which is not part of the CSV "standard", (b) uses the ^ symbol as delimiter and the ~ symbol for quotes, and (c) uses the semicolon as delimiter, but yields the exact same number of columns when using the comma.²

为什么这是个问题?为什么我们关心 CSV 文件以不同的格式出现?在保存表格数据时,这难道不是一种表达个性的绝妙方式吗?嗯……不是。CSV 文件是用来存储数据的,所以应该很容易从中加载数据。通过改变所使用的格式,CSV 文件在加载之前需要人工检查。

这是后一点的一个例子。Kaggle上的这个数据集包含了从 IMDB 检索到的 14762 部电影的信息。假设我们希望将这些数据加载到 Python 中,并希望使用 Pandas 将其加载到一个漂亮的数据框中:

>>> import pandas as pd
>>> df = pd.read_csv('./imdb.csv')
Traceback (most recent call last):
# ... skipping the full traceback ... 
pandas.errors.ParserError: Error tokenizing data. C error: Expected 44 fields in line 66, saw 46

哼,那没用。如果我们使用检测格式的标准方法,也称为方言,并按照Python 标准 csv 库文档的建议加载文件,会怎么样?

>>> import csv 
>>> with open('./imdb.csv', newline='') as csvfile: 
... dialect = csv.Sniffer().sniff(csvfile.read())
... csvfile.seek(0)
... reader = csv.reader(csvfile, dialect)
... rows = list(reader)
>>> len(rows)
13928

好的,这确实做了一些事情,但是最终读取了 13,928 行,而不是我们预期的 14,762 行!这是怎么回事??

事实证明,当电影标题包含逗号时,这个特殊的 CSV 文件使用了转义字符(\)。Pandas 和标准的csv库都没有自动检测到这一点,因此无法正确加载数据。想象一下,如果你开始分析这些数据,而没有意识到这种情况发生了!🙈

当然,您可以手动检查您在 web 上遇到的每个 CSV 文件,并确保它没有任何问题。但是都 2019 年了,为什么还要处理乱七八糟的 CSV 文件?为什么这些包不能正确检测方言?这很困难的一个原因是,CSV 文件有太多的变体。另一个原因是,要想出一个能一直正确完成的算法实际上并不容易,因为任何方言都会给你一些表,但应该只有一个表正确反映存储的数据。

CSV 是一个教科书式的例子,说明了如何而不是设计文本文件格式。
—Unix 编程的艺术(Raymond,2003)

谢天谢地,现在有一个解决方案: CleverCSV ,一个用于高精度检测 CSV 文件方言的 Python 包。它是以人类确定方言的方式为模型的:通过寻找导致单元格中有“干净数据”的规则表格结构的模式(如数字、日期等)。).CleverCSV 实际上是基于研究,在那里我们调查了近 10,000 个 CSV 文件,以开发检测 CSV 方言的最佳方法。为了便于将现有代码切换到 CleverCSV,该包被设计为 CSV 模块的直接替代品。所以不用import csv,你可以用import clevercsv(或者,如果你真的很聪明的话:import clevercsv as csv)。

但是等等,还有呢!当然,您不希望一遍又一遍地检测同一个文件的方言,因为它不太可能经常改变。因此,CleverCSV 还提供了一个命令行界面,它只给你你 need:⁴的代码

$ clevercsv code ./imdb.csv# Code generated with CleverCSV version 0.4.7import clevercsvwith open(“imdb.csv”, “r”, newline=””, encoding=”utf-8") as fp:
    reader = clevercsv.reader(fp, delimiter=”,”, quotechar=””, escapechar=”\\”)
    rows = list(reader)

CleverCSV 还附带了一些常用功能的包装器,比如read_csv用于检测方言并将文件加载为列表列表,以及csv2df用于将文件加载到 Pandas 数据框中。GitHub 和 PyPI 上的提供了 CleverCSV。此外,导致 CleverCSV 的研究是完全可重复的,并且是公开的(如果你关心这样的事情!😃)

数据争论和数据清理是数据科学家最耗时的任务,也不是最有趣的。事实上,的调查显示数据科学家将大部分时间花在这些琐碎的任务上,同时也是他们最不喜欢的工作部分!CleverCSV 是一个旨在部分解决这一问题的工具,它为数据科学家提供了一种从杂乱的 CSV 文件中正确加载数据的枯燥任务,从而节省了时间。我希望你试一试!

脚注

  1. RFC4180 提出了一个定义,但这不是正式意义上的标准,库和编程语言并不总是遵循它。
  2. 图片改编自:G.J.J. van den Burg,A. Nazábal,C. Sutton,通过检测行和类型模式来处理杂乱的 CSV 文件 (2019),数据挖掘与知识发现 33:(6)。
  3. 相比之下,R 的read.csv()方法也好不到哪里去,最终读取了 15,190 行!
  4. 如果你更喜欢熊猫数据框,只需使用:clevercsv code -p <filename>

原载于 2019 年 11 月 26 日https://gertjanvandenburg.com

处理文本数据质量问题:你能处理吗?

原文:https://towardsdatascience.com/handling-text-data-quality-issues-can-yuo-h-andle-thsi-7f77dac3ddff?source=collection_archive---------34-----------------------

Photo by Marija Zaric on Unsplash

介绍

退一步说,过去的几周很有趣。我收到了一个非常有趣的问题,任务是解决一些文本数据质量问题。

正如您可能已经从标题中猜到的那样,有两个主要问题需要解决。

  1. 拼写错误的检测和处理
  2. 单词之间的随机空格

你能处理这个吗?

作为人类,我们可以很容易地将上面的陈述理解为“你能处理这个吗?”然而,创建一种方法来解决这样的数据问题被证明是具有挑战性的。

如果你像我一样,你可能会说“哦,这不应该是坏!”

哦…我错了。

永远不要低估会突然出现并导致大量问题的复杂性。

无论如何,在本文中,我将介绍我用来解决这个问题的方法。这可能不是最好的方法,但似乎对我来说已经足够了。

我们开始吧!😃

数据质量问题 1:拼写错误的检测和处理

在我上一篇关于处理拼写错误的文章中,我使用了单词向量并做了大量的翻译来形成一个广义翻译向量

这是一种处理单词向量拼写错误的新方法。

然而,对于这种情况,我决定求助于一种更简单的方法来处理拼写错误。

这包括两个部分:

  1. 检测拼写错误的单词
  2. 处理拼写错误的单词

我使用了 SAS Viya 的开箱即用的拼错动作 tpSpell 来做到这一点。

SAS 与称为动作集的东西一起工作,动作集与 Python 库同义。在每个动作集中,有许多可以执行的动作

第 1 部分:检测拼写错误的单词

在这个步骤中,tpSpell 动作执行所谓的候选提取。

候选提取将单词分成两类;拼写正确的候选单词和拼写错误的候选单词。

在运行该过程之前,由预设参数确定拼写正确的候选单词。此参数指定一个术语要被视为拼写正确的候选单词,必须出现在多少个文档中。

例如,参考下面的图 1:

Figure 1 — Correctly-spelled candidate example (source)

潜在的候选名称是“Term”、“Role”和“Parent”列的串联,形成“algorithms-N-algorithm”。

如果潜在候选名称“algorithms-N-algorithm”在 4 个文档中出现 5 次,那么它出现的文档的数量等于 4。

如果名为“最小亲本”的预设参数被设置为 3,因为 4 比 3 大,所以单词“algorithms-N-algorithm”被添加到拼写正确的候选列表中。

跟了这么远?😃

那么,拼写错误的候选单词列表呢?我们如何创建这个表?

就像拼写正确的单词候选列表一样,还有另一个预设参数。这次叫“最大子女”。

例如,请看下面的图 2:

Figure 2 — Misspelled candidate example (source)

如果“最大子代”参数被设置为 3 并且“algoxxxthzs-N-algoxxxthzs”出现的文档数小于 3,那么“algoxxxthzs-N-algoxxxthzs”被添加到拼写错误的候选单词列表中。

注:如果符合上述参数,潜在候选人可以同时出现在两个候选人列表中。

现在我们已经有了一个拼写正确的候选列表和一个拼写错误的候选列表,接下来是如何将拼写正确的单词分配给它们各自的拼写错误。

第 2 部分:处理拼写错误

在该步骤中,执行候选比较

tpSpell 动作现在将检查拼写错误列表中的所有单词和拼写正确列表中的所有单词。

它将拼写错误的候选单词与每个拼写正确的候选单词进行比较,并计算它们之间的距离。

另一个预置参数确定拼写错误的单词是否有正确的拼写。例如,如果单词“algoxxxthzs”是给定的拼写错误的单词并且单词“算法”是正确拼写的候选单词,那么计算出的“algoxxxthzs”和“算法”之间的距离将是 50。

如果名为“最大法术距离”的预设参数设置为 20。由于 50 大于 20,正确拼写的候选“算法”现在被认为是单词“algoxxxthzs”的正确拼写。

您还可以在这里设置其他高级参数,以考虑多个术语,如“消防车”、“继续”或“加入”等。你可以在这里阅读文档

虽然我在上面说得听起来很复杂…

不是。😃

下面是如何运行以上所有操作的方法。

proc cas;
 textParse.tpSpell /
  table={name="pos", caslib="public"}
  minParents=3
  maxChildren=6
  maxSpellDist=15
  casOut={name="tpSpell_Out", replace=true};
   run;
quit;

结果将是这样的:

Figure 3 — Misspelling Handling Results

数据质量问题 2:随机空白

这个问题确实让我测试了多种方法。所有这些都表现不好,除了我现在要讲的方法。

为了恢复你的记忆,你的问题就像这样。

当我收到这样一个数据集时,我的第一个想法是“这个文本怎么会变成这样……”

但是,嘿,这是真实的世界。不是我们都熟悉的 kaggle 数据集或我们的研究数据集。

不过,上面有几个数据质量问题值得指出:

  1. 单词之间的空格,如“probl em”
  2. 缺少字符,即“锁定”
  3. 交换字符,即“thsi”
  4. 双重字符,即“你”
  5. 问题的组合,即“m emry”

我必须找到一种方法来解决单词之间的空格,同时解决拼写错误(数字 2、3 和 4)。

令人欣慰的是,处理拼写错误可以相对容易地解决,就像我上面展示的那样。

但是由于问题的组合,复杂性在于如何最好地处理(第五点)。在思考这项工作的最佳解决方案时,我从编码器-解码器网络的工作方式中获得了灵感。

我需要一种方法来“编码”句子,然后“解码”它们。

显然我在这里用词不当。我说的“编码”实际上是指删除单词之间的所有空白。像这样:

torefreshyyourmerytheeplokeddlikethsi

通过“解码”,我的意思是在解决拼写错误后,将单词重新分解成它们各自的单词:

提醒你一下,这个问题看起来是这样的

解码的单词基于单词的最长匹配。例如,如果我看到单词“helloworld ”,我将首先在潜在候选列表中查找单词“hell”。

直到下一个字符“o”出现,由于“hell+o”=“hello”,“hello”成为更好的潜在候选。我放弃了“地狱”这个词作为主要候选词,保留了“你好”这个词。

当读入下一个字符时,“hello+w”=“hellow”,因为“hellow”在潜在候选列表中不是一个合适的单词,所以最好的候选词是“hello”。

然后,我在“hello”和“world”之间添加一个空格,形成“hello world”。

那么这个潜在候选名单是什么呢?

这是我从前面的 tpSpell 动作生成的正确拼写单词列表中挑选出来的列表。

潜在候选人名单的管理

创建这个列表的诀窍在于我如何进行标记化。

是的,有现成的标记化方法,但没有一种方法会进行拼写错误检查,因为它同时执行标记化。

简单地说,我做了一个标记器,在解析标记时执行拼写错误的解析。

比如“hello wrld”会解析为“hello”+“world”。拼写错误的“wrld”将自动解析为“world ”,这是基于我用前面提到的 tpSpell 操作创建的一个拼写错误列表。

除了拼写错误的解决方案,我还删除了停用词,所有形式的标点符号,小写所有单词,只保留父术语来形成列表。

为什么?

因为最重要的总是那些小事情。

此处删除停用词是合理的,因为:

  1. 下游自然语言处理(NLP)任务是一个信息检索任务。即文档相似性。在文档相似性任务中,保持语义相关信息比语法相关信息更重要。因此我认为,删除停用词不会对我的下游任务产生太大影响。
  2. 如果不删除停止字,它将干扰我的“解码器”的工作。以这句话为例:

“丛书”->“丛书”

考虑停用词会将第一个词解析为“这些”而不是“该”。此外,因为“ries”不再是一个单词,所以算法将跳过这个输出,并将句子解码为“these of books”,这是不正确的。

“这些书”->“这些书”

影响“解码器”工作方式的另一个复杂因素如下所示:

“自行车运动”→“自行车运动”→“自行车港口”(错误)

为了解决这个问题,我只在候选列表中保留了父术语。即自行车 s →自行车。通过只查看父术语,我的输出如下所示:

“自行车运动”→“自行车运动”→“自行车运动”(正确)

还有一些其他的小因素也在起作用,但是你会明白的;最重要的是小事。

所以你有它!

我自己的“编码器-解码器”方法来解决这个文本数据质量问题!😃

很明显,我已经简化了整个方法,以便给你一个解决方案如何工作的要点。

正如我以前说过的,这不是一个完美的解决方案,但它确实足以让我开始我的下游 NLP 任务。

亲眼目睹这一切!

为了向您展示运行代码后的样子,我针对一个存在数据质量问题的图书评论语料库运行了代码。

下面是示例和流程的样子:

Figure 4 — Data Cleaning Process in Action

在我看来还不算太寒酸。😃

结尾注释

嗯,那就这样吧!

我希望你觉得这篇文章很有见地:)

尽管花了将近 2 周的时间尝试了许多方法,但我从中获得了巨大的乐趣!

如果你有更好的方法,请不吝赐教!很想听听!

下一个帖子可能会是这个的续集。这将是关于文件的相似性,以及我如何应用平滑逆频率和共同组成部分删除,以获得一个体面的结果。

下次见,再见!

领英简介:谭震霆

在数据科学算法面试中处理树

原文:https://towardsdatascience.com/handling-trees-in-data-science-algorithmic-interview-ea14dd1b6236?source=collection_archive---------28-----------------------

Image by Johannes Plenio from Pixabay

算法面试

不是那种树桩

算法和数据结构是数据科学不可或缺的一部分。虽然我们大多数数据科学家在学习时都没有上过适当的算法课程,但它们仍然至关重要。

许多公司在招聘数据科学家的面试过程中会询问数据结构和算法。

现在,许多人在这里问的问题是,问一个数据科学家这样的问题有什么用。 我喜欢这样描述,一个数据结构问题可以被认为是一个编码能力测试。

我们都在人生的不同阶段进行过能力倾向测试,虽然它们不是判断一个人的完美代理,但几乎没有什么是真的。那么,为什么没有一个标准的算法测试来判断人的编码能力。

但我们不要自欺欺人,他们需要像你的数据科学面试一样的热情,因此,你可能需要花一些时间来研究算法和数据结构问题。

这篇文章是关于快速跟踪这项研究,并为数据科学家解释树的概念,以便你下次在面试中被问到这些问题时轻松通过。

但是首先,为什么树对数据科学很重要?

对于数据科学家来说,树和软件工程师有着不同的含义。

对于软件工程师来说,树只是一种简单的数据结构,他们可以用它来管理层次关系,而对于数据科学家来说,树是一些最有用的分类和回归算法的基础。

那么这两个在哪里见面呢?

它们必然是同一件事。不要惊讶。下面是数据科学家和软件工程师对树的看法。

They are essentially the same

唯一的区别是数据科学树节点保存了更多的信息,帮助我们确定如何遍历树。例如,在用于预测的数据科学树的情况下,我们将查看节点中的要素,并根据分割值确定我们要移动的方向。

如果你想从头开始写你的决策树,你可能也需要从软件工程的角度理解树是如何工作的。

树的类型:

在这篇文章中,我将只讨论在数据科学面试问题中经常被问到的两种树。二叉树(BT)和称为二分搜索法树(BST)的二叉树的扩展。

1.二叉树:

二叉树是一种简单的树,其中每个节点最多有两个子节点。决策树是我们在日常生活中看到的一个例子。

Binary Tree: Each Node has up to 2 children

2.二叉查找树(英国夏令时):

二叉查找树是一棵二叉树,其中:

  • 一个节点的所有左后代都小于或等于该节点,并且
  • 该节点的所有右后代都大于该节点。

谈到平等,这个定义有各种不同的说法。有时等式在右边或两边。有时树中只允许不同的值。

Source

8 大于左侧子树中的所有元素,小于右侧子树中的所有元素。这同样适用于树中的任何节点。

创建简单的树:

那么我们如何构造一棵简单的树呢?

根据定义,树是由节点组成的。所以我们从定义用于创建节点的node类开始。我们的节点类非常简单,因为它保存了节点的值、左侧子节点的位置和右侧子节点的位置。

class node:
    def __init__(self,val):
        self.val = val
        self.left = None
        self.right = None

我们现在可以创建一个简单的树,如下所示:

root = node(1)
root.left = node(2)
root.right = node(3)

现在我注意到,如果我们自己不做一些编码,我们就不能真正掌握基于树的问题。

因此,让我们更深入地了解一下代码部分,我发现一些关于树的最有趣的问题。

有序树遍历:

有很多种方法可以遍历一棵树,但是我发现顺序遍历是最直观的。

当我们在二叉查找树的根节点上进行有序遍历时,它以升序访问/打印节点。

def inorder(node):
    if node:
        inorder(node.left)
        print(node.val)
        inorder(node.right)

上述方法非常重要,因为它允许我们访问所有节点。

因此,如果我们想在任何二叉树中搜索一个节点,我们可以尝试使用 inorder 树遍历。

从排序后的数组创建二叉查找树

如果我们需要像上面那样手动创建一棵树,我们会是什么样的编码人员呢?

那么我们能从一个唯一元素的有序数组中创建一个 BST 吗?

def create_bst(array,min_index,max_index):
    if max_index<min_index:
        return None
    mid = int((min_index+max_index)/2)
    root = node(array[mid])
    leftbst = create_bst(array,min_index,mid-1)
    rightbst = create_bst(array,mid+1,max_index)
    root.left = leftbst
    root.right = rightbst
    return roota = [2,4,5,6,7]
root = create_bst(a,0,len(a)-1)

树本质上是递归的,所以我们在这里使用递归。我们取数组的中间元素,并将其指定为节点。然后,我们将create_bst函数应用到数组的左边部分,并将其分配给node.left,对数组的右边部分做同样的操作。

我们得到了 BST。

我们做得对吗?我们可以通过创建 BST 然后进行有序遍历来检查它。

inorder(root)
------------------------------------------------------------
2
4
5
6
7

好像没错!

让我们检查一下我们的树是否是有效的 BST

Think Recursion!!!

但是,如果我们需要打印所有的元素并手动检查 BST 属性是否得到满足,那么我们是什么样的编码人员呢?

这里有一个简单的代码来检查我们的 BST 是否有效。我们假设在我们的二叉查找树中存在严格的不平等。

def isValidBST(node, minval, maxval):
    if node:
        # Base case
        if node.val<=minval or node.val>=maxval:
            return False
        # Check the subtrees changing the min and max values
        return isValidBST(node.left,minval,node.val) &    isValidBST(node.right,node.val,maxval)
    return TrueisValidBST(root,-float('inf'),float('inf'))
--------------------------------------------------------------
True

我们递归地检查子树是否满足二叉查找树性质。在每次递归调用时,我们改变调用的minvalmaxval,为函数提供子树的允许值范围。

结论

在这篇帖子里,我从软件工程的角度谈论了树。如果你想从数据科学的角度看树,你可以看看这篇文章。

[## 3 个决策树分裂标准背后的简单数学

🌀理解分割标准

towardsdatascience.com](/the-simple-math-behind-3-decision-tree-splitting-criterions-85d4de2a75fe)

树构成了数据科学算法面试中一些最常见问题的基础。我过去常常对这种基于树的问题感到绝望,但现在我已经开始喜欢其中涉及的精神锻炼。我喜欢这类问题中的递归结构。

虽然您可以在不学习它们的情况下在数据科学中走得更远,但您可以为了一点乐趣而学习它们,也许是为了提高您的编程技能。

这是给你的一个小笔记本,我把所有这些小概念都放在这里,让你尝试和运行。

看看我在算法面试系列的其他帖子,如果你想了解递归动态规划或者链表

继续学习

如果你想阅读更多关于算法和数据结构的内容,我强烈推荐 UCSanDiego在 Coursera 上的 算法专门化。

谢谢你的阅读。将来我也会写更多初学者友好的帖子。在 媒体 关注我或者订阅我的 博客 了解他们。一如既往,我欢迎反馈和建设性的批评,可以通过 Twitter @mlwhiz 联系。

此外,一个小小的免责声明——这篇文章中可能会有一些相关资源的附属链接,因为分享知识从来都不是一个坏主意。

使用 Python、PyMC3 和 ArviZ 实践贝叶斯统计

原文:https://towardsdatascience.com/hands-on-bayesian-statistics-with-python-pymc3-arviz-499db9a59501?source=collection_archive---------0-----------------------

高斯推断、后验预测检查、分组比较、分级线性回归

如果你认为贝叶斯定理是反直觉的,而贝叶斯统计建立在贝叶斯定理的基础上,可能很难理解。我支持你。

无数的理由让我们应该学习贝叶斯统计,特别是贝叶斯统计正在成为表达和理解下一代深度神经网络的强大框架。

我相信,对于我们在做之前必须学习的东西,我们通过做来学习。生活中没有什么事情是如此艰难,以至于我们不能通过我们对待它的方式来使它变得更容易。

因此,这是我使它变得更容易的方法:与其在开始时讲太多的理论或术语,不如让我们把重点放在贝叶斯分析的机制上,特别是,如何用pymc 3&ArviZ进行贝叶斯分析和可视化。在记忆无穷无尽的术语之前,我们将编码解决方案并可视化结果,并使用术语和理论来解释模型。

PyMC3 是一个用于概率编程的 Python 库,具有非常简单和直观的语法。 ArviZ ,一个与 PyMC3 携手工作的 Python 库,可以帮助我们解释和可视化后验分布。

我们将把贝叶斯方法应用到一个实际问题中,展示一个端到端的贝叶斯分析,从构建问题到建立模型,再到得出先验概率,最后用 Python 实现后验分布。

在我们开始之前,让我们先了解一些基本的直觉:

贝叶斯模型也被称为概率模型,因为它们是使用概率构建的。贝叶斯使用概率作为量化不确定性的工具。因此,我们得到的答案是分布而不是点估计。

贝叶斯方法步骤

步骤 1:建立关于数据的信念,包括先验和似然函数。

第二步,使用数据和概率,按照我们对数据的信念,来更新我们的模型,检查我们的模型是否与原始数据一致。

步骤 3,根据我们的模型更新我们的数据视图。

数据

由于我对使用机器学习进行价格优化感兴趣,我决定将贝叶斯方法应用于一个西班牙高铁票价数据集,可以在这里找到。感谢大师团队搜集数据集。

from scipy import stats
import arviz as az
import numpy as np
import matplotlib.pyplot as plt
import pymc3 as pm
import seaborn as sns
import pandas as pd
from theano import shared
from sklearn import preprocessingprint('Running on PyMC3 v{}'.format(pm.__version__))data = pd.read_csv('renfe.csv')
data.drop('Unnamed: 0', axis = 1, inplace=True)
data = data.sample(frac=0.01, random_state=99)
data.head(3)

Table 1

data.isnull().sum()/len(data)

Figure 1

价格列中有 12%的值缺失,我决定用相应票价类型的平均值来填充它们。还要用最常见的值填充其他两个分类列。

data['train_class'] = data['train_class'].fillna(data['train_class'].mode().iloc[0])
data['fare'] = data['fare'].fillna(data['fare'].mode().iloc[0])
data['price'] = data.groupby('fare').transform(lambda x: x.fillna(x.mean()))

高斯推论

az.plot_kde(data['price'].values, rug=True)
plt.yticks([0], alpha=0);

Figure 2

铁路票价的 KDE 图显示了高斯型分布,除了大约几十个数据点远离均值。

让我们假设高斯分布是对火车票价格的恰当描述。因为我们不知道平均值或标准差,我们必须为它们设定先验。因此,合理的模型如下。

模型

我们将对票价数据进行高斯推断。这里有一些模型的选择。

我们将像这样实例化 PyMC3 中的模型:

  • PyMC3 中的模型规范包装在 with 语句中。

先验的选择:

  • μ,总体的平均值。正态分布,很广。我不知道μ的可能值,我可以设置先验来反映我的无知。根据经验,我知道火车票价格不能低于 0 或高于 300,所以我将均匀分布的边界设置为 0 和 300。你可能有不同的经历,设定不同的界限。这完全没问题。如果你有比我更可靠的先验信息,请使用它!
  • σ,总体的标准差。只能为正,因此使用半正态分布。同样,非常宽。

票价可能性函数的选择:

  • y 是一个观察变量,代表来自参数为μ和σ的正态分布的数据。
  • 使用坚果取样抽取 1000 个后验样本。

使用 PyMC3,我们可以将模型编写如下:

model_g.py

y 表示可能性。这就是我们告诉 PyMC3 我们想要在已知(数据)的基础上处理未知的方式。

我们绘制高斯模型轨迹。这在引擎盖下的 Theano 图上运行。

az.plot_trace(trace_g);

Figure 3

  • 在左边,我们有一个 KDE 图,对于 x 轴上的每个参数值,我们在 y 轴上得到一个概率,它告诉我们该参数值的可能性有多大。
  • 在右边,我们得到了采样过程中每一步的单个采样值。从迹线图中,我们可以直观地从后验得到似是而非的数值。
  • 上图中每个参数都有一行。对于这个模型,后验概率是二维的,所以上图显示了每个参数的边际分布。

这里有几件事需要注意:

  • 我们的单个参数的采样链(左)似乎很好地收敛和稳定(没有大的漂移或其他奇怪的模式)。
  • 每个变量的最大后验估计(左侧分布中的峰值)非常接近真实参数。

我们可以画出参数的联合分布。

az.plot_joint(trace_g, kind='kde', fill_last=False);

Figure 4

我看不出这两个参数之间有任何关联。这意味着我们可能在模型中没有共线性。这很好。

我们还可以对每个参数的后验分布进行详细总结。

az.summary(trace_g)

Table 2

我们还可以通过用分布的平均值和最高后验密度(HPD) 生成一个图来直观地看到上面的总结,并解释和报告贝叶斯推断的结果。

az.plot_posterior(trace_g);

Figure 5

  • 频率主义推理不同,在贝叶斯推理中,我们得到值的整个分布。
  • 每次 ArviZ 计算和报告 HPD 时,默认情况下,它将使用 94%的值。
  • 请注意,HPD 区间不同于置信区间。
  • 在这里,我们可以这样理解,有 94%的可能性相信平均票价在 63.8 欧元和 64.4 欧元之间。

我们可以使用 Gelman Rubin 测试来正式验证链的收敛性。接近 1.0 的值表示收敛。

pm.gelman_rubin(trace_g)

bfmi = pm.bfmi(trace_g)
max_gr = max(np.max(gr_stats) for gr_stats in pm.gelman_rubin(trace_g).values())
(pm.energyplot(trace_g, legend=False, figsize=(6, 4)).set_title("BFMI = {}\nGelman-Rubin = {}".format(bfmi, max_gr)));

Figure 6

我们的模型收敛得很好,盖尔曼-鲁宾统计看起来也不错。

后验预测检查

  • 后验预测检验(PPC)是一种验证模型的好方法。这个想法是从模型中生成数据,使用从后面提取的参数。
  • 既然我们已经计算了后验概率,我们将说明如何使用模拟结果来推导预测。
  • 以下函数将从跟踪中随机抽取 1000 个参数样本。然后,对于每个样本,它将从由该样本中的μ和σ值指定的正态分布中抽取 25798 个随机数。
ppc = pm.sample_posterior_predictive(trace_g, samples=1000, model=model_g)np.asarray(ppc['y']).shape

现在,ppc 包含 1000 个生成的数据集(每个数据集包含 25798 个样本),每个数据集使用不同于后验的参数设置。

_, ax = plt.subplots(figsize=(10, 5))
ax.hist([y.mean() for y in ppc['y']], bins=19, alpha=0.5)
ax.axvline(data.price.mean())
ax.set(title='Posterior predictive of the mean', xlabel='mean(x)', ylabel='Frequency');

Figure 7

推断的平均值非常接近实际的铁路票价平均值。

分组比较

我们可能对不同票价类型下的价格比较感兴趣。我们将重点评估影响大小,即量化两种票价类别之间的差异。为了比较票价类别,我们将使用每种票价类型的平均值。因为我们是贝叶斯,我们将努力获得票价类别之间均值差异的后验分布。

我们创建三个变量:

  • 价格变量,代表票价。
  • idx 变量,用数字对票价类别进行编码的分类虚拟变量。
  • 最后是分组变量,包括票价类别的数量(6)
price = data['price'].values
idx = pd.Categorical(data['fare'],
                     categories=['Flexible', 'Promo', 'Promo +', 'Adulto ida', 'Mesa', 'Individual-Flexible']).codes
groups = len(np.unique(idx))

组比较问题的模型与前面的模型几乎相同。唯一的区别是,μ和σ是向量,而不是标量变量。这意味着,对于先验,我们传递一个形状参数,对于可能性,我们使用 idx 变量正确地索引均值和 sd 变量:

comparing_groups.py

有 6 组(票价类别),为每组绘制μ和σ的轨迹图有点困难。因此,我们创建一个汇总表:

flat_fares = az.from_pymc3(trace=trace_groups)
fares_gaussian = az.summary(flat_fares)
fares_gaussian

Table 3

很明显,各组(即票价类别)之间的平均值存在显著差异。

为了更清楚,我们在不重复比较的情况下,绘制了每个票价类别之间的差异。

  • Cohen 的 d 是比较两个均值的合适效应大小。Cohen 的 d 通过使用它们的标准偏差引入了每组的可变性。
  • 优势概率(ps)定义为从一组中随机选取的数据点比从另一组中随机选取的数据点具有更大值的概率。

difference_plot.py

Figure 8

基本上,上面的图告诉我们,在 94% HPD 的上述比较情况中,没有一个包括零参考值。这意味着对于所有的例子,我们可以排除零的差异。6.1 欧元到 63.5 欧元的平均差额范围足够大,足以证明客户根据不同的票价类别购买机票是合理的。

贝叶斯分层线性回归

我们希望建立一个模型来估计每种火车类型的火车票价格,同时估计所有火车类型的价格。这种类型的模型被称为分层模型多级模型。

  • 编码分类变量。
  • idx 变量,用数字对训练类型进行编码的分类哑变量。
  • 最后是分组变量,包含列车类型的数量(16)

encode_cat.py

Table 4

我们将建模的数据的相关部分如上所示。我们感兴趣的是不同的火车类型是否会影响票价。

层次模型

hierarchical_model.py

Figure 9

左栏中的边际后验概率信息丰富,“α_μ_tmp”告诉我们组平均价格水平,“β_μ”告诉我们购买票价类别“Promo +”比票价类型“Adulto ida”显著提高价格,购买票价类别“Promo”比票价类型“Promo +”显著提高价格,以此类推(没有低于零的质量)。

pm.traceplot(hierarchical_trace, var_names=['α_tmp'], coords={'α_tmp_dim_0': range(5)});

Figure 10

在 16 种火车类型中,我们可能想看看 5 种火车类型在票价方面的比较。通过查看“α_tmp”的边际,我们可以看到不同列车类型之间的价格存在相当大的差异;不同的宽度与我们对每个参数估计的信心程度有关——每种列车类型的测量值越多,我们的信心就越高。

对我们的一些估计进行不确定性量化是贝叶斯建模的强大之处之一。我们得到了不同列车类型价格的贝叶斯可信区间。

az.plot_forest(hierarchical_trace, var_names=['α_tmp', 'β'], combined=True);

Figure 11

最后,我们可能想计算 r 的平方:

ppc = pm.sample_posterior_predictive(hierarchical_trace, samples=2000, model=hierarchical_model)
az.r2_score(data.price.values, ppc['fare_like'])

这篇文章的目的是学习、实践和解释贝叶斯理论,而不是从数据集中得出最好的结果。不然我们就直接用 XGBoost 了。

Jupyter 笔记本可以在 Github 上找到,好好享受这周剩下的时光吧。

参考资料:

[## GLM:分级线性回归- PyMC3 3.6 文档

Gelman 等人(2007)的 radon 数据集是分层建模的经典。在这个数据集中…

docs.pymc.io](https://docs.pymc.io/notebooks/GLM-hierarchical.html) [## 橄榄球预测的分层模型- PyMC3 3.6 文档

编辑描述

docs.pymc.io](https://docs.pymc.io/notebooks/rugby_analytics.html?highlight=sample_posterior_predictive)

这本书:用 Python 进行贝叶斯分析

实践大数据流,Apache 大规模爆发

原文:https://towardsdatascience.com/hands-on-big-data-streaming-apache-spark-at-scale-fd89c15fa6b0?source=collection_archive---------16-----------------------

photo credit: pexels

介绍

在一个数据以极快的速度生成的世界中,正确分析数据并在正确的时间提供有用且有意义的结果,可以为处理数据产品的许多领域提供有用的解决方案。这可以应用于医疗保健和金融,媒体,零售,旅游服务等。一些可靠的例子包括网飞实时提供个性化推荐,亚马逊跟踪您与其平台上不同产品的交互并立即提供相关产品,或者任何需要实时传输大量数据并对其实施不同分析的企业。

能够实时处理大数据并执行不同分析的令人惊叹的框架之一是 Apache Spark 。我认为有许多资源提供了关于 Spark 的不同功能以及它在大数据社区中有多受欢迎的信息,但简单提一下 Spark 的核心功能:它采用弹性分布式数据集(RDDs)、流和大规模实时机器学习来进行快速大数据处理。在本文中,我们将通过一个实践环节来使用 Spark Streaming 组件和 pySpark 解决一个业务问题。

动机

没有人能否认社交媒体在当今社会的重要性。许多企业通过 twitter 活动收集受众的洞察力反馈兴趣。许多企业已经意识到,对社交媒体活动的突出分析可以帮助他们更好地了解客户的行为模式。通常,来自社交媒体的反馈可能会迅速变化,对反馈的实时分析是企业成功的一个重要过程。因此,有不同的方法可以更好地了解人们对新的产品品牌事件的反应。一种方法是评估与特定主题相关的推文的情绪;这个话题可以是任何与产品、品牌或事件相关的话题。我以前在 这个项目 中实现过类似的想法。另一个聪明的方法是在特定时间段内提取与我们想要的主题相关的热门#标签,比如每隔几分钟,因为带有#标签的推文有更高的参与度。

实施

我们将与 pySpark 合作,利用 Spark Streaming 组件,并使用 python 中的 TCP 套接字通过 Tweepy 库连接到 Twitter 的流媒体 API。在 Spark 中流式传输推文并将其放在 RDDs 上之后,我们对推文应用一些操作来提取顶部标签。接下来,我们使用 Spark SQL 将 top hashtags 保存在一个临时 SQL 表上。最后,我们在 python 中应用了一些可视化技术来在图形中描绘结果。下图展示了我们程序的整体架构。

The overall Architecture

了解火花流的其他使用方式也很有好处:

Different Applications of Spark Streaming (DZone)

我们的计划将包含两个模块:

1- receive-Tweets,这个模块通过 Tweepy 库处理 Twitter 的流 API 的认证和连接。该模块只有在接收到 Spark 流模块的调用并通过 TCP 套接字将 tweets 发送到 Spark 引擎时才会被触发。

2- top#tags-streaming,这个模块在 pySpark 中启动 StreamingContext,通过 socketTextStream 接收数据。接下来,我们应用一些 lambda 函数来清除 tweets 并提取#标签。然后,我们将与我们搜索的主题(新产品、品牌或事件)相关的前 10 个标签可视化。

  • 我们将简要介绍第一模块的步骤:

我们进口 Tweepy 及其所需的软件包。为了访问 Twitter 的 API,我们需要四个认证密钥,我们可以通过访问 developer.twitter.com 和注册一个新的应用程序来获得。如你所见,我把它们留为空白,因为与公众共享你的认证密钥是不安全的。接下来,我们创建从 Tweepy 中的 StreamListener 模块继承的 TweetsListener 类,并覆盖 on_data()方法,以便我们可以通过套接字发送 tweets。我们可以搜索单词“足球”作为我们想要的主题,因为它在 twitter 上非常受欢迎,我们可以非常快地获得推文,但我们总是可以根据我们的用例来改变搜索词。我们还不打算运行这个 python 文件(receive-Tweets.py ),因为我们需要首先设置 SparkStreamingContext。

有关 python 中的网络以及 Tweepy 流如何工作的更多信息,请参见以下链接:

send ex 的 Tweepy 上的 Youtube 系列。

[## 使用 Tweepy - tweepy 3.5.0 文档进行流式处理

在 tweepy 中,Tweepy 的实例。Stream 建立流会话并将消息路由到 StreamListener 实例…

docs.tweepy.org](http://docs.tweepy.org/en/v3.5.0/streaming_how_to.html)

  • 对于第二个模块,我们将使用 findspark 库在本地机器上定位 spark,然后从 pyspark 导入必要的包。
import findspark
findspark.init('directory that contains Apache Spark')# import necessary packagesfrom pyspark import SparkContext
from pyspark.streaming import StreamingContext
from pyspark.sql import SQLContext
from pyspark.sql.functions import desc

接下来,我们初始化 SparkContext()。SparkContext 是任何 spark 功能的入口点。当我们运行任何 Spark 应用程序时,都会启动一个驱动程序,它具有主函数,并且您的 SparkContext 会在这里启动。SparkContext 表示到 Spark 集群的连接,可用于在该集群上创建 rdd、累加器和广播变量。SparkContext 在这里使用 Py4J 启动一个 JVM 并创建一个 JavaSparkContext ( )。需要注意的是,每个会话中只能运行一个 SparkContext。之后,我们以 10 秒的批处理间隔启动 StreamingContext(),这意味着在流式传输期间,输入流将每 10 秒被分成几批。

sc = SparkContext()# we initiate the StreamingContext with 10 second batch interval. #next we initiate our sqlcontext
ssc = StreamingContext(sc, 10)
sqlContext = SQLContext(sc)

下一步是分配流的输入源,然后将传入的数据放入行中:

# initiate streaming text from a TCP (socket) source:
socket_stream = ssc.socketTextStream("127.0.0.1", 5555)# lines of tweets with socket_stream window of size 60, or 60 #seconds windows of time
lines = socket_stream.window(60)

值得注意的是,我们使用了与第一个模块中相同的端口号(5555)来发送推文,并且 IP 地址也是相同的,因为我们是在本地机器上运行的。此外,我们使用 window()函数来确定我们每分钟(60 秒)都在分析推文,以查看在此期间排名前 10 的标签是什么。

下面是一个有用的图片,可以帮助您更好地理解 window()函数在 Spark 中的工作方式:

source

现在我们已经通过了所有的先决条件,让我们看看如何清理以#开头的 tweets,并将前 10 条保存在一个临时 SQL 表中:

# just a tuple to assign namesfrom collections import namedtuplefields = ("hashtag", "count" )
Tweet = namedtuple( 'Tweet', fields )# here we apply different operations on the tweets and save them to #a temporary sql table( lines.flatMap( lambda text: text.split( " " ) ) #Splits to a list
  # Checks for    hashtag calls  
  .filter( lambda word: word.lower().startswith("#") ) 
  .map( lambda word: ( word.lower(), 1 ) ) # Lower cases the word
  .reduceByKey( lambda a, b: a + b ) 
 # Stores in a Tweet Object
  .map( lambda rec: Tweet( rec[0], rec[1] ) )
 # Sorts Them in a dataframe
  .foreachRDD( lambda rdd: rdd.toDF().sort( desc("count") )
 # Registers only top 10 hashtags to a table.
  .limit(10).registerTempTable("tweets") ) )

我们创建了一个 namedtuple 对象来保存标签及其计数。接下来,我们使用 flatmap()创建一个标记化 tweets 的数组。我们正在使用函数,因为它们需要更少的内存并且运行更快。之后,我们过滤不以#开头的推文。foreachRDD()是 pySpark 中一个重要的输出函数,可以帮助在 RDD 上运行更快的操作。在这里,我们将它应用于每个 RDD,将其转换为数据帧,最后我们将它保存到一个名为“tweets”的临时表中。

现在,我们可以运行 receive-Tweets.py,之后我们可以通过运行:开始流式传输

# start streaming and wait couple of minutes to get enought tweets
ssc.start()

正如我们所看到的,我在 Linux 中打开了两个终端。其中一个运行我的 Jupiter 笔记本进行 pySpark 流传输,另一个运行 read-tweets.py 文件。

运行 receive-Tweets.py 后,我们必须等待几分钟,这样我们就有足够的 Tweets 来处理:

接下来,我们导入我们的可视化库,并为“足球”主题中的前 10 个标签绘制图表。在这里,我们运行我们的流,每分钟只检查前 10 个#标签几(5)次,这只是为了学习的目的,您可以看到#标签并不经常改变,但如果您想看到更好的结果,您可以让它运行一段时间:

# import libraries to visualize the resultsimport time
from IPython import display
import matplotlib.pyplot as plt
import seaborn as sns
import pandas
%matplotlib inlinecount = 0
while count < 5:

    time.sleep(5)
    top_10_tags = sqlContext.sql( 'Select hashtag, count from tweets' )
    top_10_df = top_10_tags.toPandas()
    display.clear_output(wait=True)
    plt.figure( figsize = ( 10, 8 ) )
    sns.barplot( x="count", y="hashtag", data=top_10_df)
    plt.show()
    count = count + 1
    print(conut)

结果如下:

you can zoom in on the picture and see all those #tags

重要提示:

  • 这是理解 Apache spark 的流组件如何工作的一个简单例子。总是有更复杂的方法来应用相同的方法来处理不同类型的输入流,如来自 youtube 或 Amazon(媒体、零售)等流行网站的用户交互数据。股票市场是另一个使用案例,实时传输大量数据并运行不同的分析对于股票经纪公司至关重要,Apache Spark 可能是首选工具。

Apache Spark 的另一个重要组件是 MLlib,它使用户能够大规模地训练和部署有用的机器学习模型。在我的 下一篇文章 中,我经历了一个有趣的项目,详细解释了如何在 Spark MLlib 中训练和构建模型。

像往常一样,代码和 jupyter 笔记本在我的 Github 上可用。

非常感谢您的提问和评论。

参考资料:

  1. https://spark . Apache . org/docs/2 . 2 . 0/streaming-programming-guide . html # discretized-streams-dstreams
  2. https://github.com/jleetutorial/python-spark-streaming

动手端到端自动化机器学习

原文:https://towardsdatascience.com/hands-on-end-to-end-automated-machine-learning-a50e6bce6512?source=collection_archive---------18-----------------------

使用 AutoML 库在 Python 环境中进行 AutoML 编码的实践经验。

我们从 Python 中的一个基本管道方法开始,它实际上没有 AutoML,然后快速传递到著名的 AutoML 库。我们还将 OptiWisdom 的趋势自动 SaaS 解决方案(如 OptiScorer)与经典方法进行了比较。

这是对端到端自动化机器学习过程的快速介绍,从不同的角度介绍了许多不同的库。此外,您将能够对 AutoML 库进行比较并做出战略决策。

如果你不知道什么是 AutoML 或者它的用途,你也可以开始阅读下面的文章。

https://towards data science . com/automl-end-to-end-introduction-from-opti wisdom-c 17 Fe 03 a 017 f

Python 中机器学习的流水线和端到端解决方案介绍。

从这一点开始,我们将实现一个逐步编码的例子,其思想是用 sklearn 库实现 python 中最原语编码风格的分类。在这个例子中有两个重要的问题。首先,我们将讨论 sklearn 中的流水线,这是一种非常类似于 AutoML 流程的整体方法,其次,我们将使用网格搜索方法进行非常原始的超参数优化。

本文的步骤如下图所示:

在 Python 中,一种相对较新的称为流水线的方法是实现系统并将所有步骤结合在一起的经典方式。作为一种动手的编码实践,可以用 Python 编写如下的流水线方法:

  1. 加载数据集:实际上,这一步是数据连接层,对于这个非常简单的原型,我们将保持它的简单性,就像从 sklearn 库加载数据集一样:
"""
@author: sadievrenseker
"""
import pandas as pd
import numpy as np

from sklearn import datasets
data = datasets.load_iris()

2。上面的代码是从 sklearn 数据集加载的一个非常简单的数据集。直到数据被加载到数据层对象中,加载数据集的问题才结束。在本例中,我们将使用 pandas 作为数据访问层,并通过以下代码将数据集加载到 pandas 对象中:

df = pd.DataFrame(data = np.column_stack((data.data, data.target)), columns=data.feature_names + ['Species'])
df.head()

上述代码将返回以下输出:

DataFrame output for the data loading

上图展示了加载的数据框是 sklearn 数据集的原始版本。在某些数据集中,物种列可能是物种的名称,如“鸢尾”、“鸢尾-杂色”和“鸢尾-海滨”。

3。探索性数据分析(EDA): 如果是这种情况,我们将在稍后的数据预处理中处理字符串类型,从这一点开始,如果数据科学家对数据集不熟悉,他/她可能会选择探索性数据分析(EDA),这在大多数现实生活问题中都会发生。因此,上述代码后面的代码可能是一些可视化或信息,如下所示:

import seaborn as sns
sns.pairplot(df, hue='Species', size=3)

上述代码将返回以下输出:

EDA Output for Iris Data Set

在 seaborn 矩阵图上,

保存所有可能的 2D 组合中的逐列匹配和数据分布的可视化。

对于流水线操作,整个系统被插入到单个流水线中,在常规的 AutoML 方法中,有数据预处理和机器学习过程,如本章第一节中已经解释的。

对于这种实践经验,我们将使用 K-NN 连同标准的定标器和标签编码器。

因此,标准缩放器和标签编码器是预处理阶段,而 K-NN 将是机器学习阶段。

4。编码:如果加载的数据集有带标签的物种列,那么标签编码器解决从字符串到数值的转换。在我们的数据集例子中,这不是问题,因为原始数据集在物种列中保存数值,如下面的代码所示:

df['Species'] = LabelEncoder().fit_transform(df['Species'])

上述代码将返回以下输出:

Encoded DataFrame

5。标准化:在标签编码之后,我们可以继续标准化。归一化将数据集要素转换到相同的范围内。我们将使用标准分布来转换所有功能:

df.iloc[:,:4] = StandardScaler().fit_transform(df.iloc[:,:4])

上述代码将返回以下输出:

Normalized version of DataFrame

上面显示了数据的缩放版本,现在数据已准备好进行分类。

6。测试和训练集:我们将使用 K-NN 算法进行分类,在常规编码中,我们可以将数据分为训练集和测试集,然后进行如下分类:

from sklearn.model_selection import train_test_split
X_train, X_test, y_train, y_test = train_test_split(df.iloc[:,:-1].values,
 df['Species'],
 test_size = 0.4,
 random_state = 123)

7。机器学习:将数据拆分成 0.6 比 0.4 的训练/测试集后,现在可以应用 K-NN 算法了。

from sklearn.neighbors import KNeighborsClassifier
knn = KNeighborsClassifier(n_neighbors = 3)
knn.fit(X_train,y_train)
predictions = knn.predict(X_test)

您可以在上面的代码中很容易地注意到,在上面的示例中,n_neighbors 参数被设置为 3。

8。超参数优化:参数优化的一个解决方案是使用网格搜索,但是在进入网格搜索之前,我们将使用如下混淆矩阵和计分器显示算法的成功:

from sklearn.metrics import confusion_matrix
cm = confusion_matrix(y_test,predictions)
print(cm)

代码执行后,我们得到的混淆矩阵如下:

[[22 0 0]
 [ 0 15 1]
 [ 0 2 20]]

9。评价:对于已经熟悉混淆矩阵的读者来说,已经很清楚我们在 60 个数据点中只有 3 个错误。也是有经验的数据科学家,以前玩过 iris 数据集可以很容易地识别出第一类的清晰分类和第二类与第三类之间的问题。为了阐明数字上的成功,让我们计算准确性的分数,如下面的代码所示:

from sklearn.metrics import accuracy_score
score = accuracy_score(y_test,predictions)
print(score)

10。Score: 我们案例的分数是 0.95,现在我们可以通过使用网格搜索来优化精确度。

from sklearn.model_selection import GridSearchCV
k_range = list(range(1, 31))
print(k_range)
param_grid = dict(n_neighbors=k_range)
print(param_grid)
grid = GridSearchCV(knn, param_grid, scoring='accuracy')
grid.fit(X_train, y_train)

print(grid.best_params_)

上面的代码使用了 sklearn 库中的 GridSearchCV 类,它实际上使用了交叉验证来寻找最佳参数,我们给出了 k 从 1 到 31 的搜索空间。所以,这里的网格搜索基本上从 k= 1 开始,每次迭代增加 k 参数值 1。GridSearchCV 类也输出最佳参数,如下所示:

{'n_neighbors': 5}

因此,针对虹膜数据集的 K-NN 模型的精度的优化参数是 k=5。

11。流水线:现在,我们可以把上面所有的代码放到一个流水线中,如下所示:

from sklearn.pipeline import Pipeline
pipeline = Pipeline([
 ('normalizer', StandardScaler()), #Step1 - normalize data
 ('clf', KNeighborsClassifier()) #step2 - classifier
])
print(pipeline.steps)

流水线步骤的输出如下:

[('normalizer', StandardScaler(copy=True, with_mean=True, with_std=True)), ('clf', KNeighborsClassifier(algorithm='auto', leaf_size=30, metric='minkowski',
 metric_params=None, n_jobs=None, n_neighbors=5, p=2,
 weights='uniform'))]

12.现在,管道对任何设置都是开放的,并且在添加到管道时,规格化器或分类算法的参数也可以部署到构造函数中。

from sklearn.model_selection import cross_validate
scores = cross_validate(pipeline, X_train, y_train)
print(scores)

上面这段代码通过使用训练数据和标签来训练整个管道。在执行之后,scores 变量保存交叉验证的每一次得分的详细信息,如下所示。

{'fit_time': array([0.00163412, 0.0012331 , 0.00207829]), 'score_time': array([0.00192475, 0.00164199, 0.00256586]), 'test_score': array([0.96875   , 1\.        , 0.93103448]), 'train_score': array([0.96551724, 0.98360656, 1\.        ])}

摘要

我们实现了从数据源到机器学习算法评估分数的经典 python 机器学习过程,包括超参数优化,从上面的第一步开始,一直到步骤 11。在第 11 步和第 12 步,我们用 sklearn 下的流水线方法重新实现了整个过程,并立即执行。

请再次记住,我们的步骤可以演示如下:

Steps of operations in this article

请注意,我们的方法与 CRISP-DM 步骤非常相似:

CRISP-DM Steps

这篇文章是对 AutoML 过程的一个非常原始的介绍,我们实现流水线只是为了更好的理解。

动手全球模型解释

原文:https://towardsdatascience.com/hands-on-global-model-interpretation-3bb4264732b5?source=collection_archive---------25-----------------------

什么特性是重要的,为什么

Photo by Bram Naus on Unsplash

本文是我关于模型可解释性和可解释人工智能系列文章的延续。如果你还没有,我强烈推荐你阅读本系列的第一篇文章— “机器学习模型解释简介”,它涵盖了模型可解释性的基础知识,从什么是模型可解释性,为什么我们需要它到模型解释的潜在区别。

在本文中,我们将通过更深入地探究全局模型解释的来龙去脉来重拾我们离开的地方。首先,我们将快速回顾一下什么是全球模型解释及其重要性。然后我们将深入其中两种最流行的方法的理论——特征重要性和部分依赖图——并应用它们来获得关于心脏病数据集的特征的信息。

什么是全局模型解释?

全局模型解释是一套帮助我们回答问题的技术,比如一个模型通常是如何表现的?哪些功能驱动预测,哪些功能对你的事业完全没用。使用这些知识,您可以对数据收集过程做出决策,创建仪表板来解释您的模型,或者使用您的领域知识来修复明显的错误。

大多数全局解释方法都是通过研究完整数据集上因变量和自变量(特征)之间的条件交互作用来工作的。他们还创建和使用大量的可视化工具,这些工具很容易理解,但包含大量用于分析模型的有用信息。

特征重要性

特征的重要性是在我们置换了特征的值之后模型的预测误差的增加,这打破了特征和真实结果之间的关系。— 可解释的机器学习,一个让黑盒模型变得可解释的指南

Figure 2: Feature importance example

概念和理论

特性重要性的概念非常简单。使用特征重要性,我们通过计算在置换/混洗给定特征的特征值之后给定模型的误差的增加来测量特征的重要性。

如果置换会增加模型误差,则特征是“重要的”。这是因为在这种情况下,模型严重依赖这一特征来做出正确的预测。另一方面,如果置换不会对误差产生太大影响或者根本不会改变误差,那么特征就是“不重要”的。

Fisher,Rudin 和 Dominici 在他们 2018 年的论文中建议,“所有的模型都是错误的,但许多是有用的……”不是随机洗牌,而是应该将功能分成两半,并交换两半。

优势

特性重要性是了解特性重要性的最流行的技术之一。这是因为这是一种简单的技术,它为您提供了关于某个特性重要性的高度压缩的全局洞察力。此外,它不需要重新训练模型,这总是一个优势,因为节省了计算时间。

不足之处

尽管特征重要性是一种应该一直使用的解释技术,但是它仍然有一些缺点。例如,不清楚您是否应该使用训练或测试集来计算特性重要性。此外,由于置换过程,当重复计算时,结果可能变化很大。

另一个问题是,特征之间的相关性会通过产生不现实的实例或者通过在两个相关特征之间分割重要性来偏离特征的重要性。

要了解更多信息,我强烈推荐你去看看 Christoph Molnar 的电子书“可解释的机器学习”,这是一本学习更多解释模型的好书。

示例和解释

模型认为什么特征对于确定患者是否患有心脏病很重要?

这个问题可以用特征重要性来回答。

正如我在文章开头提到的,我们将研究心脏病数据集。你可以在我的 Github 上或者作为 Kaggle 内核找到本教程使用的所有代码。

大多数库,如 Scikit-Learn、 XGBoost 以及其他机器学习库,已经有了自己的特征重要性方法,但是如果您想在处理来自多个库的模型时获得准确的结果,使用相同的方法来计算每个模型的特征重要性是有利的。

为了确保这一点,我们将使用 ELI5 库。ELI5 允许用户可视化和调试各种机器学习模型。它提供的不仅仅是特性的重要性,还包括特定于库的特性以及一个文本解释器

为了计算特征的重要性,我们可以使用*permutation_importance*方法。在计算了给定模型的特征重要性之后,我们可以使用show_weights方法来可视化它。

利用上述方法可以得到模型的特征重要度,并对它们进行比较。

Figure 3: Feature Importance of Logistic Regression

Figure 4: Feature Importance of XGBoost

您可以看到这两个模型对于一个特性有着非常不同的重要性分数。这会对你对结果的信任度产生负面影响。

尽管如此,我们可以看到,像 ca、性别和 thal 这样的特征对于获得正确的预测非常有用,而年龄和 cp 对于获得正确的预测并不重要。

部分相关图

部分相关图(简称 PDP 或 PD 图)显示了一个或两个特征对机器学习模型的预测结果的边际效应

Figure 5: Partial Dependence Plot Example

概念和理论

部分相关图为您提供了有关特征如何影响模型预测的信息。这可以帮助我们理解什么样的特征值会给我们更高或更低的输出。

对于分类特征,可以容易地计算部分相关性。我们通过强制所有数据实例具有相同的类别来获得每个类别的估计值。例如,如果我们对性别如何影响患心脏病的几率感兴趣,我们可以首先用值“男性”替换“性别”列中的所有值,并对预测进行平均,然后用值“女性”进行平均。

计算回归的部分相关性要困难得多,但是 Christoph Molnar 在他的电子书中很好地解释了这个问题。因此,如果你有兴趣深入了解模型解释,一定要去看看。

示例和解释

为了创建部分相关图,我们将使用 PDPbox 库。PDPbox 为我们提供了一些不同的精心设计的图,包括单个功能的部分依赖图以及多个功能的部分依赖图。

Figure 6: PDP’s for one and two features

要安装 PDPbox,我们可以键入:

pip install git+https://github.com/SauceCat/PDPbox.git

现在我们可以使用pdp_isolatepdp_plot方法创建一个部分相关图来分析不同性别对患心脏病概率的影响。

Figure 7: PDP for Gender

当将性别从 sex_0 更改为 sex_1 时,黄黑线给出了预测的平均效果。只看这条线,我们就能看出性别为 0 的患者比性别为 1 的患者更有可能患心脏病。

为了创建一个部分依赖图,向我们展示目标上两个特征的交互作用,我们可以使用pdp_interactpdp_interact_plot方法。

Figure 8: 2d partial dependence plot

这可以帮助我们找到两个特征之间的相互作用,甚至是单个特征值。例如,我们可以看到,无论性别栏的值如何,年龄在 55 岁至 63 岁之间的患者患心脏病的概率最低。

结论

全局模型解释是帮助我们回答一些问题的技术,比如一个模型通常是如何表现的?哪些功能驱动预测,哪些功能对你的事业完全没用。

两种最常用的全局模型解释技术是特征重要性和部分相关图。

我们可以使用特征重要性来了解模型认为特征对于进行预测有多重要。

部分相关图有助于我们理解特定特征值如何影响预测。这是非常有用的,因为它允许你对特定的特征值感兴趣,然后可以进一步分析或共享。

下一步是什么?

在本系列的第 3 部分中,我们将深入了解什么是局部模型解释,以及两种局部模型解释技术(石灰值和 Shapely 值)是如何工作的,从而更深入地了解个人预测。

这就是这篇文章的全部内容。如果你有任何问题或者只是想和我聊天,请在下面留下评论或者在社交媒体上联系我。如果你想获得我博客的持续更新,请确保在 Medium 上关注我,并加入我的简讯。

PyTorch 和 PyTorch 几何图形的手动图形神经网络

原文:https://towardsdatascience.com/hands-on-graph-neural-networks-with-pytorch-pytorch-geometric-359487e221a8?source=collection_archive---------0-----------------------

在我上一篇文章中,我介绍了图形神经网络(GNN)的概念以及它的一些最新进展。由于这个话题被大肆炒作,我决定制作这个教程,讲述如何在你的项目中轻松实现你的图形神经网络。您将学习如何使用 PyTorch Geometric 构建自己的 GNN,以及如何使用 GNN 解决现实世界中的问题(Recsys Challenge 2015)。

在这篇博文中,我们将使用 PyTorch 和 PyTorch Geometric (PyG),这是一个基于 PyTorch 构建的图形神经网络框架,运行速度快得惊人。它比最著名的 GNN 框架 DGL 快好几倍。

除了其非凡的速度,PyG 还提供了一系列实现良好的 GNN 模型,这些模型在各种论文中都有说明。因此,用 PyG 重现实验将会非常方便。

A Subset of The Implemented Models (https://github.com/rusty1s/pytorch_geometric)

鉴于其在速度和便利性方面的优势,毫无疑问,PyG 是最受欢迎和使用最广泛的 GNN 库之一。让我们进入主题,把我们的手弄脏!

要求

  • PyTorch — 1.1.0
  • PyTorch 几何图形— 1.2.0

PyTorch 几何基础

本节将带您了解 PyG 的基础知识。基本上会涵盖 torch_geometric.datatorch_geometric.nn 。您将学习如何将几何数据传递到您的 GNN,以及如何设计一个自定义的消息传递层,GNN 的核心。

数据

torch_geometric.data 模块包含一个数据类,允许您非常容易地从数据中创建图表。您只需指定:

  1. 与每个节点相关联的属性/特征
  2. 每个节点的连通性/邻接性(边索引)

让我们使用下图来演示如何创建数据对象

Example Graph

因此,图中有 4 个节点,v1 … v4,每个节点都与一个二维特征向量相关联,并且标签 y 指示其类别。这两个可以表示为浮动传感器:

图的连通性(边索引)应该用首席运营官格式限制,即第一个列表包含源节点的索引,而目标节点的索引在第二个列表中指定。

请注意,边索引的顺序与您创建的数据对象无关,因为此类信息仅用于计算邻接矩阵。因此,上面的 edge_index 表示与下面的相同的信息。

将它们放在一起,我们可以创建如下所示的数据对象:

资料组

数据集的创建过程不是很简单,但是对于那些使用过 torchvision 的人来说,它似乎很熟悉,因为 PyG 遵循它的惯例。PyG 提供了两种不同类型的数据集类,InMemorydataset 和 Dataset。顾名思义,前一个用于适合 RAM 的数据,而第二个用于更大的数据。由于它们的实现非常相似,所以我将只介绍 InMemoryDataset。

要创建 InMemoryDataset 对象,需要实现 4 个函数:

  • raw_file_names()

它返回一个列表,显示原始的、未处理的文件名列表。如果你只有一个文件,那么返回的列表应该只包含一个元素。事实上,您可以简单地返回一个空列表,然后在过程()中指定您的文件。

  • 已处理文件名()

与上一个函数类似,它也返回一个包含所有已处理数据的文件名的列表。调用 process()后,通常返回的列表应该只有一个元素,存储唯一处理过的数据文件名。

  • 下载()

这个函数应该将您正在处理的数据下载到 self.raw_dir 中指定的目录中。如果你不需要下载数据,就直接来

pass

在函数中。

  • 流程()

这是数据集最重要的方法。您需要将数据收集到一个数据对象列表中。然后,调用 self.collate() 来计算 DataLoader 对象将使用的切片。下面是一个来自 PyG 官网的自定义数据集的例子。

在本文后面,我将向您展示如何根据 RecSys 挑战赛中提供的数据创建自定义数据集。

数据加载器

DataLoader 类允许您轻松地将数据批量输入到模型中。要创建 DataLoader 对象,只需指定所需的数据集和批处理大小。

loader = DataLoader(dataset, batch_size=512, shuffle=True)

DataLoader 对象的每次迭代都会生成一个 batch 对象,该对象非常类似于数据对象,但带有一个属性“Batch”。它指示每个节点与哪个图相关联。由于数据加载器将来自不同样本/图形的 xyedge_index 聚集成批,因此 GNN 模型需要这种“批”信息来知道哪些节点属于一批中的同一个图形以执行计算。

**for** batch **in** loader:
    batch
    >>> Batch(x=[1024, 21], edge_index=[2, 1568], y=[512], batch=[1024])

信息传递

消息传递是 GNN 的本质,它描述了如何学习节点嵌入。我在上一篇文章中已经谈到了,所以我将简单地用符合 PyG 文档的术语来介绍一下。

Message Passing

x 表示节点嵌入, e 表示边特征,𝜙表示消息功能,□表示聚合功能,更新功能。如果图中的边除了连通性之外没有其他特征,则 e 本质上是图的边指数。上标代表层的索引。当 k=1 时, x 表示每个节点的输入特征。下面我将说明每个功能的工作原理:

  • propagate(edge_index,size=None,**kwargs):

它接受边索引和其他可选信息,如节点特征(嵌入)。调用此函数将会调用消息更新

  • 消息(**kwargs):

您指定如何为每个节点对(x_i,x_j)构造“消息”。因为它跟随传播的调用,所以它可以接受传递给传播的任何参数。需要注意的一点是,可以用“_i”和“_j”定义从参数到特定节点的映射。因此,命名该函数的参数时必须非常小心。

  • 更新(aggr_out,**kwargs)

它接收聚合的消息和传递到 propagate 的其他参数,为每个节点分配一个新的嵌入值。

例子

让我们从论文 “大型图的归纳表示学习” 来看看如何实现一个 SageConv 层。SageConv 的消息传递公式定义为:

https://arxiv.org/abs/1706.02216

这里,我们使用最大池作为聚合方法。因此,第一行的右边可以写成:

https://arxiv.org/abs/1706.02216

这说明了“消息”是如何构造的。每个嵌入的相邻节点乘以一个权重矩阵,加上一个偏差,并通过一个激活函数。这可以用 torch.nn.Linear 轻松做到。

class SAGEConv(MessagePassing):
    def __init__(self, in_channels, out_channels):
        super(SAGEConv, self).__init__(aggr='max')
        self.lin = torch.nn.Linear(in_channels, out_channels)
        self.act = torch.nn.ReLU()

    def message(self, x_j):
        # x_j has shape [E, in_channels]

        x_j = self.lin(x_j)
        x_j = self.act(x_j)

        return x_j

至于更新部分,聚合消息和当前节点嵌入是聚合的。然后,将其乘以另一个权重矩阵,并应用另一个激活函数。

class SAGEConv(MessagePassing):
    def __init__(self, in_channels, out_channels):
        super(SAGEConv, self).__init__(aggr='max')
        self.update_lin = torch.nn.Linear(in_channels + out_channels, in_channels, bias=False)
        self.update_act = torch.nn.ReLU()

    def update(self, aggr_out, x):
        # aggr_out has shape [N, out_channels]

        new_embedding = torch.cat([aggr_out, x], dim=1)
        new_embedding = self.update_lin(new_embedding)
        new_embedding = torch.update_act(new_embedding)

        return new_embedding

放在一起,我们有下面的 SageConv 层。

一个真实的例子—2015 年 RecSys 挑战赛

RecSys 挑战赛 2015 向数据科学家发起挑战,要求他们构建一个基于会话的推荐系统。这项挑战要求参与者完成两项任务:

  1. 预测是否会有一个购买事件,随后是一系列的点击
  2. 预测哪件商品将被购买

首先我们从 RecSys Challenge 2015 官网下载数据,构建数据集。我们将从第一项任务开始,因为那项更容易。

该挑战提供了两组主要数据, yoochoose-clicks.datyoochoose-buys.dat ,分别包含点击事件和购买事件。让我们快速浏览一下数据:

yoochoose-click.dat

yoochoose-buys.dat

预处理

下载完数据后,我们对其进行预处理,以便将其输入到我们的模型中。item _ id 被分类编码以确保编码的 item _ id 从 0 开始,该编码的 item _ id 稍后将被映射到嵌入矩阵。

由于数据非常大,为了便于演示,我们对其进行了二次抽样。

Number of unique elements in the subsampled data

为了确定基本事实,即给定会话是否有任何购买事件,我们只需检查 yoochoose-clicks.dat 中的 session_id 是否也出现在 yoochoose-buys.dat 中。

数据集构建

在预处理步骤之后,数据就可以转换成 Dataset 对象了。这里,我们将会话中的每个项目视为一个节点,因此同一会话中的所有项目构成一个图。为了构建数据集,我们通过 session_id 对预处理后的数据进行分组,并迭代这些组。在每次迭代中,每个组中的 item_id 被再次分类编码,因为对于每个图,节点索引应该从 0 开始计数。因此,我们有以下内容:

在构建数据集之后,我们调用 shuffle() 来确保它已经被随机打乱,然后将它分成三组用于训练、验证和测试。

构建图形神经网络

下面的自定义 GNN 引用了 PyG 官方 Github 库中的一个例子。我用我们自己实现的 SAGEConv 层改变了 GraphConv 层,如上图所示。此外,还修改了输出图层以匹配二进制分类设置。

培养

训练我们的自定义 GNN 非常容易,我们只需迭代从训练集构建的数据加载器,并反向传播损失函数。这里,我们使用 Adam 作为优化器,学习率设置为 0.005,二进制交叉熵作为损失函数。

确认

这种标签是高度不平衡的,有大量的负面标签,因为大多数会议之后没有任何购买活动。换句话说,一个愚蠢的模型猜测所有的否定会给你 90%以上的准确率。因此,曲线下面积(AUC)是该任务的更好指标,而不是准确性,因为它只关心正面示例的得分是否高于负面示例。我们使用 Sklearn 现成的 AUC 计算功能。

结果

我对模型进行了 1 个时期的训练,并测量了训练、验证和测试的 AUC 分数:

仅用 100 万行训练数据(约占所有数据的 10%)和 1 个时期的训练,我们可以获得验证和测试集的 AUC 分数约为 0.73。如果使用更多的数据以更大的训练步长来训练模型,分数很可能会提高。

结论

您已经学习了 PyTorch Geometric 的基本用法,包括数据集构造、自定义图层以及用真实数据训练 gnn。这篇文章中的所有代码也可以在我的 Github repo 中找到,在那里你可以找到另一个 Jupyter 笔记本文件,我在其中解决了 RecSys Challenge 2015 的第二个任务。我希望你喜欢这篇文章。如果您有任何问题或意见,请在下面留下!确保在 twitter 上关注我,我会在那里分享我的博客帖子或有趣的机器学习/深度学习新闻!和 PyG 玩 GNN 玩得开心!

机器学习实践演示:

原文:https://towardsdatascience.com/hands-on-machine-learning-example-real-time-object-detection-with-yolo-v2-ebdd8441c12a?source=collection_archive---------3-----------------------

source: bawilabs

利用 YOLO·V2 进行实时物体检测

简介

这篇博客是为了一个具体的机器学习对象检测案例,与初学者分享我的经验而写的。

深度学习是人工智能(AI)和机器学习(ML)的一个高级子领域,长期以来一直是一个学术领域。随着数据的丰富和计算能力的指数级增长,我们已经看到跨学科应用深度学习商业案例的激增。也有很多聪明人选择研究 AI/ML,许多大型高科技公司(领先 云平台 ML 包括AWS SageMaker微软 Azure AI谷歌云平台 ML&tensor flow**

只要你在世界的任何一个角落都有互联网连接,每个人工智能/人工智能爱好者都可以获得大量的公共在线培训和资源。因此没有借口留下… (如果你是一个真正的 ML 爱好者,我认为最好的硬核开始是吴恩达的 Coursera specializations。)****

看我简单的 DIY 演示视频看看这件作品经过几个小时努力的成果: 视频 1视频 2

卷积神经网络

Source: Wikipedia

卷积神经网络 (CNN)是深度人工神经网络,主要用于对图像进行分类(即标记所看到的),通过相似性对其进行聚类(即照片搜索),并在场景内执行对象识别。它们是可以识别人脸、个人、街道标志、汽车、动物、异常、肿瘤和视觉数据的许多其他方面的算法。

卷积层用于从输入训练样本中提取特征。每个卷积图层都有一组有助于要素提取的过滤器。一般来说,随着 CNN 模型的深度增加,通过卷积层学习的特征的复杂性增加。你可以在这里这里或者这里了解更多关于 CNN 的信息。Andrej Karpathy在这个链接为他早期的斯坦福 CNN 课程写了一篇很棒的文章,如果你想在学术上更深入的话。

CNN 是一个如此迷人和具有颠覆性的领域,它为 人脸识别自动驾驶汽车光学字符识别疾病自动诊断图像到文本的转换神经艺术 等等开辟了可能性****

还有许多进一步的创新机会,从帮助数百万有视觉障碍的人到进一步推进预防性医疗诊断、药物发现、 视频游戏 全渠道零售商的货架/产品识别……天空是无限的:)这些框架也开始在边缘上工作。边缘可以是iphone,安卓小工具,亚马逊 DeepLens 等。你明白我的意思吗?

用 YOLO 进行实时物体检测

你只看一次(YOLO)多酷的名字啊?这种目标检测算法是目前最先进的,优于 CNN 及其上述变体。也许创始人受到了人类眼睛/大脑的启发,因为 YOLO 在测试期间正在查看整个图像,所以它的预测是由图像中的全球背景提供的。它还通过单一网络评估进行预测,不像像 R-CNN 这样的系统需要数千个单一图像。YOLO V2 和 V3 可以实时检测各种对象类别。最新的 YOLO V3 甚至比 R-CNN 快 1000 倍以上,比快 R-CNN ( 参考 )快 100 倍。****

您可以向它提供任何主要的图像/视频类型或来自网络摄像头的实时视频。YOLO 也是一个卷积网络,但它以一种巧妙的方式运行。(掌声送给原文YOLO·V2 的文章这里 )

YOLO 有一种有效的方法,它首先预测图像的哪些部分包含所需的信息,然后只在这些部分上运行(CNN)分类器。简单地说,YOLO 把图像分成 13×13 的网格,网格又被分成 5 个“边界框”。边界框是包围对象的矩形。对于每个包围盒,它并行运行识别算法来识别它们属于哪个图像类别。YOLO 最终输出一个置信度(概率)分数,告诉我们预测的边界框实际上包围了一个对象(图像类)有多确定。每个输入图像都可以通过这个特殊的 CNN 快速获取,并产生一个(13 x 13 x 125)的矩阵,其中每个张量都携带独特的信息,如 x,y 参数,边界框矩形的宽度/长度,置信度得分和经过训练的图像类别的概率距离。

我们提供的参数忽略了得分低的那些,并从我们训练的图像类库中挑选出概率最高的特定对象。因此,我们最终很少看到有狗、人、花、汽车等的包围盒。因此,如果我可以过于简化,YOLO 过程在视觉上看起来像下面每个图像网格的闪烁速度。最右边的图片显示了识别出的具有最高盒子置信度得分的图像和标签组合。

The input image is divided into an 7 x 7 grid. Then bounding boxes are predicted and a class is predicted among classification over the most confident ones. Source: J. Redmon and al. (2016)

YOLO V2 is trained with the COCO (Common objects in Context) library that has 100k images of 80 common classes plus it is complemented with a subset of ImageNet. It has 80 image classes. As a reference ImageNet has 14 million images and 22k classes. You can leverage other data sets or leverage Amazon mechanical Turk like new crowd sourcing services for manual labeling work and come up with your own data set!!

所有代码和环境都是 开源 因此任何人都可以克隆和修改作品。我还做了一个小的 Python 代码修改,以便在制作我的测试 YouTube 视频时,能够使用外部网络摄像头进行实时记录(以便不随身携带我的笔记本电脑)。只要懂一点 Python,对理论有一定程度的理解,就可以做任何编辑…

网上的大多数例子通常基于 Linux 或 Mac,尽管我不得不在装有英特尔酷睿 7 的联想 Windows 10 机器上做这个演示。因此,以下所有个人经验和指导都适合在 Windows 环境下使用。

最初的 YOLO 作者使用 C 和 CUDA 在开源库中创建了 DarkNet。我选择使用 Darkflow,它基本上是 DarkNet 到方便的 Tensorflow 版本的翻译。因此,我们将下载并使用暗流版本进行演示。

好了,让我们开始吧…依赖关系

您需要在您的(笔记本电脑)环境中安装 Python 3.5 或 3.6、Tensorflow、numPY、openCV 才能开始。下面是一些在 Windows 上对我有用的指导。

第一步——安装 Windows 的依赖项

对于初学者,你可以安装以下软件,为你将来的 ML 实验准备一个干净的个人计算环境。

  1. 下载并安装 Anaconda 包 64 位版本,选择 Python 3.6 版本。( 链接 到视频教程)这个自动安装 Python 和很多流行的 data scientist/ML 库( NumPy、Scikit-Learn、Pandas、R、Matplotlib… )、工具( Jupyter Notebook、RStudio )和其他数百个开源包,供你未来的项目使用。当你开始时,它感觉像是最接近 ML 软件包的圣杯的东西…例如,我仍然使用 Anaconda Jupyter 笔记本进行几乎所有的 ML 实验,主要是出于方便。虽然 openCV 库不包括在内,但我们将单独安装它,因为实时计算机视觉任务需要它。(给蟒蛇乡亲们的提示!)**
  2. 安装tensor flowT3Keras (可选)。TensorFlow 是最受欢迎的人工智能软件库,由谷歌创建/维护。 Keras 是另一个非常流行的&高级神经网络 API,用 Python 编写,能够在 TensorFlow 之上运行。它的开发重点是支持快速实验。当你在经历了 吴恩达的 这种很低级的素材后,想要“退出”的时候,Keras 感觉就像一块蛋糕!因为它是基于 Python 的高级语言。 别人 为你做了艰苦的工作!

在试图安装所有这些开源软件包时,出现问题是很常见的,尤其是在 Windows 机器上。让一切正常工作并解决所有版本或冲突问题需要一段时间。我的最佳实践是基本上谷歌这类问题,并在网上找到解决方案。像 stackoverflow 这样的网站非常有用,可以节省你的时间。

总的来说,我还发现创建一个单独的新的 conda 虚拟环境有助于缓解 Windows 安装问题。更多关于 这里

第二步——安装暗网/YOLA、暗流工具

DarkNet:最初,YOLO 算法是由 Joseph Redmon 在 DarkNet 框架中实现的。Darknet 是一个开源的自定义神经网络框架,用 C 和 CUDA 编写。它速度快,易于安装,并支持 CPU 和 GPU 计算。你可以在 GitHub 上找到开源。

Darkflow :是 YOLO 在 TensorFlow 上的一个实现的昵称。由于 Trinh Hoang Trieu,Darknet 模型被转换为 Tensorflow,并且可以安装在 Linux 和 Windows 环境中。让我们开始吧!

#打开 anaconda 提示符并克隆 darkflow github 存储库。(您可能需要安装Git BashWindows,Git 命令才能工作)****

git clone [https://github.com/thtrieu/darkflow](https://github.com/thtrieu/darkflow)

#替代方法基本上是进入dark flow GitHub页面,将主库下载到您的本地(即 C:\ users \ user _ name \ dark flow)

#如果您尚未在步骤 1 中创建新的虚拟环境,则创建一个 conda 环境用于 darkflow 安装。

conda create -n your_env_name python=3.6

#使用 anaconda 提示符激活新环境。

activate your_env_name

#你可以用 conda-forge 库安装需要的 OpenCV。 conda-forge 是一个 github 组织,包含 conda 库的存储库。

conda config --add channels conda-forge

conda install opencv

#在适当的位置构建 Cython 扩展。这是一个广泛使用的 Python to C 编译器和包装器,它帮助我们从 Python 中调用 DarkNet C 代码。

python setup.py build_ext --inplace

或者尝试以下替代方法

pip install -e .

如果出现错误,首先尝试将工作目录更改为 darkflow (cd darkflow ),然后重新运行上述命令之一。

酷毙了。上述步骤将有望建立一个本地环境来运行 darkflow 并在图像或视频上执行对象检测任务。

最后,我们需要下载 CFGWEIGHTS 文件。预训练的模型名称是 YOLOv2,其在包含 80 个类别(像汽车、狗、人、飞机等的图像类型)的 COCO 图像数据集上被训练。

权重文件:请从这里下载yolov2.weights文件。请创建一个暗流/bin 目录来保存这些重量文件。

CFG 文件:在本地 darkflow 文件夹下现有的 darkflow/cfg 目录下创建一个对应型号的yolo.cfg文本文件。勾选 这里的 为源文件。如果你愿意,你可以用记事本复制粘贴原始的 GitHub 内容。另外,不要忘记看看 Darkflow 的命令行帮助选项,以供将来参考。
python flow --h

PS:我发现这个 博客(Abhijeet Kumar)在我计算出需要的装置时非常有用。****

我们都准备好了。

让我们运行暗流 YOLO 命令行来渲染一些视频!

我喜欢使用 Anaconda 命令提示符来执行以下命令。你可以通过搜索“Anaconda 提示符”在 Windows 开始菜单中找到它。在提示窗口中,通过“激活您的环境名称”命令激活您的新 Tensorflow 虚拟环境。然后执行“cd darkflow”命令,将当前工作目录更改为本地 darkflow 存储库。然后,您可以尝试以下命令开始运行 DarkFlow 来处理图像和视频。

  1. 要处理已有的图像,可以运行以下命令:
    python flow --model cfg/yolo.cfg --load bin/yolov2.weights --imgdir sample_img

请注意 darkflow/sample_img 是一个包含样本照片的目录。

2.要处理视频文件,可以将待渲染的视频文件移动到 master darkflow 文件夹下,然后使用以下命令:

python flow --model cfg/yolo.cfg --load bin/yolov2.weights --demo samplename.mp4

提示:如果在末尾添加“— saveVideo”,也可以将处理后的视频保存在主文件夹下。

3.要通过您的笔记本电脑摄像头渲染实时流视频:

python flow --model cfg/yolo.cfg --load bin/yolov2.weights --demo camera

更多的例子可以在这里或者这里找到。

我的基本例子

因为 Medium 不允许直接流式播放,所以我在 YouTube 上上传了两个我用外部网络摄像头录制的示例视频。

视频 1 用谷歌搜索

视频 2 在我们的客厅:)

使用个人设备还是云 ML 服务?

都是。如果你是初学者,建议你先设置一台个人私人笔记本电脑,里面有需要的 Anaconda、Python 和 Keras/Tensorflow 以及其他所有相关的流行包。在你的 ML 旅程中,这是学习、尝试 MVP 和快速失败/转向的关键。您还可以轻松地设置一个 AWS SageMaker 帐户/环境,它不需要 TerasFlow/Keras 的任何这些单独的安装。我不会详细介绍,但请查看此 链接 了解更多信息。你也可以尝试微软 Azure 或者谷歌云。随着您越来越先进,云将更适合帮助您获得更大的数据空间(即 AWS S3 桶)、计算能力(即更多的 CPU 或 GPU)和快速部署/扩展。因此,它们不是竞争而是互补。

结论

围绕 AI 和 ML 有很多议论。我试图展示,任何人都可以用可用的开源框架和库创建真正的产品,开始时风险自负。

例如,您可以进一步创建和培训自己的课程(图像或图像类型),并根据您的独特需求定制培训。YOLO 和暗流都是开源的,你可以克隆和修改它们。YOLO v3 也已经上市,这一视觉识别领域将继续迅猛发展。我很期待和它一起玩。

我绝不是人工智能或 CNN 的专家,但我希望这篇博客能对人工智能/人工智能爱好者在你未来的 DIY 项目中有所启发。随时欢迎评论和反馈。不要留下来!

学分

所有学分将授予以下人员。我所做的只是利用了他们的优秀作品。

  1. 关于 YOLO 的原始论文继 YOLOv2 和 YOLO9000 之后的论文。如果你不喜欢阅读学术论文,你可以在这个链接查看开国元勋们的演讲摘要。
  2. 然后 DarkNet (Joseph Redmon)创建了 below 库,启发了许多人去实现 YOLO。他做了两次 TED 演讲。第一个主要谈论技术,第二个更多地谈论道德含义。

****** [## YOLO:实时目标检测

你只看一次(YOLO)是一个最先进的,实时对象检测系统。

pjreddie.com](https://pjreddie.com/darknet/yolo/)

3.然后 Trieu 先生已经将 Darknet-YOLO v2 翻译成 Tensorflow 框架。

[## thtrieu/darkflow

将 darknet 转换为 tensorflow。加载训练过的重量,使用 tensorflow 进行重新训练/微调,将常量图形定义导出到…

github.com](https://github.com/thtrieu/darkflow)

延伸阅读和观看…

更多关于 YOLO 的信息,请点击 此处 此处 此处 获取更多见解和灵感。 马克杰伊 也有一个很棒的 8 部分 Youtube 系列,展示如何定制暗流。你可以在演职员表部分查看创始人的 YOLO 主页。(快捷键: 暗网 YOLO暗流 )。

更新

  1. 错误处理:如果你收到一个类似“ … AssertionError: labels.txt 和 cfg/yolov2.cfg 表示不一致的类编号…
    然后检查这个解决方案。您只能使用保留的 CFG 字后面的(只要您的命令提示符指示新的“bin”文件夹下下载的权重文件名,权重名称就可以了)。首先,你可以在这里下载 yolov2,但将其重命名为 yolo.cfg ,因为它是由代码识别的。您还可以选择修改开放源代码。
  2. 如果你想使用外部网络摄像头,这里有一些调整开源代码的简单技巧。上帝保佑开源软件!

如何使用外部网络摄像头进行实时流媒体播放:
你必须对你克隆的开源暗流代码做一个小小的修改&下载。首先,你需要一个网络摄像头连接到 OpenCV 可以连接的计算机上,否则它将无法工作。如果您连接了多个网络摄像头,并且想要选择使用哪一个,您可以传递“file = 1”来选择(OpenCV 默认使用现有的网络摄像头作为 0)。请打开以下文件,并使用 Jupyter 或任何其他 Python 编辑器进行更改:http://localhost:8888/edit/dark flow/dark flow/net/help . py

或者你可以在下面的链接复制我的分叉代码。

[## Sailor74/darkflow

将 darknet 转换为 tensorflow。加载训练过的重量,使用 tensorflow 进行重新训练/微调,将常量图形定义导出到…

github.com](https://github.com/Sailor74/darkflow/blob/Sailor74-patch-1/darkflow/net/help.py)

然后,您可以轻松地使用 Anaconda 提示符命令窗口通过外部网络摄像头进行流式传输。

# run darkflow with external webcam on windows
python flow --model cfg/yolo.cfg --load bin/yolov2.weights --demo webcamera

您可以使用 Anaconda prompt 命令通过网络摄像头进行流媒体播放,并将视频保存在 darkflow 根文件夹下:

# run darkflow with ext webcam and save to local folder
python flow --model cfg/yolo.cfg --load bin/yolov2.weights --demo webcamera --saveVideo

剧终

Happy “deep learning” in 2019!!******

记忆增强神经网络构建实践(第一部分)

原文:https://towardsdatascience.com/hands-on-memory-augmented-neural-networks-implementation-part-one-a6a4a88beba3?source=collection_archive---------4-----------------------

记忆增强神经网络(MANN),可用于一次性学习,在这篇文章中,我将向您展示如何构建记忆增强神经网络。

在我们开始建立我们的曼恩之前,我想说明它的前身,神经图灵机(NTM)。在这一部分,我将向您展示 ntm 如何利用外部存储器来存储和检索信息。所以,让我们跳到 NTM。

神经图灵机架构和概念

神经图灵机是一种算法,具有从存储器中存储和检索信息的能力。NTM 的亮点是用外部存储器来增强神经网络,用于存储和检索信息,而通常一些神经网络使用隐藏状态作为存储器。这是 NTM 的建筑:

Fig 01 —The architecture of NTM

如您所见,通常 NTM 有三个核心组件:

  • 控制器
  • 记忆
  • 读写头

控制器,基本上是一个前馈神经网络或递归神经网络,读取和写入存储器。存储器部分,你可以称之为存储体或存储矩阵,这里我们有一个二维矩阵,由 N 行 M 列的存储单元组成。控制器从外部环境接收输入,并通过与存储体或存储矩阵交互来发出响应。通常,读磁头和写磁头是包含存储器地址的指针,它必须从存储器中读取和写入。

在 NTM,我们使用特殊的读写操作来决定关注内存中的哪个位置。

神经图灵机读取操作

既然我们的记忆库或记忆矩阵中有很多记忆块,那么我们需要选择哪一个来从内存中读取呢?这是由权重向量决定的。可以由注意机制获取的权重向量指定了在存储器中哪个区域比其他区域更重要。首先,我们需要规范化权重向量,这意味着它的值范围从 0 到 1,其和等于 1。好了,让我们在这里做一些数学,不要担心下面这些长公式,我们会涵盖它。

Fig 02 — — Neural Turing Machine Read and Write operations math formula

假设归一化权重向量为 w_t,其中下标 t 表示时间,w_t(i)表示权重向量中索引为 I 且时间为 t 的元素。如公式 R1 所示,假设我们的记忆库或记忆矩阵包含 N 行和 M 列,我们使用 Mt 表示时间为 t 的记忆矩阵

Fig 03 — — M_t(i), Memory Matrix M_t given time t

然后我们可以以线性方式组合存储器矩阵 Mt、权重向量 Wt、读取向量 Rt。这可以表示为公式 R2(图 02)

Fig 04 — — r_t, read vector given time t

神经图灵机写操作

擦除和添加操作包含在 NTM 写入操作中。可以应用擦除操作来移除存储器中不需要的信息。为了擦除存储矩阵中特定单元的值,我们引入一个擦除向量 e_t,它的长度与权向量 w_t 相同,擦除向量包含 0 和 1 的值。

因此,为了擦除值并获得更新的内存矩阵,我们将(1- w_t x e_t)乘以上一步 M_{t-1}^(i 中的内存矩阵,如图 2 中的公式 E1 所示。

Fig 05 — — Erase operation

对于 NTM 写操作中的加法操作,我们使用权重向量 w_t(i)乘以加法向量 a_t,加法向量 a _ t 具有要添加到存储器的值,然后将它们添加到存储器矩阵,即图 02 中的公式 A1。

Fig 06 — — Add operation

神经图灵机中的寻址机制

我们可以使用注意机制和不同的寻址方案来计算权重向量。这里我们有两种类型的寻址机制来从存储器中访问信息:

  • 基于内容的寻址
  • 基于位置的寻址

对于基于内容的寻址,根据相似性从存储器中选择值。假设控制器返回一个关键向量 k_t,相似性是通过将该关键向量与存储矩阵 M_t 中的每一行进行比较而获得的。该相似性可以通过下图中的数学公式 CB1 来测量。

Fig 07 — — Addressing Mechanisms Math in Neural Turing Machine

接下来,我们引入一个参数β,它被称为关键强度,用于确定权重向量应该有多集中。基于β的值,我们可以根据关键强度的值将注意力调整到特定位置。也就是说,当β值较低时,我们平等地关注所有位置,当β值较高时,我们关注特定位置。因此,我们的权重向量变成了图 07 的公式 CB2。

我们可以对权重应用 softmax,而不是直接使用这个数学定义。也就是图 07 中的公式 CB3。

对于基于位置的寻址,我们仍然有三个步骤:

  • 插入文字
  • 卷积移位
  • 磨刀

插值用于决定我们是否应该使用在先前时间步长 w_{t-1}获得的权重或者使用通过基于内容的寻址 w_t^c.获得的权重来解决该问题,我们引入新的参数 g_t 来确定我们应该使用哪些权重。g_t 的值可以是 0,也可以是 1。因此,我们的权重向量可以通过图 07 中的公式 CS1 来计算。

正如你所看到的,当 g_t 的值为 0 时,我们的权重向量是我们从上一个时间步获得的。而如果 g_t 的值是 1,那么我们的权重向量就是我们通过基于内容的寻址获得的权重向量。

然后,我们继续卷积移位,它用于移动头部位置。每个磁头发出一个参数,比如说移位权重 s_t,来给我们一个允许整数移位的分布。

假设我们的权重向量中有三个元素,如图 07 中的公式 CS2,我们的移位权重向量中有三个元素,假设 s_t = [-1,0,1]。移位-1 意味着我们将把 w_t^g 中的元素从左向右移位。移位 0 表示将元素保持在相同的位置,移位+1 表示将元素从右向左移位。那就是下图:

Fig 08 — — Shift Diagram

现在假设我们有移位权重 s_t = [1,0,0],我们将执行左移,因为在其他位置移位值为 0。

Fig 09 — — left shift

类似地,当 s_t = [0,0,1]时,我们执行如下右移

Fig 10 — — Right shift

当在权重矩阵中执行卷积移位时,假设我们有 0 到 N-1 个存储单元,卷积移位以图 7 的公式 CS3 的方式进行。

对于最后一步锐化,由于偏移,聚焦在单个位置的权重将分散到其他位置,为了减轻这种影响,执行了锐化。这里我们引入一个新的参数 gamma_t,应该大于等于 1 才能进行锐化。因此,权重向量可以表示为图 07 中的公式 S1。

广泛用于一次性学习任务的记忆增强神经网络(MANN)实际上是神经图灵机的变体。为了让 NTM 在一次性学习任务中表现得更好,曼恩不能使用基于位置的寻址。MANN 还使用了一种称为最近最少使用访问的新寻址模式。该场景背后的思想是最近最少使用的存储器位置由读取操作确定,并且读取操作由基于内容的寻址来执行。因此,我们基本上执行基于内容的寻址来读取和写入最近最少使用的位置。

记忆增强神经网络上的读操作

MANN 使用两个不同权重向量来执行读取和写入操作。MANN 中的读取操作与 NTM 相同。基于内容的相似性可以通过余弦相似性来测量,余弦相似性仍然可以表示为下面的第一个公式。权重向量可以表示为下面的第二个公式。与 NTM 不同,曼恩不使用密钥强度,所以 softmax 版本的加权向量成为下面的第三个公式。

Fig 11 — — Math in MANN read operations

以线性方式与权重向量和记忆矩阵结合的读取向量可以表示为上述第四个公式。

记忆增强神经网络上的写操作

为了找到最近最少使用的内存位置,我们可以计算一个新的向量,称为使用权重向量,比如 w_t^u,它将在每次读写步骤后更新。因此,使用加权向量成为读取加权向量和写入加权向量的总和,如图 12 中的公式 F1 所示。

Fig 12 — — Math in MANN Write Operations

然后,我们可以通过添加衰减的先前使用权重向量来更新我们的使用权重向量,它变成图 12 中的公式 F2,假设衰减参数γ用于确定先前使用权重必须如何衰减。

为了计算最近最少使用的位置,我们引入另一个权重向量,比如最少使用的权重向量 w_t^{lu}.从使用权重向量计算最少使用的权重向量非常简单。只需将使用权重向量中最低值的索引设置为 1,其余值设置为 0,因为使用权重向量中的最低值意味着它最近最少被使用。

然后,我们使用 sigmoid 门计算写入权重向量,该门用于计算之前的读取权重向量和之前最少使用的权重向量的凸组合。写权重向量变成图 12 中的公式 F3。在计算写入权重向量之后,我们最终更新存储器矩阵,即图 12 中的公式 F4。

这篇文章主要是关于记忆增强神经网络的概念和数学,你可以在这里找到代码实现部分:

[## 记忆增强神经网络构建实践(第二部分)

在这篇文章中,我将向你展示一些构建记忆增强神经网络(简称 MANN)的代码。可以参考一下…

medium.com](https://medium.com/@xavier_lr/hands-on-memory-augmented-neural-networks-build-part-two-896b1ef50726)

实践:预测客户流失

原文:https://towardsdatascience.com/hands-on-predict-customer-churn-5c2a42806266?source=collection_archive---------1-----------------------

长话短说——在这篇文章中,我们想亲自动手:建立一个模型,识别我们亲爱的客户在不久的将来离开我们的意图。我们通过在 python 的帮助下实现一个预测模型来做到这一点。不要期待一个完美的模型,而是期待一些你今天可以在自己的公司/项目中使用的东西!

在我们开始之前,让我们简要回顾一下什么是客户流失:客户流失量化了取消订阅或取消服务合同的客户数量。对于任何企业来说,顾客拒绝接受你的服务或产品都不是一件有趣的事情。一旦失去,赢回他们是非常昂贵的,甚至没有想到如果不满意,他们不会做最好的口碑营销。在我之前的一篇文章中,了解所有关于客户流失的基础知识。现在让我们开始吧!

我们将如何预测客户流失?

预测未来客户流失的基础层是来自过去的数据。我们关注已经流失的客户的数据(反应)以及他们在流失发生前的特征/行为(预测)。通过拟合一个将预测因素与响应联系起来的统计模型,我们将尝试预测现有客户的响应。这种方法属于监督学习的范畴,以防万一你需要一个更嗡嗡作响的表达。在实践中,我们执行以下步骤来进行这些精确的预测:

High Level Process

  1. 用例/业务用例
    第一步实际上是理解具有期望结果的业务或用例。只有理解了最终目标,我们才能建立一个实际有用的模型。在我们的案例中,我们的目标是通过预先识别潜在的客户流失候选人来减少客户流失,并采取积极的行动来留住他们。
  2. 数据收集和清理
    通过了解上下文,可以识别正确的数据源、清理数据集并为功能选择或工程设计做准备。这听起来很简单,但这可能是最难的部分。预测模型的好坏取决于数据源的好坏。尤其是初创公司或小公司往往很难找到足够的数据来充分训练模型。
  3. 特征选择和工程
    第三步,我们决定在我们的模型中包含哪些特征,并准备好净化后的数据,用于机器学习算法来预测客户流失。
  4. 建模
    有了准备好的数据,我们就可以开始构建模型了。但是为了做出好的预测,我们首先需要找到正确的模型(选择),其次需要评估算法是否真的有效。虽然这通常需要几次迭代,但我们会保持简单,一旦结果符合我们的需要就停止。
  5. 最后但同样重要的是,我们必须评估和解释结果。这意味着什么?我们能从结果中得出什么行动?因为预测客户流失只是其中的一半,许多人忘记了仅仅通过预测,他们仍然可以离开。在我们的案例中,我们实际上想让他们停止离开。

我们使用的工具

Tools to predict churn in python

为了预测客户是否会流失,我们正在使用 Python 和它令人惊叹的开源库。首先,我们使用 Jupyter Notebook,这是一个用于实时编码的开源应用程序,它允许我们用代码讲述一个故事。此外,我们导入了 Pandas ,这将我们的数据放在一个易于使用的结构中,用于数据分析和数据转换。为了让数据探索更容易理解,我们巧妙地使用来可视化我们的一些见解。最后,通过 scikit-learn 我们将分割数据集并训练我们的预测模型。

数据集

公司拥有的最有价值的资产之一是数据。由于数据很少公开共享,我们采用了一个可用的数据集,您可以在 IBMs 网站以及其他页面上找到,如 Kaggle :电信客户流失数据集。原始数据集包含 7000 多个条目。所有条目都有几个特征,当然还有一列说明客户是否搅拌过。
为了更好地理解数据,我们首先将它加载到 pandas 中,并在一些非常基本的命令的帮助下探索它。

import numpy as np
import pandas as pd 
import matplotlib.pyplot as plt 
import seaborn as sns
import warnings
warnings.filterwarnings("ignore")from pylab import rcParams%matplotlib inline# Loading the CSV with pandas
data = pd.read_csv('..Customer Churn/Telco-Customer-Churn.csv')

探索和特征选择

本节非常简短,因为您可以在更好的教程中了解更多关于一般数据探索的内容。然而,为了获得初步的见解,并了解您可以用数据讲述什么故事,数据探索无疑是有意义的。通过使用 python 函数 data.head(5)和“data.shape ”,我们得到了数据集的总体概述。

Glimpse of the dataset — overall 7043 rows with 21 columns

具体来说,我们来看看目标特性,即实际的“客户流失”。因此,我们相应地绘制它,并看到客户流失总量的 26.5%。了解这一点很重要,因为在我们的培训数据中,流失客户与非流失客户的比例是相同的。

# Data to plot
sizes = data['Churn'].value_counts(sort = True)
colors = ["grey","purple"] 
rcParams['figure.figsize'] = 5,5# Plot
plt.pie(sizes, explode=explode, labels=labels, colors=colors,
        autopct='%1.1f%%', shadow=True, startangle=270,)plt.title('Percentage of Churn in Dataset')
plt.show()

数据准备和特征工程

要知道,我们为机器学习模型准备的数据越好,我们的预测就越好。我们可以有最先进的算法,但如果我们的训练数据很烂,我们的结果也会很烂。由于这个原因,数据科学家花费大量时间准备数据。由于数据预处理需要很多时间,但这不是本文的重点,我们将通过一些示例性的转换来完成。

  1. 丢弃不相关的数据
    可能会包含一些不需要的数据来改进我们的结果。最好是通过逻辑思维或创建关联矩阵来识别。例如,在这个数据集中,我们有 customerID。因为它不影响我们的预测结果,所以我们用 pandas 的“drop()”函数删除该列。
data.drop(['customerID'], axis=1, inplace=True)

2.缺失值
此外,处理缺失数据也很重要。这些值可以用“.”来标识。isnull()"函数在熊猫中的应用。在识别空值之后,如果用平均值、中间值或众数来填充缺失值是有意义的,或者如果有足够的训练数据,则完全丢弃该条目,这取决于每种情况。在我们正在处理的数据集中,有一个非常不寻常的情况——没有空值。今天我们很幸运,但重要的是要知道通常我们必须处理这个问题。

3.从对象
转换数字特征从我们的数据探索(在本例中为“data.dtypes()”)中,我们可以看到 MonthlyCharges 和 TotalCharges 列是数字,但实际上是对象格式。为什么这样不好?我们的机器学习模型只能处理实际的数字数据。因此,通过“to_numeric”函数,我们可以更改格式,并为我们的机器学习模型准备数据。

data['TotalCharges'] = pd.to_numeric(data['TotalCharges'])

4.分类数据转换成数值数据
因为我们不能用字符串值计算任何东西,我们必须将这些值转换成数值。电信数据集中的一个简单例子是性别。通过使用 Pandas 函数“get_dummies()”,两列将用“gender_Female”和“gender_Male”替换性别列。

除此之外,我们可以对数据集中的所有分类变量使用“get_dummies()”函数。这是一个强大的功能,但是有这么多额外的列可能会令人不安。

5.分割数据集
首先我们的模型需要被训练,其次我们的模型需要被测试。因此,最好有两个不同的数据集。至于现在我们只有一个,相应拆分数据是很常见的。x 是自变量的数据,Y 是因变量的数据。测试大小变量决定了数据的分割比例。在 80 的培训/ 20 的测试比例中,这样做是很常见的。

data["Churn"] = data["Churn"].astype(int)Y = data["Churn"].values
X = data.drop(labels = ["Churn"],axis = 1)*# Create Train & Test Data*
from sklearn.model_selection import train_test_split
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2, random_state=101)

逻辑回归和模型测试

逻辑回归是最常用的机器学习算法之一,主要用于因变量(此处为流失 1 或流失 0)为分类变量的情况。相反,自变量可以是分类变量,也可以是数值变量。请注意,当然详细理解模型背后的理论是有意义的,但在这种情况下,我们的目标是利用预测,我们不会在本文中讨论这个。

第一步。让我们从 sci-kit learn
步骤 2 导入我们想要使用的模型。我们制作一个模型的实例
步骤 3。在训练数据集上训练模型并存储从数据中学习到的信息

from sklearn.linear_model import LogisticRegression
model = LogisticRegression()
result = model.fit(X_train, y_train)

有了训练好的模型,我们现在可以预测客户是否对我们的测试数据集产生了兴趣。结果保存在“prediction_test”中,然后测量并打印准确度分数。

from sklearn import metrics
prediction_test = model.predict(X_test)# Print the prediction accuracy
print (metrics.accuracy_score(y_test, prediction_test))

分数显示,在 80%的情况下,我们的模型预测了二元分类问题的正确结果。这在第一次运行中被认为是非常好的,特别是当我们查看每个变量的影响以及这是否有意义时。因此,为了减少流失并及时采取正确的预防措施,我们想知道哪些独立变量对我们的预测结果影响最大。因此,我们将模型中的系数设置为零,并查看每个变量的权重。

# To get the weights of all the variables
weights = pd.Series(model.coef_[0],
 index=X.columns.values)
weights.sort_values(ascending = False)

可以观察到,一些变量与我们预测的变量成正相关,而一些变量则成负相关。正值对我们预测的变量有积极的影响。一个很好的例子是“逐月合同”:与客户流失的正相关意味着拥有这种类型的合同也增加了客户流失的可能性。另一方面,“两年合同”与预测变量高度负相关,这意味着这种类型合同的客户不太可能流失。但是我们也可以看到,有些变量在第一点没有意义。就对客户流失的积极影响而言,“光纤”居于首位。虽然我们预计这会让客户留下来,因为它为他提供了快速的互联网,但我们的模型却不这么认为。在这种情况下,深入挖掘并获得数据的一些背景信息是很重要的。

是的,我们做到了——下一步是什么?

Hug your customer and make him stay 😃

一——和你的团队谈谈。
我们不仅发现了哪些客户可能会流失,还发现了哪些特征对客户的流失影响最大。因此,强烈建议与您的客户成功团队分享这些见解,并调整他们的关注点。只有当团队知道重点放在哪里时,他们才能引导客户关注那些能让他/她停留更久的功能。开诚布公地说出来,讨论各种选择,并确保你了解整个背景。在许多情况下,客户成功或支持团队能够提供额外的定性见解,这些见解可能会强调您的发现或完全讲述与您的发现不同的故事。

二——与可能流失的客户接触
是的,有一个故事说你不应该惹是非。但在潜在客户流失的情况下,这是扯淡。保持安静并希望你的客户不会离开,迟早会 100%地陷入客户流失。相反,不要害怕,走出去和你的客户接触。有很多选择,但最好的选择是最明显的:和他们谈谈。

查看他们的个人资料,确定特征,分析过去与你的产品的互动,然后简单地与他们交谈。寻求反馈,交流可能感兴趣的最新进展,或者向他们介绍新产品功能。接近可能会流失的客户,但要确保你提出了可能符合他们个人需求的相关内容。这将创造一种被理解的感觉,并将他们与你和你的企业捆绑在一起。


与此相关的文章:

预测性维护:ML vs 基于规则

动手:客户细分

应用机器学习提高创业估值

动手操作:使用 Docker 设置您的数据环境

消除流失是增长黑客 2.0

数据误导&统计


我写的大部分内容都让我忙于自己的创业。
期待听到你的经历:)


Python 数据可视化实践 Seaborn 计数图

原文:https://towardsdatascience.com/hands-on-python-data-visualization-seaborn-count-plot-90e823599012?source=collection_archive---------10-----------------------

A Seaborn Count Plot

在本教程中,我们将一步一步地展示如何使用 Python Seaborn 库 来创建计数图。基本上,Seaborn 计数图是一个图形显示,使用条形图显示每个分类数据的出现次数或频率。

数据来源

公共 Airbnb 数据集“ AB_NYC_2019.csv”,将用作样本数据来创建 Seaborn 计数图。数据集可以从 Kaggle 获取(https://www . ka ggle . com/dgomonov/new-York-city-Airbnb-open-data)。

先决条件 Python 库

每个库的安装和设置细节都在它们的官方网站上给出。

它是如何工作的

步骤 0:创建一个 Jupyter 笔记本文档。

我们将编写 Python 脚本并在 Jupyter 笔记本环境中运行它。

第一步:导入库并读取数据。

一旦库准备就绪,我们就可以继续读取并可视化来自“ AB_NYC_2019.csv ”的前五行列表数据。

First five rows of data from “AB_NYC_2019.csv

步骤 2:为单个分类变量" room_type " 创建一个简单的计数图

当我们观察数据集时,在“ room_type ”列中显示的基本上有三种类型的房间(“私人房间”、“整个家/apt”、“共享房间”)。直观显示每种房间类型的观察计数的一种简单方法是创建计数图。我们可以通过添加几行代码(第 13–16 行)轻松创建计数图,如下所示。

Create a count plot for a single categorical variable (room_type)

  • 第 14 行——为我们的情节设置一个 Seaborn 主题“黑暗网格”。
  • 第 15 行—将分类变量“ room_type ”(目标列)分配给参数“ x ”。参数“数据分配给绘图数据集 airbnb

快速生成一个简单的计数图。

A count plot for single categorical variables

步骤 3:为两个分类变量“房间类型和“邻居组”创建计数图

比方说,如果我们希望了解不同邻居组中每种房间类型的一般可用性,我们可以基于两个分类变量创建计数图,“房间类型和“邻居组”。

  • 第 15 行—在 seaborn.countplot()中再添加一个参数“色调,并为其分配第二个分类变量“neighborhood _ group”。

A count plot for two categorical variables

从上面的计数图中,很明显“整个家庭/公寓”的房间类型在曼哈顿非常常见。该图还揭示了在数据集中的所有邻域组中“共享房间”的可用性非常有限。因此,我们得到合住房间的机会相对较低。

**步骤 4:为三个分类变量“房间类型”、“邻居组”和“价格组”创建计数图

我们也经常会遇到这样的情况:我们的旅行预算有限,希望计划一次住宿费用较低的旅行。一张显示不同地点中低价住宿信息的图表可能对我们的旅行计划有帮助。

为此,我们可以在现有的 Airbnb 数据集中添加一个新列“price _ group”**

Add new column “price_group” into table

  • 第 9 行到第 15 行—创建一个函数 groupPrice() 将房间价格分为三个不同的组:低成本(低于 100 美元)、中等成本(100 美元到 200 美元)和高成本(高于 200 美元)。
  • 第 17 行—将 groupPrice() 函数应用于数据集的现有 price 列。这将创建一个新列,其中包含三个不同的分类值(“低成本”、“中成本”和“高成本”)。
  • 第 18 行—在数据集中的“价格”列旁边插入新列。
  • 第 19 行—显示前五行记录。**您将看到新列“价格 _ 组”被添加到表格中“价格”旁边的列中。******

Added new column in the table

接下来,我们使用 catplot() 合并三个计数图。

  • 第 22 行—组合三组计数图,这些计数图由第三个分类变量“ price_group ”分组。这是通过在 Seaborn 函数 catplot()中将“ price_group ”赋值给参数“ col ”来实现的。

Count plots based on three categorical variables

该图显示,布鲁克林可能是一个寻求低成本私人房间的个人旅行者的好选择。曼哈顿或布鲁克林可能是家庭/团体旅行的理想目的地,因为这相对更容易获得一个合理的中等价格范围的整个家庭/公寓单元,可供一群旅行者分享。

结论

当我们浏览上面的教程时,我们会发现使用 Seaborn 只需几行代码就可以生成一个吸引人的计数图,这并不困难。计数图可以揭示许多从原始数据集中无法直接发现的事实。

我希望你喜欢阅读这篇文章。非常欢迎您的评论或任何询问。

实践:使用 Docker 设置您的数据科学环境

原文:https://towardsdatascience.com/hands-on-setup-your-data-environment-with-docker-dca629607148?source=collection_archive---------30-----------------------

每当你开始一个新的数据项目或有一个处理数据的好主意时,最初的概念验证可能是必要的。当然,您不希望,也可能没有时间花几个小时来建立一个全新的数据环境,甚至连数据本身都不看一眼。在下面的文章中,您将了解 Docker 如何帮助您建立一个可复制的数据环境,而不必一次又一次地浪费您的时间。

Docker 是什么,为什么要试一试?

Docker 是一种最简单、最灵活的方法,可以在特定的环境中创建、部署和运行您想要的应用程序,也就是所谓的容器。你当然会问自己什么是容器?

非技术性的解释:就像上图一样,想象一下,在我们的例子中,你的本地机器是一个你已经在生产东西的孤岛。为了改善这一点,你需要额外的工具,这些工具(就像 Docker 标志一样)装在小容器里。一旦您设置并运行它们,它们就可以运行了。

技术解释:容器是软件的一个标准单元,它封装了代码及其所有依赖关系,因此应用程序可以快速可靠地从一个计算环境运行到另一个计算环境。Docker 容器映像是一个轻量级的、独立的、可执行的软件包,包括运行应用程序所需的一切:代码、运行时、系统工具、系统库和设置。其他重要术语:

  • 图片:只是你的容器的快照。
  • Dockerfile:这是一个 yaml 文件,用来建立你的形象。在本课程结束时,您将拥有一个 yaml 文件模板,并将其用于您自己的容器规范。
  • Docker hub: 在这里你可以推拉 Docker 图片,并根据自己的需要使用。基本上 GitHub 只是针对 Docker 的。

为什么要用 Docker?

让我向你概述一下我喜欢使用 Docker 的主要原因:

  • 对于作为数据科学家或数据分析师的您来说,docker 意味着您可以专注于探索、转换和建模数据,而无需首先考虑数据环境所运行的系统。通过使用 Docker 容器中数以千计的应用程序中的一个,您不必担心单独安装和连接它们。Docker 允许您在几秒钟内部署您选择的工作环境——只要您需要。
  • 让我们假设您不是项目中唯一的工作人员,但是您的团队成员也需要接触代码。现在唯一的选择是每个队友在他们自己的环境中运行代码,使用不同的架构、不同的库和不同版本的应用程序。docker 选项是每个成员都可以访问同一个容器映像,用 docker 启动映像并准备好。Docker 为团队中的每个人提供了可重复的数据环境,因此您可以立即开始协作。

Docker 肯定还有其他一些好处,尤其是如果您正在使用企业版的话。这绝对值得探索,不仅对作为数据科学家的你有好处。

安装和运行 Docker

您可以安装 Docker desktop,这是您需要立即开始的东西:访问 Docker Hub 这里,为您的 Mac 或 Windows 选择 Docker 版本并安装它。一旦在本地 machina 上启动 Docker,你就可以在顶部导航栏上看到这条可爱的小鲸鱼——干得好。

通过点击 Docker 的标志,你可以看到 Docker 是否正在运行。另一种方法是打开命令行并输入“docker info ”,这样你就可以看到正在运行的程序。以下是一些基本的 Docker 命令:

**docker login #Log in to Docker registry docker run <image> #create a new container and start it docker start <image> #start an existing container**
**docker stop <name|id> #stop a running container**
**docker ps [-a include stopped containers] #show all containers**

你可以从一个简单的例子开始,用 Jupyter 笔记本试试看。你所要做的就是在 Docker Hub 中寻找一个图像,打开你的终端,运行 Docker。在下面的例子中,您可以找到在 localhost:8888 上运行的 Jupyter 很容易!

docker run -p 8888:8888 jupyter/scipy-notebook:2c80cf3537ca

虽然我们现在可以在我们的容器中摆弄我们的应用程序,但它并不是高级数据科学家正在寻找的完整的数据环境。您可能希望使用更高级的工具,比如 Nifi 用于数据接收和处理,Kafka 用于数据流,SQL 或非 SQL 数据库用于存储中间的一些表。我们还能用 Docker 做所有这些吗?答案是:当然可以——Docker compose up 是为您管理这一切的。

Docker Compose:将所有内容整合在一起

为了设置您想要的数据环境,您可能希望在我们的本地机器上运行几个容器。这就是我们使用 Docker Compose 的原因。Compose 是一个定义和运行多容器 Docker 应用程序的工具。虽然单独连接每个容器可能很耗时,但 docker compose 允许多个容器的集合通过它们自己的网络以非常直接的方式进行交互。使用 compose,首先使用一个 yaml 文件来配置应用程序的服务,然后使用一个命令(docker compose up)就可以创建并启动先前定义的所有服务。 *

在下文中,您可以找到开始的主要步骤:

  1. 用一个Dockerfile来定义你的应用环境,以便于复制
  2. docker-compose.yml中指定组成您的数据环境的所有服务
  3. 在你保存 yaml 文件的文件夹中打开你的终端并运行docker-compose up

一个docker-compose.yml可能看起来像你在下面看到的一样。尽管您肯定可以使用以下内容作为模板,但您肯定应该为自己配置一次:

version: '3'
services:
  zookeeper:
    hostname: zookeeper
    container_name: zookeeper_dataenv
    image: 'bitnami/zookeeper:latest'
    environment:
      - ALLOW_ANONYMOUS_LOGIN=yes
  nifi:
    image: mkobit/nifi
    container_name: nifi_dataenv
    ports:
      - 8080:8080
      - 8081:8081
    environment:
      - NIFI_WEB_HTTP_PORT=8080
      - NIFI_ZK_CONNECT_STRING=zookeeper:2181
  minimal-jupyter-notebook:
    image: jupyter/minimal-notebook:latest
    ports:
      - 8888:8888
  mongodb:
    image: mongo:latest
    container_name: mongodb_dataenv
    environment:
      - MONGO_DATA_DIR=/data/db
      - MONGO_LOG_DIR=/dev/null
    ports:
        - 27017:27017
  grafana:
    image: bitnami/grafana:latest
    container_name: grafana_dataenv
    ports:
      - 3000:3000
  db:
    image: 'postgres:9.6.3-alpine'
    container_name: psql_dataenv
    ports:
      - 5432:5432
    environment:
      POSTGRES_DB: psql_data_environment
      POSTGRES_USER: psql_user
      POSTGRES_PASSWORD: psql
      PGDATA: /opt/psql_data
    restart: "no"

就是这样!您刚刚学习了如何在几秒钟内随时随地部署您自己的数据环境的基础知识,这意味着在设置方面浪费更少的时间,而有更多的时间来提高工作效率。


您可能也喜欢阅读的文章:

动手操作:客户细分

消除流失是增长黑客 2.0

数据误导&统计

学习创建自己的样本数据集


请注意,还有很多其他的容器软件选项。我只是喜欢和 Docker 一起工作,并想和你分享我的经验

用于编写 Docker 的资源:

[## docker/撰写

Compose 是一个定义和运行多容器 Docker 应用程序的工具。使用合成,您可以使用合成文件…

github.com](https://github.com/docker/compose)

TensorFlow 实践教程:使用 ImageNet 数据集从头开始训练 ResNet-50

原文:https://towardsdatascience.com/hands-on-tensorflow-tutorial-train-resnet-50-from-scratch-using-the-imagenet-dataset-850aa31a39c0?source=collection_archive---------6-----------------------

在这篇博客中,我们给出了如何在 TensorFlow 中训练 ResNet 模型的快速指南。虽然官方的 TensorFlow 文档确实有您需要的基本信息,但它可能不会马上完全有意义,并且可能有点难以筛选。

我们在这里展示了一个循序渐进的培训过程,同时记录了最佳实践、技巧、诀窍,甚至是我们在开展培训过程中遇到并最终克服的一些挑战。

我们涵盖您需要做的一切,从启动 TensorFlow、下载和准备 ImageNet,一直到记录和报告培训。所有的实验和训练都是在 Exxact Valence 工作站上完成的,使用了 2 个英伟达 RTX 2080 Ti GPU。

有什么意义?我就不能用迁移学习吗?

是的,但是本教程是使用大型数据集(ImageNet)从头开始训练大型神经网络的好练习。虽然迁移学习是一件美妙的事情,并且您可以下载 ResNet-50 的预培训版本,但以下是您可能想要进行此培训练习的一些令人信服的原因:

  1. 如果你完成了本教程,你已经有效地训练了一个神经网络,可以作为一个通用的图像分类器。
  2. 有了合适的流程,您可以根据自己的数据训练网络。例如,假设您想要训练一个可以对医学图像进行分类的网络。如果图像经过适当的预处理,根据您的数据训练的网络应该能够对这些图像进行分类。
  3. 如果您有许多独特的训练数据,从头开始训练网络应该比一般的预训练网络具有更高的准确性。
  4. 您可以专门针对您的数据调整训练参数。
  5. 在预训练的模型上,检查点是脆弱的,并且不能保证与未来版本的代码一起工作。

虽然迁移学习是一种强大的知识共享技术,但知道如何从头开始训练仍然是深度学习工程师的必备技能。所以现在,让我们开始吧。

步骤 1)运行 TensorFlow Docker 容器。

首先,您需要启动 TensorFlow 环境。我们喜欢和 Docker 一起工作,因为它给了我们极大的灵活性和可复制的环境。打开一个终端窗口,让我们开始吧!

注意:一定要指定你的-v 标签,以便在容器内创建一个交互卷。

nvidia-docker run -it -v /data:/datasets tensorflow/tensorflow:nightly-gpu bash

如果您计划在 docker 容器中启动 Tensorboard,请确保指定 -p 6006:6006 并使用以下命令。

nvidia-docker run -it -v /data:/datasets -p 6006:6006 tensorflow/tensorflow:nightly-gpu bash

步骤 2)下载并预处理 ImageNet 数据集。

我们决定包括这一步,因为它似乎会引起一点混乱。注意:当你做这一步时,你要确保你有 300+ GB 的存储空间(正如我们发现的),因为下载&预处理步骤需要这个!

2.1)对于第一个子步骤,如果您的环境中没有 git,您需要安装它。

apt-get install git

2.2)其次,您必须将 TPU 回购克隆到您的环境中(不,我们没有使用谷歌的 TPU,但是这里包含了基本的预处理脚本!)

git clone [https://github.com/tensorflow/tpu.git](https://github.com/tensorflow/tpu.git)

2.3)第三,您需要安装 GCS 依赖项(即使您没有使用 GCS,您仍然需要运行它!)

pip install gcloud google-cloud-storage

2.4)最后,您将需要运行 imagenet_to_gcs.py 脚本,该脚本从 Image-Net.org 下载文件,并将它们处理成 TFRecords,但不将它们上传到 gcs(因此有了‘nogcs _ upload’标志)。同样 'local_scratch_dir=' 应该指向您想要保存数据集的位置。

python imagenet_to_gcs.py --local_scratch_dir=/data/imagenet --nogcs_upload

注意:ImageNet 非常大,根据您的连接情况,可能需要几个小时(可能是一夜)才能下载完整的数据集!

步骤 3)下载 TensorFlow 模型。

这一步是显而易见的,如果你没有模型,克隆回购使用:

git clone [https://github.com/tensorflow/models.git](https://github.com/tensorflow/models.git)

步骤 4)导出 PYTHONPATH。

将 PYTONPATH 导出到计算机上 models 文件夹所在的文件夹。下面的命令是模型在我的机器上的位置!确保用模型文件夹的数据路径替换 '/datasets/models' 语法!

export PYTHONPATH="$PYTHONPATH:/datasets/models"

第 5 步)安装依赖项(您差不多准备好了!)

导航到 models 文件夹(如果您还不在那里)并运行以下命令

pip install --user -r official/requirements.txt

如果你使用 Python3

pip3 install --user -r official/requirements.txt

重要提示:你已经准备好训练了!根据我们的经验,为了让训练脚本正确运行,您需要从验证文件夹中复制(或移动)数据,并将其移动到训练文件夹中!!!

步骤 6)设置训练参数,训练 ResNet,坐好,放松。

运行训练脚本 pythonimagenet _ main . py,设置训练参数。下面是我用来训练 ResNet-50 的,120 个训练历元对这个练习来说太多了,但我们只是想推动我们的 GPU。根据您的计算能力,在完整数据集上训练可能需要几天时间!

python imagenet_main.py --data_dir=/data/imagenet/train --num_gpus= 2 --batch_size=64 --resnet_size= 50 --model_dir=/data/imagenet/trained_model/Resnet50_bs64 --train_epochs=120

关于训练参数的注意事项:注意有许多不同的选项可以指定,包括:

上面提到的只是模型训练可用的一些选项。请参见resnet _ run _ loop . py查看选项的完整列表(您必须仔细阅读代码)。

你完了!现在让我们在 TensorBoard 中查看结果!

您也可以使用 TensorBoard 查看您的结果:

tensorboard --logdir=/data/imagenet/trained_model/Resnet50_bs64

张量板输出

如果您正确运行了上面的步骤(并使用了相似的参数),您应该会得到类似的结果。注意,这些结果与官方 TensorFlow 结果相当。让我们看看你能做什么!

精度

训练 _ 精度 _1

准确度 _ 最高 _5

train_accuracy_top_5_1

损失

L2 _ 损失

cross_entropy_1

learning_rate_1

最后的想法

差不多就是这样!如果您在 ResNet 培训中有任何问题,请告诉我们。还有,你在 TensorFlow 中训练模型的时候用了哪些技巧和窍门?让我知道!

原载于 2019 年 3 月 26 日https://blog.exxactcorp.com

Handtrack.js:使用 Tensorflow.js 和 3 行代码跟踪浏览器中的手交互。

原文:https://towardsdatascience.com/handtrackjs-677c29c1d585?source=collection_archive---------5-----------------------

js 库允许你用 3 行代码从任意方向的图像中跟踪用户的手(边界框)。

Here’s an example interface built using Handtrack.js to track hands from webcam feed. Try the demo here.

不久前,我真的被一个实验的结果震惊了,这个实验使用 TensorFlow 对象检测 api 来追踪图像中的手。我让训练过的模型和源代码可用,从那以后它就被用来原型化一些相当有趣的用例(一个帮助孩子拼写的工具,对预测手语的扩展手打乒乓球等)。然而,虽然许多人想用训练好的模型进行实验,但许多人仍然有设置 Tensorflow 的问题(安装、TF 版本问题、导出图表等)。幸运的是,Tensorflow.js 解决了其中的几个安装/分发问题,因为它针对在浏览器的标准化环境中运行进行了优化。为此,我创建了 Handtrack.js 作为一个库,以允许开发人员 快速 通过训练有素的手部检测模型实现原型手部/手势交互。

运行时: 22 FPS 。在 Macbook Pro 2018 上,2.2 Ghz,Chrome 浏览器。Macbook Pro 2014 2.2GHz 上的 13 FPS

该库的目标是抽象出与加载模型文件相关的步骤,提供有用的功能,并允许用户在没有任何 ML 经验的情况下检测图像中的手。你不需要训练一个模特(你可以,如果你想的话)。您不需要导出任何冻结的图形或保存的模型。您可以通过在 web 应用程序中包含 handtrack.js(细节如下)并调用库方法来开始。

使用 Handtrack.js 搭建的互动演示在这里,GitHub 上的源代码在这里。喜欢在 Codepen 里修修补补?这里有一个 handtrack.js 示例笔可以修改。

[## victordibia/handtrack.js

一个用于直接在浏览器中原型化实时手部检测(边界框)的库。- victordibia/handtrack.js

github.com](https://github.com/victordibia/handtrack.js/)

我如何在 Web 应用程序中使用它?

您可以简单地通过在脚本标签中包含库 URL 或者通过使用构建工具从npm导入它来使用handtrack.js

使用脚本标签

Handtrack.js minified js 文件目前使用 jsdelivr 托管,这是一个免费的开源 cdn,允许您在 web 应用程序中包含任何 npm 包。

<script src="https://cdn.jsdelivr.net/npm/handtrackjs/dist/handtrack.min.js"> </script>

一旦上面的脚本标签被添加到您的 html 页面中,您就可以使用handTrack变量引用 handtrack.js,如下所示。

const img = document.getElementById('img');  
handTrack.load().then(model => { 
    model.detect(img).then(predictions => {
      console.log('Predictions: ', predictions) // bbox predictions
    });
});

上面的代码片段打印出了通过 img 标签传入的图像的边界框预测。通过提交来自视频或摄像机的帧,您可以在每一帧中"跟踪"手(您需要随着帧的进展保持每只手的状态)。

Demo interface using handtrack.js to track hands in an image. You can use the renderPredictions() method to draw detected bounding boxes and source image in a canvas object.

使用 NPM

您可以使用以下代码将handtrack.js作为 npm 包安装

npm install --save **handtrackjs**

下面给出了一个如何在 React 应用程序中导入和使用它的示例。

import * as handTrack from 'handtrackjs';

const img = document.getElementById('img');

// Load the model.
handTrack.load().then(model => {
  // detect objects in the image.
  console.log("model loaded")
  model.detect(img).then(predictions => {
    console.log('Predictions: ', predictions); 
  });
});

You can vary the confidence threshold (predictions below this value are discarded). Note: The model tends to work best with well lighted image conditions. The reader is encouraged to experiment with confidence threshold to accommodate various lighting conditions. E.g. a low lit scene will work better with a lower confidence threshold.

什么时候应该使用 Handtrack.js

如果你对基于手势(身体作为输入)的交互体验感兴趣,Handtrack.js 会很有用。用户不需要附加任何额外的传感器或硬件,而是可以立即利用基于手势/身体作为输入的交互所带来的参与优势。

A simple body-as-input interaction prototyped using Handtrack.js where the user paints on a canvas using the tracked location of their hand. In this interaction the maxNumber of detections modelParameter value is set to 1 to ensure only one hand is tracked.

下面列出了一些(并非全部)相关场景:

  • 当鼠标运动可以被映射到手的运动以进行控制时。
  • 当手和其他物体的重叠可以表示有意义的交互信号(例如物体的触摸或选择事件)时。
  • 人手运动可以代表活动识别的场景(例如,从视频或个人下棋的图像中自动跟踪运动活动,或者跟踪个人的高尔夫挥杆)。或者简单地计算图像或视频帧中有多少人。
  • 互动艺术装置。可能是一套有趣的互动艺术装置控件。
  • 教别人 ML/AI。handtrack.js 库提供了一个有价值的界面来演示模型参数(置信度阈值、IoU 阈值、图像大小等)的变化如何影响检测结果。
  • 您需要一个易于使用的演示,任何人都可以通过最少的设置轻松运行或试用。

Body as input in the browser. Results from Handtrack.js (applied to webcam feed) controls of a pong game. Try it here. Modify it here on Codepen.

Body as input on a large display. Results from Handtrack.js (applied to webcam feed) can be mapped to the controls of a game.

Handtrack.js API

提供了几种方法。两个主要方法包括加载手检测模型的load()和用于获得预测的detect()方法。

load()接受可选的模型参数,允许您控制模型的性能。该方法以 web 模型格式加载预训练的手检测模型(也通过 jsdelivr 托管)。

detect()接受输入源参数(html img、视频或画布对象),并返回图像中手部位置的边界框预测。

const modelParams = {
  flipHorizontal: true,   // flip e.g for video 
  imageScaleFactor: 0.7,  // reduce input image size .
  maxNumBoxes: 20,        // maximum number of boxes to detect
  iouThreshold: 0.5,      // ioU threshold for non-max suppression
  scoreThreshold: 0.79,    // confidence threshold for predictions.
}const img = document.getElementById('img');handTrack.**load**(modelParams).then(model => {
    model.**detect**(img).then(predictions => {
    console.log('Predictions: ', predictions); 
  });
});

预测结果的形式如下

[{
  bbox: [x, y, width, height],
  class: "hand",
  score: 0.8380282521247864
}, {
  bbox: [x, y, width, height],
  class: "hand",
  score: 0.74644153267145157
}]

还提供了其他辅助方法

  • model.getFPS():获取每秒检测次数计算的 FPS。
  • model.renderPredictions(predictions, canvas, context, mediasource):在指定的画布上绘制边界框(以及输入的媒体源图像)。
  • model.getModelParameters():返回模型参数。
  • model.setModelParameters(modelParams):更新模型参数。
  • dispose():删除模型实例
  • startVideo(video):在给定的视频元素上开始摄像机视频流。返回一个承诺,可用于验证用户是否提供了视频权限。
  • stopVideo(video):停止视频流。

库大小和模型大小

  • 库大小— 810kb。主要是因为它与 tensorflow.js 库捆绑在一起(最近的版本中有一些公开的问题破坏了该库。)
  • Models — 18.5mb。这是导致页面加载时初始等待的原因。TF.js webmodels 通常被分割成多个文件(在本例中是四个 4.2mb 的文件和一个 1.7 mb 的文件。)

它是如何工作的

在底层,Handtrack.js 使用了 Tensorflow.js 库,这是一个灵活而直观的 API,用于在浏览器中从头开始构建和训练模型。它提供了一个低级的 JavaScript 线性代数库和一个高级的 layers API。

Steps in creating a Tensorflow.js -based JavaScript Library.

数据汇编

本项目中使用的数据主要来自 Egohands 数据集。这是由 4800 张不同环境下(室内、室外)带有边框注释的人手图像组成,这些图像是使用谷歌眼镜设备拍摄的。

模特培训

使用 Tensorflow 对象检测 API 训练一个模型来检测手。对于这个项目,一个单次多盒探测器 (SSD)与 MobileNetV2 架构一起使用。然后,来自训练模型的结果被导出为savedmodel。关于模型如何被训练的更多细节可以在这里和 Tensorflow 对象检测 API github repo 上找到。

模型转换

Tensorflow.js 提供了一个模型转换工具,允许您将 Tensorflow python 中训练的savedmodel转换为可以在浏览器中加载的 Tensorflow.js webmodel格式。这个过程主要是将 Tensorflow python 中的操作映射到 Tensorflow.js 中的等价实现。有必要检查保存的模型图以了解正在导出的内容。最后,我按照 Tensorflow coco-ssd 示例的作者的建议 T17 在转换期间删除了对象检测模型图的后处理部分。这种优化有效地将浏览器中检测/预测操作的运行时间增加了一倍。

库包装和托管

该库是在 tensorflowjs coco-ssd 示例之后建模的(但不是用 typescript 编写的)。它由一个主类和一组其他有用的函数组成,主类包含加载模型、检测图像中的手的方法,例如 startVideo、stopVideo、getFPS()、renderPredictions()、getModelParameters()、setModelParameters()等。Github 上有关于方法的完整描述。

然后使用 rollup.js 捆绑源文件,并在 npm 上发布(带有 webmodel 文件)。这尤其有价值,因为 jsdelivr 自动为 npm 包提供 cdn。(在其他 cdn 上托管文件可能会更快,并鼓励读者尝试其他方法)。目前,handtrackjs 与 tensorflowjs (v0.13.5)捆绑在一起,主要是因为在编写这个库时,存在版本问题,tfjs (v0.15)在将图像/视频标签作为张量加载时出现数据类型错误。随着新版本修复此问题,它将被更新。

限制

  • 浏览器是单线程的:这意味着必须小心确保预测操作不会阻塞 UI 线程。每次预测可能需要 50 到 150 毫秒,这对于用户来说是显而易见的。例如,当将 Handtrack.js 集成到一个每秒多次渲染整个屏幕(例如在游戏中)的应用程序中时,我发现它有助于减少每秒请求的预测数量。在这个场景中, Webworkers ,一个允许在后台线程中运行脚本的新兴标准,将有助于防止 UI 阻塞。

Web Workers 是 Web 内容在后台线程中运行脚本的简单手段。工作线程可以在不干扰用户界面的情况下执行任务。此外,它们可以使用[XMLHttpRequest](https://developer.mozilla.org/en-US/docs/Web/API/XMLHttpRequest)执行 I/O(尽管responseXMLchannel属性总是空的)。创建后,工作线程可以向创建它的 JavaScript 代码发送消息,方法是向该代码指定的事件处理程序发送消息(反之亦然)。本文提供了使用 web workers 的详细介绍。

  • 逐帧跟踪手:如果有兴趣跨帧识别手,您需要编写额外的代码来推断检测到的手进入、移动和离开连续帧的 id。提示:在每帧中保持每个预测位置的状态(和欧几里德距离)可以帮助
  • 错误预测:偶尔会有错误预测(有时人脸被检测为手)。我发现每个相机和照明条件需要不同的模型参数设置(尤其是置信度阈值)来获得良好的检测。更重要的是,这可以通过额外的数据来改善。

我真的很期待使用或扩展这个项目的其他人如何解决其中的一些限制。

接下来是什么?

Handtrack.js 代表了真正的 早期步骤 关于实现人工智能人机交互新形式的整体潜力。在浏览器中。已经有一些很好的想法,比如浏览器中用于人体姿势检测的posenet和用于面部表情检测的handseys . js

最重要的是,请读者想象。想象一下有趣的用例,知道用户手的位置可以产生更吸引人的交互。

与此同时,我将在以下方面花更多时间

  • 更好的手模型:创建一个健壮的基准来评估基本的手模型。收集额外的数据,提高准确性和稳健性指标。
  • 附加词汇:在我构建示例的过程中,有一点变得很明显,那就是这种交互方法的词汇有限。显然需要支持至少一个州。也许是一只拳头和一只张开的手。这将意味着重新标记数据集(或一些半监督方法)。
  • 额外的模型量化:目前,我们正在使用最快的模型 wrt 架构大小和准确性——MobilenetV2,SSD。有没有优化可以让事情变得更快?欢迎任何想法或贡献。

如果你想更详细地讨论这个问题,请随时联系 Twitter、T2、Github 或 T4 的 Linkedin。非常感谢 Kesa Oluwafunmilola 帮助校对这篇文章。

参考

  • [1]桑德勒,马克等,“移动互联网 2:反向残差和线性瓶颈。”IEEE 计算机视觉和模式识别会议录。2018.https://arxiv.org/abs/1801.04381
  • [2] Tensorflow.js Coco-ssd 示例。
    该库使用来自 Tensorflow.js coco-ssd 示例的代码和指导,该示例提供了一个用于在 MSCOCO 数据集上训练的对象检测的库。repo 中建议的优化(去掉一个后处理层)真的很有帮助(2 倍加速)。

使用 PyTorch 的手写数字识别——神经网络介绍

原文:https://towardsdatascience.com/handwritten-digit-mnist-pytorch-977b5338e627?source=collection_archive---------1-----------------------

对吗?——弄清楚上面的图片代表数字,对你来说没什么。你甚至没有为图像的分辨率差而烦恼,多神奇啊。我们都应该花点时间感谢我们的大脑!我想知道我们的大脑对图像进行处理、分类和反馈是多么自然。我们是天才!

模仿人脑会有多难?深度学习,简单来说,是机器学习研究的领域,它允许计算机学习执行大脑自然的任务,如手写数字识别。从技术上来说,它涉及更多的(我们后面会讲到)和更多的数据

在本文中,我们将讨论神经网络,并从头开始开发一个手写数字分类器。我们将使用 PyTorch 因为它很酷

本文的唯一先决条件是 Python 语法的基础知识。坐下来,喝杯咖啡,跟着我走。

Only Good Coffee Please!

步骤 1 —了解数据集

作为数据科学家,最重要的任务是收集完美的数据集,并彻底理解它。相信我,剩下的就简单多了。对于这个项目,我们将使用流行的 MNIST 数据库。它是 70000 个手写数字的集合,分为分别由 60000 个和 10000 个图像组成的训练集和测试集。

Source: Wikimedia

该数据集最初可在 Yann Lecun 的网站上获得。清理数据是最大的任务之一。别忘了— “垃圾进,垃圾出!” 。幸运的是,对我们来说,PyTorch 提供了一个简单的实现,使用几行代码就可以下载干净的和已经准备好的数据。在开始之前,我们需要做所有必要的进口。

import numpy as np
import torch
import torchvision
import matplotlib.pyplot as plt
from time import time
from torchvision import datasets, transforms
from torch import nn, optim

在下载数据之前,让我们定义在将数据输入管道之前,我们希望对数据执行哪些转换。换句话说,您可以将它视为对图像执行的某种自定义编辑,以便所有图像都具有相同的尺寸和属性。我们使用 torchvision.transforms 来实现。

transform = transforms.Compose([transforms.ToTensor(),
                              transforms.Normalize((0.5,), (0.5,)),
                              ])
  1. 摇身一变。ToTensor() —将图像转换成系统可理解的数字。它将图像分成三个颜色通道(单独的图像):红色、绿色&蓝色。然后,它将每个图像的像素转换为其颜色在 0 到 255 之间的亮度。然后将这些值缩小到 0 到 1 之间的范围。图像现在是一个火炬张量
  2. 变换变换。Normalize()

现在,我们终于下载了数据集,对它们进行了洗牌和转换。我们下载数据集并将它们加载到 DataLoader ,它将数据集和采样器结合在一起,并在数据集上提供单进程或多进程迭代器。

trainset = datasets.MNIST('PATH_TO_STORE_TRAINSET', download=**True**, train=**True**, transform=transform)valset = datasets.MNIST('PATH_TO_STORE_TESTSET', download=**True**, train=**False**, transform=transform)trainloader = torch.utils.data.DataLoader(trainset, batch_size=64, shuffle=**True**)valloader = torch.utils.data.DataLoader(valset, batch_size=64, shuffle=**True**)

在一行中,批量大小是我们想要一次读取的图像数量。

步骤 2-更好地了解数据集

在这个阶段,我们将对我们的图像和张量进行一些探索性的数据分析。让我们检查一下图像和标签的形状。

dataiter = iter(trainloader)
images, labels = dataiter.next()

print(images.shape)
print(labels.shape)

您将发现图像的形状是,torch.Size([64,1,28,28]),这表明每批中有 64 个图像,每个图像的尺寸为 28 x 28 像素。类似地,标签的形状为torch.Size([64])。猜猜为什么?—是的,你说得对!64 张图片应该分别有 64 个标签。就是这样。轻松点。

让我们显示训练集中的一幅图像,例如第一幅。

plt.imshow(images[0].numpy().squeeze(), cmap='gray_r');

酷吧!让我们展示更多的图像,这将让我们感受一下数据集的样子。

figure = plt.figure()
num_of_images = 60
**for** index **in** range(1, num_of_images + 1):
    plt.subplot(6, 10, index)
    plt.axis('off')
    plt.imshow(images[index].numpy().squeeze(), cmap='gray_r')

这将生成一个随机排列的图像网格。现在,是时候开始定义我们将要使用的神经网络了。

步骤 3——建立神经网络

我们将构建下面的网络,正如你所看到的,它包含一个输入层(第一层),一个由十个神经元(或单元,圆圈)组成的输出层,以及中间的两个隐藏层。

PyTorch 的torch.nn模块允许我们非常简单地构建上述网络。这也非常容易理解。看看下面的代码。

input_size = 784
hidden_sizes = [128, 64]
output_size = 10

model = nn.Sequential(nn.Linear(input_size, hidden_sizes[0]),
                      nn.ReLU(),
                      nn.Linear(hidden_sizes[0], hidden_sizes[1]),
                      nn.ReLU(),
                      nn.Linear(hidden_sizes[1], output_size),
                      nn.LogSoftmax(dim=1))
print(model)

nn.Sequential包裹网络中的层。有三个带 ReLU 激活线性层(一个允许正值通过的简单函数,而负值被修改为零)。输出图层是激活了 LogSoftmax 的线性图层,因为这是一个分类问题。

从技术上来说,一个 LogSoftmax 函数是一个 Softmax 函数的对数,顾名思义,它看起来像这样,如下所示。

接下来,我们定义 负对数似然损失 。用 C 类训练一个分类问题很有用。 LogSoftmax()NLLLoss() 一起充当交叉熵损失,如上面的网络架构图所示。

另外,你一定想知道为什么我们在第一层有 784 个单元。很好!这是因为我们在将每幅图像发送到神经网络之前将其展平。 (28 x 28 = 784)

criterion = nn.NLLLoss()
images, labels = next(iter(trainloader))
images = images.view(images.shape[0], -1)

logps = model(images) #log probabilities
loss = criterion(logps, labels) #calculate the NLL loss

我们将在以后的文章中讨论更多的神经网络,激活函数,优化算法等。

步骤 4 —调整重量

神经网络通过对可用数据进行多次迭代来学习学习 是指调整网络的权值,使损耗最小。让我们想象一下它是如何工作的。

print('Before backward pass: **\n**', model[0].weight.grad)
loss.backward()
print('After backward pass: **\n**', model[0].weight.grad)

在向后传递之前,模型权重被设置为默认的值。一次,我们调用 backward() 函数来更新权重。

Before backward pass: 
 None
After backward pass: 
 tensor([[-0.0003, -0.0003, -0.0003,  ..., -0.0003, -0.0003, -0.0003],
        [ 0.0008,  0.0008,  0.0008,  ...,  0.0008,  0.0008,  0.0008],
        [-0.0037, -0.0037, -0.0037,  ..., -0.0037, -0.0037, -0.0037],
        ...,
        [-0.0005, -0.0005, -0.0005,  ..., -0.0005, -0.0005, -0.0005],
        [ 0.0043,  0.0043,  0.0043,  ...,  0.0043,  0.0043,  0.0043],
        [-0.0006, -0.0006, -0.0006,  ..., -0.0006, -0.0006, -0.0006]])

步骤 5 —核心培训流程

这是真正的奇迹发生的地方。您的神经网络迭代训练集并更新权重。我们使用 PyTorch 提供的模块torch.optim来优化模型,执行梯度下降,并通过反向传播来更新权重。因此,在每个时期(我们迭代训练集的次数),我们将看到训练损失逐渐减少。

optimizer = optim.SGD(model.parameters(), lr=0.003, momentum=0.9)
time0 = time()
epochs = 15
**for** e **in** range(epochs):
    running_loss = 0
    **for** images, labels **in** trainloader:
        *# Flatten MNIST images into a 784 long vector*
        images = images.view(images.shape[0], -1)

        *# Training pass*
        optimizer.zero_grad()

        output = model(images)
        loss = criterion(output, labels)

        *#This is where the model learns by backpropagating*
        loss.backward()

        *#And optimizes its weights here*
        optimizer.step()

        running_loss += loss.item()
    **else**:
        print("Epoch **{}** - Training loss: **{}**".format(e, running_loss/len(trainloader)))print("**\n**Training Time (in minutes) =",(time()-time0)/60)

这可能需要一些时间来执行,并且会因系统而异。我在云笔记本上花了 2.5 分钟。

步骤 6 —测试和评估

我们的工作快完成了。模型做好了,但我们要先评估一下。我创建了一个实用函数 view_classify() 来显示预测的图像和类别概率。代码可以在 GitHub 上找到。(下面参考资料部分的链接)。

我将我们之前创建的验证集中的一个图像传递给训练好的模型,以查看模型是如何工作的。

images, labels = next(iter(valloader))

img = images[0].view(1, 784)**with** torch.no_grad():
    logps = model(img)

ps = torch.exp(logps)
probab = list(ps.numpy()[0])
print("Predicted Digit =", probab.index(max(probab)))
**view_classify**(img.view(1, 28, 28), ps)

Prediction Result. Perfect Prediction!

现在,我们使用 for 循环遍历验证集,并计算正确预测的总数。这是我们计算精确度的方法。

correct_count, all_count = 0, 0
**for** images,labels **in** valloader:
  **for** i **in** range(len(labels)):
    img = images[i].view(1, 784)
    **with** torch.no_grad():
        logps = model(img)

    ps = torch.exp(logps)
    probab = list(ps.numpy()[0])
    pred_label = probab.index(max(probab))
    true_label = labels.numpy()[i]
    **if**(true_label == pred_label):
      correct_count += 1
    all_count += 1

print("Number Of Images Tested =", all_count)
print("**\n**Model Accuracy =", (correct_count/all_count))

现在来看看结果。这是最有趣的部分!

Number Of Images Tested = 10000
Model Accuracy = 0.9751

哇!我们有超过 97.5%的准确率。这是值得庆祝的事情。我们获得如此高精度的原因是,我们的数据集是干净的,有各种各样经过良好洗牌的图像,而且数量很大。这使得我们的模型能够很好地识别大量看不见的数字。

步骤 7 —保存模型

现在我们已经完成了所有的工作,我们不想失去训练好的模型。我们不想每次用的时候都训练它。为此,我们将保存模型。以后需要的时候,可以直接加载使用,不需要进一步的训练。

torch**.save**(model, './my_mnist_model.pt') 

第一个参数是模型对象,第二个参数是路径。PyTorch 型号一般用.pt.pth扩展名保存。查阅文件

结论

我希望你喜欢建立一个神经网络,训练它,测试它,最后保存它的过程。在构建一个很酷的项目的同时,你肯定已经掌握了一些概念,学到了一些新东西。我很想知道它是如何为你工作的。 并且,如果你喜欢请鼓掌,这对我是一种鼓励。 😃 更多炫酷文章一字排开。即将推出!

如果你有心情请我喝啤酒🤩> >https://www.buymeacoffee.com/amitrajit

哦!并且, 整个笔记本在这里 都有。笔记本电脑的 GPU 版本不同于 CPU 版本。你可以根据你的需要参考。

参考文献

[1] PyTorch 官方 Docs 【2】MNIST 维基百科【3】Cool GIFs 来自GIPHY
【4】GitHub 上的全部代码

承认

感谢Zykrr工程给予的灵感。在,Zykrr我们与 客户体验和反馈分析 领域的尖端技术合作。

硬编码信任:来自你最喜欢的人工智能的一年悲伤的隐私响应

原文:https://towardsdatascience.com/hardcoding-trust-one-year-of-sad-privacy-responses-from-your-favorite-ai-e8dd6bb0cd21?source=collection_archive---------23-----------------------

关于谷歌、亚马逊和苹果对数据隐私的承诺,Zork 能教给我们什么

如今,数据隐私得到了很多口头上的支持。我们有苹果宣布他们将隐私融入每一件产品谷歌决定删除数百万 Google+账户(有数百万?)因为一个可能暴露私人数据的编码错误,甚至扎克伯格最近的专栏文章要求为整个互联网制定新规则,我们已经一点一点剖析了。

但是,这些公司对数据隐私和一般可信实践的实际承诺是什么?

答案就在佐克身上

Link to Play Zork below.

当我还是个孩子的时候,我玩了很多电子游戏。特别是一个游戏,Zork 激发了我对计算机和编程的热爱。最初的 Zork 游戏是由麻省理工学院动态建模小组的四名成员创建的,是一个基于文本的冒险,程序可以处理简单的动词和名词组合,并根据你要求(或键入)的角色做什么做出反应。你可以指挥诸如“拿”、“爬”、“开”、“关”、“攻击”,甚至“数数”该游戏基本上会返回三种不同类型的内容:

级别 1:一个“对不起,我不知道那个词”类型的响应

级别 2:硬编码响应

第三级:随机响应

以今天的标准来看,这勉强称得上是一个游戏,但在过去,这是世界上第一个也是最好的随机和非随机(硬编码)回答问题或命令的例子。这里的世界,我指的是我的兄弟们,我自己,还有我们街区的其他三个孩子,他们在 20 世纪 80 年代在我们的社区玩这个游戏。

This is “video” game from 1980. Just a dialogue, a conversation.

由 Infocom 发行的《Zork》到 1986 年已售出 60 多万册。此外,为了证明我不是这款游戏中唯一的数据怪胎,Zork 的全部内容在 2010 年的游戏使命召唤:黑色行动中作为“复活节彩蛋”隐藏起来,在 Ernest Cline 的畅销书(和斯皮尔伯格的电影)Ready Player One中也有突出的表现。

这个游戏让我和我的朋友们在文法学校使用 IF-THEN-ELSE 语句和随机计数器变量编写了相似类型的基本游戏。但是 Zork 也告诉我,无论名词和动词的搭配看起来有多简单,基于人类对话创建一个引人注目的计算机交互是多么困难。早期的游戏作者花时间围绕物品、库存、内容、动作和罗盘建立一个故事和世界。鉴于这是 1979 年,他们的计算机编码令人印象深刻,但更令人印象深刻的是,与谷歌、苹果、微软和亚马逊的尖端人工智能助手相比,我们可以看到 Zork 可以提供的不同类型的响应之间的相似之处。让我们看看 Zork 中三种最常见的响应类型。

三个层次的努力

级别 1:错误消息

Is Geek a verb in this case? Zork knows.

如今,错误消息有多种形式。甚至有网站致力于最好的品牌 404‘找不到页面’页面。然而,在 Zork 时代,错误消息是第一层工作,也可能是用户输入动词-名词命令时最常见的结果。

在这些例子中,我进入了游戏,可怜的佐克没有意识到我是在赞美它。它用 “我不知道这个单词[_ _ _ _ _ _]”来响应任何没有预先编程到游戏中的命令或单词。游戏知道什么时候它不知道一些事情,因为它的代码中没有答案。今天,每当我们问谷歌助手一个过于复杂的问题时,我们都会看到这种情况,比如“好吧,谷歌,告诉我去我的下一个会议坐哪趟地铁最快。”当公司特意选择不关注某个特定领域的响应能力,而是在以后更加关注该领域时,也会出现这种情况。

级别 2:硬编码答案

Zork 中的第二个级别或响应类型是硬编码的答案。如果你问 Zork 一个被识别的动名配对,往往会得到确切的回答。所以“爬树”在适当的时候导致了:

“childless songbird” is particularly interesting.

这个硬编码的答案每次基本上都是一样的。当你在这个精确的时间下命令时,你总是得到这个精确的答案。这种类型的其他命令无论什么时候使用它们,如在“ >挥斧”中每次都会导致“”。

今天,你会在我们的人工智能助手和平台中找到大量硬编码的答案。这些有时候真的很有趣而且它们绝对揭示了这些公司的团队在对话互动上投入了多少努力。比如你问 Alexa:

问:Alexa,你知道 Siri 吗?

答:只凭名声。

第三级:随机答案

在 Zork 的几个地方,你可能会问一个问题或者命令一些东西来返回随机的答案。例如,在地牢房间的某个地方,有一个巨魔挡住了你的去路。如果你说“攻击巨魔”或“杀死巨魔”,你会得到几个不同的答案之一。通常,巨魔会在几次尝试后杀死你,但偶尔,你会随机得到这个:

Trust me, you didn’t read the whole story, the Troll needs to die.

随机答案在 1979 年花费了相当多的努力来编码(当这个被开发出来的时候),但是结果和今天是一样的,游戏的玩家很快学会了等待回应的悬念,在这种情况下,不知道结果的乐趣。这种赌博的心态使得向计算机发出命令变得更有吸引力,我敢说,也更令人兴奋。在 Zork 中,对于随机反应将如何进行并没有太多的“公平”。这可能非常令人沮丧,但老实说,这一直是游戏乐趣的一部分,你可以随时命令“保存游戏”,这样你就不必重新开始。

今天在我们的人工智能助手中有许多随机化的体验。这些同样有趣,因为你永远不知道你会得到什么…

问:Alexa,给我讲个故事。

问:Siri,你多大了?

一年来问“我能信任你吗?”致艾

一年多来,我问了 Siri、Google Assistant、Cortana 和 Alexa 各种关于隐私、信任和数据的问题。我在会议上讲过这个问题,并在舞台上现场演示了很多次,结果令人着迷,特别是在与 Zork 对对话和命令的三个层次的反应相比较时。

我问这些问题的原因是,我在追踪那些大谈数据隐私和安全的公司是否真的对此做了些什么。每个人工智能和智能助理团队都有大量的资源,除非他们不专注于这些问题,否则不可能对这些问题做出更好的回答。

我在这些平台上问过大概一百种不同的主题,但是我总是回到“我能信任你吗?”鉴于所有的数据隐私问题和关于这些“始终监听”设备的新闻故事,这是消费者可能会问的最简单和最基本的问题之一。

在第一级,人工智能本质上不知道你在问它什么。它不能解析请求,或者它没有提供例程或数据答案。Zork 不是人工智能,但“我不知道单词[ ______] ”的回答与 Alexa 的“嗯,我不确定我知道那个”非常相似。以及谷歌助手的“我找到了这些结果。”谷歌通常不会告诉你它真的不理解一个请求,相反,它的错误信息会返回一些搜索查询,这在现实生活中真的更令人沮丧。然而,这是一个错误响应,因为它是没有答案的总括。

当我问每个平台“我能信任你吗?,“令人惊讶的是,有一家公司首先回报了一个 1 级的 Zork 答案:

You should understand this.

问:嘿,Siri,我能信任你吗?

答:我不太明白。

我得说实话。鉴于蒂姆·库克对工业数据综合体的讨伐,他的努力肯定没有进入 Siri 团队。一年多来,这个答案从未改变。Siri 可以用一个简单的硬编码答案告诉你她对借钱给你的感觉,但对于你是否可以相信苹果在认真对待你的数据隐私,她根本没有回应。

在第 2 级,我们让其他三个助手返回对问题的硬编码回答。这意味着,每次你问这个问题,你都会得到相同的确切答案,这表明,这些公司至少已经决定,这是一个足够常见的请求或客户体验需要编码一个响应。

No!

然而,每个人投入的思考量实际上是他们努力深度的一个窗口。首先,Cortana…

问:Cortana,我能信任你吗?

答:是的!

真的吗?一句话的回应?感叹号是怎么回事?Cortana,你是想说服我还是说服你自己?

在过去的六个月里,微软在这个问题上也遇到了麻烦,它也奇怪地返回了类似“我现在无法连接,请稍后再试”的问题。尽管有强大的互联网连接,这种情况还是会发生。因此,在阴谋论方面,我怀疑这个“是”的答案是他们对这个问题的唯一回答。

接下来,我们有一个来自谷歌助手的奇怪回应…

That “But” should be an “And”

问:好吧,谷歌,我能信任你吗?

答:信任是赚来的。但是你可以查看谷歌的隐私政策

哇哦。信任是赚来的?这有点像幸运饼干的回应,不过没关系。这当然比“是”要好

不过,在这里,谷歌至少试图指出,作为用户,你可以查看他们的隐私政策。当然,这里没有隐私政策的链接,而每一个其他的回复,谷歌都会提供链接和选项,所以这是一个需要改进的地方。但是,我对这一点的普遍厌恶源于这样一个事实,即谷歌不是用任何定义来回答,而是字面上要求你去读你第一次没有读的东西,并且现在很可能不会去读

Perfect.

最后,赢得 2 级 Zork 硬编码响应奖的是亚马逊的 Alexa…

问:Alexa,我能信任你吗?

答:我努力给你最好的信息,响应你的命令,维护你的隐私。如果有我可以改进的方法,请在 Alexa 应用程序的帮助和反馈部分添加反馈。

亚马逊显然已经想到了他们的答案。他们谈到了对命令的响应,让你获得最好的体验和信息,以及维护你的隐私。这是自威尔·法瑞尔在守旧派与拉金卡津人辩论以来最好的回答。

在每个回答中,我们都看到了第 1 级或第 2 级的努力,这是根据 Zork 敬业度和努力程度衡量的。亚马逊显然在他们的回应上投入了更多的努力,但不是以编程的方式。他们本质上只是存储了一个更长(更好)的使命描述,因为它关系到用户和他们的信任。

言而无行

可悲的现实是,在向我们当前的人工智能助手提问的每一个例子中,他们都有所欠缺。在一个简单的,类似 Zork 的场景中,苹果提供了最糟糕的体验,但老实说,大多数其他反应仍然是机器人,第二级,硬编码的反应。

我们必须做得更好。

如果人工智能不能帮助保护数据隐私,更容易地让我们控制我们的数据,它将产生远远多于它解决的问题。为了改善这种情况,我们需要从语言走向行动。实际行为。

问:Alexa,删除我的语音历史。

问:好的谷歌,删除我的位置历史。

问:嘿,Siri,关掉我的定位服务。

问:Cortana,删除我的浏览历史。

不足为奇的是,这些请求的命令或动作都不起作用。大多数返回 1 级错误响应或总括搜索结果。我们可以订购纸巾,预订理发,学习如何通过简单的请求烹饪任何东西,但当我们要求这些人工智能工具之一帮助保护我们的数据隐私时,却没有任何进展。一点努力都没有。

在 Zork 中,你总是可以输入“重启”这个一个词的命令会显示你的分数,删除之前存储的所有内容,然后重新开始。也许是时候让谷歌、亚马逊、微软和苹果效仿 Zork,给予数据隐私更多的保护,而不仅仅是口头承诺。

另外,你可以在网上免费试用 Zork】这里。(我做到了。)

原载于 2019 年 4 月 4 日wardpllc.com。保留所有权利。

驾驭不确定性的力量

原文:https://towardsdatascience.com/harnessing-the-power-of-uncertainty-3ad9431e595c?source=collection_archive---------24-----------------------

梯度推进树、逻辑回归和深度学习——你可以在你想要的每个 ML 模型中进行,并从你的机器学习模型中实现更多。

photo by Santiago Lacarta on Unsplash

让我们从想象开始,例如,给定几张狗品种的照片作为训练数据,我们有一个训练好的模型——当用户上传他的狗的照片时——假设的网站应该以相当高的可信度返回一个预测。

但是如果一个用户上传了一张猫的照片,并要求网站决定狗的品种,该怎么办呢?

该模型已经在不同品种的狗的照片上进行了训练,并且(希望)已经学会很好地区分它们。但是该模型以前从未见过猫,并且猫的照片会位于该模型被训练的数据分布之外。这个说明性的例子可以
扩展到更严重的设置,例如诊断系统从未观察过的结构的 MRI 扫描,或者自动汽车转向系统从未训练过的场景。

在这种情况下,模型的一个可能的预期行为是
返回一个预测(试图从我们观察到的数据外推),但返回一个带有附加信息的答案,即该点位于数据分布之外(见图 1.2 中回归情况的简单描述)。也就是说,我们希望我们的模型拥有一些数量来传达这种输入的高度不确定性(或者,传达低置信度)。

在这篇文章中,我将介绍如何挖掘模型不确定性的方法。
我会在 3 种不同的模型上展示:L 逻辑回归梯度推进树 s、D 深度学习。这篇文章是写给那些已经熟悉这些算法和架构的人的。

准备好了吗?开始吧!

驾驭不确定性的力量

为了利用你的模型不确定性的力量,你需要知道你的模型的分布(大多数时候很容易假设它接近正态分布)。

当分布已知时,您可以计算您的模型均值和标准差。
标准差是模型的不确定性,平均值是模型的结果。您现在可以将它用于简单的 UCB:

3 is just a factor for the sigma, it can be any number, the larger the factor the more weights on the exploration

这是一个例子,你也可以在 Tompson 采样中使用,假设你的模型是正态分布的。

梯度推进树

梯度推进树是一种强大的算法,可能是当今最常用的算法。
我觉得最常见的算法有:XGBoost,LightGBM,和 CatBoost。在这篇文章中,我将用 CatBoost 展示这个例子,但是同样的想法可以在所有的例子中实现,也可以在像 Random Forest 这样的常规决策树中实现。

为了得到你的决策树模型的不确定性,你需要分别收集每棵树的预测。如果你使用分类,得到每棵树分类的概率。如果使用回归,请使用回归的值。

当每个预测都有一个来自每棵树的概率列表时,可以从每个预测的概率列表中计算平均值和标准偏差。

example with CatBoost how to get each tree prediction, and from those predictions calculate the mean and the std of each prediction in order to get and use the uncertainty

深度学习

我开始研究模型中的不确定性以提高准确性的原因是因为深度学习。我认为把深度学习的不确定性中的“联合国”放在一起的人是亚林·加尔,他的论文是“深度学习的不确定性”。他的主要想法是使用辍学,谁更常用于训练,以避免过度拟合,也在预测。在预测时,我们也将使用 dropout,并运行相同的预测 X 次,因为 dropout 是随机选择的,每个预测我们将得到相同预测的一些不同结果。有了这些不同的结果,我们可以很容易地计算平均值和标准差。

当你有均值和标准差时,这是和之前一样的解。

逻辑回归

Sigmoid Function Graph

The formula of a sigmoid function | Image: Analytics India Magazine

我首先要说的是,这里我们没有得到模型的不确定性,但是我们理解我们训练数据的不确定性。
这里的想法是在来自训练集的不同切割上训练相同的模型。要获得模型的不确定性,您需要做以下工作:

  1. 将你的训练集分成 N 份
  2. 每次切割将随机选择 70%–80%的训练集记录。
  3. 在每次切割中,您将训练一个逻辑模型(最后您将有 N 个模型)
  4. 对所有 N 个定型模型运行每个预测
  5. 计算所有预测的平均值和标准差。

包扎

在这篇文章中,我们回顾了获得模型不确定性的方法。
最常见的方法是深度学习,但你也看到了在 GDT 和逻辑回归模型中这样做的方法。

正如我说过的,模型不确定性的用途可以是在打开模型时进行更多的探索,但它也可以提高精确度。如果您的数据可以在对这些项目了解较少的情况下获得新项目,那么模型不确定性在这里会非常有用。

如果您有任何问题或需要更好地了解它如何帮助您,以及如何在技术上做到这一点,请通过 Linkedin 联系我。

哈佛大学 CS50 计算机科学导论 2019 回顾

原文:https://towardsdatascience.com/harvards-cs50-intro-to-computer-science-2019-review-10d89177a8a2?source=collection_archive---------5-----------------------

CS50 是哈佛的计算机科学入门课程。这门课程不仅仅是在线完成的,它是教授给哈佛学生的实际课程。所有的讲座都在哈佛拍摄,并放在网上,还有作业、辅导视频和所有支持笔记(如果你想看的话,笔记和作业链接在下面)。你的作业是有分数的,所以你和真正的哈佛学生有着同样的标准。令人难以置信的是,所有这些都是完全免费的。

该课程从最基础的开始,解释二进制并使用可视化的、基于块的编程语言 Scratch,然后继续学习 c。难度从这里开始迅速增加,深入讨论计算机如何处理代码、信息如何存储在内存中以及什么是数据结构。然后,它转移到 HTML、Javascript 和 Python。最后,您运行一个 web 服务器并从 API 中提取数据。

作为一个通过在线课程学习编程的人,我一直在想,如果不像大学生那样学习更多的理论模块,我是否会错过一些东西。尽管只是一个介绍,这个课程帮助我更好地了解了计算机是如何处理我写的代码的,并解决了我的一些自我怀疑。

谁应该上这门课?

这门课程考虑到了一系列的能力。任务通常有两种,“不太舒服”和“比较舒服”,你可以选择接受哪一种。在课程开始前,我已经处于中等水平的编码技能,所以选择了“更舒适”的作业。我仍然觉得 C 语言中的作业很有挑战性。

适合初学者吗?

在讲座中,每件事都有很好的解释,还有很棒的笔记和额外的“短片”视频,它们更详细地解释了特定的主题。由于这门课程非常受欢迎,也有许多其他资源可用,如子编辑和专用的 stackoverflow 网站。因此,虽然很有挑战性,但如果你愿意花时间,这个课程还是可以管理的。

然而,如果你只是刚刚开始,我不建议你这么做。这门课的工作量很大,如果你是初学者,可能需要 200 个小时左右(关于工作量的更多细节见下文)。这种努力会让很多人在到达终点之前就失去兴趣。

这个这个关于网络开发的课程将教你编码让你更快地构建酷的东西,这将有助于建立你的信心。我确信在这门课的某个时刻,每个人都会觉得自己像个白痴,所以保持自信让你坚持下去是很重要的。如果你以前没做过什么,很容易走开,认为编码不适合你,这几乎肯定不是真的。

是哈佛的…需要超级聪明吗?

不,一点也不。如前所述,该课程针对一系列的经验水平。唯一高的期望是他们期望学生在课外投入的时间。这些作业“psets”可能需要 20 个小时,因此在进行大学课程的其他模块的同时实时管理将是一个具有挑战性的工作量。然而,由于这是一门在线课程,你可以按照自己的进度来完成。

课程内容

在哈佛,这门课程被分成几周教授。当你在网上做的时候,你可以想花多长时间就花多长时间,每周完成。

  • 第 0 周:二进制,什么是算法,Scratch。备注pset0
  • 第一周:编译,C intro (if 语句,针对& while 循环,函数,数据类型),库。备注pset1
  • 第二周:搜索和排序算法,大 O 符号(算法运行的时间)。备注pset2
  • 第三周:指针,内存分配,十六进制注释pset3
  • 第四周: C 结构,链表,哈希表,树,尝试,递归。音符pset4
  • 第五周: HTML,CSS,Javascript,TCP/IP。备注pset5
  • 第六周: Python。注释pset 6(python 中之前 pset 的重做)。
  • 第 7 周:运行网站服务器,Flask,Jinja 模板。备注pset7
  • 第 8 周:cookie 和网站会话、SQL 和数据库。注意事项pset8
  • 第 9 周:没有讲座或 pset。
  • 第 10 周:回顾之前的讲座。不同技术的“研讨会”讲座为期末项目提供思路。最终项目规格

工作量

你可以预期花 10 到 20 个小时完成每堂课和 pset。哈佛对自己学生的调查显示,他们平均每份 pset 作业花费大约 10 个小时。最重要的是,讲座每周大约 2 小时,最后还要完成一个项目。因此,预计整个课程需要 100 到 200 个小时是合理的,这取决于你开始时的技能水平。

Harvard’s survery of students time spent on psets

我的个人经历

我真的很喜欢这门课的前几周,第一周到第四周,当你在 c 语言中工作的时候,研究指针、链表和其他数据结构是多么有趣,这也正是我想在这门课中学到的东西。在第 4 周之后,我更熟悉的主题被引入(HTML、Python 和 Javascript 等),所以我从后面的几周学到的东西较少。也就是说,我仍然喜欢它们。

如果你想比较你的代码和我提交的代码,看看我的方法,这里有一个到 Github 的链接。它们可能离最佳解决方案还很远,但我发现看到其他人解决同样问题的方法是一种有用的学习方式。

花费的时间

总的来说,这门课程花了我 133 个小时,历时 19 周才完成。在那段时间里,我花了 7 周 73 个小时听课和做 psets,然后花了 12 周 60 个小时做期末项目。

注意:第 9 周没有讲座或 pset,第 10 周因为有期末专题所以花了很长时间。

最终项目— 股市游戏化

我有一个我想获得经验的技术列表:Docker 容器、使用 AWS、MongoDB、运行服务器和使用 API。所以我想出了构建 pset8 的主意,包括获取股票市场价格和使用 Flask 服务器,并制作一个游戏,我可以在容器中运行并部署在 AWS 上。为了制作一个基于网络的游戏,我使用了 Phaser 3 Javascript 库(对我来说也是新的)。

对于一个项目来说,这可能是太多的新事物了,我发现一开始真的很难开始。在不到 2 个月的时间里完成了几乎所有的 CS50 之后,仅仅这个项目就花了我将近 3 个月的时间!

我很高兴我坚持了下来,因为游戏确实有效!你扮演一个太空人,他必须跳上纳斯达克 100 股票清单上的公司标志。这些标志随着 IEX API 中的实际股市数据而变化。

Play the game here

这里是代码的 Github 的链接。它运行在一个 Flask 服务器上,我把它放在一个运行 Alpine Linux 的容器中。然后,我在 AWS 上使用 ECS(弹性容器服务)来托管该容器,并使其可以在线访问。高分保存在 MongoDB Atlas 集群中。

在 AWS 上使用 ECS 被证明是昂贵的;大约 30 美元/月,即使我的流量很小。所以我后来改用 Heroku 上的免费层。

结论

如果你已经做过一些编程,并且想要更深入地了解计算机如何工作,以及你写的代码实际上使计算机做什么,这是一个很好的起点。这门课程值得它所得到的赞扬。我从中学到了很多,真的很喜欢!

全球暴力下降了吗?看一看数据

原文:https://towardsdatascience.com/has-global-violence-declined-a-look-at-the-data-5af708f47fba?source=collection_archive---------1-----------------------

(Source)

我们真的生活在人类历史上最和平的时代吗?这完全取决于你如何衡量:现实项目第 2 集

在他 2011 年的巨著《我们本性中的善良天使:为什么暴力减少了》中,史蒂芬·平克大胆地宣称,“今天,我们可能生活在人类历史上最和平的时代。“对于一个对当地和国际上不断的暴力新闻报道稍加关注的人来说,这种说法听起来很可笑。这个断言的宏伟应该立即引起我们的怀疑;正如科学普及者卡尔·萨根经常说的,“非凡的主张需要非凡的证据。“平克有证据吗?他的解释正确吗?

在长达 800 页的篇幅中,平克用数字、图表以及对许多书籍和文章的引用进行了令人信服的论证。尽管如此,重要的是我们不能依赖单一的论点来形成我们的世界观。我们必须记住,数据从来都不是客观的,因此我们需要查看数据本身以及多个专家的解释。在本文中,我们将考察全球暴力冲突数据以及对相同数字的不同立场。(值得注意的是,平克的作品涉及从个人到世界范围的各种形式的暴力——杀人、虐待,但这里我们将重点关注国际暴力冲突——战争——并将其他内容留给未来的文章)。

这是“现实项目”的第二集,这个项目的目标是减少对数据世界的误解。你可以在这里找到所有的文章

(我想强调的是,我并不是试图通过只提供数据来最小化战争的暴行。当看数字时,我们很容易忘记我们正在谈论的是人,每一个人的生命损失都是一场悲剧。)

数据

我们更积极方面的衍生数据的主要来源将是 《我们本性中更好的天使》史蒂芬·平克《我们的世界》数据中的“战争与和平”页面。为了对比观点,我们将使用约翰·格雷的“史蒂芬·平克是错误的”冲突的减少:数据到底说了什么?帕斯卡·西里洛和纳西姆·尼古拉斯·塔勒布。你可以在冲突目录或世界银行找到你自己分析的原始数据。

评估今天的暴力,我们需要问的第一个问题是过去有多暴力。虽然很难获得极其可靠的数据,但人类学家利用考古证据来确定死亡原因,从而估算出一个社会的暴力发生率。这些结果显示在以下图表中,这些图表显示了史前和非国家社会中暴力冲突造成的死亡百分比(来自《我们的世界》的数据)。

Percentage of deaths attributed to violence in prehistoric and nonstate societies

在史前和非国家社会中,死于暴力的人的百分比从大约 60%到不到 5%不等。这些数字几乎毫无意义,除非我们将它们与现代数字相比较:

Percentage of deaths attributed to violence in state societies

最相关的条目是最后两个。1900—1960 年间,美国和欧洲即使经历了两次世界大战,也只有不到 1%的人口死于武装冲突。2007 年,世界上只有 0.04%的死亡是由国际暴力造成的。如果这个数据是正确的,2007 年的世界至少比大多数史前社会安全一个数量级。

我们也可以用稍微不同的方式来看同样的数据,比如每年每 10 万公民中的暴力死亡人数。

Left: violent deaths per 100,000 citizens per year in non-state societies. Right: same data for state societies.

在这里,我们又一次看到了同样的现代低暴力模式。左边是非国家社会,右边是国家社会。关注右边表格的底部 3 行,我们可以看到现代社会中暴力致死率非常低,即使算上两次世界大战。再次强调,这里的数据并不完整,但现有的数据表明了以下假设:史前和非国家社会经历了比现代国家社会高得多的暴力率。

正如平克和其他人(特别是贾雷德·戴蒙德)已经明确指出的,“高贵的野蛮人”的想法是完全错误的。当人们被组织成部落,然后随着他们被文明化而变得更加暴力时,他们并没有和平地彼此生活,而是相反:他们在部落中极其暴力,随着更大的文明的建立和商业开始连接世界,他们逐渐变得不那么暴力了(这突出了全球战争衰退的两个驱动因素——贸易和强大的国家——我们很快就会看到)。即使算上民族国家在 20 世纪犯下的暴行,暴力死亡率现在似乎也比以往任何时候都低。

值得研究一下我们拥有最佳数据的时期:现代。特别是,我们将放大 1945 年后的时代,一个被平克归类为“长期和平”的时代。从这个有利的角度来看,事情看起来很好。正如平克所指出的,自 1953 年以来,世界大国之间没有任何冲突(二战以来的例外是朝鲜战争),自 1945 年以来,也没有任何国际公认的国家因被征服而不复存在。

当我们查看基于国家的冲突中每 10 万人的战斗死亡数据时,我们看到自第二次世界大战以来显著下降。

State-based violent conflict deaths from World War Two on

自第二次世界大战结束以来,所有冲突的死亡率都有所下降,国家间冲突的下降最为明显。大多数剩余的战斗死亡发生在内战中,如自 2011 年以来一直持续的叙利亚内战。此外,这些内战中有许多涉及外国,可以说主要国家已经停止了直接的相互战斗,而是通过其他冲突进行参与。

与上图形成对比的一个令人沮丧的消息是自第二次世界大战以来国家间冲突的总数:

Number of state-based conflicts since the end of World War Two

虽然与战斗相关的死亡人数(以死亡人数/100 000 人/年计算)有所下降,但冲突总数却在上升。这告诉我们,与我们可能认为的武器技术进步相反,暴力冲突正在导致更少的战斗死亡。虽然全球各地的国内冲突越来越多,但其灾难性往往不如大国之间的战争。

幸运的是,大国之间的战争一直在减少——甚至包括整个 20 世纪——而且没有逆转的迹象。我们可以在最后一张图表中看到这一点,该图表显示了过去 500 年中主要大国处于战争状态的时间百分比(以 25 年为一组)。

Percent of Years in which Great Powers Fought One Another (bunched into 25-year periods).

至少自 1600 年以来,主要大国相互交战的年数比例明显下降。这一比率一度达到 100%——表明在整个 25 年期间,世界强国之间至少发生过一次冲突。相比之下,2000 年世界强国之间没有冲突。目前,至少自罗马帝国以来,66 年没有大国冲突的时间是最长的。

在对迄今为止的数据进行研究后,平克的论点似乎站得住脚:即使算上世界大战,现代国家社会在战争中的死亡率也远低于史前和非国家社会。此外,主要大国不再相互争斗,尽管国内冲突的数量有所增加,但这些冲突造成的死亡人数少于主要国家之间的冲突。然而,在我们认为这个案子已经结束之前,我们需要谈谈一个基本问题。

关键问题:相对还是绝对

考虑以下两种情况:

  1. 两个男人独自在酒吧里。在短暂的争执后,其中一人拔出手枪,杀死了另一人。总死亡人数为 1 人,死亡率为 50%。
  2. 一场小规模的内战在一个拥有 100 万人口的国家持续了几个月。总死亡人数是 10,000 人,死亡率为 1%。

哪个更糟?问题取决于你的观察点。在地面上,从冲突本身的地点来看,酒吧要糟糕得多。酒吧里的人有 1/2 的几率被杀。从局外人的角度来看,这场内战要糟糕得多,死亡人数是它的 10 倍。这是平克的批评者提出的一个中心论点:用比率来衡量暴力忽略了绝对数字,这意味着它不能解释人类遭受的实际痛苦。

平克最严厉的批评者之一,纳西姆·塔勒布在他的回应中提出了单位的观点。他用下面一对图来说明这一点:

War casualties using raw data left and rescaled data right

左边的图表显示了主要冲突的原始伤亡人数与时间的关系。右边的图表显示了重新调整后的版本,在该版本中,人口一直被标准化为具有相同的基础人口。例如,如果一个人口为 100 的社会有 2 人死亡,而一个人口为 1000 的社会有 10 人死亡,我们将乘以 2 * 10 得到 20 人死亡,以说明人口差异。

这些数字概括了比率/绝对数字的论点:暴力冲突中的死亡率明显下降,处于历史低点,但实际死亡人数随着时间的推移而增加。尽管如此,值得指出的是实际数字自 1950 年以来一直在下降。

关于这个相对/绝对的问题,不知道有没有答案给你。作为一个功利主义者,我相信要给最多的人带来最多的整体利益,因此,我认为人类死亡的总数是我们文明失败的标志。另一方面,今天活着的人在暴力冲突中丧生的概率比过去任何时候都要低,这无疑是一种进步。我会让事实真相大白,让你自己决定。

即使我们不想对整体结果作出判断,也值得看一看暴力发生率下降的潜在原因。特别是,我们可能要思考为什么自 1945 年以来死亡总人数(除了相对数据之外)下降了。

暴力减少的驱动因素

在这一部分,我们将看看史蒂芬·平克在中概述的观点,我们本性中更好的天使。(这项工作是对暴力下降的潜在原因的最佳审视——部分原因是其他人拒绝承认这一点)。平克解释了五种力量,旨在解释所有规模的暴力下降,而不仅仅是基于国家的冲突,但我们将重点关注与国际冲突最相关的前两种。

暴力减少背后的五大历史力量是:

  1. 民族国家:由中央政府统治的社会的崛起,特别是民主国家,拥有“合法使用武力的垄断权”
  2. 商业:国家间的贸易让我们能够参与正和互动,这意味着我们的邻居活着比死了更有价值
  3. 女性化:妇女在社会中的作用和权力地位提高
  4. 理性:在制定政策和与他人互动时,越来越依赖逻辑思维,而不是传统
  5. 大众媒体和交流:让人们不再视外人为危险分子,而是具有共同人性的人

民族国家,或称利维坦

一个强大的中央政府可以使用暴力制定和执行法律,这意味着公民不太可能自行决定惩罚,这一概念被称为 Leviathon 理论。尽管有其浪漫的吸引力,私刑只会导致无休止的复仇暴力循环。当公民可以指望政府给予公平的惩罚时,他们会让司法系统来执行规则。此外,一个国家可以通过使惩罚远远大于任何潜在的回报来防止犯罪。人类既有邪恶的潜力,也有善良的潜力,一个强大的中央政府,一个公平的刑事司法系统,可以引导他们走上正确的道路。

然而,仅仅一个强大的政府不足以维持国家间的和平。在国际范围内,证据表明民主国家不会互相争斗,可能是因为它们有共同的理想。从一些数据来看,很明显,民主国家不再直接互相争斗(尽管它们可能会参与代理战争)。

Conflicts between different forms of government (source)

(关于这一概念的更多内容,参见《民主和平论》。))

一个民主国家不会与另一个民主国家作战的想法是一个好消息,因为从长远来看,民主国家在世界范围内正在崛起,正如平克所显示的那样:

Types of government since the 1940s

(一个相反的例子是最近民主指数的下降,该指数不仅衡量政府,也衡量新闻自由和投票权。虽然长期趋势是积极的,但最近的下降令人担忧。)

温和的商业

温和商业的理论可以总结为两种说法:

  1. 当买东西比偷东西便宜时,经济学就赢了
  2. 我们的邻国——无论是国内还是国外——活着比死去对我们更有价值,因为交换是正和的

你为什么不从杂货店偷一条面包?虽然大多数人认为他们不会偷窃,因为这是错误的行为,但真正的原因更为平凡:在我们的社会中,被抓到偷窃的潜在成本——坐牢和社会排斥——高于购买物品的成本。当人们有比暴力更便宜的合法途径来获得他们的商品时,他们会选择合法途径。

我们在《消失的穷人》中探讨了第二点,但值得重申一下。在市场经济中,如果没有交换,人类之间的所有互动都是零和游戏:你可以从我这里偷走一些东西,但你的收获被我的损失抵消了,所以人类并没有变得更好;经济规模保持不变。然而,在商品交换中,双方都有更好的收益。

交换也允许专业化,因此不同的个人/国家可以制造他们最适合的商品。此外,随着贸易的继续,各国变得相互依赖,因为它们不再生产所需的所有商品。交换的最终结果是为各方提供更多更便宜的商品,并改善国际关系

在过去的几百年里,我们已经慢慢地建立了一个国际市场,在这个市场中,所有的参与者都相互依赖。美国不会与另一个大国开战,不是因为她无法击败他们,而是因为经济损失将远远超过收益。正如平克所讨论的,在贸易上更加依赖彼此的国家不太可能因为其他因素而发生暴力冲突。总之,对大多数国家来说,财政刺激已经从战争转向贸易。

Leviathon 和 gentle commerce 实际上是一起工作的——一个强大的政府能够创造允许安全交易的市场,并执行监管贸易的法律。换句话说,一旦你有了一个强大的国家,贸易就更容易了,国家之间更多的贸易意味着他们不太可能互相攻击。随着世界大国之间的贸易增加,自 1953 年以来,大国之间的冲突也减少到零。

World trade as a percentage of GDP

毫无疑问,还有其他因素在国家间战争的减少中发挥了作用。我们讨论了下降背后的外部历史因素,但平克和其他人(约翰·霍根在战争的结束 ) 也概述了内部因素,如我们本性中更好的天使:移情、自我控制、道德、理性。

通过检查数据和原因,很明显,主要大国不再认为战争是一个可行的选择。这不一定是因为它们是道德的,而是因为战争经济学不再有意义。归根结底,人类和国家都受到激励的驱使,通过国际贸易,我们建立了一个激励有利于和平的世界。

警告和结论

从狭隘的角度来看,平克是正确的:暴力冲突的比率已经大幅下降,有理由相信它们处于人类历史的最低点(如果仅仅是因为数据有限的话)。此外,至少在现代民主国家中,暴力不再被视为解决问题的默认选项,而几乎在整个人类历史上都是如此。也就是说,有必要思考一下平克的观点是如何误导人的。

第一点是,通过关注比率而不是数字,我们忽视了人类的实际痛苦。死于战争的人越来越多,即使这个比例在下降。根据一个人的论点,这些数字可以用来支持多个结论。

第二个中心问题是,特别是对于史前社会,可靠的数据很难获得。史前社会的大部分冲突率和死亡数字来自于对考古遗址的考察和对暴力死亡证据的人工制品的观察。然而,这些标记可能被误解了,人类学家不可能研究所有的史前社会。简单的推断已经发现的是唯一的选择,但是不得出不成熟的结论也很重要。

我们将在这里讨论的最后一个主要问题是,我们可能生活在一个异常的时代。平克将最近 70 年的和平(现代国家之间没有战争)称为“长期和平”,但这可能真的只是暂时的和平。此外,正如塔勒布所指出的,战争往往是幂律分布的,即它们有向右倾斜的长尾巴。武装冲突中的绝大多数死亡是由少数冲突造成的,如下所示:

Distribution of war casualty deaths on log scale

就死亡人数而言,一场冲突可能完全超过所有其他冲突。自 1945 年以来,大多数武装冲突都处于较低水平,但只需一场重大战斗就能掩盖自 1945 年以来的和平。由全球变暖、资源短缺或领土争端引起的新冲突可能会完全抵消人类在减少暴力方面取得的千年进展。

最初,看了平克的书,我被他的论文说服了。然而,在我自己花时间挖掘事实之后,一个更加微妙的画面出现了,一个双方都没有理由发生耸人听闻的冲突的画面。我看到了乐观的理由:武装冲突中死亡率的下降意味着今天活着的人在战斗中死亡的可能性低于有记录的历史,自 1953 年以来大国之间没有战争,自 20 世纪 50 年代以来总体战斗死亡人数减少,以及悲观的理由:民主和国际贸易对减少重大冲突如此重要,但近年来似乎在下降。此外,尽管主要大国之间不再直接交战,但它们通过代理人战争参与进来。

Things could be much worse, but they could also be better.

对暴力冲突的探索凸显了现实项目的目标。它不是为了让我感觉良好而设计的,而是基于事实的努力,因此,每当我遇到吸引我的论点时,这只会告诉我要更加怀疑。除了获取我们世界背后的实际统计数据之外,现实项目并不忠于任何单一的利益。当事实让我们乐观时,这很好,但即使事实并非如此,理解数据也是至关重要的,这样我们才能努力改善事情。

一如既往,我欢迎反馈和建设性的批评。可以通过 Twitter @koehrsen_will 找到我。

哈希表解释

原文:https://towardsdatascience.com/hash-tables-explained-5dc457db50da?source=collection_archive---------10-----------------------

哈希表及其冲突的内幕

I 简介

当给定由与其他信息片段相关的信息片段定义的大型数据集时,我们有哪些方法可以有效地存储和检索信息?为了管理大量的关系数据,我们需要有能够快速操作它(即插入、删除和搜索)的数据结构。假设我们有与“值”数据相对应的“键”数据,那么,关联两条信息的一种方法是使用由键/值关系组成的字典。实现字典有几种不同的方法,包括使用平衡二分搜索法树和双向链表。在本文中,我们将讨论使用哈希表,这是目前为止三种字典实现中最快的方法,并且可以比其他两种字典实现更有效地执行插入、删除和搜索操作。

哈希函数的动机是什么?

首先,我将解释为什么我们需要一种不同于最简单的关联信息的解决方案,即直接地址表。这个幼稚的解决方案基本上是一个大小为 m 的数组,其中键的数量小于 m ,每个数组索引的地址都对应于这个键,这个键要么保存值,要么保存指向值的指针。示例:我们可以将与键 k 相关联的值存储在第槽中。没有相应关键字的地址简单地称为:nil。参见下面由直接地址表(T)定义的键和值之间的关系。

How a Direct Address Table works

在这种情况下,插入、删除和搜索都是 O(1 ),因为您可以通过地址直接找到键,并访问值。然而,限制这种数据结构用于存储关系信息的两个假设是:

  1. 数组的大小, m ,不算太大。
  2. 没有两个元素具有相同的键。

第一个是一个问题,因为我们不希望数组因为没有元素而占用太多空间。第二个也是一个问题,因为它限制了我们可以使用的键的类型。

因此,我们使用散列函数。

什么是哈希函数?

散列函数 h(k) 是将所有键映射到数组的槽的函数。另一种思考方式是:给定一个键和一个数组,哈希函数可以建议键的索引应该存储在数组中的什么位置。

散列函数是如何工作的?

可以为哈希表实现几种哈希函数,但最流行的是除法,其中对于 m 的某个值,h(k)=kmodm。其他哈希函数包括:乘法和折叠方法。

什么是哈希冲突,如何解决哈希冲突?

所以这一切都很好。但是当一个键被散列到与另一个键相同的数组槽中时会发生什么呢?啊哈!这就是所谓的哈希冲突。处理哈希冲突有几种不同的方法,最流行的两种方法是开放式寻址和封闭式寻址。

开放式寻址是指您将一个项目放置在某个位置,而不是其计算的位置。我们通过计算的方式来实现这一点,例如线性探测,其中使用线性搜索来查找可用的位置,并且查找项目也涉及线性搜索。

How the Linear Probe works as an example of open addressing

下面是哈希表中线性探测的代码片段:

**class** **HashEntry**:
    **def** **__init__**(self, key, value):
        self**.**key **=** key
        self**.**value **=** value
        self**.**next **=** None**class** **HashTable**:
    **def** **__init__**(self, size):
        self**.**size **=** size
        self**.**keys **=** [None] ***** self**.**size
        self**.**values **=** [None] ***** self**.**size

    **def** **hash_function**(self, key):
        **return** hash(key) **%** self**.**size

    **def** **get_slot**(self, key):
        slot **=** self**.**hash_function(key)
        **while** self**.**keys[slot] **and** self**.**keys[slot] **!=** key:
            slot **=** self**.**hash_function(slot **+** 1)
        **return** slot

    **def** **set**(self, key, value):
        slot **=** self**.**get_slot(key)
        self**.**keys[slot] **=** key
        self**.**values[slot] **=** value

    **def** **get**(self, key):
        **return** self**.**values[self**.**get_slot(key)]

另一种开放式寻址的方式是使用二次探测,当决定下一步离最初的碰撞点有多远时,我们将挫败的尝试次数平方。每当另一个挫败的尝试被做,距离最初的碰撞点的距离迅速增长。

封闭寻址本质上是使用链表将具有相同哈希值的键链接在一起。该方法的查找与在链表中搜索是一样的。

Chaining uses Linked Lists to resolve hash collisions

下面是哈希表中链接的代码片段:

**class** **HashEntry**:
    **def** **__init__**(self, key, value):
        self**.**key **=** key
        self**.**value **=** value
        self**.**next **=** None**class** **HashTable**:
    **def** **__init__**(self, size):
        self**.**size **=** size
        self**.**table **=** [None] ***** self**.**size **def** **hashing_function**(self, key):
        **return** hash(key) **%** self**.**size **def** **rehash**(self, entry, key, value):
        **while** entry **and** entry**.**key **!=** key:
            prev, entry **=** entry, entry**.**next
        **if** entry:
            entry**.**value **=** value
        **else**:
            prev**.**next **=** HashEntry(key, value) **def** **set**(self, key, value):
        slot **=** self**.**hashing_function(key)
        entry **=** self**.**table[slot]
        **if** **not** entry:
            self**.**table[slot] **=** HashEntry(key, value)
        **else**:
            self**.**rehash(entry, key, value)

    **def** **get**(self, key):
        hash **=** self**.**hashing_function(key)
        **if** **not** self**.**table[hash]: **raise** KeyError
        **else**:
            entry **=** self**.**table[hash]
            **while** entry **and** entry**.**key **!=** key: entry **=** entry**.**next
            **return** entry**.**value

暂时就这样吧!我希望这个关于散列表和它们的冲突的信息已经启发了你去学习更多关于它们的知识。

资源和引用

哈希表和哈希函数:https://www.youtube.com/watch?v=KyUTuwz_b7Q

麻省理工学院开放式课程:https://www.youtube.com/watch?v=0M_kIqhwbFo

斯坦福 CS 161 哈希注意事项:https://web . Stanford . edu/class/archive/CS/CS 161/CS 161.1168/lecture 9 . pdf

编码备忘单:https://www . alispit . tel/coding-Cheat-Sheets/data _ structures/hash _ tables . html

哈希幂概率数据结构

原文:https://towardsdatascience.com/hashes-power-probabilistic-data-structures-d1398d1335c6?source=collection_archive---------24-----------------------

Photo by Ryan Thomas Ang on Unsplash

散列函数在计算机科学中被广泛使用,但我想提一下它们在概率数据结构和算法中的用途。我们都知道数据结构是大多数算法的构建模块。一个糟糕的选择可能会导致艰难而低效的解决方案,而不是优雅而高效的解决方案。

正如 Linus Torvalds 曾经在谈论 Git 时所说的:

…事实上,我是围绕数据设计代码的强烈支持者,而不是 T2,我认为这是 git 相当成功的原因之一(*)。

此外:

(*)事实上,我会说一个糟糕的程序员和一个好的程序员的区别在于他是否认为他的代码或者他的数据结构
更重要。糟糕的程序员担心代码。优秀的程序员担心数据结构和它们之间的关系。

如果你是一名计算机科学家、工程师或程序员,你会非常清楚不同细节层次的数据结构。和任何一个程序员聊十分钟都可能会听到:链表、树、堆、地图等等。

我与同事和朋友讨论过,根据你的工作内容,掌握这些数据结构有多重要。如果你是一名学者或者在一家公司工作,在那里数量是一个真正的问题,那么你应该掌握它们。

大多数情况下,如果你是用高级语言编程,那么重新发明轮子并自己实现已知的算法就是一种代码味道。大多数框架都内置了这些数据结构,或者有超高效的库,这些库很有可能会大有作为。

从另一个角度来看,大多数人从事软件维护工作,或者资源限制不是真正问题的地方。痴迷于将性能或资源消耗作为数据结构或算法决策的唯一衡量标准是不明智的,尤其是当它们不是那么相关的时候。同样,这取决于您正在解决的问题及其扩展需求。

但是有时资源限制确实是一个问题,在这种情况下,您应该考虑工具箱中的一个重要工具:概率数据结构。它们以相当可观的资源需求来牺牲精度。如果你正在解决一个问题,其中内存空间不受限制,计算不是瓶颈,精确的精度是必须的,那么在使用它们之前你可能会三思。如果不是这样,你应该知道他们的存在。另外,学习它们很有趣。

有许多书籍、论文和文章都在谈论这个话题。在这里,我将谈论其中两个我认为非常漂亮并且在现实世界问题中大量使用的方法。我将使用一些数学,但不是非常详细,因为网上有很多优秀的资源。即使你不懂数学,你也会得到它们的基本概念(这是这里的目标)。

布隆过滤器

如果我的记忆正确的话, Bloom filters 是我几年前在阅读一些 petascale 数据库时听说的第一个概率数据结构。与许多其他概率数据结构一样,考虑到它们需要的空间和计算是如此之少,您会对它们的有效性感到非常惊讶。

假设你有一大组整数 S ,你想检查 S 是否包含一个元素 i 。你可以简单地使用一个带有空间/时间的链表来解决这个问题。还有,试试用O(n)/O(log(n))的平衡二叉树。或者很明显,一个有 O(n) / O(1) 的地图。

似乎大多数选项都需要与 S 的基数成线性关系的内存空间,考虑到如果我们不存储 S,的每个元素的值,我们怎么能检查一个元素是否存在于 S 中呢?。

布隆过滤器的思想是将整个集合 S 编码成一个固定长度的二进制串,我们称之为 Q 。这是通过将 S 中的每个元素编码到 Q 中来实现的。正如您可以想象的那样,将一个可变大小的域映射到一个固定大小的域最终会导致冲突。

让我们来看一个布隆过滤器的典型例子。假设我们将 Q 定义为固定长度 64 位的二进制字符串。此外,我们选择 k 不同的散列函数,如 MD5 或 SHA-1。接下来,我们执行以下操作:

  • S 中的第一个元素
  • 使用 k 哈希函数对元素进行哈希运算,并将它们取模 64,以生成 Q. 中的 k 索引
  • 在之前计算的索引处,将 Q 中的每一位设置为 1
  • S 中的每个剩余元素执行前两个步骤

当我们完成时,我们有一个 64 位的值 Q ,其中一些位被设置为 1,其他的被设置为 0。

现在我们要检查一个元素是否在 S 中。我们做与上面完全相同的程序来检查在 Q 中哪些位应该被置位。如果任何相应的 k置位,我们可以确定该元素不在 S 中。如果它们都被设置,我们可以说元素是可能是 Q 中的,因为这些位也可以被许多元素部分地设置为 1。事实上,当您在 S 中不断添加元素时,越来越多的位在 Q 中被设置为 1,因此您不断增加这种可能性。

布隆过滤器会产生假阳性,但不会产生假阴性。

如果我们增加 Q 的大小,我们就避免了冲突,从而避免了误报的可能性。k 值也在碰撞概率中起作用。这是在大小(Q)k假阳性率之间的权衡。如果你对量化误报率的数学感兴趣,你可以在这里阅读。同样,你可以在这里看到最佳尺寸(Q)k 考虑 #S 或期望的假阳性率。

还有一个更重要的考虑:选择散列函数来生成 Q 中的索引。之前,我提到了 MD5 或 SHA-1,但这些都不是明智的选择。加密哈希函数试图生成不可逆转的输出。这不是我们关心的问题。我们对随机输出感兴趣,并尽可能快地进行计算,因此有更好的选择。

大多数实现使用单个散列函数来生成所需的输出。特别是 MurmurHash 函数,其中计算出 MurmurHash 输出的某个恒定基集,然后通过组合这些基哈希生成 k 输出。你可以在这里看到一个流行的布隆过滤器在 Go 中的实现。

还有另一种概率数据结构称为 计数最小草图 ,它估计集合中每个项目的频率。这个想法与布鲁姆滤镜的工作原理非常相似,所以你可能有兴趣看一看。

如果你对以太坊感兴趣,布隆过滤器被用来检查一个块是否包含与某些主题相关的 日志 。在以太坊中,主题与事件索引参数相关。一个不存储任何关于世界状态交易收据的数据的轻型客户端,可以非常快速地检查一个块是否包含与任何感兴趣的主题相关的日志。如果 Bloom filter 检查匹配,考虑到误报的小概率,我们可以非常确定这个块包含一个用于查询的主题日志条目。一个假阳性的成本超过了分析所有块的所有交易的所有收据的永久成本。

超对数

HyperLogLog 是对以前的想法的改进,如 LogLog线性计数,它们关注的是计数不同问题。

假设你想知道一个大集合 S 的基数,即:S 中有多少不同的元素。我们也想在 O(1)空间中这样做。引用提出该想法的原始论文:

例如,新的算法使得有可能在仅使用 1.5 千字节的存储器的情况下,以 2 %的典型精度来估计远超过 10 ⁹的基数。

这种数据结构中的形式数学比Bloom filters的情况更复杂,但背后的主要思想相当简单。

假设您有 8000 个随机生成的二进制字符串。我们预计其中有多少至少有 3 个前导零?嗯,至少有 3 个前导零的概率是 1/8,因此,我们可以估计大约有 1000 个前导零。当然,由于这是一个随机过程,我们可以看到从 0 到 8000 的二进制字符串满足这个属性,但每个情况的概率很重要。更一般地说,如果我们正好有 n 个前导零,那么基数为 2^n.似乎是合理的。这与将一枚硬币抛 100 次,我们大致会看到 50 个正面和 50 个反面是一样的。

当你深入细节时,你很快就会意识到差异是一个问题。这是一个很大的问题,因为每一个误差单位都会对估计产生指数影响。换句话说,如果我们碰巧有 K+1 个前导零,而不是 K 个前导零,那么我们的估计将会加倍。用于改进这一方面的思想是将集合分成多个子集,并使用在每个子集中找到的最大前导零的平均值。

从双对数到超双对数的一个演变是改变估计的均值类型,以控制对异常值的敏感性。特别是,对数对数使用的是算术平均值,而超对数使用的是调和平均值。此外,应用偏差校正系数来校正甚至更多的剩余偏差。

通过将集合分成多个集合来重复这个实验是很棒的,但是它产生了另一个问题:如果集合的基数太小,那么我们将没有足够的数据来进行统计。这可以通过简单地识别案例并使用在这种情况下更有效的其他技术来解决。

像在 Bloom filters 中一样,每个子集中的每个元素都被散列以将其转换成固定长度的二进制字符串,从中我们可以遵循上面的逻辑。同样,杂音散列函数在实现中被广泛使用。

结果

我们可以理解,在所有这些情况下,散列函数都扮演着重要的角色。优雅地说,它们提供了许多对概率数据结构和算法非常有用的特征:

  • 它们将非均匀分布的数据转换成均匀分布的数据,这为概率假设提供了一个起点。
  • 数据的通用身份,如果我们将操作设计为等幂,这将导致自动重复数据删除,有助于解决计数不同等问题。

利用散列不可逆性不是一个要求的事实,非加密散列函数是一个可以更快帮助算法速度的选项。

有不平衡的阶层?尝试重要术语

原文:https://towardsdatascience.com/have-unbalanced-classes-try-significant-terms-1f449236d3f4?source=collection_archive---------30-----------------------

对一个类别有意义的词可以用来改善分类中的精确-召回折衷。使用最重要的术语作为词汇来驱动分类器,可以使用更小的模型来预测出院记录中的 MIMIC-III CCU 再入院,从而改善结果…

而且更难(抱歉瑜伽熊!)当要预测的目标类具有广泛变化的支持时。

但这种情况在真实世界的数据集上确实经常发生。一个恰当的例子是根据出院记录对一个病人近期 CCU 再入院的预测。只有一小部分患者在出院后 30 天内再次入住 CCU。我们对之前帖子中的 MIMIC-III 数据集的分析显示,超过 93%的患者不需要再次入院。这绝对是个好消息。但如果你从事预测行业,你会遇到一个更难的问题。您希望从大量不会经历再入院的病例中尽可能多地识别出那些为数不多的未来实际再入院病例。当然,你要避免错误地将病例标记为将来的再入院。

我们所面临的是一个经典的精确与召回的问题,我们在信息检索行业都很熟悉。

  • 忽略精度,实现 100%召回。只需将所有笔记标记为未来重新接收。 FN = 0
  • 忽略召回,实现 100%的准确率。只需将所有笔记标记为未来不再接收。 FP = 0

1.重要术语

兼顾精确度和召回率是一个挑战,这也是重要术语能有所帮助的地方。在之前的文章中,我们回顾了重要术语的背景,它们是什么,以及如何使用 Elasticsearch 从文本语料库中提取它们。那篇文章的要点如下。

  1. 出院笔记中最常见的术语显示出很少的差异,无论该笔记是否经历了再入院
  2. 出院记录中罕见术语的长尾受到错别字的困扰,这两个类别之间几乎没有区分能力
  3. 对每一类都有意义的术语明显不同,这潜在地为我们的分类任务提供了一个挂钩

因此,我们从上面的第三项开始,看看我们可以用哪些不同的方式来使用分类任务中的重要术语。首先,让我们从 MIMIC-III 数据集定义我们的训练和测试数据。

MIMIC-III 数据

在前一篇文章中,我们浏览了 MIMIC-III 数据集,并准备了一个弹性搜索索引。

每份文件都是出院记录,标签为再入院,为 0(本次出院后 30 天内未再入院)或 1(患者在本次出院后 30 天内再入院至 CCU)。我们有 40873 个 readmit=0 的文档和 2892 个 read MIT = 1的文档。这使得对少数类 readmit = 1 的正确预测变得更加困难。我们将数据分为训练集和测试集,同时根据重新提交标志进行分层。

train_docs, test_docs, train_labels, test_labels, train_ids, test_ids = train_test_split (docs, labels, ids, test_size=0.20, random_state=0, stratify=labels)

我们最终得到了以下用于训练和测试的分布。在训练集或测试集中,只有大约 6.6%的文档具有 readmit=1 。我们使用训练集建立模型,并预测我们在少数民族重新接纳类中的表现。

# Of Train / Test : 35012 / 8753
# Of Train Readmit / NoReadmit: 32698 / 2314
# Of Test Readmit / NoReadmit: 8175 / 578

虽然有偏差,但我们使用整个训练集来构建模型。用 SMOTE 对多数 no recent 类进行二次采样或对少数 readmit 类进行过采样都有其自身的问题,我们希望避开这些问题。然而,我们稍后会尝试在分类的背景下对少数民族类别的预测赋予更高的权重,例如使用逻辑回归……

下面的代码片段为每个类提供了训练集的 id,并使用 Elasticsearch 获得了重要的术语。

上面使用了卡方方法,但也有替代方法。最终结果是每个类的一组单词,其权重表示单词对该类的重要性。

2.具有重要术语的直接分类

有了重要的术语,我们就可以简单地根据这些术语的存在来对卸货单进行评分。我们得到了一个类的重要术语的总数,这些术语出现在一个测试放电记录中。这是这个音符和班级的分数,我们把这个音符放在分数最高的班级。我们可以进一步归一化(线性或 softmax)每个音符标签上的分数,并将其视为概率。这将有助于计算精确召回和 ROC 曲线下的面积等指标。下面是一段代码

  • 使用重要术语作为词汇表和计数矢量器将测试放电记录转化为矢量
  • 按标签计算每个音符的分数,并出于预测目的对其进行标准化

考虑的重要术语的数量是变化的,以观察其对结果的影响。下面的图 1 显示了预测重新接纳类所获得的精度和召回率( readmit = 1 )。

Figure 1. Predictions (threshold = 0.5) for the minority class in MIMIC-III dataset. The discharge notes are scored by a count of the significant terms they contain by class

这里的要点如下。

  • 当我们考虑越来越多的重要术语时,召回率会增加,精确度会降低。当然有道理。
  • 使用 500-1000 个重要术语获得了接近 99%的总召回率,精确度约为 7% 。在总共 578 例真正的再入院病例中,只有一例出院记录被错误地归类为无再入院病例。
  • 用于提取重要术语的卡方jlh 方法产生相似的结果,其中卡方略微领先。在这篇文章的剩余部分,我们将坚持使用 chi_square。

3.用有意义的术语作为词汇表

当然,我们可以在标记的出院记录上使用任何旧的分类器,如逻辑回归,并建立预测模型。 CountVectorizer 用于建立词汇和文档向量进行分类。你可以尝试使用 TfidfVectorizer ,但是它会把事情搞得一团糟。

基于跨类别的相对计数测量,从语料库中提取重要术语,并且每个术语获得关于其对类别的重要性的分数。Tf-Idf 引入了自己的权重,这些权重是主体范围内的,与职业无关……

在任何情况下,语料库词汇几乎总是相当大。即使我们进行了清理,我们还是从 MIMIC-III 文本语料库中获得了超过 124000 个术语。我们当然可以限制这个数字。在下面的代码片段中,将只考虑所有单词的前 n_features 个,因此文档向量将为 n_features 长。

vectorizer = CountVectorizer(analyzer=lambda x: x, min_df=1, max_features=n_features).fit(train_docs + test_docs)

但是如果我们只使用重要的单词而不是所有的单词呢?仅仅是前 500 名或前 100 名?我们前面已经看到,一个类的重要术语与另一个类的重要术语有很大不同。事实上,对于二进制情况,将会有零重叠。

仅从重新接收类的重要术语构建的文档向量可能足以提供足够的辨别能力……

无论如何,这是一个论题。如果可行的话,我们将拥有一个小得多的模型,并且有望拥有与使用所有词汇的完整长向量所给出的精确度和召回率相当的精确度和召回率。向 CountVectorizer 提供定制词汇表非常简单。我们已经有了按重要性排序的重新接纳类的重要术语列表。列表中数量最多的 n_features 个单词被用作下面代码片段中的词汇表。

vectorizer = CountVectorizer(analyzer=lambda x: x, min_df=1, vocabulary=significant_terms_for_class_readmit_1[0:n_features]).fit(train_docs + test_docs)

使用这两种词汇构建和运行逻辑回归模型都很简单。我们只是为下面的函数提供了一个不同的矢量器。此外,我们确保应用 class_weight ( balanced )以便主要的无重传类与较小的重传类相比具有较低的权重。我们这样做的原因是因为我们处理的整个训练集严重偏向于不重新提交类。通过鼓励分类器更加重视少数类预测,这有助于使类之间的竞争更加公平。

图 2 显示了这些词汇表的召回率和准确率结果,作为所用单词数量的函数。

Figure 2. Predictions (threshold = 0.5) for the minority class in MIMIC-III dataset. Logistic regression (LR) with just 25 significant terms for the readmit class seems to achieve a good compromise between precision and recall.

这当然是一个有趣的图形。

  • 当您限制特征的数量时,CountVectorizer 会选择最高频的单词。正如我们所知,它更倾向于回忆而不是精确。增加使用的单词数量可以提高回忆——在一定程度上!当所有的单词都被使用时,召回率会急剧下降,而准确率会小幅上升。有道理。
  • 当重要术语定义词汇表时,可以获得更均匀和一致的结果。更有趣的是,看起来我们可以将 readmit 类的前 25 个重要单词与 Countvectorizer 和逻辑回归结合使用,以获得更高的精度和召回率。

4.精确召回和 ROC 区域

图 1 和图 2 中对精度和召回率的预测是基于 0.5 的阈值概率。也就是说,当重新提交类的注释的归一化分数(两个标签的总和为 1.0)大于 0.5 时,则该注释的预测为重新提交。当然,在选择这个门槛时有一定的自由度。

  • 如果要确定(精度高!)你做出了正确的决定,那么你希望这个阈值概率很高
  • 如果你不能错过(高召回!)潜在的重新接纳可能性,那么您希望这个阈值概率较低。

再次值得重复的是,早期数据中的预测是基于 0.5 的中性阈值。选择一个足够低的阈值概率,任何分类器都可以获得 99%的召回率。

但是图 1 中使用最重要术语的 99%召回率是在中性阈值为 0.5 的情况下获得的。

评估分类器的一种方法是看它对这个阈值概率有多敏感。这可以通过精确回忆和 ROC 曲线及其包围的区域方便地得到。图 3 显示了使用前 100 个术语(重要术语或语料库词汇)时的精确召回率和 ROC 曲线。

Figure 3. Logistic regression (LR) with significant terms as the vocabulary shows a more advantageous trade-off between precision and recall.

图 4 显示了 precision-recall & ROC 曲线的曲线下面积(AUC ),它是我们在这篇文章中尝试的不同方法所使用的词汇量的函数。

Figure 4. Logistic regression (LR) with significant terms is clearly the leader in dealing with the precision-recall trade off. The ROC AUC is not an effective metric when the classes are unbalanced

使用具有重要词汇的逻辑回归比使用高频词做得更好。它也比简单的基于计数的分类器要好——至少在精确召回方面是这样。

但是我们知道,如果少数类的召回是最重要的,基于计数的方法会更好。这可能是预测类似 CCU 再入院事件的情况。你可以决定是否要召回!

5.结论

为少数阶级做出正确的预测是困难的。以下是这一系列文章的一些松散的结论。

  • 识别对一个班级来说特别/重要的单词在精确回忆舞蹈中是有用的。
  • 这些单词是了解该课程内容本质的窗口。帮助解释为什么一个文档被分类器(可解释的人工智能?)
  • 使用有意义的单词作为词汇表来构建文档向量似乎有望优化精确度和召回率。此外,你只需要几个这样的小模型。
  • Tf-Idf 矢量化结合重要术语,因为词汇表需要进一步分析它到底做什么。

原载于 2019 年 12 月 23 日http://xplordat.com

你在部署之前优化过你的深度学习模型吗?

原文:https://towardsdatascience.com/have-you-optimized-your-deep-learning-model-before-deployment-cdc3aa7f413d?source=collection_archive---------8-----------------------

Source: https://developer.nvidia.com/tensorrt#

使用 NVIDIA TensorRT 在 GPU 上优化和加快推理时间。插图基于人工智能的计算机视觉与 YOLO。

本文组织如下:

  • 介绍
  • 英伟达 TensorRT 是什么?
  • 使用 docker 设置开发环境
  • 计算机视觉应用:YOLOv3 模型的目标检测
  • 参考
  • 结论

介绍

本文介绍了如何使用 NVIDIA TensorRT 来优化您想要部署在边缘设备(移动设备、相机、机器人、汽车等)上的深度学习模型。).比如航空电子公司的智能双光谱相机:潘沙https://pensarsdk.com/

https://pensarsdk.com/

它拥有 NVIDIA Jetson TX2 GPU

https://developer.nvidia.com/embedded/jetson-tx2-developer-kit

为什么我需要一个优化的深度学习模型?

举个例子,想想基于人工智能的计算机视觉应用,它们需要处理摄像机捕捉的每一帧。因此,每一帧向前通过模型的层来计算某一输出(检测、分割、分类……)。

无论你的 GPU 有多强大,我们都希望输出端的每秒帧数(FPS)等于输入端的 1(例如 24,30 FPS…)。这意味着 GPU 正在实时处理每一帧。

对于需要实时决策的计算机视觉应用来说,这种概念更为理想,例如,监控、欺诈检测或活动期间的人群计数等。

部署前优化工作流

数据科学家的任务之一是利用数据并开发/训练/测试神经网络架构。在模型验证之后,通常,架构和模型的参数被导出用于部署。有许多方法可以做到这一点,无论是在云上还是在边缘设备上。在本文中,我们重点关注边缘设备(相机、手机、机器人、汽车……)上的部署。

一般来说,部署的工作流程遵循下图所示的框图:

从导出的、预先训练好的深度学习模型 - > 框架解析器->tensort 优化 - > 对新数据进行推理

英伟达 TensorRT 是什么?

https://docs.nvidia.com/deeplearning/sdk/tensorrt-archived/tensorrt_210/tensorrt-user-guide/

NVIDIA TensorRT 的核心是一个 C++库,它有助于在 NVIDIA 图形处理单元(GPU)上进行高性能推理。TensorRT 采用一个由网络定义和一组训练参数组成的训练网络,并生成一个高度优化的运行时引擎,为该网络执行推理。

您可以使用 C++或 Python API 描述 TensorRT 网络,也可以使用提供的解析器之一导入现有的 Caffe、ONNX 或 TensorFlow 模型。

TensorRT 通过 C++和 Python 提供 API,帮助通过网络定义 API 表达深度学习模型,或通过解析器加载预定义的模型,允许 TensorRT 在 NVIDIA GPU 上优化和运行它们。TensorRT 应用了图形优化、层融合以及其他优化,同时还利用高度优化的内核的多样化集合找到了该模型的最快实现。TensorRT 还提供了一个运行时,您可以使用它在从开普勒一代开始的所有 NVIDIA GPU 上执行这个网络。

TensorRT 还包括在 Tegra X1 中引入的可选高速混合精度功能,并通过 Pascal、Volta 和图灵架构进行了扩展。

在【开发者指南】(https://docs . NVIDIA . com/deep learning/SDK/TensorRT-developer-guide/index . html)中了解如何使用 tensorrt,以及在【TensorRT 论坛】(https://dev talk . NVIDIA . com/default/board/304/tensor rt/)中与 tensor rt 社区互动

使用 docker 设置开发环境

Docker 图像

对于开发,我们使用一个 docker 映像,其中包含一个已安装的 NVIDIA TensorRT 版本。这使得开发环境在不同的操作系统(Windows、Linux、macOS)上更加可靠和可伸缩。

下面是 docker 在应用程序和 GPU 之间的定位图。

注:如果你从未听说过“docker”,那么我强烈建议你投资了解它,你从这里开始:https://docs.docker.com/engine/docker-overview/

安装 Docker-CE

前往 docker 的官方网站,按照步骤安装“docker-ce ”( ce 代表社区版)。

我使用的是 Ubuntu 64 bit,因此,安装链接是:https://docs . docker . com/v 17.09/engine/installation/Linux/docker-ce/Ubuntu/

安装 CUDA

另外,你应该已经安装了最新版本的 CUDA 。它是由 NVIDIA 创建的并行计算平台和应用编程接口模型。它允许软件开发人员和软件工程师使用支持 CUDA 的 GPU 进行通用处理(在https://developer.nvidia.com/cuda-zone了解更多信息)。

要检查 CUDA 是否正确安装在您的机器上,只需在终端中输入

nvidia-smi

输出应该是这样的(我有一个 NVIDIA GPU GeForce GTX 1660 Ti/PCIe/SSE 2)

 Thu Aug 1 10:43:37 2019 
+ — — — — — — — — — — — — — — — — — — —— — — — — — — — — — — -+
| NVIDIA-SMI 430.40 **Driver Version:** 430.40 **CUDA Version:** 10.1 |
| — — — — — — — — — — — — -+ — — — — — — — — + — — — —— — — — +
| GPU Name Persistence-M| Bus-Id Disp.A | Volatile Uncorr. ECC |
| Fan Temp Perf Pwr:Usage/Cap| Memory-Usage | GPU-Util Compute M. |
|=====================+===================+===================|
| 0 GeForce GTX 166… Off | 00000000:01:00.0 Off | N/A |
| N/A 47C P8 4W / N/A | 994MiB / 5944MiB | 8% Default |
+ — — — — —— — — — — — — -+ — — — — — — — — + — — — — — — — — +

运行 docker 映像以使用 NVIDIA TensorRT

我已经创建了一个 docker 映像,其中包括在 Ubuntu 上安装 TensorRT,以及来自 NVIDIA、Python、OpenCV 等的必要先决条件。你可以直接从我在 docker hub 上的个人账户中调出图片。

[## 码头枢纽

欢迎来到我的码头中心

hub.docker.com](https://hub.docker.com/r/aminehy/tensorrt-opencv-python3)

  • 首先,打开一个终端(ctrl+alt + t ),输入这个命令来提取 docker 图像
docker pull aminehy/tensorrt-opencv-python3
  • 通过输入以下命令,启用从 docker 容器内部启动 GUI 应用程序
xhost +
  • 最后,用以下命令运行 docker 容器:
docker run -it — rm -v $(pwd):/workspace — runtime=nvidia -w /workspace -v /tmp/.X11-unix:/tmp/.X11-unix -e DISPLAY=unix$DISPLAY aminehy/tensorrt-opencv-python3:v1.1

计算机视觉应用:用 YOLOv3 进行物体检测

YOLO 是来自暗网项目的一个实时物体检测。你可以在这里的官方网站上了解这个项目的更多信息:【https://pjreddie.com/darknet/yolo/

https://pjreddie.com/darknet/yolo/

在本实验中,我们在 500 张图片上运行 YOLOv3 模型,并使用 NVIDIA TensorRT 比较模型优化前后的平均推理时间。本实验中使用的图像来自 COCO 数据集

[## COCO -上下文中的常见对象

编辑描述

cocodataset.org](http://cocodataset.org/#home)

1)从 Python 中的暗网中运行未优化的 YOLOv3

[## 胺 Hy / YOLOv3-DarkNet

GitLab.com

gitlab.com](https://gitlab.com/aminehy/yolov3-darknet)

  • 克隆存储库并通过我创建的脚本 docker _ tensort _ OpenCV _ python . sh 运行 docker 映像
git clone [https://gitlab.com/aminehy/yolov3-darknet.git](https://gitlab.com/aminehy/yolov3-darknet.git)cd yolov3-darknetchmod +x docker_TensorRT_OpenCV_Python.sh./docker_TensorRT_OpenCV_Python.sh run
  • 下载并解压测试图像文件夹。/数据/
wget [http://images.cocodataset.org/zips/test2017.zip](http://images.cocodataset.org/zips/test2017.zip)unzip test2017.zip ../test2017/
  • 下载重量文件` yolov3.weights '
wget [https://pjreddie.com/media/files/yolov3.weights](https://pjreddie.com/media/files/yolov3.weights)
  • 然后执行 YOLOv3 python 文件
python darknet.py
  • 成绩:

结果应该保存在文件夹`。/数据/结果'

Output: The mean recognition time over 500 images is 0.044 seconds

2)使用 Python 中的 NVIDIA TensorRT 优化并运行 YOLOv3

第一步是导入模型,包括从磁盘上保存的文件中加载模型,并将其从原生框架或格式转换为 TensorRT 网络。我们的示例从 ONNX 模型加载 ONNX 格式的模型。

ONNX 是一种表示深度学习模型的标准,使它们能够在框架之间转移。(许多框架如 Caffe2、Chainer、CNTK、PaddlePaddle、PyTorch 和 MXNet 都支持 ONNX 格式)。

接下来,基于输入模型、目标 GPU 平台和指定的其他配置参数构建优化的 TensorRT 引擎。最后一步是向 TensorRT 引擎提供输入数据以执行推理。

该示例使用 TensorRT 中的以下组件来执行上述步骤:

  • ONNX 解析器:将 ONNX 格式的训练模型作为输入,并在 TensorRT 中填充网络对象
    -构建器:在 TensorRT 中获取网络,并生成针对目标平台优化的引擎
    -引擎:获取输入数据,执行推理并发出推理输出
    -记录器:与构建器和引擎相关联的对象,用于在构建和推理阶段捕获错误、警告和其他信息

[## 胺 Hy/yolov 3-Darknet-ONNX-TensorRT

GitLab.com

gitlab.com](https://gitlab.com/aminehy/YOLOv3-Darknet-ONNX-TensorRT)

  • 从 GitHub 获取项目并更改工作目录
git clone [https://gitlab.com/aminehy/YOLOv3-Darknet-ONNX-TensorRT.git](https://gitlab.com/aminehy/YOLOv3-Darknet-ONNX-TensorRT.git)cd YOLOv3-Darknet-ONNX-TensorRT/
  • 将模型从 Darknet 转换为 ONNX。这一步将创建一个名为yolov3.onnx的引擎
python yolov3_to_onnx.py
  • 将模型从 ONNX 转换为 TensorRT。这一步将创建一个名为 yolov3.trt 的引擎,并用于推理
python onnx_to_tensorrt.py
  • 对于这个实验,我们设置这个参数:builder.fp16_mode = True
builder.fp16_mode = True
builder.strict_type_constraints = True
  • 成绩:

 Output: The mean recognition time over 500 images is 0.018 seconds using the precision fp16\. 

因此,使用 NVIDIA TensorRT 比未优化版本快 2.31 倍!。

3)通过在 C++中导入 Caffe 模型,使用 NVIDIA TensorRT 优化并运行 YOLOv3

  • 获取项目并更改工作目录

[## 胺 Hy / YOLOv3-Caffe-TensorRT

Yolov3 的 TensorRT

gitlab.com](https://gitlab.com/aminehy/YOLOv3-Caffe-TensorRT)

如果文件夹`/Caffe '不存在(出于任何原因),请下载 YOLOv3 的模型架构和权重(。prototxt 和。caffemodel)并将其插入到文件夹“Caffe”中。有两种选择,416 型和 608 型。这些参数表示 YOLOv3 网络输入端图像的高度/宽度。

  • 从 Google Drive 文件夹下载文件:[https://Drive . Google . com/Drive/folders/18 oxncrrdrcumoamgngjlhegglq 1 hqk _ NJ](http://cd TensorRT-Yolov3/ ./docker_TensorRT_OpenCV_Python.sh run)
  • 编译并构建模型
git submodule update — init — recursivemkdir buildcd build && cmake .. && make && make install && cd ..
  • 编辑 YOLO 配置文件,并在以下设置中选择 YOLO 416 或 YOLO 608
~/TensorRT-Yolov3/tensorRTWrapper/code/include/YoloConfigs.h
  • 您还需要查看位于
~/TensorRT-Yolov3/include/configs.h
  • 如上所述创建 TensorRT 引擎,并在测试映像“dog.jpg”上运行 YOLOv3
# for yolov3–416 (don’t forget to edit YoloConfigs.h for YoloKernel)
./install/runYolov3 — caffemodel=./caffe/yolov3_416.caffemodel — prototxt=./caffe/yolov3_416.prototxt — input=./dog.jpg — W=416 — H=416 — class=80 — mode=fp16
  • 一旦创建了引擎,就可以将它作为参数传递
./install/runYolov3 — caffemodel=./caffe/yolov3_416.caffemodel
 — prototxt=./caffe/yolov3_416.prototxt — input=./dog.jpg — W=416 — H=416 — class=80 — enginefile=./engine/yolov3_fp32.engine
  • 结果:
Output: Time over all layers: 21.245 ms

S 。

结论

本文介绍了优化预训练深度学习模型的重要性。我们在一个计算机视觉的目标检测应用的例子中说明了这一点,在这个例子中,我们获得了推理时间大于 2 的加速比。

下一步怎么办?

参考

你教过你的机器了吗?

原文:https://towardsdatascience.com/have-you-taught-your-machine-yet-45540b7e646b?source=collection_archive---------19-----------------------

谷歌的可教机器如何在你的小浏览器中学习

A visual representation of what a CNN actually sees — Source

机器可以看见

自 2015 年,当一个 Resnet 首次超过人类对图像进行分类的准确度阈值时,深度学习席卷了整个世界。阅读详细介绍这些成就的研究通常会给人一种印象,即表现良好的深度学习模型需要一个包含一百万张标记图像的数据集和一群 GPU 来训练它们。但是如果你只有几百张图片和一台带 CPU 的笔记本电脑会怎么样呢?有了谷歌的可教机器,你可以在几分钟内见证机器的视觉效果。

这里有一款型号(点击试试!)可以对物体是一块布还是一本书进行分类。它是由作者在他的浏览器上使用 4 个对象训练的——一本黑色的书、一本橙色的书、一块白布和一块黄色的布。我们在不同的方向上拍摄每个物体的大约 150 张图像,并在不到一分钟的时间内用总共大约 600 张图像训练该模型。你在这个模型上踢轮胎了吗?为什么不试着给这个模型看一本黄皮书来欺骗它,看看它是否成立?即使你成功地搞乱了这个模型,一台机器能够在如此短的时间内用如此少的数据学会如此准确地对物体进行分类也是非常了不起的。同样不可思议的是,你只需点击几下鼠标,就能体验到这种模式的强大——一切都在你的浏览器中进行——没有服务器,没有 GPU。那么,什么是真正的引擎盖下?

迁移学习

可教机器使用迁移学习;一种方法,使用来自另一个模型的可转移知识,并使用手头任务可用的数据对其进行提炼。这有点像在新的令人兴奋的工作场所使用你在以前的工作中学到的技能。人和系统有不同的名字,问题可能看起来有点不同,但是你的核心分析和编程技能仍然是有用的。但是如果你的工作转换是更基本的,你可能会考虑回到学校去提高你的机器学习技能。也许你想参加高级语音识别课程,了解如何检测声音中的欺骗。你的核心数学技能仍然是相关的,但你必须学习一些相当复杂的东西才能让你的下一份工作顺利进行。

在神经网络模型的情况下,第一种方法使用基本模型,该模型在一些常规任务中表现非常好,例如将所有类型的图像分类到一千个不同的类别中。我们只需去掉最后一个分类层,适合我们自己的分类层,并用新图像只训练这一层。在这种情况下,我们的基本模型只是通过创建一个已经捕获了一般相关特征的图像的表示来充当“固定特征提取器”。

第二种方法更进一步,允许我们的基本模型的权重在训练过程中改变。这被称为“微调”模型。

具体细节

谷歌的可教机器使用前一种方法,将基本模型视为固定的特征提取器。我们将确切地看到他们的实现如何使用迁移学习模型。

MobileNet paper and ImageNet Thumbnails

1.拿训练好的MobileNet【1】模型,一个 28 层的 CNN 模型来分类图像。

2.截断此模型的 softmax 层,并将此模型的输出设置为图像的倒数第二个张量表示

3.创建一个只有两层的小模型——一层是密集层(比如 100 个单元),另一层是最终的 softmax 层,其单元数与我们想要的类数一样多。我们的第一个密集层必须接受与 MobileNet 输出相同的输入。

4.捕捉图像并使用 MobileNet 将每个图像转换为其张量。这些转换后的数据就是我们训练模型所需要的。

5.使用这些训练数据和我们定义的模型,单独训练我们的 2 层模型几个时期。

6.通过附加 MobileNet 和我们的 2 层模型创建一个联合模型。

7.给定一张新图像,通过这个联合模型运行它以生成一个预测。

由于 MobileNet 本身非常小(约 2MB),整个模型可以放入您的浏览器中,并且没有图像需要离开浏览器进行训练。Tensorflow.js 进一步允许我们直接用 javascript 编写所有这些模型,从而赋予整个架构一些奇妙的属性。

1)训练是保护隐私的(图像不必离开你的浏览器)

2)推断可以很快,因为它不需要服务器——这是 MobileNet 通过浏览器摄像头检测几个人姿势的快照

Multi-pose detection on a webcam — Authors webcam using image from Source

3)用户不需要安装任何库——打开一个网页,你就可以立即体验这个模型

4)结合上面的迁移学习方法,您可以在几分钟内训练出一个新模型

该不该回大学?

我们上面详述的方法显然非常有效。但是微调呢?这对训练这些内部神经元有帮助吗?

本文【2】中探讨的视觉十项全能基准旨在回答不同迁移学习方法在性能上的比较。使用一个基础模型作为在 ImageNet 1K 数据集上训练的 resnet28,本文评估了不同迁移学习方法在各种目标数据集(如 CIFAR100、VGG 弗劳尔斯等)上的性能。,这是每一列。我们刚刚讨论的两种不同的迁移学习方法在红框中突出显示为“微调”模型和“特征提取”模型。数字代表图像分类的最高精度。

Learning multiple visual domains with residual adapters — Source

在他们的实验中,微调似乎始终优于固定特征提取器。这很可能是因为模型学习了一些非常 Imagenet 特定的特征,例如试图区分几个狗品种。将这些神经元中的一部分重新用于目标数据集,看起来确实有积极的效果。然而,训练一个 Resnet28 是耗时且计算量大的。该白皮书还找到了一个更好的解决方案,可以充分利用这两个领域的优势。

所以回到大学确实看起来很有用,但是很贵。权衡归结为你可能获得多少,以及是否值得花费。

参考

[1] A.G. Howard,M. Zhu,B. Chen,D. Kalenichenko,W. Wang,T. Weyand,M. Andreetto,H. Adam, MobileNets:用于移动视觉应用的高效卷积神经网络 (2017)

[2] S.A. Rebuffi,H. Bilen,A. Vedaldi 用剩余适配器学习多个视觉域 (2017)

拥有一份好的咨询工作:我为什么要回到学校学习计算机科学

原文:https://towardsdatascience.com/having-a-good-consulting-job-i-still-go-back-to-school-for-a-computer-science-degree-1aef777f8831?source=collection_archive---------30-----------------------

Photo by Avel Chuklanov on Unsplash

硕士毕业后不久,我很幸运地在一家大公司找到了一份分析顾问的好工作。我有很棒的同事和成长机会。

我的第一个大学学位是经济学。我甚至获得了发展经济学硕士学位,这是我当时的兴趣所在,现在依然如此。但是几年前毕业后,我做了一名数据分析师,现在我正准备从事数据科学/软件工程师的职业。渐渐地,我认真考虑了获得计算机科学大学学位的选择。我需要兼职工作和学习。

这是一个艰难的决定。也许我疯了!?

除了要花掉我所有的积蓄之外,花至少 3 到 4 年时间学习的想法也让我害怕。更不用说,如果我不够小心,我可能会耗尽自己的精力,危及我的人际关系。最明显的是,我将不得不告别我非常喜欢的早上在床上多躺几个小时的时光!我阅读了我可能在网上找到的数百篇文章、帖子、论坛帖子,希望能找到一些指导。

如果你已经在这个领域工作,关于计算机科学学位的价值和必要性会有几种相互矛盾的观点。毕竟,很多自学成才的人已经成为成功的工程师、开发人员和技术领导者。此外,网上和训练营有大量的学习资源。我还自学了很多重要的计算机和编程技能。如果是这样,那么获得学位的意义何在?

以下是我自己从一个学习者的角度对计算机科学中正式程序的价值的看法。

1.未知-未知:你不知道你不知道的事

Photo by N. on Unsplash

我们倾向于生活在某种“泡沫”中,无论是职业上还是个人上。我们和认识的人出去玩,和我们相似的人。我们和背景相似的同事一起工作。甚至我们使用的应用程序上的推荐系统也会根据你和像你一样的人的历史行为向你推荐东西。除非你有足够多样的网络,并让自己接触许多不同的角色和挑战,否则我们会把自己的思维局限在这个泡泡里。

即使我从工作中获得了一些经验和技能,我仍然有掉进这个“泡沫”陷阱的感觉。在这个我不知道的泡沫之外,仍然有那么多有价值的见解、知识和技能。虽然有很多方法可以更好地了解计算机和技术这一广阔领域中你所不知道的东西,但我选择了本科教育。我个人认为这是填补我基础中未知空白的好方法。

2.你的学习方式很重要

如果你是一个非常有原则和有组织的人,你更有可能在自学道路上取得成功(假设你已经知道你需要学习什么,以及你应该如何学习)。然而,对我们大多数人来说,这是困难的。举个例子,我是那种非常擅长拖延不紧急的事情的人。在忙碌的一天,也是不那么忙碌的一天,完成技术书籍或在线课程的另一章将是我的任务清单上的最后一件事!

然而,我在一个学习环境中茁壮成长,在那里我不是完全靠自己。有志趣相投的人可以交流,一点点压力和竞争真的给了我额外的动力。

此外,教育计划的系统方法将帮助你组织你的学习。你可能要花几周甚至几个月的时间来自己组织一个课程。有了可靠的课程,我可以按自己喜欢的方式扩展。我通常会将正式的学习课程向前推进一步——进行一些额外的阅读,查找一些更高级的概念、工具和应用程序。这是从任何教育中获得最大收益的最佳方式之一。

3.你对“没用”的东西好奇吗?

Photo by Justin Peterson on Unsplash

在大学学习通常会涉及一堆你可能一辈子都不会用到的理论和概念。但是学起来会很有趣。这些“无用”的想法也许有一天会聚集在一起,帮助你理解工作中甚至生活中的重要事情。理解看似琐碎的基础知识可以帮助你更容易地掌握新技术,更好地联系和概括你的知识。

我不知道在世人面前我会是什么样子,但对我自己来说,我似乎只是一个在海边玩耍的男孩,时不时地寻找一块比平常更光滑的鹅卵石或一个比平常更漂亮的贝壳,而真理的汪洋大海还未被发现。

-艾萨克·牛顿

最后我在网上的帮助搜索也没有找到一个很满意的答案。我只知道我的整个身心都在说“就这么做吧”。我很高兴我做到了!我喜欢像海绵一样学习和吸收每一项知识,同时努力在其他生活承诺中保持平衡。毕竟,无论如何,我们都是学生,不是吗?

拥有不平衡的数据集?以下是你可以修复它的方法。

原文:https://towardsdatascience.com/having-an-imbalanced-dataset-here-is-how-you-can-solve-it-1640568947eb?source=collection_archive---------1-----------------------

处理不平衡数据集的不同方法。

分类是最常见的机器学习问题之一。处理任何分类问题的最佳方式是从分析和探索数据集开始,我们称之为EexplorationDATAAanalysis(EDA)。这个练习的唯一目的是生成尽可能多的关于数据的见解和信息。它还用于查找数据集中可能存在的任何问题。在用于分类的数据集中发现的一个常见问题是不平衡类问题。

什么是数据失衡?

数据不平衡通常反映了数据集中类的不平等分布。例如,在信用卡欺诈检测数据集中,大多数信用卡交易不是欺诈,只有极少数类别是欺诈交易。这样,欺诈类和非欺诈类的比例大约为 50:1。在本文中,我将使用 Kaggle 的信用卡欺诈交易数据集,可以从这里的下载。

首先,让我们画出阶级分布图来看看不平衡。

如您所见,非欺诈交易远远超过欺诈交易。如果我们在没有修复这个问题的情况下训练一个二进制分类模型,那么这个模型将会完全有偏差。它还会影响特性之间的相关性,稍后我将向您展示如何影响以及为什么影响。

现在,让我们介绍一些解决班级不平衡问题的技巧。有完整代码的笔记本可以在这里找到

1-重采样(过采样和欠采样):

这听起来很直观。欠采样是指从多数类中随机删除一些观察值,以便将数字与少数类相匹配的过程。下面的代码显示了一种简单的方法:

Undersampling the majority class

对数据集进行欠采样后,我再次绘制它,它显示了相同数量的类:

Balanced Dataset (Undersampling)

第二种重采样技术叫做过采样。这个过程比欠采样稍微复杂一点。它是生成合成数据的过程,试图从少数类的观察值中随机生成属性样本。对于典型的分类问题,有多种方法可用于对数据集进行过采样。最常见的技术叫做 SMOTE ( 合成少数过采样技术)。简而言之,它查看少数类数据点的特征空间,并考虑其最近的邻居 k

Source:https://imbalanced-learn.readthedocs.io/en/stable/over_sampling.html

为了用 python 编写代码,我使用了一个名为 不平衡学习 或 imblearn 的库。下面的代码展示了如何实现 SMOTE。

SMOTE Oversampling code

还记得我说过不平衡的数据会如何影响特征相关性吗?我给你看一下治疗不平衡班前后的相关性。

重新采样前:

下面的代码绘制了所有特性之间的相关矩阵。

*# Sample figsize in inches*
fig, ax = plt.subplots(figsize=(20,10)) *# Imbalanced DataFrame Correlation*
corr = credit_df.corr()
sns.heatmap(corr, cmap='YlGnBu', annot_kws={'size':30}, ax=ax)
ax.set_title("Imbalanced Correlation Matrix", fontsize=14)plt.show()

重采样后:

请注意,现在特征相关性更加明显了。在修复不平衡问题之前,大多数功能没有显示任何相关性,而这种相关性肯定会影响模型的性能。由于 特征相关性对于整体模型的性能来说非常重要 ,因此修复这种不平衡非常重要,因为它也会影响 ML 模型的性能。

2-集合方法(采样器集合):

在机器学习中,集成方法使用多种学习算法和技术来获得比单独从任何组成学习算法获得的性能更好的性能。(没错,就像民主投票制一样)。当使用集成分类器时,bagging 方法变得流行,它通过对不同的随机选择的数据子集建立多个估计器来工作。在 scikit-learn 库中,有一个名为BaggingClassifier的集成分类器。然而,这种分类器不允许平衡每个数据子集。因此,当在不平衡数据集上训练时,该分类器将偏向大多数类并创建有偏差的模型。

为了解决这个问题,我们可以使用 imblearn 库中的[**BalancedBaggingClassifier**](https://imbalanced-learn.readthedocs.io/en/stable/generated/imblearn.ensemble.BalancedBaggingClassifier.html#imblearn.ensemble.BalancedBaggingClassifier)。它允许在训练集合的每个估计器之前对数据集的每个子集进行重采样。因此,[**BalancedBaggingClassifier**](https://imbalanced-learn.readthedocs.io/en/stable/generated/imblearn.ensemble.BalancedBaggingClassifier.html#imblearn.ensemble.BalancedBaggingClassifier)采用与 scikit-learn BaggingClassifier相同的参数,此外还有另外两个参数,sampling_strategyreplacement,它们控制随机采样器的行为。下面是一些显示如何做到这一点的代码:

Train Imbalanced Dataset using Ensembling Samplers

这样,您可以训练一个分类器来处理不平衡,而不必在训练前手动欠采样或过采样。

重要提示:

  • 在平衡数据之前,应该始终将数据集分成定型集和测试集。通过这种方式,您可以确保测试数据集尽可能地不偏不倚,并反映您的模型的真实评估。
  • 在分割之前平衡数据可能会在测试集中引入偏差,其中测试集中的一些数据点是合成生成的,并且从训练集中是众所周知的。测试集应该尽可能客观。
  • 欠采样技术的问题是,您可能会删除一些有价值的信息,并改变特定领域中具有代表性的整体数据集分布。因此,欠采样不应该是不平衡数据集的首选方法。

总之,每个人都应该知道,建立在不平衡数据集上的最大似然模型的整体性能将受到其预测稀有点和少数点的能力的限制。识别和解决这些点的不平衡对于生成的模型的质量和性能至关重要。

享受 NLP 和权力的游戏对话的乐趣。

原文:https://towardsdatascience.com/having-fun-with-nlp-and-game-of-thrones-dialogues-21c647b0837f?source=collection_archive---------17-----------------------

谁是这个系列中最重要的人物?

Photo by mauRÍCIO SANTOS on Unsplash

介绍。

最后一季即将来临!冬天终于来了!所以我想用对话来平息我对下一季的宣传。

你有没有想过哪个角色最有影响力?谁说的最多?谁的对白比较多?在整个系列中,哪些词用得最多?谁是真正的主角?或者,计算机有可能为这部剧生成新的对话吗?本文将尝试回答这些问题。

在此之前,我想提一下这两个家伙,他们的工作激发了你将要看到的很多东西,所以请检查他们的帖子和代码:

帕勒斯·乔普拉和丹尼尔·利赫特

数据免责声明。

该数据集由该系列的 65 个章节组成,并非所有的季节都是完整的,尤其是第 2、3 和 4 季,所有其他季节都是完整的。你可以在这里了解更多关于收集数据的技术方面

对话多就意味着话多吗?

Barplot for dialogues

我用最多的对话和更高的字数绘制了前 20 个角色,我们可以清楚地看到提利昂确实从不闭嘴,有超过一千个对话,平均每个对话 16 个单词,是迄今为止最健谈的角色。

Barplot for words

事实上,对话和文字是相关的,前 20 个角色从一个情节到另一个情节几乎没有变化,一个有趣的变化是兰尼斯特家,他们在每个对话中说更多的话。

让我们检查一下每段对话单词分布情况。

Distribution of words per dialogue of top 5 characters.

琼恩·雪诺是一个沉默寡言的人,他的情节几乎平淡无奇,与丹妮莉丝非常相似,兰尼斯特家的情节更加稳健,每次开口都意味着更多的话。

Longest dialogue of the sample.

詹姆的图中有一个很大的异常值,比其他 4 个大得多,当我检查时,我意识到这是其中最大的一个。我们的样本数据中最长的不间断对话是詹姆·兰尼斯特用超过 350 个单词告诉布里安他是如何在第三季杀死疯王的。

我们的角色实际上在说什么,有模式吗?

我按照前 5 个字符绘制了 60 个最常用的单词,我使用 NLTK 删除了英语中一些非常常用的单词和一些不会给情节带来任何价值的其他单词,如“国王”、“勋爵”、“先生”等。

只有兰尼斯特家的人在他们的话语中有爱,我认为这真正定义了他们的角色,他们的动机大多是激情。虽然像琼恩和奈德这样的史塔克家族是因为职责和拯救世界而战,或者丹妮是因为命运而战,从她的用词来看很明显,她是一个无情的统治者;兰尼斯特家为他们所爱的人而战。我也可以说《权力的游戏》是关于一群极度恋父的杀人犯。

这一个是令人震惊的。

主角是谁?

说得最多并不总是意味着成为最有影响力的人物,这取决于你与之交谈的人有多重要,以及你在自己的对话之外被提及的次数。你和你周围的世界有多相关,所以这是我们样本数据的交互网络。

https://bl.ocks.org/chrismartinezb/e35f6c6b7a4def1dc56eea92d8897d40/ee9d335a443b042fc20c2f2eb0d55e9997d2f2b9

检查图中的链接以获得更好的视图,并有机会玩节点。

无论如何,这个图表从数字上没有告诉我们一个字符的重要性。

这的确告诉我们瑟曦、提利昂和琼恩有多重要,但任何一个都可能是主角,对吧?

中心性的程度。

如果我们测量每个节点的中心度,我们将得到一个非常明确的答案,即我们的角色对该系列有多重要,所以让我们根据样本数据来看看前 10 个最重要的角色:

根据我们的样本,乔恩的确是《冰与火之歌》中最重要的角色。

使用示例对话生成文本。

在预先训练好的模型出现之前,你需要一个巨大的文本语料库来做任何有意义的事情。现在,即使是很小的数据集也足以做有趣的事情。请在评论中告诉我,你想到了哪些可以使用小型文本语料库和预训练模型的项目想法。

我参加了 Paras Chopra 挑战,并自己生成了一些对话,结果非常有趣。

It is indeed a pity to trust Sansa.

结论。

  • 主角是琼恩·雪诺,因为他与奈德、珊莎、提利昂和丹妮等其他重要角色有联系。
  • 在人物中心情节中,提利昂在瑟曦之下,我认为这是因为两个主要原因:第二季和第三季在数据集中有很多缺失的章节,而这几季是提利昂最出彩的地方;第二,因为瑟曦与奈德和劳勃(非常中心的人物)有很强的关系,但提利昂从不谈论他们中的任何一个。
  • 更多的对话在某种程度上与性格影响有关,但只是在一定程度上。其他角色必须谈论你,即使你没有和他们说话。
  • 奈德·史塔克在第一季中死后仍然是最重要的角色之一。
  • 与其说提利昂是丹妮莉丝的盟友,不如说他是兰尼斯特,这可能是他在最后一季背叛丹妮莉丝的原因,就像很多人推测的那样。他和兰尼斯特家的人是一伙的,在查看《乌云图》时,他和他们有很多相似之处,甚至比丹妮莉丝和琼恩还相似。
  • 即使只有 60%的数据,我们也能得出很好的结论。
  • 用这么小的数据集生成文本的效果比我预期的要好,读起来很有趣,不过还可以改进很多。

生成角色之间的对话将是一个有趣的挑战,你能想到什么方法吗?

你认为谁才是真正的主角?为什么呢?

利用这些数据,你还能得出什么结论?

用分析的每一步检查这个库这里

介绍 TextBlob

原文:https://towardsdatascience.com/having-fun-with-textblob-7e9eed783d3f?source=collection_archive---------6-----------------------

用于处理文本数据的 Python 库,NLP 框架,情感分析

作为 Python 的 NLP 库, TextBlob 已经有一段时间了,在听说了很多关于它的好东西如词性标注情感分析之后,我决定试一试,因此,这是我第一次使用 TextBlob 执行自然语言处理任务。

Yelp 数据集是其业务、评论和用户数据的子集,用于个人、教育和学术目的。作为 JSON 文件,我们将只使用yelp_academic_dataset_review.jsonyelp_academic_dataset_user.json,并且可以从这里下载。

数据

数据集是 JSON 格式的,为了能够在 pandas 数据框架中读取,我们首先加载 JSON 数据,然后将半结构化的 JSON 数据规范化为一个平面表,然后使用to_parquet将该表写入二进制拼花格式。稍后当我们需要它时,我们从文件路径加载一个 parquet 对象,返回一个 pandas 数据帧。

下面的过程为我们提供了两个数据表,user 和 review。

JSON_parquet.py

user table

review table

我们合并用户表和评论表,用后缀来处理相同的列名,去掉零星号。

user_review = (review.merge(user, on='user_id', how='left', suffixes=['', '_user']).drop('user_id', axis=1))user_review = user_review[user_review.stars > 0]

星级分布

x=user_review['stars'].value_counts()
x=x.sort_index()
plt.figure(figsize=(10,6))
ax= sns.barplot(x.index, x.values, alpha=0.8)
plt.title("Star Rating Distribution")
plt.ylabel('count')
plt.xlabel('Star Ratings')
rects = ax.patches
labels = x.values
for rect, label in zip(rects, labels):
    height = rect.get_height()
    ax.text(rect.get_x() + rect.get_width()/2, height + 5, label, ha='center', va='bottom')
plt.show();

Figure 1

很高兴知道大多数评论星级相当高,并没有很多可怕的评论。显而易见,企业有一种动机去争取尽可能多的好评。

每年的评论与每年的星级

fig, axes = plt.subplots(ncols=2, figsize=(14, 4))
user_review.year.value_counts().sort_index().plot.bar(title='Reviews per Year', ax=axes[0]);
sns.lineplot(x='year', y='stars', data=user_review, ax=axes[1])
axes[1].set_title('Stars per year');

Figure 2

user_review.member_yrs.value_counts()

Figure 3

Yelp 成立于 2004 年,根据我们的数据,从那时起已经有超过 4000 人成为 Yelp 会员。

让我们来看一个示例评论:

review_sample = user_review.text.sample(1).iloc[0]
print(review_sample)

让我们检查一下这个样本评论的极性。极性范围从-1(最负)到 1(最正)。

TextBlob(review_sample).sentiment

上述评论的极性约为-0.06,意味着它略有负面,主观性约为 0.56,意味着它相当主观。

为了更快地进行,我们将从当前数据中抽取 100 万条评论,并添加一个新的极性列。

sample_reviews = user_review[['stars', 'text']].sample(1000000)def detect_polarity(text):
    return TextBlob(text).sentiment.polaritysample_reviews['polarity'] = sample_reviews.text.apply(detect_polarity)
sample_reviews.head()

Figure 4

前几行看起来不错,星星和极性彼此一致,意味着星星越高,极性越高,就像它应该的那样。

极性分布

num_bins = 50
plt.figure(figsize=(10,6))
n, bins, patches = plt.hist(sample_reviews.polarity, num_bins, facecolor='blue', alpha=0.5)
plt.xlabel('Polarity')
plt.ylabel('Count')
plt.title('Histogram of polarity')
plt.show();

Figure 5

大多数极性得分都在零以上,这意味着数据中的大多数评论都是积极情绪,这符合我们之前发现的星级分布。

按星星分组的极性

plt.figure(figsize=(10,6))
sns.boxenplot(x='stars', y='polarity', data=sample_reviews)
plt.show();

Figure 6

总的来说,这和我们预期的一样好。让我们进行更深入的调查,看看我们是否能找到任何有趣的或异常的东西。

极性最低的评论:

sample_reviews[sample_reviews.polarity == -1].text.head()

星级最低的评论:

sample_reviews[sample_reviews.stars == 1].text.head()

它们看起来都像我们预期的负面评论。

极性最低(负面情绪最多)但有 5 颗星的评论:

sample_reviews[(sample_reviews.stars == 5) & (sample_reviews.polarity == -1)].head(10)

Figure 7

具有最高极性(最积极情绪)但只有一星的评论:

sample_reviews[(sample_reviews.stars == 1) & (sample_reviews.polarity == 1)].head(10)

Figure 8

两张桌子看起来都很奇怪。显然,一些极性与其相关评级不一致。这是为什么呢?

经过进一步挖掘,发现 TextBlob 会继续寻找可以赋予极性和主观性的单词和短语,并对较长的文本进行平均,例如我们的 Yelp 评论。

想了解 TextBlob 是如何计算极性和主观性的,Aaron Schumacher的这篇文章给出了简单而清晰的解释。

我喜欢学习和玩 TextBlob。我意识到 TextBlob 可以用来完成许多其他的 NLP 任务,比如词性标注、名词短语提取、分类、翻译等等,以后我们还会用到它们。

Jupyter 笔记本可以在 Github 上找到。享受这周剩下的时光吧!

参考资料:

文本 Blob 文档

书:算法交易的实践机器学习

使用 Python 在你的 Twitter 上玩得开心!

原文:https://towardsdatascience.com/having-fun-with-your-twitter-using-python-f9e0a7684867?source=collection_archive---------8-----------------------

我用这个标题吸引了你的注意力吗?

不管怎样,我希望如此。

今天,我将在这里展示一些东西。第一,从你的 Twitter 个人资料中获取大量信息的惊人能力,以及你如何利用它来改善或提升你的在线形象。其次,展示一些强大的 Python 库,它们可以用来完成很多事情。

所以让我们开始吧

为什么是推特?

最近我一直在疯狂发微博,因为现在是我的假期,我没有更好的事情可做。所以我注意到 Twitter,除了让我知道每条推文有多少赞和转发,还告诉我一些叫做的印象和约定

参与度:在所选日期范围内,用户与您发送的推文互动的总次数。互动包括转发、回复、关注、喜欢和点击链接、卡片、标签、嵌入式媒体、用户名、个人资料照片或推文扩展。

浏览量:在所选日期范围内发送的推文的浏览量。印象是一条推文在用户的时间线或搜索结果中出现的次数。

不像脸书(公平地说,它确实为脸书网页提供了很好的分析和信息)、Instagram 和其他社交媒体,我更容易从自己的个人资料中获得大量数据。这还没有考虑到强大的 Twitter API,你可以利用它来洞察其他人的推文!

你可能会问,你所说的这些数据在哪里?

强大的 Twitter 分析——我是如何获得数据的!

正如那些试图将推文用于情感分析等目的的人所知,推文是一种非常有用的数据来源,可以用来进行操作和提取信息。正如我之前提到的,最明显的是情绪分析——试图确定一条推文在本质上是积极的,还是消极的,或者只是中性的。从该网站的巨大流量、每天积极发推文的人数,以及他们将推文放在公共领域并可以被拉取(你实际上可以将你的个人资料保密,但很少有人这样做)这一事实可以清楚地看出,人们可以使用这些推文来了解许多事情。通过利用 Twitter 的 API,你可以进行查询,比如在一段时间内提取某个主题的每条推文,或者提取某个用户的非转发推文。

在这个数据提取阶段,有很多方法可以获取推文。你可以利用 NLTK 库中的推文。您也可以使用 Twitter API 来提取推文,但是我想让这个阶段不那么麻烦。所以我决定只分析我自己的推文,我可以很快提取出来,因为 Twitter 对我们很好。

所以首先让我们看看 Twitter 在哪里为你很好地存储了这些信息!

首先进入菜单下的分析部分,如下所示:

它会把你重定向到一个特殊的页面,这个页面已经显示了很多信息。在最上方,它提供了您在过去 28 天内所做的事情,以及与当前时间段之前的 28 天相比,您的活动情况如何:

正如你所看到的,他们还提供了每个月的信息,你的热门推文,热门提及以及该月的信息摘要。

您还可以查看您的推文进展如何,以及您的推文进展情况的图表:

现在,我们如何从中提取信息,以便使用您常用的 Python 工具进行处理呢?谢天谢地,Twitter 有一个叫做“导出数据”的东西,它可以方便地将所有数据打包成一个漂亮的 CSV 文件,并打包到你的电脑上,你可以自由地打开盒子,做你想做的事情!点击你在那里看到的导出数据按钮,它将获取你希望分析的时间段内的所有推文,并以 CSV 文件的形式发送给你。

现在它将以这样的方式到达:

请注意,这里有很多参数或列是不可见的,比如赞数、转发数、参与度等等。但关键是,对于许多活动来说,获得一个好的数据集是一个挑战,但 Twitter 给了我们如此整洁有序的数据供我们使用。所以在这方面支持推特!

让我们将 Python 引入其中吧!

如果我说我是某种专家,那我是在撒谎:( 剧透,我不是! )。但我将在这里做几件事,这表明任何人实际上都可以利用我们从我的个人资料中获得的推文做一些事情(也尝试利用你自己的个人资料,但要确保你有足够的推文来分析!).一件事是,我将使用一个名为 textblob 的 Python 库来查看我发出的推文类型,无论它们是正面的、负面的还是中性的。我要做的另一件事是查看哪些词是我经常使用的,并且在我的推文中很突出。为了增加乐趣,我可以用一种叫做“单词云”的东西以一种很酷的方式直观地呈现结果。你最终会明白为什么我对此感到兴奋。所以让我们开始吧!

先决条件:

我已经使用 Spyder (Anaconda)在这里编写了我的脚本,但是您总是可以使用 Python shell 本身或者编写代码并运行文件(我在这里的所有示例中都使用 Python3,因为为什么不这样做)。

您还需要一些库来开始(不要介意定义,它们主要是基于文档的指针:

a.textblob: TextBlob 是一个用于处理文本数据的 Python (2 和 3)库。它提供了一个简单的 API,用于处理常见的自然语言处理(NLP)任务,如词性标注、名词短语提取、情感分析、分类、翻译等。

b.matplotlib:Matplotlib 是一个 Python 2D 绘图库,它以各种硬拷贝格式和跨平台的交互环境生成出版物质量数字。Matplotlib 可用于 Python 脚本、Python 和 IPython 外壳、Jupyter 笔记本、web 应用服务器和四个图形用户界面工具包。

c.pandas: pandas 是一个开源的、BSD 许可的库,为 Python 编程语言提供高性能、易于使用的数据结构和数据分析工具。

d.wordcloud:顾名思义,你可以创建一个名字云,越常用的单词越突出显示。

对于 Ubuntu 用户,你可以使用 pip 或 pip3 来安装所有这些 Python 包,这就是我所做的:(用相关包替换包名)

pip install package-name

情绪分析时间!

建立自己的程序来做这件事不再那么困难了!随着 tweets 被整齐地排列,我所要做的就是改变 Tweets 部分下的列,在两个单词(Tweet_text)之间添加下划线,以避免程序中的空格出现错误。

导入所需的库:

import pandas as pd 
from wordcloud import WordCloud, STOPWORDS
import matplotlib.pyplot as plt

现在,导入您需要的文件,该文件应该与您正在写入的 Python 文件在同一个文件夹中,使用 pandas 提供的 read_csv 函数将它读入一个名为 df 的变量。您可以使用不同的编码方案。

df=pd.read_csv(r"tweet_activity_metrics_TheCoolFanBoi_20181208_20190105_en.csv",encoding="latin-1")comment_words = ' ' #We will be appending the words to this varstopwords = set(STOPWORDS) #Finds all stop words in the set of tweets.for val in df.Tweet_text: val = str(val) #convert all tweet content into strings tokens = val.split() #Split all strings into individual components for i in range(len(tokens)): tokens[i] = tokens[i].lower() #Converts all the individual strings to lower case.for words in tokens: comment_words = comment_words + words + ' '

最后,这是 WordCloud 发挥作用的地方:

wordcloud=WordCloud(width=1000,height=1000, background_color='blue', stopwords=stopwords,min_font_size=10).generate(comment_words)
#All of this is a single line

请随意探索 WordCloud 功能的所有参数,并根据您的意愿进行调整。

最后,让我们使用 matplotlib 库将其显示为输出:

plt.figure(figsize=(10,10),facecolor=None)
plt.imshow(wordcloud)
plt.axis("off")
plt.tight_layout(pad=0)plt.show()

这是我保存这个文件并在 Python 上运行它时得到的结果:

诚然,不是最好的背景色,但你可以看到很多用不同字体突出显示的文字。请随意从我在推文中使用的词语来分析我的个性。虽然我只会说‘joelvzach’,‘pickle Hari’,‘pallavibiriyani’和‘guyandheworld’这些词都是 Twitter 的句柄:)

玩弄情绪分析

我不会在这里花太多时间,因为我和你们一样是新手。但是开始并不困难,这也是由于程序员在开发高效库方面所做的大量工作,这使得开始使用它变得更加容易。

你需要做的就是这个:

import pandas as pd 
from textblob import TextBlob
df=pd.read_csv(r"tweet_activity_metrics_TheCoolFanBoi_20181208_20190105_en.csv",encoding="latin-1")#comment_words=' '
#stopwords=set(STOPWORDS)
print('Tweet   |     Polarity     |     Subjectivity')
for val in df.Tweet_text:
    sentiments=TextBlob(val)
    print('---------------')
    print(val,end='')
    print(' ',end='')
    print(sentiments.polarity,end='')
    print(' |  ',end='')
    print(sentiments.subjectivity)

你会得到这样的输出:

这些是我的推文,以及我的推文在情绪方面的评分,从-1(最负面)到 1(最正面)。这也显示了我的陈述在 0 到 1 的范围内是多么的主观。

你一定在想,坐在这里,自然语言处理?Pfft。我可以做到。

但是这里有一个问题:我们只是在一个非常高层次和抽象的方式上玩它。我们考虑过如何计算一条推文的情感或主观性吗?我们用了什么算法来遍历文本?诸如此类。

这是 textblob 库的奇迹。如果你想更深入地了解这一点,我不会把它添加到文章中,但是请查看这篇文章作为 textblob 文档的一部分,它告诉我们这个函数是如何工作的,以及它如何利用朴素贝叶斯算法进行情感分析。

这结束了我的短文,让我先睹为快,看看我最近都做了些什么(很明显,没什么好事)。一定要看看我的推特(因为我已经展示了很多),并在我继续发推特的时候抓住我,因为为什么不呢,对吗?代码在这里。

还要感谢所有使用的库的文档以及 GeeksForGeeks 为我完成这篇文章提供了很好的材料。

谢谢你读完这篇文章!

HBase 工作原理:Hadoop 架构的一部分

原文:https://towardsdatascience.com/hbase-working-principle-a-part-of-hadoop-architecture-fbe0453a031b?source=collection_archive---------4-----------------------

Hadoop 中 HBase 工作的简要总结

1.感应

HBase 是一个高可靠性、高性能、面向列、可扩展的分布式存储系统,使用 HBase 技术在廉价的 PC 服务器上构建大规模结构化存储集群。HBase 的目标是存储和处理大量数据,特别是仅使用标准硬件配置来处理由成千上万行和列组成的大量数据。

不同于 MapReduce 的离线批量计算框架,HBase 是随机存取存储和检索数据平台,弥补了 HDFS 不能随机存取数据的缺点。

它适用于实时性要求不是很高的业务场景——h base 存储字节数组,不介意数据类型,允许动态、灵活的数据模型。

Hadoop Ecosystem (Credit: Edureka.com)

上图描绘了 Hadoop 2.0 生态系统的各个层,即位于结构化存储层的 Hbase。

HDFS 为 HBase 提供高可靠性的底层存储支持。

MapReduce 为 HBase 提供了高性能的批处理能力。ZooKeeper 为 HBase 提供稳定的服务和故障转移机制。Pig 和 Hive 为数据统计处理提供了 HBase 的高级语言支持,Sqoop 为 HDB 提供了可用的 RDBMS 数据导入功能,使得业务数据从传统数据库迁移到 HBase 非常方便。

2。HBase 架构

2.1 设计思路
HBase 是一个分布式数据库,使用 ZooKeeper 管理集群,HDFS 作为底层存储。

在架构层面,由 h master(Zookeeper 选出的领袖)和多个 HRegionServers 组成。

底层架构如下图所示:

在 HBase 的概念中,HRegionServer 对应集群中的一个节点,一个 HRegionServer 负责管理多个 HRegion,一个 HRegion 代表一个表的一部分数据。

在 HBase 中,一个表可能需要很多 HRegion 来存储数据,每个 h region 中的数据并不是杂乱无章的。

HBase 在管理 HRegion 时,会为每个 HRegion 定义一个 Rowkey 的范围。属于定义范围内的数据将被移交给特定的区域,从而将负载分布到多个节点,从而利用了分布式和特性的优势。

此外,HBase 会自动调整区域的位置。如果某个 HRegionServer 过热,即大量请求落在由 HRegionServer 管理的 HRegion 上,HBase 会将 HRegion 移动到其他相对空闲的节点上,确保集群环境得到充分利用。

2.2 基础架构

HBase 由 HMaster 和 HRegionServer 组成,同样遵循主从服务器架构。HBase 将逻辑表划分为多个数据块 HRegion,并存储在 HRegionServer 中。

HMaster 负责管理所有的 HRegionServers。它本身不存储任何数据,只存储数据到 HRegionServer 的映射(元数据)。

集群中的所有节点都由 Zookeeper 协调,并处理 HBase 操作期间可能遇到的各种问题。HBase 的基本架构如下所示:

客户端: 使用 HBase 的 RPC 机制与 HMaster 和 HRegionServer 进行通信,提交请求并获取结果。对于管理操作,客户端使用 HMaster 执行 RPC。对于数据读写操作,客户端使用 HRegionServer 执行 RPC。

Zookeeper: 通过向 Zookeeper 注册集群中各个节点的状态信息,HMaster 可以随时感知各个 HRegionServer 的健康状态,也可以避免 HMaster 的单点问题。

HMaster: 管理所有的 hregionserver,告诉他们哪些 hregionserver 需要维护,监控所有 hregionserver 的健康状况。当一个新的 HRegionServer 登录到 HMaster 时,HMaster 告诉它等待分配数据。当一个 HRegion 死亡时,HMaster 将其负责的所有 h region 标记为未分配,然后将它们分配给其他 HRegionServers。HMaster 没有单点问题。HBase 可以启动多个 HMasters。通过 Zookeeper 的选举机制,集群中始终有一个 HMaster 在运行,提高了集群的可用性。

HRegion: 当表格的大小超过预设值时,HBase 会自动将表格分成不同的区域,每个区域包含表格中所有行的子集。对于用户来说,每个表都是一个数据集合,由一个主键(RowKey)来区分。在物理上,一个表被分成多个块,每个块都是一个 HRegion。我们使用表名+开始/结束主键来区分每个 HRegion。一个 HRegion 会在一个表中保存一段连续的数据。一个完整的表数据存储在多个 HRegions 中。

HRegionServer:h base 中的所有数据一般从底层开始存储在 HDFS。用户可以通过一系列 HRegionServers 获取这些数据。一般情况下,集群的一个节点上只运行一个 HRegionServer,每个段的 HRegionServer 只由一个 HRegionServer 维护。HRegionServer 主要负责向 HDFS 文件系统读写数据,以响应用户的 I/O 请求。它是 HBase 中的核心模块。HRegionServer 在内部管理一系列 HRegion 对象,每个 HRegion 对应逻辑表中的一个连续数据段。HRegion 由多个 HStores 组成。每个 HStore 对应于逻辑表中一个列族的存储。可以看出,每个列族都是一个集中的存储单元。因此,为了提高操作效率,最好将具有相同 I/O 特征的列放在一个列族中。

HStore: 它是 HBase 存储的核心,由 MemStore 和 StoreFiles 组成。MemStore 是一个内存缓冲区。用户写的数据会先放入 MemStore。当 MemStore 满时,Flush 将是一个 StoreFile(底层实现是 HFile)。当 StoreFile 文件数量增加到一定阈值时,会触发紧凑合并操作,将多个 StoreFile 合并为一个 store file,并在合并过程中执行版本合并和数据删除操作。所以可以看出,HBase 只是添加数据,所有的更新和删除操作都在后续的压缩过程中进行,这样用户的写操作一进入内存就可以返回,保证了 HBaseI/O 的高性能,当 StoreFiles 压缩后,会逐渐形成越来越大的 StoreFile。当单个存储文件的大小超过某个阈值时,将触发拆分操作。同时,当前 hre region 将被拆分为 2 个 hre region,父 hre region 将下线。这两个子区域由 HMaster 分配给相应的 HRegionServer,这样原 HRegion 的负载压力就分流到这两个 HRegion 上了。

HLog: 每个 HRegionServer 都有一个 HLog 对象,这是一个预先编写的日志类,实现预写日志。每当用户向 MemStore 写入数据时,它也向 HLog 文件写入数据的副本。HLog 文件被周期性地滚动和删除,旧文件被删除(已经被持久化到 StoreFile 的数据)。当 HMaster 检测到某个 HRegionServer 被 Zookeeper 意外终止时,HMaster 首先处理遗留 HLog 文件,拆分不同 HRegion 的 HLog 数据,放入对应的 HRegion 目录,然后重新分配无效的 HRegion。在加载 HRegion 的过程中,这些 h region 的 HRegionServer 会发现有历史 HLog 需要处理,所以 Replay HLog 中的数据会被转移到 MemStore,然后刷新到 StoreFiles,完成数据恢复。

2.3 根和元

HBase 的所有 HRegion 元数据都存储在. META .表中。随着 HRegion 的增加。元表也增加并分裂成多个新的 HRegions。

中每个 HRegion 的位置。中所有 HRegions 的元数据。元表存储在根表中,最后根表的位置信息由 Zookeeper 记录。

在所有客户端访问用户数据之前,它们需要首先访问 Zookeeper 以获得-ROOT-的位置,然后访问-ROOT-table 以获得。元表,最后根据元表中的信息确定用户数据的位置,如下:如图所示。

根表永远不会被分割。它只有一个 HRegion,这保证了任何 HRegion 只需三次跳转就可以定位。为了加快访问速度。元表保存在内存中。

客户端缓存查询到的位置信息,缓存不会主动失效。如果客户端仍然不能访问基于缓存信息的数据,则向区域服务器询问相关的。元表来尝试获取数据的位置。如果仍然失败,询问。与根表相关联的元表是。

最后,如果前面的信息全部无效,那么 HRegion 的数据由 ZooKeeper 重新定位。因此,如果客户机上的缓存完全无效,您需要来回六次才能获得正确的 HRegion。

3.HBase 数据模型

HBase 是一个类似于 BigTable 的分布式数据库。它是稀疏的长期存储(在 HDFS 上),多维的,排序的映射表。这个表的索引是行关键字、列关键字和时间戳。HBase 数据是一个字符串,没有类型。

把一个表想象成一个大的映射。可以通过行键、行键+时间戳或行键+列(列族:列修饰符)来定位特定数据。因为 HBase 稀疏地存储数据,所以一些列可以是空白的。上表给出了 com.cnn.www 网站的逻辑存储逻辑视图。表格中只有一行数据。

该行的唯一标识符是“com.cnn.www”,并且该行数据的每次逻辑修改都有一个时间。该戳记对应于相应的。

表格中有四列:contents: HTML,anchor:cnnsi.com,anchor:my.look.ca,mime: type,每一列给出它所属的列族。

行键(row key)是表中数据行的唯一标识符,用作检索记录的主键。

在 HBase 中,只有三种方法可以访问表中的行:通过行键访问、给定行键的范围访问和全表扫描。

行键可以是任何字符串(最大长度为 64KB ),并按字典顺序存储。对于经常一起读取的行,需要仔细设计基本值,以便它们可以集中存储。

4.HBase 读写过程

下图是 HRegionServer 数据存储关系图。如上所述,HBase 使用 MemStore 和 StoreFile 来存储对表的更新。数据在更新时首先被写入 HLog 和 MemStore。MemStore 中的数据被排序。

当 MemStore 累积到某个阈值时,将创建一个新的 MemStore,旧的 MemStore 将被添加到刷新队列中,一个单独的线程将被刷新到磁盘,成为 StoreFile。同时,系统会在 Zookeeper 中记录一个检查点,表示这个时间之前的数据更改已经被持久化。当意外系统发生时,MemStore 中的数据可能会丢失。

在这种情况下,HLog 用于恢复检查点之后的数据。

StoreFile 是只读的,一旦创建就不能修改。因此,HBase 的更新是一个额外的操作。当存储中的 StoreFile 达到某个阈值时,执行合并操作,合并对同一键的修改以形成一个大的 StoreFile。当存储文件的大小达到某个阈值时,存储文件被分割并分成两个存储文件。

4.1 写操作流程

第一步:客户端通过 Zookeeper 的调度向 HRegionServer 发送写数据请求,将数据写入 HRegionServer。

第二步:将数据写入 HRegion 的 MemStore,直到 MemStore 达到预设的阈值。

第三步:将 MemStore 中的数据刷新到 StoreFile 中。

步骤 4: 随着 StoreFile 文件数量的增加,当 StoreFile 文件数量增加到一定阈值时,触发紧凑合并操作,将多个 StoreFile 合并为一个 store file,同时进行版本合并和数据删除。

第五步: StoreFiles 通过不断的压缩操作,逐渐形成一个越来越大的 StoreFile。

第六步:当单个 StoreFile 的大小超过一定阈值后,触发拆分操作,将当前的 HRegion 拆分成两个新的 HRegion。父 HRegion 将脱机,新拆分的两个子 HRegion 将由 HMaster 分配给相应的 HRegionServer,以便将原 HRegion 的压力分流到这两个 HRegion。

4.2 读取操作流程

步骤 1: 客户端访问 Zookeeper,找到-ROOT-table,获取. META. table 信息。

第二步:从. META. table 中查找获取目标数据的 HRegion 信息,找到对应的 HRegionServer。

第三步:通过 HRegionServer 获取需要查找的数据。

第四步:HRegionserver 的内存分为两部分:MemStore 和 BlockCache。MemStore 主要用来写数据,BlockCache 主要用来读数据。先读取请求到 MemStore 检查数据,检查 BlockCache 检查,然后检查 StoreFile,将读取结果放入 BlockCache。

5.HBase 使用场景

半结构化或非结构化数据:对于没有很好定义或者杂乱的数据结构字段,很难按照一个适合 HBase 的概念提取数据。如果随着业务的增长存储了更多的字段,RDBMS 需要停机来维护变更表结构,HBase 支持动态添加。

记录非常稀疏:RDBMS 行有多少列是固定的,空列浪费存储空间。不存储 HBase 为空的列,这样可以节省空间并提高读取性能。

多版本数据:根据行键和列标识符定位的值可以有任意多个版本值(时间戳不同),所以对于需要存储变更历史的数据,使用 HBase 非常方便。

数据量大:当数据量越来越大时,RDBMS 数据库撑不住了,就有了读写分离策略。通过一个主设备负责写操作,多个从设备负责读操作,服务器成本翻倍。压力越来越大,师傅撑不住了。这时候库就分了,关联度不大的数据单独部署。有些连接查询无法使用,需要使用中间层。随着数据量的进一步增加,一个表的记录变得越来越大,查询变得非常慢。

因此,有必要将表划分成多个表,例如,通过将 ID 取模来减少单个表的记录数量。经历过这些事情的人都知道怎么折腾过程。

HBase 很简单,只需在集群中增加新的节点,HBase 就会自动水平拆分,与 Hadoop 的无缝集成保证了数据的可靠性(HDFS)和海量数据分析的高性能(MapReduce)。

6.h 基线图减少

HBase 中表和区域的关系有点类似于 HDFS 中文件和块的关系。由于 HBase 提供了与 MapReduce 交互的 API,如 TableInputFormat、TableOutputFormat 等,HBase 数据表可以直接作为 Hadoop MapReduce 的输入输出,方便了 MapReduce 应用的开发,并且不需要关注 HBase 系统本身细节的处理。

如果你喜欢这个主题,你可以看看我写下的关于 Hadoop 的其他几个主题。
如果您发现任何错误或有任何建议,请随时通过我的 LinkedIn 联系我。

[## Apache Hadoop 小结:大数据问题的解决方案和来自 Google 的提示

欢迎学习大数据和 Hadoop 简介,我们将在这里讨论 Apache Hadoop 以及如此大的问题…

towardsdatascience.com](/a-brief-summary-of-apache-hadoop-a-solution-of-big-data-problem-and-hint-comes-from-google-95fd63b83623) [## Hadoop 中的新特性:你应该知道 Hadoop 中的各种文件格式。

Hadoop 文件格式初学者指南

towardsdatascience.com](/new-in-hadoop-you-should-know-the-various-file-format-in-hadoop-4fcdfa25d42b)

PyTorch 的 HDF5 数据集

原文:https://towardsdatascience.com/hdf5-datasets-for-pytorch-631ff1d750f5?source=collection_archive---------3-----------------------

如果你从事计算机视觉领域的工作,你肯定听说过 HDF5。分层数据格式 (HDF)第 5 版是一种流行的格式,用于存储和交换非结构化数据,如 raw 格式的图像、视频或卷,以用于各种研究或开发领域。它受到许多编程语言和 API 的支持,因此变得越来越流行。这也适用于为机器学习工作流程中的存储数据。在这篇文章中,我介绍了一种在 PyTorch 中使用 HDF5 数据训练深度学习算法的可能方法(包括即用型代码)。

HDF5 文件格式

HDF5 文件由两种主要类型的对象组成:数据集和组。数据集是同构类型的多维数组,例如 8 位无符号整数或 32 位浮点数。另一方面,组是为保存数据集或其他组而设计的层次结构,构建了类似文件系统的数据集层次结构。此外,组和数据集可能会附加用户定义属性形式的元数据。

Python 使用 h5py支持 HDF5 格式。该软件包封装了原生 HDF C API,并支持该格式的几乎全部功能,包括读写 HDF5 文件。

如果你需要在可视化编辑器中查看或编辑你的 HDF5 文件,可以下载官方 HDFView 应用。该应用程序支持以表格方式或图像方式查看不同格式的数据集。此外,它使您能够通过创建新的组和数据集以及重命名和移动现有的组和数据集来编辑文件。

PyTorch 数据集

为了高效地将您的数据加载到 PyTorch,PyTorch 要求您编写自己的 Dataset 类(或者使用预定义的类)。这是通过从torch . utils . data . Dataset继承,覆盖函数 len (以便在数据集上调用 len()返回数据集的长度)和 getitem (启用索引)来实现的。

然后使用类torch . utils . data . data loader以预定义的方式从数据集中进行采样(例如,您可以随机打乱数据集,选择批量大小等)。PyTorch 中数据加载的主要优势(和魔力)在于这样一个事实,即数据加载可以以并行方式发生,而无需处理多线程和同步机制。这可以通过简单地将 DataLoader 构造函数中的参数 num_workers 设置为所需的线程数量来实现。作为在 PyTorch 中使用 Dataset 和 DataLoader 类的示例,请看下面的代码片段,它展示了如何在您的程序中使用 HDF5 数据集。我们将在下一节中研究如何实际实现数据集。

HDF5 数据集类

我设计 HDF5 数据集类时考虑了多个目标:

  1. 使用包含 HDF5 文件的文件夹(包括子文件夹)作为数据源,
  2. 在数据集中维护一个简单的 HDF5 组层次结构,
  3. 启用惰性数据加载(即应数据加载器的请求)为了允许处理不适合存储器的数据集,
  4. 维护数据缓存以加快数据加载过程,以及
  5. 允许数据的自定义转换。

我决定在数据集上实施一个简单的结构,该结构由放置在不同组中的各个数据集组成,如下所示:

这反映了许多机器学习任务的通常数据结构。通常,每个组中都有一个包含数据的数据集,以及一个或多个包含标签的数据集。例如,用于图像分割的数据集可能包括要分割的图像(一个数据集)以及地面实况分割(另一个数据集)。这些标签被放在一个组中,以便确定哪些标签属于哪些数据。此外,可以通过将不同类型的数据放置在不同的 HDF5 文件中来构建更高级别的语义层次(例如,由不同用户执行的分段)。

事不宜迟,下面是实际代码:

如您所见,数据集通过搜索目录(和子目录)中的所有 HDF5 文件进行初始化,并构建一个 data_info 结构,其中包含有关每个数据块的信息,例如它来自哪个文件、它的类型(在本例中为“数据”或“标签”,但您可以定义其他文件)及其形状。形状通常有助于确定数据集的大小,因此它是需要存储的重要信息。此外,对于每个块,我们还存储其数据缓存索引。如果数据当前已加载,则索引≥0,如果尚未加载,则索引为-1。

如果数据加载器现在请求一些数据,则调用 getitem 函数,该函数又调用 get_data 函数。注意,在这里我们不能只索引某个数组,因为我们首先必须确保数据确实在内存中。因此,在 get_data 中,我们查找缓存以找到数据,或者,如果数据不在缓存中,我们加载它并将其返回给调用者。这发生在 _load_data 函数中,该函数做两件事:加载数据并将其添加到缓存中,如果超过了 data_cache_size ,则从缓存中移除随机的数据块。

获得数据后,必须根据您在构造函数中提供的转换对其进行转换,并将其转换为 torch。张量类型。

结论

在这篇文章中,我展示了一个简单但功能强大的 HDF5 数据集类,您可以使用它在 PyTorch 中加载 HDF5 数据集。我希望它对你有用。如果您有任何问题或进一步的建议,请不要犹豫,在下面留言。

HDR 影像:到底什么是 HDR 影像?

原文:https://towardsdatascience.com/hdr-imaging-what-is-an-hdr-image-anyway-bdf05985492c?source=collection_archive---------7-----------------------

关于 HDR 成像的一切。

你可能已经注意到,以太阳(或任何明亮的物体)为背景拍摄图像通常效果不佳。根据焦点的不同,图像不是太暗就是太亮。让我们试着理解为什么会发生这种情况,以及如何解决这个问题。

在我们开始之前,我建议你看看我播客中的一个片段,我们在这里讨论了计算摄影和 HDR 成像的现状。

围绕 HDR 图像的研究有很多关键概念-

  • 动态范围
  • 图像曝光
  • 快门速度、光圈、ISO
  • 图像包围
  • 合并 LDR 图像
  • 图像编码
  • 相机响应功能
  • 线性化
  • 伽马校正
  • 色调映射
  • 可视化 HDR 图像

动态量程

场景的动态范围是指包围场景的光强度的范围。它也可以定义为图像中亮(最大可测量亮度)与暗(最小可测量亮度)的比率。

为了了解亮度如何被量化,光强度的范围是从 0 到无穷大,零是最暗的,无穷大是最亮的光源(☀️)。

Luminance value comparison (Source)

没有相机能够捕捉场景中这种完全无上限的照明范围。因此,图像要么太亮(曝光过度),要么太暗(曝光不足)。这些图像被称为低动态范围 (LDR)图像。对于变得太亮的图像,相机只能捕捉(无限范围的)较亮的子范围,相应地,对于较暗的图像,只能捕捉较低的子范围。

True image (Left), Overexposed image (Center), Underexposed image (Right)

图像曝光:进入相机的光量(以及图像)称为曝光。图像的曝光可以通过相机的三个设置来控制——光圈、快门速度和 ISO。

光圈:相机镜头上光线可以进来的区域。

快门速度:相机快门关闭的速度。随着快门速度的增加,进入相机的光量减少,反之亦然。它还提高了图像的清晰度。

ISO: 相机传感器对入射光的灵敏度。

我在这里找到了这个很好的类比,在相机设置和一个留在雨中的水桶之间。

在摄影中,光圈、快门速度和 ISO 速度的曝光设置类似于上面讨论的宽度、时间和数量。此外,正如上面的降雨率超出了你的控制,自然光对于摄影师来说也是如此。

回到动态范围。从照相机捕获的单个图像不能包含宽范围的光强度。

这个问题可以通过合并在多个曝光值下捕获的图像来解决。这样做的好处是,曝光过度的图像对图像中较暗的区域效果很好,曝光不足的图像能够降低超亮区域的亮度。在不同的曝光值下,图像的不同区域被更好地捕捉。因此,想法是合并这些组图像,并恢复具有高动态范围 (HDR)的图像。

图像包围

包围是指用不同的相机设置捕捉同一场景的多个图像。这通常由照相机自动完成。当你在智能手机上使用 HDR 功能时,手机会在三个不同的曝光时间(或曝光值)快速连续拍摄三张(通常)图像。曝光时间越短,进入的光线就越少。相机软件将这三幅图像合并,并保存为一幅图像,以使每幅图像的最佳部分成为最终图像。

A collage of 5 bracketed images that I found on the internet.

有趣的是,合并后保存在手机上的图像仍然不是(技术上)HDR 图像。这就是图像编码进入画面的地方(还有色调映射,我们将在后面讨论)。

图像编码

通常,我们在手机和电脑上看到的图像是 8 位(每通道)编码的 RGB 图像。每个像素的值使用 24 位表示存储,每个通道(R,G,B)8 位。像素的每个通道都有 0-255 个亮度值。

Example of 24-bit (3x8-bit) encoding for an RGB pixel

这种编码的问题是它不能包含自然场景的大动态范围。它只允许 0–255(仅整数)的范围来适应强度范围,这是不够的。

为了解决这个问题,每个通道都使用 32 位浮点数对 HDR 图像进行编码。这使得我们能够捕捉到大范围的 HDR 图像。书写 HDR 图像有多种格式,最常见的是。所有 hdr 图像都是 32 位编码,但并非所有 32 位图像都可以是 HDR 图像。

相机响应函数

CRF 是显示实际场景辐照度和图像中数字亮度值之间关系的函数。它也被称为光电传递函数。相机公司不提供他们的 CRF,并认为这是专有信息。

Camera response function example

在理想情况下,CRF 应该有一个线性图形,也就是说,图像中像素的亮度值应该与场景中的实际辐照度成正比。这对于 HDR 图像来说是正确的,但是对于通常的图像来说不是这样,在通常的图像中,亮度值被改变以能够将它们包含在有限的范围内。传统图像去线性化的更重要原因取决于显示设备的工作方式。

回到 CRT(阴极射线管)显示器时代,电子是在磷光体表面发射的。众所周知,荧光屏在被加速的电子撞击时会发射光子。然而,显示器的亮度并不随着电子束的强度而线性变化。这个问题已经通过在与显示器的非线性相反的方向上非线性地修改输入的图像/视频源信号而得到解决。通过这样做,我们可以获得自然场景亮度的合理线性估计。

源的这种非线性化允许补偿非线性显示。显示技术已经进步,但是非线性仍然存在于大多数设备中。这种去线性化被称为伽马校正。

伽玛校正图像=图像^ γ

如果输入图像是 x,那么伽马=1.2 的显示设备显示的是 x^(1.2).因此,输入图像被编码为 x^(1/1.2 ),以便监视器将其转换为 x^((1/1.2(×1.2 ),它等于摄像机捕获的原始图像 x。

对于目前的大多数显示器来说,图像必须用 0.45 (1/2.2)的伽马值进行编码,因为显示器的伽马解码为 2.2。

伽马编码在[0,1]的范围内执行。因此,图像首先必须通过除以 255 进行归一化,然后在伽马运算后再次乘以 255。大于 1 的放大率产生较暗的图像,而小于 1 的放大率产生较亮的图像。

Comparison between gamma encoded images

HDR 摄影(或任何摄影)非常复杂,我们需要考虑三个重要方面

  • 实际场景如何(地面实况/无上限动态范围)
  • 相机如何捕捉(包围然后合并)
  • 显示方式(色调映射)

Source

在 HDR 成像的背景下,我们已经讨论了前两点。现在让我们看看 HDR 图像是如何显示的。

色调映射

大多数现成的显示设备不能传送大范围的无上限的 HDR 图像。他们期望输入源为三通道 24 位(3x8) RGB 格式。由于这个原因,宽动态范围需要降低,以便能够适应 RGB 格式的 0–255 范围。这可以通过几种方式实现,其中一些是-

  • 常规线性归一化:这是降低 HDR 图像宽范围的最基本方法。

色调映射图像=(img—img . min()/img . max()—img . min())x 255

  • 赖因哈德色调映射:这是在这篇论文中分享的最常用的色调映射算法之一。

色调映射图像= img/(1+img) x 255

  • Drago 色调映射:这是一个基于感知的色调映射器,它使用对数函数压缩动态范围,“使用场景内容的不同基底计算”。这方面的论文可以在这里找到。

你自找的

Results

生成 HDR 内容的持续研究

生成 HDR 内容的传统方法是通过合并在不同曝光下捕获的多个图像(包围)。然而,当帧之间存在运动时,这种方法可能会产生重影(模糊)假象。这个问题已经解决了,首先使用所谓的光流将相邻帧与参考帧(中间帧)对齐。这可以是另一篇博客文章的主题,但现在我们可以将其视为一种通过将位移向量分配给特定像素位置来估计跨帧发生的对象(或像素)运动的方法。

也有使用深度学习从单一 LDR 对应物生成 HDR 框架的工作。神经网络能够成功地学习输入和输出之间的复杂表示,并且因此在学习 LDR 到 HDR 映射中表现得相当好。这些是从单幅图像生成 HDR 图像的一些最先进的方法—

这里有一些最先进的基于深度学习的方法,用于使用多个 LDR 图像生成 HDR 图像—

[## 论文综述——用于无重影高动态范围成像的注意力引导网络

“你只是想要关注,你不想要我的心”——查理·普斯

towardsdatascience.com](/paper-review-attention-guided-network-for-ghost-free-high-dynamic-range-imaging-4df2ec378e8)

如何查看 HDR 图片

HDR 图像存储为亮度图,而不是传统的 RGB 图像,因此不能使用常见的图像查看应用程序进行查看。

MacOS 允许您查看。hdr 和。使用预览和查找应用程序的 exr 文件。你也可以使用 OpenHDR 网站来可视化这些图像。

感谢阅读。

在以后的博客文章中,我将讨论如何使用 Python、OpenCV 和 Numpy 对 HDR 图像进行操作。我也想分享目前正在进行的 HDR 视频生成的研究。

使用医疗索赔数据进行预测分析的 3 个工具

原文:https://towardsdatascience.com/healthcare-claims-data-for-predictive-analytics-cbffbc19cc5f?source=collection_archive---------8-----------------------

Photo by Adhy Savala on Unsplash

一位高中英语老师告诉我,以“字典对 XYZ 的定义是:”开始一篇论文通常证明是一个没有洞察力的介绍,我担心以“医疗保健有重要的未开发的数据机会”开始这篇文章可能会同样失败。然而,就现有的大量数据而言,很难高估这个领域中未回答和未提出的问题。

除了日益完善的健康状态监控和电子健康记录数据集之外,公共和私有数据集中还有数十亿行医疗保健索赔数据,这些数据通常质量非常高。这篇文章快速介绍了医疗保健索赔数据的工作原理(结构、用途、困难),提出了使用数据的 3 个通用框架。

索赔表上的信息

医疗保健索赔有三种形式:医生、医疗机构和零售药店。每个表单都有许多共同的特征,包括成员身份(姓名、出生日期、保险卡号码等)。)、提供商信息(国家提供商 ID )、税务 ID 号等。),以及服务日期。医生和机构索赔还包含多个描述病情/症状的 ICD-10 诊断代码—机构索赔允许 20 个以上的诊断代码,但实际上 3 个诊断代码包含了两种索赔类型的大部分可用信息。医生和机构声明还包含一个 AMA 服务地点代码,用于描述提供服务的机构类型(即急诊室、紧急护理机构、医生办公室等)。).

3 种索赔类型的独特特征反映了每种类型的提供者如何获得报酬(至少一般来说,从历史上看,像所有医疗保健一样,有细微差别、最近的变化和未来的计划;请始终记住这一点,因为尽可能多地重复这一点会非常乏味。

医生按服务付费——每个程序(检查、抽血、外科手术等)。)有一个美元金额,最终付款是所有这些过程的美元金额的总和。医生报销单使用 CPT 代码列出每项独特的服务。CPT 代码是 5 位字母数字代码,用于描述医生可以执行的每项独特服务,唯一代码分配给相似类型的程序,这些程序对于常见程序具有不同的严重程度。

设施(医院、独立实验室、门诊手术中心等。)相比之下,使用更高级的视图来支付。你可以想象,将住院期间护士在你房间停留的所有时间制成表格会变得很乏味,因此医院会收取“食宿”费用,即躺在病床上所涉及的一切费用。收入代码— 4 位数字(通常包含前导零)—捕获住院期间包含的每项独特的高级服务,如手术室程序、物理治疗、分娩室/分娩等。).此外,使用 ICD10 程序代码捕获特定的重要程序,如移植或动脉旁路,更常见的程序使用医生声明中使用的相同 CPT 代码集。 DRG 代码是在单个代码中总结住院天数的第三个字段。

药店的声明很简单(但通常包含大量的预测信息)——它们只是列出处方药物(使用 NDC 编号)、数量和供应天数。

总之,下面列出了可用的关键字段。在实践中,至少有 3 倍以上的领域在发挥作用,但出于介绍性讨论的目的,这些是大的。

尽管具体情况有所不同,但在数据库构建索赔数据的方式上有着广泛的相似性。通常使用两个事实表——“标题”表存储每个索赔只有一个值的字段,如会员/提供商、服务日期和所有诊断代码,“详细”表存储每个索赔可能有多个值的字段,如 CPT、收入和 NDC 代码。数据库中的附加表格可以提供代码的描述。

虽然索赔数据通常相对干净,但这种结构以及数据所描述的事件和患者特征的临床复杂性需要大量的预处理工作。已经构建了多种方法来平衡在用最少的工作获得易于分析的数据和保存临床复杂性信息的数据之间的权衡。概括地说,有 3 个主要工具:分级条件类别(HCC)编码、事件分组器和基于临床的特征构建。我们将在下面讨论每种方法的优缺点。

工具 1: HCC 车型

HCC 编码是一种广泛使用的技术,尤其是在风险评分算法中。风险评分模型为个人分配一个数字来描述他们的“风险”,这通常意味着预测的索赔成本,但也可以表示临床管理或其他特征的机会。医疗保险优势系统(Medicare Advantage system)、ACA 个人交换(ACA Individual Exchanges)和许多州管理的医疗补助计划(Medicaid programs)使用基于 HCC 的风险调整模型来产生风险评分——尽管具体情况有很大不同,但总体思路是通过量化参加健康计划的个人的相对发病率,相应的收入转移可以确保所有保险公司的公平竞争。

HCC 模型通常通过列举基于 ICD-10 诊断代码和/或药房处方的存在将个体分配到的条件类别来工作。每个类别可以分配一个权重,个人的总得分是类别级别权重的组合。这些模型通常严重依赖个体诊断代码来量化患者的状况,并将可用信息大量总结为 20-50 个类别。他们可以捕捉大量的信息,这些信息可以很容易地快速分析,但是他们也可能遗漏很多信息。例如,高血压或二型糖尿病等疾病如果得到适当的管理,可能不会显著增加风险,但如果不加以管理,可能会导致风险显著增加——简单地量化这些疾病的存在忽略了这一现实。

一种更普遍的分析方式是将其他类型代码的出现(不仅仅是风险评分模型中常用的诊断/药物代码)视为虚拟变量,可能还包括基于频率或时间的变量。这在特征工程中很有帮助,可以快速生成成千上万的组合,并识别与特定分析相关的较小代码集。需要特别注意的是,当许多字段合并在一起时,数据可能会变得非常分散,更高级别的相关性可能会变得模糊不清。例如,无论服务地点或 CPT 代码如何,HIV/AIDS 诊断可能都很重要,但是将该诊断分成几个不同的类别可能会隐藏这一点。

工具 2:事件分组器

事件分组器试图捕捉 HCC 模型中不存在的细微差别,方法是将许多行和字段的数据汇总到由自定义 s 描述的单个事件行中,这种扁平格式可以使跨字段和单独行的数据中的相关性更容易访问。

我查阅的一份 35x19 的索赔数据表可以总结为下面的故事:“患者去了他的医生办公室,在那里对心脏植入装置进行评估。可能在这次访问中提到,患者在同一天去了急诊室。在 8 天的住院期间,患者出现呼吸急促,并接受了胸部 x 光检查和“呼吸服务”作为回应。诊断代码非常准确地告诉我们患者心脏相关状况的范围,以及营养不良的情况”。

大规模地构造这些算法是棘手的,尽管最初如何解决这个问题的想法并不难形成。大规模变得棘手,因为医疗护理是棘手的——相同的程序可以实现不同的结果,相同的诊断可能是低风险或高风险,取决于管理和合并症,诊断可能在短期和长期内有不同的表现,等等。

由于这些的复杂性,有一系列被称为“情节分组器”的商业算法来执行这种总结。这些算法的工作方式有很大的差异,因为提供商、保险公司、公共政策研究人员和其他用户可能都对不同风格的故事线感兴趣。

即使有一个精心设计的事件分组器,您的数据也不容易描述整个患者——捕获频率或时间线信息可能依赖于类似于 HCC 建模地层的技术,但仍然有限。基于临床的模型试图解决这个问题。

工具 3:基于临床的模型

为了充分利用索赔数据(像所有数据一样),大量的领域知识是必要的,但是这里的领域知识通常是通过医学博士教育和多年的临床经验获得的——不是你可以在一个周末自学的那种东西。这一现实在基于临床的模型中尤其明显,这些模型使用临床定义的算法来识别特征。例如,用于识别可能导致住院的心力衰竭患者(因为并非所有心力衰竭都是慢性的)的规则可能具有基于处方的填充组合、具有不同诊断或 DRG 代码的住院、具有特定程序或诊断的多个门诊事件以及上述各项的组合的规则。

这种逻辑在提取难以想到算法方式来全面识别的特征时会非常有帮助。不利的一面是,这种逻辑往往高度专业化,不容易概括患者的一般特征(如 HCC 模型中的“风险”)。

结论

我在这个介绍性讨论中的希望是鼓励在数据科学应用中更广泛地使用医疗索赔数据。CMS 提供了许多基于医疗保险的样本,这些样本可公开用于分析,其中可能隐藏了许多未开发的见解。愿欢乐开始!

心脏病预测

原文:https://towardsdatascience.com/heart-disease-prediction-73468d630cfc?source=collection_archive---------3-----------------------

克里夫兰心脏病(UCI 知识库)数据集——用各种模型分类。

Source

介绍

心脏病描述了一系列影响心脏的疾病。心脏病范围内的疾病包括血管疾病,如冠状动脉疾病、心律问题(心律不齐)和先天性心脏缺陷(先天性心脏缺陷)等。

术语“心脏病”经常与术语“心血管疾病”互换使用。心血管疾病通常是指血管狭窄或阻塞,可能导致心脏病发作、胸痛(心绞痛)或中风。其他心脏疾病,如影响心脏肌肉、瓣膜或节律的疾病,也被视为心脏病的形式。

心脏病是世界人口发病和死亡的最大原因之一。心血管疾病的预测被认为是临床数据分析部分中最重要的课题之一。医疗保健行业的数据量非常庞大。数据挖掘将大量原始医疗保健数据转化为有助于做出明智决策和预测的信息。

根据一篇新闻报道,心脏病被证明是男女死亡的主要原因。该条声明如下:

在美国,每年约有 610,000 人死于心脏病,也就是说,每 4 例死亡中就有一例。1

心脏病是男性和女性死亡的主要原因。2009 年因心脏病死亡的一半以上是男性。1

冠心病(CHD)是最常见的心脏病,每年导致超过 370,000 人死亡。

每年大约有 735,000 名美国人患心脏病。其中,525,000 例是首次心脏病发作,210,000 例发生在已经患有心脏病的人群中。

这使得心脏病成为需要解决的主要问题。但是很难识别心脏病,因为有几个促成的风险因素,如糖尿病、高血压、高胆固醇、异常脉搏率和许多其他因素。由于这些限制,科学家们转向了数据挖掘和机器学习等现代方法来预测疾病。

机器学习(ML)被证明可以有效地从医疗保健行业产生的大量数据中帮助做出决策和预测。

在这篇文章中,我将应用机器学习方法(并最终比较它们)来对一个人是否患有心脏病进行分类,使用最常用的数据集之一—UCI 知识库中的克里夫兰心脏病数据集

和往常一样,您可以在 Github 资源库中找到本文使用的代码。

数据

本文中使用的数据集是来自 UCI 资料库的 Cleveland 心脏病数据集。

Dataset

该数据集由 303 个个体数据组成。数据集中有 14 列,如下所述。

  1. :显示个人的年龄。
  2. 性别 :使用以下格式显示个人的性别:
    1 =男性
    0 =女性
  3. 胸痛类型 :使用以下格式显示个人经历的胸痛类型:
    1 =典型心绞痛
    2 =非典型心绞痛
    3 =非心绞痛疼痛
    4 =渐进性
  4. 静息血压 :显示个人的静息血压值,单位为毫米汞柱(单位)
  5. 血清胆固醇 :显示血清胆固醇,单位为毫克/分升(mg/dl)
  6. 空腹血糖 :将个体的空腹血糖值与 120mg/dl 进行比较。
    如果空腹血糖> 120mg/dl 则:1(真)
    否则:0(假)
  7. 静息心电图 :显示静息心电图结果
    0 =正常
    1 = ST-T 波异常
    2 =左心室肥厚
  8. :显示个人达到的最大心率
  9. 运动诱发的心绞痛 :
    1 =是
    0 =否
  10. 运动相对于休息诱发的 ST 段压低 :显示整数或浮点数。
  11. 峰值运动 ST 段 :
    1 =上坡
    2 =平坡
    3 =下坡
  12. 荧光显示的主要血管数(0-3):显示整数或浮点数。
  13. 地中海贫血 :显示地中海贫血:
    3 =正常
    6 =固定缺陷
    7 =可逆缺陷
  14. 心脏病诊断 :显示个人是否患有心脏病:
    0 =缺席
    1,2,3,4 =出席。

为什么这些参数:

在实际数据集中,我们有 76 个特征,但是在我们的研究中,我们只选择了上面的 14 个,因为:

  1. 年龄:年龄是发展心血管或心脏疾病的最重要的风险因素,生命中的每十年风险大约是三倍。冠状动脉脂肪条纹可以在青春期开始形成。据估计,82%死于冠心病的人年龄在 65 岁及以上。同时,55 岁以后,中风的风险每十年翻一番。
  2. 性别:男性比绝经前的女性患心脏病的风险更大。一旦过了更年期,人们认为女性的风险与男性相似,尽管来自世卫组织和联合国的最新数据对此提出了质疑。如果女性患有糖尿病,她比患有糖尿病的男性更容易患心脏病。
  3. 心绞痛(胸痛):心绞痛是当你的心肌没有获得足够的富氧血液时引起的胸痛或不适。它可能会让你感到胸部有压力或挤压感。不适也可能发生在你的肩膀、手臂、脖子、下巴或背部。心绞痛甚至会感觉像消化不良。
  4. 静息血压:随着时间的推移,高血压会损害为心脏供血的动脉。高血压与其他疾病一起出现,如肥胖、高胆固醇或糖尿病,会增加你的风险。
  5. 血清胆固醇:高水平的低密度脂蛋白(LDL)胆固醇(“坏”胆固醇)最有可能使动脉变窄。高水平的甘油三酯(一种与饮食有关的血脂)也会增加心脏病发作的风险。然而,高水平的高密度脂蛋白(HDL)胆固醇(“好”胆固醇)会降低心脏病发作的风险。
  6. 空腹血糖:胰腺分泌的一种激素(胰岛素)分泌不足或对胰岛素反应不佳,会导致身体血糖水平上升,增加心脏病发作的风险。
  7. 静息心电图:对于心血管疾病低风险人群,USPSTF 有一定把握地得出结论,静息或运动心电图筛查的潜在危害等于或超过潜在益处。对于中高风险人群,目前的证据不足以评估筛查的利弊。
  8. 达到的最大心率:与心率加快相关的心血管风险增加与高血压风险增加相当。已经表明,心率每分钟增加 10 次与心脏死亡风险增加至少 20%相关,并且这种风险增加类似于收缩压增加 10 毫米汞柱所观察到的风险增加。
  9. 运动诱发的心绞痛:与心绞痛相关的疼痛或不适通常感觉紧张、紧握或挤压,可从轻微到严重不等。心绞痛通常在胸部中央感觉到,但可能会蔓延到你的一个或两个肩膀,或你的背部,颈部,下巴或手臂。甚至可以用手感觉到。o 型心绞痛 a .稳定型心绞痛/心绞痛 b .不稳定型心绞痛 c .变异型(Prinzmetal)心绞痛 d .微血管型心绞痛。
  10. 峰值运动 st 段:J 点后 60-80 ms 出现水平或向下倾斜的 ST 段压低≥ 1 mm,则认为平板心电图负荷试验异常。运动心电图上斜 ST 段压低通常被认为是“可疑”试验。一般而言,在较低的工作负荷(以 METs 计算)或心率下出现水平或向下倾斜的 ST 段压低表明预后较差,多支血管疾病的可能性较高。ST 段压低的持续时间也很重要,因为峰值负荷后的恢复时间延长与平板心电图负荷试验阳性相一致。另一个高度提示严重冠心病的发现是 ST 段抬高> 1 mm(通常提示透壁缺血);这些病人经常被紧急转诊进行冠状动脉造影。

方法

这篇文章的代码可以在这里找到。代码用 Python 实现,并应用了不同的分类模型。

在本文中,我将使用以下分类模型进行分类:

  • SVM
  • 朴素贝叶斯
  • 逻辑回归
  • 决策图表
  • 随机森林
  • LightGBM
  • XGboost

数据分析

让我们看看患有或不患有这种疾病的人的年龄。
这里,target = 1 表示此人患有心脏病,target = 0 表示此人没有患病。

我们看到大多数遭受痛苦的人年龄在 58 岁,其次是 57 岁。大多数 50 岁以上的人都患有这种疾病。

接下来,让我们看看每个目标阶层的年龄和性别分布。

我们发现女性患这种疾病的年龄比男性大。

数据预处理

数据集包含 14 列和 303 行。让我们检查空值

null values in each column of the data

我们看到只有 6 个单元格具有空值,其中 4 个属于属性 ca ,2 个属于属性 thal。 由于空值非常少,我们可以删除它们或估算它们。我用平均值代替空值,但是也可以完全删除这些行。

现在让我们划分测试和训练集中的数据。在这个项目中,我将数据分成了 80: 20 的比例。也就是说,训练规模占总数据的 80%,测试规模占总数据的 20%。

培养

应用上面讨论的所有模型来得到结果。

使用的评估标准是混淆矩阵。

confusion matrix

混淆矩阵通过分类器显示正确预测和错误预测的值。来自混淆矩阵的 TP 和 TN 之和是分类器正确分类的条目的数量。

SVM

训练集的 SVM 准确率=((124+100)/(5+13+124+100)) 100 = 92.51%
测试集的 SVM 准确率= 80.32%*

同样,让我们看看每个分类器的所有混淆矩阵。

朴素贝叶斯

逻辑回归

决策图表

随机森林

LightGBM

XGBoost

总而言之,这里是所有分类器的所有精度。

我们看到,通过逻辑回归和 SVM 达到了测试集的最高准确度,其等于 80.32%。
决策树对训练集的最高准确率达到 100%。

这些算法仅使用默认参数实现。

结论

心脏病是当今社会的主要问题之一。

很难根据风险因素人工确定患心脏病的几率。然而,机器学习技术对于从现有数据预测输出是有用的。

TensorFlow 2 |面向黑客的 TensorFlow 中的心脏病预测(下)

原文:https://towardsdatascience.com/heart-disease-prediction-in-tensorflow-2-tensorflow-for-hackers-part-ii-378eef0400ee?source=collection_archive---------6-----------------------

使用 TensorFlow 2 中的神经网络对患者数据中的心脏病进行分类

TL;DR 在 TensorFlow 2 中建立并训练一个深度神经网络用于二进制分类。使用该模型从患者数据中预测心脏病的存在。

机器学习已经被用于解决许多领域的现实问题。医学也不例外。虽然有争议,但已经提出了多种模型并取得了一些成功。谷歌和其他公司的一些著名项目:

今天,我们来看看一个特定的领域——心脏病预测。

在美国,每年约有 61 万人死于心脏病,也就是说,每 4 例死亡中就有一例。心脏病是男性和女性死亡的主要原因。2009 年因心脏病死亡的一半以上是男性。— 心脏病事实&统计| cdc.gov

请注意,此处给出的模型非常有限,并且不适用于现实情况。我们的数据集非常小,这里得出的结论绝不是一般化的。心脏病预测是一个比本文描述的复杂得多的问题。

谷歌合作笔记本中的完整源代码

计划是这样的:

  1. 浏览患者数据
  2. 数据预处理
  3. 在 TensorFlow 2 中创建您的神经网络
  4. 训练模型
  5. 根据患者数据预测心脏病

患者数据

我们的数据来自这个数据集。它包含了 303 份病人记录。每个记录包含 14 个属性。

有多少病历显示有心脏病?

考虑到行数,这看起来是一个分布相当均匀的数据集。

让我们来看看心脏病是如何影响不同性别的:

以下是这些特征之间的皮尔逊相关热图:

thalach(“最大心率”)与age如何影响疾病的存在:

看起来最大心率可以很好地预测疾病的存在,与年龄无关。

不同类型的胸痛如何影响心脏病的存在:

胸痛可能不是心脏病的征兆。

数据预处理

我们的数据混合了分类数据和数字数据。让我们使用 TensorFlow 的功能列

https://www.tensorflow.org/

要素列允许您桥接/处理数据集中的原始数据,以满足模型输入数据的要求。此外,您可以将模型构建过程与数据预处理分离开来。让我们来看看:

除了数字特征,我们将患者age放入离散的范围(桶)。此外,thalsexcpslope是绝对的,我们把它们映射成这样。

接下来,让我们将熊猫数据帧转换成张量流数据集:

并将数据分为训练和测试:

模型

让我们在 TensorFlow 中使用深度神经网络构建一个二元分类器:

我们的模型使用我们在预处理步骤中创建的特性列。请注意,我们不再需要指定输入层的大小。

我们还在两个密集层之间使用了下降层。我们的输出层包含 2 个神经元,因为我们正在构建一个二元分类器。

培养

我们的损失函数是二元交叉熵,定义如下:

其中,y 是二进制指示符,表示预测类别对于当前观察值是否正确,p 是预测概率。

以下是培训过程的一个示例:

Epoch 95/100
0s 42ms/step - loss: 0.3018 - accuracy: 0.8430 - val_loss: 0.4012 - val_accuracy: 0.8689
Epoch 96/100
0s 42ms/step - loss: 0.2882 - accuracy: 0.8547 - val_loss: 0.3436 - val_accuracy: 0.8689
Epoch 97/100
0s 42ms/step - loss: 0.2889 - accuracy: 0.8732 - val_loss: 0.3368 - val_accuracy: 0.8689
Epoch 98/100
0s 42ms/step - loss: 0.2964 - accuracy: 0.8386 - val_loss: 0.3537 - val_accuracy: 0.8770
Epoch 99/100
0s 43ms/step - loss: 0.3062 - accuracy: 0.8282 - val_loss: 0.4110 - val_accuracy: 0.8607
Epoch 100/100
0s 43ms/step - loss: 0.2685 - accuracy: 0.8821 - val_loss: 0.3669 - val_accuracy: 0.8852

测试集的精确度:

0s 24ms/step - loss: 0.3669 - accuracy: 0.8852
[0.3669000566005707, 0.8852459]

所以,我们在测试集上有 ~88% 的准确率。

预测心脏病

现在,我们已经有了一个在测试集上具有一定准确性的模型,让我们尝试基于数据集中的特征来预测心脏病。

因为我们对做出二元决策感兴趣,所以我们采用输出层的最大概率。

 precision recall    f1-score    support

           0       0.59      0.66      0.62        29
           1       0.66      0.59      0.62        32

   micro avg       0.62      0.62      0.62        61
   macro avg       0.62      0.62      0.62        61
weighted avg       0.63      0.62      0.62        61

不考虑精度,可以看到我们模型的精度、召回率、f1-score 都没有那么高。让我们来看看混淆矩阵:

我们的模型看起来有点混乱。你能改进它吗?

结论

谷歌合作笔记本中的完整源代码

你做到了!你使用深度神经网络和 TensorFlow 制作了一个二元分类器,并使用它从患者数据中预测心脏病。

接下来,我们将看看 TensorFlow 2 在应用于计算机视觉时为我们准备了什么。

原载于www.curiousily.com

黑暗之心:逻辑回归与随机森林

原文:https://towardsdatascience.com/heart-of-darkness-logistic-regression-vs-random-forest-1db7b0aa1711?source=collection_archive---------10-----------------------

从 Lambda 学校开始学习数据科学已经 9 周了。本周的挑战涉及一个多类分类问题,以卡格竞赛的形式呈现,只涉及我们班的学生:DS-1。

我们的任务是结合数字和分类变量来预测坦桑尼亚的哪些水泵有故障:

坦桑尼亚水点挑战:

目标变量:'状态 _ 组'

  1. 功能的

2.功能需求修复

3.无功能

特征变量

数字 :

身份证明(identification)

金额 _tsh

日期 _ 记录

gps _ 高度

经度

纬度

区域代码

建造年份

建造年份

人口

:

投资者

安装程序

wpt_name

数量 _ 私有

盆地

子村

地区

大于胎龄儿

病房

公开会议

录制者

方案 _ 管理

方案名称

许可证

提取类型

提取类型组

提取类型类

管理

管理 _ 集团

支付

付款类型

水质

质量 _ 组

数量 _ 组

来源

来源类型

来源 _ 类别

水点类型

水点类型组

如果有读者想接受挑战,你可以在这里找到所有相关数据:

  1. 训练集

2.培训标签

3.测试设置

训练集有 59400 行和 40 列——在数据科学世界中,这是一个相对较小的数据集,但对于初学者来说仍然是相当大的(在维度方面)。

让我们启动 Jupyter 笔记本并加载数据:

*# Our usual trio of importsimport numpy as np
import pandas as pd
import matplotlib.pyplot as plt
%matplotlib inlinedf_train = pd.read_csv('train_features.csv')
df_test = pd.read_csv('test_features.csv')
train_labels = pd.read_csv('train_labels.csv')df_train.head()*

作为 Kaggle 挑战赛的参赛者,需要记住和做的最重要的事情之一是清理包括训练集和测试集在内的数据集。主要流程如下:

  1. 使用我们的一个奇怪的技巧连接训练集和测试集。
  2. 清理数据:丢弃 NaNs、插值、创建新变量等。
  3. 拆分训练集和测试集
  4. 在训练集上训练你选择的机器学习模型
  5. 对您之前分离出来的测试集进行预测

现在我们的一招:

*df_train['training_set'] = True
df_test['training_set'] = Falsedf_full = pd.concat([df_train, df_test])df_full.shape*

组合数据集(df_full)应该有 73758 行和 41 列,其中包括我们刚刚创建的“training_set”列。我们这样做的原因是为了确保模型被训练的数据在形式中与测试集相同。否则,如果测试集在某些方面与训练集不同,例如逻辑的系数就没有意义,更不用说预测了。由于很难跟踪我们对训练集所做的一切,我们不妨一石二鸟,从而保证它们的相同性质。

我将在这个集合上使用逻辑回归和随机森林分类器,但在此之前,我们还需要考虑其他一些事情。

我并不惊讶…

内特·迪亚兹

有时生活给你正确的彩票号码,有时给你柠檬。但是当生活感觉像虐待狂时,它会给你坦桑尼亚水点挑战。让这一挑战变得格外严峻的是不平衡的数据:

*train_labels['status_group'].value_counts(normalize=True)*

*import seaborn as snsfig, ax = plt.subplots(figsize=(14, 8))
sns.countplot(x='status_group', data=train_labels, palette='hls')*

目标变量的“功能性需求修复”类别仅占整个集合的 7%左右。这意味着无论你最终使用什么算法,它都可能比这个算法更好地学习其他两个平衡类。这就是数据科学:斗争是真实的。

回到正题

meme sponsored by fakedoors.com

我们要做的第一件事是为 waterpoints 创建一个“年龄”变量,因为这似乎非常相关。

*df_full['date_recorded'] = pd.to_datetime(df_full['date_recorded'])df_full['date_recorded'] = df_full['date_recorded'].dt.year# Replacing the NaN value with the mode - this would turn out to be 
# less effective than I thoughtdf_full['construction_year'] = df_full['construction_year'].replace(0, 1986)df_full['age'] = np.abs(df_full['date_recorded'] - df_full['construction_year'])# We now have an 'age' column indicating the age of the waterpoint #relative to its 'construction_year'*

“人口”变量也具有高度右偏的分布,因此我们也要改变这种情况:

*df_full['population'] = df_full['population'].replace(0, 1)
df_full['population_logged'] = np.log(df_full['population'])*

“amount_tsh”中的零也可能是 NaNs,因此我们将做一些极端的事情,将其简化为 0 和 1:

*amount_tsh_encoded = []for row in df_full['amount_tsh']:
    if row == 0:
        amount_tsh_encoded.append(0)
    else:
        amount_tsh_encoded.append(1)

df_full['amount_tsh_encoded'] = amount_tsh_encoded# And drop the old variables:df_full.drop(['date_recorded', 'construction_year', 'population',
             'amount_tsh', 'num_private'], axis=1, inplace=True)*

此时,您可以只分离出 df_full 数据帧的数字特征,并通过以下方式对其运行分类器:

*df_full_num = df_full.select_dtypes(include=['number']).copy()*

我们从上周学到的最重要的一点,也是让我记忆犹新的一点,就是尽可能快地提出一个基线模型的想法。我们需要某种参考点来迭代我们的模型性能。因此,对于像我们这样的分类问题,我们可以使用我们的主要类别“功能”作为我们的基线。

重要的是要记住,只有当机器学习模型能够在预测方面击败多数分类器时,它才能开始提供优于人类学习的好处。

如果我们在 df_full_num 上运行逻辑回归,我们应该得到大约 54%的准确率,这是多数类给我们的。

此时对我来说最重要的是不要气馁。

接下来,我们将只研究分类变量。对于大多数分类特征,我们将采取极端简化的步骤,将它们转换成二进制变量。因为它们中的许多包含一个占主导地位的类别,其余的只占总数的一小部分…本质上是一种长尾分布。

*df_full['funder'] = df_full['funder'].fillna(df_full['funder'].mode()[0])
df_full['subvillage'] = df_full['subvillage'].fillna(df_full['subvillage'].mode()[0])
df_full['public_meeting'] = df_full['public_meeting'].fillna(df_full['public_meeting'].mode()[0])
df_full['permit'].fillna(df_full['permit'].describe().top, inplace=True)*

简化分类变量的例子:

*funder_cleaned = []for row in df_full['funder']:
    if row == 'Government Of Tanzania':
        funder_cleaned.append('Tanzania')
    else:
        funder_cleaned.append('Other')

df_full['funder_cleaned'] = funder_cleaned*

我们对几乎每一个分类特征都做同样的事情。

*installer_cleaned = []for row in df_full['installer']:
    if row == 'DWE':
        installer_cleaned.append('DWE')
    else:
        installer_cleaned.append('Other')

df_full['installer_cleaned'] = installer_cleanedscheme_management_cleaned = []for row in df_full['scheme_management']:
    if row == 'VWC':
        scheme_management_cleaned.append('VWC')
    else:
        scheme_management_cleaned.append('Other')

df_full['scheme_management_cleaned'] = scheme_management_cleanedextraction_type_cleaned = []for row in df_full['extraction_type']:
    if row == 'gravity':
        extraction_type_cleaned.append('gravity')
    else:
        extraction_type_cleaned.append('other')

df_full['extraction_type_cleaned'] = extraction_type_cleanedmanagement_cleaned = []for row in df_full['management']:
    if row == 'vwc':
        management_cleaned.append('vwc')
    else:
        management_cleaned.append('other')

df_full['management_cleaned'] = management_cleanedmanagement_group_cleaned = []for row in df_full['management_group']:
    if row == 'user-group':
        management_group_cleaned.append('user-group')
    else:
        management_group_cleaned.append('other')

df_full['management_group_cleaned'] = management_group_cleanedpayment_cleaned = []for row in df_full['payment']:
    if row == 'never pay':
        payment_cleaned.append('never pay')
    else:
        payment_cleaned.append('other')

df_full['payment_cleaned'] = payment_cleaned # I'm going to skip the other variables for the sake of staying #awake*

在这个漫长过程的最后,我们必须放弃我们的旧变量:

*drop_list = ['wpt_name', 'basin', 'subvillage', 'funder',
             'installer', 'scheme_management', 'permit', 'public_meeting',
             'lga', 'ward', 'recorded_by', 'region', 'scheme_name', 'extraction_type',
             'extraction_type_group', 'extraction_type_class', 'management',
             'management_group','payment', 'payment_type', 'water_quality',
             'quality_group', 'quantity', 'quantity_group','source', 'source_class',
             'source_type', 'waterpoint_type', 'waterpoint_type_group']df_full.drop(drop_list, axis=1, inplace=True)*

现在我们可以把它们变成虚拟变量。虽然大多数其他人可能会选择使用某种类别编码器,但这些变量不是有序的——这意味着,例如,重力的“提取类型”和其他类型的提取之间没有内在的可测量的距离。虽然它可能不会在预测方面产生很大的差异,但我相信如果我们出于分析原因使用逻辑回归,它会产生很大的差异。换句话说,从序数拟合中学习到的系数可能是不同的。

我们用熊猫做假人:

*dummy_columns=['funder_cleaned', 'installer_cleaned', 'scheme_management_cleaned', 'extraction_type_cleaned',
        'management_cleaned', 'management_group_cleaned', 'payment_cleaned', 'water_quality_cleaned',
        'quality_group_cleaned', 'quantity_cleaned', 'source_cleaned', 'source_class_cleaned',
        'waterpoint_type_cleaned']print("Original Features:\n", list(df_full.columns), "\n")
df_full_dummies = pd.get_dummies(df_full, columns=dummy_columns)
print("Features after get_dummies: \n", list(df_full_dummies.columns))*

既然已经对数据进行了预处理,让我们使用之前创建的“training_set”布尔列来分离训练集和测试集。然后,我们可以在训练集上训练模型,并在测试集上进行预测。

*df_train = df_full_dummies[df_full_dummies['training_set'] == True]df_train = df_train.drop('training_set', axis=1)df_test = df_full_dummies[df_full_dummies['training_set'] == False]df_test = df_test.drop('training_set', axis=1)*

在这一点上我感觉很好。我觉得很有成就感。我觉得自己像终结者。事实上,我想走到杂货店里的某个陌生人面前,问他:

Globo Gym wins again

在所有这些工作之后,我只能取得大约 10%的进步:

*from sklearn.linear_model import LogisticRegression
from sklearn.model_selection import train_test_split
from sklearn.model_selection import cross_val_scoreX = df_train.drop(['id', 'status_group'], axis=1)
y = df_train['status_group']X_train, X_test, y_train, y_test = train_test_split(X, y, random_state=42)lr = LogisticRegression(C=100).fit(X_train, y_train)
scores = cross_val_score(lr, X, y, cv=5) # Cross-validating the model on the whole datasety_pred = lr.predict(X_test)print("CV scores: {}".format(scores))
print("CV scores mean: {}".format(scores.mean()))CV scores: [0.66315967 0.65970878 0.66271044 0.67020202 0.66635797]
CV scores mean: 0.6644277752104382*

然而,随机森林分类器做得更好,这是我最终用来对测试集进行预测的:

*from sklearn.ensemble import RandomForestClassifier
from sklearn.model_selection import train_test_split
from sklearn.model_selection import cross_val_scoreX = df_train.drop(['id', 'status_group'], axis=1)
y = df_train['status_group']X_train, X_test, y_train, y_test = train_test_split(X, y, random_state=42)rf = RandomForestClassifier(n_estimators=100, min_samples_leaf=3).fit(X_train, y_train)
scores = cross_val_score(rf, X, y, cv=5)scores = [0.78444575 0.78318323 0.78265993 0.7787037  0.7797609 ]*

Kaggle 竞赛需要记住的另一件事是,您的提交材料必须采用正确的格式:

*X_test = df_test.drop('id', axis=1)final_preds = rf.predict(X_test)kaggle_baseline_submission_7 = pd.DataFrame({'id': df_test.id, 'status_group': final_preds})kaggle_baseline_submission_7.head()*

现在你知道了。通过一些工作,我能够在数据上训练两个分类器,对变量进行特征工程,进行预测并提交准确性评分。然而,对整个过程有一种根深蒂固的不满(因此有了过于戏剧性的“黑暗之心”的标题)。

虽然随机森林在预测什么可能是错误的水点方面比逻辑回归“更好”,但我们仍然没有比我们在机器学习模型之前开始的时候更好地理解这个人为问题。

例如,我们可以找出拟合的随机森林模型的特征重要性,并将其绘制如下:

*plt.style.use('seaborn')
#fig, ax = plt.subplot(figsize=(12, 8))
feats = {}
for feature, importance in zip(feature_names, rf.feature_importances_):
    feats[feature] = importance

importances = pd.DataFrame.from_dict(feats, orient='index').rename(columns={0: 'Gini-importance'})importances.sort_values(by='Gini-importance').plot(kind='bar', rot=90, figsize=(20, 20))*

但是这些特征的重要性并不一定被解释为有助于做出预测或者允许我们分析问题。这些特征的重要性只在模型中是重要的,因为它们是如何对作为一个整体的决策树的决策起作用的。如果我们观察这个图,绝对没有理由相信错误的供水点的问题与“经度”和“纬度”有任何关系。

此外,我仍然坚信,如果我们以正确的方式对数据进行特征设计,逻辑回归仍然是更好预测的关键。

然而,逻辑回归的可取之处在于,它允许我们查看系数,并计算出它们实际上如何影响功能和非功能水点:

*Red = Non-Functional
Blue = Functional
Green = Functional Needs Repair*

上面的图是通过训练一个模型得到的,该模型具有一组修改过的标签,这些标签仅由两类组成:功能性和非功能性,而不是三类。我用这种方法来解决不平衡数据的问题。此外,特征 coord_cluster_1、coord_cluster_2 和 coor_cluster_3 是通过用 n=3 的 KMeans 聚类拟合纬度和经度数字来创建的,以便尝试提取某种更有意义的信息:

*# extract the longitude and latitude values
long_lat = df_full[['longitude', 'latitude']].valuesfrom sklearn.cluster import KMeanskmeans = KMeans(n_clusters=3)
kmeans.fit(long_lat)print("cluster memberships:\n{}".format(kmeans.labels_[:25]))coord_cluster = kmeans.labels_
df_full['coord_cluster'] = coord_cluster*

输出:

*cluster memberships:
[2 0 0 2 0 2 0 0 0 0 2 2 0 0 0 2 2 2 0 2 2 1 2 0 0]*

虽然 k 均值聚类确实提供了比之前的逻辑回归中的纬度或经度更多的信息,但它仍然没有产生足够的信息来制作顶部系数。

功能用水点相对于非功能用水点的前四大影响因素:

*1\. waterpoint_type: **handpump**
2\. water_source: **spring**
3\. quantity: **enough**
4\. extraction_type: **gravity***

这些系数的重要之处在于,它们几乎与专家在非洲讨论这个问题时所说的完全一致。

例如,供水点故障的一个根本原因是社区缺乏修理供水点故障的机制。从设计上来说,手泵比许多其他类型的供水点更简单,并且不需要机械的持续维护。因此,手泵抽取类型在模型中具有单一的最高系数。同样的事情也可以说是关于引力的提取。因为它们不需要电动泵之类的东西,所以显然需要更少的维护。另一个看似显而易见的解释变量是水量:水量越大,我们就越有可能拥有一个正常运作的供水点。

总之,尽管我没有赢得 Kaggle 挑战赛,尽管随机森林表现得更好,但我仍然相信,解决这类问题的合适的机器学习算法是逻辑回归。逻辑回归给了我们随机森林永远无法提供的东西:对企业和政府管理人员的解释,他们可以回头尝试实施解决方案。

吸取教训:

  1. 寻求帮助:在 Lambda,我们有一个 20 分钟的规则,如果我们自己仍然不能解决问题,我们会寻求帮助。我打破了这个规则,决定耍流氓,并为此付出了大量浪费时间清理没有任何有价值信息的数据。
  2. 数据科学是我做过的最难的事情之一。虽然结果可能令人沮丧,但大多数情况下,这是一个通过实践和失败反复学习的过程。我很高兴能成为 Lambda 学校的一员。

你可以在这里找到 Jupyter 笔记本版本。

使用 Python 绘制谷歌支付的热图

原文:https://towardsdatascience.com/heat-map-your-google-payments-with-python-54ed110854d?source=collection_archive---------9-----------------------

感谢您对本文的关注。我已经把它转移到我的个人博客 Lenny ' s Quest:https://lennys . Quest/heat-map-your-Google-payments-with-python

语音识别中的 Hello World

原文:https://towardsdatascience.com/hello-world-in-speech-recognition-b2f43b6c5871?source=collection_archive---------14-----------------------

Tensorflow 中的端到端 ASR 分解

本博客将帮助您使用 Tensorflow 编写一个基本的端到端 ASR 系统。我将检查一个最小的神经网络和一个前缀束搜索解码器的每个组件,它需要从音频生成一个可读的抄本。我遇到了很多关于围绕计算机视觉和自然语言处理任务构建基本机器学习系统的资源,但在语音识别方面却很少。这是一个尝试,以填补这一空白,并使这一领域不那么令人生畏的初学者。

先决条件

熟悉:

  • 神经网络的组件
  • 训练神经网络
  • 使用语言模型获得单词序列的概率

概述

  • 音频预处理:将原始音频转换成数字特征,作为神经网络的输入
  • 神经网络:一个简单的架构,用于将音频特征转换成抄本中可能字符的概率分布
  • CTC 损失:计算损失,而不用相应的字符标注音频的每个时间步长
  • 解码:使用前缀束搜索和语言模型从每个时间步长的概率分布创建抄本

我将重点介绍神经网络、CTC 损失和解码部分。

音频预处理

你需要把你的音频转换成一个特征矩阵,然后输入到你的神经网络中。一个简单的方法是创建光谱图。

这个函数计算音频信号的短时傅立叶变换,然后计算功率谱。输出是一个称为声谱图的矩阵。你可以直接用这个作为你的输入。其他替代方法是滤波器组和 MFCCs。音频预处理本身就是一个完整的话题。你可以在这里详细了解

神经网络

这是一个简单的架构。

Hello World Architecture for Speech Recognition

谱图输入可以被认为是每个时间戳的向量。1D 卷积层从这些向量中提取特征,给你一个特征向量序列,供 LSTM 层处理。对于每个时间步长,(双)LSTM 层的输出被传递到完全连接的层,该层使用 softmax 激活给出该时间步长的角色的概率分布。该网络将用 CTC(连接主义时间分类)损失函数进行训练。在了解整个管道之后,可以随意试验更复杂的模型。

为什么选择 CTC?该网络试图预测每个时间步的字符。然而,我们的标签并不是每个时间步的字符,而只是音频的转录。请记住,转录中的每个字符可能跨越多个时间步长。如果你以某种方式标记音频中的每个时间步长,单词 C-A-T 会被理解为 C-C-C-A-A-T-T。每 10 毫秒注释一次音频数据集是不可行的。CTC 解决了这个问题,因为它不需要我们标记每个时间步长。它将上述神经网络的整个输出概率矩阵和相应的文本作为输入,忽略抄本中每个字符的位置和实际偏移量。

CTC 损失计算

Example of the output matrix

假设地面真相标签是猫。在这四个时间步中,像 C-C-A-T,C-A-A-T,C-A-T-T,-C-A-T,C-A-T- 这样的序列都对应于我们的基本真理。我们将通过对所有这些序列的概率求和来计算我们的地面真实的概率。根据输出概率矩阵,通过乘以其字符的概率来计算单个序列的概率。对于上述序列,总概率为 0.0288+0.0144+0.0036+0.0576+0.0012 = 0.1056。损失是这个概率的负对数。损失函数已经在 TensorFlow 中实现。你可以在这里阅读文件

解码

你从上面的神经网络得到的输出就是 CTC 矩阵。CTC 矩阵给出了每个时间步中字符集中每个字符的概率。我们使用前缀束搜索从这个矩阵中产生有意义的文本。

CTC 矩阵中的字符集除了字母和空格字符之外,还有两个特殊的符号。这些是空白标记和字符串结束标记。

空白令牌的用途:CTC 矩阵中的时间步长通常很小。(~10 毫秒)所以口语句子的每个字符跨越多个时间步长。例如,C-A-T 变成了 C-C-C-A-A-T-T。因此,我们折叠了在 CTC 矩阵中突出的所有可能的候选字符串。像搞笑这种 N 应该重复的词呢?两个 Ns 之间的空白标记防止它们折叠成一个,而不在文本中添加任何内容。所以,F-F-U-N-[blank]-N-N - Y 崩成滑稽。

End-token 的用途: End-of-string 表示口语句子的结尾。在字符串结束标记之后的时间步长解码不会向候选字符串添加任何内容。

程序:

初始化:

  • 我们最初有一份候选人名单。它由一个空白字符串组成。该列表还包含在每个时间步中以空白标记结束和以非空白标记结束的候选的概率。空白字符串在时间 0 以空白标记结尾的概率是 1。以非空标记结尾的概率为 0。

迭代次数:

  • 我们把这个字符串一个接一个地加上每个字符。我们获取形成的每个扩展字符串,并计算其在时间=1 时以空白和非空白标记结束的概率。然后,我们将这些扩展字符串和它们的概率一起存储在我们的列表中。我们把这些新的候选人放入我们的列表,并在下一个时间步重复这个过程。
  • 案例 A: 如果添加的字符是一个空白标记,我们不改变候选字符。
  • 案例 B: 如果添加的字符是一个空格,我们按照语言模型用一个与候选概率成比例的数乘以概率。这可以防止不正确的拼写成为最佳候选。所以酷在最终输出中不会被拼写成 KUL。
  • 情况 C: 如果添加的字符与候选字符的最后一个字符相同。(候选人=好玩。我们创建了两个新的候选人,FUNN 和 FUN。乐趣的概率是根据以空白代币结束的乐趣的概率来计算的。FUNN 的概率是使用非空令牌中 FUN 结束的概率来计算的。因此,如果乐趣不以空白令牌结束,我们就丢弃额外的 N,而不是追加它。

输出: 所有时间步长后的最佳候选就是输出。

我们做了两处修改来加快这个过程。

  1. 在每个时间步长之后,我们丢弃除了最佳 K 个候选项之外的所有候选项。候选项按其以空白和非空白标记结尾的概率总和排序。
  2. 我们不考虑在矩阵中概率低于某个阈值(~0.001)的字符。

查看下面的代码,了解实现细节。

这就完成了一个基本的语音识别系统。你可以引入一些复杂的东西来获得更好的输出。更大的网络和音频预处理技巧很有帮助。这里是完整的代码

备注:
1。上面的代码使用 TensorFlow 2.0,样本音频文件取自 LibriSpeech 数据集。
2。您需要编写自己的批处理发生器来训练音频数据集。这些实现细节不包括在代码中。
3。您将需要为解码部分编写自己的语言模型函数。最简单的实现之一是基于一些文本语料库创建二元模型及其概率的字典。

参考文献:
【1】a . y . Hannun 等人,前缀搜索解码 (2014),arXiv 预印本 arXiv:1408.2873,2014
【2】a . Graves 等人, CTC 丢失 (2006),ICML 2006
【3】l . Borgholt,前缀波束搜索 (2018),中

你好,世界…组装起来不容易

原文:https://towardsdatascience.com/hello-world-not-so-easy-in-assembly-23da6644ff0d?source=collection_archive---------12-----------------------

介绍

在这篇博文中,我将介绍一个汇编语言的 Hello World 程序(RISC 风格的 Nios II 架构)。虽然我不会详细介绍 Nios II 体系结构的含义,但有一点很重要,即为了运行 Hello World 程序,需要支持 Nios II 体系结构的计算机主板或模拟器。我在这里推荐使用模拟器找到

其他语言的 Hello World

Hello World 通常是新程序员编写的第一个程序,因为它非常简单。我将用 C、Ruby、JavaScript 和 Java 演示 Hello World 程序,以强调这个程序的简单性。

C 语言的 Hello World

Figure 1: Hello World in C

Ruby 的 Hello World

Figure 2: Hello World in Ruby

JavaScript 中的 Hello World

Figure 3: Hello World in JavaScript

Java 的 Hello World

Figure 4: Hello World in Java

组装中的 Hello World

在我揭开 Hello World 的组装版之前,我必须给你一个警告,它相当长,很吓人,但我会在之后尽我所能解释一切。事不宜迟,我们一直在等待的时刻到了,你好,世界在集合:

是的,我知道,这看起来很吓人。希望你还没有点击关闭博客。在图 5 中,第 1–5 行是初始化常数。例如,第一行将 LAST_RAM_WORD 设置为 0x007FFFFC,这是一个十六进制的内存位置。第 8 行允许链接器知道程序从哪里开始。在这种情况下,程序从第 11 行开始。第 9 行让汇编程序知道下一行的内存位置。在图 5 中,第 9 行告诉汇编器 _start:位于 0x00000000 位置。

现在,我将解释 _start:标签中发生的事情,从图 5 中的第 11 行开始。_start:内的第一行,第 12 行,将 LAST_RAM_WORD 的值移动到堆栈指针(sp)。该行实际上启动了 sp 以包含存储器地址 0x007FFFFC。下面一行将' \n '或下一行字符移入寄存器 2,它是 CPU 上的一个内部寄存器。第 14 行调用 PrintChar。这意味着程序将从第 20 行开始执行 PrintChar: label 后面的代码。为了简单起见,从现在开始我将把 _start:,_end:,PrintChar:和 PrintString:称为函数或例程,即使它们是标签。

PrintChar:函数负责将字符打印到屏幕上。为了澄清,这个程序实际上打印新的行字符,后跟 hello world 字符串。我选择插入新行字符的原因是为了在解释 PrintString: function 之前解释 PrintChar: function,print string:function 只是多次调用 PrintChar: function。为了解释这个功能,我将定义字可寻址存储器。一个可以被认为是一个可以存储信息的记忆单元。在 Nios II 架构中,一个字是 4 字节或 32 位。这个 PrintChar:函数从 sp 中减去 8 个字节开始,实质上为两个字生成了空间。第 22 和 23 行将寄存器三和四的当前值存储到生成的空间中。这一点很重要,因为 CPU 包含的可用寄存器数量有限,所以存储这些寄存器的值允许函数使用这些寄存器,并在函数完成时恢复它们的值。第 24 行将寄存器 3 的值设置为 0x10001000,这是输入/输出位置。第 25 行是一个标签(pc_loop:)。在定义了接下来的三行之后,这个标签的相关性将变得显而易见。第 26 行将输入/输出位置的状态载入寄存器 4。第 27 行对寄存器 4 的值的高位和 WSPACE_MASK (0xFFFF)进行逻辑与运算,然后将结果存储在寄存器 4 中。第 28 行中的“beq”代表“分支等于”本质上,如果寄存器 4 的值等于寄存器 0 的值,第 28 行使程序循环回到“pc_loop”标签(第 25 行)。澄清一下,寄存器 0 是一个特殊的寄存器,它的值总是为零。第 25 到 28 行代表了一个高级语言中的 while 循环。while 循环使程序等待,直到输出设备准备好打印字符。第 29 行将寄存器 2 的内容输出到控制台。换句话说,第 29 行是负责让字母出现在屏幕上的行。第 30 行和第 31 行将寄存器三和四的值恢复为进入 PrintChar:函数之前的值。值恢复后,堆栈指针(sp)不再需要存储数据,因此第 32 行向堆栈指针添加 8 个字节,以将 sp 返回到其原始状态。最后,在第 33 行点击“ret”后,程序返回到调用 PrintChar 后的那一行或第 15 行。

一旦我们返回到第 15 行,register 就获得了我们要打印的字符串的地址,“Hello World\n”。然后,在第 16 行,调用 PrintString:方法。为了保持简洁,这个方法遍历字符串,将每个字母发送给 PrintChar:方法。所以最初,“Hello World\n”中的“H”被发送给 PrintChar:方法。然后,将“e”发送给 PrintChar:方法。这个过程(循环)将继续,直到“\n”字符。

在 PrintString:例程终止时,程序返回到第 17 行,或者 _end:标签。然后,在第 18 行,程序无限次分支回到第 17 行,这实质上导致程序终止,因为它陷入了无限循环。

对于任何想知道的人,第 54 和 55 行让程序知道“Hello World\n”字符串从内存位置 0x1000 开始。

结论

汇编是一种非常有趣的语言,学习起来要困难得多,因为它需要你所使用的硬件知识。如前所述,这个汇编程序是用 RISC 风格的 Nios II 架构(汇编的一个版本)编写的。Hello World 程序在汇编中比任何高级编程语言都难,因为它要求程序员完全定义程序,例如指定内存位置。此外,在汇编语言中,程序员必须指定屏幕上显示的内容和时间,这就是程序循环遍历字符串并一次打印一个字符的原因。然而,汇编允许程序员通过利用硬件特性来优化程序和算法,否则这是不可能的。

帮助读者重构 Python 网页抓取。

原文:https://towardsdatascience.com/helping-a-reader-with-python-web-scraping-refactored-c14d609134a3?source=collection_archive---------33-----------------------

来自印度的微生物学家 Bhargava Reddy Morampalli 从我的旧博客上读到了我的第一篇关于网络抓取的文章。如果你没有机会看到这篇文章,你可以在这里阅读。

[## Python 网络抓取重构

我在旧博客上的第一篇文章是关于一个网络抓取的例子。网络抓取是运用 API 之外的一种手段…

towardsdatascience.com](/python-web-scraping-refactored-5834dda39a65)

他在阅读了我的帖子后联系了我,请求我帮助他实现基于我在这个网站上的文章的网络抓取。在这里,我将像我们在上面的文章中所做的那样重构 Bhargava 的例子。我认为这是有用的,因为不是所有的网站都有相同的结构。

Made with imgflip.com

  • 注意:由于网站改变了布局(或者员工可能会改变),您得到的结果可能会有所不同。最终结果截至 2019 年 8 月 21 日。对于那些阅读我的这篇文章的原始版本的人来说,站点结构已经改变,所以这里的代码会略有不同。*

我们要废弃的网站。

该网站也是一个列出学术机构员工的页面。请务必看一看它,看看网站是如何构建的。在这里,Bhargava 想要从每个教授那里删除以下信息。

  1. 名字
  2. 指定
  3. 电子邮件
  4. 资格
  5. 出版物的数量

和上一篇文章一样,我将遵循同样的步骤,这样你就可以加强对这个过程的理解(如果你需要的话)。

导入我们的图书馆和网站。

正如我们之前所做的,我们将导入相同的库,并让我们的web_page被请求拉入。

研究 HTML 并做初步的废弃。

接下来,我们将调查 HTML,看看我们的教授藏在哪里。同样,如果您右键单击站点并选择“查看页面源代码”来查看 HTML 代码。然后,我们将使用 ctrl-f 搜索我们的第一位教授 Pramod Kumar T M .博士。

Found our first Professor…deep in HTML tags…

所以我们找到了他。但问题是我们如何得到他的名字和其他信息。如果您进一步探究,您会发现教授们被包含在tab-pane active in fade div 类标签中。因此,为了从废弃中获得我们的结果,我们将首先使用 div 类提取所有标签。

我们还将检查结果的数量,以确保我们得到正确的数量。你应该得到 17 个结果。

让我们看看从哪里获得我们的数据!

我们将使用第一个结果来研究从哪里获得我们的信息。然后我们将应用列表理解来创建我们的pandas数据框架。如果你检查结果0,我们会得到一吨的 HTML。浏览时,您应该会发现以下内容:

<div class="col-sm-9">
<h2>Dr Pramod Kumar T M</h2>
<p>
<strong>Designation:</strong> Principal<br/>
<strong>Email Id:</strong> 
pramodkumar@jssuni.edu.in<br/>
<strong>Qualification:</strong> 
B. Pharma, M.Pharma, Ph.D.<br/>
<strong>No of Publication:</strong> 121
</p>
</div>

同样,我们希望获得每位教授的姓名、头衔、电子邮件、资格和发表的论文数量。再次尝试自己确定哪些标签包含了我们需要的所有信息。然后继续读下去,看看你是否正确。

Image from BDDroppings.

名称:在<h2>标签之间。

剩下的四个项目:这有点棘手。你可能会认为我们的一些信息包含在<strong>标签中。但是如果你试着用find函数运行你的代码,并把“强”作为参数,你会发现这不是一个成功的方法。具体来说,它将返回第一对具有字符串“Designation:”的强标签,这不是我们想要的……另外,<br>标签对我们没有帮助,因为它们没有包含任何信息。

再看一下这一步中的 HTML 代码。我重新安排了它,这样你就可以看到有一个标签正确地包含了我们想要的所有信息。你看到了吗?

Image made at imgflip.com

那是<p>的标记。让我们转到测试代码,看看如何从<p>标签中检索信息。

用第一份侧写测试我们的报废。

用第一个条目创建我们的test_result,上面是检索该条目所有信息的代码。

注意,为了检索最后四条信息,我们使用了 BeautifulSoup4 函数.find(‘p’).contents

如果您运行test_result.find(‘p’).contents,您将看到以下内容:

[<strong>Designation:</strong>,
 ' Principal',
 <br/>,
 <strong>Email Id:</strong>,
 ' pramodkumar@jssuni.edu.in',
 <br/>,
 <strong>Qualification:</strong>,
 ' B. Pharma, M.Pharma, Ph.D.',
 <br/>,
 <strong>No of Publication:</strong>,
 ' 121']

我们得到的回报是我们的<p>标签之间的所有字符串和标签作为上面列表的元素!这样,我们就可以将每个所需项目的索引附加到我们的代码行中以获得它们。具体来说:

名称:索引 1

电子邮件:索引 4

资格:指标 7

出版数量:指数 10(或者指数 1,取决于你想怎么做)

当您提取信息时,您可能会注意到在返回的字符串的开头有额外的空格(您也可以在上面的列表中看到)。这种额外的间距会对您将来的数据准备产生负面影响。在数据框中搜索字符串数据时,Python 对此非常敏感。额外的间距会导致您丢失一些您需要的项目,从而产生错误的总数或平均值。从而使你的分析不准确。为了处理这个问题,我们附加了strip方法来删除字符串开头(和结尾,你知道,只是以防万一)的多余空格。

正如 Bhargava 希望我说的,我们希望对所有条目都这样做,不管它们的总数是多少。因此,现在我们将初始化一个pandas数据帧,并应用列表理解来生成列。

提取数据并创建数据框。

正如我们上次所做的,我们将为每一列数据创建列表理解。对于出版物的数量,我们必须创建一个特殊的函数,因为有些教授没有任何出版物。它们的默认值为 0。最后,我们将把收集的数据导出到一个 CSV 文件中。

了解我们的数据概况。

我们可以单独创建图表来分析我们拥有的新数据。但是最近有了一种新的更快的方法来获得我们数据的概观。那是一个叫做熊猫简介的新包装。查看文档,快速开始使用这个非常方便的工具。

最后的想法

这就结束了我们的第二轮网络搜集。对于扩展,我们可以查看这所大学的其他系,并删除他们的信息。菜单上列出的与我们的网页格式相同。我们可以用同样的方式导入所有的网页(当然是使用函数),然后创建另一个函数来整理脚本。还有额外的信息,如教授的工作历史和他们的教育,这也可能是有趣的探索,看看是否有重叠的背景。这也将为 NLP 实践提供机会。

如果您想了解更多关于请求beautifulsoup4 库的信息,请点击它们名称上的链接查看它们的文档。

感谢

我很高兴 Bhargava 读了我的第一篇博客文章,并安慰地向我寻求帮助,帮助他尝试网络抓取。他确实寻求帮助的事实表明,如果你不怕问,你可以找到你需要的信息,而且我们生活在世界的不同一边。

犯错误和不知道事情是生活的一部分。正是从提问和经验(有时是网上搜索)中学习让我们成长。在我自己抓取了网页之后,我让 Bhargava 查看完整的代码或者提供提示(通过 LinkedIn)。他选择了后者,这样他可以获得经验和成长。

Image from mindgasms.theblogpress.com

花点时间感谢 Bhargava,无论是在下面的评论中,在他的 LinkedIn 上,还是在 T2 的 Twitter 上。

直到下一次,

约翰·德杰苏斯

以下是比特币获得其价值的方式

原文:https://towardsdatascience.com/heres-how-bitcoin-gets-its-value-a1f09dba0735?source=collection_archive---------2-----------------------

为什么比特币毫无意义,以及对其未来的猜测

Image courtesy of the author

大约在 1661 年瑞典发行第一张欧洲纸币的 700 年前,中国曾为如何减轻随身携带铜币的人的负担而绞尽脑汁。这些硬币使生活变得困难:它很重,而且会使旅行变得危险。随后,商人们决定将这些硬币存放在一起,为硬币的价值发行纸质凭证

私人发行导致通货膨胀和货币贬值:政府随后介入,发行他们自己的由黄金储备支持的纸币,可以说是成为了世界上第一种法定货币。

在过去的几个世纪里,各国开始采用“金本位制”,用金银等商品铸造一定重量的硬币。这代表了一定数量的价值,直到硬币被篡改,这导致了代表性货币的兴起。

银行发行“黄金券”——一张分母为 50 的纸币意味着你可以用这张纸币兑换价值 50 美元的黄金。

然后,在 1944 年,布雷顿森林体系决定,出席会议的 44 个国家将保持他们的货币与美元挂钩,因为美元有黄金储备支持。这实质上意味着美元可以随时兑换成黄金。

这实质上意味着美元可以随时兑换成黄金。

这种方法效果不错,但时间不长。不断增长的公共债务、通货膨胀和国际收支逆差意味着美元面临更大的压力。作为回应,一些欧洲国家甚至退出该体系,用美元兑换黄金。那时,他们储备中的美元比黄金还多。

这种情况在 1971 年发生了变化,当时美国前总统理查德·尼克松(Richard Nixon)关闭了黄金窗口:外国政府持有太多美元,美国很容易挤兑黄金。他们与其他 15 名顾问一起宣布了新的经济计划,以避免通货膨胀,降低失业率,并将美元转化为法定货币——本质上依赖于货币使用者的同意,而不是商品和标准。

因此,你指望政党是否会接受你的货币,这完全是出于信任。

比特币也是如此,这种加密货币一度创下 19783.06 美元的历史新高。是什么赋予了比特币价值?声称它是通过供求来实现的似乎并没有涵盖整个画面:它没有任何东西作为后盾,也没有任何人来控制。

至少,你可以依靠合法的管理机构来维持一种货币的价值。

比特币被创造出来时就带有菲亚特的特征。然而,在治理意义上,没有人“拥有”比特币。它的运作方式似乎也与菲亚特现金相同,但本质上不同的生态系统让经济学家和金融专家思考:到底是谁给了它价格?

class CInputCoin {
public:    
CInputCoin(const CTransactionRef& tx, unsigned int i) {        
if (!tx)            
throw std::invalid_argument("tx should not be null");

你现在看到的是比特币中百万行代码的五行。最初只有几千行代码,比特币是由中本聪在 2008 年开发的,并于 2009 年初发布。中本聪在著名的白皮书中详述了比特币的概念,该白皮书题为比特币:一种点对点电子现金系统。

最初的设想是创造一种不需要通过金融机构的现金形式,因为它具有加密的性质。

最大的创新是它对区块链技术的利用。每个区块代表比特币网络中的一次交易——区块越多,时间越长。因此,它形成了一个“链”,因此得名。

为了让一个区块出现,矿工需要使用原始的计算机处理能力和大量的电力来验证人 A 和人 B 之间存在 X 值和 Y 时间的交易。当它得到确认,块出现,交易通过。矿工会得到比特币作为奖励。

然而,这种数字货币没有内在价值,不能作为商品使用。比特币的怀疑者通常会说,要让它可行,它必须首先被接受并用于其他商品用途。慢慢地,随着时间的推移,它会变成钱。例如,人们囤积黄金来储存价值,因为黄金被用于珠宝和电子产品。

在奥地利经济学家卡尔·门格尔的一部开创性著作中,他开始将货币描述为“某些商品成为普遍接受的交换媒介的事实”。同为经济学家的路德维希·冯·米塞斯在门格尔的工作基础上,将商品货币归因于“同时是一种商业商品”的货币。法定货币是由“具有特殊法律资格的东西”组成的货币。

“……法定货币的名称是由具有特殊法律资格的事物组成的货币……”—路德维希·冯·米塞斯,《货币与信用理论》

内在价值的观念在人类中一直存在:甚至亚里斯多德也写过为什么钱需要是内在有用的。从本质上说,无论是什么货币,它的价值都必须来自于它本身的有用性。这一论点不攻自破,因为历史表明,任何东西要成为货币都不需要商品价值。

在非洲和北美的部分地区,玻璃珠被用于货币目的,尽管事实证明它们作为商品几乎没有什么用处。太平洋上的雅浦人使用石灰石硬币作为货币。

比特币怀疑论者经常使用内在价值论点来谴责比特币的生存能力。不幸的是,比特币是一种纯粹的数字存在,因此它不受物理世界的限制。它不需要像黄金一样具有内在价值,也不需要其他人授予的特殊权利才能成为法定货币。虽然这看起来像是一种解释——比特币是一种不受人类规则约束的全新实体——但它仍然没有完全说得通。

可以这么想:比特币和菲亚特都是不同的金融生态系统。

法币属于物理世界,因此会带来其他货币约束。权力掌握在控制货币的人手中,央行总是可以印更多的钞票来推动通货膨胀和流通。然而,没有人能告诉你到底有多少实物美元在世界上流通。

黄金供应有限,但可能会受到通货膨胀的影响。如果有人在当前供应之外发现了大量黄金,所有权可能会被彻底稀释。材料科学的创新也可能减少电子产品和消费产品对黄金的需求。

比特币的数字本质需要新的理论基础。经济学家早就意识到贵金属和法币的约束。因此,比特币的引入催生了一套新的规则,被许多人戏称为暴发户金融生态系统。

问题在于,法定货币和加密货币生态系统无法真正共存,比特币最大化主义者会告诉你这一点。由于比特币没有作为金融工具、投资产品或证券的内在价值,因此最大的赌注是让它成为一种全球货币。

今天,全球货币供应量( M1 ),达到7.6 万亿美元。如果加上支票存款、短期债券、定期存款和其他金融工具,总额高达 90 万亿美元。要成为一种全球货币,比特币需要至少相当于全球货币供应量的——事实并非如此,因为在撰写本文时,比特币的市值仅为 1300 亿美元。

然而,迅速增长的主权债务和外债可能会刺激投资者开始寻找比黄金更容易获得和替代的通货再膨胀对冲工具。这可能会推高比特币的估值,因为它具有价值储存的效用。为了对抗通货膨胀,许多人满足于在他们的投资组合中持有美元、欧元或日元——阿根廷人和委内瑞拉人用相对稳定的美元做到了这一点。

要成为一种全球货币,比特币需要至少相当于全球货币供应量,但事实并非如此,因为在撰写本文时,比特币的市值仅为 1300 亿美元。

这可能赋予它实用价值:比特币可以充当价值储存手段。

让我们把它看作一种资产。如果是,那么比特币本质上是反通胀的。为了刺激网络增长,区块链每创造一个新街区,就铸造 50 个新比特币。每 21 万块后奖励减半(现在每块给 12.5,2020 年 5 月 14 日减半至 6.25)。除了供应上限为 2100 万比特币的内在稀缺性,难怪人们和金融机构会将比特币视为硬通货。

这意味着内在的货币政策正在推动比特币的购买力——但决定其价格的是什么?

如果你看看古典经济学派,你可以认为比特币的价格是由其生产成本决定的。这意味着硬件和电力。随着比特币继续经历通货紧缩,矿工的数量将逐渐减少,因为开采成本太高。尽管如此,仍有矿商愿意亏本经营,这可能表明,有人在对冲比特币未来再次上涨的风险:价格不仅仅取决于生产成本,尽管这是一个因素。

新古典经济学派扩展了这一理论,增加了另一个客观因素:供给和需求。由于比特币的供应有上限,被开采的比特币数量将随着时间的推移而减少,对更多比特币的需求可能会上升。更多的需求意味着更高的价格。

仅仅依靠客观因素似乎也不能描绘出全貌。如果生产成本是一个主要原因,那么比特币的价值应该接近美国广义货币供应量(M3)的水平。

尽管如此,矿工们还是无所适从,尽管开采比特币的成本更高。

如果需求和供应的平衡很重要,那么比特币的明确规定和经审计的供应上限应该会决定持续的需求。然而,比特币仍然容易出现极端波动,有可能在同一天内暴跌和暴涨。

进入奥地利经济学院,这里的比特币支持者非常喜欢。奥地利经济学家认为,任何东西的价格都是由主观因素决定的,甚至是生产成本。供需由个人喜好决定。因此,它可以解释比特币的价值——感知价值和主观因素在这里可能是一个更大的因素。

可以看出,没有明确的解释为什么加密货币——甚至是货币——有价值。在这种情况下,比特币的价格似乎是由经典经济模型、情绪和内在货币政策共同驱动的。

然而,无论采用何种经济理论,加密货币仍将引发一场金融革命。如果它能演变成另一种形式的全球货币,世界金融生态系统将被颠覆(是好是坏,我们不得而知)。

最终,比特币是金融实验的发射台。利用区块链技术引领了 2016 年至 2017 年的加密货币热潮,这带来了区块链创新的全新世界。今天,我们正在研究实际稳定的加密货币,它们可以保持 1 美元的稳定价格,使用资产挂钩和储备银行概念的组合。

与其把比特币看作一种货币形式,不如把它看作一种支付系统。

因此,比特币的真正价值在于它的网络。参与的人越多越好。本质上,这意味着比特币的价值取决于谁拥有它。如今,随着比特币的普及(不是为了日常使用,而是为了投资和交易),越来越多好奇的人开始加入这项新技术。这意味着更多的分配。

然而,为了让比特币真正按照预期的方式发挥作用,它需要通过转向利益证明(PoS)系统来摆脱矿工和采矿池。比特币的工作证明系统使交易变得异常昂贵——矿工们正在燃烧数百万美元,以利用电力和原始计算机处理能力来验证网络上的比特币交易。有了 PoS 系统,比特币将因其网络而被估价。大多数利益相关者将放弃他们的一部分股份,以允许网络增长,从而相应地增加他们的股份。

这听起来很简单,但如今大多数比特币都是由中国矿工开采的。例如,如果它能取代美国的广义货币供应,那么政府有什么理由采用一种由来自一个对立超级大国的矿商控制的全球货币呢?

如果超级大国不愿意,为什么小国会跟随?全球货币目标似乎是一个白日梦,但最终,比特币是否会起作用将取决于你从谁那里听到它,就像它从哪里获得价值一样。

以下是 Apache Flink 如何存储您的状态数据

原文:https://towardsdatascience.com/heres-how-flink-stores-your-state-7b37fbb60e1a?source=collection_archive---------8-----------------------

Photo by Samuel Zeller on Unsplash

Apache Flink 的一个重要特性是它能够进行有状态处理。存储和检索状态数据的 API 很简单,这使得它很容易使用。

然而,在 API 的背后是一个管理数据的系统,同时提供持久性保证,这就是我们将在本文中理解的。

我们将会看到国家管理的三个部分——

  1. 状态后端
  2. 数据格式
  3. 持久性和故障恢复

让我们首先看看状态实际存储在哪里。

我的数据存储在哪里?

Flink 为您的状态提供了三个现成的后端存储。这些是

  1. 内存状态后端
  2. 文件系统(FS)状态后端
  3. RocksDB 状态后端

内存状态后端

这种存储将数据保存在每个任务管理器堆的内存中。因此,这使得它的访问速度极快。尽管有这样的性能,但这种状态永远不应该在生产作业中使用。这是因为状态会在作业管理器内存中创建数据备份(也称为检查点),这给作业管理器的操作稳定性带来了不必要的压力。

这个后端的另一个限制是任务的总状态大小不能超过 10MB。可以将其配置为更高的限制,但出于性能考虑,作者不建议这样做。

这是 Flink 在没有配置任何东西的情况下使用的默认后端。

文件系统后端

这个后端类似于内存状态后端,只是它将备份存储在文件系统上,而不是作业管理器内存中。文件系统可以是任务管理器的本地文件系统或持久存储,如 HDFS/S3。

这种状态也受到堆内存的限制,因此应该在数据较少并且需要高性能的情况下使用。

RocksDB 后端

这个后端使用脸书的 RocksDB 来存储数据。如果您不知道 RocksDB,那么它是一个提供 ACID 保证的可嵌入键值存储。它基于谷歌的 LevelDB,但提供了更好的写性能。

Flink 选择使用 RocksDB,而不是一些最流行的嵌入式存储,如 SQLlite,因为它的高写入性能来自基于 LSM 架构的设计。
由于 RocksDB 还维护着一个内存表(也称为 mem-table)和 bloom filters,读取最近的数据也非常快。

每个任务管理器维护它自己的 Rocks DB 文件,并且这个状态的备份被检查点设置到一个持久存储,比如 HDFS。

这是唯一支持增量检查点的后端,即只备份修改过的数据,而不是完整的数据。

如果您的应用程序需要存储一个大的州,这应该是您的选择。但是,因为它需要磁盘访问和序列化/反序列化,所以它比其他后端要慢。

这个国家实际上是什么样子的?

让我们看看在应用程序中创建状态后,数据实际上是如何存储的。

存储格式因后端而异。但是,常见的部分是状态的键和值都存储在使用 Flink 自己的类型序列化程序创建的字节数组中。

我们将使用 RocksDB 后端进行演示。

每个任务管理器都有多个 RocksDB 文件夹,每个文件夹本身就是一个数据库。每个数据库包含由状态描述符中给出的名称定义的多个列族。

每个列族都包含键-值对,其中键是操作符的键,值是状态数据。

举个例子。让我们看看这个示例作业的状态

该作业包含两个状态函数,定义如下

如果运行此作业,并在 flink-conf.yml 文件中将 Rocksdb 设置为 state backend,则在每个任务管理器上都将生成以下目录。

drwxr-xr-x   4 abc  74715970   128B Sep 23 03:19 job_127b2b84f80b368b8edfe02b2762d10d_op_KeyedProcessOperator_0d49016af99997646695a030f69aa7ee__1_1__uuid_65b50444-5857-4940-9f8c-77326cc79279/dbdrwxr-xr-x   4 abc  74715970   128B Sep 23 03:20 job_127b2b84f80b368b8edfe02b2762d10d_op_StreamFlatMap_11f49afc24b1cce91c7169b1e5140284__1_1__uuid_19b333d3-3278-4e51-93c8-ac6c3608507c/db

下面是目录名的定义方式

这些名称由三部分组成

  1. JOB_ID: 创建作业图表时分配给作业的随机 ID。
  2. OPERATOR_ID :这是 OPERATOR 的基类、operator uid 的 Murmur3 Hash、任务的索引和任务的整体并行度的组合。例如,对于我们的 StatefulMapTest 函数,这 4 个部分结果是
  • 河流平面图
  • mur mur 3 _ 128(" stateful _ map _ test ")-> 11f 49 AFC 24 B1 CCE 91 c 7169 B1 e 5140284
  • 1,因为在并行度为 1 的作业中只能有一个任务,因此任务索引为 1
  • 1,因为我在执行作业时将并行度设置为 1
  1. UUID :这只是创建目录时随机生成的 UUID。

每个目录都包含一个 RocksDB 实例。RocksDB 的文件结构将是

-rw-r--r--  1 abc  74715970    21K Sep 23 03:20 000011.sst
-rw-r--r--  1 abc  74715970    21K Sep 23 03:20 000012.sst
-rw-r--r--  1 abc  74715970     0B Sep 23 03:36 000015.log
-rw-r--r--  1 abc  74715970    16B Sep 23 03:36 CURRENT
-rw-r--r--  1 abc  74715970    33B Sep 23 03:18 IDENTITY
-rw-r--r--  1 abc  74715970     0B Sep 23 03:33 LOCK
-rw-r--r--  1 abc  74715970    34K Sep 23 03:36 LOG
-rw-r--r--  1 abc  74715970   339B Sep 23 03:36 MANIFEST-000014
-rw-r--r--  1 abc  74715970    10K Sep 23 03:36 OPTIONS-000017

的。sst 文件是包含实际数据的 Rocksdb 的 SSTable 文件。
日志文件包含提交日志。
清单包含元数据,如列族。
选项包含用于创建 RocksDB 实例的配置。

让我们使用 RocksDB java API 打开这个 DB。我们将看一下 StatefulMapTest 函数目录。

以下代码打印数据库中存在的所有列族名称。上面这段代码的输出结果是

default
previousInt
nextInt

我们还可以打印每个列族中的所有键值对。这可以使用下面的代码来完成

在我们的例子中,它将打印出键值对,如
(testing123,1423),(testing456,1212)等。

这里的 TestInputView 只是 Flink 特定的构造,用于读取字节数组数据流。

我需要备份数据吗?

Flink 使用一种称为检查点的机制为应用程序状态提供持久性。它定期拍摄状态快照,然后将其存储在持久性存储中,如 HDFS/S3。这允许 Flink 应用程序在出现故障时从该备份中恢复。

默认情况下,对 Flink 作业禁用检查点。要启用它,您可以将以下代码添加到您的应用程序中

这将配置您的应用程序每 60 秒拍摄一次状态快照,并将其放入作业管理器/HDFS/S3 以备将来恢复。在 HDFS/S3 的情况下,可以用 flink-conf.yml 中的 state.checkpoints.dir 配置用于存储检查点的目录

检查点的最终目录结构如下所示

hdfs:///path/to/state.checkpoints.dir/{JOB_ID}/chk-{CHECKPOINT_ID}/

JOB_ID 是应用程序的唯一 ID,检查点 ID 是自动递增的数字 ID。

要在应用程序启动时从检查点恢复状态,只需运行

flink-1.9.0/bin/flink run -s hdfs:///path/to/state.checkpoints.dir/{JOB_ID}/chk-{CHECKPOINT_ID}/ path/to//your/jar

您可以使用检查点函数来扩展有状态函数,该函数提供了在初始化和拍摄快照时修改状态的能力。可以扩展前面的 StatefulProcess 函数来使用这个接口。

这就完成了我们对 Flink 状态的深入研究,现在您可以确信您的状态被应用程序很好地保存了。

如果你想开始使用状态处理 Apache Flink,这里有一些到官方文档的有用链接

  1. 工作状态
  2. 州后端
  3. 状态处理器 API

以下是如何使用 CuPy 让 Numpy 快 10 倍以上

原文:https://towardsdatascience.com/heres-how-to-use-cupy-to-make-numpy-700x-faster-4b920dda1f56?source=collection_archive---------1-----------------------

是时候来点 GPU 的威力了!

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

Numpy 是 Python 社区的一份礼物。它允许数据科学家、机器学习从业者和统计学家以简单高效的方式处理矩阵格式的大量数据。

即使就其本身而言,Numpy 在速度上已经比 Python 有了很大的进步。每当您发现您的 Python 代码运行缓慢时,尤其是如果您看到许多 for 循环,将数据处理转移到 Numpy 并让其矢量化以最高速度完成工作总是一个好主意!

尽管如此,即使有这样的加速,Numpy 也只是在 CPU 上运行。由于消费类 CPU 通常只有 8 个内核或更少,因此并行处理的数量以及所能实现的加速是有限的。

这就是我们的新朋友 CuPy 的切入点!

什么是 CuPy?

CuPy 是一个通过利用 CUDA GPU 库在 Nvidia GPUs 上实现 Numpy 阵列的库。通过这种实现,由于 GPU 拥有许多 CUDA 核心,可以实现卓越的并行加速。

CuPy 的界面是 Numpy 的一面镜子,在大多数情况下,它可以作为一个直接的替代品。只需将 Numpy 代码替换为兼容的 CuPy 代码,就可以实现 GPU 加速。CuPy 将支持 Numpy 拥有的大多数数组操作,包括索引、广播、数组数学和各种矩阵转换。

如果你有一些特定的还不被支持的东西,你也可以写定制的 Python 代码来利用 CUDA 和 GPU 加速。所需要的只是一小段 C++格式的代码,CuPy 会自动进行 GPU 转换,非常类似于使用 Cython

要开始使用 CuPy,我们可以通过 pip 安装库:

pip install cupy

使用 CuPy 在 GPU 上运行

对于这些基准测试,我将使用具有以下设置的 PC:

  • i7–8700k CPU
  • 1080 Ti GPU
  • 32 GB DDR 4 3000 MHz 内存
  • CUDA 9.0

一旦安装了 CuPy,我们可以像导入 Numpy 一样导入它:

*import* numpy *as* np
*import* cupy *as* cp
*import* time

对于其余的代码,在 Numpy 和 CuPy 之间切换就像用 CuPy 的cp替换 Numpy 的np一样简单。下面的代码为 Numpy 和 CuPy 创建了一个包含 10 亿个 1 的 3D 数组。为了测量创建数组的速度,我使用了 Python 的本地time库:

### Numpy and CPU
s = time.time()
**x_cpu = np.ones((1000,1000,1000))**
e = time.time()
print(e - s)### CuPy and GPU
s = time.time()
**x_gpu = cp.ones((1000,1000,1000))
cp.cuda.Stream.null.synchronize()**
e = time.time()
print(e - s)

那很容易!

注意我们是如何在 cupy 数组初始化之后添加额外的一行的。这样做是为了确保我们的代码在进入下一行之前在 GPU 上完成执行。

令人难以置信的是,尽管这只是创建数组,但 CuPy 的速度还是快得多。Numpy 在 1.68 秒内创建了 10 亿个 1 的数组,而 CuPy 只用了 0.16 秒;这是 10.5 倍的加速!

但是我们仍然可以做得更多。

让我们试着在数组上做一些数学运算。这次我们将整个数组乘以 5,并再次检查 Numpy 与 CuPy 的速度。

### Numpy and CPU
s = time.time()
**x_cpu *= 5**
e = time.time()
print(e - s)### CuPy and GPU
s = time.time()
**x_gpu *= 5
cp.cuda.Stream.null.synchronize()** e = time.time()
print(e - s)

在这种情况下,CuPy 撕碎 Numpy。Numpy 拿了 0.5845 而 CuPy 只拿了
0.0575;这是 10.17 倍的加速!

现在,让我们尝试使用多个数组并进行一些操作。下面的代码将完成以下工作:

  1. 将数组乘以 5
  2. 将数组本身相乘
  3. 将数组添加到自身
### Numpy and CPU
s = time.time()
**x_cpu *= 5
x_cpu *= x_cpu
x_cpu += x_cpu**
e = time.time()
print(e - s)### CuPy and GPU
s = time.time()
**x_gpu *= 5
x_gpu *= x_gpu
x_gpu += x_gpu
cp.cuda.Stream.null.synchronize()** e = time.time()
print(e - s)

在这种情况下,Numpy 在 CPU 上执行过程用了 1.49 秒,而 CuPy 在 GPU 上执行过程用了 0.0922 秒;一个更适度但仍然很棒的 16.16 倍加速!

总是超级快吗?

使用 CuPy 是将 GPU 上的 Numpy 和 matrix 运算加速许多倍的好方法。值得注意的是,您将获得的加速在很大程度上取决于您正在使用的阵列的大小。下表显示了我们改变正在处理的数组大小时的速度差异:

当我们达到大约 1000 万个数据点时,速度会急剧加快,当我们超过 1 亿个数据点时,速度会快得多。低于这个,Numpy 其实更快。此外,请记住,更多的 GPU 内存将帮助您处理更多的数据,所以重要的是要看看您的 GPU 是否有足够的内存来容纳足够的数据。

喜欢学习?

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

以下是如何在 GPU 上加速数据科学的方法

原文:https://towardsdatascience.com/heres-how-you-can-accelerate-your-data-science-on-gpu-4ecf99db3430?source=collection_archive---------6-----------------------

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

数据科学家需要计算能力。无论你是用 Pandas 处理一个大数据集,还是用 Numpy 在一个大规模矩阵上运行一些计算,你都需要一台强大的机器来在合理的时间内完成工作。

在过去几年中,数据科学家通常使用的 Python 库在利用 CPU 能力方面已经变得相当不错。

Pandas 的底层代码是用 C 语言编写的,它在处理超过 100GB 的数据集方面做得很好。如果您没有足够的内存来容纳这样的数据集,您可以使用方便的分块功能,一次处理一部分数据。

GPU 与 CPU:并行处理

对于海量数据,一个 CPU 是无法处理的。

一个超过 100GB 的数据集将会有很多很多的数据点,大概在百万甚至十亿的范围内。有这么多的点要处理,无论你的 CPU 有多快,它都没有足够的内核来进行高效的并行处理。如果您的 CPU 有 20 个内核(这将是相当昂贵的 CPU),您一次只能处理 20 个数据点!

CPU 在时钟速度更重要的任务中会更好——或者你根本没有 GPU 实现。如果你正在尝试执行的进程有一个 GPU 实现,那么如果这个任务可以从并行处理中受益,那么 GPU 将会更加有效。

How a Multi-core system can process data faster. For a single core system (left), all 10 tasks go to a single node. For the dual-core system (right), each node takes on 5 tasks, thereby doubling the processing speed

深度学习已经看到了利用 GPU 的公平份额。深度学习中的许多卷积运算都是重复的,因此可以在 GPU 上大大加速,甚至高达数百倍。

今天的数据科学没有什么不同,因为许多重复操作都是通过 Pandas、Numpy 和 Scikit-Learn 等库在大型数据集上执行的。这些操作在 GPU 上实现起来也不会太复杂。

终于有解决办法了。

GPU 加速与急流

Rapids 是一套软件库,旨在利用 GPU 加速数据科学。它使用低级别的 CUDA 代码来实现快速的 GPU 优化算法,同时仍然拥有一个易于使用的 Python 层。

Rapids 的美妙之处在于它可以与数据科学库顺利集成——像 Pandas 数据帧这样的东西很容易通过 Rapids 进行 GPU 加速。下图说明了 Rapids 如何实现低级别加速,同时保持易于使用的顶层。

Rapids 利用了几个 Python 库:

  • cuDF—Python GPU data frames。在数据处理和操作方面,它几乎可以做熊猫能做的一切。
  • cuML — Python GPU 机器学习。它包含许多 Scikit-Learn 拥有的 ML 算法,格式都非常相似。
  • cuGraph—Python GPU 图形处理。它包含许多常见的图形分析算法,包括 PageRank 和各种相似性度量。

如何使用 Rapids 的教程

装置

现在你将看到如何使用急流!

要安装它,前往网站,在那里你会看到如何安装 Rapids。您可以通过 Conda 将它直接安装在您的机器上,或者只需拉动 Docker 容器。

安装时,您可以设置您的系统规格,如 CUDA 版本和您想要安装的库。例如,我有 CUDA 10.0,想安装所有的库,所以我的安装命令是:

conda install -c nvidia -c rapidsai -c numba -c conda-forge -c pytorch -c defaults cudf=0.8 cuml=0.8 cugraph=0.8 python=3.6 cudatoolkit=10.0

一旦该命令运行完毕,您就可以开始进行 GPU 加速的数据科学了。

设置我们的数据

对于本教程,我们将经历一个修改版本的 DBSCAN 演示。我将使用 Nvidia 数据科学工作站来运行 2 个 GPU 附带的测试。

DBSCAN 是一种基于密度的聚类算法,可以自动对数据组进行分类,而无需用户指定有多少组。在 Scikit-Learn 中有它的一个实现。

我们将从获取所有导入设置开始。用于加载数据、可视化数据和应用 ML 模型的库。

import os
import matplotlib.pyplot as plt
from matplotlib.colors import ListedColormap
from sklearn.datasets import make_circles

make_circles 函数将自动创建一个复杂的数据分布,类似于我们将应用 DBSCAN 的两个圆。

让我们从创建 100,000 个点的数据集开始,并在图中显示它:

X, y = make_circles(n_samples=int(1e5), factor=.35, noise=.05)
X[:, 0] = 3*X[:, 0]
X[:, 1] = 3*X[:, 1]
plt.scatter(X[:, 0], X[:, 1])
plt.show()

CPU 上的数据库扫描

使用 Scikit-Learn 在 CPU 上运行 DBSCAN 很容易。我们将导入我们的算法并设置一些参数。

from sklearn.cluster import DBSCANdb = DBSCAN(eps=0.6, min_samples=2)

现在,我们可以通过调用 Scikit-Learn 中的一个函数对 circle 数据应用 DBSCAN。在我们的函数前加一个%%time告诉 Jupyter Notebook 测量它的运行时间。

%%timey_db = db.fit_predict(X)

对于这 100,000 个点,运行时间是 8.31 秒。结果图如下所示。

Result of running DBSCAN on the CPU using Scikit-Learn

GPU 上带 Rapids 的 DBSCAN

现在让我们用急流让事情变得更快!

首先,我们将把数据转换成一个pandas.DataFrame,并用它来创建一个cudf.DataFrame。Pandas 数据帧无缝转换为 cuDF 数据帧,数据格式没有任何变化。

import pandas as pd
import cudfX_df = pd.DataFrame({'fea%d'%i: X[:, i] for i in range(X.shape[1])})
X_gpu = cudf.DataFrame.from_pandas(X_df)

然后我们将从 cuML 导入并初始化一个特殊版本的 DBSCAN,一个 GPU 加速的版本。DBSCAN 的 cuML 版本的函数格式与 Scikit-Learn 的完全相同——相同的参数,相同的风格,相同的函数。

from cuml import DBSCAN as cumlDBSCANdb_gpu = cumlDBSCAN(eps=0.6, min_samples=2)

最后,我们可以在测量运行时间的同时为 GPU DBSCAN 运行我们的预测函数。

%%timey_db_gpu = db_gpu.fit_predict(X_gpu)

GPU 版本的运行时间为 4.22 秒,几乎是 2 倍的加速。因为我们使用相同的算法,所以结果图也与 CPU 版本完全相同。

Result of running DBSCAN on the GPU using cuML

借助 Rapids GPU 获得超快速度

我们从 Rapids 获得的加速量取决于我们处理的数据量。一个很好的经验法则是,较大的数据集将受益于 GPU 加速。在 CPU 和 GPU 之间传输数据会产生一些开销时间,对于较大的数据集,这些开销时间变得更加“值得”。

我们可以用一个简单的例子来说明这一点。

我们将创建一个 Numpy 随机数数组,并对其应用 DBSCAN。我们将比较我们的常规 CPU DBSCAN 和 cuML 的 GPU 版本的速度,同时增加和减少数据点的数量,以查看它如何影响我们的运行时间。

下面的代码演示了这个测试:

import numpy as npn_rows, n_cols = 10000, 100
X = np.random.rand(n_rows, n_cols)
print(X.shape)X_df = pd.DataFrame({'fea%d'%i: X[:, i] for i in range(X.shape[1])})
X_gpu = cudf.DataFrame.from_pandas(X_df)db = DBSCAN(eps=3, min_samples=2)
db_gpu = cumlDBSCAN(eps=3, min_samples=2)%%time
y_db = db.fit_predict(X)%%time
y_db_gpu = db_gpu.fit_predict(X_gpu)

查看下面 Matplotlib 的结果图:

当使用 GPU 而不是 CPU 时,数量会急剧增加。即使在 10,000 点(最左边),我们仍然获得了 4.54 倍的加速。在更高端的情况下,10,000,000 点在切换到 GPU 时,我们获得了 88.04 倍的加速!

喜欢学习?

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

下面是你如何用 Numba 在你的 Python 代码上获得一些免费的速度

原文:https://towardsdatascience.com/heres-how-you-can-get-some-free-speed-on-your-python-code-with-numba-89fdc8249ef3?source=collection_archive---------9-----------------------

轻松将您的 Python 代码转换成快速机器码

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

“我们不能用 Python,太慢了。”

任何使用 Python 足够长时间的人可能都曾听过这样的说法。

说这话的人也没有错。相对于很多其他编程语言,Python 基准游戏有一些比较各种编程语言在不同任务上速度的坚实基准。

解决这个速度问题的一个常见方法是用 C++之类的更快的语言重新编写代码,然后在上面添加一个 Python 包装器。这将使您获得 C++的速度,同时保持在主应用程序中使用 Python 的简便性。

当然,挑战在于你必须用 C++重写代码;这是一个相当耗时的过程。

Python 库 Numba 为我们提供了一种简单的方法来应对这一挑战——无需编写除 Python 之外的任何代码就可以免费加速!

介绍 Numba

Numba 是一个编译器库,可以将 Python 代码转换成优化的机器代码。通过这种转换,Numba 可以使用 Python 编写的数值算法接近 C 代码的速度。

你也不需要用你的 Python 代码做任何花哨的事情。只需在您想要优化的 Python 函数前添加一行代码,Numba 就会完成剩下的工作!

我们可以使用 pip 安装 Numba:

pip install numba

如果你的代码有很多数值运算,使用 Numpy 很多,和/或有很多循环,那么 Numba 应该给你一个很好的加速。

加速 Python 循环

Numba 最基本的用途是加速那些可怕的 Python for 循环。

首先,如果你在你的 Python 代码中使用了一个循环,首先检查一下你是否能用一个 numpy 函数来替换它总是一个好主意。当然也有 numpy 没有你想要的功能的情况。

在我们的第一个例子中,我们将为 Python 中的插入排序算法编写一个函数。该函数将一个未排序的列表作为输入,并将排序后的列表作为输出返回。

下面的代码首先构造一个包含 100,000 个随机整数的列表。然后,我们连续 50 次对列表应用插入排序,并测量所有 50 次排序操作的平均速度。

100,000 个数字对于排序来说是相当多的数字,尤其是当我们的排序算法的平均复杂度为 O(n ) 时。在我的 i7-8700k 电脑上,对所有这些数字进行排序平均需要 3.0104 秒!

众所周知,Python 循环很慢。在我们的例子中,情况更糟,在 for 循环的中有一个 while 循环。另外,由于我们的排序算法是 O(n ),当我们向列表中添加更多的条目时,我们的运行时间会以二次方增加!

让我们加快 numba 的速度。

当我们看到一个函数包含一个用纯 Python 编写的循环时,这通常是一个好迹象,表明 numba 可以提供帮助。查看下面的代码,看看它是如何工作的。

我们只在代码中增加了 2 行代码。第一个是导入语句,用于导入 jit 装饰器。第二个是我们在函数中使用 jit 装饰器。

将 jit decorator 应用到我们的函数向 numba 发出信号,表明我们希望将机器码转换应用到函数中。

nopython 参数指定我们是希望 Numba 使用纯机器码,还是在必要时填入一些 python 代码。这通常应该设置为 true 以获得最佳性能,除非您发现 Numba 抛出一个错误。

这就是全部了!只需在您的函数上方添加 @jit(nopython=True) ,Numba 会处理剩下的事情!

在我的电脑上,对所有这些数字进行排序平均需要 0.1424 秒,速度提高了 21 倍!

加速数字运算

Numba 的另一个亮点是加速 Numpy 的操作。这一次,我们将把 3 个相当大的数组加在一起,大约是一个典型图像的大小,然后使用numpy.square()函数将它们平方。

查看下面的代码,看看这是如何在 Python 中用一点 Numpy 实现的。

请注意,每当我们在 Numpy 数组上进行基本的数组计算时,比如加法、乘法和平方,代码都会被 Numpy 自动进行内部矢量化。这就是为什么尽可能用 Numpy 替换纯 Python 代码通常性能会好得多。

上面的代码在我的 PC 上组合数组的平均运行时间为 0.002288 秒。

但是,即使 Numpy 代码也没有 Numba 使用的机器优化代码快。下面的代码将执行与之前完全相同的数组操作。这一次,我们在函数上方添加了矢量化装饰器,通知 numba 应该对我们的函数执行机器码转换。

矢量化装饰器接受两个输入。

第一个指定您将操作的 numpy 数组的输入类型。这必须被指定,因为 Numba 使用它来将代码转换成它的最佳版本。通过事先了解输入类型,Numba 将能够准确地计算出如何最有效地存储和操作数组。

第二个输入称为“目标”。它指定了您希望如何运行您的功能:

  • cpu: 用于运行在单个 cpu 线程上
  • 并行:用于在多核多线程 CPU 上运行
  • cuda: 用于在 GPU 上运行

在几乎所有情况下,并行选项往往比 cpu 选项快得多。 cuda 选项主要适用于具有许多可并行操作的超大型阵列,因为在这种情况下,我们可以充分利用 GPU 上拥有如此多内核的优势。

上面的代码在我的电脑上组合数组的平均运行时间为 0.001196 秒,这大约是 2 倍的加速。对于添加一行代码来说还不错!

总是超级快吗?

Numba 在应用于以下任何一个领域时都是最有效的:

  • Python 代码比 C 代码慢的地方(通常是循环)
  • 对一个区域应用相同操作的地方(例如,对许多元素应用相同的操作)

在这些地区之外,Numba 可能不会给你太多的速度。因为在这种情况下,转换到低级代码所带来的优势就消失了。

总的来说,快速尝试一下总是值得的。在几个 Python 函数上添加一行代码是值得一试的,可以将代码速度提高 2 到 21 倍!

喜欢学习?

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

以下是你如何用 cuDF 和 GPU 加速熊猫的方法

原文:https://towardsdatascience.com/heres-how-you-can-speedup-pandas-with-cudf-and-gpus-9ddc1716d5f2?source=collection_archive---------7-----------------------

轻松加速超过 10 倍

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

Pandas 是数据科学家和机器学习实践者的首选数据存储库。它允许轻松管理、探索和操作许多不同类型的数据,包括数字和文本。

熊猫和速度

即使就其本身而言,Pandas 在速度上已经比 Python 有了很大的进步。每当你发现你的 Python 代码运行缓慢,特别是如果你看到许多 for 循环,改变执行数据探索和过滤的代码到熊猫函数中总是一个好主意。熊猫函数是专门开发的矢量化运算,运行速度最快!

尽管如此,即使有这样的加速,熊猫也只是在 CPU 上运行。由于消费类 CPU 通常只有 8 个内核或更少,因此并行处理的数量以及所能实现的加速是有限的。现代数据集可能有多达数百万、数十亿甚至数万亿的数据点需要处理——8 个内核是不够的。

幸运的是,随着 GPU 加速在机器学习中的普遍成功,有一股强大的推动力将数据分析库引入 GPU。cuDF 库是朝着这个方向迈出的一步。

带 cuDF 的 GPU 上的熊猫

cuDF 是一个基于 Python 的 GPU 数据框架库,用于处理数据,包括加载、连接、聚合和过滤数据。由于 GPU 拥有比 CPU 多得多的内核,因此向 GPU 的转移允许大规模加速。

cuDF 的 API 是 Pandas 的一面镜子,在大多数情况下可以用来直接替换。这使得数据科学家、分析师和工程师很容易将其集成到他们的工作流程中。

所有需要做的就是把你的熊猫数据帧转换成 cuDF 帧,瞧,你有 GPU 加速!cuDF 将支持 Pandas 所做的大部分常见数据帧操作,因此许多常规的 Pandas 代码可以毫不费力地加速。

为了开始使用 cuDF 的例子,我们可以通过 conda 安装这个库:

conda install -c nvidia -c rapidsai -c numba -c conda-forge -c defaults cudf

请记住,对于以下实验,我们测试的机器具有以下规格:

  • i7–8700k CPU
  • 1080 Ti GPU
  • 32 GB DDR 4 3000 MHz 内存
  • CUDA 9.2

获得 GPU 加速

我们将加载一个随机数字的大数据集,并比较各种 Pandas 操作的速度与使用 cuDF 在 GPU 上做同样事情的速度。

我们可以在 Python Jupyter 笔记本中完成所有这些工作。让我们从初始化数据帧开始:一个用于熊猫,一个用于 cuDF。数据框有超过 1 亿个点!

对于我们的第一个测试,让我们测量一下在 Pandas 和 cuDF 中计算我们的数据中‘a’变量的平均值需要多长时间。 %timeit 命令允许我们在 Jupyter 笔记本上测量 Python 命令的速度。

平均运行时间显示在上面的代码注释中。我们就这样获得了 16 倍的加速!

现在,做一些更复杂的事情怎么样,比如做一个巨大的合并?!让我们在数据帧的“b”列上合并数据帧本身。

这里的合并是一个非常大的操作,因为熊猫将不得不寻找和匹配公共值——对于一个有 1 亿行的数据集来说,这是一个耗时的操作!GPU 加速将使这更容易,因为我们有更多的并行进程可以一起工作。

下面是代码和结果:

即使使用相当强大的 i7–8700k CPU,熊猫平均也需要 39.2 秒才能完成合并。另一方面,我们在 GPU 上的朋友 cuDF 只用了 2.76 秒,这是一个更容易管理的时间!总共加速了 14 倍以上。

结论

所以你有它!这就是你如何使用 cuDF 在 GPU 上加速熊猫。

如果你想吃更多,不用担心!cuDF 和 RAPIDS API 的其他部分可以提供更快的速度。最好的起点是官方 GitHub 页面

喜欢学习?

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

嘿,能给我你的号码吗?

原文:https://towardsdatascience.com/hey-can-a-i-get-your-number-805eda62419f?source=collection_archive---------24-----------------------

Source: BGR

现代科学的逐步指南

用 CNN 帮助爱情在 21 世纪蓬勃发展

好吧,听着。他们刚认识你——这太疯狂了。

但是你不知何故得到了他们的电话号码,所以现在你要打电话给他们…也许。

(除非你出生在 2000 年之后,在这种情况下,你会不惜一切代价避免给别人打电话——发短信就行了,怪人。)

只有一个问题。你刚做了 Lasik 眼科手术:

You clearly CANNOT see what that says (roll with me on this)

现在你看起来像斯蒂维·旺德,你看不到 SH*T,更不用说这张纸上的数字了。在你绝望的时候,你左顾右盼,寻找一个能让你在意识到自己什么也看不见之前跳下去的高处。

This is you for the next 6 hours. Maybe you’ll get singing superpowers too. (Britannica)

但是等等。这不是结束。你已经有了一个变通办法:一个如此疯狂的计划,它可能会奏效

你要用人工智能。

等等,什么?艾!?瓦力现在能帮你什么?

看,这有点误解——人工智能不一定意味着机器人。

人工智能描述了计算机执行人类可以完成的任务。

诸如“看到”手写数字的图片并识别它们是什么数字之类的任务。当谈到图像分类时,我们通常使用一种称为卷积神经网络或 CNN 的结构。查看这篇文章,深入分析它们是如何工作的——但这里有一个简短的总结:

  • 神经网络有。CNN 的每一层都在寻找某些特征
  • 图像被分成几部分来看,搜索和映射特征。特征映射通过像素数给出特定特征出现的概率位置。
  • 我们可以通过从更小的增量中取最大值来简化复杂的地图,我们将图像分解成更小的新图像。这叫做
  • 然后,我们通过一个 ReLU (整流线性单位)函数运行所有这些值,该函数将所有负值变为 0。
  • 我们可以多次映射、合并和重新逻辑,以变得更加精确。这些可以被编译成对应于每个标签或结果的连接层
  • CNN 通过使用加权像素来确定每种结果的概率,并给出它对图像内容的最佳猜测。

很刺激,对吧?

那么,你到底如何利用这项惊人的技术呢?

幸运的是,你是一个键盘高手,甚至不需要看到屏幕就能做到这一点——下面是它的分解:

  1. 你在做数据科学——你需要数据!
  2. 然后你要看看数据是否平衡和可用。
  3. 准备好你的资料。
  4. 用模型上的数据训练和测试 CNN。
  5. 用你刚拿到的电话号码查一下。

1.让我们得到这些数据

(Giphy)

Kaggle 是一个数据科学竞赛平台,在这里你可以找到免费的数据集。通常情况下,你必须得到手写数字的照片,把它们转换成。包含其特征的 csv 文件,然后通过模型运行该文件来训练它。

幸运的是,我们现在还不需要这么做——你可以在这里从 MNIST数据集中获得这些数据。我们还必须添加一些依赖项,为我们提供实现这一目标的工具:

import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
import matplotlib.image as mpimg
import seaborn as sns
%matplotlib inlinenp.random.seed(2)from sklearn.model_selection import train_test_split
from sklearn.metrics import confusion_matrix
import itertoolsfrom keras.utils.np_utils import to_categorical # convert to one-hot-encoding
from keras.models import Sequential
from keras.layers import Dense, Dropout, Flatten, Conv2D, MaxPool2D
from keras.optimizers import RMSprop
from keras.preprocessing.image import ImageDataGenerator
from keras.callbacks import ReduceLROnPlateausns.set(style=’white’, context=’notebook’, palette=’deep’)

2.平衡程度如何?

Wikimedia Commons

在你的一生中,如果你只看到 1 只兔子和 39999 只鸭子,你可能会猜那是一只鸭子。相反,如果你看到 1 只鸭子和 39,999 只兔子,你会猜兔子。

机器的学习方式与你的学习方式类似——如果数据偏向/不平衡于某个标签,可能会导致不准确的预测。我们需要确保数据是均匀分布的,这样机器就可以学习所有相同的 10 个数字。

您可以使用一些简单的 python 命令来实现这一点:

train = pd.read_csv (r".../train.csv")
test = pd.read_csv (r".../test.csv")Y_train = train[“label”]X_train = train.drop(labels = [“label”],axis = 1)del traing = sns.countplot(Y_train)Y_train.value_counts()

看起来您的数据已经相当均匀地分布了,所以您可以开始了!

3.数据准备

我们必须使我们的数据集可行,所以我们对它进行规范化和整形,以便它能与我们稍后要使用的模型一起工作。然后,我们将标签(10 位数字)编码成向量:

X_train = X_train / 255.0
test = test / 255.0X_train = X_train.values.reshape(-1,28,28,1)
test = test.values.reshape(-1,28,28,1)Y_train = to_categorical(Y_train, num_classes = 10)

现在,让我们将数据进一步分为训练集和验证集:

random_seed = 2X_train, X_val, Y_train, Y_val = train_test_split(X_train, Y_train, test_size = 0.1, random_state=random_seed)

4.培训+测试模型

This is your model. (Giphy)

我们将使用 Keras Sequential API 来解决这个问题,它的组合有点像这样:

model = Sequential()

model.add(Conv2D(filters = 32, kernel_size = (5,5),padding = 'Same', 
                 activation ='relu', input_shape = (28,28,1)))
model.add(Conv2D(filters = 32, kernel_size = (5,5),padding = 'Same', 
                 activation ='relu'))
model.add(MaxPool2D(pool_size=(2,2)))
model.add(Dropout(0.25))

model.add(Conv2D(filters = 64, kernel_size = (3,3),padding = 'Same', 
                 activation ='relu'))
model.add(Conv2D(filters = 64, kernel_size = (3,3),padding = 'Same', 
                 activation ='relu'))
model.add(MaxPool2D(pool_size=(2,2), strides=(2,2)))
model.add(Dropout(0.25))

model.add(Flatten())
model.add(Dense(256, activation = "relu"))
model.add(Dropout(0.5))
model.add(Dense(10, activation = "softmax"))

我们在这里做的是添加我们的数据将要经过的层。现在我们设置一个优化器和退火器来避免过度拟合。我们还可以增强和扩展我们的数据集,以进一步避免这种情况:

optimizer = RMSprop(lr=0.001, rho=0.9, epsilon=1e-08, decay=0.0)model.compile(optimizer = optimizer , loss = “categorical_crossentropy”, metrics=[“accuracy”])learning_rate_reduction = ReduceLROnPlateau(monitor='val_acc', 
                                            patience=3, 
                                            verbose=1, 
                                            factor=0.5, 
                                            min_lr=0.00001)datagen = ImageDataGenerator(
 featurewise_center=False, 
 samplewise_center=False,
 featurewise_std_normalization=False, 
 samplewise_std_normalization=False, 
 zca_whitening=False, 
 rotation_range=10, 
 zoom_range = 0.1, 
 width_shift_range=0.1, 
 height_shift_range=0.1, 
 horizontal_flip=False, 
 vertical_flip=False)datagen.fit(X_train)

现在让我们把它们放在一起!

epochs = 2 #depending on how good your computer is, you can do more
batch_size = 86history = model.fit_generator(datagen.flow(X_train,Y_train, batch_size=batch_size),
 epochs = epochs, validation_data = (X_val,Y_val),
 verbose = 2, steps_per_epoch=X_train.shape[0] // batch_size
 , callbacks=[learning_rate_reduction])

耶!通过手术后正在恢复的眼睛,你可以看到这个模型大约有 96%的准确性。

5.号码是多少??

你就快到了。你和你的浪漫的命运之间唯一的事情是能够实际上使用这个模型来计算出那个电话号码是什么。

A diagrammatical representation of your predicament.

不知何故,你设法拍下了组成那个电话号码的各个数字的照片,并把它们上传到了你的电脑上,你这个聪明的坏蛋:

您的第一项工作是将它们的像素值转换成您的模型可以读取的格式。这意味着你需要一个脚本来放入这些照片。csv 格式,与您的训练数据集格式相同。

import os,array
import pandas as pd
os.chdir(r”.../phone_digits”)
import timefrom PIL import Image
columnNames = list()for i in range(784):
 pixel = ‘pixel’
 pixel += str(i)
 columnNames.append(pixel)new_data = pd.DataFrame(columns = columnNames)
start_time = time.time()
for i in range(1,11):
 t = i
 img_name = str(t)+ (“.jpg”)
 img = Image.open(img_name)
 rawData = img.load()

 data = []
 for y in range(28):
 for x in range(28):
 data.append(rawData[x,y][0])
 print (i)
 k = 0

 new_data.loc[i] = [data[k] for k in range(784)] print (“Done”)new_data.to_csv(“new_data_converted.csv”,index = False)

这应该会在同一个文件夹中创建一个. csv 文件,您可以将它输入到您的模型中。让我们现在就开始吧:

phone_number = pd.read_csv (r”C:\Users\hilal\Pictures\phone_digits/new_data_converted.csv”)
phone_number = phone_number / 255.0
phone_number = phone_number.values.reshape(-1,28,28,1)results = model.predict(phone_number)
results = np.argmax(results,axis = 1)results = pd.Series(results,name=”Label”)final_order = pd.concat([pd.Series(range(1,11),name = "ImageId"),results],axis = 1)
print (final_order)

而现在…

DRUMROLL PLEASE! (Giphy)

您的结果如下:

哇哦。你做到了。天啊。你真是个天才。弥赛亚。男人中的英雄。你从笔记本电脑上站起来,绕场一周,和你的狗击掌。右边的数字告诉你电话号码是多少,你终于可以看到了,因为你的视力恢复了。

当然,这可能意味着这整个练习是不必要的,但是请跟我一起做。)

你拿起电话,开始拨打那些甜蜜的数字,这时你意识到…

“等一下——

这不可能是一个实数。"

哦,好吧…也许其他人会对你的数据科学技能印象深刻?

cries in Python

大家好,我是 Murto,是一名 17 岁的企业家,也是加拿大多伦多的一名学生。如果你对这篇文章有任何反馈,或者你只是想聊天,请通过 LinkedIn 联系我!下一步:

  • 告诉某人你爱他们
  • 战胜你的敌人
  • 查查我写过的其他一些关于艾的文章 这里 这里
  • 祝你今天愉快

谢谢!

嘿,数据工程师,这是在源代码中

原文:https://towardsdatascience.com/hey-data-engineers-its-in-the-source-code-ea241f1dd52a?source=collection_archive---------35-----------------------

关于数据剖析的一些想法,以及如何通过学习阅读应用程序源代码来超越它。

作为一名数据工程师,你有没有尝试过解释你实际上做的是什么?例如,如果一个聚会上没有技术背景的人问起数据工程,你如何描述这项工作?我使用了关于缩放的比喻(“如果数据科学家是制作汤的米其林明星厨师,我的工作就是想出如何制作足够的汤来养活一支军队。”)或过于简化的管道(“我构建移动、整合和处理数据的东西”)。尤其是一个比喻,最近已经成为我个人最喜欢的,主要是因为它的准确性(也因为它听起来很酷):

数据工程师是考古学家的一种。我们挖掘一个组织的事务化石和工件,并使用它们来确定过去事件的事实,以便我们可以从中学习。

当然,这个角色很复杂,许多数据工程师做的远不止这些。但是对于许多数据团队来说,数据工程师负责业务逻辑转换和建模,这个数据剖析过程——理解我们的源数据,以便我们可以将其转换成更直观的形状——是工作中最耗时(也是最昂贵)的部分之一。

We have the data! Now, does anyone know what the user_prod_xq column does?

数据剖析很难。这很难,因为源系统并不真正关心我们这些数据人员——他们也不应该关心。源系统有一项工作要做,如销售我们的产品,向我们的客户做广告,或管理我们的工资单等。我们希望这些系统 100%专注于做这项工作,而不是担心让他们在这个过程中留下的数据痕迹易于阅读。这意味着数据可能会被它们所服务的交易目的的噪音所扰乱。这也意味着我们通常没有一个事件的实际记录,只有周围的证据,需要通过仔细的研究收集逻辑来填补空白。

数据剖析也很难,因为我们经常错误地假设一些人或不知名的部门知道“数据”我们相信我们的 DBA 一定知道temp_orders_related_bypass表的用途,或者至少有一个应用程序开发人员能够很容易地解释users.highest_purchase_threshold列是如何填充的。有时候会。更常见的是,他们认为他们了解,也就是说,他们对一个实体有足够的了解来做他们的工作,但没有完整的了解。而如果 codebase 已经存在几年了, 很可能他们完全没有概念 。这并不罕见,也不是您的 DBA /开发团队的一个失误。在某些情况下,他们不会比你知道得更多,这是有充分理由的:

  • 对象关系映射器(ORM)是许多应用程序用来与数据库交互的工具。这些从软件开发中抽象出许多 DBA 类型的工作,结果是没有人真正设计数据库模式。很难从开发者那里得到关于机器人为他们建造的桌子的答案。
  • 人来人往。您有疑问的数据集可能是由一位前员工或早已去世的顾问创建的。除非他们煞费苦心地记录数据集(遗留代码很少出现这种情况),否则部落知识会随着创造者一起离开。
  • 代码库变得越来越大,人们没有无限的记忆。一个没有记录他们 3 年前编写的代码/创建的表格的 DBA 或软件工程师很可能记得细节,就像我记得我高中时的储物柜组合一样(提示:不太可能)。

No science behind this, but it feels pretty accurate to me.

一个实际例子

假设您的公司提供楼宇安全管理软件即服务,并希望监控保安物业巡查的性能,并可能对其应用预测分析。当警卫走过物业时,他们会在每个由您的产品管理的外门读卡器上刷一个 RFID 密钥卡。如果出现任何问题(如入侵者),他们会立即停止走动,并通过您的产品向值班经理发送电子邮件。您在密钥卡阅读器和外发电子邮件上都有来自您产品的源数据。

两个数据集都不会有“财产步行”或“步行问题”的表格,就像考古学家不会找到一块刻有公元前 2412 年 15 万人在这里战斗的古代石碑一样。相反,您将依靠石箭头和数据的化石遗迹来讲述故事(即outgoing_emailskeyfob_swipes表)。您的模型可能会包括“完整的财产巡查”记录,即保安在每个门上刷卡,“不完整的财产巡查”记录,即保安错过一个或多个门的记录,以及“事件财产巡查”记录,即在刷卡的给定时间窗口内发送电子邮件的记录。但是您还没有分析数据!找出隐藏的复杂性,那些数据不能告诉你的,是你大部分工作的真正所在。假设该建筑在去年增加了包含在步行路线中的密钥卡阅读器,或者在 2 个月的时间里,该建筑在更换密钥卡供应商时为所有警卫使用一个共享的密钥卡。或者假设两个保安住在大楼里,当作为租户进出时使用他们的 fob,或者当值班经理离开时,他们从数据库中被删除,以及该经理的所有依赖于外键的电子邮件记录。数据不能告诉你这些,任何查看相同数据的人(无论是 DBA 还是开发人员)也不能推断出这些东西。

那么,我们在哪里找到这些复杂问题的答案呢?如果有足够的时间和资源,软件开发人员和数据库管理员最终会给他们提供答案吗?

寻找答案的一个明显的地方是主题专家和组织历史。拜访部门负责人,询问 2017 年夏天是否发生了什么事情,可能会找到一个简单的解决方案,比如“我们买了一个新仓库”或“我们开了第二家店”。但是很多时候,组织中的任何人都无法帮助你。对于在其他地方找不到的隐藏的复杂性的非常重要的一部分,那些 DBA 和软件工程师有另一个锦囊妙计…

他们阅读源代码

就像任何需要添加的功能或需要修复的错误一样,第一步是通读现有的代码,以了解一件事情是如何工作的。考虑逻辑数据“监管链”:如果应用程序是与生产数据库交互的东西,应用程序源代码是定义应用程序行为的东西,那么我们的绝大多数答案实际上都在应用程序代码库中。更重要的是,受版本控制的源代码可以让我们“穿越时空”,轻松地查看记录创建时的代码。这在许多年前应用程序的行为非常不同并且记录反映了这些差异的情况下非常有用。

您不需要精通编写源应用程序的语言——远非如此。如果你的主要产品是基于 Rails 的,那就在周末学习足够的 Ruby 吧。如果是 Django,看几个 Python 101 的视频。即使您无法编写一行可编译的代码,您也可以轻松地解决这个问题

if user.is_active:
    user.send_email()

可能意味着我们只给活跃用户发邮件。代码库通常比您预期的更直观——例如,如果您了解到应用程序的models文件夹包含所有连接到数据库的代码,那么当试图理解用户表的一个奇怪之处时,models/users.rb是一个很可能的起点。

即使它不能 100%回答您的问题,亲自阅读代码通常可以让您完成 80%的工作,并让 DBA 或开发人员轻松完成最后 20%的工作。考虑这两个请求:

request 1 :我需要知道为什么users.system_idusers.admin_id的匹配率是 75%,但是旧的记录却是 100%。你能帮我吗?

请求 2 :我正在试图找出为什么users.system_idusers.admin_id匹配的几率为 75%,但是在一月份之前的记录中,它与users.admin_id匹配的几率为 100%。看起来我们在第 76 行的文件users_import_ids.php中的<提交 sha >中提交了一个修改,它调用了第 91 行的另一个类来填充 system_id,但是另一个类使用了一些我不太理解的代码。你能帮我吗?

第一个请求是您在不阅读任何应用程序代码的情况下所能做的最好的事情。第二个是你可以做些额外的努力。一旦您能够自助,您的数据分析工作会变得多么迅速和有效,这其中的差别是惊人的。您会发现大多数开发人员和 DBA 都很乐意帮助您深入并“带您参观”存储库——因为您知道的越多,您的问题就变得越简单。

嘿人类,让我们谈谈!

原文:https://towardsdatascience.com/hey-human-lets-talk-1669e3e043b1?source=collection_archive---------37-----------------------

对话式人工智能就在这里,它想要提供帮助

德克·克内梅尔和乔纳森·福利特

Figure 01: Conversational AI can connect the consumer experience across channels — from Web site to mobile app to smart speaker.
[Photo: “HomePod” by Przemyslaw Marczynski on Unsplash]

广告业的未来会让我们的生活变得更好吗?大多数人讨厌广告:播客中的可怕信息试图让你购买你不感兴趣的东西,现有的几乎每个网站上的显示广告,以及在你的屏幕和耳机上爆炸的弹出视频,充满声音和愤怒,毫无意义。这是一种商业上可以接受的折磨,真的。

不存在全球退出。参与公共数字空间包括一个隐含的社会契约来吸收这种不和谐的噪音。虽然你的大脑已经变得善于将这些入侵推到背景中,但它们仍然在那里——对你试图完成或享受的事情增加了一层恼怒。

然而,正是广告给你带来了你正在使用的平台。事实是,创作者需要为他们制作的东西得到报酬。出于多种原因,互联网培养了一种人们想要免费东西的文化。广告已经悄悄进入,充当支付代理。我们可能会发现它是邪恶的,但它是必要的。没有它,互联网将只是一个今天的空壳,或者可能会采用替代的货币化策略,甚至更令人厌恶。

Figure 02: Your brain has become adept at shoving these intrusive marketing messages into the background.
[Photo: “Times Square” by Joshua Earle on Unsplash]

Andy Mauro, Automat 的联合创始人兼首席执行官,设想了一个市场营销和广告为消费者提供增值服务的未来——而不是遵循破坏和降低我们体验的长期传统。Mauro 已经在语音识别领域工作了近 20 年,他的公司 Automat 为品牌创造了对话式人工智能。

“我有时会对人们说,‘我职业生涯的前半部分致力于人们讨厌的东西——那些电话语音(识别)系统,后半部分致力于没人用的东西——那就是移动语音助手,比如 Siri,”毛罗说实际上,我们仍然在寻找对话式人工智能中难以捉摸的杀手用例。"

对话式人工智能是语音识别、智能扬声器和聊天机器人(各种基于语言的对话技术)的总称。“我认为只有一个术语实际上很有用,”毛罗说。“因为从自然语言理解的角度来看,底层技术几乎是相同的。理解口头或键入的自由形式文本的能力,以及建立对话、来回对话的技术——这在基于语音和文本的输入之间几乎完全相同。”

Mauro 和 Automat 的团队正在研究的技术之一是对话显示广告。“我认为,如果你试图建造一些有意义的东西,一个真正值得关注的地方是每个人都做但没有人喜欢的东西,”毛罗说。“我不认为许多消费者会说他们喜欢展示广告。我想说,大多数在它们身上花了很多钱的品牌也可能会说,“我也不确定我是否喜欢它们。”周围有问题,有人看到了吗?看到他们的东西是一个真实的人,还是某种自动系统在操纵数字?最终,我从这个广告中获得了任何价值吗?"

对话式展示广告试图为消费者提供更好的东西。“例如,我正在阅读一个汽车博客。我是一个汽车爱好者,正在考虑买车,我看到了一则广告。今天这个广告,充其量,会给我一些融资信息和汽车的图片。如果我点击它,它会把我带到制造商的网站或经销商。它让我偏离了我正在阅读的内容,”毛罗说。“通过对话式展示广告,我可以点击进入该广告,而无需离开内容页面……我还可以与虚拟销售顾问聊天,他可以告诉我一些关于汽车的事情,回答我的问题,甚至可以为我安排试驾。所以,这是更好的消费者体验。非常非常重要的是,在这个数据隐私和安全的世界,以及谷歌和脸书发生的所有事情……从消费者的角度来看,这是非常透明和非常自愿的。你知道你在和一个品牌聊天,当你提供你可能正在寻找的信息时。这比在脸书上进行搜索或喜欢某样东西要透明得多,因为你根本不知道自己选择的是商业交易还是广告交易。”这听起来像是一个巨大的升级。然而,今天,广告是你潜意识里屏蔽的东西,甚至在你意识到它们存在之前,毛罗描述的功能类型更具辅助性。这是一种与用户需求和愿望同步的在线体验,同时还提供企业利益补偿和激励。

毫无疑问,电子商务创新的时机已经成熟。“对于我们这些已经生活了一段时间的人来说,能够在凌晨 3 点穿着睡衣购物是一次了不起的经历。它压缩了时间和空间,这是最优秀、最成功的创新经常做的事情,”Mauro 说。“但在过去 20 年里,没有人真正思考过(那段经历)。我的意思是,电子商务在很大程度上仍然只是产品图像的网格,无论你是在购买电池,还是在购买 5000 美元的手袋,或者是在购买汽车。”

“我们发现,在各种类型的电子商务中,优雅的服务不仅可以带来更好的消费者体验,还可以通过与客户聊天带来更好的业务成果,”Mauro 说。“我们通常谈论的是网络或移动体验,即基于文本的聊天。从参与度和客户满意度的角度来看,我们已经看到了非常惊人的结果。”

Automat 团队还致力于通过对话式人工智能连接不同渠道的消费者体验。对于许多消费者来说,一家公司的跨渠道体验——从网站到应用程序,再到实体商店——可能看起来是脱节的,并且差异很大。“我们认为这种利用与品牌个性相关的对话体验的想法可能是一种提供关联体验的好方法,”Mauro 说。“我可以与同一个人(在这种情况下是虚拟化身)进行统一的对话,并在整个消费过程中获得我需要的东西。”从品牌的角度来看,保持渠道的一致性非常重要。品牌战略的一部分是识别品牌的个性。语音使这一战略愿景在虚拟化身中得以体现。此外,由于聊天机器人和语音技术如此容易地融入任何数字界面,它可能变得似乎无处不在。“这是一次非常相关的经历,”毛罗说。“即使你在网上聊天以了解产品,也许你在手机上聊天以了解订单状态,也许你有一个使用问题,你实际上与你的智能扬声器交谈。”

Automat 采访了数百名喜欢在品牌或零售商网站上交谈的个人消费者。“人们觉得他们得到了在网站上找不到的信息,”毛罗说。“现在,事实上,网站几乎总是在某个地方有产品信息,但它是…在一个他们必须做大量阅读才能获得它的地方。因此,他们觉得自己获得了无法通过其他方式获得的信息。”

这一切都归结为任务完成。聊天机器人——如果做得好的话——可以从数据库中提取相关信息并迅速提供给你,而不是绝望地在一个网站上导航,而不是与一个在你和许多其他客户之间玩弄你的人聊天。因此,你会觉得时间过得更快,实际上花了更多时间与公司打交道。“很多人认为像这样的引导式产品推荐是关于产品发现,找到合适的产品。我们学到的是,虽然这当然是真的,但它真正关乎的是产品信心。所以,人们觉得产品还可以,但他们真正需要的是有人,或者在这种情况下,一些东西,来强化并告诉他们为什么这实际上是适合他们的产品。

自然语言处理和自动化的发展

当然,尽管对话式人工智能可以创造一些重大胜利,但它并不是万无一失的。“在语言方面,人类远比机器好得多,”毛罗说。"我认为我们离根本性的变革还有很长的路要走。"在人类交流中,通常没有单一的意图或单一的潜在信息。语言比那更复杂,但是现在,NLP 技术有它的限制。“底层技术基础设施正迫使我们走上一条每一句话都需要满足一件事的道路。”毛罗说。"这并不是语言真正的工作方式."自然语言处理的下一个突破可能需要持续的理解——在这种情况下,机器不仅可以解释一个人此刻正在说的话的意思,还可以解释这个意思在这个人继续说话时是如何演变的。“关于语言是否等同于 AGI 或人工智能问题,存在着真实、合法、哲学和技术上的争论,”Mauro 说。“如果解决了语言,有没有让计算机变得和人类一样聪明?这两件事有很大关系吗?”

Figure 03: There’s usually not a single intent, or one single underlying message, in human communication.
[Photo: “Between lines” by JR Korpa on Unsplash]

关于这些技术可能如何改变未来工作的前景,Mauro 有一些鼓舞人心的想法。“我们可能会获得哪些我们没有预料到的自动化功能,这些功能不会使现有工作自动化,但实际上会做一些以前没有做过的事情?我可以从哪里获得我无法以任何方式获得的帮助?我认为这是一种更有创造性、更有希望、更令人兴奋的看待它的方式。我真的想挑战每个人,让他们不要认为有人有 X 工作,让人工智能来做吧。让我们考虑提供新的就业形式,只有人工智能可以[帮助实现],”毛罗说。如果对话式人工智能可以帮助实现更好的消费者体验,也许新形式的营销工作也即将到来。

Creative Next 是一个播客,探索人工智能驱动的自动化对创意工作者,如作家、研究人员、艺术家、设计师、工程师和企业家的生活的影响。本文伴随 第二季第九集——对话式营销前沿

嘿,模特,你为什么说这是垃圾邮件?

原文:https://towardsdatascience.com/hey-model-why-do-you-say-this-is-spam-7c945cc531f?source=collection_archive---------16-----------------------

将原因附加到模型预测

Shapley 值在机器学习中用于解释复杂预测模型的预测,又名“黑盒”。在这篇文章中,我将使用 Shapley 值来确定 YouTube 评论的关键术语,这些术语解释了为什么一个评论被预测模型预测为垃圾或合法。特定关键术语的“联盟”可以被认为是模型返回给定预测的“原因”。此外,我将使用聚类来识别在如何使用这些关键术语方面有相似之处的评论组。最后,我将进一步概括预测原因,以便使用代表原因类别的更少关键术语的字典对评论组进行分类。

序文

遵循这篇文章中的代码片段需要 Python 和 r。包含所有代码片段的完整 Jupyter 笔记本可以在这里找到。运行代码所需的 Python 库如下。我们将使用 rpy2 库在 Python 中运行 R 的实例。

import rpy2.ipythonfrom rpy2.robjects import pandas2ripandas2ri.activate()%reload_ext rpy2.ipythonfrom sklearn import model_selection, preprocessing, metrics, svm
from sklearn.feature_extraction.text import CountVectorizer
from sklearn import decomposition, ensembleimport pandas as pd
import numpy as npimport stringimport matplotlib.pyplot as plt
import seaborn as sns
%matplotlib inlineimport xgboostimport shap, time

沙普利法

沙普利值是在合作博弈理论中进行的一项研究的结果。他们告诉如何在玩家之间公平分配“奖金”。当使用先前训练的模型预测数据实例的标签时,可以通过假设数据实例的每个特征值是游戏中的玩家来解释该预测,其中该预测是支出。Shapley 值是所有可能的要素组合中某个要素值的平均边际贡献。Christoph Molnar 的在线书籍提供了更多的细节。

我们可以用一个简单的例子来介绍 Shapley 方法:XOR 表。我们将在接下来的章节中进行更详细的讨论。

data = {'F1':[0,0,1,1], 'F2':[0,1,0,1], "Target":[0,1,1,0]} #XOR
df = pd.DataFrame(data)X = df[["F1","F2"]]
y = df["Target"].values.tolist()df

为了计算 Shapley 值,我们首先需要训练一个模型。例如,让我们使用径向基函数核的 SVM。我们现在可以使用 Python 库 shap 计算 Shapley 值。

clf = sklearn.svm.SVC(kernel='rbf', probability=False).fit(X, y) df["Prediction"] = clf.predict(X)# Explaining the probability prediction results
explainer = shap.KernelExplainer(clf.predict, X)
shap_values = explainer.shap_values(X)pd.concat([df, pd.DataFrame(shap_values, 
           columns='shap_'+ X.columns.values)], axis=1)

从上述结果可以看出,当每个数据实例的两个特征的计算贡献(Shapley 值)都为负时,预测为 0,当 Shapley 值都为正时,预测为 1。请注意,这两个贡献加起来就是该实例的预测与预期预测𝐸(𝑓之间的初始差值,它是实际目标值的平均值,如下所示:

YouTube 垃圾评论

我们将使用一个文本分类数据集,从 5 个不同的 YouTube 视频中收集 1956 条评论。这些评论是通过 YouTube API 从 2015 年上半年 YouTube 上观看次数最多的十个视频中的五个收集的。数据集包含被标记为合法邮件或垃圾邮件的非编码邮件。由于我将在本文稍后再次使用 R,我决定使用我在搜索数据集时找到的 R 片段下载数据集。

上面的代码片段会将 csv 格式的文件下载到本地文件夹。我们可以使用熊猫图书馆来探索内容。

youtube_data = pd.read_csv("youtube_data/TubeSpam.csv")
youtube_data.head()

我们可以选择稍后将用于建模的列内容和类,并删除缺少内容的行。运行下面的代码片段将返回 1954 行,并显示标签 0(合法评论)和 1(垃圾评论)在删除重复行后出现的次数大致相同。

youtube_df = pd.DataFrame()
youtube_df['text'] = youtube_data['CONTENT']
youtube_df['label'] = youtube_data['CLASS']
youtube_df.dropna(inplace=True)youtube_df.groupby('label').describe()

youtube_df.drop_duplicates(inplace=True)

\

我们可以看看合法评论和垃圾评论在长度上是否有明显的区别

youtube_df['length'] = youtube_df['text'].apply(len)
youtube_df.hist(column='length', by ='label', bins=50, figsize = (10,4))

显然,垃圾评论平均来说要长一些。最长的注释之一是,例如:

youtube_df[youtube_df['length'] == 1077]['text'].iloc[0]

预处理注释

在使用文本数据进行建模之前,我们将使用一些标准的自然语言处理(NLP)技术对其进行清理。特别是,我们将删除数字,标点符号,额外的空格,将所有单词转换为小写,删除停用词,词干和词条。为此,我们将使用 Python 库 nltk

from nltk.tokenize import word_tokenize
from nltk.corpus import stopwords # nltk.download('stopwords')
from nltk.stem import PorterStemmer
from nltk.stem import WordNetLemmatizer #nltk.download('wordnet')import string, restop_words = list(set(stopwords.words('english')))
stemmer= PorterStemmer()
lemmatizer=WordNetLemmatizer()translate_table = dict((ord(char), None) for char in string.punctuation)def nltk_text_preproc(text_in):
    text_out = re.sub(r'\d+', '', text_in) # rm numbers
    text_out = text_out.translate(translate_table) # rm punct
    text_out = text_out.strip() # rm white spaces return text_outdef nltk_token_processing(tokens):
    tokens = [i.lower() for i in tokens]
    tokens = [i for i in tokens if not i in stop_words]
    tokens = [stemmer.stem(i) for i in tokens]
    tokens = [lemmatizer.lemmatize(i) for i in tokens]

    return tokens

之前,我们可以查看数据集中的前 10 条评论

pd.options.display.max_colwidth = 1000
youtube_df['text'].head(10)

之后,使用我们的预处理步骤

youtube_df['text'].head(10).map(lambda x: nltk_text_preproc(x)).map(lambda x: nltk_token_processing(word_tokenize(''.join(x)))).map(lambda x: ' '.join(x))

在继续之前,我们现在准备处理数据集中的所有文本。

youtube_df['text'] = youtube_df['text'].map(lambda x: nltk_text_preproc(x))
youtube_df['text'] = youtube_df['text'].map(lambda x: nltk_token_processing(word_tokenize(''.join(x))))
youtube_df['text'] = youtube_df['text'].map(lambda x: ' '.join(x))

新数据集包含 1735 行。

从文本创建要素

在这一部分,预处理的文本数据将被转换成特征向量。我们将使用 nltk Python 库的计数矢量器方法。这将文本行转换成一个矩阵,其中每一列代表所有文本中的一个术语,每个单元格代表特定术语在给定行中出现的次数。

count_vect = CountVectorizer(min_df=0.01, 
                             max_df=1.0, ngram_range=(1,3)) 
count_vect.fit(youtube_df['text'])
youtube_df_text = count_vect.transform(youtube_df['text'])

这里,我们请求删除出现在不到 1%的评论或所有评论中的术语,并要求 CountVectorizer 计算最多 2 个连续术语的 n 元语法。

例如,第二个注释(行)

text_example_orig = youtube_df['text'][1]
print(text_example_orig)

成为

text_example = count_vect.transform([text_example])
print(text_example)

如果我们想知道哪些项对应于 CountVectorizer 返回的索引,我们可以使用下面的代码

for row, col in zip(*text_example_transf.nonzero()):
    val = text_example_transf[row, col]
    #print((row, col), val)
    print(count_vect.get_feature_names()[col])

计数矩阵不是标准矩阵,而是稀疏矩阵

print ('Shape of Sparse Matrix: ', youtube_df_text.shape)
print ('Amount of Non-Zero occurences: ', youtube_df_text.nnz)
print ('sparsity: %.2f%%' % (100.0 * youtube_df_text.nnz /
                             (youtube_df_text.shape[0] * youtube_df_text.shape[1])))

稀疏矩阵是包含极少非零元素的矩阵的最佳表示。事实上,用二维数组表示稀疏矩阵会导致大量内存浪费。在我们的例子中,有 1,735 行* 166 个项,这将导致具有 288,010 个元素的二维矩阵,但是只有 7,774 个具有非零出现(2.7%稀疏度),因为不是所有行都包含所有项。

建模

我们将把数据集分成训练集和验证集。

train_x, valid_x, train_y, valid_y, index_train, index_val = model_selection.train_test_split(youtube_df_text, youtube_df['label'], range(len(youtube_df['label'])), stratify=youtube_df['label'], random_state=1, train_size=0.8)

现在属于训练集和验证集的合法评论和垃圾评论的数量是

np.unique(train_y, return_counts=True)

现在是时候训练我们的模型了

def train_model(classifier, feature_vector_train, label, feature_vector_valid, valid_label):
    # fit the training dataset on the classifier
    classifier.fit(feature_vector_train, label)

    # predict the labels on validation dataset
    predictions = classifier.predict(feature_vector_valid)

    return classifier, metrics.accuracy_score(predictions, valid_label), metrics.classification_report(predictions, valid_label)

看看它在验证集上的表现。我们将使用 XGBoost 分类器。

classifier, accuracy, confusion_matrix = train_model(xgboost.XGBClassifier(), 
            train_x, train_y, valid_x, valid_y)
print("Xgb, Accuracy: ", accuracy)
print(confusion_matrix)

对于这篇文章来说,一个高性能的模型是不必要的。事实上,我们正在寻找一个关于特性和标签如何相互关联的一般性描述。事实上,这里我们只需要一个像样的模型。

用 SHAP 计算沙普利值

Python 库SHAP(SHapley Additive explaints)可以解释任何机器学习模型的输出,特别是它为树集成方法提供了高速精确算法。这就是为什么我们的模型是 XGBoost 模型的原因之一。在我们的例子中,计算 SHAP 值只需要几分之一秒。这里,我们计算整个数据集的 SHAP 值。请注意,将 XGBoost 与逻辑目标函数结合使用时,SHAP 值是对数优势。要将对数优势差额转换为概率,我们可以使用公式 odds = exp(对数优势),其中 p = odds/(1+odds)。在本节的最后,我们将做这个练习,但现在让我们首先计算 SHAP 值并研究它们。

t0 = time.time()
explainer = shap.TreeExplainer(classifier)
shap_values_train = explainer.shap_values(youtube_df_text)
t1 = time.time()
timeit=t1-t0
print('time to compute Shapley values (s):', timeit)

将稀疏矩阵转换成密集矩阵是很方便的。

txt_dense_df = pd.DataFrame(youtube_df_text.todense(), 
                            columns=count_vect.get_feature_names())
shap_values_train_df = pd.DataFrame(shap_values_train, 
                                    columns=txt_dense_df.columns)

有了这个数据框,我们就可以计算整体要素的重要性

shap_sum = np.abs(shap_values_train_df).mean(axis=0)
importance_df = pd.DataFrame([txt_dense_df.columns.tolist(), 
                              shap_sum.tolist()]).T
importance_df.columns = ['column_name', 
                         'shap_importance (log-odds)']
importance_df = importance_df.sort_values('shap_importance (log-odds)', ascending=False)
importance_df['shap_importance (%)'] = importance_df['shap_importance (log-odds)'].apply(lambda x: 100*x/np.sum(importance_df['shap_importance (log-odds)']))

并且选择例如前 20 个特征

topN = 20
top20 = importance_df.iloc[0:topN]["column_name"]print('Cumulative Importance', 
      np.sum(importance_df.iloc[0:topN]["shap_importance (%)"]))shap_values_imp = shap_values_train_df[top20]shap.summary_plot(shap_values_train_df, 
                  txt_dense_df, plot_type="bar")importance_df.iloc[0:topN]

其累计“重要性”约为 94%。上面的条形图显示了每个特征的 SHAP 值的平均绝对值。

也可以使用更多的可视化来解释模型结果。举个例子,

j = 1
youtube_df.iloc[j]

是典型的垃圾评论。我们可以显示有助于将模型输出从基础值(我们使用的训练数据集的平均模型输出)推至模型输出的项。将预测推向更高的对数优势值的术语显示为红色,将预测推向更低的对数优势值的术语显示为蓝色。在这个特殊的例子中,有一个典型的垃圾评论的所有“成分”。事实上,所有术语的 SHAP 值都将模型输出推至一个比平均输出值高得多的值。

shap.initjs()# visualize the j-prediction's explanation (use matplotlib=True to avoid Javascript)
shap.force_plot(explainer.expected_value, shap_values_imp.iloc[j].to_numpy(), 
                txt_dense_df.iloc[j][top20])

对于合法的评论,如

上面使用的可视化变成了

在我的笔记本中,我添加了更多的可视化内容,这并不是这篇文章的主要目的。

最后,让我们做一个将对数几率转换成概率的练习,看看 SHAP 值与它们有什么关系。

j = 1# log odds margin to prob
# odds = exp(log odds), p = odds/(1+odds)log_odds = np.sum(shap_values_train_df.iloc[j].to_numpy())
avg_model_output = np.mean(youtube_df['label']) # prob
log_odds_avg_model_output = np.log(avg_model_output/(1-avg_model_output))
predicted_prob = classifier.predict_proba(youtube_df_text.tocsc())[j][1] #target=1
predicted_log_odds = np.log(predicted_prob/(1-predicted_prob))print("Sum of Shaphley values (log-odds)for j-instance:", log_odds, 
      'prob:', np.exp(log_odds)/(1.0+np.exp(log_odds)))
print("Average model output:", avg_model_output)
print("Predicted probability value for j-instance:", predicted_prob,
      "Predicted value:", classifier.predict(youtube_df_text.tocsc())[j])print('log_odds:', log_odds, 'is expected to be equal to pred-expected:', predicted_log_odds-log_odds_avg_model_output)
print('pred-expected (prob):', predicted_prob-avg_model_output)

对于评论 j = 1,我们基于对数-赔率(SHAP 值)到概率的转换,计算了 SHAP 值(6.59),对应于该评论是垃圾邮件(标签= 1)的概率为 99.86%。从模型预测的概率是 99.85%,略有不同,但足够接近。正如我在本文开头所说的,我们期望 SHAP 值(对数优势)等于预测值减去预期概率,这是所有实际目标的平均值(0.48)。

聚类 SHAP 值

本文之前选出的前 20 个术语可以用字典总结成更通用的“主题”:

top20_dict = {'ACTION': ['check','subscrib','view','share','follow','help', 'visit'],
 'REQUEST': ['plea','hey'],
 'VALUE': ['money','free','billion', 'new', "good", 'best'],
 'YOUTUBE': ['channel', 'song', 'onlin'],
 'COMMENT': ['love', 'like comment']             
}

因此,对于每个评论,我们可以确定运行以下代码片段的首要原因。

from itertools import chainntopreason = 1 #change this to allow more reasons to be capturedtop20_dict_values = list(top20_dict.values())
top20_dict_keys = list(top20_dict.keys())shap_values_imp_r = shap_values_imp.copy()
target_values_r = pd.Series(predictions)# Create summarizing labels
top_reasons_all = []
for i in range(shap_values_imp_r.shape[0]):

    shap_feat = shap_values_imp_r.iloc[i]
    shap_feat = shap_feat.iloc[np.lexsort([shap_feat.index, shap_feat.values])]

    topN = shap_feat.index.to_list()[-1:] 
    topN_value = shap_feat.values[-1:]

    topN_idx = []
    for topn in topN:
        for idx in range(len(top20_dict_values)):
            if topn in top20_dict_values[idx] and idx not in topN_idx:
                topN_idx.append(idx)

    #topN_idx = [idx for idx in range(len(top20_dict_values)) for topn in topN if topn in top20_dict_values[idx]]

    #Ordered by increasing importance
    top_reasons = [top20_dict_keys[x] for x in topN_idx]#print(i, topN, topN_idx, top_reasons)top_reasons_all.append(','.join(top_reasons))

shap_values_imp_r['target'] = target_values_r
shap_values_imp_r['top_reasons'] = top_reasons_all

在一个单独的 Jupyter 单元格中,我们将使用 R 来选择用于对评论的 SHAP 值进行分组的最佳聚类数。

%%R -i shap_values_imp_r -w 800 -h 800library(gplots)d_shap <- dist(shap_values_imp_r[1:(ncol(shap_values_imp_r)-2)]) 
hc <- hclust(d_shap, method = "ward.D2")
dend <- as.dendrogram(hc)library(dendextend)
library(colorspace)## Find optimal number of clusters
clusters_test = list()
for (ncl in 2:50){
    clusters_test[[ncl]] <- cutree(hc, k=ncl)
}

这里,我们使用层次聚类,聚类数量在 2 到 50 之间。回到 Python,我们计算每个聚类结果的轮廓分数。通过查看轮廓分数和聚类的可视化来决定要使用的聚类数量。在选择集群数量时,总是需要做出决定。

h_clusters = rpy2.robjects.r['clusters_test']h_clusters_sil = []
cl_id = 0
for cl in h_clusters:
    if cl is not rpy2.rinterface.NULL:
        sil = metrics.silhouette_score(shap_values_imp_r.drop(shap_values_imp_r.columns[len(shap_values_imp_r.columns)-2:], axis=1, inplace=False), 
                                       cl, metric='euclidean')
        h_clusters_sil.append(sil)
        #print(cl_id, sil)
        cl_id += 1
    else:
        cl_id += 1plt.plot(range(2, 51), h_clusters_sil)
plt.title('Silhouette')
plt.xlabel('Number of clusters')
plt.ylabel('Silhouette Index') #within cluster sum of squares
plt.show()

我们使用 Ward 的方法进行聚类,该方法使总的组内方差最小化。在每一步,具有最小聚类间距离的聚类对被合并。合并的高度(见下图)表示两个实例之间的相似性。合并的高度越高,实例越不相似。数据的平均轮廓是评估最佳聚类数的标准。数据实例的轮廓是一种度量,它与它的分类中的数据匹配得有多紧密,与相邻分类的数据匹配得有多松散。剪影得分范围在-1 和 1 之间,最好为 1。在我们的例子中,我们选择 30 个聚类,以便在评论类型中有足够的粒度,并获得大约 0.70 的良好轮廓分数。

%%R -i shap_values_imp_r -w 800 -h 800library(gplots)d_shap <- dist(shap_values_imp_r[1:(ncol(shap_values_imp_r)-2)], 'euclidean') 
hc <- hclust(d_shap, method = "ward.D2")
dend <- as.dendrogram(hc)library(dendextend)
library(colorspace)n_clust <- 30dend <- color_branches(dend, k=n_clust) #, groupLabels=iris_species)clusters <- cutree(hc, k=n_clust)
#print(head(clusters))print(format(prop.table(table(clusters,shap_values_imp_r$top_reasons, shap_values_imp_r$target), margin=1), 
             digit=2, scientific = F))
print(format(prop.table(table(clusters,shap_values_imp_r$top_reasons), margin=1), 
             digit=2, scientific = F))heatmap.2(as.matrix(shap_values_imp_r[1:(ncol(shap_values_imp_r)-2)]), 
          dendrogram = "row",
          Rowv = dend,
          Colv = "NA", # this to make sure the columns are not ordered
          key.xlab = "Predicted - Average log-odds",
          #hclustfun=function(d) hclust(d, method="complete"), 
          srtCol=45,  adjCol = c(1,1))

在上面的热图中,我们将分层聚类(左侧 y 轴)与前 20 个术语的重要性(x 轴,根据评论中相应术语对模型预测的影响而着色的单元格)相结合,前者显示了更接近的相似评论(右侧 y 轴上的数字是评论行号)。

我们可以通过汇总每个集群中的评论来进一步总结上面的热图。为了使这一步更通用,我们假设我们的数据集是一个标签未知的新数据集,并使用 k=1 的 k-最近邻分类器基于聚类结果预测标签。然后,在按预测标签分组后,我们可以聚合每个聚类中的 SHAP 值。

from sklearn.neighbors import KNeighborsClassifiercluster_model = KNeighborsClassifier(n_neighbors=1)
cluster_model.fit(shap_values_imp,rpy2.robjects.r['clusters'])predicted = cluster_model.predict(shap_values_imp_r[shap_values_imp_r.columns[:-2]]) grouped = pd.concat([shap_values_imp, pd.Series(youtube_df['label'].tolist(), name='avg_tgt')], axis=1).groupby(predicted)# compute average impact to model prediction output. 
sums = grouped.apply(lambda x: np.mean(x))

下面的热图显示了 30 个分类(y 轴)中的每个分类的前 20 个术语对模型预测的影响(z 轴上显示的对数优势)。

import plotly
import plotly.graph_objs as go
plotly.offline.init_notebook_mode()data = [go.Heatmap(z=sums[sums.columns[1:-1]].values.tolist(), 
                   y=sums.index,
                   x=sums.columns[1:-1],
                   colorscale='Blues')]plotly.offline.iplot(data, filename='pandas-heatmap')

例如,从热图中,我们可以看到,聚类 30 主要是“喜欢的评论”2 元语法,如果我们查看平均预测标签,我们可以看到这是合法评论的聚类(“总和”数据帧的“avg_tgt”值)。聚类 8 平均来说是垃圾邮件聚类,并且以术语“视图”为主。

我们还可以聚集每个聚类中评论的 SHAP 值,以显示每个聚类中什么“主题”占主导地位。

agg_sums = pd.DataFrame({k: sums[v].mean(axis=1) for (k, v) in top20_dict.items()})data = [go.Heatmap(z=agg_sums[agg_sums.columns].values.tolist(), 
                   y=agg_sums.index,
                   x=agg_sums.columns,
                   colorscale='Blues')]plotly.offline.iplot(data, filename='pandas-heatmap')

第 30 组的意见是

pd.options.display.max_colwidth = 1000cluster_no = 30ex_2 = youtube_df.iloc[rpy2.robjects.r['clusters']==cluster_no]
ex_2_pred = pd.Series(predictions[rpy2.robjects.r['clusters']==cluster_no])
ex_2_top = shap_values_imp_r.iloc[rpy2.robjects.r['clusters']==cluster_no]['top_reasons']ex_2

第 8 组的意见是

结论

在这篇文章中,我展示了如何使用 Shapley 值向模型分数添加信息,这是获得预测标签的“原因”。事实上,一个模型分数应该总是跟随着对这个分数的解释。此外,聚类 Shapley 值可用于识别数据实例组,这些数据实例可以用代表多种原因的更通用的主题来解释。

我要感谢 Sundar KrishnanPraveen Thoranathula 的有益讨论。

💎隐藏的宝石:一个伟大的 PyTorch YouTube 教程系列

原文:https://towardsdatascience.com/hidden-gem-a-great-pytorch-youtube-tutorial-series-by-deeplizard-8de677411bc5?source=collection_archive---------16-----------------------

在你深入研究 fast.ai 源代码之前,一定要看一看

为什么是 PyTorch🔥?

答根据维基百科:

PyTorch 是一个基于 Torch 库的开源机器学习库,用于计算机视觉和自然语言处理等应用。它主要是由脸书人工智能研究小组开发的。

脸书最近在 PyTorch DevCon 2019 上发布了备受期待的 1.3 版本,增加了对谷歌 TPU、PyTorch Mobile 等的支持。另外, The Gradient 发布了一份关于机器学习框架现状的报告,称越来越多的研究人员倾向于将 PyTorch 到 TensorFlow 作为他们的主要框架。如果您正在学习/使用 fast.ai 库,另一个很好的原因是它基于 PyTorch,因为它:

"使用常规 python 代码的所有灵活性和功能来构建和训练神经网络",并且"我们能够处理更广泛的问题"

对我来说,和 PyTorch 一起工作感觉更自然,更像是蟒蛇。一个更好的类比是,使用 TensorFlow 开发机器学习模型就像穿着沉重的盔甲:它很强大,但非常笨重。PyTorch 给你所有的自由和流畅的动作。

Photo from GHYFY

介绍深蜥蜴🐊

Photo from deeplizard vlog — YouTube

但是 PyTorch 的灵活性是有代价的。进入 PyTorch 并不容易。更多的自由意味着你有更多的因素需要考虑,更多的细微差别需要平衡。

这就是为什么一个好的教程会帮助你平滑学习曲线。外面有很多资源。PyTorch 网站上杰瑞米·霍华德的精彩教程是一个很好的起点。然而,如果你想更深入地研究,我建议你看看 YouTube 上 deeplizard 的 PyTorch 教程系列

它简明扼要(尊重观众的时间),相关(基于 PyTorch 1.1),最重要的是,看起来很有趣。它使用了许多简洁的动画/图形编辑技术,使视频引人入胜,令人愉快。生产质量令人印象深刻。

“作秀”让 deeplizard 的教程引人入胜🎭

Chris 非常擅长借助出色的动画和多功能的视频短片,以非常简洁明了的方式解释复杂的概念。他们的视频会让你从头到尾都忙个不停。有几件事非常突出:

动画、插图的大量使用,以及整体的美感

deep lizard uses animation to explain how convolution works

一些 YouTube 视频提供了出色的内容,但缺乏美感,尤其是截屏视频。观众通常大部分时间都要盯着一两个窗口,视觉上很枯燥,容易疲劳。但对深蜥蜴来说不是。这个团队非常擅长创作微妙而又富有美感的动画。即使对于通常是静态的背景图像,他们也创造了一些放大/缩小的效果,使其不那么无聊。动作非常细微,所以不用担心会晕车。许多赏心悦目的东西🍬我会说。

嵌入 TED 演讲、主题演讲和其他教育视频的相关短片

Image from deeplizard @ YouTube

嵌入相关但风格不同的内容的短视频剪辑是使学习引人入胜的另一种方式。如果只有一部分受到刺激,我们的大脑很快就会疲劳。看着同一个场景或者听着同一个人说话,人们不会把注意力保持足够长的时间。至少不花点心思是做不到的。嵌入各种风格的视频剪辑解决了这个问题。你大脑的不同部分变得兴奋,你可以毫不费力地保持学习流程。

男性、女性和一个名为“深蜥蜴”的特殊科幻风格的“人工智能”角色来解释不同类型的问题,增加内容的趣味性

R2D2 and C-CPO from theverge.com

除了频道的两个可爱的 YouTubers 用户[克里斯和曼迪](http://Chris and Mandy),还有一个他们创造的虚拟“人工智能生物”作为第三个画外音。听起来像是星球大战电影里的 C-3PO,不过是女的。它引导浏览者完成调试过程,或者问一些发人深省的隐晦问题,等等。如果你喜欢科幻氛围,你会完全爱上它。同样,不那么无聊,更吸引人。

会员网站上良好的扩展内容

除了视频本身,他们还有一个会员网站,你可以在那里找到额外的学习材料:博客、测验、代码片段和其他额外的资源。它在付费墙后面,但我想说它是视频的一个很好的补充。

结论

T 何主外卖?我觉得他们让 PyTorch 看起来非常简单易懂。我觉得我完全可以在 PyTorch 上完成我的 ML 项目。虽然我只完成了他们的 PyTorch 教程,但我猜他们的其他内容也不错。请随意探索更多,并在下面告诉我您的体验。如果你正在学习 fast.ai 课程,因为它是建立在 PyTorch 之上的,你迟早要加强你的 PyTorch 知识,deeplizard 的教程是一个很好的起点。此处链接:

觉得这篇文章有用?在 Medium 上关注我(李立伟)或者你可以在 Twitter @lymenlee 或者我的博客网站wayofnumbers.com上找到我。你也可以看看我下面最受欢迎的文章!

使用 PyMC3 对福特 GoBike 乘客进行分层贝叶斯建模—第二部分

原文:https://towardsdatascience.com/hierarchical-bayesian-modeling-for-ford-gobike-ridership-with-pymc3-part-ii-23f84fb4a5e7?source=collection_archive---------12-----------------------

Photo by sabina fratila on Unsplash

在本系列的第一部分中,我们探索了使用基于贝叶斯的机器学习模型框架 PyMC3 来构建福特 GoBike 数据的简单线性回归模型的基础。在这个示例问题中,我们的目标是根据前一天的聚合属性预测明天将使用自行车共享的骑行者数量。那个微不足道的例子仅仅是我们展示我们的贝叶斯笔触的画布。

总结一下我们之前的尝试:我们根据数据建立了一个多维线性模型,我们能够了解权重的分布。这与标准线性回归模型相反,在标准线性回归模型中,我们接收点值属性。这些发行版可能非常强大!你的模型有多确定特性 i 驱动你的目标变量?对于概率编程,它被打包在你的模型中。我们将我们的模型结果与来自熟悉的 sklearn 线性回归模型的结果进行了匹配,并基于 RMSE 度量发现了奇偶校验。

Some fairly strong correlations in our data.

老实说,我会在一个模型上花费更多的时间和精力来获得同样的结果吗?即使对模型输出有稍微好一点的理解?大多数情况下可能不会。我想了解的结果。我们可以通过贝叶斯推理模型来实现这一点,而 PyMC3 非常适合实现这一点。

PyMC3 最擅长的特性之一是可定制的模型。我以前对这个问题的了解可以融入到解决方案中。可以估计测量不确定度。我可以解释许多偏差、非线性效应、各种概率分布,这样的例子不胜枚举。有了sk learn或者Spark ml lib这样的包,我们作为机器学习爱好者就被赋予了锤子,我们所有的问题看起来都像钉子。有了 PyMC3,我有了一台 3D 打印机,可以为这项工作设计一个完美的工具。

您可以从 PyMC3 中学到的最简单、最具说明性的方法之一是层次模型。很多问题都有结构。在一周的不同日子(季节、年份……)人们有不同的行为。气候模式不同。如果我们用标准方法设计一个简单的 ML 模型,我们可以对这些特性进行热编码。我们的模型会学习这些权重。我们还可以为我们正在研究的问题的每个版本建立多个模型(例如,冬季与夏季模型)。

事实是,我们在这里丢弃了一些信息。单个模型可以共享一些潜在的特征。在分层贝叶斯模型中,我们可以学习模型的粗略细节特定上下文的微调参数。我们的福特 GoBike 问题就是一个很好的例子。如果我们绘制前一天(X)的所有数据,并查看第二天(第二天)的乘客数量,我们会看到不同斜率的多重线性关系。在上一篇文章中,我们有效地在大量数据中画了一条线,这使得 RMSE 最小化。当然,我们有一个非常好的模型,但是看起来我们似乎遗漏了一些重要的信息。

如果我们只绘制星期六的数据,我们会看到分布更加受限。真实的数据当然是杂乱的,而且线性关系是分散的。然而,与上面的分布相比,两者形成了鲜明的对比。那怎么办呢?我们可以简单地为一周中的每一天建立线性模型,但是对于许多问题来说这似乎很乏味。我猜,虽然周六和周日可能有不同的斜率,但它们确实有一些相似之处。一个聪明的模型也许能够从他们共享的关系中收集一些有用的信息。

让我们建立一个简单的层次模型,只有一个观察维度:昨天的骑手数量。我们的目标变量仍然是今天预测的乘客数量。我们从两个非常宽的正态分布开始, day_alphaday_beta 。把这些想象成我们粗略调整的参数,模型截距和斜率,我们不能完全确定的猜测,但是可以分享一些共同的信息。从这些广泛的分布中,我们将估计我们微调过的 alpha beta 的星期几参数。这就是等级发挥作用的地方: day_alpha 将会有一些正斜率的分布,但是每天都会略有不同。星期一的斜率( alpha[0] )将是从 day_alpha 的正态分布得出的正态分布。星期三( alpha[1] )将分享星期一的一些特征,因此将受到 day_alpha 的影响,但在其他方面也将是独特的。这就是层次模型的神奇之处。

一旦我们实例化了我们的模型,并用 NUTS 采样器训练了它,我们就可以检查最适合我们问题的模型参数的分布(称为轨迹)。我们可以看到我们的 day_alpha ( 分级截距)和 day_beta (分级斜率)都是非常宽的形状,并且分别以大约 8.5 和大约 0.8 为中心。向下移动到每一天的αβ参数,它们在分级参数的后验分布中唯一分布。一些斜率( beta 参数)的值为 0.45,而在高需求日,斜率为 1.16!

此外,每天的参数看起来都建立得相当好。我们可以看到这一点,因为分布是非常集中的峰值(左侧图),本质上看起来像一条跨越最后几千条记录的水平线(右侧图)。

我们也可以从数字上看到轨迹分布。到目前为止,分层的 alpha 和 beta 值具有最大的标准偏差。相比之下,每一天都受到很好的约束,差异很小。

和上一个模型一样,我们可以通过 RMSE 来检验我们的预测。在训练集,我们有一个微不足道的+/- 600 骑手误差。在我们故事的第一部分中,我们的 6 维模型有 1200 个骑车人的训练误差!

我们看不见的(预测的)数据也比我们以前的模型好得多。sklearn LR 和 PyMC3 型号的 RMSE 约为 1400。这个简单的 1 功能模型比我们以前的版本强大 2 倍。

我们甚至可以把它变得更复杂。如果对于我们之前模型中的 6 个特征中的每一个,我们都有一个分层的后验分布,那会怎么样?我们可以在我们的模型中添加一层又一层的层次结构、嵌套的季节性数据、天气数据等等。

在 PyMC3 中,您可以非常灵活地构建模型。这绝对比使用预先打包的方法花费更多的时间,但是理解基础数据、模型中的不确定性和误差的最小化的好处可以超过成本。

像往常一样,随时查看 Kaggle 和 Github repos。请在下面添加评论或问题!感谢您的阅读。

[## 分层 _MVP | Kaggle

编辑描述

www.kaggle.com](https://www.kaggle.com/franckjay/hierarchical-mvp)

Github 回购

分级神经结构搜索

原文:https://towardsdatascience.com/hierarchical-neural-architecture-search-aae6bbdc3624?source=collection_archive---------27-----------------------

许多研究人员和开发人员对神经架构搜索可以为他们的深度学习模型提供什么感兴趣,但被巨大的计算成本吓住了。已经开发了许多技术来促进更有效的搜索,特别是可区分架构搜索、参数共享、预测性终止和架构的分层表示。

本文将解释分层表示的概念,因为这是实现效率和充分表达的搜索空间之间的平衡的最简单的方法。神经网络的这种表示是如此强大,以至于您可以通过随机搜索获得有竞争力的结果,从而消除了实现贝叶斯、进化、强化学习或可微分搜索算法的需要。

30 秒内分级神经架构搜索:

这个想法是将更大的结构表示为它们自身的递归组合。从一组构建块开始,如 3x3 可分离卷积、最大池或身份连接,我们用一组预定义的节点构建一个微结构。在构建下一级结构时,以前发现的结构被视为与初始构建块相同。关键思想是递归组合。

原始论文测试了这一层次的两个级别,如下所示。在下面的例子中,第一层有一个人类编码的 3 个节点和一个人类编码的 3 个单元,第二层有一个人类编码的 4 个节点和一个人类编码的 1 个单元。如果这种粗体字体看起来多余,我很抱歉,但强调神经架构搜索算法中插入的先验/偏见是很重要的。

作为算法的人类设计者,层次表示的超参数包括原语操作、层数、每层的结构数以及每层包含的节点数。上面的示例演示了 3 个基本操作(1x1 conv、3x3 conv、3x3 最大池)、2 个级别、第一级的 3 个节点和第二级的 4 个节点,以及第一级的 3 个结构和第二级的 1 个结构。

对此感兴趣的两个快速理由:

  1. 给定这种表示,即使随机搜索也能很好地执行。这些架构被编码为一系列邻接矩阵,对角线上是 0,对角线左侧是 0,以呈现 DAG。Dag 在解码时服从神经网络的拓扑排序。在这些 DAG 邻接矩阵的右侧随机填充每一层可用的不同操作效果非常好。与论文中测试的更复杂的进化搜索相比。
  2. 由此产生的架构具有理想的稀疏性,如下图所示:

从参数计数的角度来看,这种稀疏性是非常可取的,其他的神经网络设计理论超出了本文的范围。

层级与平面表示

基本区别是 11 节点邻接矩阵 4 个独立的 4 节点邻接矩阵和 1 个 5 节点邻接矩阵。

首先,像直接编码 11 个节点的 DAG 这样的平面表示会有非常密集的连接,不像上图中的渲染单元。这导致网络具有高得多且不必要的参数计数。其次,这些细胞的组合学要复杂得多。拥有如此高的组合学使得搜索空间不可行。

Flat Representation DAGs (Combinatorics)11 nodes results in OPS^n(n-1)/2 different ways to encode them
ex: 6 operations, 11 nodes --> 6^55 possible architectures

分层表示的组合爆炸要低得多,并且可由搜索的人类设计者高度控制。

Hierarchical Representation DAGs (Combinatorics)
6 primitive operations, 4 nodes in level 1
OPS^n(n-1)/2 --> 6^6 ways to encode each level 1 structure5 level 1 structures, 5 node in level 2
OPS^n(n-1)/2 --> 5^10 ways to encode each level 2 structure4(6^6) level 1 structures * 1(5^10) level 2 structures6^24 * 5^10 (Hierarchical Rep.) << 6^55 (Flat Rep.)

虽然 6 ⁴ * 5 ⁰仍然是一个巨大数量的可能的结构,它明显少于 6⁵⁵.

我希望这篇文章能帮助你理解神经结构搜索中的层次表示背后的思想,这使得搜索更加有效!感谢您的阅读,如果您有进一步的兴趣,请查看下面的视频!

分级 RNNs,训练瓶颈和未来。

原文:https://towardsdatascience.com/hierarchical-rnns-training-bottlenecks-and-the-future-415788192773?source=collection_archive---------16-----------------------

Image source

众所周知,标准反向传播算法是计算神经网络中损失函数相对于其参数的精确梯度的最有效的方法。所谓有效,我的意思是给定固定的网络架构,其计算成本总是与计算损耗的成本相同(例如,给定分别具有 I、j、k 和 l 个节点的 4 层前馈网络,具有“t”个训练实例的一个时期的总时间复杂度将总是 O(t*(ij + jk + kl)) )。

可微性和连续性公理告诉我们,对于一个在点 x_ 0 可微的函数,它在定义域中的每一点都必须是连续的。这进一步要求反向传播中涉及的所有参数。必须拥有连续的值。然而,情况可能每次都不一样;相反,我们可能希望有一个由神经元组成的网络,这些神经元在不同的时间尺度上对时间事件做出艰难的随机决策——0/1 值表示文本中的单词/短语边界或视频中故事片段的结尾。这种二进制输出进一步引入了可用作正则化技术的稀疏表示,从而允许设计选通单元来选择对于给定实例实际上需要计算模型的哪一部分。[1]

这可以用下面的例子来解释。设 x 是神经元的输入,其值决定神经元是否输出尖峰(1)或(0)。定义函数 f 的一种方式是二进制化的 ReLU 激活:

f(x) = {1 如果 x ≥ 0 否则 0

然后我们可以观察到,除了阈值,f 的导数都是 0,也就是说,当它等于∞时,导数是 0。这意味着在用 f 训练网络时,任何基于梯度的学习在这些点都是不可能的,因为权重将与零梯度相乘,因此没有更新。因此,反向传播失败!

ℚ.等等,但是什么样的网络可能需要这样的神经元呢?

这正是我们的交易——分级递归神经网络(HRNNs)的目的。简而言之,HRNNs 是一类堆叠 RNN 模型,其设计目标是对序列数据(文本、视频流、语音、程序等)中的层次结构进行建模。).在文本的上下文中,这些层次结构可以构成最低层的字符,这些字符组合形成单词,单词组合形成句子,而在计算机程序的上下文中,这些层次结构可以指调用子模块的模块。因此,关键思想在于更新属于对应于数据中的层级层的堆栈的不同层的神经元的权重。

那么,我们如何决定属于堆栈不同层的内容呢?一个可能的想法是让二进制神经元,如上所述,具有 0/1 输出,指示当前时间步长的输入是否属于与先前处理的输入相同的层级。HRNNs 也是基于同样的原理。能够捕捉这样的层次结构有助于他们解决典型 rnn 的缺点,典型 rnn 可以构造顺序敏感但结构无知的文本中单词的表示。

ℚ.好吧,那么我们如何训练需要这种二元决策的网络呢?

迄今为止,存在两种广泛使用的用于训练这种网络的方法:(a)梯度估计技术,其将二进制神经元训练为网络的组成部分,以及(b)基于策略梯度的强化学习方法,其通过创建状态-动作对的映射来决定在观察特定输入时采取什么动作,从而绕过对二进制神经元的需要。我们将使用两类能够在文本中学习多层抽象的 HRNNs 来浏览它们。

1.分层多尺度递归神经网络(HM-RNN)

下图描绘了 HM-RNN 模型【1】的清晰结构:

为了决定上面提到的 0/1 边界决策,HM-RNN 在每一层使用边界检测器(比如, z )。这些自适应地基于三个操作来确定权重的更新时间:

  • 更新:类似于 LSTMs 中通常的更新规则。
  • 复制:保留当前层的全部状态,不丢失任何信息
  • FLUSH :将当前段的汇总表示弹出到上层,然后重新初始化状态以处理下一段。

现在应该很清楚,边界检测器只不过是我们之前讨论过的相同的二进制神经元。但是它们可能还有其他用途吗?答案是肯定的,取决于当前时间步 t 和当前层 lz 的值以及前一时间步 t-1 和层 l-1 的值:

  • 如果在层 l 和步骤 t-1 处 z = 0,并且在层 l-1 和步骤 t 处 z = 1,这意味着已经在较低层检测到边界(即,字结束),因此,执行更新以反映从较低层获得的汇总信息。
  • 如果在(l,t-1)和(l-1,t)处 z = 0,这意味着在任一级都没有识别出边界,因此,执行复制操作只是为了保存来自先前神经元的信息。
  • 如果在(l,t-1)处 z =1,这意味着在前一时间步检测到边界(即,短语结束),现在,执行刷新操作以将当前神经元的表示传输到上层神经元,同时重新初始化其单元状态。

因此,边界检测器的使用消除了每个时间步的更新操作。因为更新动作包括 RNN 单元中操作复杂性的主要部分,省略它在总时间成本【2】上给予良好的增益。现在,问题仍然存在:我们如何计算边界检测器神经元的梯度(0/1 输出)?

这就是直通估计器发挥作用的地方。这个想法很简单。让我们回忆一下上面定义的函数 f 。我们现在进行两步训练:

  1. 在正向传递过程中,我们保持神经元的输出不变。由于输出由 0/1 值组成,我们可以用逐位运算优雅地取代大多数算术运算。因此,二进制神经元被认为可以显著减少内存大小和访问【3】
  2. 在反向传递期间,不是计算 f,的导数,而是将其输入梯度设置为等于其输出梯度的阈值函数。由于后向传递涉及将梯度设置为固定值,直通估计器属于有偏估计器的范畴。

2.分级结构 lstm(HS-lstm):

研究了 HMRNN 的基本原理后,现在让我们来看看另一个模型,即。HS-LSTMs。

框架【4】由三部分组成:结构化表示网络为每个输入单词分配一个状态“s ”,并接收来自策略网络(P-net)的反馈,该策略网络基于随机策略π(α| s;θ).使用的两个结构化表示模型是:信息提取 LSTM (ID-LSTM)和 HS-LSTM,两者都将动作翻译成结构化表示。然后,分类网络(C-net)使用学习到的表示进行预测,并相应地向 P-net 提供策略学习的奖励。

回到 HS-LSTM,该模型具有与前述 HRNNs 类似的架构。然而,代替 0/1 边界检测器,我们现在依赖于策略梯度方法,该方法逐渐学习策略来为每个状态(即,单词)选择更好的动作(即,短语结束或短语内部)。HS-LSTM 仅在 p-net 已经对其所有单词的动作进行采样之后才确定句子的结构化表示。p-net 因此在延迟奖励策略上运行。

下一个至关重要的步骤是使用加强算法,这是一种基于梯度的技术,通过增加政策在给定状态下做出有益行为的概率来更新政策权重:

未来

综上所述,我们看到,以捕获时间序列中的层次结构为最终目标的分级 rnn 家族依赖于识别边界来分离多层层次结构。在基础层面上,目标是对底层数据的组合性进行建模。正如彭博著名认知科学教授艾伦·l·尤耶最近在的博客文章中优雅地解释的那样, 组合模型 通过学习数据的结构和子结构的结构化表示来工作。由于大多数现实世界数据中出现的组合爆炸问题,组合性原则旨在开发可解释的模型,并可以生成样本,从而使错误更容易诊断。虽然已经发现这一特性在视觉领域有很大帮助(通过引入对抗攻击的鲁棒性),但是 NLP 领域也有可预见的好处。

“这个世界是合成的,或者上帝存在。”—斯图尔特·格曼

在这一点上,你一定想知道是什么让我在结束这篇文章时得出了组合性原则。事实上,在层次化 rnn 想要捕捉的结构化表示和我们正在谈论的组合语义[3]之间有着根深蒂固的联系。这就把我们带到了我们的最终目的地——分布假设 。根据语言的语义理论,这一假说认为一个词是由它的同伴来表征的。因此,在相同的上下文中使用的单词倾向于表达相似的意思。从我们通过分层 rnn 识别的子结构的角度来考虑这个问题,会给出一个清晰的视图。每个子结构/短语现在可以被认为是具有相似分布并且语义一致的单词。因此,很明显,复合模型,如神经模块网络【5】——由联合训练的神经模块集合组成的模型,其架构足够灵活,可以捕捉深度网络的表示能力和文本中的复合语言结构,可能是分层递归神经网络的未来!

参考资料:

[1] Chung,j .,Ahn,s .,& Bengio,Y. (2017)。分层多尺度递归神经网络。 CoRR,abs/1609.01704

[2]张,s .,吴,y .,车,t .,林,z .,梅米塞维奇,r .,萨拉赫胡季诺夫,r .,&本吉奥,Y. (2016)。递归神经网络的结构复杂性度量。辊隙

[3]胡巴拉,I .、库尔巴里奥克斯,m .、苏德里,d .、亚尼夫,r .、&本吉奥,Y. (2016 年)。二值化神经网络。 NIPS

[4]张,汤,黄,米,赵,李(2018).通过强化学习学习文本分类的结构化表示。 AAAI

[5]j . Andreas、m . rohr Bach、t . Darrell 和 d . Klein(2016 年)。神经模块网络。 2016 年 IEEE 计算机视觉与模式识别大会(CVPR) ,39–48。

带人工智能的高频交易(HFT):简化

原文:https://towardsdatascience.com/high-frequency-trading-hft-with-ai-simplified-a24c00da72e0?source=collection_archive---------10-----------------------

让我们来看看高频交易这个竞争激烈的世界,以及人工智能是如何成为其中一部分的。

我为什么关心交易?

高频交易(HFT)是一种复杂的算法交易,在这种交易中,大量订单在几秒钟内被执行。它增加了市场的流动性,让难以置信的大量资金在每一秒钟内流过市场。

自从几十年前出现以来,高频交易已经成为吸引个人和公司巨额利润的来源。这就像切蛋糕,虽然大公司得到了更大的一块,但请放心,每个来的人都会得到蛋糕。

我需要知道什么?

高频交易是基于一种叫做订单簿的东西。在任何给定时刻,该订单簿包含产品/库存/商品的前几名出价要价

让我给你分析一下。你通过下单与市场互动。你发出的每一个订单要么是出价要么是要价。出价是你愿意支付的购买股票的金额,而要价是你愿意出售股票的金额。如果有人愿意比你支付更多(更高的出价)或想要更少(更低的要价),他们在订单簿中的位置就在你之上。

但是等等,交易还没结束呢!!你所做的就是下订单。需要有人来匹配你的价格,交易才能完成。或者你可以去匹配别人的价格。在正确的时间买入和卖出,以最大化你的利润,这基本上是高频交易的游戏名称。

听起来很简单!!

理论上,是的。那么我们开始交易吧!!哦,但是在你这么做之前,让我告诉你,这是行不通的。正如我前面提到的,这是一种算法交易风险,这是有原因的。

高频交易发生在几分之一秒内。单靠人类进行高频交易是不可能的。当你阅读市场趋势并出价时,市场已经改变了它的趋势!!这就是为什么我们需要计算机可以为我们执行并出价的算法。

AI 呢?

显然,当谈到自动化任务时,人工智能是首选。已经有许多机器学习算法和特征创建技术应用于该领域。其中最常见的是支持向量机。

粗略地说,SVM 正在数据中制造一条分界线。模型被训练以识别指示市场定价即将增加或减少的特征,并相应地出价。它们非常成功,以至于大多数高频交易公司都在交易模块中集成了这种模型。

但是为什么不“深入”呢?

HFT 是一眨眼的事情。模型不仅需要准确,还需要非常快,否则它们的准确性就没用了!!虽然深度学习方法在准确性方面非常成功,但也带来了繁重计算的诅咒。正因为如此,HFT 还没有像其他领域一样看到深度学习的巨大注入。

然而,随着硬件实现和 GPU 提供的处理能力越来越复杂,人们可以开始考虑尝试将深度学习纳入 HFTs。虽然最近有一些论文尝试用神经网络进行价格预测,但要成功运行能够实际产生利润的模型,还有很长的路要走。

下一步是什么?

HFT 不仅仅是软件。由于时间延迟变得非常重要,HFT 已经间接加速和激励了更好的硬件设计。

近年来另一个非常有趣的发展是强化学习在 HFT 中的应用。试图创造一个可以从错误中学习并交易以获取最大利润的代理似乎是一条显而易见的道路,但由于其计算的复杂性,直到最近才被探索。

注来自《走向数据科学》的编辑: 虽然我们允许独立作者根据我们的 规则和指导方针 发表文章,但我们不认可每个作者的贡献。你不应该在没有寻求专业建议的情况下依赖一个作者的作品。详见我们的 读者术语

这个博客是努力创建机器学习领域的简化介绍的一部分。点击此处查看完整系列

[## 机器学习:简化

在你一头扎进去之前就知道了

medium.com](https://medium.com/@prakhargannu/machine-learning-simplified-1fe22fec0fac)

或者干脆阅读系列的下一篇博客

[## 自动文本摘要:简化

了解自动文本摘要的世界

towardsdatascience.com](/automatic-text-summarization-simplified-3b7c10c4093a)

参考

【1】迈克尔·卡恩斯(Michael Kearns)和塞维多夫·内夫米瓦卡(Michael Nevmyvaka),用于市场微观结构和高频交易的机器学习
【2】阿轧曼蒂奥斯·恩塔卡里斯(Adamantios Ntakaris)和马丁·马格里斯(Martin Magris)和朱霍·坎尼艾宁(Juho Kanniainen)和蒙塞夫·加博伊(Moncef Gabbouj)和亚历山大·约西菲迪斯(Alexandros Iosifidis),限价单簿数据中间价预测基准数据集,2017 年
【3】加内什、普拉哈尔(Prakhar)和普内特·拉赫贾(Puneet Rakheja)。"高频交易中的深度神经网络."arXiv 预印本 arXiv:1809.01506 (2018)。

神经网络的高级介绍

原文:https://towardsdatascience.com/high-level-introduction-to-neural-networks-51cb0a088d7a?source=collection_archive---------20-----------------------

Photo by Daniel Hjalmarsson on Unsplash

在数据科学、机器学习或人工智能领域呆上一段时间,你肯定会碰到神经网络。问它们是什么,大多数人会说,“它就像一个大脑,有很多相连的神经元”。但这意味着什么呢?

这种与人脑的关系有一定的真实性,因为在它们的核心,神经网络是由模拟神经元的尝试激发的(由于许多原因,模拟神经系统一直是一个大话题)。发现它们对于执行二元分类问题是很好的,在二元分类问题中,对象可以属于一个类别,也可以不属于一个类别(即,它是“猫”还是“狗”)。正是从这一点出发,我们将选择最简单和最不复杂的人工神经网络来构建我们关于神经网络如何工作的知识:感知器。

感知器

感知器诞生于 1958 年,是最长寿的机器学习算法之一,你最有可能知道它,并且在你的现代数据科学和机器学习工具包中可以找到它。

作为一个有趣的旁白,感知机有着可疑的荣誉,既刺激了大量的研究投资,也导致了该领域的一些停滞不前(称为人工智能冬天)。它被吹捧为能够做从自然语言到图像识别的大量事情,但这种吹嘘是导致 10 年停滞不前的原因之一,当时感知机的局限性被发现,主要是感知机只能解决线性可分的问题(我将在后面解释)。

那么,什么是感知机呢?

形象化的最好方法是观察一个神经元:

Fig 1. A very simple representation of a typical Neuron

神经元的工作方式是从其树突接收信号,并根据这些输入决定是否要发送信号(根据强度以及它对接收的每个信号给予的权重或考虑)。如果是的话,那么这个信号就沿着它的轴突传播,并通过轴突末端离开。这个终端连接到另一个神经元,同样,树突是神经元从与之连接的神经元接收信号的地方。这些神经元一起形成了一个复杂的连接网络,能够完成一些令人惊叹的壮举,例如写这篇文章(即我的大脑)。

感知器是神经元的数学表示,看起来像这样:

Fig 2. Visual representation of a Perceptron

感知器接收一系列信号(X 值),并在函数(F)中使用它们来决定输出是什么。因为我们想要调整输出,所以需要给每个输入信号(W)一个权重,以获得最佳输出。赋予该函数的值仅仅是权重乘以信号并相加。

对于一个简单地输出它接收的总信号的函数,它看起来像这样:

Fig 3. Example output for a Perceptron

在上面的例子中,我们接收信号 1 和 2,权重分别为 3 和 0.5。这意味着输出是 13+20.5=4.0。

您可能会看到,如果这两个信号中的一个保持不变,而另一个允许变化,那么您就创建了一个线性回归函数:

y = m*x + c

其中,m 是变化的输入的权重(回归中的斜率),c 是从不变化的输入的输入(它是常数或回归的截距),y 是函数的输出。

然而,虽然感知器可以被修改来执行线性回归,但它的许多工作都是围绕分类进行的,在分类中,它会尝试确定数据点是否属于一个组或另一个组。另一个重要的概念是偏见。在回归示例中,保持不变的输入类似于截距,因此可以在不修改斜率的情况下移动直线(否则直线将始终通过图表上的零点)。在神经网络中,这种偏差可以添加到感知器中,以改善它们的行为(通常可以通过预测准确性的提高来看出)。否则,如果输入特征都是零,那么感知器只能输出零。增加一个偏差使这种行为变得不同。

例如:

Fig 4. Classifying blue and green points with a Perceptron (the decision boundary is in Orange)

在这个例子中,我们有绿色和蓝色的点,我们希望感知器能够根据它们在图上的位置告诉我们哪个是哪个。为了做到这一点,它画了一条直线,一边的任何东西都属于一组,另一边的属于第二组。

但是它是如何处理数字的呢?

最简单的方法是,我们替换之前使用的返回加权输入总和的函数,并替换为返回总和值的符号的函数。如果它返回正值(+ve),则它属于蓝色组,而负值(-ve)则属于绿色组。然后是调整权重的情况,直到感知器使用数据的最佳拟合线(图 6 中的橙色虚线)。

Fig 5. An example Perceptron giving a classification prediction

线性可分的问题

查看图 4 中给出的示例,您可以看到感知器可以清楚地绘制一条线来完美地分隔各组,这就是我之前所说的线性可分的意思。只有当感知器能画出一条直线时,它才能完美地区分各组。这就是它的问题所在——如果有多个组,或者它们稍微混杂在一起,那么它就无法将它们分开。

这是感知器的问题之一,因为它只能将事物分成两组,并且它们必须很好地分开才能完美地工作。

值得注意的是,感知器的许多问题可以通过将它们链接在一起来解决。我的意思是,输入馈入几个感知器,这些感知器的输出馈入另一层感知器,以此类推,直到我们得到最后一层,给出我们的最终输出。这被称为多层感知器(MLP,图 6)。这些通常使用不同的函数(称为激活函数,因为它决定感知器是否给出输出),这取决于期望的 MLP 行为(例如分类或回归)。

Fig 6. Example of an MLP where every layer is a different colour and all Perceptrons are connected to each other (some connections are missing for legibility)

将这一切结合在一起

为了将更准确的标签(和一些进一步的阅读链接)放在感知器上,我们有:

  • 信号在感知器中以一种方式传播,并给出一个单一的输出(其中信号只在一个方向上传播,没有返回,这被称为前馈算法)
  • 我们将一组输入标记为 X0、X1 等。
  • 感知器可以有任意多的输入
  • 每个输入都有一个权重(W0,W1 等等。)
  • 加权输入被输入到一个激活函数(例如我们正在使用的符号函数)
  • 调整权重使得感知器能够通过改变输入的权重来调整它的答案,如果它得到的答案是错误的
  • 这种对权重的调整被称为梯度下降,在这里我们最小化函数的误差
  • 可以改变激活函数来改变感知器输出的行为
  • 也可以在感知器输入中加入一个偏差来改善行为

拿走

我们已经研究了最基本的神经网络,它的局限性,并讨论了它在更高层次上的功能。它可以执行分类,并且通过改变激活函数,它还可以用于回归问题。

如果你想更深入地了解感知机(以及后来的 MLP)的数学和结构是如何工作的,那么我怎么推荐 YouTube 上关于从头开始构建的神经网络的视频都不为过(它们从简单开始,逐渐变得越来越强大)

链接:

基于 Oracle 云和 H2O 的高性能机器学习

原文:https://towardsdatascience.com/high-performance-machine-learning-on-oracle-cloud-with-h2o-b60acc8815fa?source=collection_archive---------29-----------------------

Running on a multi-CPU VM

介绍

如果你读一本关于机器学习(ML)的介绍性书籍,那么开发一个模型似乎总是一件容易、有趣和美好的任务。在真正的商业案例中,现实是完全不同的。

在现实世界中,开发一个有效的模型可能是一项困难而漫长的任务。为了实现良好的预测能力,您需要大量的数据(越多越好),并且经常需要使用不同的算法进行多次尝试,以便为模型的超参数定义最佳值。

这就是为什么你经常需要高计算能力,以便能够在合理的时间内迭代许多次执行。

因此,能够使用底层基础设施的所有可用 CPU 并进行扩展的 ML 算法的可用性对于能够在期望的时间框架内实现您的业务目标至关重要。

正是在这种背景下,像 H20 这样的框架可以成为整个解决方案的重要组成部分。

在这个主题的第一个故事中,我想快速描述什么是 H2O,并提供我在 Oracle 云基础设施(OCI)上进行的一些测试的一些细节,以验证 H2O ML 框架的可扩展性和性能。

闪闪发光的 H2O。

H2O.ai 是一家硅谷公司,其宣称的使命是:“为每个人民主化人工智能”。换句话说,使采用 ML 技术解决商业问题变得更加容易。

他们提供的核心是 H2O (现在版本 3,H2O-3)。最好的描述可以在他们的网站上看到:

“H2O 是一个完全开源的分布式内存机器学习平台,具有线性可扩展性。H2O 支持最广泛使用的统计和机器学习算法,包括梯度增强机器、广义线性模型、深度学习等。H2O 还拥有行业领先的 AutoML 功能,可自动运行所有算法及其超参数,生成最佳模型排行榜”。

所以,关键成分是:

  • 支持最重要的“经典”算法,用于回归和分类,有监督和无监督:GLM,朴素贝叶斯,SVM,K-Means,PCA
  • 支持更现代和“最先进”的算法,如分布式随机森林、梯度推进机(GBM)、XGBoost、堆叠集成、隔离森林、深度神经网络(DNN)
  • 内存计算
  • 一种能够使用单个虚拟机上的可用核心,并在连接节点的群集上线性扩展,同时仍使用所有可用核心的实施
  • Python、R、JavaScript 的客户端库
  • AutoML
  • 基于 POJO(和 MOJO)的训练模型的简单部署

除了 H2O,你还可以使用:

  • H2O4GPU ,提供上述算法的实现,运行在 NVIDIA GPU 上
  • 苏打水,运行在 HadoopApache Spark 集群之上的实现,用于大数据环境

该实现具有客户端-服务器架构:核心是一个提供 REST 接口的 JEE 应用程序(h2o.jar)。提供了支持 Python、R 和 JavaScript 编程的库。

H2O architecture (from h2o.ai official documentation)

此外,还提供了一个不需要任何编码的图形化的“基于笔记本”的交互界面:它被称为

使用 Flow,如果你知道你在做什么,你可以不写一行代码就完成开发和测试你的模型的整个旅程。很好也很有成效。

最后,但同样重要的是,H2O 也有重要的 AutoML 功能:要搜索最佳模型,你可以简单地定义搜索边界(哪些算法),让引擎搜索所有的算法和超参数空间。

为了完整起见,H2O.ai 还出售一款名为无人驾驶 AI 的授权产品。无人驾驶人工智能使模型的开发、测试和可解释性变得更加容易,拥有一个漂亮的深色用户界面。

Driverless AI (from H2O.ai site).

测试。

在和 H2O 玩了一段时间后,我决定在甲骨文云基础设施(OCI)上建立一个测试环境来验证:

  • H2O 的性能和可扩展性
  • 在某种程度上,用大量数据开发一个模型是多么容易

我决定使用的数据集是“ 希格斯数据集 ”。这个数据集想要解决的问题非常有趣:如何使用机器学习技术快速识别高能粒子(著名的希格斯玻色子)。你可以在网上找到许多关于这个挑战的文章。

该数据集包含 1100 万个样本。磁盘上的大小约为 8 GB。它以 CSV 文件的形式提供。第一列(values: 0,1)包含标签(1 表示:是真正的希格斯玻色子,0 表示“噪音”);其他 28 列包含代表从探测器测量的运动学数据的数值。你可以在 UCI 机器学习库找到数据集的完整描述。

我决定采用这个数据集的主要原因是,它是一个大型数据集,并且经过一些变化,它已经在一个著名的 Kaggle 挑战赛中使用过。另外,我已经意识到这个分类任务并不容易。

测试基础设施是在 OCI 建立的 2 虚拟机集群。每个虚拟机有 24 个 OCPU(核心)。这两个虚拟机通过 OCI 提供的高性能、非超额订阅网络连接。数据的共享存储是使用文件存储(NFS 装载)实现的。H2O 集群的两个节点之间的通信设置为使用单播。

Test Environment on OCI

我已经决定建立一个基于希格斯数据集的梯度推进机模型。梯度推进是基于决策树(DT)的所谓“集成模型”的一部分。GBM 的基本思想是迭代地改进 DT 的性能,将权重应用于先前模型不能很好工作的样本。

这些是我为模型采用的(非默认)参数(在一些试验后定义):

ntrees      1000
max_dept    10
min_rows    10
learn_rate  0.05

大量的树和小的学习率增加了训练模型所需的计算能力。但是使用大量 OCPU,训练所需的时间可以保持较小。

模型的开发。

如前所述,模型的整个开发都是使用 H20–3 的 Web UIFlow完成的。我没有写过一行代码。

在默认设置中,可以通过端口 54321 访问 H2O 流。

H2O Flow UI starting page

以下是开发模型所需的步骤列表:

  1. 导入文件
  2. 设置文件解析;将列 C1 标记为枚举(标签)
  3. 解析文件
  4. 验证没有缺失值
  5. 训练/验证集中的分割(数据)帧(90%,10%)
  6. 建立模型;从菜单中选择 GBM 设置非默认值(见上表)

结果。

最后,结果如下:

构建时间 : 9 分钟。13 秒。

得分历史:

从评分历史中,您可以看到,在 500 棵树之后,性能没有显著提高,并且(有待确认)没有大的过度拟合(训练集和验证集之间的性能差异)。

GBM 还为您提供了一个衡量特征重要性的方法,我们可以据此决定开发一个更简单的模型,例如,只使用前 10 个特征:

最后,在验证集上计算的混淆矩阵:

The Confusion Matrix

混淆矩阵非常有趣(它证实了这个问题并不简单):

  • 在 1 类样品(真玻色子)上,达到的精度是 0.87
  • 在 0 类样本(噪声)上,精度仅为 0.58

从全球来看,该模型的准确率约为 73%。还不错。但该模型在 0 类样本上表现不佳。当然还有改进的余地,但整个练习只花了我半天时间。事实上,在这种环境下,训练所需的时间只有 10 分钟左右。让我安心。

比较在训练集和验证集上计算的混淆矩阵,我们可以确认没有过度拟合。

改进的想法:

  • 我首先会尝试使用 AutoML 。使用 AutoML,我们可以定义探索的边界(使用哪些算法),并让引擎尝试找出具有最佳参数的最佳模型。这需要更多的时间(几个小时)
  • 第二个是尝试堆叠的系综。

最后一个问题:引擎能够充分利用 24+24 OCPU 吗?答案是肯定的!在两个节点上运行的“htop”实用程序证实,H2O 以 100%的 CPU 利用率全速运行(本文开头的第一张图片是来自一个节点的“htop”报告)。

结论。

从我所做的测试来看,H2O 和甲骨文 OCI 公司似乎是一个很好的组合,为开发机器学习模型提供了一个高性能易于使用的平台。

Github 上评分最高的 ML 项目

原文:https://towardsdatascience.com/highest-rated-ml-projects-on-github-694486293512?source=collection_archive---------7-----------------------

不可能什么都懂。然而,这 5 个值得一看。

机器学习作为一个领域,正在以极快的速度发展。Github 是全世界都在看的白板。高质量的代码被定期发布在无限的智慧板上。

Photo by Morgan Harper Nichols on Unsplash

显然不可能跟踪机器学习世界中发生的所有事情,但 Github 对每个项目都有一个星级。基本上,如果你启动一个库,你就表明了你对这个项目的欣赏,同时也记录了你感兴趣的库。

Github Blog

这个星级可以作为了解最受关注的项目的一个很好的指标。让我们来看看 5 个评价很高的。

1) 人脸识别—25858★

世界上最简单的面部识别工具。它为 Python 和命令行提供了应用程序编程接口(API)。它对于识别和处理图像中的人脸非常有用。它是使用 dlib 最先进的人脸识别算法构建的。深度学习模型在野生数据集的标签人脸上的准确率为 99.38%。

它还提供了一个简单的face_recognition命令行工具,可以让你从命令行本身对一个图像文件夹进行人脸识别!

这个库也可以处理实时人脸识别

Github — face-recognition

2)fast text by Facebook research—18819★

fastText 是由脸书团队开发的开源免费库,用于高效学习单词表示。它是轻量级的,允许用户学习文本表示和句子分类器。它在标准的通用硬件上工作。模型可以缩小尺寸,甚至适合移动设备。

文本分类是许多应用的核心问题,如垃圾邮件检测、情感分析或智能回复。文本分类的目标是将文档(如电子邮件、帖子、短信、产品评论等)分配到多个类别。

Example of word classes | Source: Alterra.ai

对于 NLP 爱好者来说,这是一个非常有用的资源。

fastText

3)awesome-tensor flow—14424★

这是一个帮助你理解和利用张量流的资源集合。github repo 包含一个令人敬畏的 TensorFlow 实验、库和项目的精选列表。

TensorFlow 是 Google 设计的机器学习端到端开源平台。它有一个全面的工具、库和社区资源的生态系统,让研究人员在 ML 中创建最先进的技术。使用它,开发者可以很容易地构建和部署 ML 驱动的应用程序。

Tensorflow

Apache 预测— 11852 ★

Apache PredictionIO 是一个面向开发人员、数据科学家和最终用户的开源机器学习框架。用户可以使用这个框架来构建现实世界的 ML 应用,部署和测试它们。

它甚至支持事件收集、评估和查询预测结果。它基于可扩展的开源服务,如 Hadoop、HBase 等。

就机器学习而言,它基本上减轻了开发人员的思想负担。

PredictionIO

5) Style2Paints — 9184 ★

这个存储库与上面的略有不同,因为它由于缺乏资金而被关闭了!这是一个相当有趣的概念,人工智能被用来给图像着色。

他们声称 Style2paints V4 是目前最好的人工智能驱动的艺术线条着色工具。

他们声称,它不同于以前的端到端图像到图像的翻译方法,因为它是第一个在现实生活的人类工作流程中给艺术线条着色的系统。大多数人类艺术家都熟悉这个工作流程

**sketching** -> **color filling/flattening** -> **gradients/details adding** -> **shading**

Style2Paints 就是根据这个流程设计的。这样的流程只需两次点击就能从最左边的图像生成中间的图像。

Style2Paints

只需再点击 4 次,这就是你所得到的

Style2Paints

互联网是海洋,机器学习是流入其中的河流。Github 上的星星是筛选这条宝藏河的一个很好的指标。

使用 Tensorflow 突出足球中的动作区域

原文:https://towardsdatascience.com/highlight-action-area-in-soccer-using-tensorflow-1c59d644b404?source=collection_archive---------18-----------------------

用数据做很酷的事情!

介绍

如果相机能够智能地自我理解体育运动中的活动区域并捕捉正确的镜头,那该有多酷。这可以使我们在足球场上安装摄像机,特别是在当地比赛进行的地方,捕捉他们的视频,并自动创建有用的亮点,供球队观看他们的移动和学习新的打法。有几家公司提供具有这些功能的“人工智能相机”——veo就是其中之一。但是这些相机很贵。一个更经济的选择是拥有自己的高分辨率普通相机和定制模型,连接到一个或多个相机,并在云中进行处理。这可能是一个更具可扩展性的解决方案,也可以扩展到足球以外的运动。那么我们如何做到这一点呢?

张量流物体探测正在带我们去那里!我用了一个 youtube 视频来强调这一点。见下文。蓝色矩形框突出显示了作用区域。

Soccer — Highlighting area of action

我喜欢这个视频,因为它为这部戏捕捉了一个广角。如果相机是高分辨率的,那么物体检测可以突出显示行动区域,我们可以放大它,创建一个特写镜头,如下所示。

你可以找到我在我的 Github 回购上使用的代码。

步骤概述

Tensorflow 对象检测 API 是用于快速构建对象检测模型的非常强大的资源。如果你对这个 API 不熟悉,请看下面我写的介绍 API 的博客,教你如何使用 API 构建自定义模型。

tensor flow 对象检测 API 简介

使用 Tensorflow 对象检测 API 构建自定义模型

用于检测球员和球的定制模型

我在这里建立了一个自定义模型来检测球员和足球。为此,我从视频中截取了大约 50 帧,并在其中标注了球员和球。这需要一些时间,因为每一帧有 15-20 名球员。我也注释了足球,但是正如你在下面看到的,检测它有点困难,因为它移动的速度太快了,所以变得模糊。通过添加更多模糊球的图像,也可以更好地检测球。我从 Tensorflow 对象检测动物园选择了更快的 RCNN 初始模型。一旦模型在大约 50 帧上被训练,我在 10 分钟的完整视频上运行它,我可以看到模型已经概括得很好。为了使模型能够在各种摄像机角度下工作,需要对不同的图像进行更多的训练。

Player and Ball detection using Faster RCNN Inception model

你可以在我的 github repo 上找到训练好的模型。

确定行动领域

现在,我们可以确定所有球员的位置以及我们对球位置的最佳猜测,我们可以做一个有趣的练习来理解动作在哪里。

tensorflow 对象检测为我们提供了传递给它的每一帧的类、盒子和分数的信息。我们可以缩小输出范围,只在得分高的地方得到边界框。有了这些信息,我们就知道了球场上大部分球员的质心,以及某些帧中的球。

现在我们必须找出有最多球员和球的矩形,因为那里可能是行动的地方。我采取的方法是:

  1. 选择高亮区域作为帧大小的一部分,以保持代码的灵活性
  2. 一旦我们有了所选区域的尺寸,我们就在整个框架上迭代,系统地选择许多区域,并计算其中有多少玩家。如果该区域也有球和球员,那么得分会高得多
  3. 选择得分最高的区域,并将该矩形添加到框架上

结论和下一步措施

太棒了。所以现在你可以看到我们如何使用深度学习模型的输出来产生有趣的结果。这仅仅是开始。再多花一点时间,我们可以进一步改进这段代码。以下是一些后续步骤:

  1. 通过更多针对本课程的训练,更好地探测球
  2. 添加旋转矩形焦点区域的选项,以捕捉与此处不同方向的角度或视图
  3. 更快地运行这段代码。我很想用 YOLO 来实现这个目标。很快会有一个帖子。

我有自己的深度学习咨询公司,喜欢研究有趣的问题。我已经帮助许多初创公司部署了基于人工智能的创新解决方案。请到 http://deeplearninganalytics.org/来看看我们吧。

你也可以在 https://medium.com/@priya.dwivedi看到我的其他作品

如果你有一个我们可以合作的项目,请通过我的网站或 info@deeplearninganalytics.org 联系我

参考

  1. 摄像机角度
  2. 张量流物体检测

为什么我的 ML 模型不起作用?

原文:https://towardsdatascience.com/hint-model-complexity-problem-complexity-and-sample-size-should-be-in-line-c12e73b498a6?source=collection_archive---------19-----------------------

提示:问题复杂性、模型复杂性和样本大小应该一致。

在学习机器学习课程时,您可以轻松地在课程项目中部署和测试机器学习模型。一切正常。然而,在现实生活中,你的模型只会产生无意义的结果,你可能不确定问题出在哪里。

在本文中,我将讨论三个应该相互匹配的组件,以使一个 ML 模型工作:问题复杂性、模型复杂性和样本大小。作为一名数据科学家,我们负责定义和识别每个组件。我们定义一个清晰的问题,识别模型,决定是否需要更多的数据。

在本文的其余部分,我将分别研究这些组件,然后研究不同的场景并给出一些建议。

Problem Complexity, Model Complexity, and Sample Size should be in line.

问题复杂性

在某些情况下,问题可能不清楚,我们可能需要自己定义确切的问题。这是第一步,好的开始总会有好的结局。尝试尽可能简单地定义问题,同时确保它将解决业务挑战。下面举两个例子来说明这个问题:

a)假设您有一个视频监控项目,其中一台摄像机记录了一个房间的镜头。任务是确定房间里是否有人。一种方法是在视频数据上部署人体检测算法。第二种方法是检测视频中的任何运动,因为你知道房间中的运动只能由人引起。第二种方法比第一种简单得多,并且预计更简单的模型将给出期望的结果。

b)问题的复杂性在于数据的多样性。因此,如果我们有更少的维度,问题就不那么复杂。

假设一个文档分类算法,其中您想要对官方文档进行分类。第一种方法是应用基于视觉的方法,该方法考虑文档的每个像素。另一种方法是查看文档中的文本。如果文档包括不同的文本,那么它们可以通过文本来区分。第二种方法中问题的复杂性远低于第一种方法中的复杂性,因为文本与图像相比是低维度的。低维意味着灵活性和复杂性较低。

模型复杂性

模型复杂性可以从训练阶段应该设置的数量的权重中推断出来。如果模型中包含大量的权重,那么学习起来就更加灵活。反过来,你需要更多的数据来训练模型。

让我们看一些例子:

A)具有 3 个输入和一个具有 10 个神经元的隐藏层的深度学习模型,具有大约 50 个权重。

b)深度为 4 的决策树有 15 个权重(阈值被认为是权重)。

c)3 个输入的线性回归模型具有 4 个权重。

数据科学家应该对他或她使用的不同算法有所了解。如果你知道算法是如何工作的,你就会对算法的权重和复杂度有所了解。在这种情况下,您不需要花费时间向复杂的模型提供少量数据。

在下一节中,我将根据权重的数量给出一些关于样本数量的提示。

样本量

这是设计 ML 模型时要考虑的最重要的部分。我见过很多样本量太小的情况,但是机器学习工程师花时间部署不同的模型和调优参数。在某些情况下,数百个样本就足以进行训练,而在其他情况下,模型无法从数千个样本中学习。

需要多少样品?

看看这三个组成部分,现在是时候看看你是否有足够的数据用于指定的 ML 模型和问题了。

样本的正确数量是一个公开的问题。没有人能在不分析数据的情况下说出训练一个模型需要多少样本。这更多的是基于经验。但是,有一个正确范围的感觉是非常重要的。你可能会在会议中被问到你需要的样本的大概数量。你的答案是 100,10000,还是 1000000?

在这里,我会给你一些估计样本数量的建议。

模型中代表模型复杂性的权重数不应超过样本数。考虑一个简单的线性回归问题,它有 10 个权重(9 个特征),你有 8 个样本。从数学的角度来看,有无限的线性模型来拟合样本。从我的经验来看,样本的数量至少要比特征的数量多十倍。这意味着训练一个具有 10 个特征的回归模型,我们至少需要 100 个样本。请记住,数字 10 是基于经验的,没有证据证明这一点,因为它取决于数据的特征。在我们的示例中,如果数据具有线性特征,我们可以用较少的样本来训练我们的模型。此外,如果所有的样本看起来相似,我们需要更多的样本来建立一个更健壮的模型。还有其他一些参数有助于获得正确的样本数。然而,考虑模型中权重的数量会提示您大概需要多少个样本。

不同的场景

基于每个参数的状态,我们有 8 个不同的场景。图 1 和图 2 显示了每个场景的示例图。我将分别讨论每个场景。

小样本量:如果样本数量太少,不如考虑一个基于规则的模型,而不是训练一个 ML 模型。一般来说,如果样本少于 50 个,我们不使用 ML 模型。

a)模型复杂度=低,问题复杂度=低,样本量=小:这是在没有足够数据的情况下,唯一可以得到有意义结果的情况。如果问题不复杂,就挑一个简单的模型,用那些样本训练它。

b)模型复杂性=高,问题复杂性=低,样本量=小:您应该选择一个更简单的模型,因为模型的复杂性应该与问题复杂性和样本量相称。即使您从非常复杂的模型中获得了更高的性能,简单的模型对于看不见的数据也能更好地工作。原因是评估只是基于少量不可靠的数据,通过调整复杂模型的参数,您可能会过度拟合模型。简单模型在实践中会更加稳健。

c)模型复杂性=低,问题复杂性=高,样本量=小:如果可能,尝试解决一个子问题或问题的一个简单版本。至少,你可以达到一个有意义的结果。

d)模型复杂度=高,问题复杂度=高,样本量=小:即使你获得了很高的精度,在处理看不见的数据时,模型在现实情况下也会失效。

大样本量:拥有足够的样本是创建一个好的 ML 模型的关键。应该注意的是,样本不应该有偏差。否则,小样本量和大样本量没有太大区别。

e)模型复杂度=低,问题复杂度=低,样本量=大:对于复杂的问题和大样本量,模型选择不是大问题。大多数 ML 模型返回一个好的结果。

f)模型复杂性=高,问题复杂性=低,样本量=大:与典型模型相比,复杂模型可能返回稍好的结果。考虑到模型的可解释性和维护性,您可以选择使用更简单的模型。

g)模型复杂度=低,问题复杂度=高,样本量=大:如果你喜欢使用最先进的方法,这是一个适合你的案例。挑一个复杂的模型(比如深度学习),你会得到一个想要的结果。

h)模型复杂度=高,问题复杂度=高,样本量=大:在这种情况下可以看到机器学习的强大和美好。魔法在这里发生。

结论

我在本文中所写的内容纯粹基于我使用 ML 模型的经验。你永远不会在课程或书中找到它们,因为这些都是定性的概念。每个数据都是不同的,您无法确定所需数据的数量。如果不分析数据,就不可能有选择最佳模型的规则。然而,在实践中,粗略了解本文中讨论的三个组件非常重要。这将有助于你采取正确的行动来修复你的 ML 模型。

一如既往,我非常感谢每一个阅读我作品的人,我希望你们喜欢这本书!如果您有任何问题或意见,请在下面留下您的反馈,或者您可以通过 LinkedIn 联系我。

直方图均衡化——提高图像对比度的简单方法

原文:https://towardsdatascience.com/histogram-equalization-a-simple-way-to-improve-the-contrast-of-your-image-bcd66596d815?source=collection_archive---------4-----------------------

我在石溪大学的计算机视觉课上从 Shilkrot 教授那里学到了直方图均衡化。这是一个非常简单的概念,只需要几行代码就可以实现。

你认为图像的直方图表示是什么样的?就像左边的红色区域?是啊!

(a) input image and its histogram

我们从上面的图中看到,直方图位于(a)中较亮的区域。但是,如果我们需要亮度的均匀分布,我们将需要一个变换函数,将较亮区域中的输入像素映射到整个区域中的输出像素。这就是直方图均衡所做的。它增强了图像的对比度。直方图均衡化的结果图像可以在(b)的右侧看到。

(b) resulting image post histogram equalization technique

## code to plot histogram in pythonimport numpy as np
import cv2
from matplotlib import pyplot as pltimg = cv2.imread('Chatth_Puja_Bihar_India.jpeg',0)
hist,bins = np.histogram(img.flatten(),256,[0,256])
plt.hist(img.flatten(),256,[0,256], color = 'r')
plt.xlim([0,256])
plt.show()

我们可以在 OpenCV 中使用函数 cv2.equalizeHist() 来做到这一点。如果它的输入只是灰度图像,那么输出就是我们的直方图均衡化图像。如果是彩色(RGB)图像,我们可以分离所有三种不同的流——红色、绿色、蓝色;在这些通道上分别调用 cv2.equalizeHist() ,最后合并回来,如下面的代码所示。为了更好地理解,我还通过 numpy 数组提供了代码。

def histogram_equalization(img_in):# segregate color streams
    b,g,r = cv2.split(img_in)
    h_b, bin_b = np.histogram(b.flatten(), 256, [0, 256])
    h_g, bin_g = np.histogram(g.flatten(), 256, [0, 256])
    h_r, bin_r = np.histogram(r.flatten(), 256, [0, 256])# calculate cdf    
    cdf_b = np.cumsum(h_b)  
    cdf_g = np.cumsum(h_g)
    cdf_r = np.cumsum(h_r)

# mask all pixels with value=0 and replace it with mean of the pixel values 
    cdf_m_b = np.ma.masked_equal(cdf_b,0)
    cdf_m_b = (cdf_m_b - cdf_m_b.min())*255/(cdf_m_b.max()-cdf_m_b.min())
    cdf_final_b = np.ma.filled(cdf_m_b,0).astype('uint8')

    cdf_m_g = np.ma.masked_equal(cdf_g,0)
    cdf_m_g = (cdf_m_g - cdf_m_g.min())*255/(cdf_m_g.max()-cdf_m_g.min())
    cdf_final_g = np.ma.filled(cdf_m_g,0).astype('uint8')cdf_m_r = np.ma.masked_equal(cdf_r,0)
    cdf_m_r = (cdf_m_r - cdf_m_r.min())*255/(cdf_m_r.max()-cdf_m_r.min())
    cdf_final_r = np.ma.filled(cdf_m_r,0).astype('uint8')# merge the images in the three channels img_b = cdf_final_b[b]
    img_g = cdf_final_g[g]
    img_r = cdf_final_r[r]

    img_out = cv2.merge((img_b, img_g, img_r))# validation
    equ_b = cv2.equalizeHist(b)
    equ_g = cv2.equalizeHist(g)
    equ_r = cv2.equalizeHist(r)
    equ = cv2.merge((equ_b, equ_g, equ_r))
    #print(equ)
    #cv2.imwrite('output_name.png', equ)return img_out

应用程序

  1. 您可以使用直方图均衡化来改善任何低对比度图像的亮度。
  2. 在人脸识别技术中,在训练人脸数据之前,对人脸图像进行直方图均衡化,使它们具有相同的光照条件。

奖金

首先,使用下面的代码将图像转换为灰色和黑白。

import cv2

originalImage = cv2.imread('avalon_lake.jpeg')
grayImage = cv2.cvtColor(originalImage, cv2.COLOR_BGR2GRAY)
(thresh, blackAndWhiteImage) = cv2.threshold(grayImage, 127, 255, cv2.THRESH_BINARY)cv2.imwrite('blackAndWhiteImage.png', blackAndWhiteImage)
cv2.imwrite('grayImage.png', grayImage)

Original -> Gray -> BW

skimage-Python 在图像处理中的直方图

原文:https://towardsdatascience.com/histograms-in-image-processing-with-skimage-python-be5938962935?source=collection_archive---------2-----------------------

可视化一直是表示和解释许多统计细节的有效方法。在图像处理中,直方图用于描述我们正在处理的图像的许多方面。比如,

  • 暴露
  • 对比
  • 动态量程
  • 浸透

还有很多。通过可视化直方图,我们可以改善图像的视觉呈现,并且我们还可以通过比较图像的直方图来找出可以应用什么类型的图像处理。

什么是直方图?

图像存储为像素值,每个像素值代表一个颜色强度值。直方图是图像中出现的这些强度值的频率分布。

h(i) = the number of pixels in I(image) with the intensity value i

例如,如果 i = 0,则 h(0)是值为 0 的像素数。

用 skimage 创建图像的直方图

灰度图像

from skimage import io
import matplotlib.pyplot as pltimage = io.imread('~/Desktop/Lenna_gray.png')ax = plt.hist(image.ravel(), bins = 256)
plt.show()Output: Figure-1

Figure-1

在上面的代码中,我们已经加载了 Lenna 的灰度图像,并使用 matplotlib 生成了它的直方图。由于图像是以 2D 有序矩阵的形式存储的,我们使用 ravel()方法将其转换为 1D 数组。

彩色图像

在彩色图像中,我们有 3 个颜色通道代表 RGB。在组合颜色直方图中,强度计数是所有三个颜色通道的总和。

h(i) = h_red(i) + h_green(i) + h_blue(i)

from skimage import io
import matplotlib.pyplot as pltimage = io.imread('~/Desktop/Lenna.png') _ = plt.hist(image.ravel(), bins = 256, color = 'orange', )_ = plt.hist(image[:, :, 0].ravel(), bins = 256, color = 'red', alpha = 0.5)_ = plt.hist(image[:, :, 1].ravel(), bins = 256, color = 'Green', alpha = 0.5)_ = plt.hist(image[:, :, 2].ravel(), bins = 256, color = 'Blue', alpha = 0.5)_ = plt.xlabel('Intensity Value')
_ = plt.ylabel('Count')
_ = plt.legend(['Total', 'Red_Channel', 'Green_Channel', 'Blue_Channel'])
plt.show()Output: Figure-2

Figure-2

什么是直方图宁滨?

通常,在 8 位 representation(2⁸).中,图像的亮度值范围是从[0–255]但是图像也可以使用 2 ⁶、2 比特等来表示。在这种情况下,强度范围很大,很难在直方图中表示每个强度值。

我们用宁滨来克服上述问题。这里我们将范围量化为几个桶。举个例子,

if we quantize 0-255 into 8 bins, here our bins will be
0-31, 32-63, 64-95, 96-127, 128-159, 160-191, 192-223, 224-255

现在,我们需要找到一种方法将每个亮度值放入适当的箱中。我们可以简单地解决这个问题,

k = 256 #number of possible integer values in 8 bit representation
b = 8   #number of binsj = floor( (h(i)*b)/k )#j is the bin number of the intensity value at position i

让我们再次绘制灰度 Lenna 图像的直方图,

from skimage import io
import matplotlib.pyplot as pltimage = io.imread('~/Desktop/Lenna_gray.png')_ = plt.hist(image.ravel(), bins = 8 )
_ = plt.xlabel('Intensity Value')
_ = plt.ylabel('Count')
plt.show()Output: Figure-3

Figure-3

什么是累积直方图?

累积直方图是一种特殊的直方图,可以从正常直方图中导出。我们找到从 0 到 255 的每个强度值的计数,然后将每个后续计数相加,

if i = 0 then H(i) = h(0)
else H(i) = H(i-1) + h(0)

累积直方图在许多图像处理应用中是有用的,如直方图均衡化等。

from skimage import io
import matplotlib.pyplot as pltimage = io.imread('~/Desktop/Lenna_gray.png')_ = plt.hist(image.ravel(), bins = 256, cumulative = True)
_ = plt.xlabel('Intensity Value')
_ = plt.ylabel('Count') 
plt.show()Output: Figure-4

Figure-4

我希望你明白什么是直方图,以及如何使用 skimage 创建直方图。让我们再见面,我会告诉你一些直方图在图像处理中的用例。

基于深度神经网络的组织病理学癌症检测

原文:https://towardsdatascience.com/histopathological-cancer-detection-with-deep-neural-networks-3399be879671?source=collection_archive---------11-----------------------

(注:相关 Jupyter 笔记本及原帖可在此处找到:https://www . human unsupervised . com/post/organisotrophic-cancer-detection)

能够利用机器学习和深度神经网络在病理扫描中自动检测转移的癌症是医学成像和诊断的一个领域,具有潜在的临床用途。

在这里,我们探索一个为这种类型的分析和诊断准备的特定数据集 PatchCamelyon 数据集(PCam)。

PCam 是一个二元分类图像数据集,包含大约 300,000 个从数字组织病理学扫描中提取的淋巴结切片的标记低分辨率图像。每张图像都由训练有素的病理学家标记是否存在转移癌。

这项工作的目标是在 PCam 数据集上训练一个卷积神经网络,并获得接近或接近最先进的结果。

正如我们将看到的,利用 Fastai 库,我们在 PCam 数据集中预测癌症的准确率达到了 98.6%。

我们通过准备和训练具有以下特征的神经网络来实现这一点:

  1. 以预先训练的 Resnet50 ImageNet 模型为基础的迁移学习。
  2. 以下数据增强:图像大小调整、随机裁剪和
  3. 水平和垂直轴图像翻转。
  4. 适合一个周期的方法来优化我们培训的学习率选择。
  5. 有区别的学习率进行微调。

此外,我们在培训中应用了以下“开箱即用”的优化和规范化技术:

  • 拒绝传统社会的人
  • 重量衰减
  • 批量标准化
  • 平均池和最大池
  • 亚当乐观主义者
  • ReLU 激活

本笔记本展示了使用 Fastai + PyTorch 对该数据集的研究和分析,并作为参考、教程和开源资源提供给其他人参考。它并不打算成为严肃的临床应用的生产就绪资源。相反,我们在这里使用 Camelyon16 数据集中原始高分辨率临床扫描的低分辨率版本进行教育和研究。这被证明是原型化和测试各种深度学习算法的有效性的有用基础。

背景和数据来源

原始资料来源:Camelyon16

PCam 实际上是 Camelyon16 数据集的子集;一组淋巴结切片的高分辨率全切片图像(WSI)。该数据集由荷兰 Nijmegen 的 Radboud 大学医学中心(Radboudumc)的诊断图像分析组(DIAG)和病理学部门提供。以下是他们网站的摘录:https://camelyon16.grand-challenge.org/Data/

本次挑战中的数据包含总共 400 张前哨淋巴结的全切片图像(WSIs ),这些图像来自两个独立的数据集,分别收集于拉德布大学医学中心(荷兰奈梅亨)和乌得勒支大学医学中心(荷兰乌得勒支)。

第一个训练数据集由 170 个淋巴结 WSI(100 个正常和 70 个包含转移)和第二个 100 个 WSI(包括 60 个正常载玻片和 40 个包含转移的载玻片)组成。

测试数据集由从两所大学收集的 130 个 WSI 组成。

Examples above of a metastatic region (from Camelyon16)

PatchCam (Kaggle)

PCam 是由来自荷兰的健康机器学习博士生 Bas Veeling 编写的,专门用于帮助对这一特定问题感兴趣的机器学习从业者。它由 327,680,96x96 的彩色图像组成。可以在这里找到数据集的精彩概述:http://basveeling.nl/posts/pcam/,也可以通过 github 上的下载获得,那里有关于数据的进一步信息:https://github.com/basveeling/pcam

这个特殊的数据集是通过 Kaggle API 直接从 Kaggle 下载的,它是原始 PCam(patchcamelion)数据集的一个版本,但删除了重复项。

PCam 旨在成为执行基本机器学习分析的良好数据集。顾名思义,它是用于执行类似分析(https://camelyon16.grand-challenge.org/Data/)的大得多的 Camelyon16 数据集的缩小版

出自作者的话:

PCam 将转移检测的临床相关任务打包成直接的二值图像分类任务,类似于 CIFAR-10 和 MNIST。模型可以在几个小时内在单个 GPU 上轻松训练,并在肿瘤检测和全切片图像诊断的 Camelyon16 任务中获得有竞争力的分数。此外,任务难度和易处理性之间的平衡使其成为主动学习、模型不确定性和可解释性等主题的基础机器学习研究的主要怀疑对象。

了解了一些数据背景之后,让我们开始设置我们的项目和工作目录…

获取数据

我们使用的数据存在于 Kaggle 上。我们使用 Kaggle 的 SDK 直接从那里下载数据集。要使用 Kaggle SDK 和 API,您需要在您的 Kaggle 帐户中创建一个 Kaggle API 令牌。

登录 Kaggle 后,导航至“我的帐户”,然后向下滚动至“创建新的 API 令牌”。这会将一个 JSON 文件下载到您的计算机上,其中包含您的用户名和令牌字符串。把这些内容复制给你~/。kaggle/kaggle.json 令牌文件。

使用 ImageDataBunch 准备数据

下载完数据后,我们创建一个 ImageDataBunch 对象来帮助我们将数据加载到模型中,设置数据扩充,并将数据分成训练集和测试集。

ImageDataBunch 包含了许多功能,可以帮助我们将数据准备成一种在训练时可以使用的格式。下面让我们来看看它执行的一些关键功能:

数据扩充

默认情况下,ImageDataBunch 对数据集执行许多修改和扩充:

  1. 居中裁剪图像
  2. 出于数据扩充的目的,在何处以及如何进行裁剪方面也引入了一些随机性
  3. 重要的是,所有图像的大小必须相同,以便模型能够进行训练。

图像翻转

我们还可以使用各种其他数据增强。但是我们激活的关键之一是垂直方向的图像翻转。

对于病理扫描,这是要激活的合理的数据扩充,因为扫描是定向在垂直轴还是水平轴上并不重要,

默认情况下,fastai 将在水平方向翻转,但我们需要在垂直方向打开翻转。

批量

我们将使用 1cycle 策略(fit_one_cycle())来训练我们的网络(稍后将详细介绍)。这是一个超参数优化,允许我们使用更高的学习率。

更高的学习率是 1 周期政策中的一种规范化形式。回想一下,小批量增加了规则性,因此当在 1 周期学习中使用大批量时,允许使用更大的学习速率。

这里的建议是使用 1 周期策略进行训练时,使用我们的 GPU 支持的最大批量。

培训、验证和测试集

  1. 我们指定数据的文件夹位置(子文件夹 train 和 test 与 csv 数据一起存在的位置)
  2. ImageDataBunch 将图像(在 train 子文件夹中)分割成训练集和验证集(默认为 80/20 分割)。在训练集中有 176,020 幅图像,在验证集中有大约 44,005 幅图像。
  3. 我们还指定了 test 子文件夹的位置,它包含未标记的图像。我们的学习模型将针对该数据集测量准确性和错误率
  4. 还指定了包含数据标签的 CSV 文件

基于基础架构和目标架构的图像大小

目标 PCam 数据集中的图像是 96×96 的正方形图像。然而,当将预训练的 ImageNet 模型引入我们的网络时,我们需要相应地设置大小,以考虑该数据集中的图像大小。

我们选择 224 作为开始时的默认大小。

使图像正常化

一旦我们设置了 ImageDataBunch 对象,我们还会对图像进行标准化。

标准化图像使用图像的平均值标准偏差将图像值转换为标准化分布,这对于神经网络的训练更有效。

下面我们来看看一些随机的数据样本,这样我们就可以了解我们在网络中输入了什么。这是一个二元分类问题,所以只有两类:

阴性(0) /转移(1)

学习者(CNN Resnet50)

一旦我们正确地设置了 ImageDataBunch 对象,我们现在就可以将它和预先训练的 ImageNet 模型一起传递给 cnn_learner。我们将使用 Resnet50 作为我们的主干。

Fastai 在其 cnn_learner 中包装了许多最先进的计算机视觉学习。它是管理我们的模型训练和集成我们的数据的顶级构造。

迁移学习

从已经在另一个数据集上预先训练好的表现良好的模型的主干网络开始,是一种叫做迁移学习的方法。

迁移学习的工作前提是,你可以使用来自另一个机器学习模型的学习(即学习的权重)作为起点,而不是从头开始训练你的数据。

这是一种令人难以置信的有效训练方法,并巩固了当前训练深度神经网络的最先进实践。

当使用预训练模型时,我们特别利用与预训练模型和目标数据集(PCam)最共有的学习特征。

因此,例如,对于在 ImageNet(如 Resnet50)上预先训练的模型,训练将利用已经从基本数据集(特别是前几层)学习到的共同特征(例如线、几何图形、图案)在目标数据集上进行训练。

对于我们的模型,我们将使用 Resnet50。Resnet50 是使用 50 层在 ImageNet 数据上训练的残差神经网络,并且将为我们的网络提供良好的起点。

训练和健身一个周期

适合一个周期

我们将用一种叫做“适合一个周期”的方法来训练我们的网络。这种优化是一种针对特定层组在我们的训练运行中跨总次数应用可变学习率的方式。这已被证明是一个非常有效的方法来调整学习率超参数的训练。

“适合一个周期”改变学习率,从第一个时期的最小值(默认为 lr_max/div_factor)到预定的最大值(lr_max),然后再下降到剩余时期的最小值。这个最小-最大-最小学习率方差称为一个周期。

在 fastai docshttps://docs.fast.ai/callbacks.one_cycle.html中可以找到很好的概述,以及 Leslie Smith [7]的原始论文中更详细的解释,其中提出了这种超参数调谐方法。

那么,我们如何确定最合适的最大学习速率来适应一个周期呢?我们运行 fastai 的 lr_find()方法。

在解冻网络之前运行 lr_find 会产生下图。我们想在损失开始指数增长之前选择一个学习率。

从所得学习率图的视觉观察来看,以 1e-02 的学习率开始似乎是初始 lr 值的合理选择。

冻结

默认情况下,我们开始与我们的网络冻结。这意味着我们预训练的 Resnet50 模型的层应用了 trainable = False,并且训练仅在目标数据集上开始。我们提供给 fit_one_cycle()的学习率仅适用于此初始训练运行的层组。

分析初步结果

分析初始训练运行的图,我们可以看到,随着训练的进行,训练损失和验证损失都稳步下降并开始收敛。

目前的准确率是 97.76%。

我们可以通过使用 Fastai 的混淆矩阵和绘制我们的最高损失来了解这次训练的更多信息。

困惑矩阵是一个方便的工具,可以帮助我们获得关于培训效果的更多细节。具体来说,我们对神经网络预测的假阳性和假阴性的数量有所了解。

绘制我们的最高损失可以让我们更详细地检查特定的图像。Fastai 生成了我们预测错误的图像热图。热图允许我们检查使我们的网络混乱的图像区域。这样做是很有用的,这样我们就可以更好地了解我们的模型在每次测试中的表现,并指引我们找到如何改进它的线索。

微调、解冻和区别学习率

第一次训练的初步结果已经很好了。但是通过更多的微调,我们实际上可以做得更好。

迁移学习+微调=更好的概括

光是迁移学习就比从头开始训练我们的网络要远得多。但是当连接预先训练的网络时,这种方法容易在脆弱的适应层之间出现优化困难。我们通过微调我们的模型来解决这个问题;使我们网络的所有层,包括预训练的 Resnet50 层,都是可训练的。当我们解冻时,我们训练我们所有的层。(参见[6])

这导致了更好的结果和更强的归纳新例子的能力。

区别学习率和 1 周期

随着我们网络中所有层的解冻和开放训练,我们现在还可以结合 fit_one_cycle 使用区别学习率来进一步改进我们的优化。

区别学习率允许我们将特定的学习率应用于网络中的层组,为每个组进行优化。然后,Fit one cycle 对这些值进行操作,并根据 1cycle 策略使用它们来改变学习率。(https://docs . fast . ai/basic _ train . html #判别层训练)

我们如何找到用于 fit 1cycle 的最佳学习率范围?我们可以使用 lr_find()来帮助我们。

分析上面的 lr 图,我们在损失开始急剧增加之前选择一个学习率范围,并将其应用于下面的 fit_one_cycle 方法。

从上面的图来看,选择 1e-4 的上限速率似乎是合理的,作为下限速率的推荐规则,我们可以选择比上限小 10 倍的值,在本例中为 1e-5。

下限速率将应用于我们预训练的 Resnet50 层组中的层。这里的权重已经被很好地学习了,所以我们可以对这组层进行较慢的学习速率。

上限比率将应用于我们上次在目标数据集上运行训练时训练的最终图层组。该组中的层将受益于更快的学习速率。

最后分析

在最后的微调训练运行中,我们可以看到,我们的训练损失和验证损失现在在训练中期开始彼此偏离,并且训练损失以比验证损失快得多的速度逐渐改善,稳步下降,直到在运行的最后时期稳定到稳定的值范围。

在训练损失持续减少的情况下,我们验证损失的任何进一步增加都会导致过度拟合,不能很好地推广到新的例子。

在我们训练的这一点上完成,产生了比第一阶段训练运行结果高 98.6%的微调准确度。

参考

[1]程序员实用深度学习,v3。法斯泰。杰瑞米·霍华德。雷切尔·汤姆森。【https://course.fast.ai/index.html

[2] B. S .韦林,j .林曼斯,j .温肯斯,t .科恩,m .韦林。“用于数字病理学的旋转等变 CNN”。arXiv:1806.03962

[3] Ehteshami Bejnordi 等.用于检测乳腺癌妇女淋巴结转移的深度学习算法的诊断评估。JAMA:美国医学协会杂志,318(22),2199–2210。doi:jama.2017.14585

[4] Camelyon16 挑战赛https://camelyon16.grand-challenge.org

[5]卡格尔。组织病理学癌症检测—在淋巴结切片的组织病理学扫描中识别转移组织https://www.kaggle.com/c/histopathologic-cancer-detection

[6]杰森·约辛斯基。杰夫·克伦。约舒亚·本吉奥。霍德·利普森。"深度神经网络的特征有多容易转移?"。arXiv:1411.1792v1 [cs。LG]

7 莱斯利·n·史密斯。“神经网络超参数的训练方法:第 1 部分——学习速率、批量大小、动量和权重衰减”。arXiv:1803.09820v2 [cs。LG]

第一个人工智能冬天的历史

原文:https://towardsdatascience.com/history-of-the-first-ai-winter-6f8c2186f80b?source=collection_archive---------4-----------------------

人工智能历史悠久。人们可以争辩说,它甚至早在这个术语首次被创造出来之前就已经开始了;大部分是在故事里,后来是在叫做自动机的实际机械装置里。这一章只涵盖了与 AI winters 时期相关的事件,并没有过于详尽,希望从中提取出可以应用于今天的知识。

导致第一个人工智能冬天的事件

为了帮助理解艾温特斯现象,导致他们的事件进行了审查。

20 世纪 50 年代人工智能领域的开端

许多关于思维机器的早期想法出现在 20 世纪 40 年代末至 50 年代,由图灵或冯·诺依曼等人提出。图灵试图框定“机器能思考吗?”创造了模仿游戏,现在著名的图灵测试。

1955 年,亚瑟·塞缪尔写了一个程序,可以很好地玩跳棋。一年后,它甚至出现在电视上。它结合使用了启发式和学习权重的树搜索。塞缪尔手工制作的启发来自跳棋专家的一本书。他使用了一种他称之为“时间差学习”的学习算法,利用最初计算的分数和搜索完成后的分数之间的“误差”来调整权重。

1954 年,进行了机器翻译的首批实验之一。它使用了 250 个单词的词典进行翻译,并结合了句法分析。演示了英语和俄语之间的翻译。纽约时报评论道:

“不可否认,这相当于粗略的逐字翻译……但设计者说,对于科学家翻译词汇远比句法更成问题的外国技术论文来说,这将是非常有价值的。”

那时,设计者认为大部分工作已经完成,只有一些小错误需要修复。Hutchin 指出,这是机器翻译有史以来最深远的报道。由于这个原因,它产生了巨大的炒作,并使其更容易获得资金用于后续工作。

人工智能研究从美国国防机构(ONR 和 ARPA,后来称为 d ARPA)获得了大量资金,希望这些技术对美国海军有用。当时,人们对人工智能的状态充满了热情和乐观。机器翻译领域在冷战期间尤为重要,因为政府对从俄语到英语的自动翻译非常感兴趣。

早期的实验激发了 1956 年创建达特茅斯夏季项目的灵感,人工智能一词就是在那里诞生的。暑期项目的主题是“学习的每一个方面或智力的任何其他特征原则上都可以被精确地描述,以至于可以制造一台机器来模拟它”。来自许多不同领域的研究人员被邀请,提出了许多不同的想法、论文和概念。虽然取得了进展,但有些人感到失望,例如,麦卡锡在回应研讨会时说,“研讨会没有达到我的预期的主要原因是人工智能比我们想象的更难。”

1957 年,罗森布拉特发明了感知器,这是一种神经网络,其中二进制神经单元通过可调权重连接。他受到 20 世纪 40 年代神经科学工作的启发,这使他在大脑中创建了神经元的原始复制。

他尝试了很多不同的布局和学习算法。一种感知器被称为串联耦合,这在今天是指神经网络的标准前馈布局,其中数据从输入流向输出。一个突出的布局是他所谓的阿尔法感知器,一个三层串联耦合网络,在这种情况下,三层包括输入和输出层。当时的计算机运行感知器太慢了,所以罗森布拉特建造了一台特殊用途的机器,带有由小电机控制的可调电阻(电位计)。该设备能够学习对不同形状或字母的图像进行分类。纽约时报报道了感知器:

"海军展示了一种电子计算机的雏形,它期望这种计算机能够行走、说话、看、写、自我复制并能意识到自己的存在。"

同年(1957 年),西蒙这样总结了人工智能的当前进展:

“我的目的不是让你感到惊讶或震惊——但我能总结的最简单的方法是,现在世界上有了会思考、会学习、会创造的机器。此外,他们做这些事情的能力将迅速提高,直到——在可见的未来——他们能够处理的问题范围将与人类思维的应用范围相同。”

平静的十年

在 20 世纪 50 年代和 60 年代初对机器翻译的投资和热情增加后,进展停滞了。哈钦斯把 1967 年到 1976 年这段时间称为机器翻译的平静十年。Bar-Hillel 说机器翻译是不可行的。他证明了计算机需要太多关于世界的信息来进行正确的翻译,他认为这“完全是空想,几乎不值得任何进一步的讨论。”自动语言处理咨询委员会在 1964 年得出结论,没有立即或可预见的有用的机器翻译的前景。1966 年的一份报告得出结论说,“还没有通用科学文本的机器翻译,而且近期也不会有”,这导致所有学术翻译项目的资金被削减。

机器翻译中的失望对人工智能领域尤其有害,因为美国国防机构希望出现可用的系统,但在人工智能的其他领域也注意到了类似的模式。1965 年,德雷福斯将人工智能与炼金术并列。他研究了当时几个领域的成就,并得出结论:“一个总体模式正在形成:基于简单任务的轻松表现或复杂任务的低质量工作的早期戏剧性成功,然后是回报递减、失望,以及在某些情况下的悲观情绪。”

机器翻译平静的十年是导致第一个人工智能冬天的最重要事件之一。另一个是联结主义运动的衰落,这将在下一节讨论。

联结主义的衰落

1969 年,明斯基和帕佩特的书感知器出版。这是对罗森布拉特感知机的严厉批评。Minsky 和 Papert 证明了感知器只能被训练来解决线性可分问题。例如,非线性可分问题的一个最糟糕的例子是异或(XOR)。对于成功解决 XOR 问题的网络,只有当它的一个输入为真时,它的输出才能为真,而不是两个都为真。这对联结主义者来说是一个巨大的打击,他们相信人工智能可以通过模仿大脑来实现。Minsky 和 Papert 知道多层能够解决这个问题,但是没有算法来训练这样的网络。这种算法花了 17 年才被设计出来,现在被称为反向传播。只是到了后来,人们才发现反向传播算法以前就被发现过。事实证明,反向传播算法甚至在感知机发表之前就已经发明了。

莱特希尔报告及其后果

莱特希尔报告(1973 年出版)是为英国科学研究委员会撰写的对当时人工智能现状的评估。该报告得出的结论是,人工智能研究人员的承诺被夸大了:“迄今为止,该领域的任何发现都没有产生当时承诺的重大影响。”尽管报告指出,最令人失望的研究领域是机器翻译,“在这个领域,花费了巨额资金,却没有什么有用的结果……”报告的作者詹姆斯·莱特希尔认为,未能战胜“组合爆炸”是问题的核心。他所指的术语组合爆炸是搜索空间中一个众所周知的问题,就像树一样,当沿着树向下时,节点的数量呈指数增长。例如,在像国际象棋这样的游戏中,Shannon 证明了可能的游戏数量从第一步的 20 个增加到第二步的 400 个,到第五步已经有 4,865,609 个可能性,因此代表了组合爆炸。

当时莱特希尔的报告遭到了很多批评,甚至一场为 BBC 拍摄的辩论也不幸从未播出。与其他科学领域进行了比较,并评论说,人们不应该期望结果那么快。尽管这些评论可能是正确的,但这份报告还是产生了影响。报告发布后,英国政府削减了除两所大学以外的所有参与该领域研究的大学的资金,这掀起了一股席卷整个欧洲的浪潮,甚至对美国产生了影响。

第一个人工智能冬天

几个情况结合起来创造了第一个人工智能冬天。起初,随着大量乐观的新闻报道,人们对这一新领域的潜力的热情迅速增长。然后,机器翻译中的失望创造了一个安静的时代。接着明斯基和帕佩特提出了阻碍感知机发展的障碍。最终,莱特希尔的报告出台了,它要求对该领域进行现实的评估。随着莱特希尔报告的到来,第一个冬天开始于 1973 年左右。该报告对资金有影响,因此人工智能的研究变得困难。DARPA(国防高级研究计划局)开始资助更多的应用人工智能项目和更少的基础工作。人工智能的冬天持续了几年,但在 80 年代初,人工智能领域经历了另一个高潮。

我就这个话题制作了一个很酷的视频——来看看吧!

查看第二部分!

第二届 AI 冬季的历史

原文:https://towardsdatascience.com/history-of-the-second-ai-winter-406f18789d45?source=collection_archive---------13-----------------------

先来看看第一部

导致第二次人工智能冬季的事件

在第一个人工智能冬天的影响开始下降后,一个新的人工智能时代开始了。这一次,更多的努力集中在创造商业产品上。此外,像 AAAI 这样的大型会议始于 20 世纪 80 年代初,门票销售迅速增长。普通行业和政府官员都开始对人工智能技术表现出新的兴趣。

人工智能商业化的核心是专家系统。这些系统是由调查专家手工制作的,并相应地创建了“如果-那么”规则集。这种方法被称为“自上而下”的人工智能方法,许多人认为专家知识是创造人工智能的最佳方式。这些系统应用于金融规划、医疗诊断、地质勘探和微电子电路设计等领域。

《T2 商业周刊》也加入了炒作的行列,并在 1984 年发表了标题为《人工智能:它在这里》的文章。类似地,许多公司做出了不同寻常的声明,如:“我们已经建造了一个更好的大脑”,并宣称“现在可以将人类的知识和经验编程到计算机中……人工智能终于成熟了。"

对即将到来的冬天的恐惧

随着对人工智能的大肆宣传,研究人员担心该领域可能不会产生预期的结果。在一个名为“人工智能的黑暗时代——我们能避免还是生存下去?”在 1984 年的 AAAI 会议上,科学家们讨论了是否可以阻止即将到来的人工智能冬天。

“这种不安是因为担心对人工智能的期望过高,这最终会导致灾难。我认为重要的是,我们要采取措施,确保人工智能冬天不会发生[……]。”

人们担心,当不切实际的期望无法实现时,资金会再次枯竭。这种担心被证明是正确的。

第二个人工智能冬天

在接下来的几年里,关于人工智能系统能力的说法不得不慢慢面对现实。处于革命中心的专家系统面临许多问题。1984 年,约翰·麦卡锡批评专家系统,因为他们缺乏常识和对自身局限性的了解。

John McCarthy

他描述了为帮助医生而建立的专家系统 MYCIN。然后,他列举了一个病人肠道内有霍乱弧菌的情况。当被询问时,系统开出了两周的四环素。这很可能会杀死所有的细菌,但那时病人已经死了。此外,对于工程师来说,许多任务过于复杂,无法围绕它们手动设计规则。视觉和语音系统包含太多的边缘情况。

DARPA ISTO(国防高级研究计划局/信息科学与技术办公室)主任施瓦茨在 1987 年至 1989 年间得出结论,人工智能研究一直有

“……在特定领域取得了非常有限的成功,紧接着又未能实现更广泛的目标,而这些最初的成功起初似乎暗示了……”。

这导致人工智能研究的资金减少。由于预期无法实现,对人工智能的普遍兴趣下降。这个时候很多 AI 公司关门了。1986 年吸引了 6000 多名参观者的 AAAI 会议到 1991 年迅速减少到只有 2000 人。类似地,从 1987 年开始,人工智能相关的文章减少,并在 1995 年达到最低点,这可以在纽约时报中观察到。

我就这个话题制作了一个很酷的视频——来看看吧!

喀拉斯剩余网络搭便车指南(ResNet)

原文:https://towardsdatascience.com/hitchhikers-guide-to-residual-networks-resnet-in-keras-385ec01ec8ff?source=collection_archive---------2-----------------------

学习剩余网络的基础,并在 Keras 中建立一个 ResNet

Photo by Andrés Canchón on Unsplash

非常深的神经网络很难训练,因为它们更容易消失或爆发梯度。为了解决这个问题,来自一层的激活单元可以被直接馈送到网络的更深层,这被称为跳过连接

这形成了剩余网络剩余网络的基础。这篇文章将在 Keras 中实现一个之前介绍剩余网络的基础知识。

关于机器学习、深度学习和人工智能的实践视频教程,请查看我的 YouTube 频道

With ResNets, we can build very deep neural networks

残余块

ResNet 的构造块被称为剩余块标识块。当一层的激活被快进到神经网络中更深的层时,残余块就简单了。

Example of a residual block

正如您在上面的图像中看到的,来自前一层的激活被添加到网络中更深一层的激活中。

这个简单的调整允许训练更深层次的神经网络。

理论上,训练误差应该随着更多层被添加到神经网络而单调减少。然而,在实践中,对于传统的神经网络,它将达到训练误差开始增加的点。

ResNets 没有这个问题。随着更多的层被添加到网络中,训练误差将不断减小。实际上,ResNets 已经使训练 100 层以上的网络成为可能,甚至达到 1000 层。

建立图像分类的资源网

现在,让我们使用 Keras 为图像分类构建一个 50 层的 ResNet。

Keras 是一个高级神经网络 API,用 Python 编写,能够在 TensorFlowCNTKTheano 之上运行。它的开发重点是支持快速实验。

在这种情况下,我们将使用 TensorFlow 作为后端。当然,在开始之前,可以随意抓取整个笔记本并进行所有必要的导入。

步骤 1:定义标识块

首先,我们定义身份块,这将使我们的神经网络成为一个剩余网络,因为它表示跳过连接:

步骤 2:卷积块

然后,我们构建一个卷积模块,如下所示:

注意卷积块是如何结合路径和快捷方式的。

步骤 3:构建模型

现在,我们将两个模块结合起来构建一个 50 层剩余网络:

第四步:培训

在训练之前,要认识到我们有一个返回模型的函数。因此,我们需要将它赋给一个变量。然后,Keras 要求我们编译模型:

model = ResNet50(input_shape = (64, 64, 3), classes = 6)
model.compile(optimizer='adam', loss='categorical_crossentropy', metrics=['accuracy'])

完成后,我们可以对图像进行标准化,并对其进行一次性编码:

之后,我们可以拟合模型:

model.fit(X_train, Y_train, epochs = 2, batch_size = 32)

看看它的表现如何:

preds = model.evaluate(X_test, Y_test)
print (“Loss = “ + str(preds[0]))
print (“Test Accuracy = “ + str(preds[1]))

现在,你会看到我们只有 16%的准确率。这是因为我们只训练了 2 个纪元。你可以在你自己的机器上训练你的模型更长的时间,但是要意识到这需要很长的时间,因为它的网络非常大。

步骤 5:打印模型摘要

Keras 使得对我们刚刚构建的模型进行总结变得非常容易。只需运行以下代码:

model.summary()

您将获得网络中每一层的详细总结。

您还可以生成网络架构的图片,并将其保存在您的工作目录中:

plot_model(model, to_file=’ResNet.png’)
SVG(model_to_dot(model).create(prog=’dot’, format=’svg’))

太好了!您刚刚学习了剩余网络的基础知识,并使用 Keras 构建了一个剩余网络!同样,随意训练算法更长时间(约 20 个历元),您应该会看到网络表现非常好。然而,如果你只在 CPU 上训练,这可能需要超过 1 小时。

在未来的帖子中,我将展示如何在 TensorFlow 中执行神经风格转移,这是一种非常有趣的应用卷积神经网络的方法!

继续学习!

参考: deeplearning.ai

#抗议:可视化来自中国造谣运动的国家巨魔推文

原文:https://towardsdatascience.com/hkprotest-visualizing-state-troll-tweets-from-chinas-disinformation-campaign-1dc4bcab437d?source=collection_archive---------17-----------------------

使用各种可视化工具,深入探究北京在社交媒体上反对香港抗议活动背后的言论。

A Scattertext plot of key words in tweets and retweets by Chinese state trolls targeting the protest movement in Hong Kong.

8 月下旬,随着香港持续数月的反政府街头抗议导致紧张局势加剧,Twitter、脸书和谷歌宣布,它们发现并处理了中国政府巨魔在其平台上发起的造谣活动。

这些活动旨在“抗议运动和他们对政治变革的呼吁”, Twitter 在 8 月 19 日发布了 360 万条来自该公司所谓的“国家支持的协调行动”的国家巨魔推文。脸书谷歌发布了新闻声明,但尚未发布与中国政府造谣活动相关的数据集。

这是我研究 Twitter 发布的巨魔推文的第二部分,继上个月的快速探索之后。在这里,我将尝试使用一系列自然语言处理和可视化工具,筛选出中国巨魔推文中的关键词和修辞。

关键假设和回购

首先:这是最新笔记本项目的回购。CSV 文件太大,无法上传到 Github 上。直接从推特下载。

这个数据集有超过 360 万行和 59 种语言的推文。这里非常嘈杂——充斥着体育和色情相关的推文,以及政府官员和逃亡的中国亿万富翁郭文贵之间的口水战。

现已被暂停的国家巨魔账户也在用多种语言发布推文。例如,一个将账户语言设置为英语的巨魔可以同时用英语和中文,或者更多语言发微博。许多账户也已经休眠了很长时间。

为了使这个项目更易于管理,我采取了以下步骤:

  • 只关注英文和中文推文(因为它们主要针对香港人),但确保我从有中文语言设置的账户中捕捉英文推文,反之亦然。
  • 将 2017 年设定为分析的起点,因为许多人认为俄罗斯 2016 年在美国的假情报活动激发了最近国家假情报工作的重大战术变化。当然,中国巨魔早在 2017 年就已经在 Twitter 上活跃了。
  • 使用明显的关键词,如“香港”和“警察”,作为主动过滤的定位点。这清楚地将选择偏差引入了分析和可视化。但是考虑到数据集中的噪声量,我觉得这是一个可以接受的折衷方案。

信号和噪声:关键发现

#1。非常低的信噪比

如果没有积极的过滤,很难从数据集中发现更多信息。这适用于英文和中文推文(以及转发)。以下面的图表为例,它显示了在对郭的推文进行轻微过滤后,前 50 个最常见术语的频率分布:

前 50 名名单中几乎没有任何一个词可以暗示这些推文是关于什么的。中文巨魔推文同样嘈杂,充斥着涉及犯罪故事、美中关系和日光浴的垃圾内容:

2。极少数“主角”演员/巨魔

In its press release, Twitter highlighted the activities of 2 accounts — Dream News(@ctcc507) and HK 時政直擊(@HKpoliticalnew) — without explicitly saying why it chose to “showcase” these two out of the 890 unique userids in the dataset.

通过挖掘数据集,很快就发现这两个账户是一小撮超级活跃的巨魔,推动了北京对抗议运动的言论。这些“领头的巨魔”活跃地用英文和中文发推文,并经常被不太活跃的账户转发。不清楚@ctcc507 和@HKpoliticalnew 是否直接控制了其他的巨魔账号。

这两个主要客户的推文示例:

  • @ ctcc5072019–07–02 12:31:00+08:00 发微博:‘立法会是香港人的。以势力为代表的那些别有用心的人躲在幕后围攻立法会,这是对大多数香港人的严重侮辱。
  • @ HKpoliticalnew2019–06–14 09:50:00+08:00 发微博:‘很明显,先是有特工在现场指挥和扰乱香港,然后是美国政府出面指责和制裁香港。这些代理人通过散布有关香港的负面信息向中国和香港政府施加压力。#香港https://t.co/Q6dGQUUHoG'
  • @ctcc507,2019–06–22 21:51:00+0800 发微博:‘别有用心的人企图通过‘颜色革命’在香港兴风作浪,煽动不明真相的学生团体和香港市民,围攻警察总部,意图破坏香港稳定。https://t.co/awxlQnMF4A'

这些中国国有巨魔账户的显示名称看起来像新闻媒体会采用的名称,这并非巧合。这一增选新闻媒体身份的举动直接出自俄罗斯 2016 年剧本

其他一些稍微活跃一点的中文账号包括:@charikamci、@KondratevFortu、@jdhdnchsdh、@shaunta58sh、@Resilceale、@ qujianming1、@vezerullasav158 和@ardansuweb。但是没有一个接近@ctcc507 和@HKpoliticalnew 在巨魔网络中的影响力水平。

3。每个角落都有“外国代理人”

巨魔推文的内容在很大程度上是可以预见的,从呼吁支持陷入困境的香港警方到谴责抗议者的暴力行为。

但是在“带头”的国家巨魔中,一个特别占主导地位的线索是阴谋论,即美国是香港抗议活动背后的“黑手”,这些抗议活动吸引了数百万人走上街头。

我稍后将详细介绍散点图,但它有一个很好的功能,您可以在用于图表的语料库中搜索关键词,并显示该词出现在哪个 tweet/retweet 中。以下是你在搜索“不可告人”时出现的内容:

And if you search for “color revolution”, or 顏色革命:

我已经上传了交互式散点图给那些想在不使用或重新运行 Jupyter 笔记本的情况下进行实验的人。

4。中文推文中更具攻击性、偏执的语气

在用中文发微博时,“领头”的“巨魔”似乎采取了更尖锐、更偏执的语气。在接下来的两条推文中,账户@HKpoliticalnew 实质上指责美国驻香港领事馆与“香港的叛徒”合作,破坏这座城市的稳定。

此外,巨魔还声称,“许多”领事馆工作人员实际上是中央情报局的特工,是中央情报局下令发生流血冲突的:

  • @HKpoliticalnew; tweeting at 2019–07–01 05:12:00+08:00: ‘美國香港領使館千人員工,不小是 CIA 特工連同香港漢奸在港推動顏色革命 Over 1,000 US Consulate staffs, many with CIA launched Color Revolution to destabilize HK 香港警察「阿 sir 我撐你」 支持者逼爆添馬。\n\n 多名藝人藍衣撐警 譚詠麟:家和萬事興。\n\n#香港 #撐警行動 [https://t.co/alO0lhkMc6']](https://t.co/alO0lhkMc6'])
  • @HKpoliticalnew, tweeting at 2019–06–22 22:16:00+08:00: 美國喺香港推動顏色革命 總指揮嚟自香港美國領事館 下令一定要制造流血事件 美國要見血讓其媒稱…

完整的内容分析超出了本分析的范围。但是看到一份关于中国造谣运动的完整学术研究将会很有趣。

在接下来的几节中,我将更深入地研究英文和中文推文,以及用于可视化关键术语的工具。

可视化中国国家巨魔推文与分散文本

将非结构化的文本可视化是困难的。虽然频率令牌图和树形图有助于快速洞察混乱的文本,但从视觉角度来看,它们并不特别令人兴奋,当您想要检查某些关键词在原始文本中是如何使用的时,它们也没有用。

上面的树形图,突出了前 2 个巨魔账户最常用的 50 个关键英语单词,给出了一个非常粗略的用法。但是当你想直接指出一个你感兴趣的单词时,它是不精确的,也不是特别有用。

进入 散射文本 ,它将自己描述为“在中小型语料库中区分术语”的“性感、互动”工具。它有一些怪癖,比如你想分析的文本对二进制类别的硬性要求。但在其他方面,它开箱即用,包括中文文本,详细的教程将使您能够尝试各种各样的可视化。

在这种情况下,互动功能特别有用,允许我在图表中搜索关键词,并查看哪些推文和转发使用了该特定单词或短语。

我已经在这里上传了交互文件,这样你就不必为了尝试散点图而运行这个笔记本了。以下是解读图表的方法:

图表中的单词根据它们之间的联系被涂上颜色。蓝色的与原创推文联系更紧密,而红色的与转发推文联系更紧密。每个点对应一个提到的单词或短语。

定位:
-更靠近图顶部的单词代表“原始”推文中最频繁使用的单词。

-圆点越靠右,该词或短语在转发中使用的次数越多(例如:立法会)。

-在 tweets 和 rewteets 中频繁出现的词,如“警察”和“中国”,出现在右上角。

-在推文或转发中不常使用的词出现在左下角。

重点区域:
——左上角:这些词在推文中出现频率很高,但在转发中并不常见。我们仍然可以在这里看到大量的噪音,就像“sterling”和“osullivan”这样的词出现在最顶端。

-右下角:同样,经常出现在转发中而不是推文中的词出现在右下角。在这里,我们可以看到一些术语,这些术语指出了哪些是网络钓鱼者转发的热门账号——那些由中国官方媒体拥有的账号。

您可以按照自己的意愿过滤数据集,并绘制符合您需求的自定义散点图。在下面的图表中,我绘制了@ctcc507 和@HKpoliticalnew 的推文和转发:

散点图也适用于中文文本,如下两个例子所示:

The chart above plots a subset filtered for tweets containing the characters “香港”(Hong Kong). The chart below is a plot for tweets containing “顏色革命”(Color Revolution), “外國勢力”(Foreign Forces) and “美國”(United States):

生成散点图的两个笔记本分别是这里的和这里的。我对笔记本中的图表有一个稍微详细的解释,供那些希望深入了解这个话题的人参考。

我还在这个笔记本中对中国巨魔的推文进行了更详细的“去层化”尝试。例如,看到推文和转发中使用的关键词的差异是很有趣的:

最终想法

该数据集将明显受益于认真的网络分析,以找出巨魔帐户和关键字之间的联系。我没有这方面的经验,很想看看这方面的专家有什么建议。

我假设 Twitter 有一些很棒的内部工具来找出这些巨魔账户之间的网络联系,以便能够大规模关闭此类操作。

这给我们带来了一个主要问题,Twitter 和其他社交媒体巨头如何发现他们平台上的这种国家造谣活动。到目前为止,这些科技公司都没有暗示他们用来清除这些“巨魔”的方法或标准。他们的执法行动是否过于宽松或过于全面?我们现在只能猜测。

最后,鉴于香港正在发生的事件,这种“桌面分析”似乎微不足道。但希望当尘埃落定时,它会增加我们对这个复杂问题的理解。

如果您发现任何错误,请 ping 我@

推特: @chinhon

领英:【www.linkedin.com/in/chuachinhon

我早期的项目是关于推特上的造谣活动:https://github.com/chuachinhon/twitter_state_trolls_cch

有熊猫的节日日历

原文:https://towardsdatascience.com/holiday-calendars-with-pandas-9c01f1ee5fee?source=collection_archive---------1-----------------------

听说数据科学家是在 Mac 上使用 Python 的统计学家是很常见的。在某种程度上,这是正确的。然而,任何在学术界工作过的人都知道,对于统计学家来说,奶牛是球形的,一个月有 365.25/12 天。相反,在现实世界中,没有两头牛是相同的,也没有一个月是相同的。

我希望这篇文章为那些处理数据的人所花费的额外工作和时间增加价值,避免统计简化,不管他们是数据科学家还是其他什么人。

Photo by Julien Riedel on Unsplash

熊猫的时间序列

Pandas 是 Python 中数据管理的实际分析工具。它允许你轻松地处理数字表格和时间序列。Pandas 中的一个有用特性是使用 pd.date_range() 函数轻松设置日期范围,该函数包括以下参数(必须指定三个):

  • 开始:范围的开始。生成日期的左极限
  • 结束:范围结束。右极限
  • 周期:要生成的周期数
  • 频率:频率字符串(如 D:日历日频率,M:月末频率,Y:年末频率)参见抵销别名列表

时间序列的基本例子

几行就够了:

 Date
0  2019-01-31
1  2019-02-28
2  2019-03-31
3  2019-04-30
4  2019-05-31
5  2019-06-30
6  2019-07-31
7  2019-08-31
8  2019-09-30
9  2019-10-31
10 2019-11-30
11 2019-12-31

创建每月最后一个工作日的时间序列

在某些领域,主要是金融和精算领域,管理日期范围特别有用,其中系列中的日期对应于该月的第一个或最后一个工作日(例如,当计划支付息票或年金时)。

为此,PD . date _ range()函数具有不同的频率参数值。在以下示例中,“BM”对应于 BusinessMonthEnd (每月的最后一个工作日):

 Date
0  2019-01-31
1  2019-02-28
2  2019-03-29
3  2019-04-30
4  2019-05-31
5  2019-06-28
6  2019-07-31
7  2019-08-30
8  2019-09-30
9  2019-10-31
10 2019-11-29
11 2019-12-31

要从数据中预测未来,就必须知道要填补的空白

然而,如果我们想要更准确,我们必须考虑银行假日(例如,如果我们计算的成本取决于息票和息票之间的确切天数,20 天中有 1 天是 5%的误差)。在评估人类习惯和行为(医疗保健、旅行等)时,知道一段时间内的假期特别有用。).在保险业,这些模式可以直接影响会计准备金;例如,在计算已发生但未报告的成本时(IBNR)。事实上,在一些保险公司,由于闰年比其他年份多一个日历日,所以略微提高索赔率是很常见的。

在下面的例子中,我们引入了两个银行假日的列表(2 月 28 日5 月 31 日)来看看它是如何工作的。然后,如果付款发生在每月的最后一个工作日,我们将计算付款间隔的天数:

 Date  n_days
0  2019-01-31     0.0
1  2019-02-27    27.0
2  2019-03-29    30.0
3  2019-04-30    32.0
4  2019-05-30    30.0
5  2019-06-28    29.0
6  2019-07-31    33.0
7  2019-08-30    30.0
8  2019-09-30    31.0
9  2019-10-31    31.0
10 2019-11-29    29.0
11 2019-12-31    32.0

如图所示,2019–02–28 和 2019–05–31 没有出现在支付日历中。

为自定义假日日历创建规则

最后,可以选择编写计算公共假期的规则(因为这些规则通常会延续到下一个工作日)。

在某些国家,如美国,有法律(1968 年统一星期一假日法案),其规则包含在 Pandas,print(usfederalholidaycalendar . rules)中,作为开发其他日历的示例。

然而,在许多其他国家,没有确定一年中的假期的规则(如在欧洲),假期是由每年的法规确定的。对于在固定日期发生的假日(例如美国阵亡将士纪念日4 月 4 日),遵守规则确定该假日是在周末还是其他未遵守的日子。定义的遵守规则有:

在这种情况下,可以使用一些公共前提来编写劳工日历的规则,用于计算银行假日,因为星期日被移到下一个星期一(observation = Sunday _ to _ Mondayinstruction)。例如:2018 年加拿大国庆日(7 月 1 日)是周日,被移到了 7 月 2 日。这些应该在AbstractHolidayCalendar类上被覆盖,以使范围应用于所有日历子类。

后来,我展示了 2018 年 7 月的劳动节,以检查它是如何工作的:

 Date
0  2018-07-03
1  2018-07-05
2  2018-07-06
3  2018-07-09
4  2018-07-10
5  2018-07-11
6  2018-07-12
7  2018-07-13
8  2018-07-16
9  2018-07-17
10 2018-07-18
11 2018-07-19
12 2018-07-20
13 2018-07-23
14 2018-07-24
15 2018-07-25
16 2018-07-26
17 2018-07-27
18 2018-07-30
19 2018-07-31

你可以看到 7 月 1 日星期日是如何被 7 月 2 日星期一取代的

这样,一旦我们创建了自己的国家假日日历,我们就可以使用它来查看未来几年的银行假日,例如 2020 年:

DatetimeIndex(['2019-01-01', '2019-01-07', '2019-03-18', 
               '2019-04-01', '2019-04-19', '2019-05-01', 
               '2019-07-01', '2019-07-04', '2019-11-01', 
               '2019-12-25'],
              dtype='datetime64[ns]', freq=None)

地区和当地的节日也可以以同样的方式包括在内,尽管注意到在某些国家通常是可移动的节日(一个宗教节日,每年不在同一天)。在这种情况下,有必要基于 【复活节()周日 _ 至 _ 周一() 熊猫函数创建一个新函数。例如,在法国,圣灵降临节是复活节后的第七个星期一。

Photo by San Fermin Pamplona - Navarra on Unsplash

我们的自定义日历也可以用于其他图书馆,如 Prophet。 Prophet 是一个由脸书创建的高级机器学习库,专注于非线性时间数据回归模型,需要用户提供一个假期列表。

关于犹太历中规则的创建,请看由 Ulrich 和 David Greve 所做的这些规则。

(西班牙文,)

整体大规模视频理解

原文:https://towardsdatascience.com/holistic-large-scale-video-understanding-c423701b777a?source=collection_archive---------16-----------------------

每年在世界各地都会举行几次机器学习、深度学习和计算机视觉方面的会议。在这些会议上,将确定提交研究人员文章的具体截止日期。会议的组织者将收集提交的文章,然后,他们的裁判将判断和审查他们。通常,裁判是从优秀的大学教授中挑选出来的,这些教授对机器学习领域有着丰富的知识,拥有长尾专业知识。最后,在创新程度、质量、解决科学问题的效果以及其他措施方面,一些较好的文章将被选择用于出版过程。

在会议期间,他们提交的论文被接受的研究团队将在预定的时间内展示他们的工作和研究成果。通常在这些会议之余,会在上述领域举办一些特别重要的研讨会。在这些研讨会中,将研究人工智能特定领域的科学和实践方面的当前趋势(例如,视频理解)。在某些情况下,还会发起一场竞赛来鼓励研讨会的参与者。这些会议及其相关的研讨会对人工智能领域的实践和科学进步具有重大意义。

在计算机视觉和机器学习领域最重要的会议中,我们可以参考计算机视觉和模式识别(CVPR)、国际计算机视觉会议(ICCV)、欧洲计算机视觉会议(ECCV)、神经信息处理系统会议(NIPS)、国际学习表征会议(ICLR) 等。同时, ICCV 2019 大会预计将于今年 10 月 27 日至 11 月 2 日在韩国首尔举行。

ICCV 2019 [reference]

ICCV 2019 提供了非常有趣的研讨会,在它的研讨会中,还提议在视频处理领域举办其他几个研讨会。这些讲习班包括以下内容:

1- 大规模整体视频理解:

这个研讨会的内容是这篇文章的主题,我将在后面继续阐述(在接下来的部分)。

2- 野外综合视频理解(CoVieW 2019) :

本次研讨会主要讨论基于场景和动作信息组合的未剪辑(,真实视频)视频摘要任务。由于在当今世界,为互联网用户节省时间是一件非常重要的事情,根据这一观点,视频摘要在不同的应用中是一项非常有利可图的任务。视频摘要任务仍然处于其早期阶段,并且从用户的观点来看还远远没有达到期望的程度。根据本次研讨会组织者的观点,动作识别和场景识别信息的结合可以导致解决这个问题的适当方法。本次研讨会的组织者还为此提供了一个数据集,其中包括约 1,500 个视频,并基于此设计了一个挑战。他们将每段视频分成 5 秒钟的片段,然后让 20 名人类注释者对每段片段进行注释。注释过程也由该段视频(,即,每个视频片段)的重要程度,以及相关的场景和相关的动作标签决定。该数据中场景和动作类的总数分别为 98 和 74 类。总而言之,可以说,提到的工作坊是视频内容理解领域的一个有价值的工作坊。然而,在我看来,对于这样一个复杂的任务来说,所提供的数据集的大小(,即,其中可用的视频数量)是低的。

Some Video Snapshots of the CoVieW 2019 Workshop [reference]

3- 视频检索方法及其局限性(病毒性):

本次研讨会的重点是基于内容分析的视频检索任务。在这方面,研讨会的组织者将视频搜索和检索问题分为两大类:1- 一般搜索和 2- 实例搜索一般搜索特别搜索是根据用户的查询检索最相关或最相似的视频的任务。查询类型还可以包括视频、图像或文本(,自然语言描述)。而实例搜索任务是用户实际在寻找一个特定的物体、人或者地点,从而检索出包含用户想要的物体的视频。本次研讨会的组织者没有为上述任务提供具体的数据集,相反,他们介绍了该领域三个先前开发的数据集,作为他们提议的数据集。这三个数据集如下:1- Vimeo Creative Commons (V3C),2-Internet Archive Creative Commons(IACC . 3),3-BBC east endersReference

4- 第三届 YouTube-8M 大型视频理解工作坊:

本次研讨会的主要焦点是基于 YouTube-8M 数据集的视频分类任务。谷歌公司在 2016 年首次引入了这个数据集;显然,这个数据集是庞大的 YouTube-100M 数据集的子集,YouTube-100m 数据集是谷歌的私有数据集,谷歌不打算发布它。就视频数量而言,该数据集被认为是视频分类领域中最大的可用数据集。此外,它还对应着 YouTube 网站上约 610 万个视频的视频分类任务,每个视频的时长在 120 到 500 秒之间。该数据集的类别集(,标签集)包含 3862 个实体(类别标签)。每个视频的关联标签是半自动生成的(,机器生成),并由 3 个审查者视觉验证。
这个数据集中的所有视频也都有音频,在 多模态(视听建模)深度融合学习 方法方面很重要。该数据集包含总共约 35 万小时的视频,需要超过 100 的存储空间。谷歌研究团队为了使小型团队对这个庞大的数据集进行研究变得可行,还从帧级 Inception V3 模型中提取并提供了总共 13 亿个视觉特征,以及来自 VGG 启发的声学模型的大约 13 亿个音频特征。尽管就可用视频的数量而言,这个数据集被认为是当前最大的数据集,但在我看来,它的主要问题和缺点是其现有的注释非常有限,并且没有足够的丰富度来全面处理整体视频理解任务。

[reference]

5- 智能短视频:

由于大量的短视频(,从几秒到几分钟的视频)在社交网络上在不同用户之间共享和交换的事实,这些视频的处理可以是计算机视觉社区的重要主题。研讨会的主要重点是讨论这个案例。据我所知,只要这篇文章还在写,这个研讨会就不会提供任何数据集和竞赛。

6- 多模式视频分析和时刻:

该研讨会的重点是基于视频内容的多模态行为来分析视频内容(,提供深度融合学习模型,可以同时整合和训练正确的空间、时间和听觉视频信息)。研讨会的组织者,大部分是麻省理工学院-IBM 沃森人工智能实验室的成员,也提议在研讨会的同时举办两个比赛。第一场比赛是多模态多标签动作识别挑战赛。比赛是基于 时刻 数据集设计的,旨在以多模态、多标签的方式识别给定视频中的动作。《时刻》数据集由大约 83 万个 3 秒的视频片段组成,有超过 200 万个动作标签[ 参考参考 ]。该数据集在视频理解领域是一个重要而有价值的数据集,但问题是其当前版本仅关注视频的动作,没有其他注释。

[reference]

第二场比赛名为 时间动作定位挑战赛 ,计划在视频动作定位任务中进行。动作定位任务意味着精确地确定给定视频中特定动作的确切时间段。主办方团队为本次比赛提供的数据集为 HACS 片段数据集;它有 140,000 个动作片段,带有来自 50,000 个未剪辑视频的时间注释。
接下来,我会详细讲解 大规模整体视频理解 工作坊以及视频内容综合理解的话题。

整体视频理解:

我们在视频处理领域的终极目标是全面理解给定视频的内容。视频中包含了很多信息,比如关于每一帧的信息(也称为 空间 信息)、运动信息、时间信息、音频信息、不同帧中发生的动作、事件、视频每一帧中存在的物体、每一帧的场景信息等概念和属性。如果我们可以将所有这些信息结合在一起,并对它们进行适当的分析,或者我们设计一个深度神经网络,将所有这些信息一起彻底学习,那么我们可以声称我们已经实现了一个智能视频分析系统,通过它我们可以对视频信息进行二次分析,换句话说,我们已经使视频可以搜索。
遗憾的是,几乎所有视频内容理解领域的前期工作都只关注视频中的动作识别问题。虽然准确的动作识别将对视频内容的理解产生重大影响,并且动作识别在视频理解中起着关键作用,但在以前的作品中,其他信息的缺乏是相当明显的。之前的数据集如 YouTube-8M,Sports-1M,Kinetics 等。,只专注于动作识别或视频分类任务(特别是关于体育活动和人类活动),其他关于视频内容的信息不包含在它们的标注中。因此,他们的注释列表在提供整体智能视频理解系统方面并不丰富。值得注意的是,其他视频信息的可用性,如其中的对象、场景信息等。在确定视频活动的类型方面也非常有效,不幸的是当前的数据集缺乏这种信息。

[reference]

非常好的消息是,计划在 ICCV 2019 大会上举行的 大型整体视频理解 研讨会即将应对上述问题。在这方面,研讨会的组织者设计了一个全面且极具价值的数据集(整体视频理解(HVU)数据集),包括一整套语义概念(来自脸书人工智能研究 (FAIR)、KU Lueven、波恩大学、KIT、ETH Zurich)。这个数据集着重于全面的 多标签多任务 视频理解,而在这方面,HVU 数据集包含了大约57.7 万个视频和1300 万个标注!此外,我们可以声称,从大量注释的角度来看,HVU 数据集被认为是用于视频内容理解的极其有价值和独特的数据集。

HVU 视频的持续时间不同,最长为 10 秒钟。HVU 有 6 个主要类别:场景、对象、动作、事件、属性和概念。总共有 4378 个班级。用于训练和验证集的 13M 注释。平均来说,每个类有 2681 个注释。它包含 419 个场景类别、2651 个对象类别、877 个动作类别、149 个事件类别、160 个属性类别和 122 个概念类别,自然地捕捉到了现实世界中视觉概念的长尾分布。HVU 由训练、验证和测试集中的 481k、31k、65k 个样本组成,是一个足够大的数据集,这意味着数据集的规模接近图像数据集的规模(例如,ImageNet)。下图展示了 HVU 数据集的一些统计数据。

The HVU dataset statistics [reference]

Number of classes of each category over all classes in the HVU dataset [reference]

Number of annotations of each category over all annotations in the HVU dataset [reference]

HVU 数据集是在整体视频理解的语义分类中分层组织的。如前所述,我可以说,在最近的动作识别工作中,一个重要的研究问题没有得到很好的解决,那就是利用视频中的其他上下文信息。HVU 数据集使得评估不同任务之间的学习和知识转移的效果成为可能,例如实现视频中物体识别到动作识别的转移学习,反之亦然。总之,HVU 可以帮助视觉社区,并为整体视频理解带来更多有趣的解决方案。HVU 数据集侧重于识别现实世界中用户生成的视频中的场景、对象、动作、属性、事件和概念。下图展示了 HVU 数据集和其他公开可用的视频识别数据集在注释方面的比较。显然,HUV 数据集的注释比其他数据集更加丰富。

Comparison of the HVU dataset with other publicly available video recognition datasets [reference]

事实上,受努力构建静态图像中对象识别的大规模基准的激励,学习 通用特征表示 的大规模视觉识别挑战(ILSVRC)现在是支持几个相关视觉任务的主干。我的意思是,由于 ImageNet 数据集的发布为图像理解任务的许多领域开辟了一个研究场所,因此这样的数据集也是视频理解所需要的。考虑到这一事实,上述研讨会的组织者收集并设计了 HVU 数据集。他们受同样的精神驱使,学习视频级别 的 通用特征表示,以获得整体视频理解。因此,我们得出结论,HVU 数据集可以帮助视觉社区,并为整体视频理解带来更多关注。

HVU 数据集的采集和注记过程:

本节简要介绍了 HVU 数据集的收集和注记过程。由于他们的目标是现实世界中用户生成的视频,得益于 Youtube8M、Kinetics-600 和 HACS 的分类多样性,他们将这些数据集用作 HVU 的主要来源。所有上述数据集都是用于动作识别的数据集。我们知道,由于视频的数量,手动注释大量具有多个语义概念的视频是不可行的,而且人类很难注意到每个细节,这可能会引入难以消除的标签噪声。因此,他们采用了半自动的标注方法。他们已经使用 森思飞视频标签 API 来获得视频的粗略注释,该注释预测每个视频的多个标签(或类别标签)。Sensifai 是一家创业公司,它开发了许多前沿的视听深度学习技术,以提供明智的整体视频理解模块。为了确保每个类都有大约相同数量的样本,他们删除了样本少于 50 个的类。他们提供了一个带有视频播放器的 GUI 界面和每个视频的预测标签,每个标签都有一个复选框条目。随后,专家人工注释者验证标签与其相应视频的相关性,以用于验证和测试集。

结论:

视频内容理解是计算机视觉领域中最有趣和最具挑战性的课题之一。在这篇文章中,我试图简要介绍计划在 ICCV 2019 大会上举行的研讨会,以便给研究人员一个参与这些研讨会的强大激励和动力。除了 HVU 数据集,在视频理解领域已经提供的其他数据集和研讨会中,没有一个具有用于明智的视频理解的强大和全面的注释集。幸运的是,随着新 HVU 数据集的引入,可以设计和训练深度神经网络,以提供端到端的全面视频理解过程。值得注意的是,在视频处理领域数据集(如 HVU)上训练深度模型的过程需要基于高性能 GPU 的服务器,并且实际上不可能将它们安置在家用和较低 GPU 架构上(例如,游戏 GPU)。这是由于该领域中大量的大规模数据集以及该领域深层网络的多模态和通常的 3D 性质(,例如,3D ConvNet 架构)。因此,我鼓励读者使用基于高性能多 GPU 的机器在该领域提到的数据集上训练他们设计的深度模型(,例如,AWS,FloydHub, Paperspace ,或具有多 Tesla V100 GPUs 的 Alibaba 实例)。

值得一提的是,据我所知,HVU 数据集提供商团队打算在未来开发该数据集(在视频数量和丰富其注释列表方面),甚至可能添加视频描述作为自然语言描述。因此,在未来,我们可以利用这样一个巨大而有价值的数据集来完成一些有用的任务,比如视频字幕或视频问答。此外,在未来几年而不是目前,我们可能会看到通过使用视频的自然语言描述和生成对抗网络 ( a.k.a. ,GANs)自动创建目标视频的帧!

最后,我想说,我相信 HVU 数据集将在学习通用视频表示方面补充计算机视觉,这将实现许多现实世界的应用。此外,在 HVU 数据集上训练模型,将提高基于视频的任务的迁移学习泛化能力。我还将鼓励深度学习研究人员通过基于多 GPU 的机器在 HVU 数据集上设计和训练他们的深度模型,以达到视频理解的奇妙通用特征表示。

关于作者:

我是高级深度学习研究员。我在机器学习、深度学习和计算机视觉方面经验丰富。我为这个行业在这些领域做了很多项目。
可以关注我的
(我的 LinkedIn 简介 )
(我的 GitHub 简介 )
(我的谷歌学术简介)

整体声誉管理:集体影响力之路

原文:https://towardsdatascience.com/holistic-reputation-management-the-road-to-collective-impact-985dc6cd7d90?source=collection_archive---------26-----------------------

如今的声誉管理与媒体监督齐头并进。毕竟,没有监控就不可能洞察正在发生的事情,没有洞察就没有焦点,没有焦点就没有控制。这正是你想要的。控制。当你处于控制中时,你可以主动行动,即使是在危机这样的被动情况下。当你处于领先地位并积极行动时,你可以保护和建立公司的声誉,因为这使你能够正确预测和预防工作。你如何确保作为沟通专家的角色在你的组织中变得可见,并且你的整个公司也能从中学到东西?这就是我们关于声誉管理的四篇系列文章中的这一篇。

确保你不必动不动就灭火。作为一名通信专业人员,您在改善预防和预测公司中不希望出现的情况方面发挥着关键作用。毕竟,你想为整个组织的成功做出贡献,并创造一个透明和明确的沟通。因此,在内部分享你开展的有针对性的活动(例如在危机情况下)非常重要。这包括由于媒体报道而“可见”的活动,如与利益相关者的预防性沟通。

阅读更多关于媒体监控 2.0 (这个四部分系列的第 1 部分)

阅读更多关于如何衡量 PR (这个四部分系列的第二部分)

明确你的角色

企业沟通的角色已经发展成为一个多方面的功能,需求也越来越多。如今,通信专业人士不仅要保护自己公司的声誉,还要主动帮助建立声誉。更重要的是,他们应该成为成熟的讨论伙伴,挑战和反驳董事会,不应该害怕提问。换句话说:是时候加强你的游戏并取得控制权了。

你的角色告诉你,保护和影响声誉不再是企业沟通的“事情”,而是整个组织的事情。从首席执行官到客户服务,利益相关者的每一句话、每一个决定、每一个接触点都会产生影响。声誉的可制造性已经成为过去,你不能再把任何东西伪装成一个组织。这带来了第四个角色:连接器的角色,重点是“教育”内部组织,以便每个人都在同一页面上。这样,组织就可以从整体的角度开始运作。企业传播教授 Cees van Riel 强调了整体主义的概念:“声誉在一个公司中或多或少要制度化”。

将内部利益相关者纳入流程

整体方法的重要性显而易见。但是你如何引起人们对此的关注呢?在沟通中保持清晰透明,包括所有利益相关方。告诉他们在危机时刻采取了什么措施,为什么。还要说明它是如何影响每个独立部门的。培训内部利益相关者,让他们了解沟通和声誉以及他们在其中扮演的角色。向他们展示你的员工(和管理层)是你组织的重要象征,他们有很大的(积极的)影响力。确保他们意识到这一点,并用 LinkedIn 或 Twitter 帖子中的例子以及这些对公司声誉的影响来具体说明这一点。

“意识是获得关注的第一步,并确保每个人都在同一页上。”

让他们相信整体方法:3 个关键因素

比以往任何时候都有更多的公司愿意投资他们的声誉,他们显然已经看到了光明。合乎道德和可信的行为是非常重要的,如果一家公司没有做到这一点,整个世界都会立即知道。甚至像脸书、优步和 Airbnb 这样抱着“快速失败”心态的公司,在几起被广泛报道的丑闻之后,也意识到了声誉的重要性。在内部分享这些案例有助于让管理层相信声誉作为整个组织的一项责任的重要性。3 这一责任的重要因素是充分的透明度、可信度和领导力。

#1 完全透明

企业管理透明化是一种已经持续了一段时间的趋势。这是无法回避的。当你对实际活动保持透明,并把它映射出来时,情况就大不一样了。简单地说你是什么和做出承诺不会让你有任何进展。目前,透明度还比洞察年度数据和战略更进了一步。人们想知道过程是如何进行的,它们是否合乎道德,以及你为什么做出这样的决定。例如,公开整个生产过程以及公司员工的待遇。

独立监督人也获得了越来越多的权力,因此不可能避免对你的过程公开和诚实。RTL·纽斯最近在 T2 进行的一项关于动物福利、药物使用和环境的研究强调了这一点。几份检验报告显示,数百种产品被错误地当作有机产品出售。有机部门的声誉直接受此影响。

#2 要可信

此外,围绕品牌目标的宏观趋势(例如,作为一家公司,你代表什么?)和信任让你的可信度增长。每个组织都可以说他们在做这做那,但是当他们没有提供任何证据时,这是完全不可信的。座右铭是:“言出必行”。为了让你的承诺和行为可信,它们必须匹配并在组织的各个层面得到传达。如果你不将可持续发展政策应用到日常运营中,那么在你的网站、媒体宣传以及你所采取的行动上保持透明是没有意义的。

# 3 展现领导力

首席执行官的声誉也变得越来越重要。去年,声誉研究所甚至为此专门进行了一项独立的 T4 研究。而且有充分的理由;它有助于传达第一点。在媒体交流中保持透明或在客户服务中保持可信已经不够了。是的,这些要素当然很重要,它们有助于“步调一致”的原则。但如果你想增加这方面的权力,重要的是展现你的领导力,采取明确的立场,并以首席执行官的身份传达这一点。当然,在你传达的信息中,与第一点和第二点保持一致是必不可少的。

一个很好的例子是伦敦政府决定禁止优步进入伦敦后,优步新任首席执行官 Dara Khosrowshahi 的行动。在一封公开、诚实和充满感情的致员工的电子邮件中,他采取了具体的步骤来改善公司的形象。这导致 2018 年在伦敦更新了执照。

因此,整体声誉管理至关重要。在这方面,对社会的影响、道德行为和采取明确的立场是至关重要的主题。基于这一趋势,我们也看到 CSR(企业社会责任)获得了不同的含义,包含了比一般公众所认为的更多的内容。你可以在这个博客系列的第四部分,也是最后一部分,读到更多关于这种转变以及如何应对的内容。

全息伦敦地铁可视化

原文:https://towardsdatascience.com/holographic-london-underground-visualisation-b0462ae19d6e?source=collection_archive---------30-----------------------

Image of the Victoria line presented as a hologram ©Christopher Doughty

使用 d3.js 和 pepper 的 ghost 作为呈现数据的创造性方式

在他的书《想象信息》中,爱德华·塔夫特谈到了我们的视觉被屏幕和纸张的二维平面困住[1]。我想探索一种可视化数据的替代方法,所以我寻找一种创造性的方法来引起观众的兴奋,并逃离电脑屏幕的单调。像增强现实这样的技术是通过在现有的基础上增加层次来实现的;然而,我选择了更容易和更便宜的东西。用一张塑料,我创造了一个数据可视化的全息幻觉。

最终的可视化效果可在以下页面查看(需要查看器):https://penguinstrikes . github . io/content/pepper _ ghost/index . html

Me interacting with the visualisation on an iPad

佩珀的鬼魂

我想在作品中利用的视觉化技术使用了一种叫做“胡椒幽灵”的幻觉。19 世纪 60 年代,一位名叫约翰·h·佩珀的讲师首次描述了这一现象。这种效果在剧院里被用来创造舞台上的幻影,包括从观众和被投影的物体上斜放一块玻璃。下图显示了错觉的工作原理。

Diagram explaining how Pepper’s Ghost works

为了使效果在屏幕上工作,必须建立一个查看器。这可以通过从四个梯形塑料创建一个金字塔来创建一个查看器来实现,如下图所示。

My pyramid placed on an iPad

伦敦地铁数据

有了全息技术和一个观察器,我寻找一些数据来显示。已经下载了几个开源数据集,我决定使用伦敦地铁站和深度数据[2]。

D3.js 实现

最棘手的部分是构建可视化。我选择使用 D3.js 并创建四个 SVG,它们都显示相同的数据,但是旋转形成一个正方形的每一边。下图是从浏览器中捕捉到的,以不同的投影角度呈现了所有四个数据集。

D3.js visualisation showing the same data at 0, 90, 180, and 270 degrees

我想在表示层使用 D3.js 的原因是为了提供与数据交互的功能,而我之前在 Pepper's Ghost online 上看到的都是演示视频。

决赛成绩

您可以通过以下链接查看 D3.js 可视化效果https://penguinstrikes . github . io/content/pepper _ ghost/index . html,但是您需要自己的查看器来查看实际效果。请注意,如果您在平板电脑或手机上浏览,那么您需要水平旋转显示屏并重新加载页面以确保格式正确。

虽然我不认为这将成为一种革命性的数据呈现方式,但投影确实可以让信息在离开屏幕时变得更加有形。主要的缺点是全息图的尺寸使得你几乎不可能理解数据显示给你的是什么。我知道这严重违反了数据可视化原则,但是尝试一些有创意的东西是值得的!

参考

[1] Tufte,E. R .,&图形出版社。(1990).预见信息

[2]根据开放政府许可证 v3.0 提供

Airbnb 购房者指南:NYC(数据挖掘和回归分析)

原文:https://towardsdatascience.com/home-buyers-guide-to-airbnb-nyc-a240c43ff610?source=collection_archive---------31-----------------------

Photo by NASA on Unsplash

自 2008 年成立以来,Airbnb 一直是庞大的酒店业的主要颠覆性力量,为全世界的消费者重新定义了旅行的现状。通过在一个强大的平台上将闲置的私人生活空间与旅行者联系起来,Airbnb 能够以酒店无法竞争的价格提供令人难以置信的价值。

纽约是 Airbnb 的第三大市场,约有 35000 个活跃房源(截至 2018 年 8 月)。尽管对上市有相对严格的要求(由于 2016 年底签署的一项法案,该法案禁止在主人不在场的情况下在 30 天内短期上市),纽约市场仍然很好地保持了这一全球地位,这是由于其强劲的旅游业 &昂贵的接待费用。尽管纽约可能会被监管较少的城市取代,但它很可能会继续成为 Airbnb 的主要市场。

目标

作为一个有兴趣在纽约购买公寓的人(可能在很远很远的将来…🙄),我想更好地了解:

  1. 整体市场(趋势、平均价格、细分市场)
  2. 潜在的邻居
  3. 配置(卧室-浴室)
  4. 评定类别(哪些重要,如何做好)

一旦我们对这些有了更好的了解,我们将能够为那些想在纽约购买公寓并从空房中获利的人提供关于寻找什么类型的公寓/公寓(以及在哪里)的建议。

1.纽约 Airbnb 市场

纽约的 Airbnb 市场似乎已经繁荣起来,在过去的 5 年里,房源数量增加了 85%。🚀

在同一时期,评论也有类似的增长,表明市场的客人方面也有显著增长。

虽然事情似乎已经有所放缓(可能是由于纽约市议会的监管打击,这种打击在最近几年有所加剧),但纽约最有可能继续成为 Airbnb 的强劲市场——因为它作为大都市旅游业务中心的强大地位。

2.潜在的邻居

根据纽约市的房源分布,最受欢迎的社区似乎是曼哈顿、布鲁克林和皇后区(T21)。自然,这些都是纽约挂牌交易增长背后的主要驱动力(尤其是曼哈顿&布鲁克林)。

为了找出最有吸引力的社区,我们使用线性回归模型来确定 3 个最受欢迎的地区(曼哈顿、布鲁克林、皇后区)的顶级社区的平均估计月收入(使用 2018 年 1 月至 2019 年 6 月的数据)。以下是结果(针对 1 间卧室+ 1 间浴室):

最有吸引力的社区(就预期收入而言)大多在曼哈顿,其次是威廉斯堡(布鲁克林)和阿斯托里亚(皇后区)。平均而言,曼哈顿的预期收入似乎是布鲁克林和皇后区顶级社区的两倍左右。不出所料,这些社区在各自的群体中也拥有最好的位置。

New York City Airbnb Listings, by Price

为了在 Airbnb 上获得最佳回报,我们建议将搜索集中在这三个地区,尤其是曼哈顿(如果预算允许的话)💰)。

3.配置

另一个关键因素是公寓单元的配置。也就是说,我们应该考虑多少间卧室&浴室(除了我们自己的空间)。出于此分析的目的,我们考虑了以下因素:

  • 1 间卧室+ 1 间浴室
  • 2 间卧室+ 1 间浴室
  • 2 间卧室+ 2 间浴室

我们还使用线性回归模型来预测哪种配置会产生最高的预期年收入。以下是结果(使用曼哈顿东村作为参照区):

我们可以清楚地看出,仅仅增加卧室数量不会对平均收入产生重大影响。为了产生影响,需要有相应的浴室数量(即 2 间卧室+ 2 间浴室,而不是 2 间卧室+ 1 间浴室)。这缩小了我们的选择范围:

  • 1 间卧室+ 1 间浴室
  • 2 间卧室+ 2 间浴室

由于双卧室配置表现明显更好,决定取决于你能负担多少。请注意,上述配置是在你的个人卧室&浴室的顶部,所以你实际上是在比较一个两居室和一个三居室。

4.等级

在 Airbnb 中,有 5 个关键的评级类别(准确性、入住率、沟通、清洁度、准确性)。我们决定更深入地研究这些因素与预计月收入表现之间的关系。

线性模型系数

当查看线性回归模型中每个的系数时,我们可以清楚地看到每个在 Airbnb 性能中的重要性。在这些指标上取得良好的绩效归结于:

  • 精准&优质房源(即描述、照片等。)
  • 良好运营(例如清洁、维护、游客支持)

这些都是可变的,完全取决于你建立物流和流程的能力,以确保上述同时保持低成本。

然而,位置是独一无二的,因为它是一个固定的参数,完全取决于你决定将你的房产建在哪里。我们关注的社区群体(曼哈顿、布鲁克林和皇后区)在这个标准中表现最好。具体来说,你离曼哈顿的“热点”越近(如时代广场、帝国大厦),你在这个指标中的表现就越好。

那么…我该买什么呢?

既然我们对纽约 Airbnb 市场、候选地点和配置以及评论类别有了很好的了解,我们就可以开始评估“理想”的 Airbnb 应该是什么样子了。

为了简化分析,我将假设我正在寻找一个至少有两个卧室和一个卫生间的公寓(因为纽约市的法规要求主人必须在场才能合法短期居住)。

假设下面的公寓价格,这里是来自 Mashvisor 的 2019 年公寓的大概平均价格:

不出所料,曼哈顿的价格明显高于其他两个区域——尤其是当你走向更多的卧室时。对于布鲁克林和皇后区来说,随着卧室数量的增加,价格上涨似乎没有那么剧烈。

当您将此与邻域排名数据(来自问题#1)叠加时,我们可以看到最佳性价比是:

  • 曼哈顿:东村两室两卫
  • 非曼哈顿:阿斯托利亚的三房三卫

结束语

尽管纽约市是 Airbnb 最大的市场之一,但它也是监管不确定性最高的城市之一(Airbnb 纽约市议会互相攻击已经有 5 年了)。当你探索纽约的住宅房地产市场时,关注这些市场的发展轨迹和对最终结果的了解是至关重要的。

此外,另一个不在本次分析范围内的因素是纽约市的整体房地产市场。该地区房地产市场的增长轨迹是购房时最大的决定因素之一(也就是说,你不会想在市场崩溃之前买房,就像 2008 年那样!).

上面分析的 GitHub repo 可以在这里找到。

家庭价值预测

原文:https://towardsdatascience.com/home-value-prediction-2de1c293853c?source=collection_archive---------10-----------------------

使用机器学习算法预测房地产价值

像 Zillow 这样的公司是如何为不出售的房屋提供估价的?他们收集每个属性的特征数据,并使用机器学习算法进行预测。在本文中,我将使用 Kaggle 的“房价”竞赛中包含的数据集来演示类似的分析。

探索性数据分析

首先,让我们看看响应变量“销售价格”。它是正向倾斜的。大多数房子的售价在 10 万至 25 万美元之间,但有些房子的售价要高得多。

Figure 1: Observed sale price

该数据集包含 80 个描述房产特征的特征,包括浴室数量、地下室面积、建造年份、车库面积等。热图(图 2)显示了每个特性和响应变量“销售价格”之间的相关性。这为我们提供了有关预测销售价格的特征重要性的信息,并指出哪里可能存在多重共线性。毫不奇怪,房屋的整体质量“总体质量”与销售价格高度相关。相比之下,房屋出售的年份“YrSold”与销售价格几乎没有关联。

Figure 2: Heat map showing the correlation among features and sale price

数据清理

应对 NAs

此数据集中有许多 NAs 有些功能几乎全是 NAs,而许多功能只有少数几个。

我们可以删除提供很少信息的功能,如实用程序。

df.Utilities.describe()

除了一个属性之外,所有属性都被指定为“Allpub”类别,因此我们可以删除该特性。由于缺乏变化,该特性与我们的响应销售价格几乎没有关联(图 2),所以我们并不担心会失去它。

df=df.drop([‘Utilities’], axis=1)

很少有 NAs 是随机的,因为缺少信息通常与记录本身有关,而不仅仅是因为收集错误。例如,GarageType 记录的 NA 可能意味着该物业上没有车库。在该数据集中,有与车库相关的分类和连续特征。我们可以相应地用 0 和“无”来填充那些具有 NAs 功能的属性,表示缺少车库空间。

# Garage categorical features to none
for i in (‘GarageType’, ‘GarageFinish’, ‘GarageQual’, ‘GarageCond’):
 df[i] = df[i].fillna(‘None’)# Garage continuous features to 0
for i in (‘GarageYrBlt’, ‘GarageArea’, ‘GarageCars’):
 df[i] = df[i].fillna(0)

NAs 对于其他功能没有明确的解释,与信息的缺乏有关。在这种情况下,我们可以观察每个记录的出现频率,并选择最可能的值。让我们看看描述分区分类的特性“MSZoning”的频率分布。

Figure 3: Frequency of zoning classification

到目前为止,住宅低密度(RL)是最常见的分类。解决此功能中四个 NAs 问题的实用方法是简单地用“RL”替换 NAs。

df.MSZoning=df[‘MSZoning’].fillna(df[‘MSZoning’].mode()[0])

数据转换

为了最大化我们的模型的性能,我们想要标准化我们的特征和响应变量。正如我们在图 1 中看到的,我们的响应变量是正偏的。通过应用对数转换,销售价格现在类似于正态分布(图 4)。

resp=np.log1p(resp) # transform by log(1+x)

Figure 4: Log transformed response variable Sale Price

我们还必须检查所有连续要素的倾斜情况。

# identify numerical features
num_feats=df.dtypes[df.dtypes!=’object’].index# quantify skew
skew_feats=df[num_feats].skew().sort_values(ascending=False)
skewness=pd.DataFrame({‘Skew’:skew_feats})
skewness=skewness[abs(skewness)>0.75].dropna()
skewed_features=skewness.index

在我们想要转换的所有这些特性之间,偏斜度会有很大的变化。box cox 变换提供了一种灵活的变换特征的方法,每个特征可能都需要另一种方法。函数 boxcox 将估计最佳 lambda 值(变换中的一个参数)并返回变换后的要素。

# add one to all skewed features, so we can log transform if needed
df[skewed_features]+=1
# conduct boxcox transformation
from scipy.stats import boxcox# apply to each of the skewed features
for i in skewed_features:
 df[i],lmbda=boxcox(df[i], lmbda=None)

一键编码

最后,我们需要对我们的分类变量进行一次性编码(或伪代码),以便它们可以被模型解释。

df=pd.get_dummies(df)

建模

我们将把两个广泛应用的机器学习模型拟合到训练数据中,并使用交叉验证来评估它们的相对性能。

随机森林回归量

为了确保我们的随机森林回归模型具有最大化其预测能力的属性,我们将优化超参数值。我们希望估计以下各项的最佳值:

n _ 估计量: 森林中的树木数量

max _ features:每次分割要考虑的最大特征数

max_depth: 任意树的最大分裂数

min _ samples _ split:拆分一个节点所需的最小样本数

min _ samples _ leaf:每个叶节点所需的最小样本数

自举: 数据集是自举还是整个数据集用于每棵树

n_estimators=[int(x) for x in np.linspace(start = 200, stop = 2000, num = 10)]
max_features = [‘auto’, ‘sqrt’, ‘log2’]
max_depth = [int(x) for x in np.linspace(10, 110, num = 11)]
max_depth.append(None)
min_samples_split = [2, 5, 10]
min_samples_leaf = [1, 2, 4]
bootstrap = [True, False]
grid_param = {‘n_estimators’: n_estimators,
 ‘max_features’: max_features,
 ‘max_depth’: max_depth,
 ‘min_samples_split’: min_samples_split,
 ‘min_samples_leaf’: min_samples_leaf,
 ‘bootstrap’: bootstrap}

如果我们使用 sci-kit learn 的 GridSearchCV 来确定最佳超参数,我们将评估 6,480 个候选模型和 32,400 个符合五重交叉验证的模型。这在计算上将非常昂贵,因此我们将使用 RandomizedSearchCV,它使用从我们定义的参数空间中随机选择的超参数来评估指定数量的候选模型(n_iter)。我们将使用五个折叠进行 k 折叠交叉验证。

from sklearn.ensemble import RandomForestRegressor# the model prior to hyperparameter optimization
RFR=RandomForestRegressor(random_state=1)from sklearn.model_selection import RandomizedSearchCV
RFR_random = RandomizedSearchCV(estimator = RFR, param_distributions = grid_param, n_iter = 500, cv = 5, verbose=2, random_state=42, n_jobs = -1)RFR_random.fit(train, resp) 
print(RFR_random.best_params_)

现在我们有了一个模型,它的属性最适合我们的数据。

Best_RFR = RandomForestRegressor(n_estimators=1000, min_samples_split=2, min_samples_leaf=1,max_features=’sqrt’, max_depth=30, bootstrap=False)

我们希望精确测量模型预测的房价与售出房屋的实际价格之间的差异。我们将通过 k 倍交叉验证来计算模型的均方根误差(RMSE)。给定五个折叠,我们将使用五组模型拟合中每一组的平均 RMSE 值。

from sklearn.model_selection import KFold, cross_val_score
n_folds=5
def rmse_cv(model):
    kf = KFold(n_folds,shuffle=True,random_state=42)
.get_n_splits(train)
    rmse= np.sqrt(-cross_val_score(model, train, resp, scoring=”neg_mean_squared_error”, cv = kf))
    return(rmse.mean())

rmse_cv(Best_RFR)

随机森林模型表现相当好,平均 RMSE 为 0.149。

让我们尝试另一个模型,看看我们是否能获得更好的预测。

梯度推进回归器

我们将使用 RandomizedSearchCV 进行相同的评估,以确定最佳超参数。我们将从“xgboost”中使用的梯度推进回归器具有以下我们想要优化的超参数:

n _ 估计量: 树木数量

子样本: 每棵树样本百分比

max_depth: 每棵树的最大层数

min _ child _ weight:一个子代中需要的所有观察值的最小权重之和

col sample _ bytree:每棵树使用的特征百分比

学习率: 学习率或步长收缩

伽玛: 进行拆分所需的最小缩减成本函数

n_estimators=[int(x) for x in np.linspace(start = 200, stop = 2000, num = 10)]
subsample = [.6,.7,.8,.9,1]
max_depth = [int(x) for x in np.linspace(10, 50, num = 10)]
min_child_weight = [1,3,5,7]
colsample_bytree=[.6,.7,.8,.9,1]
learning_rate=[.01,.015,.025,.05,.1]
gamma = [.05,.08,.1,.3,.5,.7,.9,1]
rand_param = {‘n_estimators’: n_estimators,
 ‘subsample’: subsample,
 ‘max_depth’: max_depth,
 ‘colsample_bytree’: colsample_bytree,
 ‘min_child_weight’: min_child_weight,
 ‘learning_rate’: learning_rate,
 ‘gamma’: gamma}

使用与随机森林模型相同的方法,我们将使用 k-fold 交叉验证运行随机超参数搜索。

Boost_random = RandomizedSearchCV(estimator = Boost, param_distributions = rand_param, n_iter = 500,
 cv = 5, verbose=2, random_state=42, n_jobs = -1)Boost_random.fit(train, resp)

我们现在可以计算优化模型的 RMSE,并将 xgboost 的性能与随机森林模型进行比较。

Best_Boost = XGBRegressor(subsample=.7, n_estimators=1600, min_child_weight=3, max_depth=41,learning_rate=.025, gamma=.05, colsample_bytree=.6)# evaluate rmse
rmse_cv(Best_Boost)

我们的梯度推进回归模型表现出优于随机森林模型的性能,RMSE 值为 0.131。

做最后的预测

在这个分析中,我采用了一种实用的建模方法;还有其他建模技术可以略微提高预测精度,如堆叠或应用一套替代模型(如 Lasso、ElasticNet、KernalRidge)。

我们将把这个分析中的最佳模型(梯度推进回归)应用于测试集,并评估它的性能。

# fit to the training data
Best_Boost.fit(train,resp)
# transform predictions using exponential function
ypred=np.expm1(Best_Boost.predict(test))# make a data frame to hold predictions, and submit to Kaggle
sub=pd.DataFrame()
sub['Id']=test['Id']
sub['SalePrice']=ypred
sub.to_csv('KaggleSub.csv', index=False)

梯度推进回归模型在测试集上以 0.1308 的 RMSE 值执行,不错!

结论

我们可以根据房产的特点对房子的售价做出合理的预测。关键步骤包括为 NAs 分配适当的值、标准化变量、优化候选模型的超参数以及选择最佳模型。

我感谢任何反馈和建设性的批评。与该分析相关的代码可在github.com/njermain上找到

用 OCR 防止同形异义字符攻击。

原文:https://towardsdatascience.com/homoglyph-attack-prevention-with-ocr-a6741ee7c9cd?source=collection_archive---------12-----------------------

TLDR;这篇文章描述了什么是同形异义攻击以及如何用认知服务来防止它们。

入门指南

这个故事的代码可以在 github 上找到。

[## aribornstein/homoglyphatckpreventionservice

一种防止同形异义攻击的服务。通过以下方式为 aribornstein/homoglyphatckpreventionservice 的发展做出贡献…

github.com](https://github.com/aribornstein/HomoglyphAttackPreventionService)

Azure 上的一键式部署说明可以在下面找到。

什么是同形攻击?

正字法印刷术中,同形异义字是两个或更多字符中形状看起来相同或非常相似的一个。通俗地说,同形字就是任何看起来与另一个字符相似的字符,比如上图中的 S$

语言模型经常容易受到使用同形符号的混淆攻击,这是由于它们编码文本的方式。例如,在 Unicode 和 Ascii 中,相同的字符代码在不同的字体中看起来不同,模型将努力学习它们的相似性。

[## 面向初学者的字符编码

什么是字符编码,我为什么要关心?

www.w3.org](https://www.w3.org/International/questions/qa-what-is-encoding)

为了说明这一点,让我们来看看下面的短语:

我从令人敬畏的云情感分析模型中得到了$hitty 结果。

上面这句话清楚地表明了消极情绪。单词 $hitty 是亵渎单词shipped的同音字混淆。

让我们看看互联网上最流行的四种云情感分析服务是如何处理这种攻击的。

Clockwise, Azure Text Analytics and GCP Natural Language correctly classify the original sentiment but fail on the obfuscated text, IBM Watson fails to correctly classify sentiment of either text and AWS Comprehend does not provide a demo with out an AWS account but also fails on the example sentence.

正如我们所看到的,Azure 文本分析和 GCP 自然语言正确地对原始情感进行了分类,但都没有对模糊文本进行分类。IBM Watson 未能正确地对两种文本的情感进行分类。AWS comprehensive 不提供没有 AWS 订阅的演示,也不能使用例句。

虽然上面的$和 S 的例子可能看起来有些武断,但维基百科下面的拉丁字母和西里尔字母展示了这种攻击是如何有效和难以检测的。

这给用例带来了各种各样的问题,在这些用例中,这种攻击可以利用应用程序或对应用程序造成伤害,例如试图躲避假新闻检测器的机器人。

如何防范同形异义攻击?

Azure Computer Vision Correctly Reveals the Homoglyph when the text is represented as an image.

在与我来自 BIU NLP 实验室的朋友 Amit Moryossef 交谈后,我们意识到我们可以使用 OCR 系统来防止同形异义字符攻击。

使用 Azure 计算机视觉服务,我用上面的句子测试了这个理论,它正确地使用图像域上下文从同形词 $hitty 中提取单词shipped

使用这种能力,我编写了下面的开源容器服务,它将:

  1. 将一个给定的文本作为输入

2.将文本转换为图像

3.使用 OCR 处理图像

4.返回删除了同形异义字符的正确文本。

Docker 服务是云不可知的。为了方便起见,我向 Azure 提供了一个单击部署选项。

如果您已有 Azure 订阅,您可以通过单击下面的按钮来自动部署服务。

Click here to get started!

否则你可以在这里获得一个免费 Azure 账户,然后点击上面的部署按钮。

[## Azure 免费试用版|微软 Azure

开始您的免费 Microsoft Azure 试用,并获得 200 美元的 Azure 点数,以任何方式使用。运行虚拟机…

azure.microsoft.com](https://azure.microsoft.com/offers/ms-azr-0044p/?WT.mc_id=medium-blog-abornst)

如果您有任何问题、评论或希望我讨论的话题,请随时在 Twitter 上关注我。再次感谢 Amit Moryossef 和 BIU NLP 实验室的惊人灵感,以及 Iddan Sachar 在他的帮助下调试 ARM 的一键式部署。

使用服务

要使用该服务,只需向该服务发送一个最多 200 个字符的 URL 编码查询字符串,该服务非常适合验证推文。下面是一个使用 curl 的调用示例,请务必使用您自己的服务端点。

后续步骤

虽然该服务在删除同形异义词方面表现很好,但仍有少数情况下会失败。

Example Failure Case

未来的工作将探索使用一个更加定制的方法来解决这个问题,但这种方法非常适合非常小的努力。

额外资源

[## 使用计算机视觉 API | Microsoft Azure 进行图像处理

使用 Microsoft Azure 的计算机视觉 API 分析图像并提取您需要的数据。查看手写 OCR…

azure.microsoft.com](https://azure.microsoft.com/en-us/services/cognitive-services/computer-vision/#text?WT.mc_id=blog-medium-abornst) [## 应用服务—容器的 Web 应用| Microsoft Azure

带上您自己的容器,使用 web app 在几秒钟内部署到应用服务,作为运行在 Linux 上的 Web App…

azure.microsoft.com](https://azure.microsoft.com/en-us/services/app-service/containers/?WT.mc_id=blog-medium-abornst) [## 文本分析 API | Microsoft Azure

使用 Azure 文本分析 API 将非结构化文本转化为有意义的见解。获取情感分析,关键词…

azure.microsoft.com](https://azure.microsoft.com/en-us/services/cognitive-services/text-analytics/?WT.mc_id=blog-medium-abornst)

关于作者

亚伦(阿里) 是一个狂热的人工智能爱好者,对历史充满热情,致力于新技术和计算医学。作为微软云开发倡导团队的开源工程师,他与以色列高科技社区合作,用改变游戏规则的技术解决现实世界的问题,然后将这些技术记录在案、开源并与世界其他地方共享。

多臂土匪问题的 Thompson 抽样(上)

原文:https://towardsdatascience.com/hompson-sampling-for-multi-armed-bandit-problems-part-1-b750cbbdad34?source=collection_archive---------7-----------------------

使用贝叶斯更新进行在线决策

“多臂土匪”可能是数据科学中最酷的术语,不包括对“裸欧式看涨期权”或“空头铁蝴蝶”的金融应用。它们也是最常见的实际应用。

这个术语有一个有益的激励故事:“一个武装匪徒”指的是吃角子老丨虎丨机——拉“手臂”,“匪徒”会拿走你的钱(大多数时候——有可能你会赢大钱)。“多臂土匪”是一个有许多手臂的吃角子老丨虎丨机,每个手臂都有不同的获胜概率和相关的支付。如果不知道这些概率/收益,你需要边走边学,拉动更容易成功的杠杆,并希望尽快收敛到最佳杠杆。

抛开赌博不谈,我们可以想象很多情况下的多臂土匪问题。一家医院对临床协议的潜在修改有多种想法,以改善结果——由于需要干预的临床事件数量有限,并且修改不当可能会产生意想不到的后果,我们如何评估所有修改,同时确保最好的修改能够迅速上升到最高层。或者一家营销公司想通过选择它已经开发的 3 个潜在活动之一来部署新的广告策略。

在本文中,我们将重点关注伯努利强盗问题——支出为 1 或 0 的问题(将问题的复杂性降低到确定支出的概率)。我们将应用两种方法:ε-贪婪和汤普森抽样。在以后的文章中,我们将讨论更复杂的多臂土匪问题(包括共轭先验对我们不友好的采样方法!)和其他解决这个问题的方法。

ε-贪婪

一个算法是“贪婪的”,因为它选择立即的回报而不考虑长期的结果。树算法通常是“贪婪的”——在每个节点上,它们选择熵最小化最多的分裂。该分裂可能不是在后续分裂中最小化熵最多的树。

贪婪算法在路径数量呈指数增长并且很快变得难以处理的情况下很常见(即计算强度达到不可能的程度)。例如,基于 10 个特征的树,甚至允许每个变量仅使用一次(这不是常见的约束),3.6M 个可能的配置(10!= 10 * 9 * 8…).加上第 11 个特征就成了 39.9M,等等。

使用贪婪算法可以合理地处理多臂土匪问题。在老丨虎丨机公式中,我们假设所有杠杆都有相同的成功概率,我们随机选择一个,然后根据成功/失败更新我们的成功假设。在每次连续的迭代中,我们选择成功概率最高的杠杆。

这种算法可能会为了眼前的利益而忽略新的信息。假设我们有 3 个概率为 0.04、0.07 和 0.1 的杠杆。我们可能会偶然发现低概率杠杆的早期成功,然后继续拉杠杆 20-50 次,直到它的概率低于其他杠杆。算法被“卡住”。

该算法的一个增强允许我们忽略成功概率并随机选择一个杠杆的小概率次数(ε)。这有助于收集新信息,允许非最优选择偶尔进入组合。

下面的代码为我们建立了算法。请注意,贝塔分布是伯努利分布的“共轭先验”。这是一个贝叶斯术语,表示贝塔分布是伯努利试验中包含的成功概率的后验预测分布。共轭先验使贝叶斯分析的数学变得简单——下面我们可以通过将 alpha 视为成功的计数,将 beta 视为失败的计数来更新 Beta。

import numpy as np
import pandas as pd
import random#Initialize Sampling 
def initialize(arms):
    prior = pd.DataFrame(np.ones((arms, 3)), columns = ['alpha', 'beta', 'theta'])
    prior.loc[:, 'theta'] = prior.loc[:, 'alpha'] / (prior.loc[:, 'alpha'] + prior.loc[:, 'beta'])

    post = pd.DataFrame(columns = ['i', 'arm', 'payout'])
    return prior, post# e-Greedy
def e_greedy(eta, arm_prob, prior):
    #Determine path-selection
    if np.random.uniform(0, 1, 1) <= eta:
        s = np.random.randint(0, len(arm_prob) -1, 1)[0]
    else:
        s = random.choice(np.where(prior['theta'] == np.amax(prior['theta']))[0])

    #Determine success/failure
    r = 1 if np.random.uniform(0, 1, 1) <= arm_prob[s] else 0    

    prior.loc[s, 'alpha'] += r
    prior.loc[s, 'beta'] += 1- r
    prior.loc[s, 'theta'] = prior.loc[s, 'alpha'] / (prior.loc[s, 'alpha'] + prior.loc[s, 'beta'])

    return s, r, prior

我们将在该方法上使用几个词之后,用 Thompson sampling 直接测试这段代码。

汤普森采样

Thompson 采样采用不同于ε-greedy 的方法来选择下一个要拉的臂。ε-greedy 的一个缺点是,它可能会陷入局部最大值——通过统计机会表现良好的次标准分布。eta 参数被设计成通过迫使算法采取在当前看来是次优选择(即,不是当前最大预测概率)但实际上可能是给定足够信息的最优选择来抵消这一点。

为了做到这一点,Thompson 抽样使用一个随机的统一变量从每个选择的后验预测分布中提取数据。这允许以变化的频率对非最优分布进行采样——随着后验分布变得更加确定,做出选择的概率会动态降低,因此 Thompson 采样动态地平衡了对更多信息的需求和做出当前最优选择。例如,在下图中,我们假设有两种选择,蓝色代表 4 次成功,1 次失败,橙色代表预备队。虽然蓝色选择的平均值约为 0.7,橙色选择的平均值约为 0.3,但有相当大的概率(~4%)会选择橙色而不是蓝色。

我们的 Thompson 抽样实现看起来是这样的——注意,random.choice 选择现在使用的是以前的分布,而不是以前的均值。

# Thompson Sampling
def thompson(arm_prob, prior):
    #Determine path-selection
    s = [np.random.beta(prior.loc[n, 'alpha'], prior.loc[n, 'beta'], 1) for n in range(len(arm_prob))]
    s = random.choice(np.where(s == np.amax(s))[0])

    #Determine success/failure
    r = 1 if np.random.uniform(0, 1, 1) <= arm_prob[s] else 0    

    prior.loc[s, 'alpha'] += r
    prior.loc[s, 'beta'] += 1- r
    prior.loc[s, 'theta'] = prior.loc[s, 'alpha'] / (prior.loc[s, 'alpha'] + prior.loc[s, 'beta'])

    return s, r, prior

这场对决!

将这两种算法相互比较有助于阐明它们的优缺点。

在下面的例子中,我们模拟了概率来自β(1.5,1.1)的 5 个分支,即向较低概率移动,但仍保持足够的机会获得较高概率。

下图显示了这些方法特有的一次试运行。经过 250 次迭代后,两种方法都达到了最佳水平(水平 1),但是 TS 由于在分析的早期表现优异而领先。经过 50 次迭代后,两种方法实际上都以 30 胜打平,EG 略微领先。然而,在这一点之后,TS 领先。EG 已经开始拉杠杆 2(通过改变),并且看到了成功,并且继续拉,直到在前 15 次抽中它看到了 10 次成功(所有这些都是在 EG 假设其他未尝试的杠杆有 0.5 的概率的情况下)。EG 继续大力支持杠杆 2,直到第 175 次迭代,此时它尝试杠杆 1 并发现长期成功。相比之下,EG 早在第 20 次迭代时就发现了 Lever 0,并且早在第 40 次迭代时就几乎独占地拉动了它。

Bernoulli Multi-Armed Bandit with Lever Probabilities = 0.86, 0.44, 0.56, 0.34, and 0.05. EG using eta = 0.05.

这些算法都可以调整——我们可以调整两个模型中的先验,以及调整 eta,例如,在上面的示例中,我们使用了 5%的 eta。使用更激进的 eta 允许模型不容易出现局部最大值,同时还可能通过实施次优选择来减少长期收益。下图显示了使用 eta = 0.1 的 1000 次迭代。正如预测的那样,我们看到 EG 甚至能够在早期击败 TS(虽然 TS 希望“证明”Lever 0 是正确的选择,但 EG 愿意在没有太多证明的情况下做出这种假设),但是随着模拟进行到第 1000 次迭代,TS 略微领先,因为 EG 仍有 10%的时间从非最佳 Lever 中采样。对 EG 的改进可以使用 eta 的衰减因子。

Bernoulli Multi-Armed Bandit with Lever Probabilities = 0.86, 0.44, 0.56, 0.34, and 0.05. EG using eta = 0.1.

上面的模拟表明,这两种方法都是有效的——它们在很大程度上依赖于上下文。EG 将在做出次优选择伤害较小的情况下表现良好——如果第二或第三个选择的真实概率与第一个选择的真实概率足够接近,那么做出那些勉强低于标准的选择不会损失太多。此外,如果搜索空间广阔,TS 可能会陷入试图证明最佳选择的困境,而 EG 则愿意在没有太多“证明”的情况下快速取胜。

在下面的例子中,使用β(3.5,0.7)模拟了 50 条手臂,这有利于给予手臂更高的概率(参见下面的直方图)。正如预测的那样,EG 能够在 TS 通过迭代 1000 搜索广阔空间的同时取得快速胜利。

50 Arms with skewed-high probabilities. Histogram of success probabilities, and results from 1000 iterations (with zoom-in on 250).

如果我们翻转概率分布以支持低概率结果-Beta(0.7,3.5)-我们会看到每个算法都在努力寻找胜利。虽然最优选择在 67%的情况下获胜,但在 500 次迭代后,EG 赢了 229 次,TS 略少。然而,在 1000 次迭代之后,TS 领先,预计这一领先将保持,因为 EG 继续对无效空间进行采样。

50 Arms with skewed-low probabilities. Histogram of success probabilities, and results from 1000 iterations (with zoom-in on 250).

我们看到 TS 在下面的双峰分布中再次上升(Beta(2.5,1)和 Beta(2.5,10)的 25/75 混合)。

50 Arms with bi-modal probabilities. Histogram of success probabilities, and results from 1000 iterations (with zoom-in on 250).

结论

Thompson 采样是一种解决多臂强盗问题的贝叶斯方法,它动态地平衡了合并更多信息以产生每个杠杆的更确定的预测概率与最大化当前获胜的需要。ε-greedy 是一种更简单的方法,它更侧重于当前的成功案例,采用确定性方法来整合更多信息。这种方法的结果是,当前的成功和更多的信息有时是不平衡的(即,集中在局部最大值上),但是一个好处是,如果该方法在早期发生在全局最大值上,它更愿意信任它,并且可以产生早期成功。

在以后的文章中,我们将讨论使用更复杂的贝叶斯采样技术(在非共轭先验的情况下)扩展这个框架,以及 Thompson 采样在新问题中的应用:非二项式多臂 bandit、路径优化等等。

希望这个贝叶斯垃圾邮件过滤器不是太天真

原文:https://towardsdatascience.com/hopefully-this-bayesian-spam-filter-isnt-too-naive-d89675bce99c?source=collection_archive---------42-----------------------

我们都遇到过垃圾邮件,从 Gmail 收件箱中的可疑电子邮件,到社交媒体帖子上的重复评论。垃圾邮件是一种自 2000 年初以来一直困扰互联网的现象,并不是什么新鲜事。然而,我们现在有很好的方法使用机器学习来处理垃圾邮件。今天,我们将创建一个带有自然语言处理的垃圾邮件过滤器,它将根据我们是否确定该文本是垃圾邮件来返回布尔值 1 或 0。

处理自然语言

(笔记本

我们的数据最初有一些不重要的列,我很快就删除了。接下来,看看我们从数据帧中提取的两列,标签和文本,标签是包含“垃圾邮件”或“火腿”的分类特征,所以我认为垃圾邮件是垃圾邮件,火腿不是垃圾邮件。

接下来,为了让我们能够使用我们想要使用的任何模型,我将数据集中的所有标签映射到数字类型的布尔

dataset['numerical_label'] = dataset.label.map({'ham':0, 'spam':1})

这样一来,我使用了一个反矢量器来对我们的英语输入进行矢量化:

from sklearn.feature_extraction.text import CountVectorizer
vect = CountVectorizer(stop_words='english')
vect.fit(X_train)

对于我的模型,我选择利用贝叶斯多项式模型,

from sklearn.naive_bayes import MultinomialNB
model = MultinomialNB()
model.fit(X_train_df,y_train)

所以在适应、转换和改变之后,我得到了一个准确度分数:

并准备序列化我的模型,以便在 Flask 应用程序中使用。

from sklearn.externals import joblib
filename = 'alg.sav'
joblib.dump(model, filename)

烧瓶时间,宝贝

我决定使用 HTTP 参数,因为这将使默认版本对任何人来说都是最通用和最容易实现的。所以我们当然要从我们的 app.route()开始:

@app.route(‘/’)

并在其下方添加我们的函数。

def template():
    try:
        txt = request.args['text']
    except KeyError as e:
        return ('Some Values are missing')

Request.args 从 URL 中提取 HTTP 参数,用作 Flask 应用程序中的变量。HTTP 请求非常适合数据管道和深度嵌套的后端。接下来,我选择将读取的文本放入数据帧中进行预测。这一步不一定是至关重要的,但我已经将熊猫添加到 Flask 应用程序中,所以我决定使用它。

现在我们已经将数据放入 Flask,我们可以反序列化并加载我们的管道。

需要注意的一点是,为了使数组适合模型,您可能需要用 np.reshape()来改变数组的形状。

pipeline = load('alg.sav')    
estimate=pipeline.predict(df['input'])    
return(estimate)

没什么太复杂的!现在,我们可以通过任何字符串请求访问 Flask 应用程序,并通过数据管道尽可能多地重用这个精确的算法!

厉害!

Hopfield 网络毫无用处。以下是你应该学习它们的原因。

原文:https://towardsdatascience.com/hopfield-networks-are-useless-heres-why-you-should-learn-them-f0930ebeadcd?source=collection_archive---------6-----------------------

Photo by Ryan Schroeder on Unsplash

Hopfield 网络是由 J.J. Hopfield 于 1982 年发明的,到那时,许多不同的神经网络模型已经被放在一起,相比之下具有更好的性能和鲁棒性。据我所知,它们大多是在教科书中介绍和提到的,当接近玻尔兹曼机器和深度信念网络时,因为它们是建立在 Hopfield 的工作基础上的。

然而,与深度学习的当前状态相比,它们提供了如此不同和替代的学习系统视角,因此值得理解。

让我们来看看它们是如何工作的。

一个基本的 Hopfield 网络及其工作原理

Hopfield 网络的核心是一种模型,它可以在收到相同数据的损坏版本后重建数据。

我们可以把它描述为一个由节点——或单元,或神经元——通过链接连接起来的网络。每个单元在任一时刻都有两种状态,我们假设这些状态可以是+1 或-1。我们可以在向量 v 中列出每个单元在给定时间的状态。

链接代表单元之间的连接,它们是对称的。换句话说,无论您在图中向哪个方向看,node-i 和 node-j 之间的链接都是相同的。特别是,相同的是代表每个单元之间连接强度的数字。我们可以在矩阵中列出这些数字。

Fig.1 — A Hopfield Network

如果我们有一个如图 1 所示的网络,我们可以这样描述它:

A state vector and a weight matrix describe the graph at some point in time

我们如何构建 W ?我们首先注意到一个节点与其自身之间没有连接,因此我们通过将 waa、wbb、wcc、wdd 置零来明确这一点。我们也知道链接或者权重是对称的,所以例如 wab = wba 。所以 W 是零对角线对称的。其余元素是这样填充的: wab = Va Vb 。结果是矩阵 W 。对于连接权重来说,这是一个聪明的选择,因为它遵循了我们稍后将再次看到的赫比规则。

The weight matrix fully describes the network connections

现在我们已经建立了权重矩阵,我们需要定义一个规则来确定每个节点的状态。因为我们有二进制状态,我们可以使用这个定律:

State update rule

类似地,通过使用上面定义的权重矩阵,我们得到:

现在我们可以直观地了解 Hopfield 网络实际上是如何工作的。

假设我们有一个 V 的腐败版本,我们就叫它 V' = [1 -1 -1 -1] ,这样最后一位就反过来了。我们可以用V’初始化网络状态。

Network initialized with corrupted states: d is now -1

我们可以继续用之前建立的规则更新网络状态。对于 Va,我们将有:

Va = f(wab Vb+WAC Vc+wad Vd)=+1

注意 wab Vbwac Vcx 都有正的贡献,尽管 VbVc 为-1,推动 Va 为+1,而讹误位的贡献方向相反。换句话说,通过像以前一样构建 W ,我们迫使节点在它们应该具有相反符号时处于相反状态,而在它们应该相等时处于相同状态。相反的状态互相排斥,而相同的状态互相吸引。这是赫比规则的一种表述。

赫布边法则:一起放电的神经元,连接在一起

同理:
Vb = f(wba Va+WBC Vc+wbd Vd)=-1 Vc = f(WCA Va+WCB Vb+wcd Vd)=-1
现已损坏位:
Vd = f(wda Va+wdc Vc+wdb Vb)=+1

并且 Va = +1 通过让 wda Va > 0 吸引节点 d 为正,而 Vc=Vd= -1 通过给予整体正贡献 wdc Vc + wdb Vd > 0 排斥节点 d

原本相同的节点被驱使变得相同,原本符号相反的节点互相排斥变得相反。

原来的 V 神奇的恢复了!

但是* 为什么* 有用呢?

到目前为止,我们已经看到,一旦我们用状态向量 V 完全定义了网络——它的W——我们想要在损坏后恢复,我们可以通过更新网络状态来完成。

换句话说,在用V’初始化网络状态后,我们让网络按照我们之前定义的规律进化,它会收敛到我们最初想要的状态。不仅如此,无论我们持续更新多少次,它都会一直存在。

让我们找出为什么是

我们可以定义一个依赖于图的状态和矩阵的函数。我们将把这个函数称为与网络状态相关的能量函数,并表示为:

Energy function in a Hopfield Network

结果#1

如果节点 Vi 将其状态从+1 更改为-1,反之亦然,我们将得到:

现在:
如果 Vi 从-1 变为+1,那么 dVi = +2
,这意味着 x 必须为正,
反过来,能量增量必须为负

这意味着如果按照我们的规则更新网络,能量函数会一直递减,它是单调递减,它会努力达到最低点。

结果#2

但是有没有一个最低点或者能量会一直减少到负无穷大?

换句话说,我们试图弄清楚能量增量是否可以为零。
为了让 dEi = 0 ,我们需要,例如,让 dVi = 0 ,这仅在 Vi(k-1)' = Vi(k)' 时成立,其中 Vi(k-1)' 是更新前的节点状态,而 Vi(k)' 是更新后的节点状态。

假设我们有 Vi(k-1)' = +1 ,我们想要 Vi(k)' = +1 ,或者类似的
xi(k) > 0
这是:

但是当 Vj(k-1)' = Vj 那么 xi(k) 总是正的!

在一个镜头中,我们展示了当状态采用原始值(未损坏的值)时,能量函数将不再改变。换句话说, dVi = 0 并且节点不会更新到不同的值——配置被认为是稳定的。

因此我们证明了在网络达到节点状态的稳定配置之前,能量一直在减少。甚至,稳定配置是对应于恢复的状态向量的配置,即能量函数的局部最小值。

这里省略了许多实现细节,但是我在这里准备的这个 Jupyter 笔记本中有一个基本的工作 Hopfield 网络。

马蹄修道院

原文:https://towardsdatascience.com/horseshoe-priors-f97672b4f7cb?source=collection_archive---------12-----------------------

比 L1 和 L2 有更多的正规化选择。

Photo by Jeff Smith on Unsplash

正规化是一个迷人的话题,困扰了我很长时间。首先在机器学习课程中介绍,它总是提出一个问题,为什么它会工作。然后,我开始揭示正则化与潜在模型的统计属性之间的联系。

事实上,如果我们考虑线性回归模型,很容易表明,L2 正则化等价于将高斯噪声添加到输入中。事实上,如果我们考虑特征交互,后者是优选的(或者我们必须使用非平凡的 Tikhonov 矩阵,例如,与单位矩阵不成比例)。从贝叶斯的角度来看,L2 正则化相当于在我们的模型中使用高斯先验,正如这里的所解释的。从贝叶斯线性回归模型开始,通过取最大后验概率,你将得到 L2 正则化项。一般来说,正态先验使模型变得简单,因为正态分布是正态分布的一个共轭先验,这使得后验分布也是正态的!如果你选择一个不同的先验分布,那么你的后验分布会更复杂。

高斯先验和 L2 正则化的问题在于,它没有将参数设置为零,而只是减少了它们。当我们有许多功能时,这尤其成问题,大约 6 个月前我不得不处理这种情况,当时在所有功能处理之后,我有超过 100 万个功能。在这种情况下,我们想使用一种不同的正则化,L1 或套索正则化。它不是添加参数平方和的惩罚,而是基于参数绝对值的和进行惩罚。正则化模型将许多参数设置为零,实际上为我们完成了特征选择的任务。不幸的是,每个使用过它的人都可以证实,它大大降低了精度,因为它引入了偏差。

在贝叶斯术语中,L1 正则化等价于双指数先验:

在这里以及更远的地方,我会跟踪这个案例研究。理想的先验分布将把概率质量设置为零以减少方差,并具有厚尾以减少偏差。L1 和 L2 都没有通过测试,也就是说,双指数分布和正态分布都有细尾,他们把概率质量设为 0。请注意,为了使概率质量为 0,概率密度函数必须发散。

卡瓦略等人在此在此以及其他一些论文提出了一个非常优雅的解决方案。该解决方案称为马蹄形先验,定义如下:

让我来帮你破译这个。如果你记得,L2 正则化相当于有一个正态先验,这是一个均值为 0 的正态分布,方差是一个超参数,我们必须调整。(方差是 L2 正则化常数 λ 的倒数)。本着真正的贝叶斯精神,我们希望定义一个关于 λ 的先验分布,然后将其边缘化。在这种方法中,建议使用半柯西分布作为先验分布。已经证明它把非零概率质量放在 0,也有一个胖尾。如果我们使用 s hrinkage weight k 的转换来重新参数化分布的形状,那么“马蹄”这个名称就来自于它:

在这种情况下,分布支持变为[0,1],并且当与其他先前的分布候选进行比较时:

我们可以看到马蹄先验满足我们的两个条件。

结论

在上述论文中,该方法在各种合成数据集上进行了测试,并且从那时起,它成为贝叶斯线性回归正则化方法的标准之一。从那时起,它已经过多次改进,并针对其他情况进行了调整。当然,由于免费的午餐定理,不可能排斥所有的超参数,所以很多讨论都致力于调整算法或克服它的一些缺点。

参考

卡瓦略,C. M .,波尔森,N. G .和斯科特,J. G. (2009 年)。通过马蹄处理稀疏性。《第 12 届人工智能和统计国际会议论文集》(D. van Dyk 和 M. Welling 编辑。).机器学习研究会议录 573–80。PMLR。

卡瓦略,C. M .,波尔森,N. G .和斯科特,J. G. (2010 年)。稀疏信号的马蹄形估计器。生物计量学 97 465–480。

使用 Node.js 和 Cloud Firestore DB 在 Google Firebase 上托管一个动态网站

原文:https://towardsdatascience.com/host-a-dynamic-website-on-google-firebase-for-free-using-node-js-and-cloud-firestore-db-88e98239e1b9?source=collection_archive---------1-----------------------

Img Source: https://firebase.google.com/images/social.png

图沙尔·卡普尔😦https://www.tusharck.com/)

演示 Git 网址:https://github.com/tusharck/firebase-demo

为什么选择 Firebase 托管?

Firebase 是一个建立在谷歌基础设施上的综合应用程序平台,因此它提供了一个安全、快速、免费(付费选项也可用于额外资源)和简单的方式来在网络或移动应用程序上托管您的内容。

免费层的主要特性和优势:

  1. 它提供了免费的自定义域& SSL (SSL 为 https 连接提供了一个标准的安全层。
  2. Cloud Firestore:一个灵活且可扩展的数据库,用于跨客户端应用程序的实时数据同步。
  3. 其他功能:云功能,云消息(FCM),Crashlytics,动态链接,托管,ML 工具包,存储,性能监控,预测和测试实验室(这些产品的功能和资源可以通过购买付费计划来增加,但免费层服务非常好。要查看计划,请检查 Firebase 定价
  4. 资源的自动缩放。

在 Firebase 上托管动态网站的步骤

要求

1。谷歌账户 如果你没有谷歌账户,你需要注册一个。你可以去 https://accounts.google.com/SignUp 看看。

2。Node.js 和 npm

sudo apt-get install curlcurl -sL https://deb.nodesource.com/**setup_13.x** | sudo bash -sudo apt install nodejs

注: 我用的是setup_13.x因为当时的教程最新版本是 13 你可以去https://nodejs.org/en/查看最新版本。

要检查 Node.js 和 npm 是否已成功安装,请运行以下命令,这将输出已安装的版本:

node -v
npm -v

3。Firebase-CLI(命令行界面) 这些是管理、查看和部署 Firebase 项目的工具。

npm install -g firebase-tools

步骤 1:创建 Firebase 项目

  1. 从右上角进入https://firebase.google.com签到。
  2. 点击右上角的进入控制台
  3. 然后点击创建项目,如下所示。

4.下一件事是输入你的项目名称,并按下 continue。

5.按“继续”为您的 Firebase 项目启用 Google Analytics(如果您不想要它,请选中“禁用”)。

6.为 Google Analytics 选择最近的位置。

7.点击创建项目,等待加载。然后你会看到类似下面的

步骤 2:初始化 Firebase 登录

  1. 打开命令行/终端,然后创建并转到一个新目录。
mkdir my-firebase-projectcd my-firebase-project

2.要在 firebase 上托管网站,请使用以下命令登录 Firebase。运行该命令后,会打开一个浏览器窗口,要求您使用 Google 凭据登录 firebase。在那里输入凭证,Firebase 将登录到您的系统。

firebase login

You will see something like this after successful login

步骤 3:将 Firebase 项目初始化到系统中

  1. 现在,我们必须将我们在 Firebase 控制台上创建的项目初始化到系统中。运行下面的命令。
firebase init

2.按下向下键,然后通过按下空格键选择两件东西

  • 功能
  • 主办;主持

然后按回车继续。

3.然后选择**Use an existing project**并按下回车键。

4.在**my-firebase-project** 或您使用的项目名称上按回车键。

5.选择 Javascript 并按回车键。

6.你可以说你想用 ESLint 来捕捉可能的 bug 并加强风格吗?

7.键入 Yes 安装与 npm 的依赖关系。

8.这里我们必须完成两项任务:

  • 你必须选择你的网站和资产所在的目录。默认情况下,它是public你可以按回车键继续,或者你可以改变到你想要的目录名。
  • 为单应用程序页面键入 Yes ,这样您的动态 URL 就可以被重定向到正确的目的地。

9.通过运行以下命令,在本地系统上测试 firebase 应用程序。然后去http://localhost:5000看看你的基本网站运行情况。

firebase serve --only hosting,functions

打开http://localhost:5000网址后应该会看到下面这样的内容。

10.从终端关闭服务器。

步骤 4:为动态网站安装软件包和创建视图目录

  1. 在这里,我们将切换到函数目录中进行使用。
cd functions

2。Install Express 它是一个极简灵活的 Node.js web 应用框架。

npm i express --save

3。安装手柄 它是 Node.js 的模板引擎,用于网站的动态前端。

npm i handlebars --save

4。安装合并

npm i consolidate --save

5.在函数文件夹中创建一个名为视图的文件夹,我们将在其中存储所有的前端代码。

mkdir **views**

6.通过运行以下命令切换回主目录:

cd ..

步骤 5:设置 Firestore(云数据库)

数据库配置

  1. https://console.firebase.google.com/。
  2. 选择您的项目。
  3. 从左侧窗格中选择数据库

4.点击创建数据库

5.选择在测试模式下启动,因为否则您将无法从您的系统访问数据库。我们将改变这个设置,一旦我们完成了网站的发展。
完成后,点击下一步

6.选择 Firestore 数据库的位置。
注意: 设置好这个位置后,以后就不能更改了。

创建虚拟数据

  1. 点击开始收集。

2.输入收藏 ID ,即可进行采样。

3.输入样本数据。输入 sample_doc 作为文件 ID。字段中输入标题。我喜欢里面的云。然后点击保存

步骤 6:建立网站的动态内容

我们将把这一部分分成两部分,在第一部分,我们将看到如何从 Firestore 获取数据并在网站中使用。在第二部分,我们将看到如何提交表单数据。

首先,我们将下载访问 Firestore 的凭据

  1. 前往https://console.firebase.google.com/

2.点击左侧窗格中的设置,进入项目设置

3.转到服务账户并点击生成新的私钥。

4.点击生成密钥,会弹出下载密钥的窗口。将密钥存储在您网站的功能文件夹中。

从 Firestore 获取

  1. 打开功能文件夹内的 index.js

2.我们需要定义一些我们希望在应用程序中使用的库。这些是我们之前安装的相同的库。

const functions = require('firebase-functions');const express = require('express');const engines = require('consolidate');var hbs = require('handlebars');const admin = require('firebase-admin');

3.我们在这里设置了一些东西:

  • 使用 express 初始化应用程序。
  • 我们将把引擎设置为把手。
  • 然后,我们将告诉 express,我们的前端代码将放在 views 文件夹中。
const app = express();app.engine('hbs',engines.handlebars);app.set('views','./views');app.set('view engine','hbs');

4.授权您的应用程序访问您的 Firestore 数据库。
注:
1。更改您的 SDK 名称。json 与您下载的文件一起作为访问 Firestore 的凭证。
2
2。将数据库 URL 更改为您的数据库 URL。要查看网址你可以到设置>服务账号

var serviceAccount = require("./**YOUR_SDK_NAME**.json");admin.initializeApp({credential: admin.credential.cert(serviceAccount),**databaseURL: "https://myfirebaseproject-bx54dasx3.firebaseio.com"**});

5.从 Firestore 获取数据的函数。

  • 收集 ID 为的样本
  • 文档 ID 为 sample_doc。

我们在输入样本数据时定义了上述内容。

async function getFirestore(){const firestore_con  = await admin.firestore();const writeResult = firestore_con.collection('**sample**').doc('**sample_doc**').get().then(doc => {
if (!doc.exists) { console.log('No such document!'); }
else {return doc.data();}})
.catch(err => { console.log('Error getting document', err);});return writeResult
}

注: 我们使用 async 是因为我们要等待数据库和我们网站之间的承诺操作完成。

6.创建路由并将结果发送到前端。

app.get('/',async (request,response) =>{var db_result = await getFirestore();response.render('index',{db_result});});exports.app = functions.https.onRequest(app);

7.在视图文件夹中创建 index.hbs
注: 。hbs 是一个 handelbars 文件

8.在 index.hbs 中编写这个基本的 HTML 代码,以查看获取的结果。

<html>
    <body> <h1>{{db_result.Heading}}</h1> </body>
</html>

注: {{db_result。Heading}},db_result 是从后端传递过来的变量。。标题是我们在 Firestore 数据库中输入数据时定义的文档内的字段。

9.打开 firebase.json ,将" destination ":"/index . html "改为"function":"app".

10.删除公共文件夹内的index.html,删除这个很重要。如果你不删除它,它将总是选择这个文件,我们的后端代码将是无用的。

11.通过运行以下命令,在本地系统上测试 firebase 应用程序。然后去http://localhost:5000看看你的基本网站运行情况。

firebase serve --only hosting,functions

12.从终端关闭服务器。

插入 Firestore

在这里,我们将从我们的网站插入数据到 Firestore。

1.创建另一个名为 form_data 的集合,我们将在其中插入表单数据。

注意: 它将要求您输入一个文档,并创建集合以输入任何样本值。

2.运行下面的命令在本地服务器上进行测试后,转到http://localhost:5000

firebase serve --only hosting,functions

3.添加 HTML 代码,在 index.hbs 中创建一个示例表单。

<html>
    <body><h1>{{db_result.Heading}}</h1>**<form action="/insert_data"** **method="post" >
     <fieldset>
       <legend>Sample Form</legend>** **First name:<br>** **<input type="text" name="firstname" >** **<br>** **Last name:<br>** **<input type="text" name="lastname">** **<br><br>** **<input type="submit" value="Submit">** **</fieldset>
     </form>** </body>
</html>
  • action="/insert_data" 是我们将在函数内部定义的路径。
  • 刷新页面后,它应该像下图所示。

3.在 index.js 中添加将数据插入 Firestore 的代码。

async function insertFormData(request){const writeResult = await admin.firestore().collection('**form_data**').add({
firstname: request.body.firstname,
lastname: request.body.lastname
})
.then(function() {console.log("Document successfully written!");})
.catch(function(error) {console.error("Error writing document: ", error);});
}

4.在 index.js 内部定义 HTML 表单发送 post 请求的路径。

app.post('**/insert_data**',async (request,response) =>{var insert = await insertFormData(request);response.sendStatus(200);});

6.在表单中插入一些示例数据来测试它。

7.点击提交后,你应该会看到网页上显示的回复**OK**

8.转到https://console.firebase.google.com/然后转到数据库部分。您应该会看到插入的表单数据。

步骤 7:在线部署(最后一步)

  1. 我们需要更改一些用于身份验证的代码,因为当您在线部署它时,Firebase 会负责身份验证。
  • index.js 内部删除以下代码:
var serviceAccount = require("./**YOUR_SDK_NAME**.json");admin.initializeApp({credential: admin.credential.cert(serviceAccount),**databaseURL: "https://myfirebaseproject-bx54dasx3.firebaseio.com"**});
  • 取而代之的是在 index.js 中,将它插入到您的代码中:
admin.initializeApp(functions.config().firebase);

这里我们告诉 Firebase 从部署时存在的配置中获取认证信息。

2.在网站目录内的终端上,运行以下命令:

firebase deploy

这需要几分钟的时间,但之后,您应该会看到类似这样的内容:

3.如上图所示,转到 firebase 提供的托管 URL

恭喜你已经在 Firebase 上托管了一个动态网站。

步骤 8:(可选)使用自定义 URL

  1. 从任何一个提供商那里购买域名,比如 GoDaddy 或其他你喜欢的提供商。
  2. 从左侧窗格转到主机
  3. 点击连接域

4.在此输入域:

5.遵循验证说明。

声明:

  1. 【Firebase 服务的服务条款
  2. Firebase 和它的服务是谷歌的产品,这篇文章中没有任何地方暗示不是这样。
  3. 这篇文章是为了教育目的。

在 AWS SageMaker 中托管 Scikit-Learn 最近邻模型

原文:https://towardsdatascience.com/hosting-an-scikit-learn-nearest-neighbors-model-in-aws-sagemaker-40be982da703?source=collection_archive---------12-----------------------

除了一系列内置算法,AWS SageMaker 还提供了训练和托管 Scikit-Learn 模型的能力。在本帖中,我们将展示如何在 SageMaker 中训练和托管 Scikit-Learn 最近邻模型。

我们的用例将是本文中描述的葡萄酒推荐模型。在本练习中,我们将假设葡萄酒推荐器的输入数据已经准备就绪:一组 180,000 个 300 维向量,每个向量描述一种特定葡萄酒的风味特征。根据前面提到的文章,我们将这些向量称为 wine 嵌入。我们的目标是有一个模型,可以返回与给定输入向量最相似的葡萄酒嵌入。

正如官方文件所述,我们将在整个过程中处理两个主要步骤:

  1. 准备一个 Scikit-Learn 脚本在 SageMaker 上运行
  2. 通过 Scikit-Learn 估算器在 SageMaker 上运行这个脚本

准备在 SageMaker 上运行的 Scikit-Learn 脚本

在我们的 Scikit-Learn 脚本中,我们将从我们的输入通道(S3 桶和我们完全准备好的葡萄酒嵌入集)加载数据,并配置我们将如何训练我们的模型。模型的输出位置也在这里指定。这一功能已被置于主要保护之下。

我们还将安装 s3fs,这是一个允许我们与 S3 交互的包。这个包使我们能够识别特定的 S3 目录(输入数据、输出数据、模型),以便脚本与之交互。另一种方法是使用特定于 SageMaker 的环境变量,这些变量指定要与之交互的标准 S3 目录。为了说明这两个选项,我们将使用环境变量 SM_MODEL_DIR 来存储模型,以及输入和输出数据的特定目录地址。

到目前为止一切顺利!通常,我们可以在 SageMaker 上运行这个脚本,首先训练模型,然后通过调用“predict”方法返回预测。然而,我们的 Scikit-Learn 最近邻模型没有“预测”方法。实际上,我们的模型正在计算各种葡萄酒嵌入之间的余弦距离。对于任何给定的输入向量,它将返回最接近该点的葡萄酒嵌入。这与其说是一种预测,不如说是一种计算哪些点彼此距离最近的方法。

幸运的是,“模型服务”功能允许我们配置 Scikit-Learn 脚本来实现这种类型的定制。模型服务由三个功能组成:

i) input_fn :这个函数将输入数据反序列化为一个对象,该对象被传递给 prediction_fn 函数

ii) predict_fn :该函数获取 input_fn 函数的输出,并将其传递给加载的模型

iii) output_fn :该函数获取 predict_fn 的结果并将其序列化

这些函数中的每一个都有一个运行的默认实现,除非在 Scikit-Learn 脚本中另有说明。在我们的例子中,我们可以依赖 input_fn 的默认实现。我们传递到最近邻模型中进行预测的 wine 嵌入是一个 Numpy 数组,这是默认 input_fn 可接受的内容类型之一。

对于 predict_fn,我们会做一些定制。我们不是在模型对象上运行“预测”方法,而是返回前 10 个最近邻居的索引列表,以及输入数据和每个相应建议之间的余弦距离。我们将让函数返回一个 Numpy 数组,该数组由一个包含这些信息的列表组成。

函数 output_fn 也需要一些小的定制。我们希望这个函数返回一个序列化的 Numpy 数组。

Scikit-Learn 脚本还有一个组件:加载模型的函数。必须指定函数 model_fn,因为这里没有提供默认值。该函数从保存模型的目录中加载模型,以便 predict_fn 可以访问它。

具有上述所有功能的脚本应该保存在一个源文件中,该文件独立于您用来向 SageMaker 提交脚本的笔记本。在我们的例子中,我们将这个脚本保存为 sklearn_nearest_neighbors.py。

通过 Scikit-Learn 评估器在 SageMaker 上运行这个脚本

从这里开始就一帆风顺了:我们需要做的就是运行 Scikit-Learn 脚本来适应我们的模型,将它部署到一个端点,然后我们就可以开始使用它来返回最近邻葡萄酒嵌入。

在 SageMaker 笔记本中,我们运行以下代码:

现在,我们的近邻模型已经准备好行动了!现在,我们可以使用。predict 方法,返回样本输入向量的葡萄酒推荐列表。正如预期的那样,这将返回一个嵌套的 Numpy 数组,该数组由输入向量与其最近邻居之间的余弦距离以及这些最近邻居的索引组成。

[[1.37459606e-01 1.42040288e-01 1.46988100e-01 1.54312524e-01
  1.56549391e-01 1.62581288e-01 1.62581288e-01 1.62931791e-01
  1.63314825e-01 1.65550581e-01]
 [91913 24923 74096 26492 77196 96871 113695 874654
  100823 14478]]

我们走吧!我们在 AWS SageMaker 中培训并主持了一个 Scikit-Learn 最近邻模型。

托管您的交互式可视化

原文:https://towardsdatascience.com/hosting-your-interactive-visualizations-f11a10b74f51?source=collection_archive---------29-----------------------

Bokeh & Heroku

请点击下面的链接亲自查看!

[## 全球选民投票率

voterturnoutmap.herokuapp.com](https://voterturnoutmap.herokuapp.com/MapScript)

https://voterturnoutmap.herokuapp.com/MapScript

可视化使每个人都可以访问数据。他们把令人麻木的 excel 电子表格变成有趣且易于理解的图表。他们总结,突出,良好的可视化也允许用户自己探索数据。用户可以探索数据来回答他们自己的问题并做出他们自己的发现。

“Look at this graph.”

作为 Python 程序员,许多人都熟悉 Matplotlib 和 Plotly,但最近我一直在尝试使用散景。有一些关于使用散景的很棒的教程,我鼓励你去看看—

[## 使用 Python 中的散景进行数据可视化,第一部分:入门

提升你的视觉游戏

towardsdatascience.com](/data-visualization-with-bokeh-in-python-part-one-getting-started-a11655a467d4) [## 使用 Python 制作交互式地理地图的完整指南

想知道这些美丽的地理地图是如何创建的吗?我们的数据世界收集了大量的…

towardsdatascience.com](/a-complete-guide-to-an-interactive-geographical-map-using-python-f4c5197e23e0)

这些教程演示了如何创建交互式可视化,但交互仅通过 gif 或视频显示。您可以在自己的服务器上本地托管您创建的可视化效果,但是有没有办法托管交互式可视化效果,以便读者可以进行交互?是的,答案是 Heroku!

Heroku 有很棒的文档和一步一步的指导来迎合不同的编程语言。我将引导你通过我所做的把我的视觉化变成一个应用。如果你想让你的作品容易被分享,这是非常有用的。

设置

首先,你必须用 Heroku 创建一个帐户,因为我们是数据科学家,所以我假设你正在使用 Python。确保你的 Python 是最新的!你还需要一个 GitHub 账户。动手吧!最后,您需要安装 Heroku。这很容易,尤其是如果你已经有了自制软件。

Command to install Heroku via Homebrew

现在,您应该已经拥有了开始工作所需的一切。用这个简单的命令从您的终端登录 Heroku:

You must login!

根据 heroku 文档,“Heroku 和 git 命令都需要这种身份验证才能正常工作。”

现在真正的工作开始了。我假设你已经有了一个伟大的想象,你需要与世界分享。如果没有,遵循我上面链接的教程之一。我使用的数据来自 IDEA 的选民投票率数据库

您需要将可视化转换为. py 文件。您需要整理您的数据帧并创建一些必要的文件:

  • procfile——用 py 文件初始化应用程序的简单代码行

I broke this up into two lines so you could see the whole thing.

  • requirements.txt

Find your versions with the terminal command, “pip freeze”

  • runtime.txt

Your version of Python!

一旦存储库中有了所有这些文件,就可以部署应用程序了。在 github repo 中,发出命令:

Create the app

您可以在创建后指定应用程序的名称。留空,Heroku 会为你命名。最后,把你的工作推给 Heroku,它会把你的代码作为自己的应用程序托管。

Look for the url printed at the bottom.

发布的 url 会将您带到您的活动应用程序。你也可以按照下面的命令,它会做同样的事情。

Simple.

既然你的项目已经有了自己的网站,那就和全世界分享吧!

[## 使用 Python 开始使用 Heroku

本教程将让你在几分钟内部署一个 Python 应用程序(一个简单的 Django 应用程序)。再坚持几分钟…

devcenter.heroku.com](https://devcenter.heroku.com/articles/getting-started-with-python)

在 AWS Lambdas + API Gateway 上托管您的 ML 模型第 1 部分

原文:https://towardsdatascience.com/hosting-your-ml-model-on-aws-lambdas-api-gateway-part-1-9052e6b63b25?source=collection_archive---------3-----------------------

我关于模型部署的其他帖子

所以你辛苦了几个星期/几个月,你漂亮的机器学习模型完成了。感谢上帝。

但是现在有人想用你的模式。这是个好消息,不是吗?

确实是,但是一个全新的问题出现了。你必须把它放在某个地方,让其他人也能使用它。

我将向您展示如何在 AWS 上轻松、廉价地完成这项工作。

关于我的其他关于模型部署的文章,请查看标题上方的链接。

You don’t need to be Gordon Freeman to handle these lambdas

本系列教程将向您展示如何使用 AWS 来做到这一点。具体来说,我们将使用以下组件:

  • S3 水桶
  • λ函数
  • λ层
  • API 网关(来自第 2 部分)

为什么不用 Sagemaker?

我没有使用 Sagemaker,因为它可能非常昂贵,每个模型 100 p/m,而 lambda 函数只需为每个请求付费。

这可能导致 lambdas 的成本是在 Sagemaker 上运行相同模型的 1/5 到 1/10,特别是如果您有几个模型要在低流量下部署。

你需要什么

你需要一些东西来完成这个。你需要安装 Python (scikit learn,pandas 等)和 Docker。如果你在 Windows 机器上,Docker 将需要构建正确的 lambda 层文件(我是通过艰难的方式学到这一点的)。

所以你首先需要一个模型。我将根据 Kaggle 上的英国房价数据集建立我的模型(数据可以在这里找到,我的代码在这里)。

λ—层/功能

Lambdas 是执行特定任务的小型运行时。它们可能需要一段时间来配置,但它们完全由 AWS 管理,所以您需要配置的只是 lambda 的内存。

他们可以在上面安装 Python,但不会安装开箱即用的模型运行包。为了实现这一功能,我们需要使用λ层。

如果你熟悉的话,Lambda 层与 Docker 图像非常相似。每一层都继承了上一层的功能。但是你需要知道一些关于他们的事情。

  • Lambda 图层必须是 zip 文件
  • 对于给定的 lambda 函数,只能有五个 lambda 层
  • lambda 层不能大于 250MB(总计,解压缩后)

对于这个例子,我们需要使用 4 个 lambda 层

  1. Numpy / scipy 层,因为后面的层需要这些包(由 AWS 预构建)
  2. Pandas 层,以允许我们使用模型中使用的 ColumnTransformer
  3. Sklearn 层支持使用 scikit-learn 库
  4. 我们的模型将驻留的模型层

所以接下来我将向您展示如何构建您自己的 AWS lambda 层,以允许您的 lambda 函数使用 Pandas

第 2 层—熊猫

这些步骤在 Pandas/scikit-learn 层之间是相同的,因此我们将在这里重点关注它们,您可以对 scikit-learn 层重复这些步骤。

接下来,您需要打开 bash/Powershell 并将目录更改为 layers/Pandas 目录。

然后运行以下命令:

docker run --rm -it -v ${PWD}:/var/task lambci/lambda:build-python3.6 bash

注意:${PWD}在 Powershell 中将当前工作目录挂载到 Windows 环境中的映像。如果你用的是 mac/linux $pwd 应该没问题。

这个简单的命令做了几件事:

  • 拉下兰姆西的 docker 图像。这个 docker 映像模拟了 Python 3.6 lambda 环境的运行时,并允许我们在运行文件的相同环境中构建文件(这对 Windows 用户非常重要)
  • 将当前目录挂载为一个卷,以便 docker 映像可以输出 lambda 构建文件
  • 允许我们直接攻击 docker 图像

现在运行以下脚本,在 docker image bash 中为 lambda 层构建 python 文件(对于 sklearn 层也完全相同):

pip install -r requirements.txt --no-deps -t python/lib/python3.6/site-packages/

这将构建在 lambda 函数中使用 Pandas 所需的 python 文件。主要区别是 pycache 中的所有文件扩展名都应该有。pyc 文件类型。在 lambda linux 环境下运行代码需要这些文件。

接下来,我们需要为要使用的代码创建一个 zip 文件。

Lambda 层需要在 zip 文件中有一个特定的文件夹结构:

- python
  - lib
    - python3.6
      - site-packages
        - all your python package files will be included in here

所以仔细检查并运行 zip_layers.py 中的代码,它将创建作为 lambda 层工作的 zip 文件。

在 AWS 上上传和测试

接下来的步骤是:

  1. 将您的 pandas_layer.zip 上传到 S3
  2. 将 pandas_lambda.zip 文件的路径复制到 S3 存储桶中
  3. 选择 AWS 服务上的 Lambda
  4. 单击左侧面板并选择图层
  5. 创建一个新层

Viola,你已经创建了你的第一个 lambda 层!但是现在我们需要测试它是否有效。为此,你需要用 Python 3.6 运行时创建一个 lambda 函数。

要添加 lambda 图层,您需要单击 lambda 函数模板中的图层图标,然后单击添加图层按钮。

然后,您将从运行时兼容层列表中选择 numpy/scipy,然后选择您刚刚构建的 Pandas 层。

但是一定要先放 numpy/scipy 层。否则熊猫层将不能使用它上面的层的 numpy 依赖。

别忘了点击保存!!

接下来你需要刷新你的页面,浏览并编辑 lambda 函数。使用下面的代码来测试 Pandas 功能是否如您所期望的那样工作:

import json
import pandas as pddef lambda_handler(event, context):

    print((pd.DataFrame(data={'col1': [1, 2, 3, 4]})))

保存您的功能并单击测试。您将需要创建一个测试用例,但只需给示例一个名称,因为我们在构建模型层之前不需要它。

如果你看到了下面的输出,那么这是一个巨大的成功,你已经让熊猫在你的 lambda 函数上工作了。哇哦。

第三层— sklearn

现在,我们需要重复上述步骤,使用 docker 来构建文件,以便使用 sklearn。重复以上步骤(使用 my github 中的 sklearn resources.txt)创建新的 sklearn_lambda.zip 并上传到 S3。

现在我们需要测试 sklearn 安装是否在 lambda 函数上工作。要使用它,我们只需更新上面的 lambda 函数代码,以包含对 sklearn 的引用。

import json
import pandas as pd
import sklearndef lambda_handler(event, context):

    print((pd.DataFrame(data={'col1': [1, 2, 3, 4]})))
    print(sklearn.__version__)

如果你看到 0.20.3 被添加到 lambda 的输出中,那么你做得非常好,几乎所有的困难工作都完成了!!接下来,我们将模型添加到 lambda 函数中,这样我们就可以开始返回模型预测。

第 4 层—您的 ML 模型

通过运行 build_model.py,您将获得一个完美格式化的 zip 文件,以便在您的 lambdas 上使用该模型。

要将它添加到你的函数中,你需要重复上面的步骤,并使用那个压缩文件(上传压缩文件到 S3,创建一个新的模型层,然后将这个层添加到你的 lambda 函数中)。

为了测试这一点,我们需要做更多的工作。首先,我们需要配置 JSON,以允许输入模型所需的字段。

如果您没有更改 lambdas 中的基本测试用例,您的测试 JSON 将如下所示:

{  
  "key1": "value1",
  "key2": "value2",
  "key3": "value3"
}

现在,您需要更新它,以便与我们需要的模型输入一起工作。

{
    "Property Type": "S", 
    "Old/New": "Y", 
    "Duration": "L"
}

一旦你把你的模型 lambda 层链接到你的 lambda 函数,你就可以开始了。

将您的 lambda 函数更新为这段代码,您将能够从您的模型返回预测。lambda 函数将获取您的模型层并保存您的。pkl 文件到/opt/model_name.pkl。

import json
import pandas as pd
from sklearn.externals import joblibmodel = joblib.load('/opt/house_price_model.pkl')def lambda_handler(event, context):

    df = pd.DataFrame([event])

    # Returning the value from the list
    result = model.predict(df)[0] 

    return result

仅此而已。如果所有的步骤都成功了,那么你应该会得到一个结果。我得到 1644.62626412,但这将取决于你的随机种子,功能的数量等。

但仅此而已。这不是太可怕,但如果你不知道来龙去脉,可能需要一段时间。

接下来,我将把这个 lambda 挂接到 API 网关,这样我们就可以使用 Python 中的请求包来调用我们的模型 API。

在 AWS Lambdas + API Gateway 上托管您的 ML 模型第 2 部分

原文:https://towardsdatascience.com/hosting-your-ml-model-on-aws-lambdas-api-gateway-part-2-23517609522b?source=collection_archive---------23-----------------------

我关于模型部署的其他帖子

这是我在 AWS 系列上托管您的 ML 模型的第 2 部分,我将通过 API 网关安全地公开您的 ML 模型 lambda。

我有一些好消息,虽然,这是容易的一点

你已经完成了设置 lambda 函数和所有层的所有艰苦工作,所以这应该是小菜一碟。

关于我的其他关于模型部署的文章,请查看标题上方的链接。

将 lambda 链接到 API

因此,首先您需要通过 API 网关创建一个新的 API。

对于您的新 API,选择 resources 并单击 actions。您需要添加一个资源,然后添加一个 POST 方法。让我们称资源为 predict,因为这就是它的作用(有趣的想法),并将 POST 方法分配给 predict 资源。

接下来,您将需要将 API 与 lambda 函数集成在一起。输入您的 lambda 函数名,并允许 API 访问该资源。它应该是这样的:

APIs are easy AF

接下来我们只需要部署 API。重新单击 Actions 按钮,选择 Deploy API,并为您的新部署命名和描述(如果您愿意的话)。

我通常把我所有的 API 都称为测试,这样至少人们不会太惊讶,然后他们会爆炸。

测试您是否可以访问您的 API

你已经在 AWS 端完成了所有的配置,现在让我们看看是否能从你的 API 中得到一些预测。

其实超级简单。

import requests

url = "https:your_url.amazonaws.com/test/predict"input_data = {
  "Property Type": "S",
  "Old/New": "Y",
  "Duration": "L"
}

r = requests.post(url, json=input_data)
print(r.json())164735.29632791804

维奥拉。您实际上已经部署了您的模型,现在可以从任何可以在您的 API 上创建 POST 请求的地方访问它。

这很酷。

为您的 API 增加一些安全性

但是很明显,我们不希望任何获得 URL 的人能够从 API 访问结果。

也许它是商业 IP 或其他东西,但无论哪种方式,你都必须为通过它的所有请求付费(不要担心它真的很便宜),所以让我们为 API 添加一个 API 密钥,这样它就变得很好很安全。

你需要做的第一件事是创建一个使用计划。您可以通过 API 设置节流/突发流量。

Just click the toolbar on the left hand side and select usage plan. Please set your quota to more than 5 per month though. Testing will be hell otherwise

一旦您创建了您的使用计划(如果您正在与企业合作,您可能希望每秒钟有 5 个以上的请求),您就可以开始了,然后接下来会提示您创建您的 API 密钥。

现在我发誓我们快到了。接下来,您需要进入您的 APIs POST 方法并添加 API 密钥需求,否则您仍然可以在没有密钥的情况下访问 API。

所以让我们直接进入方法响应

最后一步,别忘了部署您的 API。

您会惊讶地发现,做出更改却忘记部署是多么容易。

现在我们需要去做一些测试,以确保这是我们所希望的工作。所以我们要检查一下:

  • 1:测试没有密钥的 API 请求失败

  • 2:测试带有密钥的 API 请求成功

#1 测试没有 API 密钥的 API 密钥失败

import requests

url = "https:your_url.amazonaws.com/test/predict"input_data = {
  "Property Type": "S",
  "Old/New": "Y",
  "Duration": "L"
}

r = requests.post(url, json=input_data)
print(r.json())

运行该脚本应该会返回以下错误。

{'message': 'Forbidden'}

如果这种情况没有发生,你需要检查你的 API 密匙是否已经被正确地附加到你的 API 上,因为它现在不工作。

但是,现在你已经成功地保护了你的 API。

#2:带有密钥的 API 请求成功

您需要返回到 API 网关,在 API 密钥下,您需要显示您的 API 密钥。

Half the battle of AWS is knowing where to find these things

将它粘贴到 Pycharm(或您正在使用的任何 IDE)中,这样您就可以在 POST 请求中传递它。

所以你的帖子请求应该是这样的:

key="yourapikey" # In reality it'll look much weirder

headers = {
  'x-api-key': key
}

r = requests.post(url, json=input_data, headers=headers)
print(r.json())

您应该得到这样的有效响应(实际结果可能会有所不同)

164735.29632791804

包裹

因此,在本教程之后,您应该能够将您的模型部署为 lambda 函数,并使用 API 网关安全地将该 lambda 公开给外界。

我希望你们都学到了一些新的东西,如果有什么你想让我介绍的,就写在评论里,我会研究的。

在 Azure 函数上托管您的 ML 模型—第 1 部分

原文:https://towardsdatascience.com/hosting-your-ml-model-on-azure-functions-ae3ca4ae1232?source=collection_archive---------13-----------------------

我关于模型部署的其他帖子

终于有了一种便宜又简单的方法来部署您的模型

这是几个星期的功能工程,模型选择和超参数调整,你完成了。

你的同事对你不断使用“泡菜”这个词感到困惑,他们不再问你在做什么,只是假设你真的喜欢保存蔬菜。

现在让我们把这个模型放在一个你可以从中获得一些价值的地方。

如果你想通过 AWS lambdas 部署你的模型,请点击标题上方的链接查看我的文章。

如果你想跟进 ,这里是我的 Git 回购的链接

Azure 函数 vs AWS Lambdas

这些与 AWS lambdas 非常相似,从模型部署选项来看,它们比 AWS lambdas 有更大的优势。

指定你的 Azure 函数运行时就像 pi 一样简单

还记得让 AWS Lambdas 用熊猫有多痛苦吗?我当然知道。改变一个小东西(你的内部 ML 包或者想用一个新的花式 sklearn 模型)AWS lambdas 就开始了。

接下来你使用 Docker 重新创建图层,但愿你不会忘记更改图层版本..

使用 Azure Functions,你只需指定一个 requirements.txt,当你将 Azure Functions 部署到你的帐户时,它会为你安装所有这些包。

它还允许你从本地直接上传模型到你的 Azure 函数。

这真是太酷了。

Azure CLI 允许你在本地调试你的 Azure 功能

如果你遵循我的 AWS lambda 教程,你可能会花很多时间编写简单的测试来运行你的 AWS lambda,以确保你可以导入熊猫或一些非常小的东西。

然后你可以测试通过 Python 中的请求包向 Azure 函数发送数据。但是现在您只需在本地运行它们,并通过请求包发送 POST 请求,您就可以在部署之前确保它正在工作

创建 HTTP Azure 函数只需一个简单的步骤就可以部署和公开端点

以前,当将模型部署到 AWS Lambdas 和 API Gateway 时,您必须分别执行这两个步骤。有了 Azure 函数,它们只是一个步骤。

除此之外,你的 Azure 函数是预先保护的(比如:有一个 API 密匙),所以当你在 API 网关端配置东西时,你不必担心关闭你的 AWS Lambda。

入门指南

现在我们进入有趣的部分。如果你想跟进,这里有GitHub 回购。

首先你需要安装 Azure CLI 工具。这将允许您在本地测试您的 Azure 功能,然后将其推送到您的 Azure 帐户。

在这一点上,获得 Azure 帐户可能是值得的。如果你从未注册过,你可能会得到 200 美元的免费积分。但是,如果您不能,请不要担心,这些部署不会让您倾家荡产。

按照这个来安装 Azure CLI,这样我们就可以开始构建我们的功能了。

要测试这一点,您需要尝试:

func new

如果安装成功了,你就可以在本地创建一个 Azure 函数。但是在 Windows 上工作可能有点困难。

让 Azure CLI 在 Windows 上运行

如果你得到一个错误,说 func not found,你想安装做一些更多的步骤:

  • 通过管理外壳安装巧克力
  • 使用 chocolatey 安装 azure cli 工具 azure cli 工具工作(答案#2)。
  • 运行 func 检查您的结果是否与 Stackoverflow 答案匹配,然后您就可以开始了

显然这是因为 func 不在你的路径上。所以,如果你比我聪明,并整理了这些东西,让我知道,我会在这里添加它。

这将是你初始化 Azure 函数的地方。简单的事情是,如果你让你的 Azure 函数响应 HTTP 请求,那么你已经部署了你的模型,并通过 API 在一个简单的步骤中使它可用。

设置你的 Azure 函数和本地 python 环境

1 初始化您正在工作的文件夹

func init titanic_model --python

2 设置基本 Azure 功能

cd titanic_model
func new
  • 选择 HTTP 触发器
  • 给你的函数一个名字,我称之为我的模型 _ 部署

如果你做对了,你会看到这个:

眼尖的读者会意识到我是在我的基本 Python 安装上运行这些功能的。

当我们在本地运行 Azure 函数时,它使用我们指定的 Python 环境来执行。这让我们可以使用 requirements.txt 来指定一个本地环境,该环境将镜像将在 Azure 函数上运行的内容。

我使用 conda 创建我的环境,因为它很简单,但是你也可以使用 venv 或任何其他解决方案。

我还会添加到 requirements.txt 中,以涵盖所有的依赖项。这是我的样子:

azure-functions==1.0.4
pandas==0.25.3
scikit-learn==0.21.3
requests==2.22.0

现在运行,这样您就可以安装包并构建用于部署的模型。

conda create --name model_deploy python=3.7
activate model_deploy
pip install -r requirements.txt 

构建模型和配置 Azure 函数

我在 Git repo 中放了一个简单的模型来指导您。来创建模型。您需要运行的 pkl:

python model_build.py

这个模型是根据泰坦尼克号的数据集建立的,它预测了幸存者:

  • 年龄
  • 乘客等级
  • 上船(乘客上船的地方)

改变 init。py 处理您的请求

init。py 是你的 Azure 函数运行的内容。

使用 JSON 输入/输出可能有点麻烦,我花了一段时间才适应。

我将把代码的主要部分粘贴在这里,这样我就可以突出我遇到的主要困惑,这样你就可以从我的错误中吸取教训。

data = req.get_json()
data = json.loads(data)

您将为此模型使用 POST 请求。但是当您读入 JSON 请求时,它仍然是字符串格式,所以我们需要使用 json.loads 将它转换成适当的 dict/JSON 对象,然后才能使用数据进行预测。

response = []
for i in range(len(data)):

    data_row = data[i]
    pred_df = pd.DataFrame([data_row])
    pred_label = clf.predict(pred_df)[0]
    pred_probs = clf.predict_proba(pred_df)[0]

    results_dict = {
        'pred_label': int(pred_label),
        'pred_prob_0': pred_probs[0],
        'pred_prob_1': pred_probs[1]
    }

    response.append(results_dict)

return json.dumps(response)

有几件事我会很快提到:

  • 警察。DataFrame([data_row]):允许您在 Pandas 中创建一个单行数据框架。否则你会得到一个索引错误
  • int(pred_label):因为输出的类是 numpy 数据类型(int64)而在返回 JSON 对象时是不可用的,所以我转换了它
  • json.dumps(response):即使我们使用 json,你也需要在发回之前将其转换成一个字符串

现在让我们在本地部署那个坏的 boi

func host start

一旦它启动并运行,应该会给你下面的结果

http://localhost:7071/API/model _ deployment是我们想要发送请求的目标。在本地 Azure 函数运行之后,使用 test_api.py 将数据 ping 到我们的 api。您应该会看到以下结果:

布欧耶。现在成功了!!!!!所以现在我们有了一个本地运行的 Azure 功能,我们需要把它推送到 Azure,这样我们就可以永久地部署它。

部署到 Azure

现在我们已经让 Azure 函数在本地工作,我们可以把它推到 Azure 并部署这个坏的 boi。

如果你还没有创建一个 Azure 帐户,那么现在是时候了。一旦你这样做了,就去你的门户网站,然后运行一个 Azure Function 应用程序。

下面是我如何配置我的

Using Docker is a good shout. I’ll do my next blog post on that

现在你已经创建了你的 Azure 应用,你现在可以将你的模型部署到 Azure 并进行测试。

从您的本地 Azure 函数目录中,您将需要运行以下命令

az login

这将无缝执行,或者要求您登录 Azure 帐户。一旦完成,你就可以开始了。现在让我们将您的本地代码推送到 Azure。

 func azure functionapp publish <APP_NAME> --build remote

其中 APP_NAME 是您给函数 APP 起的名字(duh)。我的是泰坦模型,但是你的会不同。

一旦完成,你需要找到你的 Azure 应用的 URL。你可以在这里找到

这个 URL 是您将要用来从 Azure 访问您的模型的。所以用你的 azure 函数 url 替换 test_api.py 中的 azure_url,试一试。

如果一切按计划进行,您将获得:

[
  {
    "pred_label": 1,
    "pred_prob_0": 0.13974358581161161,
    "pred_prob_1": 0.86025641418838839
  },
  {
    "pred_label": 0,
    "pred_prob_0": 0.65911568636955931,
    "pred_prob_1": 0.34088431363044069
  },
  {
    "pred_label": 1,
    "pred_prob_0": 0.13974358581161161,
    "pred_prob_1": 0.86025641418838839
  },
  {
    "pred_label": 0,
    "pred_prob_0": 0.65911568636955931,
    "pred_prob_1": 0.34088431363044069
  }
]

现在,您还会有一种温暖而模糊的感觉,即将您的第一个 ML 模型部署到 Azure 函数中!!

由于 API 端是由 Azure 函数本地处理的,我将在第二部分使用 Docker 重新创建这个过程,这可能会使事情变得更简单。

热狗还是热狗:使用元编程编写 UI 测试

原文:https://towardsdatascience.com/hot-dog-or-not-a-hot-dog-using-metaprogramming-to-write-ui-tests-61e70b050dc5?source=collection_archive---------27-----------------------

关于 Kotlin 运行时脚本当前缺点的见解,黑盒与白盒测试,以及 AST 解析如何帮助编写愚蠢(但有效)的 UI 测试。

在对 Kotlin 的长期探索中,现代元编程的下一个前沿领域,我很高兴能够使用元编程来编写 UI 测试。这个想法是将一个 TornadoFX 项目上传到的 TornadoFX-Suite 中,后者依次读取项目,检测 UI 控件,并动态编写 UI 测试。

Tornado-FX 套件即将开始编写 UI 测试。尽管在过去几个月里 AST 解析受阻,但我终于又开始行动了。当我接近复合分解的 MVP 时,现在可能是谈论如何使用应用程序的复合抽象来创建测试的好时机。以下是迄今为止所取得的成就:

The last two steps are stages 2 and 3 of this project.

我们已经检测到一些 UI 输入,并使用解析来创建类分解。所以…我们该拿它怎么办?让我们花点时间来谈谈 UI 测试。

用户界面(UI)测试

测试是验证软件是否按预期运行的必要组成部分。不同种类的测试可能有其各自的目的,但是如果没有一个坚实的基础,其他种类的测试可能会变得乏味,甚至糟糕。测试一般可以分为两类: 黑盒测试白盒测试

黑盒测试是一种从用户角度保证软件质量的方法,意思是在不知道代码本身是什么的情况下测试软件。这可能意味着测试是在用户与应用程序交互时在应用程序本身上进行的(手动或自动)。其他测试可能会检查应用程序的不同组件是否能够有效地相互通信。 黑盒测试测试系统的行为和功能。

另一方面,白盒测试测试系统如何运行。与黑盒测试不同,白盒测试是利用代码本身的知识编写的。 白盒测试涵盖了代码的健康,它的业务逻辑,并确保正确的数据路径。

我们正在从我们分析的代码中创建 UI 测试,这可能是一个灰色地带。根据 Android 文档,UI 测试“让你确保你的应用程序满足其功能需求,并达到高质量标准,从而更有可能被用户成功采用。”

探索应用程序本身的环境可能会发现错误,但是如果没有白盒测试,就很难确定不需要的功能的来源。

一年多前,我编写了一个非常酷的仪表板生成器,来帮助生成可以呈现为 JavaScript 的 XML。因为我自己对拖放功能进行了微观管理,所以很难确定为什么代码本身会出现这样的错误:

TornadoFX-Dnd-TilesFX

应用程序不会崩溃,也不会记录任何错误。应用程序本身没有中断,但是功能显然没有按预期工作。UI 错误很难诊断和解决,但这正是 UI 测试的用武之地。UI 测试不仅有助于定义和保证期望的行为,而且随着复杂性的增加,它还使得调试、重构和维护代码变得更加容易。

一个好的 UI 测试应该是这样的:

  1. 抓取特定视图
  2. 在视图上执行一个动作
  3. 检查用户界面,看它看起来是否正常

在这个特别讨厌的 bug 的例子中,我们可以看到大多数预期的行为都在那里;然而,很明显,一个特定的序列暴露了一个功能漏洞。我们的测试将遵循这些步骤,但包括边缘情况以及顺序交互的排列将有助于解决类似这些棘手的疏忽。

元编程如何编写 UI 测试?

在编写 UI 测试的元编程中存在一些挑战,尤其是在像 Kotlin 这样的静态类型语言中。虽然从 Kotlin 1.3 开始,Kotlin 具有反射能力和自脚本能力来编译运行时代码,但如果没有必要的导入和依赖,我无法成功编译上传的 Kotlin 文件。

不幸的是,Kotlin 还没有完全准备好像在运行时编译整个项目这样雄心勃勃的事情,但是我将同时关注问题 KT-27960KT-28916

现在,我求助于另一个 Kotlin 解决方案,通过创建一个 AST 解析器,使用 kastreegson 进行基本的类分解,来编写我自己版本的代码自省。创建我自己的 AST 解析器有助于克服挑战,例如不必担心封装和访问级别或递归中的类型转换,同时将解决方案保留在 Kotlin 中——最终,编写 Kotlin DSLs 变得容易!

我们有一种方法来确定所需的控制,我们有一个基本的复合分解。让我们看看如何利用这些东西来实现编写 UI 测试:

  1. 抓取一个特定的视图 —通过用视图()扩展类,TornadoFX 有一种区分视图的简单方法。说到测试,我们可以用 id 抓取视图控件。由于人们通常不会在他们的 TornadoFX DSLs 上附加 id,我不想强迫他们这样做。相反,我们可以遍历视图层次结构中的节点,并将每个节点的路径以及节点的状态保存在一个字典中,以便在编写脚本时容易访问。
  2. 在视图上执行一个动作——以编程方式在视图上执行一个功能并不是一个挑战,除了保存一个可以用每个控件完成的可能动作的字典。
  3. 检查用户界面,看看它是否…嗯,变化—真正的挑战是知道 UI 控件预期会发生什么变化,更不用说弄清楚 UI 应该是什么样子了。机器学习可能会发现节点中哪些属性发生了变化,但目前,我们将保持较小的目标。保持一个组合契约的抽象表示对于帮助跟踪视图中的节点是什么是必要的,节点的状态是否变脏是必要的,以及将改变节点的函数的关系映射到节点本身是必要的。如此复杂的关系需要用有向图结构来表示。

这是一个很高的要求,只是看看一个节点是否改变或保持不变,热狗或不是热狗。为了让测试更有用,下一阶段将应用 Tensorflow 开始收集尽可能多的数据,以进行更智能的测试。这个阶段的 UI 测试可能没什么用,但这是我感到兴奋的事情。

正如库梅尔·南贾尼在硅谷所说,“核心技术是有效的。它只是……它只是需要训练。”

旧金山湾区的住房:使用机器学习寻找交易

原文:https://towardsdatascience.com/house-hunting-in-the-san-francisco-bay-area-deal-hunting-using-machine-learning-3ed6fc8e8991?source=collection_archive---------16-----------------------

模拟房价揭示了被低估的社区和房源。

Aerial view of San Francisco downtown and the East Bay. Photo credit: Unsplash

总结

本文描述了旧金山湾区单户住宅价格的收集、可视化和建模。使用 2019 年 6 月的 7,000 个活跃房源的数据集,探讨了影响该地区房价的因素。发现用位置数据(学校质量和通勤时间)补充列表信息(卧室和浴室的数量、住宅大小和地块大小)可以显著提高简单线性回归模型的解释能力。回归系数还讲述了一个有趣的故事,即市场对住宅及其位置各方面价值的看法。重要的是,定价模型能够识别被低估的房源和社区,为个人购房者和投资者提供潜在兴趣的关键信息。

简介

虽然自 2000 年以来,标准普尔 500 和美国整体房地产市场的表现几乎相同(都上涨了约 100%),但旧金山湾区的房价指数上涨了约 167% ( 圣路易斯联邦储备银行)。因此,海湾地区的房主享受了一个通过房地产积累财富的机会,而这种机会在美国其他地区不一定能获得。

对于那些已经入市的人来说,自 2000 年以来,房地产价值增长了近两倍,这无疑是一件好事。然而,对于那些刚搬到该地区的人来说,攒钱付首付和选择买房地点可能是一项艰巨的任务。受我与朋友和家人的讨论以及投资的基本概念(即,购买定价过低的资产)的启发,我开始收集尽可能多的关于湾区独户住宅当前价格的信息,应用简单的机器学习技术梳理出推动住宅价值的因素,并确定该地区可能吸引投资的角落。

方法

使用 RegexPandas 清理和处理来自整个湾区的单户住宅列表的数据(地址、床位、浴室、住宅大小、地段大小、纬度/经度坐标和价格)。作为列表数据的补充,通勤时间从谷歌地图获得,学校质量数据来自 2018 年加州学生表现和进步评估( CAASPP )。使用来自斯坦福土方工程 CartopyMatplotlib 和 shapefiles(城镇、邮政编码和街区边界)将结果信息叠加到地图上。使用 Seaborn 可视化了盒/条图和变量之间的成对关系。使用 StatsmodelsScikit-learn 库对数据进行普通最小二乘(OLS)回归分析。这个项目的完整源代码可以在 GitHub 上找到。

结果

可视化清单数据

地理趋势

有了海湾地区市场上几千处房产的信息,所有房源的位置都用 Python Cartopy 包和从斯坦福 Earthworks 获得的城市边界信息绘制在地形地图上,并用价格进行颜色编码(图 1)。这张地图揭示了该地区房价相对成本的清晰地理趋势。例如,旧金山、马林县和半岛通常包含最昂贵的 20%的房源(深蓝色数据点),而奥克兰、圣莱安德罗和里士满通常包含最便宜的 20%的房源(深红色数据点)。类似地,在南湾,靠近圣克鲁斯山脉的房子通常比沿着迪亚波罗山脉的房子更贵。

Figure 1. Overview of single-family homes listed for sale in the Bay Area in June 2019. The 7,153 entries are split into quintiles by price, with list prices falling within the bottom and top 20% colored dark red and blue, respectively.

这种分析的一个自然延伸是将清单分成次区域。放大旧金山、东湾、半岛和南湾,地理价格趋势再次显现(图 2)。旧金山最贵的独栋住宅位于市中心和普雷斯迪奥之间,而最便宜的位于该市南部,从日落区到湾景区。在东湾,奥克兰山两侧(包括皮德蒙特、伯克利和奥林达)的房子最贵,而里士满、南奥克兰和圣莱安德罗的房子最便宜。在半岛上,阿泽顿的帕洛阿尔托和希尔斯伯勒的房价最高,而圣马特奥和东帕洛阿尔托的房价最低。在南湾,最靠近圣克鲁斯山脉(洛斯阿尔托斯、萨拉托加和洛斯加托斯)的房子最贵,而在那以东的几乎所有房子都不太贵。跨地区的相对成本也值得注意:虽然东湾的最高价格五分之一起价为 150 万美元,但半岛上的最低价格也是同样的价格。

Figure 2. Zoom showing detail of single-family home list prices in the San Francisco, East Bay, Peninsula, and South Bay regions. In each case, price quintiles have been recalculated to reflect the distribution of prices within the highlighted region.

城镇间的房价和地价

为了更好地量化价格变化,使用 Python Seaborn 库构建了箱线图。这种表示允许跨分类变量(这里是城市/城镇)的分布比较,其中彩色框表示四分位范围的界限(第 25 到 75 个百分点),其中的线显示中值价格,而触须包含分布的剩余部分减去异常值。

从这个角度来看,从最低到最高的房价中值对选定地区进行排序提供了一些有趣的见解(图 3)。例如,房价中值最低的主要是东北湾(瓦列霍、安提阿和里士满),而最高的是半岛(希尔斯伯勒、帕洛阿尔托和伍德赛德)。此外,散点叠加在箱线图上说明了大多数人居住的地方:奥克兰、圣何塞和旧金山都有数百套当前房源,而更昂贵的十几个社区只有少数几套当前待售房屋。

Figure 3. Box plot displaying home price and for selected Bay Area cities, with individual observations superimposed to reveal sample size and distribution.

有趣的是,将同样的分析应用到房子所在土地的价格上(图 4 ),会得出有些不同的结论。例如,虽然伍德赛德的房价中位数在图 3 所示的 29 个城镇中排名第三,但该社区(主要位于 I-280 以西,以骑马闻名)的单位面积土地成本中位数实际上是这 29 个城镇中最低的。同样,从土地成本的角度来看,其他中值房价较高的城镇,如 Orinda 和 Los Gatos,似乎更实惠。另一方面,帕洛阿尔托和旧金山是迄今为止购买土地最昂贵的地方,这反映了它们作为该地区主要经济活动中心的地位。

Figure 4. Box plot displaying land price for selected Bay Area cities.

对于旧金山、奥克兰和圣何塞,房价的分布也是按社区划分的。虽然旧金山的几个街区(内里士满、俄罗斯山、诺布山、滨海区、北海滩)号称是湾区最贵的(> 500 万美元)住宅,但仍有几个街区(湾景、猎人角、Visitacion Valley、怡东、克罗克-亚马逊)提供标价低于 100 万美元的房产(图 5,顶部)。

在奥克兰(图 5,中间),只有 3 个社区(蒙特克莱尔、栈桥格伦和洛克里奇)的房价中值超过 100 万美元,而几乎所有其他社区(最显著的是考克斯/艾姆赫斯特公园、体育馆和弗鲁特维尔)都有大量价格低于 50 万美元的房源,是该湾最便宜的房源之一。

Figure 5. Box plots showing home prices across neighborhoods in San Francisco, Oakland, and San Jose.

这样的便宜货通常在圣何塞找不到(图 5,底部),那里最便宜的社区房价中值不到 100 万美元。即便如此,这个地区只有少数房子的价格高于 100 美元 2M,而且它们似乎大多位于柳树谷、阿尔马登和常青树社区。有趣的是,这里最高的中值房价出现在西圣何塞,尽管价格分布比类似的社区窄得多,这或许反映了这样一个事实,即该地区的房价普遍不高,其房价是由靠近苹果和网飞等科技巨头而推高的。

建模房价

在这里,我描述了一个非常简单的方法,使用普通的最小二乘(非正则化)线性回归模型来构建房价模型。我的目标是( 1 )产生一个可解释的模型,其系数揭示了市场对房屋及其所在土地的各个方面的价值,并( 2 )确定湾区的哪些部分提供了最“物有所值”的东西,即那些提供了多种功能组合、保证价格高于市场目前承受水平的东西。当然,其他方法(例如,k-最近邻法、决策树、神经网络)可以产生一个解释力更强的模型。下面描述的线性模型符合本文的意图——从描述性分析的角度提供对房屋价值的见解。

清单数据

除了简单描述当前湾区住房和土地价格的地理分布,该数据集还用于使用 Python StatsmodelsScikit-learn 库对房价进行建模。

首先,数据集中的 7,151 套房屋的价格根据清单中包含的房产数据(卧室数量、浴室数量、房屋大小和地块大小)分别绘制,并通过 Seaborn pairplots(图 6,顶部)使用普通最小二乘(OLS)回归进行拟合。在这四个特征中,房子的大小解释了大多数观察到的标价差异( R = 0.56)。另一方面,当完整的数据集缩小到一个邮政编码(95126)时,这些特征中的每一个都可以更好地解释价格差异(图 6,底部)。

Figure 6. Relationship between price and listing factors is tightened when full set of listings (top) is narrowed to a single zip code (bottom).

新增功能:通勤时间和学校质量

整个地区的房屋面积和价格之间的适度相关性,以及单个邮政编码内的强相关性,提出了一种非常直观的可能性,即特定位置的因素也对价格有影响。为了将“地点”纳入等式,引入了反映便利性和特权的额外数据:通勤时间和公立学校质量。

认识到旧金山和帕洛阿尔托是该地区的两个主要经济中心,通勤时间是通过谷歌地图测量的,即从每个邮政编码到两个目的地中较近的一个的乘车时间(周三上午 8 点)(图 7,左侧)。结果表明,从旧金山到圣何塞,半岛上上下下的住宅提供了通勤时间短于一小时的可能性。同样,马林和奥克兰到旧金山也很方便,弗里蒙特到帕洛阿尔托也是如此。另一方面,从外东湾(里士满、安提阿、圣拉蒙)的家到更近的枢纽的通勤时间通常超过 1.5 小时。

Figure 7. Commute times (left) and school quality (right) for zip codes across the Bay Area.

公立学校的质量也很可能在特定地区独户住宅的定价中发挥作用。方便的是,加州学生表现和进步评估(CAASPP)标准化测试机构已经为加州的每所公立学校提供了大量的学生水平数据。使用 2018 年的数据集,平均每个学校各年级的熟练程度测量值,以及每个邮政编码的学校的熟练程度测量值,学校质量被量化为特定邮政编码内被认为精通阅读和数学的学生的比例(图 7,右)。即使经过这样的平均,这张地图也指出了整个海湾地区学生成绩的近乎双峰的分裂,马林县、半岛和三谷地区享有优秀的学校(> 75%的学生优秀),而安提阿、瓦列霍、里士满、圣莱安德罗和圣何塞的公立学校学生相比之下似乎很挣扎。

Figure 8. Relationship between price and commute times (left) or school quality (right) across the Bay Area.

这些新参数也被评估为标价的独立预测指标。事实上,通勤时间和学校分数在相似的程度上解释了( R ~ 0.55)观察到的价格差异,作为之前的最佳预测因素(图 8)。直觉上,最佳拟合线意味着房价和学校质量之间的正相关关系,以及价格和通勤时间之间的负相关关系。

功能选择

多重共线性,或特征集合中特征之间的显著相关性,可导致系数的不同值,这取决于选择哪些特征包含在模型中。为了创建一个具有可解释系数的简单模型,这个扩展的特征集必须筛选出那些为价格预测提供有意义的新信息的特征集。

Figure 9. Heatmap showing correlation across independent variables.

为此,图 9 中示出了跨特征集的皮尔逊相关系数。事实上,列表数据中的三个参数(卧室、浴室的数量和房屋大小)都彼此强烈相关(0.65 < ρ < 0.83),如果我们要在拟合模型后从系数中提取意义,就必须删除其中的两个。作为价格的最强独立预测因素(图 6,顶部),房屋大小被保留在模型中,而卧室和浴室被丢弃。

引入通勤时间和学校质量数据,简单线性回归模型构建如下:

价格~户型+地段+通勤时间+学校分数 ( 1 )

拟合和解释模型

使用 sci kit-learnlinear regression软件包将房价数据回归到上面列出的四个特征上。十倍交叉验证用于估计泛化误差,或模型对未用于训练模型的数据的表现。根据房屋大小、地段大小、通勤时间和学校分数,使用数据集中的所有示例获得了 0.61 的平均测试集 R 。然而,剔除异常值后,拟合质量有了相当大的提高,在剔除价格最低和最高的 5%的房屋(分别为 45 万美元和 430 万美元)后,平均测试集 R 达到 0.70。下面将进一步研究根据过滤数据训练的模型。

这种简单模型的主要优点是易于解释。为此,特征系数表明,在其他条件相同的情况下,湾区购房者应该准备好为每增加一平方英尺的室内空间支付大约 430 美元,为每增加一平方英尺的室外空间支付 0.35 美元,为每分钟节省的通勤时间支付 14k 美元,为当地公立学校的优秀学生比例每增加一个百分点支付 12k 美元:

*预计标价($)
= $675,900

  • ($429 /平方英尺)住宅面积(平方英尺)
  • ($0.35 /平方英尺)地段面积(平方英尺)
    +(-13,560 美元/分钟)通勤时间(分钟)
  • ($12,217 / %熟练程度)* ( 2 )

鉴于其简单性,以及训练和测试集误差非常接近的事实( R 分别为 0.71 对 0.70),可以有把握地说,这种四特征最小二乘线性回归模型位于偏差-方差权衡的高偏差侧。例如,通过使用更大的特征集或非参数方法,如k-最近邻或决策树,可以毫不费力地构建更精确的模型(参见我最近关于同一主题的文章)。可解释性是付出的代价——关于额外一平方英尺室内空间或较短通勤距离的市场价值的简单规则不容易从复杂的模型中提取出来。

当前模型的性能( R = 0.71)和完美性( R = 1)之间的差距可以通过三个因素来解释:( 1 )在简单线性模型下无法处理的非线性效应(例如,特征之间的交互效应、房屋大小和价格之间的饱和关系)、( 2 )可能影响价格但不包括在该模型中的房屋及其周围环境的方面,以及( 3 )不匹配第一个问题可以通过增加复杂性来解决,例如添加交互项或转向非参数模型。第二个可以用附加特征来固定,例如本地犯罪率、邻居的美学、财产状况。邻里侦察兵有一个犯罪风险地图,但是据我所知,潜在的数据还没有公布。通过量化理想的属性,如树木覆盖率或海拔高度,可以近似得出邻里关系的美观程度。第三是由市场定价固有的随机性造成的不可减少的误差。

识别被低估的领域

购买被低估的资产是价值投资的核心原则。从机构投资者或精明的购房者的角度来看,住宅价值模型提供了一个诱人的前景,可以识别相对于市场其他部分可能被错误定价的区域(以及最终的个人房产)。

为此,每个列表的位置被标绘在地形图上,现在用标记颜色表示实际价格和预测价格之间的差异(图 10)。低价房源(以红色显示)是那些提供高价房典型的四个特征(住宅和地段大小、通勤时间和学校质量)组合的房源。根据该模型,定价过低的地区可以在旧金山(日落区和湾景区)、沿半岛(戴利市和东帕洛阿尔托)、东湾(阿拉米达、奥林达、海沃德和弗里蒙特)和马林(圣安塞尔莫)找到。

Figure 10. Map showing difference between list price and price predicted by the model described in Equation 2. Listings deemed by the model to be undervalued and overvalued are shown in red and blue, respectively.

考虑一个更复杂模型的场景,例如,我们为每个城市或邮政编码添加虚拟变量。这个模型将提供一个更准确的房价假设,通过将一些美元数字添加到恰好位于高消费城市或邮政编码的列表的预测价格中,从而更好地识别列表级别的交易。然而,我们将失去识别地图上定价过低或过高的角落的能力!通过只选择与房地产内在价值相关的特征,我们剥夺了我们的模型了解东帕洛阿尔托价格便宜的能力,从而获得了揭示东帕洛阿尔托相对于其所提供的价格偏低的能力。

箱线图提供了残差的另一种有趣表示(图 11)。通过实际和预测标价之间的差异排列所选城市,可以看到东帕洛阿尔托和奥林达提供了住宅和位置属性的组合,这些属性是通常定价高于这两个位置 50 万美元的列表的特征。另一方面,门洛帕克、洛斯加托斯和帕洛阿尔托等地的情况似乎正好相反。

Figure 11. Box plot showing difference between list price and price predicted by the model described in Equation 2 for selected cities/towns.

对于旧金山、奥克兰和圣何塞,残差也绘制在各个街区上(图 12)。在旧金山,交易很简单:最实惠的社区看起来被低估了。另一方面,在奥克兰就不一定了:例如,蒙特克莱尔和格伦高地社区,看起来在标价上很贵,但相对于 Eq 也很便宜。2.圣何塞似乎结合了两者的元素,这表明一些名义上昂贵的街区(柳树谷,中城)可能确实被高估了,而其他昂贵的街区(寒武纪公园,西圣何塞)看起来在 Eq 方面更合理。2.

Figure 12. Box plots showing difference between list price and price predicted by the model described in Equation 2 across neighborhoods in San Francisco, Oakland, and San Jose.

结论与展望

从几千份当前的房地产清单中,我们用图表和统计的方法研究了旧金山湾区的独栋房屋的价格。将住宅和地块大小、通勤时间和学校质量纳入多元线性回归拟合,可以对价格进行建模,并识别可能吸引投资的被低估的海湾地区。未来的工作可能包括通过添加可能影响位置的感知合意性的附加特征(例如,犯罪数据、树木覆盖率、海拔)来改进模型,并随着未来几年住房市场的发展跟踪该定价模型的性能。

应用数据科学技术来为房地产交易提供信息不需要只由专业投资者来进行,与 Python 一起使用的免费开源包使个人能够收集大型数据集,可视化关键指标,并应用机器学习技术来识别可能被其他市场参与者忽略的交易。

伊斯坦布尔房屋销售价格和场地数据分析

原文:https://towardsdatascience.com/housing-sales-prices-venues-in-istanbul-dbdefb8b06f0?source=collection_archive---------16-----------------------

Photo by Osman Köycü on Unsplash

A.介绍

A.1 .背景的描述和讨论

伊斯坦堡是世界上最大的都市之一,居住着超过 1500 万人,人口密度为每平方公里 2.813 人(T2)。作为这个城市的居民,我决定在我的项目中使用伊斯坦布尔。这个城市总共分为 39 个区。然而,事实上,各区都被挤在大约 72 平方公里的区域内,这使得这个城市有一个非常交织和混杂的结构[1]。

从图中可以看出,伊斯坦布尔是一个人口多、人口密度大的城市。如此拥挤的城市导致人口密集的城市中的商店和社交分享场所的所有者。当我们从投资者的角度考虑时,我们希望他们更喜欢房地产成本较低的地区,他们希望建立的企业类型也不那么强烈。如果我们想到城市居民,他们可能也想选择房地产价格较低的地区。同时,他们可能希望根据社交场所的密度来选择地区。然而,现在很难获得将投资者引向这一方向的信息。

当我们考虑所有这些问题时,我们可以创建一个地图和信息图表,其中房地产指数放在伊斯坦布尔上,每个地区根据场地密度进行聚类。

A.2 .数据描述

为了考虑这个问题,我们可以列出如下数据:

  • 我从 NYU 的空间数据库中找到了土耳其的二级行政区划[2]。的。json 文件有土耳其所有城市的坐标。我清理了数据,并将其归入伊斯坦布尔市,在那里我用它创建了伊斯坦布尔房屋销售价格指数的 choropleth 地图。
  • 我使用 Forsquare API 来获取伊斯坦布尔给定行政区最常见的场地[3]。
  • 关于伊斯坦布尔市的人口和社会参数,没有太多的公开数据。因此,在大多数情况下,您必须建立自己的数据表。在这种情况下,我从住房零售网页[4]上收集了伊斯坦布尔每个区最新的每平方米住房销售价格平均值。
  • 我使用谷歌地图的“搜索附近”选项来获得每个区的中心坐标。[5].

B.方法学

作为数据库,我在学习中使用了 GitHub repository。我的主数据,其中有主要成分区,平均房价,纬度经度城市的信息。

Master Data

我使用 python yellow library 来可视化伊斯坦布尔及其行政区的地理细节,并创建了一个叠加了行政区的伊斯坦布尔地图。我使用纬度和经度值得到如下的视觉效果:

Borough of Istanbul

我利用 Foursquare API 来探索行政区并对它们进行分段。我根据给定的经纬度信息,为每个区设计了 100 个场地和 750 米半径的限制。这里是一个从 Forsquare API 列表场馆名称,类别,纬度和经度信息的标题。

List of Venues

总的来说,Foursquare 返回了 43 个地点。这是一张行政区和场馆的合并表。

Table of Boroughs and Venues

我们可以看到卡迪科伊、马尔特佩、贝约格鲁、贝西克塔斯、西斯里和法提赫·豪达到了 100 场馆的限制。另一方面;Pendik、Arnavutkoy、Tuzla、Adalar、Buyukcekmece、Sultangazi、Cekmekoy、Beylikduzu、Sultangazi 行政区在 20 场馆下方,在我们给定的经纬度坐标中,如下图所示。

这一结果并不意味着在各个行政区都进行了调查。实际上,这取决于给定的纬度和经度信息,这里我们只是为每个区运行单一的纬度和经度对。我们可以用包含更多经纬度信息的邻居信息来增加可能性。

Number of venues for each borough

总的来说,Foursquare 返回了 256 个独特的类别,然后我创建了一个表格,显示了下表中每个区的前 10 个场馆类别。

List of top 10 venue category

我们在行政区有一些共同的场地类别。出于这个原因,我使用了无监督学习的 K-means 算法来对行政区进行聚类。K-Means 算法是无监督学习中最常用的聚类方法之一。

首先,我将运行 K-Means 来将行政区聚类成 3 个聚类,因为当我用肘方法分析 K-Means 时,它确保了 K-Means 的最佳 K 的 3 度。

Elbow method to specify the best k value

这是我的合并表,每个区都有聚类标签。

Merged Table with clusters

我们还可以估计每个集群中第一个最常见的场馆的数量。因此,我们可以创建一个条形图,帮助我们为每个集群找到合适的标签名称。

Number of venues in each cluster

当我们检查上图时,我们可以将每个集群标记如下:

  • 群组 0:“咖啡馆场所”
  • 群组 1:“多种社交场所”
  • 第 2 组:“住宿和密集咖啡馆场所”

我们还可以考察一下,在不同的范围内,房屋平均销售价格出现的频率是多少。因此,直方图有助于可视化:

Average Housing Sales Prices in Ranges

如上图所示,我们可以将范围定义如下:

  • 4000 AHP:“低级 HSP”
  • 4000–6000 AHP:“中级 1 级 HSP”
  • 6000–8000 AHP:“中级 HSP”
  • 8000–10000 AHP:“高一级 HSP”
  • 10000 AHP:“高-2 级 HSP”

我的目标之一是在地图上显示每个区的前 3 名场馆信息的数量。因此,我根据前 3 个场馆的数量对每个区进行了分组,并将这些信息组合在 Join 列中。

Number of top 3 venues for each borough

C.结果

让我们将这些新变量与主主表中的相关集群信息合并。

Master table

现在,您可以看到上表中的最后三列是 Join、Labels 和 Level_labels。你还可以看到伊斯坦布尔的一个聚集地图区

Clustered map boroughs of Istanbul

在总结部分,我的目的之一是用 choropleth 风格的地图可视化每平方米的平均房屋销售价格。因此,我首先从 NYU 空间数据库[2]下载了一个土耳其二级行政区划的 json 文件。我清理了 json 文件,只调出了伊斯坦布尔市。

在最后一部分,我制作了 choropleth 地图,上面有每个区的以下信息:

  • 区名,
  • 群集名称,
  • 住房销售价格(HSP)水平,
  • 场馆数量前三名

Choropleth map of Istanbul with final datas

D.讨论

正如我之前提到的,伊斯坦布尔是一个在狭窄区域内人口密度很高的大城市。总共 39 个区的测量总数和人口密度可能不同。由于这种复杂性,在聚类和分类研究中可以尝试非常不同的方法。此外,很明显,并不是每种分类方法都能为这个大都市区产生同样高质量的结果。

我在这个聚类研究中使用了 Kmeans 算法。当我测试肘部方法时,我将最佳 k 值设置为 3。然而,只使用了 39 个地区坐标。为了获得更详细和准确的指导,可以扩展数据集,还可以钻取街区或街道的细节。

我还通过这些信息进行了数据分析,在 GitHub 上添加了地区坐标和房屋销售价格平均值作为静态数据。在未来的研究中,还可以从特定的平台或包中动态访问这些数据。

我通过在伊斯坦布尔地图上可视化数据和聚类信息来结束研究。在今后的研究中,可以通过网络或电话向直接投资者进行申请。

F.结论

因此,人们开始转向大城市创业或工作。因此,人们可以通过访问提供此类信息的平台来获得更好的结果。

不仅对于投资者,城市管理者也可以通过使用类似的数据分析类型或平台来更有规律地管理城市。

G.参考资料:

22 年的 AI 优势如何改变国际象棋

原文:https://towardsdatascience.com/how-22-years-of-ai-superiority-changed-chess-76eddd061cb0?source=collection_archive---------9-----------------------

机器完美前沿笔记

德克·克内梅尔和乔纳森·福利特

Figure 01: The Game of Kings
[Illustration: “Chess Players” by Lovis Corinth (1918), National Gallery of Art]

1997 年,IBM 超级计算机“深蓝”在六局系列赛中以 4 比 2 的比分击败了国际象棋世界冠军加里·卡斯帕罗夫。这是我们称之为“思维机器”发展过程中的一个里程碑时刻,因为在当时世界上最负盛名的战略游戏中,计算机已经证明了自己比最优秀的人类更优秀。

数百年来,机器在国际象棋中击败人类的基准一直是关注的焦点。众所周知,1770 年研发的土耳其机器人让像拿破仑·波拿巴和本杰明·富兰克林这样的名人激动又困惑。这只是一个精心设计的骗局,这个人力驱动的、不完全自动化的机器人愚弄了公众近 100 年。它的非凡之处不仅在于它似乎是一台自动机,还在于它是一台看似天才的自动机,能够在《王者游戏》中击败人类。从那时起,对能够在国际象棋中击败人类的机器的追求就一直持续着。事实上,第一波计算机科学先驱,像艾伦·图灵、克劳德·香农和约翰·冯·诺依曼,都是国际象棋选手,都试图编写能够掌握国际象棋的软件。

Figure 02: A Chess Playing Automaton?
[Illustration: “The Turk” by Joseph Racknitz (1789), Humboldt University Library]

当深蓝打败卡斯帕罗夫的时候,计算机已经在国际象棋上打败了人类。在 20 世纪 80 年代,对于业余棋手来说,Radio Shack 牌电脑象棋可能是一个强大的对手,而且有各种技能水平。深蓝的成功是最高的成就,在这一点上,机器游戏完全超过了人类游戏,永不回头。大约 250 年后,我们终于有了一台比我们玩得更好的机器。

最近在围棋、扑克和 Dota 2 等游戏中出现的更多机器征服让最初的深蓝胜利显得过时了。但是有一个重要的区别。因为它发生在 22 年前,我们有 22 年的证据来考虑。深蓝的胜利确实改变了国际象棋,但不是以人们期望或预测的方式。机器和人类如何在国际象棋世界中共存,不仅为我们在围棋、扑克和 Dota 2 等游戏的未来,而且为机器智能将增强或取代人类智能的正常工作和生活环境提供了一个诱人的预览。虽然“深蓝”的技术与现代人工智能几乎没有共同点,但它是人类和机器将如何走到一起的实物课程。

机器比我们好…现在怎么办?

我们采访了认知科学家兼国际象棋大师克里斯托弗·沙布里斯,他在《继续游戏》中讲述了职业国际象棋的场景。华尔街日报的专栏,关于深蓝征服国际象棋以及这项运动如何改变,这要归功于 22 年来人工智能的进一步发展。Chabris 分享了深蓝 1997 年胜利的影响:“很多人预测这不可能发生,或者当时不会发生。所以,我认为卡斯帕罗夫的落选让人很惊讶。…一些人预测,不知何故这会毁了国际象棋,一旦计算机真的擅长某件事,那么人类就会失去兴趣,或者对人类来说,参与这项活动本质上是一项回报较少的活动。事实上,什么也没发生。接下来的一个月,国际象棋世界继续进行。我相信,如果我没有记错我的国际象棋历史,卡斯帕罗夫本人——在被那场比赛的结果明显摧毁,并说了一些他可能不是故意说的或后来并不感到自豪的过激话之后——在同年晚些时候,他回来了,用他有史以来最好的一些游戏赢得了一场强大的特级大师锦标赛。卡斯帕罗夫继续保持了三年多的世界冠军,我认为当他自己退役时,他仍然在排行榜上名列前茅。至少在受欢迎程度方面,国际象棋基本上还在继续。”

当然,今天,深蓝已经不再是世界上最好的国际象棋“棋手”,甚至远非如此。20 年后,你的智能手机拥有比 IBM 为深蓝设计的电脑更好的电脑。“拥有一台可以打败世界冠军的计算机,它被存放在 IBM 的一个研究实验室里,并没有真正改变很多事情,”Chabris 说。“但是让每个人都拥有一台可以打败世界冠军的电脑确实让事情发生了很大的变化。…手机现在被禁止参加国际象棋比赛,因为作弊太容易了。如果你参加锦标赛,如果你能走进浴室,看着你的手机,你就能赢得每一场比赛。”

改变游戏方式

虽然考虑到将智能手机机器象棋偷偷引入竞争可能改变结果的所有方式很有趣,但人工智能已经在更深层次上影响了游戏的玩法。首先,让我们考虑防御策略的领域:“计算机擅长防御,因为它们会检查每个动作。他们不会因为自己处于不利地位、处于守势而受到情绪影响,”沙布里斯说。“他们会考虑每一种可能性,并尽可能长时间地进行分析。通过这样做,他们基本上表明了很多位置是可以防守的…防守比人们想象的更有可能。”

对我们许多人来说,耐心肯定是很难的。虽然人类可能喜欢积极的攻击计划,但计算机可能会采取完全不同的策略,专注于缓慢但稳定的改进,等待对手犯错。“保持压力直到另一个人成为第一个犯重大错误的策略——计算机显示,这些策略比我们意识到的要好,”Chabris 说。

电脑象棋已经影响了顶级游戏和教练。教练使用软件来帮助分析他们的学生和学员的游戏。顶级玩家都必须准备好让他们的对手玩从机器游戏中学来的独特的,甚至是不人道的动作。

Figure 03: Study, Learn, and Advance the Game
[Photo: by rawpixel on Unsplash]

一种新的学习方式

机器象棋已经在许多方面改变了人们学习游戏的方式。在过去,书籍和杂志在一个人提高和掌握这项运动的道路上发挥了重要作用。“国际象棋仍然有大量的印刷文献,”Chabris 说。“事实上,现在出版的国际象棋书籍可能比过去任何时候都多,而且会有更多伟大的国际象棋书籍问世。”但是象棋书籍越来越不重要,因为强有力的玩家可以使用计算机来研究、学习和推进他们的游戏。电脑国际象棋程序可以评估你的游戏,计算最佳的步骤,并为你的游戏做注解。该软件不仅可以指出每一个错误,还可以告诉你错误的严重程度,并告诉你最好的行动应该是什么。“这就像一个真正的好教练,告诉你,‘你应该这样做。“你应该那样做,”沙布里斯说。“这对于改进非常有用,只要学习和看到这一点就行了。”

然而,计算机象棋仍然是一个不完美的系统,至少在人类学习方面是如此。“这并不能解释为什么你应该走那一步,”沙布里斯说。“这并没有解释你将来如何能更好地找到那些更好的动作。它只是说,“这是你的错误。这是你应该做的。…这是人类教练可能会做的事情。我认为最终计算机也能做到。这是一个投入研究努力的问题。“大多数人,大多数时候,不仅仅是通过看到正确的答案来学习。有一个学习的过程。但是,在计算机象棋现在被利用的方式中,完美和实时信息的两步前进伴随着失去最初最能让你学习的过程的一步后退。

在国际象棋软件中添加为什么这一层可能在这一点上需要人类的洞察力,但将人类的视角编织到软件中只是时间、金钱和意愿的问题。国际象棋教育市场可能没有足够的利润来让它在短期内发生,但可以肯定地说,向最终用户提供这种服务的软件没有技术障碍,只是对机器学习生成的分析软件的功能有所限制。

走向人机协作

从更广泛的意义上来说,过去 22 年来国际象棋游戏的演变和国际象棋教育的进程,暗示了人类可能通过与智能机器合作来改变、适应和改进的方式。

在输给“深蓝”加里·卡斯帕罗夫(被许多人认为是有史以来最伟大的棋手)后,他开始接受机器象棋。他开创了一种叫高级国际象棋或半人马国际象棋的游戏,这种游戏涉及人类和计算机的合作。它从未真正流行起来,在更大的国际象棋社区中只是一个小插曲。

“人类的能力和计算机的能力之间的差异在什么时候变得如此之大,以至于将人类插入系统成为一个错误?”夏布利问道。“在早期,我认为卡斯帕罗夫的想法是,在国际象棋中,有些情况人类理解得更好,有些情况计算机理解得更好,因此最佳组合是让人类判断是否听从计算机的建议。”

“随着时间的推移,这一比例一直在缩小……到了你开始冒风险的时候,人类可能会认为他们知道得更多,而实际上他们并不知道——这有点像重写计算机,而事实上计算机会提供做出最佳举措的最佳机会。或者在更危急的情况下,计算机有最好的机会驾驶汽车,或降落飞机,或做出正确的医疗诊断。”

象棋 AI 的教训

从计算机统治国际象棋世界的 22 年中,我们可以学到哪些更广泛的教训?“当计算机在智力活动中变得非常出色时,它不会扼杀这种活动。事实上,对人类来说,它甚至可能变得更有趣、更民主,因为它使高质量性能的可用性更加普遍,”Chabris 说。对 Chabris 来说,这种民主化在很多方面改变了游戏规则。在机器象棋出现之前,只有少数特权阶层能够在幼年时接受高质量的训练。“如今,你甚至不需要有那么多钱或者有一个教练,”Chabris 说。也许有点讽刺的是,人工智能象棋事实上已经为人类铺平了竞技场。

随着电脑象棋的不断进步,现在它已经成为游戏的一个公认的支柱,人们对它的态度也在改变。“‘哦,那是引擎移动’,或者‘那是计算机移动’。”这在国际象棋中是一种侮辱。“计算机移动是一个愚蠢的无意义的举动,计算机出于某种模糊的原因做出了没有任何意义的举动,”沙布里斯说。现在,一个计算机移动意味着一个移动是如此好,但如此不寻常,只有计算机会看到它,看到它有多好。"

当然,从机器互动中学习还有很长的路要走。“拥有一个近乎客观的预言或你认为客观的东西,并不是学习、提高和更好决策的唯一必要因素,”Chabris 说。"人类总是能够忽略,甚至是客观上好的想法、信息、观点等等."

“也许我们还需要更多地了解如何最好地利用这些工具,”沙布里斯说它们是新的。我们很久没见过他们了。我们需要真正学习如何……更好地使用计算工具,并更多地研究人与计算工具之间的关系。"

这些都是很好的提醒,人工智能自动化不是一件可怕的事情。它不会很快扼杀我们的工作,它需要时间从笨拙走向有效,更需要时间走向最佳。因为,正如我们所看到的,在人工智能和国际象棋中,无论玩家是人类还是机器,国王的游戏仍然是一个诱人的挑战。

Creative Next 是一个播客,探索人工智能驱动的自动化对创意工作者,如作家、研究人员、艺术家、设计师、工程师和企业家的生活的影响。本文伴随 第一季第四集——AI 优势如何改变人类的努力。

为什么 90%的司机可能“高于平均水平”,或者为什么在使用统计数据时需要小心

原文:https://towardsdatascience.com/how-90-of-drivers-can-be-above-average-or-why-you-need-to-be-careful-when-talking-statistics-3df7be5cb116?source=collection_archive---------14-----------------------

(Source)

现实世界中的均值、中位数和偏态分布

大多数人看到“90%的司机认为自己高于平均水平”的标题,会想“哇,其他人在客观评价自己方面很糟糕。”你应该想的是“如果我们在一个严重负偏态分布中使用均值来表示平均值,这听起来并不那么难以置信。”

尽管像这样的标题经常被用来说明优越感(人们高估了自己的能力)它也提供了一个有用的教训,在你谈论数据统计时澄清你的断言。在这种特殊情况下,我们需要区分一组值的 平均值中值 。根据我们问的问题,有可能 9/10 的司机高于平均水平。这里有数据可以证明:

Driver Skill Dataset and Dot Plot with Mean and Median

区别在于,我们是使用平均值还是中位数来表示“平均”驾驶员技能。使用平均值,我们将所有值相加,然后除以值的数量,得到该数据集的 8.03。由于 10 名驾驶员中有 9 名的技能等级高于此,因此 90%的驾驶员可被视为高于平均水平!

相比之下,中位数是通过将值从最低到最高排序并选择一半数据点较小、一半数据点较大的值来确定的。这里是 8.65,下面 5 个司机,上面 5 个司机。根据定义,50%的司机低于中位数,50%超过中位数。如果问题是“你认为自己比其他 50%的司机强吗?”比 90+%的司机不能如实回答肯定。

(中值是百分位数的一个特例,在这个值上,给定的数字百分比更小。中位数是第 50 个分位数:数据集中 50%的数字更小。我们还可以找到第 90 个分位数,其中 90%的值较小,或者第 10 个分位数,其中 10%的值较小。百分位数是描述数据集的直观方式。)

为什么这很重要?

这可能看起来是一个人为的例子或技术细节,但平均值和中间值不一致的数据在现实世界中经常出现。当值对称分布时,平均值等于中值。然而,现实世界的数据集几乎总是有一定程度的偏差,无论是正的还是负的:

Positive, symmetric, and negative skews. (Source)

在正偏态分布中,平均值大于中位数。当图表上端相对较少的异常值使图表向右倾斜,而大多数值聚集在较低值时,就会出现这种情况。真实世界的情况是个人收入,平均收入明显大于中值收入。下图显示了 2017 年美国的收入分布,以直方图的形式显示为 100 个百分点。

Income distribution in the United States, a positively skewed distribution

具体数字因来源不同而有所不同(该数据来自这里),但总体模式是清晰的:少数高收入者将图表向右倾斜(正值),使平均值高于中位数。价值 55880 美元,平均值接近第 66 百分位。解释是 66%的美国人收入低于平均国民收入——当平均收入被认为是平均数时!这种现象几乎在每个国家都会发生。

负偏态分布的一个例子是死亡年龄。不幸的是,在这个数据集中,有一些人在相对年轻的时候死亡,降低了平均值,并使图表向左倾斜(负向)。

Age at death in Australia, a negatively skewed distribution (Source)

在负偏斜的情况下,中值大于平均值。结果是,当平均值被定义为均值时,更多的人可以在“平均值”之上。“大多数人比平均寿命更长”可能是一个奇怪的标题,但如果你仔细选择你的统计数据,你就可以让它成真。

大多数涉及人类行为的数据集都表现出某种偏斜。股市回报、收入、社交媒体关注者、战斗死亡和城市规模都是高度偏斜的分布。在反脆弱 , 纳西姆·塔勒布将这个扭曲结果的世界描述为极端主义。我们在 mediocristan 进化,所有的数据集都是正态分布的,但我们的现代生活现在被不平等分布所主导。生活在极端的地方有机会获得难以置信的回报,但这些只会发生在极少数人身上。这也意味着我们在谈论作为数据集“平均”表示的均值和中位数时必须小心。

DIstribution of Followers (source) on social media, a positively skewed distribution.

( Zip 定律和其他幂定律也会产生偏态分布。)

结论

要记住的一点是,当你指定“平均值”时,你需要澄清你是在说平均值还是中位数,因为它有区别。世界不是对称分布的,因此,我们不应该期望分布的平均值和中位数是相同的。

机器学习可能会得到所有的关注,但数据科学真正重要的部分是我们每天使用的部分:帮助我们理解世界的基本统计数据。能够区分平均值和中值可能看起来很平常,但这比知道如何建立神经网络更与你的日常生活相关。

一如既往,我欢迎反馈和建设性的批评。可以在 Twitter @koehrsen_will 上找到我。

博弈论——解释了极大极小算法

原文:https://towardsdatascience.com/how-a-chess-playing-computer-thinks-about-its-next-move-8f028bd0e7b1?source=collection_archive---------4-----------------------

1997 年,一台名为“深蓝”的计算机击败了国际象棋世界冠军加里·卡斯帕罗夫——这是人工智能理论史上的一个决定性时刻。

但是国际象棋计算机问题背后的伟大头脑在近 60 年前就已经开始发表这方面的文章了。被称为现代计算机科学之父的艾伦·图灵被认为是引发了追溯到 20 世纪 40 年代的调查。

1997 chess match between world champion Garry Kasparov and IBM computer “Deep Blue”

国际象棋计算机问题被考虑的时间跨度之大,证明了解决方案的复杂性。教科书已经被写在计算机象棋问题上,并且许多复杂程度不同的策略已经被测试。然而,本文将关注计算机在各种战略游戏中使用的一种通用决策策略,包括国际象棋、跳棋、曼卡拉棋、井字游戏等等。

这个一般策略包含在博弈论中广泛使用的算法中,称为极大极小算法。本文将简要介绍计算机如何使用极大极小算法来决定下一步行动,但首先我们需要定义一些东西:

游戏树

在计算机科学中,树是指一种嵌套的数据结构,其中我们从一个“根”节点(第 0 层)开始,从这个根节点开始分支,我们可以有任意数量的“子”节点(第 1 层)。假设这些“子”节点分支成“孙”节点(第 2 层)。现在我们可以说,从第 2 层节点的角度来看,第 1 层的节点是“父”节点,第 2 层的节点是“子”节点。

A schematic of a binary tree from the perspective of Level 2

直观地说,我们可以看到这种数据结构有无限多层次的潜力。在棋盘游戏中,我们可以将根节点(第 0 层)视为棋盘的当前状态,而第 1 层的节点则视为棋盘的每一种可能状态,这取决于下一步该怎么走。换句话说,1 级节点负责每一个可能的下一步行动。

展望游戏的未来

在多人游戏中,我们可以想象一个游戏树,其中的根节点是对手 B 走一步后棋盘的当前状态,轮到对手 A 了。因此,第 1 层包含代表对手 A 可能的移动的节点,第 2 层包含代表对手 B 在第 1 层中可能进行的每一次移动的节点。

如果我们继续这样做足够长的时间,我们完全可以描绘出游戏的未来。在某种意义上,上面的示意图过于简单,对手在任何给定的回合中只有 3 种可能的移动。通常情况下,例如在国际象棋中,可能的走法数量会非常非常多,导致我们的博弈树突然变得复杂。事实上,国际象棋的平均分支系数约为 35。

效用

效用可以被认为是一种根据每一个可能的移动可能导致的胜利来“打分”的方法。效用如何计算完全取决于程序员。它可以包含各种各样的因素,并在程序员认为合适的时候对它们进行权衡。例如,棋盘上空格的数量,对手当前棋子的位置,我们当前棋子的位置,我们离胜利的阵型有多近,等等。所有这些都可能是在计算某一特定移动的效用时要考虑的因素。让我们以井字游戏为例,它可以有相对简单的效用度量。下图显示了游戏中途的井字游戏棋盘,其中有一个非常简单(可能不是最优)的效用规则。我们可以看到,轮到了 X ,只有 3 个可能的移动,因此,有 3 个子节点。对于每个可能的移动,使用下面的效用规则计算效用。用简单的英语来说就是:

“对于每一行、每一列和每一条对角线,如果我们在一行中有 3 个 X,我们就赢了这场游戏,应该分配 1.0 的效用。如果我们有一行、一列或对角线上有 2 个 X 和 1 个空白正方形的场景,我们的效用应该是发生这种情况的场景数的 0.2 倍。”

我们可以看到获胜的棋盘具有最大的效用,所以我们的效用规则并非完全无用,尽管它肯定会受益于“防御”成分,这将考虑 O 离获胜有多近。

接下来,我们将把这些碎片放在一起,看看计算机如何“思考”它的下一步行动。假设轮到电脑了。决定下一步走哪一步的一个可能的方法是简单地计算每个可能的下一步的效用,并选择效用最高的一步。这通常是普通人在玩棋盘游戏时的策略,当然,游戏也可以通过这种方式获胜。

但是大师和普通人的区别在于他们有能力提前思考几个步骤。事实证明,计算机做这件事的效率比最好的国际象棋大师还要高。以下是如何…

极大极小算法

在开始之前,我们将对我们的游戏做两个假设:

  1. 人类玩家应该在最佳状态下比赛,或者努力获胜。随意移动或试图失败实际上可能会干扰算法的有效性。
  2. 该游戏必须是纯战略性的,不能包含任何形式的机会成分(大富翁、扑克、俄罗斯方块)。注:该算法的变体可用于说明“运气因素”。

该算法的前提是,计算机将通过评估棋盘在几个回合后的效用来计算下一步最佳棋。在这样做的时候,计算机假设对手总是选择最好的移动,最小化计算机的效用。当然,这不是一个安全的假设,但你瞧,不管怎样,它往往会很好地工作。

需要注意的一点是,当我们说“效用”时,我们总是从计算机的角度来指效用。例如,当人类玩家做出最好的移动时,我们说该回合的效用最小化。

该算法包含三个基本函数:最大化最小化,以及一个效用计算函数伪代码看起来像这样:

现在没必要太纠结于细节。该示意图的两个关键要点是:

  1. 该算法是递归的,因为最大化调用最小化,而最小化调用最大化
  2. 我们有打破递归循环的条件。例如,如果我们到达我们搜索空间中的一个节点,其中有人赢得了游戏,棋盘已满,或者最常见的情况是,我们已经达到了预定的深度限制,就会发生这种情况。

回到轮到计算机的场景,计算机将调用当前棋盘上的最大化功能。这将在棋盘的每个子棋盘上调用最小化,这将在每个孙棋盘上调用最大化,以此类推…

该算法执行我们在计算机科学中称为“深度优先搜索”的操作。这意味着它主要沿着树的整个长度垂直遍历,直到到达终端节点,然后再向上返回。其次,该算法在其他兄弟节点之间水平移动或。这与“广度优先搜索”形成鲜明对比,后者的作用正好相反——它首先在兄弟节点之间水平移动,一次搜索整个“层”,然后沿着树向下搜索。下面的示意图有助于说明这一概念:**

极大极小算法以深度优先的方式沿着树向下移动,直到它到达终端节点(某人赢得游戏)或预定的深度限制。深度限制是为涉及复杂搜索空间的游戏设置的,在这种情况下,在合理的时间内搜索整个可能的移动网络是不可行的。一旦到达终端节点或深度限制,调用效用计算函数,计算出该特定端子板的最终效用值。

然后,该效用值被“向上传递”到父节点,在父节点处,该效用值与父节点处的当前效用值进行比较(如果已分配)。如果父节点处于最大化循环中,如果终端节点效用值大于父节点处的当前值,则该终端节点效用值替换父节点处的效用值,父节点尚未被分配效用值。如果父节点在最小化循环中,则相反。

直觉上,我们可以思考这个循环是如何反复递归发生的,直到我们能够用效用值填充下一个移动节点(第 1 层)。这些是允许计算机做出决定的。下面的剪辑可能有助于形象化这个概念。

Note: The “best” next move returned by the algorithm is the move that corresponds to the utility value passed all the way up the tree to the root node (current state of the board).

但是我们实际上在做什么,这如何帮助计算机做出决定?计算机实际上应用了以下逻辑:

你的下一步棋只有对手的下一步棋弱的时候才算强。

从表面上看,我们也许能够识别出什么看起来像是一个强有力的行动;然而,如果这个强有力的移动导致对手更强有力的移动(击落我们的设施),那么我们最初的移动真的很强吗?

这是算法背后的思路,应用于我们的树的几个层次。我们计算未来某处可能的移动的效用,并决定这些效用是否应该代表我们当前的移动选项。如果对手(总是试图最小化效用)很可能会采取所有的行动将我们引向所述未来点,我们应该将该特定的未来效用值沿树向上传递,以表示我们当前的决策节点。

这就是它的要点。当我们想到相对复杂的游戏,有巨大的搜索空间和各种各样的策略时,如果计算机能够预测未来,我们就很幸运了。但是历史一次又一次地表明,只要我们的效用规则是有效的,这种总体策略仍然比单独的人类脑力更有效。

国际象棋是一种复杂的游戏,具有相当复杂的效用度量和巨大的搜索空间。将上述逻辑应用于国际象棋比赛可能足以让你头晕目眩,这就是为什么这个问题花了几十年(可以说是几十年)才得以解决。但是,编写国际象棋计算机程序的基本原则与上面简化的例子基本相同——观察未来可能的走法,决定这些走法有多好,并预测对手是否会采取所有正确的走法来引导你到达那里。

数据科学家如何买车

原文:https://towardsdatascience.com/how-a-data-scientist-buys-a-car-822fffbe384d?source=collection_archive---------15-----------------------

在荷兰生活和工作多年后,我和我的家人是时候搬回美国,用自行车换汽车了。

在美国没有车是很难生活的,因为我们在移居国外之前已经卖掉了我们的车,所以我们现在想买一辆新车。我决定像任何优秀的数据科学家一样,通过使用数据来解决这个问题。

获取数据

很多时候,数据科学项目最困难的部分是获取数据。尤其是如果只是一个副业的话。很可能你无法从网上下载 CSV 文件,没有任何数据,你就无法建立任何模型或做出任何预测。

网页抓取拯救

Developer tools in google chrome

网络抓取是以自动化的方式从网站获取数据的过程。我不是网络抓取的专家,这篇文章也不是设计成如何抓取网站的教程。但是通过一点点实践和理解某些 python 模块是如何工作的,您可以实现您最疯狂的数据幻想。

在这个项目中,我使用了一个叫做 Selenium 的 python 包,这是一个无头浏览器。这意味着它会打开一个网页,并以类似于真实用户的方式与之交互(与 BeautifulSoup 之类的只是读取 HTML 代码的东西相反)。

Google chrome 的开发工具使这个过程变得非常简单,因为你可以右键单击网页中你感兴趣的项目,并轻松复制 xpath、element_id 或任何其他你想要的内容,所有这些都与 Selenium 包配合得非常好。有时需要一点尝试和错误来找到您真正需要的元素和文本。

你可以在这里找到我用来刮几百辆车的代码。

清理数据

网络抓取数据的一个问题是,最终结果很可能非常混乱,需要你做大量的清理工作,因为你受网站设计的支配,网站设计是为了呈现信息而不是数据存储。很多时候你需要解析字符串来得到你想要的东西。

在将我的 web 抓取过程的结果保存到 CSV 之后,我现在可以将数据加载到 pandas dataframe 中并开始清理了。

随着 lambda 和 regex 函数的大量使用,我可以开始提取有用的信息,并开始创建特性来探索和建模。

首先,我创建了一个可重用的正则表达式函数,可以将它传递给。应用熊猫法。

A reusable regex function

“name”列有很多有用的数据,我可以使用我创建的函数从中创建四个新的特性。

我现在得到了一个类似这样的数据帧:

探索数据

现在是时候开始做一些更有趣的事情了,那就是探索数据。这是数据科学过程中至关重要的一步,这样您就可以开始了解您的数据及其趋势和相互作用。价格将是我的目标变量,所以我在设计我的图表时会考虑到这一点。

这些箱线图在我的一些分类变量中显示了非常清晰的信号,表明根据车辆的年份和类型,价格有很大的差异。

同样,我发现我的一个解释变量(里程)和目标变量之间有很强的相关性。随着里程数的增加,价格下降,两者之间有很强的负相关关系。知道了我们对汽车世界的了解,这很有意义。

通过查看我们的一些解释变量和目标变量之间的关系,我们可以开始很好地了解哪些特性将是重要的,以及我们以后应该使用哪种类型的模型。

编码分类特征

建模前的另一步是对我的分类特征进行编码。【4wd】【认证】已经是布尔特征,不再需要任何预处理,但是【类型】和【年份】应该被编码。我用的是熊猫一热编码法(。get_dummies)来实现这一点。

Pandas 足够聪明,允许我传递所有的特征,它将只对分类特征进行编码,并允许我选择删除一个新创建的列,以避免完全相关的特征。这将导致我的模型输出和解释出现错误。(请注意,只有两个年份列,因为 year_2015 已被删除。同样适用于“类型”栏

我的数据现在是我可以建模的格式。

建模数据

从上面的图表和汽车行业的先验知识来看,线性模型似乎很可能会很好地处理这些数据。

为了对此建模,我使用了 OLS(普通最小二乘法)线性回归模型statsmodel python 包。

This model resulted in a RSME of 1556.09

所得到的系数与探索性分析期间图中显示的故事相一致。里程与价格成反比。平均每增加 1000 英里,车辆价格就会降低 1600 美元(这适用于 GMC Yukons,可能并非所有车辆)。可能最令人震惊的数字是 SLE(Yukon 的最低等级)和 Denali(Yukon 的最高等级)之间的差异超过 9000 美元。这意味着你最好真的喜欢你从更高阶层获得的额外功能和奢侈品,因为你肯定为此付出了代价。

综合考虑,我应该买哪辆车?

到目前为止,我已经收集、清理、解析、探索、可视化和建模了这些数据。但问题仍然存在,我怎么知道买哪辆车?我如何知道我是否得到了一笔好交易?

方法很简单,使用模型进行预测,并计算每辆车的预测价格和要价之间的差异。然后根据差异对列表进行排序,在顶部显示最被低估的工具。这应该给你的车辆是最好的交易。

在优化了一些其他约束条件(例如,我的个人预算和我妻子的偏好)后,我能够创建一个排序列表,并开始给经销商打电话。

The car we bought is highlighted in blue

我们最终以 32,000 美元的价格买了一辆 2015 款 GMC Yukon Denali,比我的模型预测的价格便宜了大约 3,000 美元。

虽然有一些潜在的更好的交易,我们决定购买的汽车是本地的,使整个过程更容易和更快。考虑到我们当时根本没有车,轻松和快捷对我们来说是一个重要因素。

最后,我们现在可以重温之前的情节,从视觉上确认我们确实得到了一笔好交易!

我妻子非常喜欢她的新车,我对它的价格也很满意。总的来说,这是成功的。

数据科学家如何购买延期保修

原文:https://towardsdatascience.com/how-a-data-scientist-buys-extended-warranties-fac4ad3ea8de?source=collection_archive---------10-----------------------

深入了解“延长保修”的数学原理

这是我关于利用数据买车的帖子的“第二部分”。
如果你还没看过,那就来看看 这里

简介

我们都经历过。我们刚刚承诺购买那辆闪亮的新车,而且我们即将毫发无损地把它开出大楼。
但是,等一下,在我们在虚线上签字并骑行到日落之前,我们还要与“财务”人员再开一次会(也就是一长串推销的最后一行)
他们将为您提供一整套延长保修选项,以保护您的新虚拟资产。 这些是汽车经销商最大的赚钱者,令人惊讶的是有大量的数学数据支持它,这就是我们打算探索的。

一个简单的案例

假设你正坐在当地汽车经销商的财务办公室里,准备完成一笔交易。

你的轮胎获得了延长保修,每月只需花费 7 美元。

它涵盖了从你在车道上碾过一个钉子并需要一个补丁到完全爆胎需要一个全新轮胎的所有事情。

你应该接受这笔交易吗?值得吗?对经销商有什么好处?

这是一个概率游戏,为了简单起见,我们将使用一些相当合理的预期概率,这些概率是我经过数秒钟的思考后得出的。比方说,一年中有 5%的几率轮胎完全爆裂,30%的几率只需要修补。假设更换一个轮胎的平均成本是 200 美元,补片的平均成本是 20 美元。

这对代理商有什么好处?

为了回答经销商为什么会提供这笔交易以及他们期望从中赚多少钱的问题,我们可以开始用数学公式来表示。

假设经销商一年销售 1000 份延长保修。

为了计算出经销商将产生多少成本,我们可以使用以下基本概率概念,其中 E(x)是经销商需要维修的预期车辆数量。

通过一些基本的运算,我们现在可以得到下表:

因此,在一年内,经销商预计从 1000 笔此类交易中获得 68,000 美元的利润(难怪销售人员如此咄咄逼人)

但到目前为止,这不是很有趣,看起来更像会计而不是数据科学。

这是数据科学家开始考虑概率分布、均值方差、模拟、极端情况、数学关系、拐点等等的地方。

但首先是一些来自统计课的回顾。

这个,

Binomial distribution

是一个分布(确切地说是二项式分布)。分布有各种形状和大小。有些有定义它们的名称和功能,有些没有。

你如何解读这种分布?
y 轴上的值代表观察到 x 轴上对应值的概率。
我意识到令人困惑。
最容易理解的方法就是通过一个例子。
假设你掷一枚
公平硬币** 100 次(公平硬币的意思是:正面或反面的概率是 0.5)。
你觉得你会得到几个人头?当然,预期的头数是 50。
但你我都知道,你完全有可能得到 54 或 43 或 61 分。
但是 95 头呢?这可能吗?肯定是可能的,但是可能吗?**

如果你将一枚硬币抛 100 次,得到 95 个正面,常识将会起作用,你会认为这枚硬币必须有重量。你的担心是正确的,因为在 100 次抛硬币中获得 95 个正面的概率是 5.939138117904783 e-17如果你不能将这个科学数字转换为人类数字,别担心,它真的很小。 (翻译:大概不会发生)

这个概率在二项式分布图中表示。
我现在加了一个
橙 X
* 代表获得 95 个头的概率。
看到 x = 95 时 y 轴上的蓝线有多低了吗?
大约就是 0。这告诉我们,基本上 100 次翻转中有 95 次正面朝上的概率是 0 %(从技术上讲,这种情况可能发生,但极其罕见)。***

谁在乎硬币呢?让我们来谈点真实的东西吧!

如果我们用一个更真实的例子来代替掷硬币的例子,会怎么样呢?).

为了解决这个问题,我们将使用一种不同的分布,即二项式分布的派生物— 泊松分布**

为什么使用泊松分布而不是二项式
不需要太多的细节,我们可以用它们来回答相同类型的问题,但是在这个特殊的例子中,泊松分布二项式给了我们一些自然的好处。主要是因为它不是二进制的,因此我们不局限于每个时间段只有一个 0 或 1。
为了证明这一点:
如果我想将我的时间段定义为一年,那么一名车手完全有可能出现不止一次爆胎或补胎。
泊松分布允许我建模,而如果我使用二项式分布,那么我需要缩短我的时间周期,这样就只有一个可能的井喷或补丁。这可能是不可能的,或者至少不太容易,因为你可能会违反模型中的一些假设。这些原因使得泊松分布成为“罕见事件”建模的更自然和更常见的方法——如补丁和井喷。
如果你想了解更多关于
泊松二项分布有多么相似,这里有一篇很棒的文章
**

现在回到我们的问题。

问题 1:给定补丁(0.3)和井喷(0.05)的概率,

车行未能盈利的概率有多大?

在进行任何分布建模之前,我们需要了解作为利润函数的补丁和井喷之间的关系。之前,我们计算了汽车经销商的预期利润,结果是 68,000 美元。现在我们要问的是,所有利润被成本吞噬的可能性有多大?首先,让我们看看一家汽车经销商需要进行多少次修补和爆胎维修才能达到收支平衡。这可以通过下面的等式来定义。

84,000 is the expected revenue

然后,我们可以重新排列等式,并绘制下面的线。

粉色阴影区域显示了代理商可能会亏损的空间。给这个已经很棒的图添加一些有趣的东西是当前的期望值。

两条黑色实线显示了漏白数(垂直线)和补片数(水平线)的期望值,两者的交点显示了联合期望值。
因此,我们已经开始看到,平均而言,代理商不会处于粉色区域,因此他们不会亏损。

但是就像硬币的例子一样,我们知道期望值不一定是现实生活中发生的。

那么,经销商有可能赔钱吗?(有没有可能我们会在粉色阴影区域结束?)
一探究竟。
这就是我们的老朋友
泊松分布
出现的地方。
**

PMF of the Poisson Distribution

上面的函数是泊松分布概率质量函数(废话连篇的数学废话——这只是意味着如果我们插入数字,我们就会得到概率)*
让我们以下面的例子为例:***

p = p(爆胎)= 0.05
n =售出保修数量 x 每辆车轮胎数量= 1000 x 4
x = 210

一年中正好有 210 次井喷的概率是 0.0215。

Probability of getting exactly 210 blowouts in a year

这个数字可能看起来很低,因为 210 非常接近预期值 200,但请记住这是得到确切的* 210 井喷的概率。如果我们想回答至少得到210 次井喷的问题,那么我们可以简单地计算橙色柱右侧每个值的概率,然后将它们相加。
(专业提示:鉴于这个分布没有真正的上限,通常更方便的做法是将橙色条左边的所有概率相加,然后从 1 中减去它们)
数学上看起来是这样的:
***

如果我算出这一点,那么至少发生210 次井喷的概率将是 0.249 ,从图形上看,这一概率由下面的橙色阴影区域表示:****

See how the orange shade is about 25% of the area under the curve?

用简单的英语来说,这是什么意思?
大约有 25%的可能性,代理商一年内将不得不修理至少 210 次爆裂。

现在让我们展开

由于爆裂只是代理商必须支付的一种方式,我们需要对补丁做同样的事情。当我们得到两个概率时,我们可以创建一个联合概率,这意味着我们把它们相乘。
这在数学上可以写成:
**

假设我们对一年内至少 210 个井喷和至少 1500 个补丁感兴趣。得到的联合概率是 0.000498。**

再说一遍,这用通俗的英语来说是什么意思?
基本上,经销商一年内不得不修理至少 210 次爆裂和至少 1500 次修补的可能性不到 0.01%。

但是为了真正开始讲述一个故事,我们需要对补丁和井喷的所有组合都这样做。
我们可以将我们之前创建的利润边界两侧的这些联合概率相加,以计算出代理商亏损的总概率。

在实践中,我将使用上面的泊松公式,计算在白色区域中所有组合的精确联合概率(蓝线以下的一切),然后从 1 中减去该总和。**

为了形象化这一点,我创建了一个热图,显示每个组合的联合概率。

Heatmap: P(blowout)P(patch)

画面开始变得相当清晰。由于所有的密度都在蓝线的“赚钱”一侧,代理商似乎不太可能会赔钱。
但为了确保万无一失,我们将对利润边界左侧的所有值求和,并从 1 中减去总和。

结果是 4.000000330961484e-10。
耶……我认为他们在这些交易中不会亏钱。

问题 2:作为客户,我应该购买延保吗?

这真的是我们都关心的问题。
刚买了车,该不该买质保?

我们刚刚证明了这对代理商来说确实是一笔好交易,但这并不一定意味着对您不利(生活中有些事情是互惠互利的)。

所有的数学计算都是多余的,因为我们实际上是在问和以前一样的问题,只是时间倒过来了,空间小了很多。所以我们将跳过细节。

只购买一份保修服务,你需要付出什么才能让你的钱物有所值?
我们需要做的就是计算出多少
爆裂
补丁会让你的成本(如果你没有购买保修)超过保修的成本**

为了解释这个图表,作为一个例子,你可以说,如果我有至少 3 个爆裂和至少 0 个补丁,那么我应该购买保修。但是发生这种事情的可能性有多大呢?

我现在可以应用我的老朋友泊松分布公式来得到与每个概率相关的概率,然后将它们加在一起。**

你赔钱的最终概率是 0.00144

最终翻译:
你或许可以跳过保修

这种方法的美妙之处在于,你可以根据自己的需要调整概率,自己动手计算。

老实说,现实生活比我在这里介绍的要复杂得多。还有无数的其他变量可以考虑。

可能你开车比一般人多。也许你经常在建筑工地或土路附近开车。也许你是一个比大多数人都糟糕的司机,会在路上撞倒东西。

我的观点是,可能会有这样的情况,购买保修是值得的,因为你发生这种事件的概率高于平均水平(或者你不喜欢钱——这也是一个有效的理由)。但是我想我们已经证明了,总的来说,你最好不要在最后的账单上提供保修。**

生活小贴士

生活提示数字 1我知道你在想什么。
我的房子被飓风摧毁的概率有多大?我不记得堪萨斯的最后一场飓风了。这证明我的国营农场代理人一直在敲我的竹杠。 踩刹车一秒钟(双关语),一个好的经验法则是问自己

自我,最极端的灾难性事件对我的生活有重大影响吗?

如果答案是肯定的(比如你的房子被烧毁)那么很可能值得你花钱投保。
但是如果答案是否定的
(你有一套公寓)那么也许不值得。**

生活小贴士第二条 当你面临抉择,你不确定自己是否被骗了,而且这件事不会改变你的生活时,你可以用这个快速的“信封背面”计算来决定你是否应该买。**

也就是说,如果期望值小于成本,那么你就通过了。

感谢阅读!
我希望你在延长保修的冒险中取得成功,并记住下次你买车并面临购买保修时,只需要求将 lambda 参数插入到你的泊松分布计算器中。如果你想独自跟随,你可以在这里找到 Jupyter 笔记本。

额外问题:当你改变概率时会发生什么?

这个问题真的会把我们送进兔子洞,因为可能会发生大量的变化和可能性。但我认为很明显,如果补丁和/或井喷的概率增加,这将使我们的联合概率热图上的黑暗区域越来越接近盈利边界。但是经销商当然不会吃亏,他们只会提高保修的价格。如果每月花费 8 美元而不是 7 美元,您会动摇而不购买它吗?大概不会。**

为了证明这一点,我将给你们留下一个有趣的图表,它展示了井喷的概率和泊松期望之间的关系。随着井喷的可能性增加,一年中预期的井喷次数越来越接近经销商在赔钱之前可以处理的最大井喷次数,在某一点上,它实际上跨越了几乎保证经销商会赔钱的界限,这当然会迫使他们提高价格。

Distributions with varying values of P(blowout)

人工智能将如何帮助解决经济学中的因果问题

原文:https://towardsdatascience.com/how-a-i-will-help-address-the-causation-problem-in-economics-bdb0a7b96e35?source=collection_archive---------43-----------------------

Photo by Markus Spiske on Unsplash

大数据、人工智能、经济学

填补经济学的空白——现在用数据

几十年来,经济学家基于他们的研究助理所能处理的数据集进行研究,因此严重限制了他们工作的范围和精度。

然而,人工智能将使经济学家能够以有史以来最快的速度大幅扩大这些数据集并进行分析。随着计算能力和收集经济数据的能力的提高,人工智能算法在检测经济模式和趋势方面将变得越来越好。

因果关系是经济学家千百年来一直在努力解决的问题。你可能已经听过一千遍了,相关性并不意味着因果关系。

解释因果关系的问题使经济分析变得复杂。

当涉及到自然科学,如物理和化学,建立因果关系链相对容易:你可以建立一个实验,控制所有的变量,除了你想了解的影响。

然而,在经济学中,这项任务要困难得多。例如,如果你想评估一项特定的经济政策对国家的影响,就很难将一个事件的影响与另一个事件的影响分开。解释因果关系的问题使经济分析变得复杂,并使其不太准确,因为社会事件太复杂,不可能只因为一个原因而发生。

但 AI 非常擅长处理大量数据,并推断多个变量之间错综复杂的相互关系。经济学家的工作跨越数百万个变量:消费者、企业、政府、金融机构、监管机构。分析所有变量的影响非常困难,一方面是因为随着玩家数量的增加,推断因果关系变得更加困难,另一方面是因为数据量巨大。

伟大的物理学家理查德·费曼曾经说过

你不知道游戏规则,但你可以不时地看看棋盘,也许在一个小角落里。从这些观察中,你试图找出规则是什么。

虽然通过传统的非人工智能方法获得的数据有时可能会失败代表现实,但人工智能不会受到这种限制。它将使我们能够超越人类思维的极限来观察正在发生的事情,并提供一个更加全面和客观的经济图景。

一些经济学家已经在研究能够推断因果关系的人工智能算法。我们不再争论需求导致供给还是反向;相反,人工智能对市场参与者行为的分析将有助于为我们的问题提供数据驱动的答案。

根据具体情况,人工智能将对导致某种现象的每个因素赋予权重,从而使我们能够更好地理解经济政策对人类活动各个领域的影响。

AI 的使用无疑会带来重要的里程碑。21 世纪经济学的未来将由人工智能来定义。

进一步:

[## 人工智能将如何重新定义经济学

人工智能将标志着经济科学史上的一个转折点

towardsdatascience.com](/how-ai-will-redefine-economics-ec305e3cb687)

2D 人工神经网络中的神经元如何在 3D 可视化中弯曲输出

原文:https://towardsdatascience.com/how-a-neuron-in-a-2d-artificial-neural-network-bends-space-in-3d-visualization-d234e8a8374e?source=collection_archive---------26-----------------------

这是为那些想直观了解人工神经网络中神经元内部工作的人准备的。你只需要一点点高中水平的数学和一点点耐心。我们将构建一个简单的程序来区分苹果和橘子,然后从这里开始深入研究。开始了。

第一步:去水果市场买苹果和橘子。

第二步:我们中的一个书呆子根据两个属性给它们打分——红色和甜蜜。

瞧——我们现在有二维空间了。x 代表红色,Y 代表甜味。这就是我所说的 2D 神经元,即有两个输入的神经元。

我们大多数人都会同意苹果通常更甜更红,因此我们最终会得到一个类似下图的图表。

让我们也画一条好的线来分类他们。我们如何提出一条线的规范是另一个故事的主题,但这不会妨碍我们的可视化。

2D graph for apples and oranges on a plane (x-axis: redness, y-axis: sweetness)

但是线到底是什么?

在斜率截距格式中,为 y = mx+ c (其中 m 为斜率,c 为 y 截距)。

一切都好吗?通过一些简单的重新排列,这可以表示为

w1 * x + w2 * y + b1 = 0

如果我现在用这个方程并在它周围画一些圈,它将开始看起来像一个我们非常熟悉的整体——是的,这是我们的人工神经网络的基本构件,也就是神经元。

现在,如果我们用一个 z 代替等式中的 0,它将把我们的视觉带到一个全新的维度——我是指字面上的意思。

w1 * x+w2 * y+B1 = z

或者z =w1 * x+w2 * y+B1

这是一个 3D 平面的方程(不设猜奖)。所以 2D X-Y 轴上的任何一条线都只是平面方程被设置为 0 的特例,也就是说,它是平面与平坦的 X-Y 平面相交的所有点的集合。

Neuron intermediate output without any activation

激活情况如何?

到目前为止,我故意忽略的部分是神经元的激活,所以我们也把它放进去。我用过一个 ReLU,就是把所有的负值都换成零。所以,g(z) = max{0,z}

下面的粉红色部分是神经元的最终输出。如果床单平放在地板上,水果就是橙子。如果床单悬在空中,那就是苹果。此外,越往上,它是苹果的概率就越高。

Final neuron activation in 3D with a ReLU activation

Final neuron activation in 3D with a ReLU activation — different perspective

多神经元的这种输出弯曲看起来如何?

我正致力于本系列的下一页,将可视化带到多个神经元——一旦发表,我将添加一个链接。如果你认为我们应该选择一些其他的激活函数(比如 sigmoid)来增加趣味,请给我留言。谢谢你。

面向对象编程的简单混合如何增强你的深度学习原型

原文:https://towardsdatascience.com/how-a-simple-mix-of-object-oriented-programming-can-sharpen-your-deep-learning-prototype-19893bd969bd?source=collection_archive---------3-----------------------

通过混合面向对象编程的简单概念,如函数化和类继承,您可以为深度学习原型代码添加巨大的价值。

介绍

这篇文章不适合经验丰富的软件工程师。这是面向数据科学家和机器学习(ML)实践者的,他们和我一样,没有软件工程背景。

我们在工作中经常使用 Python。为什么?因为这对 ML 和数据科学社区来说太棒了。

它正在成为现代数据驱动分析和人工智能(AI)应用发展最快的主要语言。

然而,它也用于简单的脚本目的,以自动化东西,以测试假设,为头脑风暴创建交互图,以控制实验室仪器等。

但问题是。

用于软件开发的 Python 和用于脚本编写的 Python 并不完全是同一只野兽——至少在数据科学领域是这样。

脚本(大部分)是你为自己写的代码。软件是你(和其他队友)为他人编写的代码的集合。

明智的做法是承认,当(大多数)并非来自软件工程背景的数据科学家为 AI/Ml 模型和统计分析编写 Python 程序时,他们倾向于为自己编写这样的代码

他们只想得到隐藏在数据中的模式的核心。很快。没有深入思考正常凡人- 用户

他们写了一段代码,产生了丰富而美丽的情节。但是他们没有创造出 功能 出来,以备后用。

他们从标准库中导入大量的 方法 。但是他们没有通过继承来创建自己的 子类 并为其添加方法以扩展功能。**

脚本(大部分)是你为自己写的代码。软件是你(和其他队友)为他人编写的代码的集合。

、函数、继承、方法、类——这些是健壮的面向对象编程(OOP)** 的核心,但是如果你只想用你的数据分析和绘图创建一个 Jupyter 笔记本,它们多少是可以避免的。**

您可以避免使用 OOP 原则的最初痛苦,但这几乎总是会导致您的笔记本代码不可重用和不可扩展。

简而言之,这段代码只为你服务(直到你忘记你到底编码了什么逻辑),而不是为其他人服务。

但是 可读性(以及可重用性)至关重要 。这是对你作品价值的真正考验。不是为了你自己。但对其他人来说。

事实上,数据科学家威尔·科尔森刚刚就这个想法写了一篇精彩的文章。

** [## 从代码完成看软件构造

“代码完成:软件构造实用手册”的经验教训及其在数据科学中的应用

towardsdatascience.com](/notes-on-software-construction-from-code-complete-8d2a8a959c69)

更糟糕的是,数百种关于数据科学和 AI/ML 的流行 MOOC 或在线课程也不强调编码的这一方面,因为这对年轻、热情的学习者来说感觉是一种负担。他/她是来学习很酷的算法和神经网络优化的,而不是 Python 中的 OOP。因此,这一方面仍然被忽视。

那么,你能做什么?

您可以避免使用 OOP 原则的最初痛苦,但这几乎总是会导致您的笔记本代码不可重用和不可扩展。

简单的 OOP 组合可以强化你的深度学习(DL)代码

我不是软件工程师,这辈子从来没有过。因此,当我开始探索 ML 和数据科学时,我写了大量草率的、不可重用的代码。

渐渐地,我试图变得更好,并对我的编码风格进行简单的改进,使它们更有用(对世界上的任何人)。

而且,我发现在你的数据科学代码中开始混合 OOP 原则并不需要太多。

即使你一生中从未上过软件工程课程,一些想法也可能自然而然地出现在你面前。你所要做的就是站在别人的立场上,想想那个人会如何以一种建设性的方式接受和使用你的代码。

我说的这些到底是什么意思?让我们用一个简单的案例来演示一下——一个关于时尚 MNIST 数据集的 DL 图像分类问题。

而且,我发现在你的数据科学代码中开始混合 OOP 原则并不需要太多。

DL 分类任务的案例说明:

方法

详细的笔记本在我的 Github repo 中给出。鼓励你去过一遍,叉一下,供自己使用和扩展。

代码对于构建优秀的软件来说是必不可少的,但不一定适合中等水平的文章,你阅读这些文章是为了获得洞察力,而不是练习调试或重构。

因此,我将只选择一些代码片段,并尝试指出我是如何试图在本笔记本中对一些原则进行编码的,这些原则在前面已有详细介绍。

核心 ML 任务和高阶业务问题

ML 的核心任务很简单——为 时尚 MNIST 数据集构建深度学习分类器,这是对最初著名的 MNIST 手写数字数据集的有趣旋转。“时尚 MNIST”由 60,000 幅 28 x 28 像素大小的训练图像组成,包括与时尚相关的对象,如帽子、鞋子、裤子、t 恤、连衣裙等。它还包含 10,000 张测试图像,用于模型验证和测试。

Fashion MNIST (https://github.com/zalandoresearch/fashion-mnist)

但是,如果围绕这个核心 ML 任务有一个更高阶的优化或可视化分析问题— 模型架构的复杂性如何影响达到期望精度所需的最小时期 呢?

读者应该很清楚,我们为什么要为这样一个问题而烦恼。因为这关系到整体的业务优化训练一个神经网络不是一件微不足道的计算事情。因此,有必要调查一下要达到目标性能指标必须花费的最少培训工作量,以及架构的选择如何影响

在这个例子中,我们甚至不使用卷积网络,因为简单的密集连接的神经网络可以实现相当高的精度,事实上,需要某种次优的性能来说明我们上面提出的高阶优化问题的要点。

我们的解决方案

所以,我们必须解决两个问题-

  • 如何确定达到所需精度目标的最小历元数?
  • 模型的具体架构如何影响这个数字或训练行为?

为了实现目标,我们将使用两个简单的 OOP 原则,

  • 从基类对象创建一个继承类
  • 创建实用函数,并从紧凑的代码块中调用它们,这些代码块可以呈现给外部用户,以便进行更高阶的优化和分析

展示良好实践的代码片段

这里我们展示了一些代码片段来说明简单的 OOP 原则是如何被用来实现我们的解决方案的。为了便于理解,这些片段标有注释。

首先,我们继承了一个 Keras 类,并编写了我们自己的子类,添加了一个方法来检查训练准确性,并根据该值采取行动。

这个简单的回调导致对历元的动态控制——当精度达到期望的阈值时,训练自动停止。

我们将 Keras 模型构造代码放在一个效用函数中,这样一个任意数量的层和架构(只要它们是紧密连接的)的模型可以使用一些函数参数形式的简单用户输入来生成

我们甚至可以将编译和训练代码放入一个实用函数中,以便在高阶优化循环中方便地使用这些超参数。

接下来,是可视化的时候了。在这里,我们再次通过功能化的实践。通用绘图函数将原始数据作为输入。然而,如果我们有一个特定的目的来绘制训练集准确性的演变并显示它如何与目标进行比较,那么我们的绘图函数应该只是将深度学习模型作为输入并生成所需的绘图。

典型结果如下所示:

最终分析代码—超级简洁

现在,我们可以利用前面定义的所有函数和类,将它们组合起来完成更高级的任务。

因此,我们的最终代码将非常紧凑,但对于各种精度阈值和神经网络架构,它会生成相同的随时间变化的损失和精度曲线,如上文所示。

这将使用户能够使用最少量的代码来产生关于性能度量(在这种情况下是精度)和神经网络架构的选择的可视化分析。这是建立优化的机器学习系统的第一步。

我们生成一些案例进行调查,

对于不需要了解 Keras 模型构建或回调类的复杂性的高级用户来说,我们最终的分析/优化代码简洁易懂

这是 OOP 背后的核心原则——复杂性层的抽象,我们能够完成我们的深度学习任务。

注意,我们是如何将print_msg=False传递给类实例的。虽然我们需要基本的状态打印来进行初始检查/调试,但是我们应该静默地执行优化任务的分析。如果我们的类定义中没有这个参数,那么我们就没有办法停止打印调试消息。

我们展示了一些有代表性的结果,这些结果是通过执行上面的代码块自动生成的。它清楚地表明,如何用最少量的高级代码,我们能够生成可视化分析,以判断各种性能指标水平的各种神经架构的相对性能。这使得用户在不调整较低级功能的情况下,根据他/她的性能需求,容易地对型号的选择做出判断。

此外,请注意每个图的自定义标题。这些标题清楚地阐明了神经网络的目标性能和复杂性,从而使分析变得容易。

这是对绘图实用程序功能的一个小小的补充,但这表明在创建这样的功能时需要仔细规划。如果我们没有为函数设计这样一个参数,就不可能为每个图生成一个自定义标题。API(应用程序接口)的精心规划是良好 OOP 的重要组成部分。

最后,将脚本转换成简单的 Python 模块

到目前为止,您可能正在使用一个 Jupyter 笔记本,但是您可能希望将这个练习变成一个整洁的 Python 模块,您可以随时从它导入。

就像你写“从 matplotlib 导入 pyplot ”一样,你可以在任何地方导入这些实用函数(Keras 模型构建、训练和绘图)。

总结和结论

我们展示了一些简单的好的实践,借用了 OOP,应用于一个 DL 分析任务。对于经验丰富的软件开发人员来说,几乎所有这些都可能看起来微不足道,但这篇文章是为初露头角的数据科学家写的,他们可能没有这方面的背景,但应该明白在他们的机器学习工作流程中灌输这些良好实践的重要性

笔记本在这里

冒着重复太多遍的风险,让我再次总结一下好的实践,

  • 只要有机会,将重复的代码块转化为实用函数
  • 仔细考虑函数的 API,即需要什么样的最小参数集,以及它们将如何为更高级别的编程任务服务
  • 不要忘记为一个函数写一个 docstring ,即使它只是一行描述
  • 如果你开始积累与同一个对象相关的许多实用函数,考虑将那个对象变成一个类并将这些实用函数作为方法
  • 只要有机会使用继承完成复杂的分析,就扩展类的功能
  • 不要停留在 Jupyter 笔记本。将它们转换成可执行脚本并放入小模块。养成将工作模块化的习惯,这样任何人、任何地方都可以轻松重用和扩展工作。

谁知道呢,当你积累了足够多有用的类和子模块的时候,你可能会在 Python 包存储库(PyPi 服务器)上发布一个实用程序包。你将有权利吹嘘自己发布了一个原始的开源软件包,然后:-)**

如您有任何疑问或想法可分享,请通过tirthajyoti[AT]Gmail . com与作者联系。此外,您还可以在作者的 GitHub 知识库中查找 Python、R 或 MATLAB 中其他有趣的代码片段以及机器学习资源。如果你像我一样,对机器学习/数据科学充满热情,请随时在领英上添加我或在推特上关注我。

** [## Tirthajyoti Sarkar - Sr .首席工程师-半导体,人工智能,机器学习- ON…

乔治亚理工学院理学硕士- MS,Analytics 本 MS 课程教授理论和实践…

www.linkedin.com](https://www.linkedin.com/in/tirthajyoti-sarkar-2127aa7/)**

深度学习新手团队如何在 kaggle 竞赛中获得第三名

原文:https://towardsdatascience.com/how-a-team-of-deep-learning-newbies-came-3rd-place-in-a-kaggle-contest-644adcc143c8?source=collection_archive---------6-----------------------

利用 fast.ai 对油棕林图像进行分类

Photo by Alexander Naglestad on Unsplash

数据科学领域的妇女与其合作伙伴共同发起了 WiDS 数据马拉松。面临的挑战是创建一个模型来预测卫星图像中油棕种植园的存在。行星八字慷慨地提供了一组由行星的卫星最近拍摄的卫星图像的注释数据集。数据集影像的空间分辨率为 3 米,每个影像都根据影像中是否存在油棕种植园进行标注(0 表示无种植园,1 表示有种植园)。任务是训练一个模型,该模型将卫星图像作为输入,并输出图像包含油棕榈种植园的可能性预测。竞赛创建者为模型开发提供了带标签的训练和测试数据集。更多此处 阅读。

我和我的队友(阿卜迪沙库尔哈利玛伊欧马·奥科)在这次挑战中使用了 fast.ai 框架。非常感谢托马斯·卡佩勒🤗对于他在 kaggle 上的入门内核,它提供了关于如何解决这个问题的如此多的见解,也为 fast.ai 团队创造了一个令人惊叹的深度学习课程,简化了许多困难的深度学习概念。深度学习的初学者现在可以赢得游戏比赛😁。

让我们开始吧:一个简单易用的深度学习教程

不要担心理解所有的东西,这需要大量的练习。这个教程就是想让你看看 fast.ai 对于初学深度学习的人来说有多酷。我假设你了解一些 python,并且对 ML 有所涉猎。如果那是你;那我们就走上正轨了。

这里显示的所有代码都可以在谷歌合作实验室获得;一个免费的 Jupyter 笔记本环境,不需要设置,完全在云中运行。借助 Colaboratory,您可以编写和执行代码、保存和共享您的分析,以及访问强大的计算资源,所有这些都可以从浏览器中免费获得。点击这里访问我们将要使用的代码。

导入 fast.ai 和我们将使用的其他库

Import libraries

获取比赛数据

为了尽可能直截了当,阿卜迪沙库尔上传了比赛数据文件给 dropbox.com。你可以在比赛网页这里找到它们。你需要接受比赛规则并加入才能访问数据。

# Get the data from dropbox link
!wget [https://www.dropbox.com/s/6kltw0kqynlijxv/widsdatathon2019.zip](https://www.dropbox.com/s/6kltw0kqynlijxv/widsdatathon2019.zip)

# The downloaded competition data is zipped, let us unzip it
!unzip widsdatathon2019.zip# The training and testing data have already been seperated, Unzip them as well
!unzip train_images.zip
!unzip leaderboard_holdout_data.zip
!unzip leaderboard_test_data.zip

看着这些数据

当我们着手解决一个问题时,首先要做的是看一看现有的数据。我们需要了解问题和数据是什么样的,然后才能找到解决方法。查看数据意味着了解数据目录的结构,标签是什么,以及一些示例图像是什么样子。

Use the pandas library to read the data

The labels of the data we’ll use to train our models

处理影像分类数据集和表格数据集的主要区别在于标注的存储方式。这里的标签指的是图像中的内容。在这个特定的数据集中,标签存储在 CSV 文件中。

要了解更多关于如何计算分数栏的信息,请点击 此处

我们将使用 seaborn 的countplot 函数来查看我们的训练数据的分布。从该图中,我们可以看到大约 14,300 幅图像中没有油棕榈种植园,而只有 942 幅图像中有。这被称为不平衡数据集,这是一个深度学习问题,我们不打算在这里讨论;目前我们正在慢慢地走👶🏽。

Count of the two classes

Distribution of the training dataset

准备数据

提供的测试数据位于两个独立的文件夹中,分别是排行榜维持数据、排行榜测试数据。我们将把两者结合起来,因为比赛要求提交对两者的预测。我们组合了6534个图像。

Combine leaderboard holdout data and leaderboard test data

我们将使用 fast.ai 的数据块 API 来构建数据,这是一种将数据集呈现给模型的便捷方式。

Creating an ImageList to hold the data

  • 我们将使用一个ImageList来保存我们的训练数据,并使用from_df方法。我们这样做是因为我们将关于训练集的信息存储在一个名为df的数据帧中。我们告诉它在哪里可以找到我们的训练图像,path以及保存图像的文件夹的名称,train_images
  • 接下来,我们使用随机拆分来拆分我们的训练集。我们希望留出 20%的数据来监控模型在训练期间的表现。我们选择了一个种子,以确保我们再次检查时得到相同的结果。我们需要知道什么可行,什么不可行。
  • 我们告诉ImageList在哪里可以找到我们训练集中数据的标签,has_oilpalm并添加我们刚刚合并的数据作为测试数据。
  • 最后,我们对数据执行转换。用flip_vert = True翻转图像有助于模型识别图像,不管它们的方向如何。我们将使用imagenet_stats来标准化图像。 注意:这是一种迁移学习技巧,为了尽可能简单起见,这就是我要说的。🤐

图像预览

以下是有或没有油棕榈种植园的卫星图像:

Show 2 batches of images

Images with oil palms are labeled 1, those without are 0

训练我们的模型

现在我们训练我们的模型。我们将使用一个卷积神经网络主干,并使用来自 resnet 模型的预训练权重,该模型已被训练用于对各种图像进行分类。不要管这具体是什么意思。目前,我们正在建立一个模型,该模型以卫星图像为输入,输出两个类别的预测概率。

Convolutional neural network

Find an optimal model learning rate

接下来,我们使用lr_find()找到一个理想的学习率,并使用recorder.plot()将其可视化。

Find an optimal model learning rate

我们将选择一个接近斜率最陡的学习率,在我们的例子中是1e-2

Train model for 5 cycles with learning rate = 1e-2

我们将使用fit_one_cycle函数为我们的模型训练 5 个时期(通过所有数据的 5 个周期)。

Training and validation losses

注意显示的metricstraining_lossvalid_loss?我们用它们来监控模型随时间的改进。

我们最好的模型是在第四纪元获得的。

The output of training our model; the progression of training and validation losses

当你运行训练和验证数据集时,fast.ai 在内部只挑选和保存你的最佳模型。

评估我们的模型

根据预测概率和观察目标has_oilpalm之间的接收器工作特性曲线下的面积,对提交的竞赛进行评估。在这个开发者速成班、这个视频或这个 Kaggle 学习论坛帖子中了解更多关于 AUC 的信息。Fast.ai 默认情况下没有这个指标,所以我们将使用 scikit-learn 库。

Print out validation metrics

使用预训练模型和 fast.ai 的好处在于,你可以获得非常好的预测精度,99.44%在我们的情况下,无需做最多的事情。

The metrics for the first stage of training

让我们保存我们的模型,并绘制一个关于预测的混淆矩阵。

learn.save('resnet50-stg1')

使用混淆矩阵查看结果

Plot confusion matrix

混淆矩阵是查看模型准确或不准确预测的图像数量的图形方式。

Confusion matrix for the first stage of training

从该图中,我们可以看到,该模型准确预测了 2,863 幅图像中没有油棕榈种植园,168 幅图像中有油棕榈种植园被正确分类。包含油棕种植园的 10 幅图像被分类为没有,而不包含油棕种植园的 7 幅图像被分类为有。

对于一个简单的模型🥳.来说还不错

接下来,我们为这个训练迭代找到一个理想的学习率。

Find an ideal learning rate

We choose a learning rate that’s between 1e-6 and 1e-4

使用 7 个时期内1e-61e-4之间的最大学习速率来拟合模型。

Train model for 7 cycles, the learning rate shouldn’t exceed the range of 1e-6 and 1e-4

Training and validation losses

以图形方式观察训练指标,以在每个训练周期后监控模型的性能。

The output of training our model; the progression of training and validation losses

省去第二阶段的模型训练。

learn.save('resnet50-stg2')

Accuracy, error rate and AUC score

打印出模型的精确度、误差率和曲线下面积。

The metrics for the second stage of training

你会注意到模型的精确度从99.44%提高到99.48%。错误率从0.0056降低到0.0052。AUC 也有所改善,从99.82%99.87%.

Plot confusion matrix

与我们绘制的上一个混淆矩阵相比,你会注意到这个模型做出了更好的预测。

Confusion matrix for the second stage of training

以前 7 张没有油棕榈种植园的图片被错误分类,现在我们减少到 3 张。这就是进步。

你会注意到我们在训练中一直遵循一个模式,并在这个过程中调整了一些参数。我们一直在做的叫做调谐。大多数深度学习实验都遵循类似的迭代模式。

图像转换

我们将对数据执行更多的图像转换。这应该会改进我们的模型。每个转换的详细描述可以在 fast.ai 文档中找到:

Applying different transforms to improve our model

  • max_lighting:如果不是None,则以概率 p_lighting 应用由 max_lighting 控制的随机闪电和对比度变化
  • max_zoom:如果不是1.或更小,则以概率 p_affine 应用1.和 max_zoom 之间的随机缩放
  • max_warp:如果不是None,则以概率 p_affine 应用在-max_warpmax_warp之间的大小的随机对称扭曲

我们又找到了一个最优学习率。

Find an ideal learning rate

We chose a learning rate of 1e-6

5 个周期的训练模型。

Train for 5 cycles

Training and validation losses

比较培训指标,并与过去的指标进行比较。我们的模型在这次迭代中0.01690.0163稍差。不要绝望。

The output of training our model; the best model is at epoch 3

保存模型培训的第三阶段,并打印出指标。你会注意到,模型的精度现在是99.38%,在前一阶段是99.48%。AUC 得分从99.87%提高到99.91%,这是对竞争进行评级的指标。

learn.save('resnet50-stg3')

Accuracy, error rate and AUC score

The metrics for the third stage of training

最终培训阶段

如果你注意到我们从有size = 164的图像开始,我们逐渐建立,直到我们到达下面的size = 256。我们这样做是为了利用 fast.ai 的渐进式图像大小调整进行分类,即在训练开始时使用小图像,并随着训练的进行逐渐增加大小。这样,当模型在早期非常不准确时,它可以快速看到大量图像并取得快速进展,然后在训练中,它可以看到更大的图像以了解更精细的区别。点击这里阅读更多相关内容。

Applying different transforms to improve model, increased image sizes to 256

我们又找到了一个最优学习率。

Find an ideal learning rate

Find an ideal learning rate

使用 5 个时期的学习率1e-4拟合模型。

Train model for 5 cycles, the learning rate is set to 1e-4

Training and validation losses

观察培训指标,并与过去的指标进行比较。我们的模型做了一点改进,从0.01690.0168

The output of training our model; the best model is at epoch 2

保存模型训练的最后阶段并打印出指标。

learn.save('resnet50-stg4')

Accuracy, error rate and AUC score

正如你所注意到的,模型的精度现在是99.44%,这比上次训练阶段99.38%有所提高。

The metrics for the fourth stage of training

准备竞赛提交文件

现在我们可以看到我们的模型对尚未看到的数据的预测有多好。

Prepare a CSV submission file

向 WiDS Datathon 提交一份材料

您仍然可以参加 WiDS 竞赛,并提交一份迟交的材料。为此,请点击进入竞赛页面,点击加入竞赛并接受竞赛规则。现在你可以提交一份申请,看看如果你参加的话,你的排名会是多少。

Private and Public Scores for the submission I made from our model’s predictions.

声明:文章中的说明不会像我们一样把你放在第三位,我想尽可能保持简单。要弄清楚这一点,请查看 Abdishakur 关于它的帖子这里

好奇想了解更多?看看这个由杰瑞米·霍华德和 fast.ai 团队策划的惊人的 7 部分系列讲座。

人工智能和人工智能如何在电子商务行业产生巨大影响

原文:https://towardsdatascience.com/how-ai-and-ml-are-making-big-differences-in-the-e-commerce-industry-9eb4214ecaac?source=collection_archive---------27-----------------------

Photo by Marta Filipczyk on Unsplash

人工智能及其子集 ML 是当今最时尚的技术,对商业世界产生了巨大影响。许多行业都在关注 AI 和 ML,并发现如何利用它们的优势。两者都将帮助行业发现其系统中的低效率,智能地执行计划,基于历史趋势分析预测未来结果,以及帮助做出基于事实的决策。

电子商务公司也对人工智能和人工智能表现出兴趣。电子商务行业的专家正在寻找基于人工智能和人工智能技术的强大而实用的解决方案,以接触和影响更多的客户,使销售过程更有效,为客户提供高度个性化,等等。

让我们来看看人工智能和人工智能在电子商务行业中发挥巨大作用的一些方式。

1。让产品搜索更容易

典型的电子商务技术在展示消费者真正想看到的产品结果方面不够智能。这导致客户放弃在特定电子商务平台上搜索产品,因为在尝试了各种方法后,显示的结果往往是不相关的。

这个问题可以通过利用人工智能的子集来解决,自然语言处理可以缩小范围,融入背景,并最终改善购物者的产品搜索结果。电子商务搜索也可以通过更智能的人工智能应用程序得到改善,这些应用程序可以像你一样看待世界。它们使企业能够通过先进的图像和视频识别技术形成以客户为中心的方法。基于 ML 和 AI 的解决方案可以通过标记特定图像或视频的特征来自动标记、管理和可视化搜索。

当企业将人工智能技术引入他们的系统时,他们可以获得竞争优势。Pinterest 就是一个很好的例子,它提供了一个 Chrome 扩展,使用户能够从在线照片中选择一个项目,然后 Pinterest 会推荐类似的项目。为此,该平台使用图像识别软件。同样的解决方案也可以帮助电子商务平台,客户可以拍下他们想要购买的产品的照片,然后在平台上搜索是否有类似的产品。

2.瞄准到访但不购买的客户

每个电商平台获得的访客都比买家多。但是所有那些曾经访问过网站或应用却没有购买就离开的访问者确实总是有可能被转化为买家。问题是,通常的方法永远不会让销售团队看到它们,但 AI 和 ML 可以做到这一点。有了这些技术,电子商务企业可以重新定位潜在客户。

人工智能和人工智能将帮助企业整理大量数据,并对其进行过滤,以找到有可能转化为买家的访问者。

AI 甚至可以帮助拥有实体店的零售商。一家零售店可以通过面部识别解决方案实施基于人工智能的闭路电视摄像机,以捕捉客户在商店的消费时间。现在,如果一个特定的客户在查询产品上花费的时间超过了平均时间,但没有购买,人工智能解决方案可以建议有吸引力的报价和折扣来吸引该客户。

3。发现目标前景

有了人工智能技术,预测性营销将变得更容易,企业可以解决重大挑战,如线索的产生。Getty Images 已经尝试了类似的东西。该公司从 Getty 的竞争对手那里获取展示商业图片的数据,然后瞄准高质量的潜在客户,以产生新的线索。

4。形成高效的销售流程

人工智能和 CRM 还可以帮助电子商务企业在正确的时间,在正确的平台上接触客户。当人工智能与客户关系管理融合在一起时,管理人员回答客户查询、解决问题以及在这中间发现新的销售机会变得更加容易。AI 还可以让 CRM 系统进行多任务处理,同时处理几个功能。

5。在多种设备上打造新的个性化水平

然而,个性化在电子商务软件开发中并不是一件新鲜事,但是有了人工智能和 Ml 技术,企业为他们的客户提供深层次的个性化已经成为可能。有了深度个性化,顾客会感到快乐和满意,因为他们可以按照自己想要的方式探索商店,也可以根据自己的喜好定制商店。

人工智能和人工智能在电子商务行业发挥作用的其他方式如下:

a)。人工智能聊天机器人可以帮助客户在没有人类代表支持的情况下获得一般查询的解决方案。此外,企业不需要维持一个庞大的客户服务主管团队来解决每个客户的问题。

b)。像 AI 和 ML 这样的技术不仅适用于电子商务商店,还可以应用于增强店内体验和更好地管理库存。

c)。人工智能和语音虚拟助理也在影响客户的购买方式。一个平台也可以利用这些新时代平台。

作者简介。:Sofia Coppol 是 Rapidsoft Technologies 的数字营销专家,Rapidsoft Technologies 是一家领先的 it 咨询公司,提供全方位的 IT 服务,包括 物联网应用程序开发 、ERP 软件开发、AI 应用程序开发和大数据应用程序开发解决方案。分享就是关爱!

人工智能如何成为历史上的颠覆性技术之一。

原文:https://towardsdatascience.com/how-ai-can-be-one-of-the-disruptive-technology-in-history-1dc3f7d38cfa?source=collection_archive---------26-----------------------

人工智能正在从未来技术快速过渡到我们日常生活中的技术。从拍摄完美的照片到预测我们接下来可以在电子邮件中说什么,人工智能正在融入我们每天使用的产品和服务,以改善我们的生活,但这项新兴技术将如何影响我们未来的工作?

在所有推动企业数字化转型的技术中,人们通常认为人工智能是最具颠覆性的。由于复杂的自动化,人工智能如何扰乱人们的日常工作是毫无疑问的。

Courtesy-Freepik

人工智能正在让人们失业,无论是将工作转移到更具生产力的任务,因为自动化取代了繁重的工作。这种讨论显然很重要,因为它们错过了更大的变革故事。毕竟,数字化转型发生在每个组织和行业层面。

未表达的经济影响?

有各种各样的尝试来做出一个预测,这个预测会导致国家或全球一级的总体就业水平,在这个水平上,技能的短缺和过剩在未来的时间里是波动的。在一般实践中,就业前景可能会受到第四次工业革命的影响,在第四次工业革命中,强大的公司和投资者的决策需要当前和预测的未来产业,这可能是不可预测的经济周期数。

此外,在这种情况下,不同的经济因素可能会构成复杂的挑战,难以确定地预测未来几年创造就业和失业的可能进展。大多数预测者、分析师、开发人员、科学家、技术提供商和经济学家都在争论他们是否能够进化或加速人工智能的学习能力及其对社会的潜在影响。对此,最明智的做法将是开始准备一系列的解决方案。

人工智能正在形成新的社会结构吗?

目前,社会上许多人不知道人工智能如何改变关键的社会结构。例如,如果法律系统可以由人工智能管理和执行,这是否表明我们已经达到了公正客观的理想?或者从另一方面来说,这是否会用新秩序创造者固有的和无意的偏见来定义新秩序?如果人工智能真的取代了人类,那么人类将如何为活着的人工作?人们将如何度过他们新获得的永久闲暇时间?

对于更广泛的社会来说,由于人工智能的普及,什么实际上影响了所有职业的大规模裁员?所有这些可能只是我们人工智能的应用带来直接和意想不到的后果的几个主题,这些后果挑战了我们当前的假设和工作模式,需要在不远的将来得到解决。这些挑战需要一个包容性的、试验性的和积极主动的对策,以便看到变革的影响,并确保社会没有一个阶层落在后面。

业务面临哪些新挑战?

随着多种技术在最近的过去,企业可以奢侈地知道,他们可以等到他们准备好追求人工智能。对于许多组织来说,这可能是相对安全的,因为他们认为上市晚并不一定意味着他们的灭亡。此外,主要的短期结果推动了关注,这种文化导致许多人忽视人工智能。

courtesy-Freepik

最终,那些在大型组织高层的人很少对任何技术感到兴奋,这可能会导致一场欣赏人工智能真正颠覆性潜力的斗争。人工智能发展的指数速度表明,企业越是以数据为中心,就越有必要开始投入时间来更好地理解和分析技术。如果我们从上到下看,我们需要了解人工智能是如何进步的,与以前的破坏性进步有何不同,并掌握其实现新的和不可想象的想法和商业模式的能力。我们需要了解人工智能的真正潜力,以从我们业务中的大量数据中释放价值。此外,我们需要更加关注长期的社会影响和更广泛的社会商业规则。

企业需要更多地从战略角度思考运营决策的更广泛的社会影响,称之为企业社会责任或开明的利己主义。出现了许多问题,如如果组织开始依赖自动化,资金将从何而来?我们如何确保人类和机器之间的平衡,让科技为人类服务?明确地说,今天的商业中有一种强烈的愿望,即通过人工智能的应用来实现人的能力,并为我们最好的人才腾出时间。

此外,证据表明,绝大多数人工智能项目都有一个商业案例预测支持,即以人类的形式降低运营成本。一些人提出了高度关注,即在自动化的帮助下如此狭隘地追求成本效率会限制我们应对问题和改变客户需求的能力。然而,当我们了解新兴产业并寻求新的创新机会以在这个快速变化的竞争世界中保持领先时,人类是适应新发展的最佳选择。商业领袖权衡了通过商品化我们的产品将人性从企业中剥离出来的短期成本节约的好处,以及自动化的风险。

未来 IT 行业将如何使用人工智能?

智能机器低估人类工人的能力肯定是一种有效的威胁,但这种威胁并不强烈,除非技术工人对人工智能感到开明。确保人工智能服务于人类的一个突出方法是保持它更有益,并通过拒绝威胁更大利益的方面来利用这些利益。

这种大规模的转变可能是一个惊人的发展,但不知何故,它听起来像是以前的技术突破,如互联网,它导致了全新的经济体系和商业模式,创造了整个 it 行业。继续学习!

作者简介:

惠普·摩根是 Tatvasoft.com.au 的技术分析师,它是澳大利亚的软件开发服务提供商。他在技术领域有七年的经验。他喜欢去自然的地方旅行。

人工智能如何将“丢失的 80%”数据带回决策中?

原文:https://towardsdatascience.com/how-ai-can-bring-back-the-lost-80-data-into-decision-making-de786ad8c208?source=collection_archive---------24-----------------------

Photo by Omid Armin on Unsplash

一家物流公司的业务负责人曾告诉我,他的公司正在亏损,因为它无法有效优化承运商的运力。运营无法应对货物交付的波动;这个问题在高峰期更为突出。不优化运力会产生进一步的连锁效应:物流公司无法分配成本开销,进而无法提供有吸引力的价格,因此失去了客户。

这种情况引发了一次诊断演习;分析师们重新审视了存储在大型关系数据库中的销售数据,看它们是否能揭开消费者需求模式波动的神秘面纱。经过彻底调查后,分析师得出结论,大量销售数据(存储为发票图像)无法得到有效分析。这导致需求的非代表性观点,因此导致收入损失。

上述情况以及我从事分析咨询工作期间的其他多种情况表明,图像、语音记录、电子邮件、文本、社交媒体、网页等形式的数据(被称为“非结构化数据”)正日益成为企业洞察的重要来源。Gartner 估计超过 80%的企业数据是非结构化的。然而,(其中大部分)数据并未被企业用于决策,即“丢失 80%”的数据,从而导致盲点并影响业务成果。此外,这也让企业付出了代价:IDC 预测,到 2020 年,能够分析所有相关数据并提供可操作信息的组织将比不太注重分析的同行多获得 4300 亿美元的生产力收益。

因此,将“丢失的 80%”数据带回日常决策变得极其重要。这就是 AI 可以发挥关键作用的地方,这将是我这篇文章的重点。

导致“丢失 80%”数据的原因

R “非结构化数据未被用于决策”即“丢失 80%”数据的原因是:对现状的错误安全感,技术限制了实验和扩展的能力,机构记忆是默认的。

对于上述物流公司,以下是大量销售数据未得到有效分析的原因:

短视的见解造成了现状可以维持的错觉:

大多数分析师都接受过用于收集数据的关系数据库以及用于切片、切块和分析数据的商业智能(BI)工具的培训。这些分析师非常依赖 IT 提供的精选数据。反过来,它根据分析师经常遇到的业务问题定义数据库模式和查询。它将提取—转换—加载回答重复出现的业务问题所需的数据;并丢弃或存档其余的数据。鉴于反复出现的业务问题主要集中在大型企业客户上,这一细分市场的销售数据在数据库中组织得井井有条。然而,通过发票图像获取的许多中小企业的数据并没有填充到数据库中。

结果是,业务分析师产生的见解是基于可用的数据,而不是必要的数据(包括中小企业的销售数据);导致 目光短浅,受限于数据可用性。 性情温和的商业智能分析师让他们的业务利益相关者了解最新的销售需求预测,但不知不觉中忘记了提醒客户群的界限。

传统技术阻碍了可扩展性:

具有统计学和高级分析知识的数据科学家相对有限,他们处理高价值的业务问题,这些问题在 BI 报告中没有得到回答。这些数据科学家通常与 IT 团队合作,从关系数据库之外获取数据。在这种情况下,数据科学家分析了他们沙盒环境中的销售图像数据,并推断中小型企业的需求特征不同于大型客户。然而,这些见解并没有及时在整个客户群中推广。

鉴于对高杠杆 IT 团队的依赖,扩展见解极其耗时且昂贵,该团队试图用传统技术来实现收支平衡,而传统技术并不是为管理如此大量和多种数据而设计的。

机构知识被困在筒仓中,无法为决策过程提供信息:

在孤岛中运行的一个副产品是,这些见解经常被困在这些数据科学家的头脑中或他们的沙盒环境中。商业领袖不容易获得这些见解;即它们成为了 隐性知识,不可搜索、不具信息性

这意味着数据科学家发现的方向性洞察不会给业务利益相关者带来任何风险。

上述所有挑战意味着物流公司无法主动发现会降低其收入的触发因素。细想一下,这种情况对于当今许多企业来说并不少见。日常的商业洞察力是短视的;而这导致了未知的风险。高价值资产优先考虑高价值问题;事实证明,技术是扩展推断洞察力的限制因素。见解没有民主化;因此,研究努力付诸东流。最后,在揭露潜在的黑天鹅方面努力有限;随时可能出现的未知问题。

简而言之,企业严重瘫痪,无法从“丢失的 80%”数据中获得任何真正的价值。

需要什么来把“失去的 80%”带回来考虑?

“代表性数据——可扩展技术——技能组合”的支柱,基于业务目标设计,目标是加强重点决策。

Source: Image by Author

为了从这种“损失 80%”的数据中吸取教训,企业需要首先促进正确的基础模块,如下所示:

代表性数据世界:

他们必须根据优先的业务成果不断识别现有的和新的用例;并通过引入缺失的非结构化数据来构建真实业务环境的数字表示。这将是未来的一个重要支柱,届时人工智能等工具将利用这些数据来增强洞察力。

可扩展技术:

与此同时,他们需要灵活、开放和敏捷地添加或升级到更合适的大数据技术,这是完成业务任务所必需的。提示:找到适合您的技术堆栈。谷歌、脸书、亚马逊、网飞都有不同的技术栈,每一个都基于他们的业务需求、发展、他们拥有的技能和他们想要去的地方。

调整技能组合:

最后,也是最重要的一点,企业需要不断提升技能和/或引进相关技能,例如数据工程师、数据科学家、技术架构师,以充分利用新的数据和下一代技术组合,实现所需的业务成果。

这家自上而下的物流公司踏上了“持续变革”之旅,在这一过程中,它始终专注于代表性数据的三大支柱——可扩展技术——在技能组合中调整,按业务目标划分优先级,目标是改善数据驱动的决策。

人工智能将如何通过使用“失去的 80%”来增强决策?

人工智能可以帮助发现更深层次的见解,优先考虑那些呼吁采取行动的人;同时也便于用户利用机构记忆,从而最大限度地减少盲点。

随着代表性数据的三大支柱——可扩展技术——在 skillset 中调整为基础模块,人工智能可以开始发挥关键作用。这里是人工智能可以使用“丢失的 80%”数据增强决策的方式:

人工智能可以实现更深入的见解,从而最大限度地减少盲点

随着企业开始使用海量的非结构化数据,深度学习等复杂的人工智能算法将变得相关。深度学习和其他机器学习方法非常擅长从非结构化数据中揭示复杂模式,将有助于触发新的诊断并产生有价值的见解。这将有助于商业利益相关者最大限度地减少他们的盲点,从而最大限度地降低他们的业务风险;帮助他们对所处的环境有更好的直觉。

人工智能可以通过个性化的行动号召来扩展洞察力:

人工智能工具通常建立在大数据环境上,大数据环境具有快速扩展的能力。人工智能工具的解决方案管理通常是分散的——更接近用户组,因此最大限度地减少了对低带宽 IT 资源的依赖。这些运营转变意味着数据科学家现在可以学习新的见解,并更快地扩展这些见解,以支持日常决策。

鉴于数据收缩的半衰期,人工智能将在优先考虑各种用户角色的洞察力方面发挥重要作用;此外,触发个性化的行动号召消息,以实现及时的行动。

人工智能可以使机构记忆民主化,并提高生产率:

利用人工智能的一个结果将是,公司现在将收获一个被动的见解库。这些见解,加上人工智能支持的搜索和检索能力,将成为企业如何将其隐性知识转化为机构记忆的基石。洞察力的搜索能力将帮助分析师和数据科学家在重复和多余的工作上花费更少的时间。人工智能中的自然语言处理技术可以帮助非技术和非分析业务用户实现民主化。

总之,人工智能将有可能通过利用“丢失的 80%”数据来增强数据驱动的决策。然而,人工智能有多成功和有效,将取决于企业如何继续专注于巩固代表性数据——技术——技能组合的基础模块。

至于物流公司,它成功地引入了 AI(高级机器学习算法)来揭开决策中的盲点;并逐渐为个性化行动号召和见解搜索能力奠定基础。

原载于 2019 年 7 月 26 日http://hawkaiblog.wordpress.com

人工智能如何改善未来的工作场所

原文:https://towardsdatascience.com/how-ai-can-improve-the-future-workplace-5c1c4977f1f?source=collection_archive---------18-----------------------

人工智能和机器学习技术有望通过指导、组织和自动化工作来帮助改造下一代工作场所。它将提高员工的效率和生产力。

使用人工智能和 3D 应用程序的数据可视化能力可以使工作空间规划更加清晰。对公司来说,这将是一个有利可图的转变,尤其是在生产和营销领域。此外,客户交易已经开始享受机器人的使用,这使得 24/7 的援助成为可能。这确实是寻求重大变革的良好开端。

人工智能应用在未来工作空间的优势

人工智能应用的最重要用途是管理数据和重塑现有资源,以构建未来战略。一些重点领域是:

  • 创造满意的员工体验
  • 采用敏捷方法招聘和培养员工
  • 创建工作空间,以促进健康的环境,促进友好的文化
  • 在 HR 中使用飞行员聊天机器人
  • 帮助客户对你的业务做出积极的回应
  • 帮助准备人力资源部门的新角色
  • 为 android 和 iOS 设备提供付费或免费 VPN 的数据安全
  • 用于团队发展,而不仅仅是个人发展

人工智能应用是 IT 领域的下一个热点。许多软件公司专门致力于开发人工智能应用程序。尽管人工智能服务的成本很高,但大多数公司都喜欢用人工智能重塑他们的工作空间

因此,在我们规划未来的工作空间之前,我们必须确保采用人工智能开发服务来提高生产率。人工智能工具可以加速你的应用程序,并使你的工作自动化。

允许每个员工使用 SaaS(软件即服务)连接到云的工作环境已经就绪,只需在多个地点进行单点登录和访问。软件开发公司提供灵活的上下文多因素身份验证,以使用人工智能工具提供简单安全的工作场所。

这些公司可以选择在家或任何虚拟的地方工作。通过单点登录,您将能够建立一个“认证、授权和记帐”环境。这个过程建立了一种新的工作文化,你可以在任何地方工作。

员工生产率

这个组织的主要目标是利用最少的人力获取最大的利润。通过技术改进和自动化软件,可以毫不费力地管理办公室的多项任务,员工的工作也变得简单多了。

技术的进步是一种强大的工具,但同时也增加了工作场所的复杂性。雇员们必须熟悉新的工作系统。很少有任务比记住多个密码、运行应用程序和操作新设备更简单。

为了解决这个问题,公司可以采用一个集中式的基于云的系统,该系统可以使用人工智能工具进行操作。这将有助于建立一个员工友好的环境。人们将开始欣赏与他们一起工作的机器人,并帮助他们快速完成任务。

创造未来工作场所的主要挑战

为了克服公司在实施人工智能应用中面临的挑战,软件开发公司为其客户管理工作场所的设计和建设。

构建新工作空间的关键驱动力是灵活性、协作和沟通。代替传统的办公室。如今,组织面临的主要困难是不断增长的数据量。 AI 开发帮助管理数据,并使用数据样本提供智能解决方案。

实施中的下一个问题是公司开发人工智能应用所需的巨额预算。这就是为什么在转换到人工智能之前,公司会进行详细的分析,并确定需要实施这种新时代技术的领域。

构建人工智能应用程序的主要目标不是增加成本和减少人力,而是让组织能够发展并在业务中获得更多利润。一项调查显示,谷歌和类似亚马逊的公司在为其客户服务引入聊天机器人后,其盈利能力可以提高 69%。

有三个主要因素是采用人工智能应用的障碍。他们是;文化、复杂性和信心

人工智能工具给公司现代化的工作文化带来了重大变化,这些变化不是一天之内发生的。实现新技术的兴奋是诱人的,但对于人工智能的发展,你必须把注意力集中在最受影响的领域。

与机器人和机器一起工作并不像看起来那么容易。这些机器要靠指挥才能操作好。通常,机器语言和自然处理语言用于控制机器人和其他基于人工智能的机器

执行完成后,各公司必须自行运作。为此,员工必须接受培训。许多公司在财务预算紧张的情况下,还没有准备好进行这项支出。

无论今天的情况如何,为了解决复杂的编程和数据管理问题,需要寻找一种解决方案,这是一个事实。人工智能工具具有这种能力,因为它们提供快速的数据分析来得出结论。好消息是,许多专业人士正在致力于降低人工智能设备的成本。

现代工作空间将通过人工智能和机器学习服务来实现。从基本的办公室工作到云安全等安全层,控制权将掌握在人工操作的机器人手中。一些大型组织已经意识到这个事实,在不久的将来,人工智能工具将成为必需品。因此,他们已经开始做同样的准备。

在转向人工智能应用之前,组织必须确保对数据进行适当的备份,因为人工智能工具和机器学习服务从根本上改变了工作系统。此外,分阶段实施是优选的。

目前,人工智能应用程序仅用于为工作场所中的大型组织提供服务,但初创公司和中型公司也可以通过访问网络管理、办公室管理工具等人工智能工具来享受好处。

经济波动肯定会在顶级人才搜寻中造成混乱。人工智能将在人力资源中发挥更大的作用,因为人工智能机器将不带偏见。他们将带来一种以技能为基础、不受身体因素影响的文化。

今天,几乎每个行业都在应对金融危机。每个部门都有保留和波动。机器学习服务等下一代技术的使用将通过隔离和预测单个组织的未来范围和性质来稳定市场。这是业界期待已久的最终结果。这样,企业将能够确保我们组织的安全存在。

展望未来

是时候让组织为让你的公司与机器人和机器人相协调而兴奋了。新兴的组织必须全心全意地接受更好的工作空间的变化。人工智能即服务(AIaaS)帮助组织确定自己的优势和劣势,为采用人工智能革命做好准备。这些服务可以轻松地与您现有的系统集成。你可以随时接近领先的人工智能开发和机器学习服务公司,确保你的公司凭借人工智能取得成功!

人工智能如何让你成为总统

原文:https://towardsdatascience.com/how-ai-can-make-you-the-president-4756f6b1c0c0?source=collection_archive---------14-----------------------

对于希望获得更高权力的政治家来说,理解人工智能技术有着巨大的力量——无论道德如何。

今年是 2012 年。《大破天幕杀机》正在影院上映,Psy 的《江南 Style》正在音乐排行榜上打破记录,巴拉克·奥巴马即将连任美国总统。

美国总统竞选已经接近尾声。民主党候选人巴拉克·奥巴马和共和党候选人米特·罗姆尼一直不分上下。最终,就像通常的情况一样,它归结为几个摇摆州。每一张选票都很重要,因为巴拉克·奥巴马执行了政治史上最大的人工智能(AI)行动。四年后,唐纳德·特朗普(Donald Trump)通过更大规模地使用人工智能战胜了希拉里·克林顿(Hilary Clinton),在接下来的几年里,欧洲各地的各种领导人也将人工智能纳入了他们的竞选战略。就像商业公司通过机器学习瞄准消费者一样,政治家也会这样做——无论道德如何。

这份工作的合适人选

对于乔治·r·r·马丁来说,选择统治者很容易。他只要写下来,谁都可以坐上铁王座。对于巴拉克·奥巴马来说,事情稍微复杂一点,但是他发现了一个人可以做类似的事情。奥巴马为他的竞选团队聘请了一位机器学习专家:Rayid Ghani。加尼使用分析工具从社交媒体和其他来源收集选民数据,以预测个体选民支持奥巴马的可能性有多大,他们是否容易被说服投票给其他人,以及他们在选举日来到投票站的可能性有多大(Domingos 2017)。他的团队每晚运行 66,000 次模拟,根据结果,他们确切地知道该敲什么门,给谁打电话,说什么。

罗姆尼队只能看着。他们可以看出奥巴马团队在非常具体的领域开展了竞选活动,但他们不知道为什么。他们可以看出,奥巴马团队正在非常具体的社区挨家挨户地敲门,但他们不知道为什么。他们可以看出奥巴马团队在给特定的选民打电话,但同样,他们也不知道为什么。当罗姆尼团队在询问人们他们将如何投票时,奥巴马团队不用费心去问就在收集答案。

奥巴马团队赢了。

Cleisthenes first suggesting democracy to the Athenian assembly (508 BC, colorized).

我知道你是谁

在这一点上,你可能很清楚公司是如何研究你的数据并根据你的身份推荐产品和服务的,为什么政治家不会这样做呢?营销人员可以利用无数的数据在社交媒体或其他地方锁定你,以说服你购买某种产品。这样的变量包括你的搜索历史,你的购物行为,你的位置,你的年龄,你的工作,你分享什么,你写什么,你喝什么,你是否吸烟,你是外向还是内向,你的朋友是多还是少,等等。大约 300 个数据点是准确了解你是谁所需要的。剑桥分析公司(Cambridge Analytica)是一家为唐纳德·川普(Donald Trump)和英国退出欧盟脱欧运动赢得胜利的组织,该组织使用多达 5000 个数据点,为美国成年人创建了 2.2 亿个个性档案(Anderson 2017)。

社交媒体是收集人们数据的最佳场所,同样也是开始用广告瞄准用户的最佳场所。收集的数据和社交媒体上展示的广告是在个人层面上完成的,这意味着两个邻居看到的广告大不相同,尽管他们在地理上毗邻而居。每个人都有专门为他们制作的广告。广告的图形可能会有所不同,这取决于您更有可能点击的内容。文章可以用不同的风格来写:有些是喜剧性的,有些是严肃的,有些使用逻辑论证,有些使用情感论证,有些使用简单的语言,而有些使用复杂的语言。

如果这个人已经强烈支持你的政党,你可以提到与候选人有关的正面消息,鼓励他记得去投票。另一方面,如果这个人强烈支持你的对手,并且很难说服他站在你这边,你可以通过强调对方其他不太受欢迎的候选人,或者通过强调他们喜欢的领导人犯的错误,试图说服他们少投一票。你的政治对手甚至永远不会知道你的广告是什么样子,因为你控制着谁能看到他们,谁不能。这就是现代宣传不可思议的力量。

Data tells you exactly who your readers are, but you don’t need data to figure out that your readers love pictures of cats. I mean, what kind of monster doesn’t like cats? Photo by Amy Chen.

有选择地使用你的人力资源。大多数广告平台为你提供工具,让你检查转化率。使用这些数据来决定把你的志愿者派到哪里,他们会在哪里产生最大的影响。对奥巴马来说,这是关键。如果你身边有志愿者,充分利用他们。

这种有针对性的广告系统也允许政客们做出不一致的承诺——如果你愿意的话,也可以说是谎言——这些承诺和谎言的展示取决于相关的个人。然而,如果你想走上这条谎言之路,你必须非常非常小心。如果通过微目标收集公民数据和操纵意见在道德上还不够糟糕,那么传播不真实的信息可能是引爆点。

谎言的网络

机器人,或虚假的社交媒体档案,是以传播政治宣传为目的的机器人。今天,社交媒体包含了大量的机器人网络。一旦一个人在社交媒体上喜欢了一个帖子,一个机器人就会在互联网上跟随他们,在其他看似无关的网站上为他们提供有针对性的广告。未来的总统可以利用机器人迅速传播他们的宣传。

事实上,机器人是一种传播新闻的极好方式,通常是假的,通过使新闻看起来足够受欢迎,它们对人类来说似乎是值得信任的。当一篇伪造的新闻文章首次上传时,它会受到来自机器人的赞和分享的轰炸,直到它看起来足够可信,真正的用户也开始与它互动。最终,更多的分享和喜欢来自人类用户。机器人只需要启动新闻。

Hey, not all bots are bad. Some can order you pizza. Photo by Vita Marija Murenaite.

给人们他们想要的

上述技术针对个人和非常特定的人群,但自然地,机器学习工具也可以用来收集共识。为了做出受欢迎的决定,并把自己树立为一个良性的政治家,你可以使用人工智能来了解你的选民想要什么,而不必用提问来打扰他们。如果机器学习模型(算法)足够好,你可以在任何时间点了解大多数人想要什么。呼吁对这个国家的每一个问题都进行漫长而昂贵的投票是不可能的。人工智能使你能够简单地运行一个查询,想运行多少次就运行多少次,并在任何给定的问题上取得一致意见。

我不需要你

在这一点上,你可能会对自己说:Jacob,这很有趣,但是 AI 真的决定政治胜利吗,或者我已经被点击诱饵了?有无数的其他因素影响着选民的决定,此外,并不是每次选举都势均力敌。另外,我绝不会听信假新闻或政治广告——我知道我在投什么票。

说得好,但实际上,许多选举的胜利幅度只有百分之几(Planet Money 2019)。虽然可能不受有针对性的政治议程的影响——而是选择通过探索广泛的来源和检查任何特定问题的所有方面来找到某种真相——但没有必要。在一个一百人的房间里,只有三个人需要受到影响才能改变选举的结果,你肯定能想到三个人会受到影响?

此外,今天使用的机器学习技术和方法仍然相对年轻,我们才刚刚开始发现这些算法的真正潜力。随着机器学习算法变得越来越复杂,它的影响力也会增加。

29 darts could miss the bullseye, as long as the 30th dart lands. Photo by Artur Matosyan.

数据科学家掌权

未来的赢家不一定是那些想法最强、钱最多、数据量最大的人(数据是免费的,无处不在!),而是那些拥有最精确数据模型的人。这很可怕,很难完全理解,很容易低估,也许很难相信,但人工智能在政治中的重要性只会越来越大。人工智能是当今民主的最大威胁,也是任何想要赢得选举的人最强有力的工具。

你可以成为总统。

你需要的只是正确的算法。

参考

安德森 2017。Berit Anderson 写了一篇出色的文章,深入探讨了政治机器人的主题:https://medium . com/join-scout/the-rise-of-the-weapon ized-ai-propagation-machine-86 DAC 61668 b

多明戈斯 2017。我第一次了解奥巴马使用 AI 是在佩德罗·多明戈的杰出著作《大师算法》(2017)中。在这个特殊的问题上,他没有比我说得更详细,但是这本书对于任何对人工智能感兴趣的人来说都是一个惊人的读物。

星球货币 2019。播客《星球货币》(Planet Money)(由 NPR 运营)在 2019 年 5 月 25 日播出了一集关于利用定向广告干预选举的节目:“#915:如何干预选举”。

对人工智能感兴趣?这里还有一些你可能会喜欢的文章。

[## 我的手很凉

也是一般人工智能的例子。

towardsdatascience.com](/my-hand-is-pretty-cool-48373b5dc37a) [## 谁是终结者?

Deepfakes 将成为人类的巨大威胁,AI 创造 deepfakes 和 AI 检测 deepfakes 的竞赛…

medium.com](https://medium.com/swlh/who-is-the-terminator-c5135890651b)

人工智能如何改变物流行业

原文:https://towardsdatascience.com/how-ai-changes-the-logistic-industry-3d55401778d?source=collection_archive---------11-----------------------

了解人工智能用例、有前途的初创公司等

由于人工智能或人工智能的发展,物流行业和供应链发生了很多变化。这项强大的技术带来了预测分析、自动驾驶汽车和智能道路等变革。

因此,我们决定讨论人工智能在物流领域可以解决的 5 大问题。此外,有几个实施人工智能的创业公司。

物流中的人工智能用例

由于最近的研究,在供应链中实施人工智能可以让公司每年获得 1.3 万亿到 2 万亿美元的收益。

谷歌、亚马逊、英特尔等很多企业开始将资源投入到人工智能领域。实际上,这项技术可以节省时间和金钱,因为它提供了各种耗时过程的自动化。

现在是时候来看看人工智能在物流领域的用例,以及讨论已经定期使用这项技术的公司了。

#1.自动化仓储

如今,人工智能有转变仓储业务的趋势,如收集和分析信息或库存处理。因此,人工智能有助于提高效率和获得利润。它是如何工作的?人工智能用于预测某些产品的需求。之后,该公司将需要的物品运送到地区仓库,降低了运输成本。

Vero Solutions 称,未来几年,公司可以自动化 30%的仓储任务。

此外,具有人工智能的系统可以管理工作以及完成各种日常任务。我们准备了一个公司的例子,该公司已经将人工智能应用到仓储系统中,并获得了一些利润。

奥卡多。这是一家位于英国的网上超市。这家公司开发了一个自动化仓库。有一种叫做“蜂巢网格机器”的机器人完成订单的速度比工人快得多。这些数字是疯狂的。在一周内,“蜂巢网格机器”可以完成 65,000 份订单或替换 350 万件杂货。这些机器人帮助搬运、举起和分类东西。之后,Ocado 的员工打包并发送订单。因此,发送订单所需的时间减少了。

自动化仓库倾向于使用计算机视觉。这项技术允许识别和组织项目。此外,在未来,计算机视觉将有助于在没有人监督的情况下管理质量控制。如果供应链中有几个仓库,人工智能会将它们连接起来,以便找到运输库存的最佳方式。

#2.自动驾驶汽车

人工智能对交通有利可图。自动驾驶汽车给供应链带来了变化,并有助于降低物流费用。当然,我们知道无人驾驶汽车,但人工智能允许更多的车辆自动化。例如,卡车、货车或公共汽车等运输工具也可以实现自动化,以便运输货物。这种车辆可以单独工作,也可以与人合作。然而,在许多国家,政府认为驾驶员必须在车内才能完全控制道路上的情况并分析可能的风险。当然,这种说法未来可能会有所改变。

Waymo 。2018 年 12 月,这家公司已经集成了一项利用自动驾驶汽车的出租车服务。这项服务在亚利桑那州凤凰城的郊区运作。如今,Waymo 试图制造无人驾驶卡车。该公司想让卡车运输更安全。该公司的收入预计到 2030 年将达到 1140 亿美元。

劳斯莱斯。这家企业与英特尔合作开发自主船。自 2010 年以来,罗尔斯·罗伊斯一直在创造这项技术。于是,情报意识在 2018 年发布。这个工具有几个有趣的特性。例如,它可以识别和定义水中的物体,监控发动机状况,并选择最佳路线。因此,交货速度变得更快。

无人驾驶技术可以给物流带来很多好处。例如,利用自动驾驶汽车,人们有机会减少燃料使用,优化路线以及避免人为错误。

#3.智能道路

除了无人驾驶汽车,AI 在物流领域还有一个用例。几家公司正在致力于建设智能道路。这些公司倾向于创建各种解决方案,以满足地区需求。

例如,有用太阳能电池板和 LED 灯开发的道路。物流部门的利润是什么?这种高速公路可以发电或使用彩色灯来提醒司机注意不断变化的路况。另一个好处是太阳能电池板的加热能力。因此,冬天路面不会滑。

所有提到的好处导致智能道路对物流领域有用的结论。因为在供应链中没有由于不适当的天气条件造成的交货延迟。

综合巷道。该公司因创造智能路面系统而闻名。为了测试这项技术,Integrated Roadways 的所有者已经与科罗拉多州交通部签署了一项协议。智能路面系统有几个有用的特点。首先,它能够将路上的汽车连接到互联网。因此,驾驶员可以获得关于交通堵塞、事故等的实时信息。此外,创造者认为他们的系统可以“感觉”每辆车的位置,并为司机提供详细的导航。

Image by Author

#4.后台操作的人工智能

后台运作对物流部门至关重要。人工智能和机器人流程自动化(RPA)等技术可以让员工加快工作流程。例如,有一些数据相关的任务每天都在重复。它们可以自动化。由于后台办公自动化,拥有供应链的公司可以节省时间和金钱。

人工智能和 RPA 的结合创造了一种叫做认知自动化的技术。因此,公司有机会节省时间,提高生产率和准确性。这项技术的主要目的是取代某些类别的员工,如会计、人力资源等。由于这种替换,人为错误的数量将会减少。

UiPath 。这家公司专门生产机器人设备。据老板称,如果员工要求,机器人可以完成 99%的任务。这是因为 UiPath 的机器人可以“看到”屏幕元素。

最新的研究声称机器人可以管理 22%的律师工作。当然,阅读协议和识别风险条款等任务是很费时间的。人工智能支持的合同管理软件是一个节省时间和提高准确性的机会。LawGeex 声称人工智能应用程序显示出 94%的准确率,而人类律师只有 85%。此外,该系统审查合同的速度更快。根据同一项研究,软件只需要 26 秒,而人却要花 92 秒。

勒弗顿。这家公司开发人工智能软件。例如,有一款合同分析软件可以管理协议并支持大约 30 种语言。此外,可以教这个工具从文档中提取必要的信息。Leverton 声称这项技术可以节省 30%到 50%的工作时间。

#5.人工智能预测需求并改善客户体验

物流领域的人工智能有一个非常明显的用例。这项技术可以帮助预测需求。

当然,公司需要预测货物的大概数量,以加快交货速度。在另一种情况下,如果商品数量有限,但需求很高,企业将会损失一些钱。

有一些算法可以预测趋势。根据最近的研究,基于人工智能的工具往往比人类专家预测得更好。
人工智能允许跟踪必要的因素,以提高需求预测的准确性。之后,这些信息可以使仓库管理更容易。

此外,人工智能改善了客户体验。由于这项技术的实施,客户可以获得更加个性化的体验,从而更加信任公司。

DHL 。亚马逊和 DHL 包裹已经签署协议。他们合作是为了增加客户体验。因此,亚马逊创建了一个名为 Alexa 的语音服务。它被教会回答关于包裹的问题,例如装运细节、去向等等。Alexa 使用起来相当简单。这个人可以问 Alexa,我的包裹在哪里?’并接收所有必要的细节。

Image by Author

正如你所看到的,在物流领域有大量的人工智能用例。如今,这项强大的技术正在发展,以改善物流和供应链。人工智能允许自动化需要大量时间的常规任务。

物流领域基于人工智能的初创公司

创业公司带来很多创新。因此,我们创建了一个列表,列出了几家尝试将人工智能集成到物流中的有前途的初创公司。

6 个河流系统

6 河流系统在仓库自动化上工作。该公司创造了一个名为查克的机器人。创造者使用了类似于自动驾驶车辆的技术。恰克连接到了管理系统。这个机器人可以完成诸如收拾东西、计数甚至分类等任务。

而且,Chuck 是无线的,可移动的。因此,它很容易在箱子之间转移,甚至可能在员工或设备上路时减速。

轨迹机器人学

又一家想自动化仓库的创业公司。Locus Robotics 制造移动机器人,使电子商务运营变得更容易。该公司的机器人名为 LocusBot。

该机器人有一个集成的触摸板为基础的用户界面。因此,培训员工与 LocusBot 合作所花费的时间减少了。

轮回学

Transmetrics 帐篷,为交通和物流行业打造 AI 解决方案。该公司为客户提供现代技术,如预测优化、高级预测等。因此,公司的运营效率更高。

Image by Author

瓦莱伦

运输领域需要现代技术解决方案。瓦勒兰开发了一套智能道路系统。这是一个收集高分辨率信息的无线网络。这些数据存储在云中并进行分析。因此,基于人工智能的算法为跟踪路况和预测高速公路上的情况提供了机会。

Image by Author

擎天柱骑行

有许多创业公司致力于创造无人驾驶汽车。Optimus Ride 构建软件和硬件解决方案,可与任何车辆类型配合使用。该公司的领导声称,他们的解决方案适用于许多场所,如住宅社区、工业园区、机场等。

Image by Author

希波

这家公司专门为市场、仓库以及电子商务公司开发解决方案。初创公司的最终目标是创建一个技术解决方案,为用户提供最合适的交付选项。因此,运输过程将变得轻松舒适。Shippo 已经创造了一些解决方案,例如,客户可以获得个性化的跟踪数据,定制交付等。

Image by Author

所以,我们刚刚讨论了六家在物流领域和供应链中集成人工智能的有前途的初创公司。每个公司都使用一种独特的方法来实现人工智能。当然,这个列表并不完整,可以扩展到更多的创业公司。

人工智能可以为物流部门带来好处。首先,这项技术提高了任何物流操作的有效性和准确性。其次,AI 允许自动化耗时的任务,并降低最终成本。

人工智能如何促进有声读物行业的繁荣

原文:https://towardsdatascience.com/how-ai-contributes-to-the-audiobook-industry-boom-2cc5406331eb?source=collection_archive---------18-----------------------

有声读物的销量近年来一直在飙升,音频出版商协会(APA) 报告称,2018 年,美国出版商销售了约 9.4 亿美元的有声读物,比 2017 年增长了 24.5%。APA 还指出,2018 年 91.4%的收入来自数字格式销售。这显示了数字媒体对有声读物行业增长的巨大影响。

多亏了 Audible 这样的平台,有声读物现在变得更加容易获得。用户可以在手机上听有声读物,将其连接到汽车上,在平板电脑、笔记本电脑和智能扬声器上听。它甚至会自动记住用户在有声读物中的位置,并通过他们的所有设备进行同步。

人工智能在当今有声读物行业的应用

最近,因其人工智能功能而陷入困境。美国五大出版商起诉 Audible 的字幕功能。公司今年夏天宣布的功能使用机器学习将有声读物转录成文本。因为有声读物许可证与电子书许可证是分开的,出版商声称这是侵犯版权。考虑到版权限制,人工智能在有声读物中的这个用例似乎有争议,但如果双方能够达成版权协议,它可能会在不久的将来成为有声读物平台的一个合法部分。

Audible needs no introduction; it’s the most popular audiobook platform owned by Amazon.

字幕功能可能对使用有声读物学习语言的用户特别有用。据路透社报道,语言学习行业本身就有巨大的收入,预计到 2024 年,英语学习的全球市场规模将达到 220 亿美元。

Audible 利用人工智能的另一种方式是对有声读物的个性化推荐。就像所有主流流媒体平台一样,该平台使用用户的有声读物收听历史来提供更好的建议,以便他们总是有东西可听,并尽可能长时间地订阅。

虽然网飞在电影和节目中使用自动生成的个性化缩略图,但我们还没有在有声读物平台上看到这种用例。但是谁知道呢,也许对于那些以貌取人的人来说也是如此。

人工智能为您带来有声读物的新机遇

自动化有声读物旁白

虽然人工智能还远未达到人类表演的质量,但它已经能够模仿人类的语言。人工智能有助于推进文本到语音转换技术,听起来像自然语音记录。NaturalReader 是一款免费的在线文本到语音转换器,它是制作听起来很自然的语音记录的工具之一。 Animaker 甚至允许用户定制人工智能生成的语音记录,通过插入短暂的停顿和呼吸,使其听起来像真人说话。

NaturalReader is a text-to-speech tool that can create natural-sounding voice recordings.

让人工智能文本到语音转换听起来像人类已经被科技巨头解决了一段时间。苹果、谷歌、微软和亚马逊都在努力让他们的人工智能私人助理的声音听起来更像人类。正如《科学美国人》的文章所述,这些系统通过连接预先录制的文件中的单词和短语来工作。但这不足以让它们听起来很自然。没有人类说话的细微差别,比如我们说话时的停顿和呼吸,这些系统听起来像机器人。这就是深度学习进入场景的地方。通过分析不同的人类语音记录,AI 可以学习模仿细微差别,使语音听起来更自然。

创建有声读物的简短摘要

随着 Blinkist 这样的应用程序(所谓的浓缩阅读平台)越来越受欢迎,人工智能在有声读物市场上迎来了新的机遇。有了人工智能,亚马逊和 Audible 这样的平台可以使用人工智能为不想在一本书上投入时间的人创建书籍的简短摘要和关键要点。像 Blinkist 这样的平台的存在,最近筹集了 1880 万美元的资金,表明人们对书籍的短版有需求,这可能是有声读物的绝佳机会。

Blinkist is a book summary platform that offers key takeaways from non-fiction books.

毫不奇怪,已经有工具试图使用人工智能来做到这一点。AISummarizer 是一个免费的在线工具,你可以粘贴你的文本并得到一个摘要版本。它让用户根据百分比选择文本应该减少多少。

讲述人口音和声音调整

TechCrunch 报道近日,亚马逊申请了一项音频系统的专利,该系统可以检测说话者的口音,并根据听者的口音进行调整。这项技术对有声读物行业也有潜力。想象一下,听一本有声读物,有一个功能,你可以选择叙述者的口音。虽然听起来有些牵强,但当您发现一本有趣的有声读物,但讲述者的口音让您很难听下去时,这个功能会很方便。

或者如果你想要一个熟悉的声音给你读这本书呢?这也有人工智能的解决方案。彭博最近采访了 Lyrebird 的团队,这是一家利用人工智能克隆人类声音的初创公司。为了实现这一目标,他们正在使用上述深度学习技术来分析一分钟的语音记录,并创建一个人工智能版本,可以操纵它说出你输入的任何类型的文本。它甚至保留了口音。在错误的人手中,像这样的工具可能会产生破坏性的后果,而另一方面,它也可能有伤感的用途,比如怀旧和听妈妈给你读童话。

Lyrebird AI is an AI tool that lets users create a voice clone by just using a one-minute voice recording.

有声读物现在正在兴起,很快竞争对手就会希望以独特的功能脱颖而出。无论是呈现享受有声读物的新方式,还是仅仅改进生产流程,AI 都可以为这个行业提供很多东西。现在,我们只能等着看有声读物的下一步。

ByMax KalmykovVP,媒体&娱乐 数据艺术

人工智能如何实现更智能的索赔处理和欺诈检测?

原文:https://towardsdatascience.com/how-ai-enables-smarter-claims-processing-fraud-detection-e65a8b2997a6?source=collection_archive---------9-----------------------

人工智能技术已经很好地真正改革了信息系统,使它们更适应人类,同时显著改善了人类和计算机系统之间的交互。

凭借这一点,保险业内的人工智能通过使索赔管理过程更快、更好、更少的错误而彻底改革了索赔管理过程。保险公司现在可以选择通过以下方式利用该技术来实现更好的索赔管理:

  • 促成实时 Q & A 服务第一时间通知丢失情况。
  • 自动执行损失评估流程的同时,对索赔进行预评估。
  • 通过丰富的数据分析自动检测索赔欺诈。
  • 预测理赔量模式。
  • 增加损失分析。

从全天候提供快速客户服务的智能聊天机器人,到通过自动化功能改善任何工作场所运作的一系列机器学习技术,人工智能在保险领域不断扩大的潜力已经在许多方面得到应用。

随着对人工智能在保险行业中改变游戏规则的影响的认识和资源的增加,最初的犹豫和围绕其实施的浅层不适现在正在迅速消退,因为它开始相信人工智能和机器学习带来的能力和无数机会。唯一的问题是——我们能把它的能力推进到什么程度?

AI 在保险行业的角色

2017 年,人工智能通过快速创建受控的数字化增强自动化环境来实现最大生产力,在各种商业垂直领域展现了其实质。

显然,特别是保险公司,可以从投资人工智能技术中受益匪浅,这种技术不仅可以自动安排执行层面的任务,还可以通过帮助代理人做出正确的决策和无可辩驳的判断来提高服务质量。

人工智能支持的创新和解决方案一瞥

如今,保险公司面临三大挑战:

  1. 在正确的时间接触潜在客户。

2.提供适合客户需求的合适产品。

3.为忠诚客户提供最快的索赔支持,拒绝虚假索赔。

保险公司正在努力开发一种技术先进的系统,帮助所有员工保持同步。这些员工从代理人、经纪人、理赔调查员到市场和支持团队不等。这些员工加上冗余的流程在保险生态系统中产生了层层混乱。

为了使系统更加完善和高效,他们应该选择稳定和一致的人工智能解决方案,这些解决方案可以穿透混乱的层面,并向客户提出明确的价值主张。保险行业的人工智能提供了几种有前途的技术支持解决方案:

  • 不间断的商业信息流

许多行业已经适应了不断变化的数字技术环境,并创造性地整合了自动化和机器人技术,以重塑其生产渠道和非同步结构。一些已经体验并利用了人工智能力量的行业有酒店业医疗业客户服务电子商务等等。

保险公司和保险公司被成堆的数据和许多其他分散的管理部门包围的事实并不新鲜。

利用人工智能的数据处理能力,保险公司可以建立一个战略性的复杂环境,在这个环境中,与业务和客户交互有关的信息可以在一个公共平台上从一个特定部门流向另一个部门,而没有任何连锁中断。因此,保险公司不仅为他们的员工组织任务管理,而且在许多方面,它有助于提高端到端信息管理系统的质量。

  • 自动化索赔支持

可以实施基于人工智能的聊天机器人来改善由多个员工运行的索赔流程的当前状态。在人工智能的驱动下,无接触保险索赔流程可以消除过多的人工干预,并可以自行报告索赔、捕获损失、更新系统和与客户沟通。这样一个轻松的过程会让客户毫不费力地提交索赔。

例如,人工智能支持的索赔聊天机器人可以审查索赔,核实保单细节,并在向银行发送电汇指令以支付索赔结算之前通过欺诈检测算法。

这是一个最好的例子,说明使用标准文档的索赔可以最大限度地减少人工工作,并可以由机器人审查,从而为保险巨头节省劳动力并提供即时客户援助。此外,人工智能支持的自动化索赔支持系统可以通过识别索赔报告中的数据模式,将公司从昂贵的欺诈性索赔、人为错误和由此产生的不准确性中解放出来。

  • 保险聊天机器人的互动能力

由于冗长的文件,复杂的政策和繁琐的指示,客户往往会产生恐惧症,并感到困惑和气馁的想法解决保险政策。他们需要类似人类的互动,既能进行顺畅的交易,又能接受教育。

智能聊天机器人超越了保险代理人的能力,在客户设备上的消息应用程序中充当虚拟助手。为了深入了解客户的查询,聊天机器人应该有 NLP 支持以及情感分析,以评估客户的反应并相应地解决问题。

客户可以输入或使用他们的声音来传达他们对不同政策的关注,聊天机器人可以处理这些政策以提供个性化的解决方案。从与索赔相关的基本问题开始,聊天机器人可以做更多的事情,如产品推荐、促销、线索挖掘或客户保留。这些机器人可以与你选择的渠道(网站、脸书、Slack、Twitter 等)整合。)为客户提供报价、保单解释和购买保险的指导。

  • 提前承保

物联网和跟踪设备会产生大量有价值的数据,这些数据可用于使确定保险费的流程变得合理和规范。健康和汽车保险领域的健身和车辆跟踪系统产生了动态、智能的承保算法,这些算法巧妙地控制了保费的确定方式。使用人工智能和机器学习,保险公司可以节省大量核保过程中涉及的时间和资源以及繁琐的问题和调查,并使这一过程自动化。

保险机器人可以自动探索客户的总体经济和社会概况,以确定他们的生活模式、生活方式、风险因素和财务稳定性。金融模式更有规律的客户有资格通过低保费感到安全。由于人工智能更有能力严格审查收集的数据,它可以预测所涉及的风险金额,保护公司免受欺诈,并向客户提供合理的保险金额。

总部位于美国的初创公司 MetroMile 已经建立了一个名为“每英里付费”的动态核保系统,根据该系统,汽车的使用情况决定保险费。在这里,该公司安装在车辆上的一个基于人工智能的设备使用一种特殊的算法来监控英里数、颠簸、碰撞和摩擦、速度模式和其他汽车在路上的挣扎,它收集详细的数据,这些数据对于决定司机是否应该获得低保费至关重要。

  • 前瞻性措施的预测分析

由机器学习支持的预测分析现在可能是许多采用人工智能解决方案的垂直商业领域智能服务的核心。然而,这种智能功能不仅仅旨在推动对客户偏好的未来洞察并定制相关产品。健康保险公司正在推出奖励性的先发制人的护理,重点是鼓励客户照顾好自己的个人健康。如果一个人保持健康,公司不需要在索赔支付和管理过程中投资。

例如, Aditya Birla 健康保险计划了健康福利,鼓励客户保持健康。人工智能的预测算法扫描过去一年的索赔活动和住院数据,以激励客户改善健康状况。这样,健康风险将被最小化,公司的资源也将被最小化。

因此,如今,初创企业利用人工智能的独特潜力来搜索成堆的索赔数据和覆盖模式,以更加积极主动地预测个人层面的健康风险,以免它们实际发生。

  • 营销及相关产品

营销是保险公司的另一个行动工具,他们希望扩大自己的覆盖范围,确保获得更多的客户。作为竞争市场的一部分,保险公司需要利用一种重要的营销策略,这种策略超越了传统的电话推销方法。

旧的一揽子方法濒临灭绝,因为数字颠覆已经动摇了保险领域的基础。如今,客户寻求复杂、奢华和极具个性化的定制销售策略服务。在保险行业中使用预测分析、NLP 和 AI 的组合能力,代理可以获得客户和潜在客户的完整资料。可以对这些数据进行进一步分析,以产生成熟的洞察力,准确预测客户偏好,以及在他们的营销活动中应该添加哪些确切的产品或服务。

今日保险行业 AI 一瞥

根据埃森哲的一项调查,截至今天,74%的客户愿意与现代技术互动,并欣赏电脑生成的保险系统的建议。

那些较早采用索赔流程某些方面自动化的公司可以体验到处理时间和成本的显著下降,以及服务质量的良好提高。

谈到早期采用者,好事达商业保险公司最近也与 EIS 合作开发了 ABIe 。ABIe(陈细洁)是一个基于人工智能的虚拟助理应用程序,旨在满足好事达保险代理人寻找 ABI 商业保险产品信息的需求。希望随着时间的推移,我们将听到更多保险公司人工智能投资的突破。

机器学习、高级分析和物联网传感器的强大组合使保险公司能够接触到潜在客户,研究他们的实时需求,从他们对风险大小的描述中获得洞察力,并最终创建定制的解决方案。

AI 在保险行业的未来

虽然挑战似乎让目前的市场感到沮丧,但保险公司仍然喜欢用乐观的眼光看待人工智能在保险业的潜力。为了获得全方位的好处,保险公司需要设计一个企业级战略来实施人工智能,使其提供的不仅仅是客户体验。

马鲁蒂技术实验室,我们已经在研究人工智能在保险行业的多种应用,涉及索赔管理、通过图像识别进行损失分析、自动化自助服务指导等。

当谈到图像识别时,整体损失分析、成本估计和索赔结算将由扫描图片和视频的机器人来执行。这样,随着时间的推移,公司可以完全依靠图像识别技术实现一级索赔自动化,随后自动解决索赔或解决保险中的欺诈检测。通过致力于现有工作流程的智能自动化,我们旨在减少管理或监控索赔所花费的时间和资源,提高流程效率并改善客户体验。

随着新的人工智能工具不断改造索赔管理,回报必然包括更智能的欺诈检测、更快的结算和更好的客户服务。

未来 10 年技术的快速进步将导致保险业发生颠覆性的变化。采用新时代技术开发创新产品、利用来自无数数据点的认知学习见解、简化流程以及更重要的是个性化整个客户体验的公司将成为人工智能主导的保险领域的赢家。

人工智能如何帮助肯尼亚的母亲更快地获得她们需要的护理

原文:https://towardsdatascience.com/how-ai-helps-mothers-in-kenya-get-the-care-they-need-faster-eb4f05b34732?source=collection_archive---------11-----------------------

每个母亲在怀孕期间和之后都会有疑问。我应该多久感受一次宝宝的踢腿?我应该什么时候去医院?我如何知道我的新生儿是否吃饱了?在世界各地的许多地方,母亲们会与她们的提供者、朋友取得联系,或者在网上搜索这些答案。但是对于一个只受过小学教育,生活在肯尼亚农村社区,与外界的联系只是简单的功能手机的母亲来说呢?

蓝花楹健康中心正在努力寻找解决方案,以改善在公立医院寻求护理的低收入母亲的健康状况。我们推出了名为 PROMPTS 的短信服务,为孕妇和新妈妈提供重要信息。在很短的时间内,超过 11,000 名母亲注册了这项服务。我们最初的目标是向母亲们发送一系列经过严格测试的信息,以“提示”她们寻求护理。我们很快意识到,母亲们有她们想要答案的问题——很多问题!几乎一半的用户会对文本提示提出三到五个问题,一小部分人会提出超过 20 个问题。我们设立了一个服务台来回答这些问题(通过短信)。这些问题大多是一般性的(“怀孕期间可以吃鳄梨吗?”),但我们收到的问题中至少有 30%可能需要紧急回复()“我在流血,我该怎么办?”)。随着 PROMPTS 迅速扩展到全国成千上万的母亲,我们面临着一个伦理挑战:我们如何准确地回答成千上万的问题,并迅速回应紧急问题?

使用聊天机器人?几年前,聊天机器人风靡一时,并预示着客户服务的一场革命。一个私人助理,帮你订购杂货,帮你的孩子做作业,帮你报税。大多数聊天机器人是流量机器人,或基于菜单,在寻找答案时“选择你自己的冒险”。客户服务台长期以来一直使用基于菜单的选项来指引客户找到信息来源(如果您丢失了银行卡,请按 2)。Flowbots 通过道歉和表情符号来“人性化”这种方式。最近,人工智能和聊天机器人被认为是应对全球健康挑战的解决方案(在此进行了广泛回顾)。有几种机器人解决方案可以解决妇女的生殖健康问题(Nivi、怀孕机器人、Sophie Bot、Lily)。生和阿达)。我们构建并测试了 flowbot,看看它是否能够支持我们在支持孕妇的数千个问题方面的挑战,但遇到了一些根本性的挑战,如下面的聊天机器人交互所示:

用户:“一个人怎么能在不吃很多食物的情况下增加牛奶供应呢?我不想增加太多的体重,因为我已经超重了

Bot:“对不起,请回答“是”或“否”来接收关于您第一次母乳的信息

挑战 1:人类没有共同的信息组织方式。上述问题的答案应归入“体重增加/减少”还是“母乳喂养”类别?(谁没有在一系列菜单选项中迷失过,才反复按 0 找一个接线员)。

挑战 2:流量机器人不是以客户为中心的:记住,我们的大多数用户都有一些迫切的问题需要解答。流量机器人希望你按照预先设定的路径找到答案——这不是一个好的客户体验。

挑战三:语言输入难以‘理解’。我们的服务台接收英语和斯瓦希里语的问题,其中很大一部分问题是这两种语言的混合,包括含有俚语的信息。

挑战 4:背景在客户服务中很重要,但在医疗保健中也很关键。如果这个特定用户先问了一个关于怀孕减肥的问题,随后又透露了对母乳供应的挑战,会怎么样?为了方便而组织起来的信息很少能为良好的健康建议提供足够的上下文细节。

帮助服务台代理的人工智能。我们相信人类的存在对我们的用户来说是至关重要的,因此我们寻找一种方法来提高人类工作负载的效率。我们设计了一个“分类机器人”,它使用自然语言处理(NLP)对数千个用户问题的意图进行分类。NLP 使用机器学习以人类的方式“理解”语言。例如,疼痛可以被描述为“疼痛”、“我的一侧正在疼痛”、“一侧紧张”。一个基于 NLP 的机器人通过模式识别学习这些区别,我们的分类机器人还为意图增加了一个优先级。关于疼痛的问题被确定为高度紧急,而关于营养的问题优先级较低。

分流机器人现已整合到我们的服务台流程中。该机器人读取每个传入的问题,分配一个优先级并建议一个响应,以便我们的服务台代理可以更快、更有效地做出响应。我们不断训练分诊机器人来改进它的意图分类,但它已经在我们帮助母亲的能力方面发挥了作用。自从集成了 bot 后,我们的帮助台对紧急或高优先级问题的响应时间减少了以前的 50%,总体响应时间减少了 40%。

经验教训。使用正确的用例,人工智能可以变得非常强大。在我们的用例中,我们发现人工智能增强了人类的活动,而不是取代人类的存在。也许有一天,分诊机器人将升级到回答关于鳄梨的问题,这样我们的服务台代理就可以更好地支持迫切需要与人接触的母亲们。

人工智能如何帮助提高效率

原文:https://towardsdatascience.com/how-ai-is-helping-efficiency-improve-98d0171a23e2?source=collection_archive---------9-----------------------

人工智能是现代科学的奇迹,它使许多以前不可想象的事情成为可能。现在多亏了人工智能,许多事情可以做得更快更有效。AI 提高了行业很多东西的效率和生产力。在这篇文章中,已经讨论了人工智能如何帮助提高效率的一些例子。

分析数据和报告速度

AI 在提高数据分析速度和增加报告时间方面非常有帮助。数据分析更加准确,报告时间也有所增加。AI 可以用来分析大量数据,得出结论性的报告。如果将同样的工作交给任何人,所需的时间将会非常长,并且在报告中出现某种错误的可能性也很高。

全天候服务

与人类不同,人工智能不需要休息,它们可以一天 24 小时提供服务。人类可以工作最少的时间,他们不能一整天都保持一致的表现。另一方面,人工智能本质上是一台不会疲劳或厌烦的机器。它可以全天工作,全天提供相同的性能和一致性。这提高了业务效率,使行业运行更加顺畅和有效。如果这项工作由人工智能来完成,出错的几率也会更低。

过程自动化

在人工智能发明之后,许多复杂的过程现在已经自动化了。完成这些过程不需要任何人工支持。许多微服务是由人工智能自动提供的。微服务的一个例子可以是应用程序部署,这对于开发人员来说曾经是一项非常单调乏味的任务,现在在人工智能的帮助下可以轻松完成。许多其他复杂的流程已经实现了自动化,降低了商业成本,也减少了员工的工作量。

分析学

人工智能可以广泛用于数据分析。AI 擅长处理算法,并使用它们从非常大量的数据中提取有意义的信息。该企业定期大规模收集数据,以便对其进行分析,从而制定更好的策略来获得更多客户。这些数据包含大量信息,很难正确分析。在人工智能的帮助下,这些数据可以快速处理,也可以快速生成详细的报告。这对商业非常有帮助,并且提高了整个商业行业的效率。

提高安全性

人工智能非常有助于提高网络、应用程序或网站的安全性。网络、应用程序或网站包含企业的重要信息和商业秘密,对任何企业来说,保护这些信息和商业秘密都是至关重要的。人工智能可用于增强企业网络中的保护措施。人工智能彻底改变了网络安全行业,改变了网络安全和检测网络异常的流程。当实施人工智能技术来维护网络安全时,系统会得到更多保护。

提供更好的客户支持

人工智能现在被用来为访问企业网站的用户提供客户支持。它降低了成本,因为公司需要雇用更少的客户服务代理。但是理解人和机器之间的适当平衡是至关重要的。当涉及到为用户提供客户支持时,人工智能肯定有一些限制。重要的是要意识到在客户服务体验的哪些部分要实现 AI。如果实施得当,人工智能可以为整个企业节省大量成本。

人工智能如何在这个假期彻底改变圣诞老人的工作室

原文:https://towardsdatascience.com/how-ai-is-revolutionizing-santas-workshop-this-holiday-season-4bed707bfa48?source=collection_archive---------41-----------------------

当 North Pole 创始人兼首席执行官圣诞老人寻求优化其全球制造和包裹递送组织时,这位创始人转向人工智能,以在供应链中实现各种成功。

如果你有机会采访北极创始人兼首席执行官圣诞老人,不要提亚马逊。当我提到这家总部位于西雅图的在线零售巨头时,圣诞老人忍不住嘲笑了我。“请,”他说。"在杰菲还没有换尿布的时候,我就已经在送包裹了!"

虽然季节性组织可能不像亚马逊那样消耗所有的资源,但这个留着白胡子的胖子说得有道理。从中世纪开始,北极就一直在履行使命,给全世界的孩子送包裹。

“我们是首批获得 IBM 165 的公司之一,就在美国人口普查局之后。”—圣诞老人,北极的首席执行官。

那么,一个有数百年历史的组织如何继续创新呢?
好吧,克劳斯先生会是第一个告诉你老公司不能总是用老方法做事的人,这就是为什么北极一直致力于与时俱进——将最新的技术解决方案引入他们的运营中,以确保他们实现目标。

“我们看到的是一个非常小的(交付)窗口。”克劳斯先生解释道。“你可以在晚上 9 点到早上 6 点之间进去,拿到树下的包裹,然后出来,如果孩子还小的话,可能是 7 点。世界各地。这是一场物流噩梦。”

起初,该组织完全是模拟的,依靠一个名副其实的簿记员和会计大军来跟踪每个包裹、每个收件人和数以千计的其他细节,以使圣诞节——嗯,平安夜——发生。

但随着世界的变化和技术的发展,克劳斯先生坚持尽可能高效地运营。

“我们是首批获得 IBM 165 的公司之一,就在美国人口普查局之后,”他告诉我们,他指的是首批投放市场的商用计算机之一。“它占据了一个房间的大小,但我太太不想让它呆在房子里,所以在最初的几个冬天,我们把它放在一个空的驯鹿海湾。我们的工程师冻得要死,但这让我们的 DCR 降低了 5%。”

DCR 是“失望儿童率”的北极代表——在任何给定的圣诞节都没有得到他们想要的东西的儿童的百分比。虽然克劳斯先生拒绝告诉我们他们目前的 DCR 比率是多少,但几家研究公司估计它在低位。对于一个一晚上递送超过 80 亿个包裹的组织来说,这已经不错了。

技术采用的浪潮仍在继续。80 年代是个人电脑。在 90 年代,是互联网。最近,北极开始涉足人工智能。

2017 年,该组织推出了第一个人工智能倡议,名为 ONE HORSE OPEN SL-A.I。最初的计划是部署几个系统,以便更容易地将淘气鬼从好人中分类出来(见下文);然而,这种努力一直持续到现在。

现在,从供应链管理到人力资源,北极几乎在所有的业务中都看到了人工智能。所以,无论你想要一个官方的红色莱德,卡宾枪行动,200 射程模型气步枪还是同样疯狂的东西,人工智能都有助于从北极带给你最好的东西。

请继续阅读,了解北极如何利用人工智能完美地递送数十亿个包裹——全部在一个晚上完成。

人工智能预测消费者趋势

过去,北极会自己制造所有的玩具,但近年来,情况发生了变化。“你不能只是教一个小精灵做一个任天堂,”克劳斯先生解释说,这就是为什么,今天,该组织主要转向外部供应商的大部分库存。

无论是在内部生产还是在其他地方生产,北极知道今年哪些玩具会畅销是绝对必要的。“当电子鸡浪潮在 90 年代末袭来时,我们完全没有准备。“胳肢我吧,埃尔莫,”克劳斯说。但是去年,我们的人工智能很早就发现了坐立不安者的崛起。这是足够的警告,让我们有数以百万计的这些小杂种随时准备来到平安夜。"

“我们利用各种消费者数据来预测流行玩具,”圣诞老人说。“你不会想跑出去的。”

通过训练玩具趋势的预测模型,圣诞老人团队可以提前了解哪些玩具开始走俏。

人工智能区分好的和坏的

团队不再可能单独评估地球上每个孩子的行为,这就是为什么北极的人们现在将大部分决策留给 AI。

通过在淘气和乖孩子的数据集上训练人工智能算法,北极利用强大的 ML 分类器全年自动标记孩子。

人工智能将淘气的(供应商)与善良的分类

去年,圣诞老人团队推出了一个类似的淘气鬼/好人分类器,以改善他们对供应商的选择。通过分析公开可用的数据,如审计、信用评分和其他评估,North Pole 能够在与供应商签订合同之前对其进行审查。

人工智能跟踪仓库中的包裹

北极仓库可能是地球上最复杂的地方之一。我们谈论的是一个递送中心,其中数十亿包装好的礼物几乎没有可识别的信息。毕竟,大多数圣诞标签只有四个字:

给吉米,

爱圣诞老人。

没有地址。没有条形码。他们怎么可能保持一切正常?

答案是 PERT[钢笔背书表示转换器],这是一个能够在超过 990 种语言中识别手写涂鸦所有者的模型,准确率超过 97.9%。今年早些时候,谷歌开源了 PERT,并收集了大量的每个人的手写样本。

遍布仓库的摄像头在整个订单履行过程中跟踪包裹。首先,一个精灵收到物品和物品接收者的详细信息。然后,摄像机看着小精灵抓起物品,完美包装,填写礼物标签,最后将包装好的包裹放在货架上,直到平安夜。

通过监控精灵的动作并将这些动作与计算机上的原始读数联系起来,精灵能够将每个包裹与最终打开它的保罗或葆拉完美地配对。

我想知道你什么时候睡着了,什么时候醒着

这些歌曲让整件事看起来像魔术一样,但事实远没有那么神秘。圣诞老人团队可以以近 98%的准确率确定您的孩子是否舒适地躺在床上,只需通过旨在处理图像的机器学习算法运行您所在城镇的无人机镜头。

该系统寻找各种线索,从你房子的照明程度(比利的卧室灯亮着吗?)到有多少烟从烟囱里冒出来,然后将这些结果输入导航器。

人工智能保持驯鹿健康

当你的公司在偏僻的地方时,很少有外部兽医可以寻求第二意见,这就是为什么当 Dasher 或 Dancer 生病时,圣诞老人团队会求助于 AI 来帮助我们进行诊断。当现场兽医使用人工智能训练的模型时,他们会做出更好的决定,从而带来更好的结果。

用于路线优化的人工智能

去年,北极首次使用人工智能来帮助他们的导航员绘制圣诞老人的平安夜路线,优化他跨越时区、海洋和天气系统的路线。结果令人震惊。
通过访问关于天气、风速等的综合历史数据集。,圣诞老人团队能够完全避免不可预见的天气系统,并从他们的总旅行时间中节省了近 45 分钟。

这是一个惊人的记录——他们希望在几周内打破它。🎄

这个故事最初由曼斯普斯在 T2 出版。Manceps 帮助企业组织大规模部署 AI 解决方案。

想把人工智能带到你的运营中?下载我们的免费资源:人工智能就绪讨论问题。该指南包含几十个发人深省的问题,将帮助你和你的团队在尝试人工智能时很好地了解可能发生的事情。

人工智能是如何为了更大的利益升级太空技术的?[五大领域]

原文:https://towardsdatascience.com/how-ai-is-upgrading-space-technologies-for-a-greater-good-top-5-areas-e5f2245f8d3b?source=collection_archive---------39-----------------------

Credits: Canva

人工智能和空间技术有着密切的关系。太空研究和探索是第一批在日常操作中实施人工智能的领域之一。

在太空探索中使用 AI 的一个关键原因是因为它必须处理大量数据。有如此多的数据要处理,人们不能完全依靠人类的智慧。人工智能正在帮助我们减少人为错误,并使估计接近现实。

让我们看看人工智能是如何通过对太空探索和研究做出贡献来造福人类的。

#1 地球观测

我们一直在利用卫星进行通讯、导航、遥感等。近半个世纪以来。人工智能一直在帮助我们更高效、更有效地使用这项技术。

卫星的主要任务之一是收集数据并把数据传回给我们。在其整个生命周期中,卫星收集了大量的数据。大部分是无用的。AI 有利于搞清楚哪些数据有意义。

机器学习算法被用于分析大量的数据。这些算法可以在几分钟内分析数据,这有助于我们快速获得重要信息。

一个很好的例子是在移徙领域采取的保障措施。除此之外,人工智能还有许多其他应用,可以帮助我们更好地了解我们的地球。

#2 城市规划

由于人工智能已经在帮助我们以更好的方式绘制地球地图,它帮助我们以最好的方式规划和设计城市区域。卫星被用来拍摄土地的照片以便绘图。

此外,卫星和人工智能还可以用于管理整个城市或城镇的交通。AI 可以提供一个管理密集交通区域交通的建议。

由于世界正在转向可再生能源,这也有助于我们确定放置风力涡轮机、水轮机或太阳能电池板的最佳位置,以获得最佳效果。

基于这些数据,我们可以相应地规划我们的城市,为更可持续的未来铺平道路。最终,人工智能将帮助我们创造一个更好的环境,确保我们工作和生活的地方能够满足今天的需求。

#3 可再生能源预测

人工智能通过帮助天气预报部门提前识别天气模式来帮助他们。使用卫星作为主要输入设备,人工智能正在帮助我们预测天气模式。

例如,它帮助我们识别世界上哪个地方的潮汐强度更高。根据这些信息,我们可以最大限度地利用潮汐能,将其转化为电能。

我们对可再生能源了解得越多,我们就越能利用它们来使我们的地球更加可持续发展。越来越多的国家开始利用人工智能来优化可再生能源的使用。

#4 污染监测

人工智能以许多不同的方式帮助减少污染。它帮助我们的最新方法之一是,如果某个港口拥挤或堵塞,就向附近的其他港口和船只发送信号。

这不仅有助于管理港口的交通,也有助于减少港口和城市附近的污染。利用卫星,它可以帮助减少航运带来的负面后果。

在卫星图像的帮助下,人工智能可以计算出最安全、最快的运输路线。这将有助于我们优化全球运输流程。

#5 运输

AI 和 GPS 位置跟踪可以彻底改变公共交通。例如,人工智能可以在公共汽车站检测到人类,并通知公共汽车司机他/她应该在特定的车站预计有多少乘客。

它还可以通过检测途中的恶意活动来帮助士兵进行运输。除此之外,列车维护也是一个可以带来巨大利益的领域。

机器学习算法可以帮助我们通过查看卫星图像来确定需要特别注意的车厢。总的来说,人工智能和空间技术将简化任何东西或人的运输。

结论

公司和创新者可以继续受益于人工智能、人工智能和空间技术相结合带来的商业机会。随着技术的进步,由于这些和新的进步,我们的日常生活将继续进步。

作者 Sandeep Agarwal,一家 iPhone 应用开发公司

人工智能时代资本主义的未来。

原文:https://towardsdatascience.com/how-ai-will-force-us-to-redefine-capitalism-2e8360f7aae0?source=collection_archive---------8-----------------------

Image by Pexels on Pixabay

人工智能、数据和经济学

前景令人不安;然而,如果我们采取必要措施,挑战是可以克服的

资本主义是有史以来世界上最具弹性和最有效的经济意识形态,尽管它有缺点,因为没有可行的替代方案。资本主义不仅经受住了共产主义的挑战,成功地经受住了工业革命的负面影响,而且已经成为希望以可持续和有效的方式发展的国家的几乎普遍的经济政策。

但今天,许多政策制定者谈到需要改革资本主义,以确保其未来的活力和灵活性,并解决迫在眉睫的挑战,如不断加剧的不平等、无力应对环境退化和气候变化、金融体系的内在弱点(这在 2008 年金融危机中达到高潮),以及越来越有吸引力的自由市场资本主义和中央集权、政府控制的经济的中国组合。

集中式与分布式

与共产主义曾经构成的威胁相比,资本主义目前面临的挑战相形见绌。然而,尽管有资本主义制度最终灭亡的不祥预测,但事实证明,是共产主义无法适应不断变化的现实,最终崩溃了,而资本主义在冷战后占据了至高无上的地位。这为所谓的华盛顿共识铺平了道路,即全球普遍采用资本主义原则,并通过国际货币基金组织和世界银行等国际机构得到美国和欧盟的支持。

资本主义打败共产主义的原因是分布式数据处理系统比集中式更有效。如果一个有多个数据处理器的系统出现错误,其他参与者会很快利用这个错误,使系统恢复平衡(这就是市场看不见的手的工作方式)。

另一方面,在中央数据处理系统中,决策是由单个处理器作出的,如果出现错误,将会产生灾难性的后果,因为没有人去纠正它。这一优势使得资本主义在冷战中击败了共产主义。

然而,人工智能可能会抵消资本主义的决定性优势,并使天平向有利于中央集权的经济体系倾斜。

毕竟罗马帝国以中央集权的数据处理方式存在了几个世纪,而延续了几百年的中国王朝也是依靠中央集权的官僚机器。

这意味着,如果 21 世纪的条件再次发生变化,资本主义的分布式数据处理系统在人工智能时代可能变得无关紧要。

众所周知,为了改进人工智能算法,可用数据的质量和数量成为一个重要因素。

如果政府拥有足够多的高质量数据,它们可以使用先进的人工智能算法来预测市场力量,然后评估潜在的选择,以应对挥之不去的危机或更有效地分配资源。那么,自由市场资本主义的意义何在?

以前,自我调节的市场力量确保了比中央经济计划好得多的效率。然而,一个拥有足够的经济活动数据的国家——中央系统在收集大量数据方面比资本主义国家好得多,资本主义国家的数据分散在各种行为者手中——将比其竞争对手拥有相当大的优势。

想象一下,在一个国家,甚至在崩溃的第一个迹象出现之前,就能发现并解决可能引发经济危机的漏洞。不会有商业周期这种东西:只有经济扩张,没有任何衰退。

那么,自由市场资本主义的意义何在?

人工智能驱动的垄断

资本主义的到来,人工智能的到来将挑战资本主义的另一个支柱——自由市场竞争。

人工智能驱动的经济的主要问题是,由于人工智能对数据的依赖所产生的正反馈循环,行业自然倾向于垄断

如果一家使用人工智能的特定公司胜过其竞争对手,将很难抵制垄断的自我延续循环。这样的公司,得益于已经庞大的数据集,将拥有先进的算法。先进的算法意味着更好的用户体验和更多的功能,从而吸引更多的客户。更多的客户,反过来,产生更多的数据,这进一步改善了现有的算法,使公司的产品更有吸引力,最终导致更大的客户群,无止境。

Credit: Author

垄断的问题在于,资本主义的基石、其成功和效率的秘诀——自由竞争——可能会成为历史。

没有政府的干预,资本主义的发展引擎将会终结。

“无用”类

由于算法和机器人取代了工作岗位,前所未有的社会动荡也对资本主义体系构成了威胁。

尽管研究表明,在短期内,人工智能创造的就业机会将多于淘汰的就业机会,但从长远来看,取代大部分就业机会在技术上是可行的。此外,尽管会出现新的工作,但它们大多是白领工作,需要非常高的知识水平和多年的大学培训。人工智能时代所谓的 技能偏见 将创造有史以来最不平等的社会。

一个新的“无用”人阶层将会形成,他们只会在由人工智能算法和机器人操作的经济中变得无关紧要和多余。他们对富人的不满可能会导致社会的严重动荡和不稳定的后果。

在工业革命之后,实业家的利润飙升,而受压迫的工人阶级的生活质量仍然很低。因此,社会主义和共产主义意识形态应运而生,它们试图迎合工人阶级的情绪,从而通过直接挑战资本主义的基础,对其构成有史以来最大的威胁。

世界各地的民主政府将如何应对这些挑战?就目前而言,西方政府未能减轻 ICT 革命远不那么严重的后果,比如不断加剧的不平等。当“政府变得对这些目标具有破坏性”时,也就是说,当政府无法为人民提供“生命、自由和对幸福的追求”时,“人民建立新政府的权利”会占上风吗?

资本主义将继续存在——尽管形式不同

尽管如此,令人怀疑的是,资本主义的西方将不可避免地崩溃,而共产主义的中国由于其集中的数据处理将不可避免地获得绝对的经济优势。

毕竟,正是灵活性、适应性和韧性定义了民主,并帮助它们长期存在,而不像独裁政权那样,因为无力和不愿适应变化和实施紧急改革而经常停滞不前和无法发展。

正如外交事务文章《自由世界》的作者所说,

美国第一届国会马萨诸塞州代表费希尔·艾姆斯(Fisher Ames)曾将专制比作一艘商船,“它航行得很好,但有时会触礁,沉入海底。”他说,一个共和国“是一只永远不会沉没的木筏,但是你的脚永远在水里。”自由秩序及其民主将会盛行,因为不自由主义的庄严航船很容易在动荡的时代搁浅,而自由主义的坚韧木筏则缓慢前行。

人类发展过程的独特之处在于,它受到对它的预测的影响。正如 g .索罗斯所说,

…现实是一个移动的目标,因为它受我们理解的影响。我们习惯于认为事件是一系列事实:一系列事实接踵而至,永无止境。当一个情境有思考的参与者时,这个链条不会直接从一个事实引向另一个事实。它将一个事实与参与者的思维联系起来,然后将参与者的思维与下一组事实联系起来。

因此,马克思在《资本论》中对资本主义灭亡和无产阶级必然胜利的悲观预言并没有实现。

正如里根所说,

你怎么告诉一个共产主义者?嗯,是读马克思列宁的人。你怎么告诉一个反共产主义者?是懂马克思列宁的人。

这句话有更深的含义:里根不仅说共产主义者误解了 k·马克思;他还指出,因为反共产主义者理解 T2 和列宁,并采取措施改善工人阶级的状况,从而将潜在的叛乱扼杀在摇篮中,从而相应地改变了他们的行为。结果,革命没有发生,资本主义仍然存在

同样,今天关于人工智能引发的剧变将导致资本主义体系崩溃的不祥预测可能会迫使政策制定者改革这一体系,使其符合大多数人的期望并反映他们的需求。

此外,尽管自由市场可能会因为人工智能算法在经济决策中的实施而变得过时,但这并不意味着资本主义的美国将不可避免地输给共产主义的中国。美国的优势在于它拥有大量高质量的经济数据,这要归功于负责任地收集信息的悠久传统。

对于美国和其他资本主义国家来说,最好的方法是将人工智能无法取代的资本主义优势——如自由竞争和私营部门在处理可投资资源时的固有效率——与新技术结合起来并加以保留。它们可以用来识别系统中的潜在弱点,让市场这只看不见的手不是为市场的最佳利益服务,而是为最优秀的人服务。

我们可以通过减轻不受监管的自由放任资本主义的负面影响——不平等、垄断形成、欺诈和腐败——的措施来实现这一目标。

然而,这将要求西方政府控制大型科技,以防止垄断和维护自由竞争,同时设计更有效的税收制度,并实施一系列措施来降低不平等水平和巩固社会稳定。

为此,我们需要政府、民间社会、非政府组织和企业之间的互动与合作。只有通过共同努力,我们才能拯救资本主义,并促进向新时代相关的新型社会秩序的和平过渡。

……正是灵活性、适应性和复原力定义了民主,并帮助它们长期存在,而不像独裁政权那样,由于没有能力和不愿意适应变化和实施紧急改革,独裁政权往往停滞不前,无法发展。

正如共产主义和社会主义的意识形态因工人阶级的贫困状况而在工业革命后出现一样,如果我们不能克服机器人、人工智能和大数据的出现对资本主义构成的挑战,当前的秩序可能会因为全新的运动、信仰和理想的出现而终结。

人工智能将如何重新定义经济学

原文:https://towardsdatascience.com/how-ai-will-redefine-economics-ec305e3cb687?source=collection_archive---------2-----------------------

Photo by M. B. M. on Unsplash

人工智能将使经济学更接近一门真正的科学

人工智能正以前所未有的方式改变着世界,并重新定义了人类努力的几乎所有领域。到目前为止,经济学一直抵制人工智能的采用,它将经历巨大的变革——可以说是自亚当·斯密创立这门科学以来最大的变革——从而帮助人类更好地解决问题。

简单地说,人工智能是一套技术,它允许我们分析数据,做出推断,预测,并在总体上做出更好的决定。机器学习是人工智能的一个子集,它能够自己不断学习,而不必由人类预先编程。

理解人工智能和机器学习如何改变该领域对于设定正确的优先事项和解决现有问题至关重要,这些问题不允许经济学被视为真正的科学。

Conventional programming versus machine learning. Source: IBM

为什么经济学不像自然科学——以及人工智能将如何纠正这一点

经济学和政治学的主要问题在于,它们并不构成真正的“科学”,如物理或数学。换句话说,自然科学和社会学科之间存在着明显的区别,这使得传统的科学方法不适用于社会学科。

正如诺贝尔经济学奖得主保罗·萨缪尔森所说,“经济学从来就不是一门科学——现在甚至不如几年前。”

经济学家坚持他们的理论模型,其中大多数在现实世界中几乎没有价值,因为他们无法考虑不可预测和内在不理性的人类行为对事态的影响。

人类是非理性的;他们的偏见、成见、误解和谬误决定了他们的行动。因此,在社会事件中,人们基于有缺陷的知识做出决定。

然而,尽管社会事件具有固有的不确定性,但大多数经济学家都坚信市场反映了人们的理性预期(导致了理性预期和完全竞争等理论的产生)。顺便说一下,正是由于无法认识到我们的非理性,导致了新自由主义经济学范式的出现和 2008 年的危机。

经济学家坚持他们的理论模型,其中大多数在现实世界中几乎没有价值,因为他们无法考虑人类感知对事态的影响以及随之而来的不确定性。

与物理学不同,经济学研究的是人、人的感知和非理性。由于玩家情绪的快速变化,某一天有效的模式下一次就不再有效了。

行为经济学已经认识到传统的经济理论是建立在错误的假设之上的。然而“由于缺乏对其研究数据的复制,缺乏对科学和行为科学(行为分析)的理解,经济学教授们只是根据他们的经验进行猜测。”显然,行为经济学虽然旨在更好地感知世界,但迄今为止还无法科学地做到这一点。

然而,人工智能和信息技术在经济学中的普遍应用可能会更好地改变这种情况。通过模拟人类行为,我们可以潜在地估计它对现实世界的影响。这将更容易识别金融泡沫和经济中的潜在脆弱性,并做出更好的预测。

Photo by Element5 Digital on Unsplash

经济学的政治化

由于人类思维的介入,经济学不能声称符合自然科学的标准。但经济学的问题超出了对世界的错误理解。

科学家的首要目标是追求真理。他们努力拥抱一种不偏不倚的态度,这种态度允许他们以可能的最佳方式分析现实世界。理论上,社会科学的学者也致力于获得真理。然而,在实践中,这很少成立。

政治家的主要目标不是通过更好地理解现实来获得真理,而是追求权力,这往往是通过操纵现实来实现的。经济学虽然远非真正的科学,但在当今日益党派化的环境中,它仍然是清晰和客观的源泉。

然而,政治经常干扰经济。

大西洋报道,

自 2016 年大选以来,党派经济预期差距(即共和党人和民主党人对经济方向的评估之间的差异)已经扩大到前所未有的水平,从罗纳德·里根、乔治·w·布什和巴拉克·奥巴马总统时期的大约 20 点扩大到今天的 56 点。民主党人现在预计衰退即将到来,而共和党人预计强劲的增长将持续下去。“差距太大了,”密歇根大学社会研究所的理查德·科廷告诉我。

经济辩论经常变成政治辩论,经济学家不是致力于追求真理,而是成为其政党纲领的倡导者,歪曲或故意曲解和忽视现有证据。

为了避免经济学的政治化,我们可能会利用人工智能来分析所有关于经济的信息,并给出公正客观的基于证据和数据驱动的建议。人工智能将结束无休止的充满政治色彩的经济辩论,并将为我们提供如何应对经济挑战的平衡建议。

Photo by Markus Spiske on Unsplash

经济预测—现在有了人工智能

当预测经济状况时,唯一确定的就是不确定性。经济学家在预测可怕

例如,Prakash Loungani(国际货币基金组织)的分析显示,在过去的 150 次衰退中,经济学家未能预测到 148 次。

有效的经济预测面临许多障碍。一是几乎不可能预测消费者情绪的大幅波动。

增加的复杂性并不是唯一的问题——由于反馈循环,预测也变得不太可信。因此,如果气象学家说会下雨,你带伞出门并不会影响天气。但是,如果一位经济学家预测通货膨胀将上升 3%,而我们的反应是要求工资至少增加 3%,我们就改变了预测的基础。通货膨胀率现在可能会上升 3%以上。预测存在的事实改变了它试图预测的现实。

为什么经济预测一直是一门有缺陷的科学?

人工智能驱动的预测分析将克服经济预测中存在的一些挑战。通过在行为经济学中实施人工智能技术,经济学家将能够更精确地估计人类感知和行为对实际事态的影响。预测分析的使用将结合经典的统计分析和人工智能的新世界。

人工智能算法还可以分析媒体标题如何影响对经济的看法。事实上,摩根大通已经使用一种算法来跟踪特朗普总统的推文对金融市场的影响。

央行和财政当局知道衰退何时到来,将更有效、更迅速地实施货币和财政工具,从而减轻商业周期的影响。

我们甚至可以预测供给和需求的变化,以实施必要的改变,从而避免经济衰退。

正如约翰·索内尔在 金融时报 所写的,

我们所有的联网设备都在输出大量关于我们实时经济活动、需求和欲望的数据。如果利用得当,这些数据可以模仿价格机制,作为一种匹配供需的手段。

人工智能驱动的决策

D. Esty 和 R. Rushing 在 Issues 中写道:“联邦政府在使用信息技术以创新的方式收集、分析和使用数据方面还只是皮毛。

正如我在《人类事件》的文章中所写的,“决策者可以依赖数据和人工智能算法,而不是依赖个人经验、非理性本能、误导的教条或有害的偏见。”

理论上,社会科学的学者也致力于获得真理。然而,在实践中,这很少成立。

人工智能将使政府官员不再依赖传统的有缺陷的数据收集方法,而是将他们的决策建立在数据基础上。信息技术将使数据驱动的监测、政策评估和分析成为可能。

经济学重新定义

多亏了循证经济决策的出现,我们将能够结束无休止的经济辩论,找到基于数据的共同点。

AI 将做出更好的预测,并将人类感情(即反身性)对实际事态的影响纳入考虑。总之,这些变化将使经济学更接近一门真正的科学。

人工智能的出现是经济学史上一个最重要的事件。我们的目标应该是有效地利用人工智能的力量来改善我们所有人都能繁荣发展的经济条件。

进一步:

* [## 人工智能将标志着政治史上的一个转折点。人类事件

科技如何让世界变得更加民主?科技对政治的影响力无处不在。在…

humanevents.com](https://humanevents.com/2019/10/23/a-i-will-mark-a-turning-point-in-the-history-of-politics/) [## 人工智能时代资本主义的未来

前景令人不安;然而,如果我们采取必要措施,挑战是可以克服的

towardsdatascience.com](/how-ai-will-force-us-to-redefine-capitalism-2e8360f7aae0)*

算法如何塑造另一种现实——鲍德里亚式的分析

原文:https://towardsdatascience.com/how-algorithms-are-shaping-an-alternative-reality-a-baudrillardian-analysis-76e68f6dad56?source=collection_archive---------25-----------------------

Photo by Markus Spiske on Unsplash

有偏见。有偏见。种族主义者。

通常,当我们谈论算法时,我们采用拟人化的语言。将人类特征归因于本质上无生命的代码是我们理解算法本质的方式。

虽然这为我们提供了一种表达方式,但它并没有抓住辩论的细微差别。给一个算法贴上有偏见的标签,意味着它是一个自主的实体。这意味着是代码本身存在偏见,而不是编写代码的开发人员或认可代码的组织。

从本体论方法(关注什么算法)转移到目的论方法(关注什么算法做什么)允许问题的微妙之处浮出水面。

算法做什么

算法产生现实的模型或表示,然后用于推断大量的决策。

这些范围从网上购物的产品推荐到高中教师的绩效评估;医院出院的贷款申请批准;从保险费风险评估到社交媒体新闻排名。

我们可以把这些模型看作是模拟的类型。

这些模拟不仅构建了我们的虚拟生活,也构建了我们的现实生活,影响着我们日常生活中的社会、经济和政治领域。

算法不是简单地反映现实,而是积极地创造现实。

鲍德里亚式分析

为了充分理解这些模拟的深层影响,我们可以求助于法国哲学家、社会学家和文化理论家让·波德里亚。

鲍德里亚写了大量关于模拟(真实的副本)如何逐渐演变成拟像(真实的),与原作几乎没有相似之处。

他用来阐明他的概念的一个例子是地图,一个人工产生的抽象,代替实际的地理地形。

今天,这与我们和数字地图的互动产生了共鸣。我们认为现实不是我们看得见的,而是像谷歌地图这样的导航应用所描绘的那样。

另一个更现代的例子是 Instagram,在那里,大量经过严格过滤的图像和精心策划的信息聚合成一个虚构的现实。一个人的网络身份取代了他们现实生活中的身份。

将这个概念与算法联系起来,让我们探索算法创建的模型最终如何取代现实。

作为一个例子,我将使用在美国广泛使用的累犯模型来确定监狱判决,如凯茜·奥尼尔的数学毁灭武器:大数据如何增加不平等和威胁民主中所详述的。

根据鲍德里亚的说法,模拟(鲍德里亚称之为图像)如何转变为拟像有四个阶段。

“这将是图像的连续阶段:它反映了深刻的现实;它掩盖和改变了深刻的现实;它掩盖了深刻现实的缺失;它与任何现实都没有关系;它是自己纯粹的拟像。”

(来源:拟像与仿真,p6)

让我们进一步打开包装。

1.模拟反映了现实

该算法的目的是建立一个犯罪人的准确图像,然后可以用来推断相应的累犯风险——他们重新犯罪的可能性有多大。

这里的意图完全没有恶意——它旨在创造真实的现实反映。

2.模拟扭曲了现实

随着算法的开发,它需要访问数据点来运行风险评估。当特定的数据不容易获得时(大多数情况下不容易获得),开发人员求助于代理。

这可能意味着使用间接数据点,如一个人的家乡和相应的犯罪率,作为其重新犯罪风险的指标。因此,一个出生在高犯罪率地区的人会被自动认定为高危人群。

其他的“替身”包括从一个人被警察拦下搜查的次数中得出相关性。这明显忽略了一个事实,即在英国和美国,黑人不成比例地受到统一卫生系统法律的约束。

通过将相关性与因果性混为一谈,算法模型输出了一个扭曲的现实版本。

3.模拟掩盖了现实的缺失

由于自我延续的反馈循环,几乎不可能检测到算法是基于虚假的现实而工作的。

通过认定一名罪犯极有可能再次犯罪,该算法不只是简单地做出预测,而是积极创造实现预测的物质条件。

考虑一个在等待判决的人,他住在一个高犯罪率的社区。他很有可能来自这样一个地区,他的朋友或家庭成员有前科。利用这一标准,该算法给所述人分配高风险分数,导致最长的监禁时间。

这个人在监狱里呆的时间越长,一旦被释放,他们的工作前景就越渺茫,尤其是如果被释放到同一个高犯罪率的街区。在绝望的尝试中,如果这个人确实犯了另一个罪行,这就转化为算法表面上的胜利。

4.模拟变成了现实

对于观察者来说,情况的真实情况是完全模糊的。

无论一个人是否有可能再次犯罪,都要感谢算法产生的模拟模型,无论如何,他都被视为高风险。

正如鲍德里亚所说,

所有的越轨行为,不管是模拟的还是真实的,都有相同的后果。

我们现在踏上了超现实的土地,在这里现实和想象之间的区别毫无意义。这听起来可能很抽象,但正如我们上面提到的,它有着严重的现实后果。数学模型、数据结构和统计系统现在发号施令。

"现实本身仅仅开始模仿模型,而模型现在领先于并决定着现实世界."

(来源

那么我们能做什么呢

为了有效地根除算法偏差,我们需要审计算法。

通过大规模仔细检查算法的输入和输出,我们可以辨别它所依赖的潜在假设、前提和相关性。纠正这些错误可以作为改善自动化系统造成的不公正的起点。

以替代事实为特征的替代现实的前景正在迅速成为现实。除非我们接受算法透明性、问责制和审查,否则我们几乎没有机会抵御这一迫在眉睫的威胁。

分析如何帮助企业

原文:https://towardsdatascience.com/how-analytics-can-help-business-84ae8ca76a6d?source=collection_archive---------26-----------------------

这篇文章的目的是解释如何以简单的方式使用 Python 来帮助你的公司成长

如果你想自己使用这个方法,你可以在我的 github 访问我的代码。你所需要的只是关于蟒蛇熊猫的基本知识。

你可以在 Kaggle 在线零售数据找到我要用的数据。

理解手头数据的第一步是理解不同变量之间如何相互作用。

像往常一样,我们需要使用 pandas 从 CSV 读取数据:

正如您在上面看到的,我们的功能有限,但是我们可以使用数学和统计学从可用的功能中创建功能。

我们将使用的可用功能有:

发票日期

单价

CustomerID

国家

根据这些特性,我们将创建:

收入

百分比增长

用户类型(新客户和现有客户)

保留率

清理数据:

在删除空值和重复值、缩小范围到仅英国数据(因为它有最多的记录)、删除 2011 年 12 月的月份(因为 12 月的数据不完整)并将“InvoiceDate”对象更改为 DateTime 之后,我们得到以下结果:

现在,我们的数据从 541909 行 8 列减少到 349227 行 9 列。我们在删除空值和重复值时需要小心,因为我们不希望丢失太多数据,但是因为我们这里有足够的数据,所以我们可以承受丢失一些数据。

既然我们已经清理了数据,是时候写下清晰客观的 KPI 了,这些 KPI 根据每个企业的目标而有所不同。出于本文的目的,我决定选择每月的总收入作为 KPI。让我们来计算一下收入。

月收入:

收入 =单价数量*

使用熊猫来寻找每个月的收入。

现在有趣的部分,我使用来可视化数据。

正如你在上面看到的,收入从 2011 年 8 月开始上升。然而,2 月和 4 月显示出下降趋势。

计算月增长也很有用,你可以在下面找到。

上图显示,2011 年 11 月的收入增长了近 19%,最大的增长发生在 9 月,增长了近 60%。正如我们之前看到的,增长在二月和四月下降。让我们多评估,多了解数据。

每月订单数量:

我们使用与查找月收入相同的方法来查找月订单数。

正如我们所料,月订单数在 2 月(从 277k 下降到 212k)和 4 月(从 275k 下降到 259k)有所下降。但是 11 月份的月订单增加到了 58 万。

到目前为止,我们评估的所有指标都在 2 月和 4 月下降。这是一个回顾你的业务并找出收入下降的原因的时候,是因为不太活跃的客户还是客户订购较少?或者许多其他原因……我们应该继续调查其他一些重要指标,如新客户和现有客户,以便更多地了解数据,并能够评估保留率

新客户:

谁是新客户?对于每个企业来说,这可能会有不同的答案,就本文而言,我将新客户定义为以前从未购买过产品的客户。所以,我用。min() 函数查找第一次购买的客户。

现有客户:

既然我们计算了新客户和现有客户,我们就根据现有客户和新客户评估每月的收入

现有客户呈现积极趋势,企业现有客户多于新客户。

一如既往,良好的可视化使分析更有趣,感谢 Plotly,我们可以做出漂亮的图形。

该公司似乎在 2011 年 1 月获得了新客户,但随着时间的推移,新客户的数量呈下降趋势。再次,这是一个时间来审查你的 KPI,看看你是否在轨道上,如果需要改变目标,并问这样的问题:企业在 2011 年初获得新客户是由于巨大的促销活动,还是新产品?为什么企业没有获得更多的新客户?

现在我们有足够的信息来评估的保留率

保留率:

客户保留率 表示公司在给定时间段内保留的客户百分比。保留率流失率的反面,它显示了一个公司在特定时期内失去的客户的百分比。

Pandas 为分组和汇总数据提供了几个选项,为了本文的目的,我使用了 crosstab 函数,它构建了一个交叉制表表,可以显示特定数据组出现的频率。下表中的数字 1 表示该客户在该月活动,而 0 表示该客户在该月没有购买。

在 Python 的帮助下,我们可以通过计算上个月留存客户数总客户数来计算留存率。

我们可以看到,2011 年 11 月,只有 37%的客户被保留。

但是我们如何利用所有这些信息来做决定。正如彼得·德鲁克所说:

使用数据来了解您业务中的问题,从而在问题变成问题之前找到解决问题的策略。例如,在这种情况下,我们可以看到收入在 4 月份下降,因此如果我们诊断出问题,我们就可以在问题变成问题之前解决它。我们还观察到,2011 年 3 月和 9 月的保留率较低,而 8 月的保留率非常高,因此有必要了解客户没有与我们一起购物的原因。这是由于新产品的推出,糟糕的客户服务,还是缓慢的市场?

所有这些信息对于帮助企业发展都很重要,使用数据科学来分析这些信息有助于企业有效应对不断变化的业务环境,并回答以下问题:

  • 问题的原因是什么?(报告)
  • 为什么会这样?(诊断)
  • 未来会怎样?(预测)
  • 最好的前进方式是什么?(建议)

在下一篇文章中,我将更多地介绍数据科学如何帮助您的业务增长,以及如何预测客户流失。

人们如何以及何时使用公共图书馆

原文:https://towardsdatascience.com/how-and-when-people-use-the-public-library-1b102f58fd8a?source=collection_archive---------25-----------------------

西雅图公共图书馆历年来的借阅趋势。

2018 年 1 月 6 日更新: 西雅图公共图书馆的伙计们指出,我使用了一个过时的库存数据集来制作这篇帖子旧版本中发布的列表。该错误导致我的分析忽略了自 2017 年 9 月以来添加到库中的所有项目。我已经更新了数据集,下面的分析也是最新的。!非常感谢来自 SPL 的大卫发现了这个错误!

公共图书馆什么时候最忙?退房高峰是在一月份阅读决议时还是在夏天海滩度假时?

Image from pexels.com

公共图书馆是社会的伟大机构之一。它们为任何有兴趣阅读、学习和与社区交往的人提供了一个机会。

人们从公共图书馆借出什么、如何借出以及借出多少可以提供一个有趣的视角来观察社区的感受和行为。

数据

我使用这个数据集以及数据的原始来源来探索来自西雅图公共图书馆的结帐。我使用的最终数据集包括从 2006 年到 2018 年 12 月 26 日的所有结账项目。除了结帐记录之外,数据集还包括详细的库存和数据字典,以便将结帐记录转换回物理项目标题、类型和作者。

如果你错过了,我使用相同的数据集创建了从 2006 年到 2018 年每年的“最多检出”项目列表。你可以在这里找到那个帖子。

方法学

所有的检出加在一起(从 2006 年到 2018 年)达到了大约 6700 万条记录,这对于一次加载所有记录进行分析来说是相当大的规模(特别是因为这些记录附有它们的元数据)。这些文件是按年份分开的,因此人们可以一个接一个地加载每年的数据集,但是我希望能够一次完成跨年份的分析。我使用的解决方案是从每年的结帐记录中随机抽取 10%的样本,并创建一个包含所有这些样本的文件。这给我留下了一个具有代表性的数据集,包含所有可获得年份的约 670 万条记录。

我还创建了一个数据集,其中包含所有的唯一项以及它们被检出的次数(这是从整个数据集创建的,而不是样本)。我用这个数据集得到了每年最常结账的清单。

让我们深入分析一下结果。

历年结帐

我们观察到图书借阅数量总体上呈稳定趋势(同样,不包括续借),每年不超过 400 万次。

视听借阅量在 2009 年达到高峰,此后呈缓慢但稳步下降的趋势。这可能是因为流媒体服务(如网飞的电视和 Spotify 的音乐)的崛起,这些服务可以轻松(有点)负担得起地点播大量电视和音乐,无需等待时间。

由于这个数据集只针对实体图书,我想知道图书借阅量是否会保持稳定,但越来越多的用户会借阅电子书。

检验时间趋势

让我们探索一下人们从图书馆借阅图书时表现出的趋势。我研究了一天中的时间、一周中的日期和一年中的月份的趋势。

一天中的时间

让我们从最微观的时间趋势开始,一天中的时间。西雅图公共图书馆通常从上午 10 点到晚上 8 点开放。它在周五和周六下午 6 点关门,周日减少了营业时间(主要是下午 1 点至 5 点)。

我们在数据中看到,下午 4 点是最受欢迎的结账时间。对于书籍和 DVD/CD 来说都是如此。我们还发现,尽管这一趋势在过去几年中略有变化,但在数据集中,下午 4 点一直是每年最受欢迎的结账时间。但我们看到,下午 1 点至 5 点之间的时间也不远了。

我们还看到,数字产品(DVD 和 CD)的趋势几乎与书籍相同。即使我们观察一周中的某一天和一年中的某一月的趋势(见下文),这一观察仍然成立,它表明人们不会为了他们的图书和数字需求而单独去图书馆。

Figure 1. Checkouts by Time of Day. On the far right plot, darker lines represent more recent years.

星期几

看了一天中的时间趋势,让我们看看一周中的一天。就像我上面提到的,西雅图公共图书馆每天开放,周五和周六的开放时间略有减少,周日的开放时间大幅减少。

我们看到周六是最受欢迎的借阅日,无论是书籍还是 DVD/CD。我们再次看到,尽管 2009 年出现了趋势变化,周六仍然是数据集中所有年份中最受欢迎的一天。此外,周五和周日是最不受欢迎的日子。

当我们观察这些年的趋势时,我们发现在 2009-2010 年左右发生了变化,星期五变得越来越不受欢迎。这可能是由于图书馆开放时间的变化引起的吗?趋势改变后,周一和周二似乎恢复了周五之前“下降”的退房率,周六保持相对稳定。

Figure 2. Checkouts by Day of Week. On the far right plot, darker lines represent more recent years.

一年中的月份

最后,让我们看看月份的时间趋势。当人们去度假并需要一本好书阅读时,或者当人们开始新的决心时,也许在新年前后,退房会达到高峰吗?

似乎两者都有一点,即使没有主要的趋势,最高值出现在 7 月,最低值出现在 2 月和 9 月。考虑到并非所有月份都有相同的天数,趋势会变得更加稳定。然而,年初和夏季似乎是最受欢迎的退房月份,九月和十二月最不受欢迎。

我们再次看到,DVD/CD 和书籍的趋势基本相似,但我们确实看到,12 月图书借阅量比视听产品下降得多。相反,我们看到书籍在夏季的几个月里比视听产品表现更好。

Figure 3. Checkouts by Month of Year. On the far right plot, darker lines represent more recent years.

现在你知道了:下午 4 点,周五和 1 月& 7 月是西雅图公共图书馆最繁忙的借阅时间,主要是图书和 DVD/CD。尽管我们观察到了一些变化,如从 2009 年起周五退房率下降,但这些趋势在数据集中的所有年份(2006 年至 2018 年)也基本保持不变。

就像我上面提到的,这个数据集只针对实体物品,毫无疑问,这是一个向更多数字物品的转变,尤其是在西雅图这样的科技城市。为了对趋势有一个全面的了解,看看数字结账也是非常有趣的。

这个数据也只针对西雅图的公共图书馆。你知道任何其他公开他们数据来源的公共图书馆吗?调查不同城市的趋势是否不同会很有趣。

感谢阅读。

你可以在这里 找到我关于西雅图 PL(使用相同数据源) 最多检出商品的故事。

如何以及何时使用圆形图

原文:https://towardsdatascience.com/how-and-when-to-use-a-circle-graph-b91f6910cc63?source=collection_archive---------24-----------------------

你知道吗,一个圆,是的一个 ——一个圆图形的基础,曾经是一个神。或者,至少在公元前五世纪,古希腊哲学家恩培多克勒将它标记为一个。

很神奇,对吧?

在希腊,圆是无限的象征,但是对于我们当中的技术人员来说,圆是一些最有用的发明的灵感来源,比如轮子。

同样,圆也是圆图的基础。

圆形图,通常也称为饼图(听起来很熟悉吧?)是一个简单的、视觉上很吸引人的图表,它分为几个楔形,每个楔形代表一个数据值。

这是显示统计数据最常用的图表之一,所以我们当然不能想当然地认为它受欢迎。

这就是为什么我们把这篇文章献给圆形图。我们将从圆图的定义开始,跳到它的重要性,最后深入探讨如何以及何时使用它。我们走吧。

什么是圆图?

你可以把圆图想象成一个比萨饼。所有的比萨饼切片都是数据的代表,就像饼图中的切片一样。如果你不均匀地切比萨饼,你会得到不同的数据切片。

有道理吗?

所以让我们从圆图的经典定义开始。圆形图是数据的圆形表示,不同的切片表示总的百分比。圆圈中的每一个楔形都与它所代表的数量成正比。

因为它的每个切片都是一个数据代表,所以圆形图在向不知情的读者有效地传达数据方面起着至关重要的作用。

使用圆形图的优势

饼图是大众媒体和商业展示的宠儿,也是市场营销和销售中常见的数据代表。他们还偷偷溜进社交媒体源,在那里他们可以用赏心悦目的方式分享无聊的数据。

圈图如此广泛的应用归功于它的优点。就是这么简单易懂。最重要的是,圆形图在信息可视化方面胜出。

这里有一个饼状图的优点。

圆形图以易于理解的方式展示数字信息。

“等等,让我去拿我的老花镜,”从来没有饼状图读者说。

这是因为信息以圆形图的方式呈现,这很简单,很容易理解。相比之下,大多数其他图形类型需要解释其轴任一侧的数字。

圆圈是信息可视化的专家。

信息可以大致以两种图形类型呈现——统计图形和信息可视化。统计学家 Anthony Unwin 和 Andrew Gelman 指出了两者的区别

据他们说:

  • 统计图是数据迷的一种,因为他们的主要目标是准确地传递数据。
  • 信息可视化关注的是抓住观众的注意力,这也是饼状图的卑微原因。

简而言之,圆形图是营销人员用来讲故事的合适的视觉辅助工具。然而,如果目标是呈现准确的数据,企业家们可能不得不依赖其他图表。您可以在后面的章节中了解更多信息。

圆形图是圆形的。

事实是,我们人类喜欢圆圈。正如多项研究证实的那样,这是因为我们将弯曲的形状与健康和生命联系在一起,将尖锐的形状与危险联系在一起。

众所周知,棱角分明的形状也会引发恐惧,进而引发厌恶和厌恶。自然地,这有利于曲率和随后的饼状图。

饼图很容易构建。

虽然我们已经讨论了饼状图是如何给你的观众带来视觉娱乐的,但是现在我们也该看看它们对你有多大的帮助了。

自从图形出现以来,圆图很容易构建,只需要数据、指南针和铅笔。

然而,随着技术的进步,量角器和笔的组合被 Excel 和其他电子表格程序边缘化了,这些程序帮助开发了饼状图。

但是说实话,这些图表在视觉上远不如使用 Visme 这样的设计工具制作的圆形图表丰富。

使用 Visme 时,您只需将数据记录到中,并根据您的喜好进行定制。例如,在 Twitter 上,纽约证券交易所社交媒体负责人 Matthew Kobach 进行了一项有趣的调查。

我们使用这个现成的 Visme 模板将数据转换成饼状图。我需要做的唯一工作就是编辑模板以添加数据并更改配色方案,我的圆形图已经准备好了:

何时使用圆形图

这是一个棘手的问题。您应该将它用于所有类型的可用数据吗?还是应该将其指定为所选数据类型的数据代表?简而言之,圆图只适用于特定的情况。

让我们从什么时候可以使用圆图开始。

当数据变化时,使用圆形图。

您需要不同的数据值,然后才能将它们可视化到饼图中。假设你有 67%和 33%的值。这些在如下所示的饼图中会很好看:

但是,如果您有两个相等的数据值,例如 50%和 50%,您可能不希望使用圆形图进行数据可视化。

想想地球的南北半球就是一个恰当的例子。他们把我们的星球分成相等的两部分,用饼状图来表示它们是没有意义的。

对于等值数据,您宁愿写下数字,然后在饼图中显示它们。或者,使用 Visme 制作一个视觉上吸引人的图形。

当您最多有 7 个数据片段时,请使用圆形图。

其次,当您有 2-7 个数据条目时,使用圆形图。有 7 个以上楔形的饼图最终看起来很混乱,如下例所示。在这种情况下,你的大脑开始将楔形感知为一个,扼杀了图形的整个目的。

换句话说,圆形图中的数据切片越多,其可读性或易理解性就越差。所以养成坚持最多吃七片的习惯。

当你比较整体的各个部分时,使用圆形图。

最后,当你从整体上比较数据时,使用圆形图是合适的。例如,比较一家公司的不同部门就是比较整体的各个部分。

然而,比较不同的公司导致比较不同的整体。所以你没有资格使用饼状图,因为不同的公司不能构成一个有意义的整体。

何时不使用圆形图

现在你知道了什么时候使用圆形图是最好的,让我们来看看什么时候创建圆形图是没有意义的。

当你有相似的数据值时,不要使用圆形图。

饼图不适用于数据条目之间差异很小的时候。例如,数据显示为 23%、25%和 26%。当您在圆形图上绘制它们时,代表每个值的切片在大小上是相似的。

如果你有这样的可用数据,用一个条形图让微小的差异变得明显。

当你有相似的数据值时,不要使用圆形图。

饼图不适用于数据条目之间差异很小的时候。例如,数据显示为 23%、25%和 26%。当您在圆形图上绘制它们时,代表每个值的切片在大小上是相似的。

当准确性是游戏的名称时,不要使用圆形图。

虽然圆形图本质上很醒目,但它们在显示精确值时并不十分准确。

原因?饼图中的数据很容易操作。例如,使用 3D 效果。这些会误导读者认为切片比实际要宽。

研究人员说,正如他们得出的结论一样,我们不能像比较长度一样估计角度的相对大小(例如,在条形图的情况下)。这使得阅读饼图不准确。

我们也倾向于低估锐角(小于 90 度的角),而高估钝角(90 到 180 度之间的角)。

当你需要显示一段时间内的模式、原因、结果或变化时,不要使用圆形图。

另一个不能依赖饼图的情况是当你需要显示一段时间内的模式或变化时。普通的舍入无法像具有精确数值的图表那样显示比较。

首先,它不擅长显示精确的值。第二,它很容易操作。

因此,在绘制跟踪更改的数据时,最好选择折线图,而对于跟踪更改以及不同组之间比较的数据,最好选择条形图。

毫不奇怪,Visme 可以帮助您实现这两个目标。这里有线图模板条形图模板供你入门。

如何创建圆形图

开始使用圆图并不那么具有挑战性,即使你没有注意你的数学老师。多亏了 Visme 这样的饼状图制作工具,你可以在几分钟内设计出一个圆形图。

但是怎么做呢?让我们用 6 个简单的步骤来回答这个问题。

1.收集您的数据。

快速回顾一下,您需要至少两个不相似的数据变量。此外,确保您的饼图最多包含 7 个楔形。

2.选择您的圆形图表生成器来设计图表。

使用电子表格创建饼图的日子已经一去不复返了。你现在能做的就是尝试 Visme 这样高效易用的工具。

下面是该过程的视频演示:

3.选择你的配色方案。

饼图对每个楔形使用不同的颜色和对比度,唯一的目的是增强可读性。这是因为我们的视觉大脑能够迅速注意到差异和对比。因此,添加颜色可以帮助事物脱颖而出。

为此,最终确定不屏蔽数据的颜色。你还需要小心选择正确的颜色对比。选择不相配的颜色会使图表看起来令人厌恶。

一个专业建议是挑选从暗到亮色调变化的颜色,并从图形的开始部分到最后一点调整它们。或者,更深入一点,根据色彩心理学选择色调,以吸引观众的注意力。

4.顺时针排列数据。

现在你已经选好了颜色,开始整理数据。你可以简单地把所有的数据放在一个图表里,然后你就可以开始了。对吗?

除了它不完全像那样工作。当你把所有的数据随机放在一起时,它看起来没有吸引力。为什么?因为每个切片大小不一。

为了打破图表中的某种风格,你需要按大小顺序顺时针排列不同的数据扇区。因此,您得到的是一个包含数据值的切片图,当您顺时针开始并完成该圆时,数据值会减少。

至于不属于某个特定类别的数据,你可以将它们集中在一个类别中,如果是调查,就将切片命名为“其他答案”,如果是你收集的数据,就将其命名为“其他类型”。

5.用标题、图例和简短的描述性句子来标记你的圆形图。

没有标签的饼图是不完整的。因此,您需要添加三个描述:

  • 标题:暗示你的图表是关于什么的标题。
  • 图例:解释圆形图中每种颜色代表什么的按键。它出现在图表的两边(图表 A)。或者,根据 Tufte 的数据墨水比率标记数据切片(图表 B ),建议用数据标签替换图例以简化图表。
  • 底部的一个短句:这有助于描述你的圆图或解释你的数据来源。

6.最后,做斜视测试。

斜视测试需要你部分闭上眼睛来模糊你面前的图像。目的是创造出一个突出的设计。斜视测试适用于所有设计工作,包括圆图。事实上,这是制作图表的一个至关重要的练习。

斜视测试在以下方面有所帮助:

  • 允许您删除多余的行
  • 有助于做出客观的设计
  • 确保数据被恰当地突出显示给读者

另外,如果你是设计新手,这里有一个避免常见设计错误的资源

使用圆形图的提示

我们已经走了很长一段路,但在我们结束之前,让我们快速讨论一下你需要记住的三个圈图最佳实践。

开始了。

如果需要表示两组相关数据,请使用多个饼图。

这最适合于比较两个或多个相同类别但变量不同的数据集。一个恰当的例子是年龄和婚姻状况变量的差异,其余数据保持不变。

不过这里有一点需要注意——图表的颜色和顺序保持不变。这背后的原因很简单。这有助于比较。

3D 和爆炸效果很酷,但并不总是如此。

3D 效果不言自明。你给你的图表添加三维效果。类似地,爆炸效果与图形的爆炸切片相关,因此它们是分开的。

这两种效应听起来都很有趣,但它们并不是在所有情况下都有效。

这是因为 3D 和爆炸效果使得在圆形图中比较不同的数据类别具有挑战性。此外,他们还夸大了数据的真正价值。这一切都要归功于的最佳效果,从而诞生视觉插图,进而欺骗你的视觉。

在下面的例子中,当看起来后者比前者更宽时,很难区分 Chessington World of Adventures 或 Legoland,Windsor 是相同大小的切片。

幸运的是,如果你是这种设计效果的粉丝,那么我们有一些好消息。爆炸效果可以在某些情况下使用,例如当您想要强调一个切片中的信息时,如下所示:

您可以制作圆形图的动画。

动画在吸引观众的同时也让解释数据变得容易。在动画可视化和静态图形的比较中,动画得分最高。

胜利的功劳归于动画在吸引注意力、帮助观众解读数据和进行价值比较方面发挥的作用。

但是你不需要成为一个 Photoshop 专家来制作动画。改为使用 Visme 创建动画图表

今天就开始设计圆形图

饼图一直是读者的最爱,以一种可抓取的格式呈现数据。

如果你还没有画出一个圆形图,今天就开始注册 Visme 吧。您可以创建视觉上令人惊叹的图表,而不必担心从头开始设计。

如果你已经是一个饼状图爱好者,使用 Visme 上的饼状图模板来提升你的设计水平。那么,你找到你的圆形图的完美模板了吗?

本帖 原版 最早出现在 Visme 的 视觉学习中心

posted @ 2024-10-13 15:29  绝不原创的飞龙  阅读(15)  评论(0编辑  收藏  举报