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

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

原文:TowardsDataScience Blog

协议:CC BY-NC-SA 4.0

使用 Hummingbird 将传统机器学习管道标准化为张量计算

原文:https://towardsdatascience.com/standardizing-traditional-machine-learning-pipelines-to-tensor-computation-using-hummingbird-7a0b3168670?source=collection_archive---------38-----------------------

图片由尼克·费因斯提供(来源于 unsplash)

来自微软研究员蜂鸟包的应用

背景和挑战📋

T 这里仅仅是没有新闻中提到的机器学习深度学习人工智能的日子。说到传统 ML 我想提一下发展了很久的基础算法;与深度神经网络 (DNNs)形成对比。尽管深度学习近年来在计算机视觉、自然语言处理或推荐系统等许多方面发展迅速,...传统的机器学习仍然完全占据主导地位。

Kaggle 调查 2019 结果(图片由作者提供)

另一项 调查 研究了 2017 年 7 月(GH2017)在 GITHUB 上的 120 万个公开可用的数据科学笔记本和 2019 年 7 月(GH2019)的 510 万个笔记本中的“使用最多的库”,表明最广泛使用的四个库是 NumPy、Matplotlib、Pandas、Scikit-learn (不是 DNNs 框架此外, Scikit-learn 的知名度大约是 PyTorch 和 TensorFlow 总和的 5 倍,而且增长速度也超过了这两家公司。

它们仍然备受关注的主要原因是解释黑盒的能力,以便在软件基础设施中为业务、更简单和更有效的使用做出正确的指示。最近,不仅是大型企业,还有中小型企业都在寻求机器学习来帮助解决业务挑战,包括预测性维护、客户流失预测和供应链优化。对于企业来说,他们更喜欢理解数据,研究每个参数的特征,并彻底考虑它们,而不是仅仅朝着高度准确的预测前进。

然而,交互式或分析型企业应用程序有一条关键路径,即模型评分。在数据科学解决方案的总成本中,模型得分占45–65%(基于 AWS 报告1)。通常,在部署时,甚至在培训期间,ML 模型被多次评分并应用于实际工作应用中(例如,横向扩展批量或交互式服务、个人计算机、移动和物联网设备)。由于可移植性、可维护性、部署和监控方面的考虑,评分控制了复杂性。因此,评分模型的延迟(计时)和吞吐量是企业非常关心的问题。

到目前为止,最流行的工具包像 ML.NET 的(。NET)、Scikit-learn(基于 Python)和 H2O(基于 Java)来生成操作符的预测管道(pipeline ),例如训练模型、预处理程序、特征化器、缺失值估算器,但是它们主要是针对训练而优化的,而不是针对部署期间测试集的评分。这些框架的可移植性通常受限于在许多环境中支持它们的操作者。优化模型评分的解决方案之一是通过将复杂多样的传统 ML** 转化为一小组简单张量,从 DNNs 中利用有向无环图 (DAGs)的优势。基于这一想法,许多系统已经被建立,如 ONNX 运行时【2】、torch script【3】和TVM【4】,利用了神经网络 DNN 运行时优化的相对计算简单性,但是它们在与**传统 ML 一起工作的能力和适用性方面仍然有限。****

最近发布了蜂鸟- 一个来自微软研究团队的库,它可以将特征化运算符和传统 ML** 模型编译成一小组张量运算,以增强 CPU 和硬件加速器(GPU,TPU)的高效计算。它为降低基础设施复杂性和传统 ML 的模型评分成本开辟了新的途径。在接下来的章节中,系统架构和实现在三个基本研究问题方面的重点将使您对其有一个清晰的概述。**

传统的最大似然算子(基于线性代数的,如线性模型,算法的,如决策树)可以转化为张量计算吗?

张量空间中产生的(密集)计算能与我们作为输入(例如,遍历一棵树)得到的(稀疏)命令性选择竞争吗?

HUMMINGBIRD 能帮助降低软件复杂性和提高模型可移植性吗?

技术亮点📄

****蜂鸟的高层架构(图片由作者提供)

****蜂鸟库是基于对传统 ML 流水线周期寿命的简单观察。一旦应用了特征并训练了模型,就可以将整个管线符号化为将输入特征转换为预测分数的函数(例如,对于二元分类为真或假)。因此, Hummingbird 的目标是将流水线中每个操作符的预测函数(而不是训练算法)编译成张量计算,并将它们适当地联系起来。为此,蜂鸟引入了三个主要组件:

  1. ****管道解析器:生成内存中的中间表示(IR)对象,用其输入参数和相关的输入/输出依赖关系对给定预测管道中的每个运算符进行编码。
  2. ****优化器:为操作符搜索潜在的编译策略,并产生潜在的修改 IR。
  3. ****张量 DAG 编译器:挑选优化的 IR 对象,并将其编译成遵循目标 DNN 运行时格式的张量运算。

蜂鸟目前支持将很多有代表性的算法算子编译成张量计算。在实践中,没有一种策略始终支配其他策略,它取决于每个输入和模型结构。更多细节,可以去看看他们的Github或者这篇 论文

在这篇文章中,介绍了基于树的模型的方法。编译基于树的模型有三种不同的策略:通用矩阵乘法 (GEMM)、 TreeTraversal、PerfectTreeTraversal。

  • GEMM 策略可以在批量小或者有大量小树的模型上高效运行(CPU 上 D≤ 3,GPU 上 D≤10——D 是树的高度)。
  • TreeTraversal: 对于大批量和较高的树(D > 10), TreeTraversal 策略通常优于 GEMM 策略。
  • PerfectTreeTraversalTreeTraversal 稍快,因为索引查找次数减少,合并内存访问更好,但如果树太深, PerfectTreeTraversal 会遇到内存占用问题(D≤ 10)。

让我们来看一个简单的例子,看看蜂鸟如何用 GEMM 策略编译简单的回归树。在这个例子中,树将输入作为具有五个元素( x ∈R5)、四个决策节点(橙色)和五个叶节点(蓝色)的特征向量。蜂鸟将将决策树模型翻译成如下神经网络:

简单回归树(作者图片)

假设我们想要计算这个观察的输出

  • 步骤 1: 将输入张量乘以张量 A(从上面的决策树模型计算得到),该张量捕获输入特征和内部节点之间的关系。然后将其与张量 B 进行比较,张量 B 被设置为每个内部节点的阈值,以创建表示从输入到节点的路径的高音输入路径。在这种情况下,树模型具有 4 个条件,输入向量是 5,因此,张量 A 的形状是 5×4,张量 B 是 1×4。

  • 步骤 2: 张量 p 将与张量 C 相乘,张量 C 捕捉内部节点是否是该内部节点的父节点,如果是,它是在左子树还是右子树中(左= 1,右=-1,否则=0),然后检查与张量 D 的等号,张量 D 捕捉从叶节点到树根的路径中其父节点的左子节点的计数,以创建表示从节点到输出的路径的 tenor 输出路径。在这种情况下,该树模型具有 4 个条件的 5 个输出,因此,张量 C 的形状是 4x5,张量 D 是 1x5。

  • 第三步:张量 P 将与捕获叶节点之间映射的张量 E 相乘,以推断最终预测。在这种情况下,树模型有 5 个输出,因此,张量 E 的形状是 5x1。

从这个例子中,我们可以清楚地想象出蜂鸟如何编译一个基于树的模型。此外,蜂鸟还有其他技术可以高效地编译传统的 ML ,比如自动广播、最小化操作符调用、… 目前蜂鸟支持超过 40 个 scikit-learn 操作符(Github)

Scikit-learn 目前在蜂鸟中支持的操作符(图片由作者提供)****

即使 Hummingbird 非常有用,为企业和数据科学家节省了大量时间和金钱,但它仍处于开发阶段,有许多局限性,需要社区做出更多贡献来改进:

  • 不支持任意用户定义的运算符
  • 不支持稀疏数据
  • 不支持文本特征提取
  • 目前正在开发中

实验评估📊

让我们用加州住房数据集来测试蜂鸟在回归模型中的表现。总观察值为 20640,有 8 个数字输入特征,目标变量为房屋价值中值。这个数据集是从 StatLib 存储库中获得的,您也可以使用[**sklearn.datasets.fetch_california_housing**](https://scikit-learn.org/stable/modules/generated/sklearn.datasets.fetch_california_housing.html#sklearn.datasets.fetch_california_housing)函数下载。

在本实验中,从简单到复杂测试了 4 种不同的模型,分别是线性回归、决策树回归、RandomForestRegressor 和 xgb 回归。要使用的指标是 MSE 和运行时间,显示在帖子的末尾。

毫无疑问,使用复杂的模型,准确性会提高,但训练时间以及评分时间也会增加。让我们将这些模型编译成张量运算符,并检查编译是否有助于减少运行时间。首先,这些转换后的模型将在 CPU 中运行。

运行时间在所有情况下都没有减少。原因是测试数据的数量不大,每个模型本身的复杂程度是正常的。让我们看看转换后的模型在 GPU 中运行的性能。

在这段时间里,运行时间比在 CPU 中运行减少了。然而,与原始模型相比,只有 RandomForestRegressor 和 XGBRegressor 的运行时间有所减少,而 LinearRegression 和 DecisionTreeRegressor 的运行时间仍然较高,因为模型本身很简单。所有结果汇总如下。

最后的想法📕

很明显可以看出模型的复杂性(或准确性)与运行时间之间的权衡。由于测试数据的数量、数据集的复杂性和模型的复杂性,在某些情况下将传统模型转换为张量算子无助于减少评分时间。你可以自由地用更复杂的特征符来测试编译模型的性能,在管道模型中如使用变换技术(RobustScaler,StandardScaler,KBinsDiscretizer,..)、插补技术(SimpleImputer,MissingIndicator,..)或特征提取技术(多项式特征,特征散列器,..)来查看转换为张量运算符的效率。

如果你想进一步讨论,可以联系我。这是我的 Linkedin

尽情享受吧!!!👦🏻

参考

1亚马逊。亚马逊 sagemaker 的总拥有成本(tco)。https://pages.awscloud.com/rs/112-TZM-766/图片/亚马逊 _SageMaker_TCO_uf.pdf,2020。

[2] ONNX 运行时。https://github.com/microsoft/onnxruntime.

[3] TorchScript 文档。https://pytorch.org/docs/stable/jit.html.

[4]陈、莫罗、江、郑、严、科恩、沈、王、胡、策泽、盖斯特林和克里希那穆提。Tvm:深度学习的自动化端到端优化编译器,2018

星巴克提供分析

原文:https://towardsdatascience.com/starbucks-capstone-challenge-35e3b8c6b328?source=collection_archive---------32-----------------------

Udacity 的数据科学家纳米学位计划的顶点项目

索林·索尔布在 Unsplash 上的照片

项目概述

这是 Udacity 的数据科学家纳米学位项目的一个顶点项目。在这个项目中,给定的数据集包含模拟星巴克奖励移动应用程序上的客户行为的模拟数据。每隔几天,星巴克就会向手机应用程序的用户发出一次报价。优惠可以仅仅是饮料的广告,也可以是实际的优惠,如折扣或 BOGO(买一送一)。某些用户可能在特定的几周内收不到任何优惠。并非所有用户都收到相同的报价,这是使用该数据集要解决的挑战。

问题陈述

该项目的目标是将交易、人口统计和优惠数据结合起来,以确定哪些人口统计组最适合哪种优惠类型。这个数据集是真实星巴克应用程序的简化版本,因为底层模拟器只有一种产品,而星巴克销售几十种产品。

这一目标可以通过以下策略实现:

  • 探索和可视化数据。
  • 数据预处理。
  • 对清洁的预处理数据应用快速数据分析
  • 缩放数字特征。
  • 尝试几种监督学习模型。
  • 使用选择的度量(精确度)评估模型,然后在其中选择最佳的监督学习模型。
  • 如果结果需要改进,实现 GridSearchCV 以找到最佳参数(以提高所选模型的性能)。

数据集描述

数据包含在三个文件中:

  • portfolio.json —包含报价 id 和关于每个报价的元数据(持续时间、类型等)。)
  • profile.json —每个客户的人口统计数据
  • transcript.json 记录交易、收到的报价、查看的报价和完成的报价

以下是文件中每个变量的模式和解释:

portfolio.json

  • id(字符串)—优惠 id
  • offer_type (string) —一种优惠类型,即 BOGO、折扣、信息
  • 难度(int)——完成一项提议所需的最低花费
  • 奖励(int) —奖励是为完成一项提议而给予的
  • duration(int)-要约开放的时间,以天为单位
  • 频道(字符串列表)

profile.json

  • 年龄(整数)—客户的年龄
  • 成为会员日期(int) —客户创建 app 帐户的日期
  • 性别(str) —客户的性别(请注意,有些条目包含“O”代表其他,而不是 M 或 F)
  • id (str) —客户 id
  • 收入(浮动)—客户的收入

抄本. json

  • 事件(str) —记录描述(即交易、收到的报价、查看的报价等。)
  • 人员(字符串)—客户 id
  • time (int) —测试开始后的时间,以小时为单位。数据开始于时间 t=0
  • value —(字符串字典)—报价 id 或交易金额,具体取决于记录

韵律学

为了评估我们模型的性能,我们将使用准确性。选择这一指标的原因如下:

  • 因为我们有一个简单的分类问题,即要么:要约已查看,要约已完成。
  • 它使我们能够通过比较正确预测的数量与预测的总数(准确性的概念)来识别我们的模型预测得有多好。

解释性数据分析

1.投资组合数据集

该数据集包含 6 列:

  • 奖励(int) —奖励是为完成一项提议而给予的
  • 频道(字符串列表)
  • 难度(int)——完成一项提议所需的最低花费
  • duration(int)-要约开放的时间,以天为单位
  • offer_type (string) —一种优惠类型,即 BOGO、折扣、信息
  • id(字符串)—优惠 id

投资组合数据集的头。

投资组合数据集的探索显示了以下内容:

  • 该数据集既没有空值也没有重复值。
  • 有三种类型的优惠:“BOGO”(买一送一)、“信息”和“折扣”。
  • 数据集中包括 4 个报价,分类为:“BOGO”,4 个报价分类为“折扣”,2 个报价分类为“信息”。
  • “难度”一栏的单位是美元,并不反映获得奖励的难度。重新缩放该功能是一个有用的步骤。这需要在建模之前完成。

2.个人资料数据集

该数据集包含 5 列:

  • 性别(str):客户的性别(M:男性,F:女性,O:其他)。
  • 年龄(int):客户的年龄。
  • id (str):客户 id。
  • become _ member _ on(int):客户创建 app 账户的日期。
  • 收入(浮动):客户的收入。

配置文件数据集的头。

剖面数据集的探索和可视化显示如下:

  • 数据集没有重复的行。
  • 该数据集在“性别”、“收入”变量上各有 2175 个缺失值。
  • 顾客的年龄从 18 岁到 101 岁不等。尽管这 2175 名客户的注册年龄是 118 岁,但我仍然认为这个特定年龄是异常值。很明显,数据集中的这 2175 行有问题。

探索和可视化“性别”、“收入”和“年龄”变量

“性别”和“收入”变量中缺失的值仅与 2175 名 118 岁注册的客户相关。换句话说,118 岁的顾客没有登记的“性别”和“收入”。这需要在数据预处理部分进行清理。

年龄分布

根据现有数据,客户分为三个“性别”类别(M、F 和 O)。记住上面的观察结果,有 2175 个值缺失,男性顾客(8484 名男性)多于女性顾客(6129 名女性),男性顾客占 57%,女性顾客占 41%。然而,有 212 名顾客选择了“O”作为他们的性别。

收入分配栏

顾客的收入从 3 万到 12 万不等,大多数顾客的收入在 5 万到 7.5 万之间。

3.抄本数据集:

该数据集包含 4 列

  • 人员(字符串)—客户 id
  • 事件(str) —记录描述(即交易、收到的报价、查看的报价等。)
  • value —(字符串字典)—报价 id 或交易金额,具体取决于记录
  • time (int) —测试开始后的时间,以小时为单位。数据开始于时间 t=0

对抄本数据集的探索显示了以下内容:

  • 数据集既没有重复的行,也没有缺失的值。
  • 如上所述,“值”列是一个字典,我们可以在其中应用某种特征工程来提取有用的数据,这些数据肯定会有助于我们未来模型的成功。该步骤将通过数据预处理(争论/清理)部分完成。
  • 该数据集中有四种类型的事件:“交易”、“收到报价”、“查看报价”和“报价完成”。
  • 所有被分类为“事务”的事件在其“值”列中都没有“已提供”。

数据处理

投资组合数据集:

处理这些数据包括:

  1. 将“id”列重命名为“offer_id”。
  2. 将“持续时间”列的单位从天更改为小时。
  3. 将“duration”列重命名为“duration_h ”,表示测量单位为“小时”
  4. 使用最小最大缩放器标准化“难度”和“奖励”特征。
  5. 使用 one-hot 编码从“channels”列创建虚拟变量,然后删除“channels”列。
  6. 用更简单的 id 替换“优惠 id”。
  7. 将“报价类型”替换为代表各报价类型的整数,如下所示:
  • BOGO
  • 打折
  • 报告的

原始投资组合数据集

数据处理后的投资组合数据集

配置文件数据集:

处理这些数据包括:

1.预处理“id”功能:

  • 将“id”列名重命名为“customer_id”。
  • 重新排列列,使“customer_id”列成为数据集中的第一列。
  • 用最简单的数值替换 customer_id 字符串值。

2.预处理“年龄”特征:

  • 将年龄= 118 替换为 NaN 值。
  • 删除没有“年龄”、“性别”和“收入”的客户(删除行)。
  • 将“年龄”和“收入”列的数据类型更改为“int”。
  • 创建一个新列“年龄组”,其中包括每个客户所属的年龄组
  • 将“年龄组”分类标签替换为相应的数字标签,如下所示:

1:青少年

2:年轻成人

3 岁以上:成人

4:老年人

3.预处理“收入”功能:

  • 创建一个新列“income_range ”,其中包括客户收入所属的收入范围。
  • 将“收入范围”分类标签替换为相应的数字标签,如下所示:

大于 1:平均(30,000–60,000)

2:高于平均水平(60,0001–90,000)

3:高(超过 90,000)

4.预处理“性别”特征:

  • 将“性别”分类标签替换为相应的数字标签,如下所示:

1: F(女性)

2: M(男性)

3: O

5.预处理“成为成员”功能:

  • 将' became_member_on '列的数据类型从 int 更改为 date,并将其设置为 otoe 中的适当格式一种可读的日期格式,如果需要,可以很容易地对其进行分析。
  • 向现有数据集添加一个新列“start_year”,该列将显示客户成为会员的年份(用于进一步分析)。
  • 向现有数据集添加一个新列“membership_days”,该列将显示自客户成为会员以来的天数(用于进一步分析)。
  • 创建一个新列“member_type ”,表示成员的类型:新成员、普通成员或忠诚成员,具体取决于其“membership_days”的数量。
  • 将“member_type”分类标签替换为相应的数字标签,如下所示:

1:新会员(1000 天或更短时间内的会员)

2:普通会员(1001-1600 天会员资格)

3:忠诚(超过 1600 天的会员资格)

  • 删除“年龄”、“收入”、“成为会员日期”和“会员天数”列,因为不再需要它们。

原始轮廓数据集

处理后的剖面数据集

抄本数据集

处理这些数据包括:

1.将“time”列重命名为“time_h ”,表示测量单位为“小时”。

2.预处理“人”特征:

  • 将“人员”列重命名为“客户标识”。
  • 将“customer_id”列中的分类值替换为与每个客户 id 相对应的新初始化的数值,这些数值是由之前对“id”功能的预处理产生的

3.预处理“值”功能:

  • 将“值”列中存在的每个键提取到单独的列,而不是删除“值”列。
  • 用“不适用”值填写“报价 id”列中的所有 nan(即不适用)。
  • 删除“值”列,因为不再需要它。

4.预处理“事件”功能:

  • 从我们的 clean _ 抄本数据集中排除“交易”或“收到报价”的所有事件。
  • 将“事件”分类标签替换为相应的数字标签,如下所示:

1:报价完成

2:已查看报价

5.预处理“offer_id”功能:

  • 将“offer_id”列中的分类值替换为预处理投资组合数据集时使用的相应数值

原始抄本数据集

处理后的转录数据集

将三个清理过的数据集(投资组合、配置文件和交易)合并成一个主清理数据集

主数据帧

删除缺失值后的主数据集

主数据集的分析

对主数据报的快速分析包括一些问题,例如:

Q1——每个年龄组(青少年、年轻人、成年人和老年人)的常见优惠是什么?

所有年龄组中最常见的优惠类型是 BOGO,其次是折扣优惠。然而,最不常见的提议是信息性提议。我相信 BOGO 的优惠比星巴克的其他优惠更有吸引力。

Q2——基于收入最高的顾客的人口统计数据,男性还是女性?

高收入(9 万以上)的客户多为女性客户。然而,平均收入(30,000-60,000)的客户大多是男性。

Q3——男性或女性中,谁需要很长时间才能获得每份工作?

当谈到完成一项提议所花费的时间时,男性和女性非常接近。雄性和雌性都需要大约 17 天才能完成。

Q4——星巴克每年有多少新会员?

2017 年就新会员数量而言,是星巴克最好的一年。在我们的数据集中,大约有 38% 的客户在这一年注册为会员。

Q5 —男女都喜欢哪种类型的促销(优惠)?

我们得到的图表显示,男女都喜欢 BOGO 和折扣优惠,他们对信息性优惠的反应相同,他们似乎都对它不感兴趣。

Q6 —同一个客户的两份抄本的平均长度是多少?

客户完成报价的平均时间不到 16 天(372 小时)。

Q7 —在顾客查看的所有报价中,他们完成了多少报价?

数据建模

在这一部分,我试图建立一个模型来预测客户是会只查看报价,还是会查看&完成报价。由于该模型关注的是事件‘报价视图’‘报价完成’,我将只考虑事件‘报价视图’‘报价完成’的那些记录。换句话说,我不会将带有事件'交易或'报价已收到'的抄本包括在我的训练和测试集中。

说到特征,我打算只考虑那些我认为对我们的模型准确预测目标很重要的特征。

那些特征是:' time_h ',' offer_id ',' amount ',' reward_x '(将被重命名为' reward '),'难度',' duration_h ',' offer_type ',' gender ',' age_group ',' income_range ',' member_type '。

****目标(标签)是:‘事件’,它将保存数值:

1 : 报价完成

2 : 报价已查看。

以下是建模前要素数据框的外观:

我的特征和标签的形状是:

  • 训练特征形状:(65843,11)
  • 训练标签形状:(65843,)
  • 测试特征形状:(16461,11)
  • 测试标签形状:(16461,)

对于建模部分,我尝试了六种不同的模型,结果如下:

上表显示了与使用不同监督学习模型相关的准确度分数。如表中所示,我们在 4 个模型(共 6 个模型)的训练集和测试集上都有 100%的准确率。为了尽可能避免过度拟合,我将选择在测试集上给我最低精度分数的模型,这就是 KNeighborsClassifier 。在这个模型上,我在测试集上得到了 99.88%。我知道这是一个很高的分数,但我选择了这个模型,因为我相信它可以用于解决二元结果问题陈述:关于客户是否会查看报价(只是查看)或他是否会(完成报价),即查看&完成该特定报价。****

结论

通过这个项目,我试图分析星巴克提供的数据集,然后建立一个模型,可以预测客户是否会完成报价或只是浏览?

首先,我研究了每个数据集,将其可视化以获得对数据的整体理解。这还包括分析数据集的不同方面。然后,我转移到预处理部分。预处理数据是花费大部分时间和精力的任务。数据集有点棘手,包含的数据要求我使用我的争论/工程和预处理技能来获得三个数据集的最终干净版本。下一步是创建一些可以提高模型性能的潜在特性。这些特征是从原始的现有列派生出来的,但是包含在数据集中的值和简单值的范围较小。这方面的例子如下:

  • 从“年龄”功能派生的“年龄组”功能。然后,我将特征的分类标签替换为相应的数字标签,如下所示:

1:青少年

2:年轻人

3:成人

4:老年人

  • 从“收入”功能派生的“收入范围”功能。这包括客户收入所属的收入范围。然后,我将“收入范围”分类标签替换为相应的数字标签,如下所示:

1:平均(30,000–60,000)

2:高于平均水平(60,0001–90,000)

3:高(9 万以上)

  • “member_type”功能派生自“became _ member _ on”功能。当然,分类标签的特征已经被相应的数字标签所取代,如下所示:

1:新成员(1000 天或更短时间内的成员)

2:普通会员(1001-1600 天会员资格)

3:忠诚(超过 1600 天的会员资格)

对数据集的快速分析让我获得了以下见解:

  • 顾客的收入从 3 万到 12 万不等,大多数顾客的收入在 5 万到 7.5 万之间。
  • 根据现有数据,客户分为三个“性别”类别(M、F 和 O)。记住上面的观察结果,有 2175 个值缺失,男性顾客(8484 名男性)多于女性顾客(6129 名女性),男性顾客占 57%,女性顾客占 41%。然而,有 212 名顾客选择了“O”作为他们的性别。
  • 所有年龄组中最常见的优惠类型是 BOGO,其次是折扣优惠。然而,最不常见的提议是信息性提议。我相信 BOGO 的优惠比星巴克的其他优惠更有吸引力。
  • 高收入(9 万以上)的客户多为女性客户。然而,平均收入(30,000-60,000)的客户大多是男性。
  • 当谈到完成一项提议所花费的时间时,男性和女性非常接近。雄性和雌性都需要大约 17 天才能完成。
  • 就新会员数量而言,2017 年是星巴克最好的一年。在我们的数据集中,大约有 38%的客户在这一年注册为会员。
  • 男性和女性都喜欢 BOGO 和折扣优惠,他们对信息优惠的反应是一样的,他们似乎都对此不感兴趣。
  • 客户完成报价的平均时间不到 16 天(372 小时)。
  • 女性完成了她们所查看的要约的 75%,比男性多 16%,男性只完成了她们所查看的要约的 58%。女性似乎比男性更容易被升职说服。

丰富

虽然我相信“总有改进的空间”这句话,但我认为 KNeighborsClassifier 模型给了我很高的分数。试图改进这样的模型肯定会使我们陷入过度拟合的错误。因此,我不会建议对这个模型进行任何改进,因为我相信我们不需要试图获得更好的结果。

值得一提的是,我计划使用 GridSearchCV 来改进我将要选择的模型。这是我的计划,在被高分击中之前。

我相信我在预测模型方面取得了非常好的结果。我非常理解星巴克提供的数据。

由于总有改进的空间,我认为改进数据收集或解决与缺失数据或 NaNs 相关的问题的想法将非常有用。我认为,我们可以从这个数据集获得很好的见解,也可以建立很好的预测模型来解决与这个数据集相关的问题。这些模型的示例如下:

  • 构建一个可以预测向哪个客户发送哪种优惠的模型?
  • 建立一个模型,可以预测哪些客户会购买(不管是否有优惠)

反射

我喜欢在这个顶点项目上工作,它让我提高了我在数据预处理和建模方面的技能。在我看来,最困难的部分是决定问题陈述。这是因为薄弱的问题陈述肯定会导致其他工作被低估和重视。

预处理步骤是要完成的最长和最具挑战性的部分。数据集本身是鼓舞人心的。老实说,一切都很棒。

包含项目文件和数据集的 GitHub 存储库可以在这个链接中找到。

星巴克顶点挑战

原文:https://towardsdatascience.com/starbucks-capstone-challenge-b95b0931bab4?source=collection_archive---------50-----------------------

这个项目是 Udacity 数据科学纳米学位的一部分

图片来源: seattle.eater(免费用于商业用途)

介绍

星巴克提供了模拟数据,模拟星巴克奖励移动应用程序上的客户行为。每隔几天,星巴克就会向手机应用程序的用户发出一次报价。优惠可以仅仅是饮料的广告,也可以是实际的优惠,如折扣或 BOGO(买一送一)。某些用户可能在特定的几周内收不到任何优惠。并非所有用户都收到相同的报价,这是这个数据集要解决的挑战。

任务是将交易、人口统计和优惠数据结合起来,以确定哪些人口统计组对哪种优惠类型做出最佳响应。

数据包含在三个文件中:

  • portfolio.json —包含报价 id 和关于每个报价的元数据(持续时间、类型等)。).
  • profile.json —每个客户的人口统计数据。
  • transcript.json 记录交易、收到的报价、查看的报价和完成的报价。

以下是文件中每个变量的模式和解释:

portfolio.json

  • id(字符串)—优惠 id
  • offer_type (string) —优惠的类型,如 BOGO、折扣、信息
  • 难度(int)——完成一项提议所需的最低花费
  • 奖励(int) —为完成一项提议而给予的奖励
  • duration(int)-要约开放的时间,以天为单位
  • 频道(字符串列表)

profile.json

  • 年龄(整数)—客户的年龄
  • 成为会员日期(整数)—客户创建应用程序帐户的日期
  • 性别(str) —客户的性别(请注意,有些条目包含“O”代表其他,而不是 M 或 F)
  • id (str) —客户 id
  • 收入(浮动)—客户的收入

转录本. json

  • 事件(str) —记录描述(即交易、收到的报价、查看的报价等。)
  • 人员(字符串)—客户 id
  • time (int) —测试开始后的时间,以小时为单位。数据开始于时间 t=0
  • value —(字符串字典)—报价 id 或交易金额,具体取决于记录

问题陈述

我选择解决的问题是建立一个模型来预测客户是否会对报价做出反应。

以下是我在分析过程中遵循的主要步骤:

1-探索和清理给定的数据集。

2-组合数据集以获得包含相关特征的最终干净数据。

3-将数据分成训练和测试数据集/缩放特征。

4-选择合适的绩效矩阵。

5-使用 GridSearch 训练分类器并选择最佳估计器

6-计算最佳估计值给出的特征重要性。

7-使用测试数据计算模型的性能,并绘制混淆矩阵。

1-探索和清理给定的数据集

为了理解数据集并揭示初始模式、特征和兴趣点,首先我们需要探索数据集,包括检查缺失值、可视化数据分布等。这样,我们可以看到数据能告诉我们什么,以及如何选择支持模型实现的重要特性。
我们还会做一些预处理,在这一步中,数据会被转换或编码,使其达到机器可以轻松解析的状态。

*# read in the json files*
portfolio = pd.read_json('data/portfolio.json', orient='records', lines=**True**)
profile = pd.read_json('data/profile.json', orient='records', lines=**True**)
transcript = pd.read_json('data/transcript.json', orient='records', lines=**True**)

投资组合数据

投资组合的预处理执行如下:

  • 将功能的名称“id”更改为“offer_id”。
  • 将持续时间从一天改为一小时。
  • 将 OneHotEncoding 应用于 channels 列。
  • 将 OneHotEncoding 应用于 offer_type 列。

所有这些步骤都包含在下面的函数中:

**def** clean_portfolio(portfolio):

    *'''*
 *data cleaning the portfolio dataframe*

 *INPUT:*
 *portfolio - the portfolio dataframe to be cleaned*

 *OUTPUT:*
 *portfolio - the cleaned portfolio dataframe*

 *'''*

    *# Change name of feature id to offer_id*
    portfolio.rename(columns={'id': 'offer_id'}, inplace=**True**)

    *# change the duration from day to hour*
    clean_portfolio = portfolio.copy()
    clean_portfolio['duration'] = clean_portfolio['duration'] * 24

    *# apply one hot encoding to channels culumn*

    channels=clean_portfolio['channels'].map(**lambda** x: ','.join(map(str, x))).str.get_dummies(sep=',')

    *# apply one hot encoding to offer_type column*
    offer_type = pd.get_dummies(clean_portfolio['offer_type'])

    *# drop the culumns channels and offer_type* 
    clean_portfolio.drop(['channels', 'offer_type'], axis=1, inplace=**True**)

    *# combine the dataframe clean_portfolio and offer_type to form a cleaned dataframe*
    clean_portfolio = pd.concat([clean_portfolio, channels, offer_type], axis=1, sort=**False**)

    **return** clean_portfolio

将函数应用于投资组合数据集

clean_portfolio=clean_portfolio(portfolio)

清理完数据后,看起来是这样的:

b 剖面数据

绘制年龄分布图

从上面的图中,我们可以清楚地看到,年龄为 118 岁的客户在分布图中非常突出,这似乎是异常值。我检查了年龄等于 118 的所有配置文件,它们没有任何性别和收入,年龄为 118 的客户数量为 2175 是不现实的,出于这些原因,我将删除年龄为 118 的所有行。

配置文件的预处理执行如下:

  • 在配置文件数据框中将列 id 的名称更改为 customer_id。
  • 删除年龄在 118 岁以上的客户。
  • 将 OneHotEncoding 应用于特征“性别”。
  • 将特征“年龄”转换为“年龄-十年”,这将有助于确定某一特定年龄是否更受优惠的影响。
  • 将 OneHotEncoding 应用于功能“按年代”。
  • 创建功能“成为成员年”,其中客户从功能“成为成员年”成为成员。
  • 创建功能“成为会员月”,其中客户从功能“成为会员月”成为会员。
  • 创建功能“成为会员日”,其中客户从功能“成为会员日”成为会员。
  • 从“成为会员”功能创建客户的“成为会员”功能。
  • 将 OneHotEncoding 功能应用于“成为 _ 成员 _ 年份”。
  • 将 OneHotEncoding 功能应用于“成了 _ 成员 _ 月”。
  • 将特征“收入”转换为“收入范围”,这将有助于确定某一特定收入范围是否更多地受到报价的影响。
  • 将 OneHotEncoding 功能应用于“income_by_range”。

所有这些步骤都包含在下面的函数中

def clean_profile(profile):

    """ Transforms a DataFrame that contains demographic data for each 
    customer

    INPUT:
        (Optional) data_dir: String that stores the full path to the
                             data directory

    OUTPUT:
        profile: DataFrame that contains demographic data for each 
                 customer
    """
    # copy dataframe from profile to clean_profile
    clean_profile = profile.copy()

    # Change name of culumn id to customer_id in profile dataframe
    clean_profile.rename(columns={'id': 'customer_id'}, inplace=True)

    # Remove customers with age 118
    profile_118 = clean_profile[clean_profile['age'] == 118]
    clean_profile.drop(index=profile_118.index, inplace=True) 

    # OneHotEncoding feature 'gender'
    gender_dummies = pd.get_dummies(clean_profile['gender'], prefix='', prefix_sep='')

    # Convert fetaure 'age' into 'age_by_decade' which would be helpful in determining if a particular age 
    #is influenced more by an offer
    clean_profile['age_by_decade'] = pd.cut(clean_profile['age'], bins=range(10,120,10),right=False, labels=['10s','20s', '30s', '40s', '50s','60s', '70s', '80s', '90s', '100s'])

    # OneHotEncoding feature 'age_by_decade'
    age_dummies = pd.get_dummies(clean_profile['age_by_decade'], prefix='age', prefix_sep='_')

    # Drop feature 'age' 
    clean_profile.drop(columns=['age'], axis=1, inplace=True)

    # Convert type of feature 'became_member_on' to type Datetime
    type(pd.to_datetime(clean_profile['became_member_on'],format='%Y%m%d').dt)# Create feature 'became_member_year' in which customer became member from feature 'became_member_on'
    clean_profile['became_member_year'] = pd.to_datetime(clean_profile['became_member_on'],format='%Y%m%d').dt.year# Create feature 'became_member_month' in which customer became member from feature 'became_member_on'
    clean_profile['became_member_month'] = pd.to_datetime(clean_profile['became_member_on'],format='%Y%m%d').dt.month

    # Create feature 'became_member_day' in which customer became member from feature 'became_member_on'
    clean_profile['became_member_day'] = pd.to_datetime(clean_profile['became_member_on'],format='%Y%m%d').dt.day

    # Create feature 'became_member_tenure' of customers from feature 'became_member_on'
    clean_profile['became_member_tenure'] = (datetime.today().date() - pd.to_datetime(clean_profile['became_member_on'],format='%Y%m%d').dt.date).dt.days# Drop feature 'became_member_on'
    clean_profile.drop(columns=['became_member_on'], axis=1, inplace=True)

    # OneHotEncoding feature 'became_member_year'
    year_dummies = pd.get_dummies(clean_profile['became_member_year'], prefix='', prefix_sep='')# OneHotEncoding feature 'became_member_month'
    month_dummies = pd.get_dummies(clean_profile['became_member_month'], prefix='month', prefix_sep='_')

    # Convert feature 'income' into 'income_by_range' which would be helpful in determining
    # if a particular income range is influenced more by an offer
    clean_profile['income_by_range'] = pd.cut(clean_profile['income'], bins=range(30000,140000,10000), right=False,\
                                    labels=['30ths','40ths', '50ths', '60ths', '70ths','80ths', '90ths',\
                                            '100ths', '110ths', '120ths'])

    # OneHotEncoding feature 'income_by_range'
    income_dummies = pd.get_dummies(clean_profile['income_by_range'], prefix='income', prefix_sep='_')

    # combine the dataframe clean_profile with the different dummies variables
    clean_profile = pd.concat([clean_profile, gender_dummies, age_dummies,year_dummies,month_dummies,income_dummies], axis=1, sort=False)# Return a DataFrame with clean customer profile data
    return clean_profile

将函数应用于数据集配置文件

*# apply the function clean_profile on our dataset 'profile' to  get a cleaned profile*
clean_profile=clean_profile(profile)

这是我们数据集简介的新栏目

*# show the columns of cleaned profile data*
clean_profile.columns

显示数据的可视化表示

该图显示,在去掉年龄 118 之后,特征年龄是均匀分布的,我们看到大多数消费者的年龄在 40 到 80 岁之间。

结果表明,大多数顾客在 2017 年加入了星巴克奖励计划,随后在 2018 年加入。

从上面的图中,我们看到大多数顾客的收入在 30 000 到 90 000 之间。

剧情描绘了每年加入计划的男性客户比女性客户多。

从上面的图表中,我们得出结论,男性和女性的最低和最高收入大致相同,但低收入水平的男性顾客数量略高于女性顾客。此外,其他人的收入分配也与男性和女性相似,最低和最高收入低于男性和女性。

c-抄本数据

转录本的预处理如下进行:

  • 在副本数据框中,将人物姓名更改为 customer_id。
  • 从副本数据框架中删除年龄为 118 岁的客户的观察结果,因为我们发现年龄为 118 岁的客户是异常值。
  • 创建仅包含优惠事件的数据框 offers_df 和仅包含交易事件的交易 _df。
  • 清理和转换 offers_df 和 transaction_df 数据集。

首先,我们使用下面的函数清理数据集副本

**def** clean_trascript(transcript):

    *'''*
 *data cleaning the transcript dataframe*

 *INPUT:*
 *transcript - the transcript dataframe to be cleaned*

 *OUTPUT:*
 *transcript - the cleaned transcript dataframe*

 *'''*
    *# copy dataframe from transcript to clean_transcript*
    clean_transcript = transcript.copy()

    *# Change name of feature person to customer_id in transcript dataframe*
    clean_transcript.rename(columns={'person': 'customer_id'}, inplace=**True**)

    *# Remove observations having customers with age 118 from transcript dataframe*
    clean_transcript = clean_transcript[~clean_transcript['customer_id'].isin(id_age_118)]    

    **return** clean_transcript

在转录数据集上应用函数

clean_transcript=clean_trascript(transcript)

创建仅包含报价事件的数据帧 offers_df 和仅包含交易事件的交易 _df

*# Create a list of offer event types*
offer_event_list = ['offer received', 'offer viewed', 'offer completed']

*# Find index where feature 'event' is 'offer received', 'offer viewed', 'offer completed'*
offer_index = clean_transcript[clean_transcript['event'].isin(offer_event_list)].index

*# Find index where feature event is 'transaction'*
transaction_index = clean_transcript[~clean_transcript['event'].isin(offer_event_list)].index

*# Create offers_df*
offers_df = clean_transcript.loc[offer_index,:]

*# Create transaction_df*
transaction_df = clean_transcript.loc[transaction_index,:]

这些是我们的新桌子

那些桌子似乎需要清洗一下

  • 清洁报价 _df
*# Create another column 'offer_type' with respect to feature 'offer_id'*
offers_df['offer_type'] = offers_df['offer_id'].copy()

offers_df['offer_type'].replace(['ae264e3637204a6fb9bb56bc8210ddfd','4d5c57ea9a6940dd891ad53e9dbe8da0',\
                                 '9b98b8c7a33c4b65b9aebfe6a799e6d9','f19421c1d4aa40978ebb69ca19b0e20d'],\
                                 'bogo', inplace=**True**)

offers_df['offer_type'].replace(['0b1e1539f2cc45b7b9fa7c272da2e1d7','2298d6c36e964ae4a3e7e9706d1fb8c2',\
                                 'fafdcd668e3743c1bb461111dcafc2a4','2906b810c7d4411798c6938adc9daaa5'],\
                                 'discount', inplace=**True**)

offers_df['offer_type'].replace(['3f207df678b143eea3cee63160fa8bed','5a8bc65990b245e5a138643cd4eb9837'],\
                                 'informational', inplace=**True**)
*# Drop feature value as it is not required now and drop feature offer_type as that information is also in portfolio dataframe*
offers_df.drop(columns=['value', 'offer_type'], inplace=**True**)

*# OneHotEncoding feature 'event'*
offers_df = pd.get_dummies(offers_df, columns=['event'], prefix='', prefix_sep='')

*# Reorder columns of offers_df dataframe*
col_order = ['customer_id', 'offer_id', 'time', 'offer received', 'offer viewed', 'offer completed']
offers_df = offers_df.reindex(col_order, axis=1)
  • 清理交易 _df
*# Create column 'amount' in the dataframe transaction_df*
transaction_df['amount'] = transaction_df['value'].apply(**lambda** x: x['amount'])*# Drop'event' and 'value' features*
transaction_df.drop(columns=['event', 'value'], inplace=**True**)

这些是生成的数据集的最终外观(offers_df 和 transaction_df):

2-组合数据集以获得包含相关特征的最终干净数据。

下面的函数包括用于组合数据集 clean_portfolip、clean_profile、offers_df 和 transaction_df 的代码。

*# Create function to combine transaction, offer, portfolio and profile datasets*
**def** create_combined_data(portfolio, profile, offers_df, transaction_df):

    *'''Create a combined dataframe from the transaction, demographic and offer data:*
 *INPUT:*
 *portfolio - (dataframe),offer metadata*
 *profile - (dataframe),customer demographic data*
 *offers_df - (dataframe), offers data for customers*
 *transaction_df - (dataframe), transaction data for customers*
 *OUTPUT:*
 *combined_data_df - (dataframe),combined data from transaction, demographic and offer data*
 *'''*

    combined_data = [] *# Initialize empty list for combined data*
    customer_id_list = offers_df['customer_id'].unique().tolist() *# List of unique customers in offers_df*

    *# Iterate over each customer*
    **for** i,cust_id **in** enumerate(customer_id_list):

        *# select customer profile from profile data*
        cust_profile = clean_profile[clean_profile['customer_id'] == cust_id] 

        *# select offers associated with the customer from offers_df*
        cust_offers_data = offers_df[offers_df['customer_id'] == cust_id]

        *# select transactions associated with the customer from transactions_df*
        cust_transaction_df = transaction_df[transaction_df['customer_id'] == cust_id]

        *# select received, completed, viewed offer data from customer offers*
        offer_received_data  = cust_offers_data[cust_offers_data['offer received'] == 1]
        offer_viewed_data = cust_offers_data[cust_offers_data['offer viewed'] == 1]
        offer_completed_data = cust_offers_data[cust_offers_data['offer completed'] == 1]

        *# Iterate over each offer received by a customer*
        rows = [] *# Initialize empty list for a customer records*

        **for** off_id **in** offer_received_data['offer_id'].values.tolist():

            *# select duration of a particular offer_id*
            duration = clean_portfolio.loc[clean_portfolio['offer_id'] == off_id, 'duration'].values[0]

            *# select the time when offer was received*
            off_recd_time = offer_received_data.loc[offer_received_data['offer_id'] == off_id, 'time'].values[0]

            *# Calculate the time when the offer ends*
            off_end_time = off_recd_time + duration

            *#Initialize a boolean array that determines if the customer viewed an offer between offer period*
            offers_viewed = np.logical_and(offer_viewed_data['time'] >= off_recd_time,offer_viewed_data['time'] <= off_end_time)

            *# Check if the offer type is 'bogo' or 'discount'*
            **if** (clean_portfolio[clean_portfolio['offer_id'] == off_id]['bogo'].values[0] == 1 **or**\
                    clean_portfolio[clean_portfolio['offer_id'] == off_id]['discount'].values[0] == 1):

                *#Initialize a boolean array that determines if the customer completed an offer between offer period*
                offers_comp = np.logical_and(offer_completed_data ['time'] >= off_recd_time,\
                                                 offer_completed_data ['time'] <= off_end_time)

                *#Initialize a boolean array that selects customer transctions between offer period*
                cust_tran_within_period = cust_transaction_df[np.logical_and(cust_transaction_df['time'] >= off_recd_time,\
                                                                                 cust_transaction_df['time'] <= off_end_time)]

                *# Determine if the customer responded to an offer(bogo or discount) or not*
                cust_response = np.logical_and(offers_viewed.sum() > 0, offers_comp.sum() > 0) **and**\
                                                    (cust_tran_within_period['amount'].sum() >=\
                                                     clean_portfolio[clean_portfolio['offer_id'] == off_id]['difficulty'].values[0])

            *# Check if the offer type is 'informational'*
            **elif** clean_portfolio[clean_portfolio['offer_id'] == off_id]['informational'].values[0] == 1:

                *#Initialize a boolean array that determines if the customer made any transctions between offer period*
                cust_info_tran = np.logical_and(cust_transaction_df['time'] >= off_recd_time,\
                                                    cust_transaction_df['time'] <= off_end_time)                   

                *# Determine if the customer responded to an offer(informational) or not*
                cust_response = offers_viewed.sum() > 0 **and** cust_info_tran.sum() > 0                  

                *#Initialize a boolean array that selects customer transctions between offer period*
                cust_tran_within_period = cust_transaction_df[np.logical_and(cust_transaction_df['time'] >= off_recd_time,\
                                                                                 cust_transaction_df['time'] <= off_end_time)]

            *# Initialize a dictionary for a customer with required information for a particular offer*
            cust_rec = {'cust_response': int(cust_response),'time': off_recd_time,'total_amount': cust_tran_within_period['amount'].sum()}
            cust_rec.update(clean_profile[clean_profile['customer_id'] == cust_id].squeeze().to_dict())
            cust_rec.update(clean_portfolio[clean_portfolio['offer_id'] == off_id].squeeze().to_dict())

            *# Add the dictionary to list for combined_data*
            rows.append(cust_rec)

        *# Add the dictionaries from rows list to combined_data list*
        combined_data.extend(rows)

    *# Convert combined_data list to dataframe*
    combined_data_df = pd.DataFrame(combined_data)

    *# Reorder columns of combined_data_df*
    combined_data_df_col_order = ['customer_id', 'offer_id', 'time']

    port_ls = clean_portfolio.columns.tolist()
    port_ls.remove('offer_id')
    pro_ls = clean_profile.columns.tolist()
    pro_ls.remove('customer_id')
    combined_data_df_col_order.extend(port_ls)
    combined_data_df_col_order.extend(pro_ls)
    combined_data_df_col_order.extend(['total_amount', 'cust_response'])

    combined_data_df = combined_data_df.reindex(combined_data_df_col_order, axis=1)
    combined_data_df.to_csv('combined_data2.csv', index=**False**)
    **return** combined_data_df

以下是组合数据的特征:

创建一个名为 offer_success 的数据框,其特征为 offer_id、count、success_pourcentage 和 offer_type,以建立出价之间的比较。

**def** calculate_percentage_success():

    *'''Create dataframe offer_success with features offer_id, success_pourcentage and offer_type*

 *OUTPUT:*
 *offer_response - (dataframe), with the features offer_id, success_pourcentage and offer_type*
 *'''*

    *#* 
    offer_response = combined_data_df.groupby(['offer_id'])['cust_response'].count().reset_index()
    offer_response.rename(columns={'cust_response': 'count'}, inplace=**True**)
    success_pourcentage = combined_data_df.groupby(['offer_id'])['cust_response'].sum()/\
                combined_data_df.groupby(['offer_id'])['cust_response'].count()
    np.round(success_pourcentage.values*100,2)
    offer_response['success_pourcentage'] = np.round(success_pourcentage.values*100,2)                                  
    offer_response['offer_type'] = offer_response['offer_id'].map({'ae264e3637204a6fb9bb56bc8210ddfd': 'bogo',\
                                                               '4d5c57ea9a6940dd891ad53e9dbe8da0': 'bogo',\
                                                               '3f207df678b143eea3cee63160fa8bed': 'informational',\
                                                               '9b98b8c7a33c4b65b9aebfe6a799e6d9': 'bogo',\
                                                               '0b1e1539f2cc45b7b9fa7c272da2e1d7': 'discount',\
                                                               '2298d6c36e964ae4a3e7e9706d1fb8c2': 'discount',\
                                                               'fafdcd668e3743c1bb461111dcafc2a4': 'discount',\
                                                               '5a8bc65990b245e5a138643cd4eb9837': 'informational',\
                                                               'f19421c1d4aa40978ebb69ca19b0e20d': 'bogo',\
                                                               '2906b810c7d4411798c6938adc9daaa5': 'discount'})

    offer_response=offer_response.sort_values(by=['success_pourcentage'], ascending=**False**)
    **return** offer_response

这是数据集 offer_success

绘制两个条形图,一个到显示了有多少客户获得了特定的报价,另一个显示了每次报价的成功率。

从上面显示的结果中,我们注意到发送给客户的报价数量几乎相同。
对于要约的成功率,我们观察到 10 号和 2 号要约最成功,成功率分别为 75.20%和 72.28%,最低的是 4 号要约,成功率为 36.76%。

  • 获得准备好的数据集的最后一步是清除无用的要素。
*# Drop features from combined_data which are not required for training the model*
combined_data_df.drop(columns=['customer_id', 'offer_id', 'time', 'email','gender', 'income', 'age_by_decade','became_member_year',
'became_member_month', 'became_member_day','income_by_range'], inplace=**True**)

清洗后,我们得到上面的列:

3-将数据分成训练和测试数据集/缩放特征

我们使用的数据通常分为训练数据和测试数据。训练集包含一个已知的输出,模型学习这个数据,以便以后推广到其他数据。我们有测试数据集来测试我们的模型对这个子集的预测。

*# features : independece variables that act as the input of the model*
X = combined_data_df.drop(columns=['cust_response'])
*# target : the variable to predict* 
y = combined_data_df['cust_response'
*# split data into train and test sets*
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.3, random_state=42)

然后,我们继续进行特征缩放,这是一种使用最小最大缩放器来归一化独立变量范围或数据特征的方法。

准备要缩放的要素列表

*# Prepare list of features to scale*
features_to_scale = ['difficulty', 'duration', 'reward', 'became_member_tenure', 'total_amount']

然后是缩放要素的函数

**def** features_scale(df, feat=features_to_scale):

    *"""*
 *Scale list features in a given dataframe*

 *INPUT:*
 *- df (dataframe): dataframe having features to scale*
 *- feat (list): list of features in dataframe to scale*

 *OUTPUT:*
 *- scaled_df (dataframe): dataframe containing scaled features*
 *"""*

    *# Prepare dataframe with features to scale*
    df_feat_scale = df[feat]

    *# Apply feature scaling to df*
    scaler = MinMaxScaler()
    df_feat_scale = pd.DataFrame(scaler.fit_transform(df_feat_scale), columns = df_feat_scale.columns,index=df_feat_scale.index)

    *# Drop orignal features from df and add scaled features* 
    df = df.drop(columns=feat, axis=1)
    df_scaled = pd.concat([df, df_feat_scale], axis=1)

    **return** df_scaled

将函数应用于要素

*# Scale selected features in training set i.e. X_train*
X_train_scaled = features_scale(X_train, feat=features_to_scale)

计算目标类在训练集中的分布百分比

round((y_train.squeeze().value_counts()/y_train.squeeze().count())*100,2)

输出

从上面显示的结果中,我们可以观察到我们的训练数据集几乎是平衡的,响应报价的客户数量(53.8%)和未响应报价的客户数量(46.2%)几乎相等。因为,我们的训练数据集几乎是平衡的,我们不需要处理技术来对抗类别不平衡。

4-选择适当的绩效矩阵

我们发现,我们的训练数据在目标类的分布方面几乎是平衡的,精度、召回率和 f1_score 等性能指标是评估模型的完美度量。F1 得分指标是“精确度和召回率指标的调和平均值”,是一种更好的方法,可以提供更强的问题预测能力以及预测模型的预测能力。

5-使用 GridSearch 训练分类器并选择最佳估计器

下面的函数将使用 k-fold 交叉验证来拟合分类器,并计算 f1 值

**def** fit_classifier(clf, param_grid, X=X_train_scaled.values, y=y_train.squeeze().values):

    *"""*
 *Fits a classifier to its training data using GridSearchCV and calculates f1_score*

 *INPUT:*
 *- clf (classifier): classifier to fit*
 *- param_grid (dict): classifier parameters used with GridSearchCV*
 *- X_train_scaled (DataFrame): training features*
 *- y_train (DataFrame): training label*

 *OUTPUT:*
 *- classifier: input classifier fitted to the training data*
 *"""*

    *# cv uses StratifiedKFold*
    *# scoring f1 available as parameter*
    start = time.time()
    grid = GridSearchCV(estimator=clf, param_grid=param_grid, scoring='f1', cv=5, verbose=0)
    print("Training **{}** :".format(clf.__class__.__name__))
    grid.fit(X, y)
    end = time.time()
    time_taken = round(end-start,2)

    print(clf.__class__.__name__)
    print("Time taken : **{}** secs".format(time_taken))
    print("Best f1_score : **{}**".format(round(grid.best_score_,4)))
    print("*"*40)

    **return** grid.best_score_, grid.best_estimator_, time_taken

初始化分类算法

lr = LogisticRegression(random_state=42) *# LogisticRegression*
rfc = RandomForestClassifier(random_state=42) *# RandomForestClassifier*
gbc = GradientBoostingClassifier(random_state=42) *# GradientBoostingClassifier*
abc = AdaBoostClassifier(random_state=42) *# AdaBoostClassifier*

寻找最佳分类算法

cl_names = []
cl_scores = []
cl_best_ests = []
cl_time_taken = []
cl_dict = {}

**for** classifier **in** [lr, rfc, abc, gbc]:
    best_score, best_est, time_taken = fit_classifier(classifier, {})
    cl_names.append(classifier.__class__.__name__)
    cl_scores.append(best_score)
    cl_best_ests.append(best_est)
    cl_time_taken.append(time_taken)

输出

RandomForestClassifier 和 GradientBoostingClassifier 的 f1_score 几乎相等(大约。0.92),但 RandomForestClassifier 比 GradientBoostingClassifier 花费的训练时间要少得多。因此,上述 4 种分类器中性能最好的分类器算法是 RandomForestClassifier。

  • 然后,我们可以借助 GridSearchCV 中的 param 网格来调整 RandomForestClassifier 分类器。
*# Tuninig RandomForestClassifier classifier with the help of param grid in GridSearchCV*
param_grid = {
               *# Number of trees in random forest*
              'n_estimators': [10, 50, 80, 100],
               *# Maximum number of levels in tree*
              'max_depth': [**None**],
               *# Minimum number of samples required to split a node*
              'min_samples_split': [2, 5, 10],
               *# Minimum number of samples required at each leaf node*
              'min_samples_leaf': [1, 2, 4]}

rfc = RandomForestClassifier(random_state=42)
rfc_best_score, rfc_best_est, _ = fit_classifier(rfc, param_grid)
rfc_best_est

调整后,我们获得了以下结果:

为了选择要调整的超参数,我们进行了彻底的网格搜索,它接受许多超参数,并尝试超参数的每一个可能的组合以及我们希望它执行的许多交叉验证(这里我们选择 cv=5)。彻底的网格搜索是确定要使用的最佳超参数值的好方法,但是随着我们添加每个额外的参数值和交叉验证,它会很快变得非常耗时。

我们选择调整的参数是:min_samples_leaf、min_samples_split、n_estimators、max_depth。在调整之前,这些参数的值是 max_depth=None,min_samples_leaf=1,min_samples_split=2,n_estimators=10。

上面显示的代码运行了 20 多分钟,但选择的超参数在预测训练模型时有 92.94%的准确性。得到的“最佳”超参数如下:min_samples_leaf = 1,min_samples_split = 2,n_estimators = 100,max_depth=None。

仔细而有条理地调整超参数可能是有利的。它可以使我们的分类模型更准确,这将导致总体上更准确的预测。

我们注意到,在对训练好的 RandomForestClassifier 进行微调之后,我们得到了更好的 f1 _ score 0.9294,而在调整之前它是 0.9196,因此我们可以观察进度。

6-计算最佳估计值给出的特性重要性

通过 RandomForestClassifier 准备包含要素及其重要性的数据框

feature_imp = pd.DataFrame(rfc_best_est.feature_importances_,index=X_train_scaled.columns.tolist(),columns=['feat_imp']).reset_index()

feature_imp.rename(columns={'index': 'feature'}, inplace=**True**)
feature_imp['feat_imp_rate'] = np.round((feature_imp['feat_imp']/feature_imp['feat_imp'].sum())*100,2)
feature_imp = feature_imp.sort_values(by=['feat_imp_rate'], ascending=**False**).reset_index(drop=**True**)
feature_imp.drop(columns=['feat_imp'],inplace=**True**)
feature_imp

绘制特征及其重要性的条形图

从上面显示的结果中,我们注意到:

影响客户在查看报价后是否会对报价做出回应的 4 大特征是:

  • 客户花费的总金额是最重要的特征,它几乎不会影响客户在查看报价后是否会完成报价。
  • “成为会员任期”是第二大特征,它代表了顾客成为星巴克奖励计划会员的时间长短,对顾客是否会在回应后完成报价有很大影响。
  • “社交功能”表示,如果星巴克通过社交媒体向顾客发送报价,可能会比其他沟通方式得到更多回应。
  • “难度”特征,表示如果客户响应并完成报价,完成报价所需的最小花费金额。

7-使用测试数据计算模型的性能,并绘制混淆矩阵

  • 计算预测
*# Classification of test data using best model trained on train data*
predictions = rfc_best_est.predict(X_test_scaled)
  • 绘制归一化混淆矩阵

结果表明,有 4%的百分比错误分类客户接受要约和 11%的错误分类客户拒绝要约。由于假阴性比假阳性少,我们的预测模型做得很好,因为它错过会响应的个体的机会非常低。

由于 Starbucks 不希望错过向愿意回应的个人发送报价,因此该模型适合这种情况,因为它不会错过向愿意回应的个人发送报价。此外,星巴克不会介意向一些不会回复的人发送报价,因为他们已经覆盖了所有会回复的人。因此,我们的预测模型在这种情况下会工作得很好。

结论

我选择解决的问题是建立一个模型来预测客户是否会对报价做出反应。我解决这个问题的策略主要有三个步骤。首先,在预处理投资组合、配置文件和交易数据集之后,我将它们组合起来,以获得包含相关特征的最终干净数据,该数据可用于训练我们的模型。其次,在分割数据以训练和测试数据集之后,我们使用 GridSearch 选择了最佳估计器“RandomForestClassifier ”,这是上述 4 个测试的分类器中性能最好的分类器算法(我比较了 F1 分数和所用时间)。第三,我使用测试数据预测测试目标,并绘制混淆矩阵以确保我们的模型的性能,我们发现我们的预测模型非常适合这种情况。

我喜欢在这个项目中工作,这让我可以在一个真实的项目中工作。这个项目最有趣的方面是结合不同的数据集,并使用预测建模技术和分析来为业务提供更好的决策和价值。争吵是最长也是最具挑战性的部分。整个分析中最困难的部分是找到逻辑和策略来创建一个组合数据集,并决定问题陈述。

丰富

  • 如果有更多的客户指标,可能会有更好的预测。对于这一分析,我觉得我们所掌握的客户信息有限,只有年龄、性别和收入。为了找到最佳的客户统计数据,最好能有更多的客户特征。这些附加特征可以帮助提供更好的分类模型结果数据,以便具有更好的模型。
  • 此外,最初看起来我们有很多数据要处理,但是一旦删除了 NaN 值和重复的列,并将数据合并到一个单独的数据集中,就好像模型可能会从更多的数据中受益。有了更多的数据,分类模型可能已经能够产生更好的 F1 分数结果。
  • 另外,我们可以通过另一个问题陈述来改进这个项目,我们可以建立一个模型来预测哪些人口统计群体会购买,即使他们没有收到报价。

请注意,文章讨论的是分析的重要代码,你可以在这里找到星巴克顶点挑战项目的完整代码。

使用 CatBoost 和散景的星巴克顾客特征分析

原文:https://towardsdatascience.com/starbucks-customer-classification-using-catboost-c3026d1785d7?source=collection_archive---------20-----------------------

多类 | 活页夹

使用客户旅程和多类分类的解决方案

TRUnsplash 上拍照

介绍

在这篇文章中,我探索了由 StarbucksUdacity 合作提供的客户数据,以了解客户在潜在回报方面的行为。星巴克的移动应用程序向其顾客发送不同种类的激励优惠,以保持他们对该品牌的参与。

这篇文章的动机是讨论一种用来分析预测客户响应的数据和机器学习解决方案的解决方案。

我使用机器学习库 CatBoost 来解决多类分类问题,并使用散景作为主要的可视化工具。

该项目的 GitHub Repo 可以在这里找到。

1.概观

该数据集包含模拟星巴克奖励移动应用程序上的客户行为的模拟数据。每隔几天,星巴克就会向手机应用程序的用户发出一次报价。优惠可以仅仅是饮料的广告,也可以是实际的优惠,例如折扣或 BOGO(买一送一)。某些用户可能在特定的几周内收不到任何优惠。

在要约到期之前,每个要约都有一个有效期。例如,BOGO 的报价可能只有五天的有效期。你会在数据集中看到,信息优惠有一个有效期,即使这些广告仅仅是提供关于产品的信息;例如,如果信息性报价有七天的有效期,您可以假设客户在收到广告后的七天内感受到了报价的影响。

【项目概述摘自 Udacity 的顶点项目 数据科学纳米学位项目

数据集

数据包含在三个文件中:

portfolio.json —包含要约 id 和关于每个要约的元数据(持续时间、类型)

profile.json —每个客户的人口统计数据

抄本. json —交易记录、收到的报价、查看的报价和完成的报价

2.问题陈述

目的是分析单个客户的行为,以识别不寻常的模式。这种分析的发现应该有助于星巴克企业根据具体结果重新评估其奖励计划。

我旨在针对以下业务问题提供分析:

  • 我们可以根据客户的响应能力对他们进行分类吗?
  • 我们能否识别不关心奖励计划的高收入客户?
  • 我们能否确定过去没有任何交易的客户?
  • 我们能否可视化客户与优惠和消费活动的互动,以获得有趣的见解?

3.解决方案概念

  • 有三个不同的数据集,我逐一研究并识别任何问题,如缺失信息、额外/冗余信息、其他不一致。我通过在必要时充分利用视觉化来实现这一点。在这一步的最后,我有了一个干净的数据集,可以做进一步的探索。
  • 我将所有三个数据集合并成一个数据集,并通过高级可视化进行进一步分析。基于此,我构建了一个分类问题,通过一些机器学习算法来解决。
  • 我选择了 CatBoost 算法,一种多类分类算法。它自动识别高度相关的特征之间的关系,并带有内置的可视化功能。使用它训练和评估模型是简单的。使用默认参数的最终结果通常会更好,因为 CatBoots 在内部使用水平决策树。由于我们正在处理分类问题,并且错误分类的错误不会导致任何不利影响,在这种情况下,模型准确性应该是我们的标准评估标准,包括混淆矩阵。
  • 最后,我对整体分析的结果进行评估,包括机器学习模型的评估。

4.数据探索和基本可视化

投资组合数据集预览

  • 通过查看“通道”列,将每个通道值分解到单独的列中并使用 0|1 标识符对其进行编码是有意义的。
  • 让我们为“offer_type”列创建虚拟列,对其进行编码,并删除原来的列,因为我们不再需要它。

清理后的投资组合数据集

在这里,每个报价总是通过“电子邮件”渠道发送。因此,该特征仅提供信息,并且可能不会给任何机器学习算法的预测能力增加任何价值。

配置文件数据集预览

显然,“年龄”值 118 是缺失值的占位符。进一步的分析显示,性别、年龄和收入栏总共有 2175 个缺失条目。

“成为会员”列是一个带有时间戳的日期,让我们将其转换为可读性更好的格式,并提取自客户注册以来的天数。

让我们创建一些可视化工具来分析人口统计数据

顾客年龄分布

按年份统计的客户注册数

客户收入分配

左图显示了这些年来客户数量的稳步增长。然而,在 2017 年底有一个陡峭的下降。这也可能是由于准备数据集的采样。

令人惊讶的是,属于相对较低收入群体的客户很多,属于相对较高收入群体的客户很少。

配对图显示,女性客户不多,女性群体年龄相对较大,收入较高。

人口统计数据对图表

具体观察结果

  • 年龄组[20,30]中没有收入高于 80K 的客户。
  • 在[40,50]年龄组中,没有收入高于 10 万英镑的客户。
  • 所有 2000 多天前成为会员的客户收入都低于 10 万。

成绩单数据集预览

快速查看一下脚本数据集,就会发现“value”列被编码为一个字典。如果事件与报价相关,则“值”列编码报价 id,如果是交易事件,则编码交易金额。

因此,将“价值”列解码为单独的列,以了解优惠和客户花费的金额之间的关系是有意义的。

5.数据预处理和高级可视化

首先要计算完成的总报价数和每个客户查看的总报价数。
这些数据包括客户有意或无意的“完成的报价”。不应向不知情已完成报价的客户发送进一步的报价。这个群体代表了公司的盈利客户。

我们将我们的成绩单数据集与客户人口统计数据(个人资料)和投资组合数据相结合。

在应用于联合数据集的几个预处理步骤之后,

按时间线查看的出价数([0–714])

上图显示了根据时间戳查看的报价数量(以小时为单位)。在六个峰值中,浏览报价的数量急剧增加。

我已经在图表中嵌入了收到的报价数(正确的收到报价数是标记数的四倍)。当收到新的报价时,已查看报价的数量会增加,然后随着时间的推移慢慢减少。一般来说,大多数优惠都是在收到后 24 小时内查看的。

根据时间表完成的出价数([0–714])

上图显示了以小时为单位的时间戳中已完成的报价数量。它遵循与之前图表相似的模式,因为新报价在 24 天内发送了 6 次,因此图表有 6 个峰值。

在每个峰值之间,图表逐渐减小,就像查看报价图表一样。然而,下降并不像查看报价图那样平稳。下跌期间有一些地方选股。

显示交易数量和按时间表完成的报价的联合图表

上面的图表结合了一些交易和报价一起完成。在交易的每个“报价发送间隔”之间有一个局部峰值。这意味着当收到报价时,客户会快速执行一些交易,从而完成报价。

在时间戳 0 处,存在大约 600 个事务。其中大约 200 个有助于“要约完成”(时间戳为 0 时完成的要约数量),这大约是 25%的转化率。这个数字与已完成要约总数与交易总数的比值=> 138953/33579)*100 = 24.16%大致吻合。

存在一些高价值交易(100 美元以上)。这可能是个人为特殊活动或公司客户的大订单。这样的高价值交易导致与客户相关联的所有当前报价被完成。

在现实中,这些交易并没有完成要约的动机,因此应被视为副作用。向如此高收入的客户发出报价不会导致他们购买行为的增加或减少。因此,我们应该从数据集中删除这样的高价值交易。

接下来,我们还应该找出并清除不响应的客户。我定义无响应客户=未收到报价、未查看+未达成交易。

在一些进一步的预处理步骤之后,我发现有 422 个客户没有进行交易。其中,412 人收到并查看了报价,10 人收到但未查看任何报价。

同样,在分析交易金额时,收集了以下观察结果:

  • 有些交易超过 1000 美元。
  • 范围[0.05,50]内的事务比该范围内的其他事务多得多。
  • 任何超过 50 美元的交易都可以被视为高价值交易,不一定有动机完成报价。

6.通过客户之旅进行特征工程

在本节中,我们将通过一些高级的可视化方式来了解顾客与产品的互动。基于此,我定义了一些计算特征。

客户旅程(id:“6 E0”)

在上面的图表中,我们有一个客户,他/她已经完成了发送给他/她的所有报价。如果这些交易的价值较低,通常需要一次以上的交易才能完成要约。

有时,客户会立即查看报价,而有时,他/她会在稍后时间查看。

在完成的 4 个报价中,只有 1 个(最后完成的)未被客户查看。

两位高价值客户的并肩之旅

在这里,我们有两个高付费客户并排完成了所有收到的报价。

有趣的是,对于客户“9fa ”,在完成第一次报价后,他/她已经进行了五次交易,总计约 75 美元,没有任何待完成的报价。它表明,这些交易没有动机完成报价,并显示客户在没有任何报价的情况下的消费倾向。

基于以上分析我推导出以下自定义特性
1。给定客户完成报价的百分比
2。给定客户完成的报价绝对计数
3。给定客户查看的优惠的百分比
4。给定客户查看的优惠的绝对数量
5。给定客户的总消费金额

7.模型训练+评估

注意事项:

我们的问题属于多类分类的范畴。多类分类问题可以总结如下:

给定一个数据集,该数据集具有𝑥𝑖和𝑁类的实例,其中每个𝑥𝑖实例都精确地属于一个类,𝑦𝑖是多类分类器的目标问题。
在训练和测试之后,对于测试集中的每个实例𝑥𝑖,我们有一个具有正确类别𝑦𝑖和预测类别𝑎𝑖的表。因此,对于每个实例,我们要么匹配(𝑦𝑖=𝑎𝑖),要么不匹配(𝑦𝑖≠𝑎𝑖).
然而,F1-score 也可以用于多类问题的评估。

由于在我们的案例中,错误分类的成本并不高(向没有响应的客户发送报价不会给公司带来额外的成本),因此 F1-分数是不必要的。

在这个项目中,我更喜欢使用混淆矩阵和平均分作为我们的评估指标。 混淆矩阵: 一个混淆矩阵显示了实际和预测类的组合。矩阵的每一行代表预测类中的实例,而每一列代表实际类中的实例。这是一个很好的方法来衡量模型是否能解释类属性的重叠,并理解哪些类最容易混淆。

准确率:
分类正确的项目总数百分比- (TP+TN)/(N+P)
TP:真正
TN:真负
N:负
P:正

对于不平衡的类分布,我已经给每个类标签提供了权重,CatBoost 自动处理。

我已经创建了一个自定义目标标签来表示客户的响应能力。

对于二元分类,它将简单地根据完成的报价百分比对客户进行分类。如果报价完成百分比> 50 %,则客户属于“响应型”客户。否则,它属于“无响应”类。

稍后,我将问题扩展到多类分类。为此,我创建了 3 级、4 级和 5 级标签,将完成的报价百分比分配给特定的类别,并为每个类别分配适当的标签。

对于 5 类问题,标签编码如下:

编码= {

'响应':4,
'非常响应':0,
'中等响应':3,
'非常响应':2,
'无响应':1

模型评估策略

1。超参数固定值的模型评估(基础模型)

我在所有分类问题(class_2,class_3,class_4,class_5)上使用以下固定超参数评估 CatBoost 分类器

迭代次数= 2000

loss _ function =[' multi class ']

早停轮数= 50

eval_metric = 'Accuracy'

其余参数值默认由 CatBoost 分类器提供。

使用固定超参数的基本模型评估

2。使用 GridSearch 找到的超参数进行模型评估(调整模型)

在这一轮实验中,我编写了一个定制的 GridSearch 函数,它为每个给定的超参数范围找到最佳值,并返回训练数据上平均精度最佳的模型超参数。

对于 CatBoost Multiclassifier,有许多超参数需要优化。可在此处找到详细列表:

我只选择了以下具有指定范围的超参数(通过在 CatBoost 网站和 Kaggle 上的一些研究找到),以找到具有最佳性能的模型。

- iterations = [1000,3000]
- loss_function =  ['Logloss','MultiClass','MultiClassOneVsAll']
- depth = [4,6,8]      
- early_stopping_rounds = [10, 20, 50]

使用 GridSearch 的最佳发现超参数模型评估

8.结论+反思

  • 我评估了四个多类分类模型并记录了结果。似乎训练精度是模型性能的可靠指标,而不是测试精度。

综合两种评估

  • 这表明基本模型实际上比通过 GridSearch 找到参数的模型表现得更好。这可能是因为范围选择没有优化。在未来的工作中,使用 RadomizedGridSearch 评估模型可能会很有趣。
  • 向 GridSearch 提供太多的参数会导致搜索非常慢(一个模型需要 7 个多小时),因此我缩小了参数范围,然后平均花费 20 分钟来搜索最佳参数。
  • 最初,我面临一些清理事务和确定如何使用事务数据进行数据建模的挑战。关键的洞见是识别出同一时间线与不同事件相关。这让我能够绘制一些伟大的客户旅程可视化和随后的定制功能创建。
  • 总的来说,我觉得参与这个项目很令人兴奋。我学到了很多关于数据分析的东西,特别是使用散景的数据可视化。
  • 使用 CatBoost 创建一个模型需要一些初步的尝试和错误。尽管我没有改变很多默认参数,但结果非常好。部分原因是因为我在训练集中包括了像“查看的报价数量”这样的功能,这是报价完成率的一个很好的指标,基于此,我对目标类进行了编码。

未来细化

  • 我建议尝试自定义分类特征来训练模型。
  • 此外,从数据集中移除一些自定义要素并评估模型也会很有趣。
  • 关于特征工程,可以开发关于顾客在查看报价之前已经花费多少的特征。

非常感谢您阅读这篇文章。如果你对该项目的更多细节感兴趣,请点击查看项目资源库

星巴克优惠数据集——uda city 顶点

原文:https://towardsdatascience.com/starbucks-offer-dataset-udacity-capstone-7b562843ff47?source=collection_archive---------15-----------------------

实践教程

对“浪费要约”的调查

卡尔·弗雷德里克森Unsplash 上拍摄

介绍

Starbucks Offer Dataset 是学生可以从中选择的数据集之一,以完成他们的 Udacity 数据科学纳米学位的顶点项目。该数据集包含模拟数据,模拟顾客收到星巴克报价后的行为。这些数据是通过星巴克奖励移动应用程序收集的,优惠每隔几天就会发送给移动应用程序的用户。

数据文件包含 3 个不同的 JSON 文件。

*File descriptions provided by Udacity*portfolio.json — containing offer ids and meta data about each offer (duration, type, etc.)profile.json — demographic data for each customertranscript.json — records for transactions, offers received, offers viewed, and offers completed

有 3 种不同类型的优惠:买一送一(BOGO),折扣,和信息意味着纯粹的广告。然而,对于每种类型的优惠,优惠期限、困难或促销渠道可能会有所不同。该数据集包含大约 300,000+个模拟事务。

这个项目的目标不是由 Udacity 定义的。因此,它是开放式的。尽管如此,从为星巴克提供商业价值的角度来看,问题总是要么:我们如何增加销售额,要么我们如何省钱。如何省钱的问题不是不花钱,而是不把钱花在无效的事情上。

从这两个角度来看,都有很多值得探索的东西。Udacity 给出的一个警告引起了我的注意。它警告我们,一些优惠在用户不知情的情况下被使用,因为用户不会加入这些优惠;报价已经给出。因此,如果一些用户不管有没有优惠都会在星巴克消费,我们还不如保存这些优惠。

我觉得这是个有趣的问题。我决定对此进行调查。我想看看我是否能找出这些用户是谁,我们是否能避免或尽量减少这种情况的发生。在下面的文章中,我将介绍我是如何研究这个问题的。我将遵循 CRISP-DM 流程。如果你不熟悉这个概念。这是我写给你的一篇文章。

[## 数据科学在线课程没有教给你的两件重要事情

如果你的数据科学在线课程大纲看起来像…

towardsdatascience.com](/2-crucial-things-that-data-science-online-courses-didnt-teach-you-2da0ae3267bd)

业务理解和数据理解

我们先来看看数据。从数据集来看,很明显,我们需要组合所有三个数据集,以便执行任何分析。此外,数据集需要大量清理,主要是因为我们有许多分类变量。

下面是我希望在分析结束时解决的五个业务问题。前三个问题是为了对数据集有一个全面的了解。最后两个问题直接解决了我想调查的关键业务问题。

  • Q1:哪个是最受欢迎的提议?
  • Q2:不同的人群对报价有不同的反应吗?
  • 问题 3:人们通常会查看并使用优惠吗?还是他们在没有注意到的情况下使用了报价?
  • Q4:如果存在这样一个群体,那么哪一类人更有可能在没有查看报价的情况下使用报价或进行购买?
  • Q5:如果有,哪种类型的优惠更有可能在不被查看的情况下被使用?

在我摆弄了一下数据之后,我还决定在这个分析中只关注 BOGO 和折扣优惠,主要有两个原因。一是因为我相信 BOGO 和折扣优惠与信息性优惠/广告有着不同的商业逻辑。对于 BOGO 和折扣优惠,我们希望找出不知情的人,这样我们就不会白花钱。对于这个广告,我们想确定哪一组人被鼓励花更多的钱。换句话说,一个逻辑是确定损失,而另一个是衡量增长。

另一个原因和第一个原因联系在一起,就是关于范围的问题。由于不同的业务逻辑,我想把这个分析的范围限制在只回答这个问题:谁是“浪费”我们的产品的用户,我们如何避免它。因此,我没有分析信息提供类型。

成功指标及其合理性

重复一遍,我想要解决的商业问题是调查用户在没有观看我们的产品的情况下使用它的现象。换句话说,优惠没有起到刺激消费的作用,因此被浪费了。因此,关键的成功标准是我是否能识别出这群用户以及这种行为背后的原因。此外,如果我可以建立一个机器学习模型来预测这种情况何时可能发生,这将是有帮助的。在这种情况下,该公司将处于一个更好的位置,不会浪费这个机会。

明确地说,关键的成功标准是我是否对上面列出的所有问题都有明确的答案。因为能够回答这些问题意味着我可以清楚地识别出有这种行为的用户群,并对原因进行一些教育猜测。

对于机器学习模型,我重点以交叉验证准确率和混淆矩阵作为评价。准确性分数很重要,因为我的模型的目的是帮助公司预测何时要约可能会被浪费。所以精度越高越好。

当然,当数据集高度不平衡时,准确度分数不会是实际准确度的良好指标,精确度分数、f1 分数或混淆矩阵会更好。然而,在这种情况下,不平衡的数据集不是一个大问题。两个虚拟模型,其中一个使用随机猜测的方法,另一个使用全部选择多数的方法,一个具有 51%的准确度分数,另一个具有 57%的准确度分数。这表明数据集不是高度不平衡的。

我选择混淆矩阵作为第二个评估矩阵,与交叉验证准确性一样重要。原因是与假阳性和假阴性相关的商业成本可能不同。因此,了解模型更容易出现哪种类型的错误将是有益的。有些人喜欢 f1 的分数。然而,我发现 f1 的分数有点难以理解。因此,我坚持使用混淆矩阵。为了更好地处理第一类和第二类错误,这里是我之前写的另一篇文章,有更多的细节。

[## 为什么一定要说 1 型错误和 2 型错误?

从模型评估到商业决策…

towardsdatascience.com](/programming-journal-4-why-do-we-have-to-talk-about-type-1-error-and-type-2-error-41b3ae68bb96)

数据准备

在数据准备阶段,我主要做了两件事。一个是合并 3 个数据集。另一个是将所有的分类变量转换成数字表示。

合并 3 个数据集的一个困难是抄本数据集中的'值''列包含报价 id 和美元金额。此外,该列是一个字典对象。下面是我如何使用' offer_id '来分隔列,以便数据集可以与投资组合数据集相结合。

当把分类变量转换成数值变量时。有两个更复杂的列,一个是“年”列,另一个是“通道”列。‘year’列很棘手,因为数字表示的顺序很重要。举个例子,如果我用:0–2017,1–2018,2–2015,3–2016,4–2013。这违背了我们的直觉。然而,对于其他变量,如“性别”和“事件”,数字的顺序并不重要。因此,我为分类变量编写了一个不需要考虑顺序的函数。

‘channel’列比较棘手,因为每个单元格都是一个对象列表。有两种方法可以解决这个问题。一种方法是将每个通道转换成列索引,并用 1/0 表示该行是否使用了该通道。然而,我使用了另一种方法。我意识到有 4 种不同的频道组合。我想知道不同的组合对每个优惠有什么不同的影响。所以,我想把物品清单当做 1 个东西。我是这样处理的。

EDA 和结果:

Q1:哪个是最受欢迎的提议?

左边绝对数字,右边百分比|作者图片

回答:折扣优惠更受欢迎,因为它不仅在绝对值方面“报价完成”的数量略高,而且总体完成/接收率也更高(~7%)。然而,值得注意的是,BOGO 优惠有更大的机会被顾客看到。

Q2:不同的人群对报价有不同的反应吗?

在两个图表中,红色的“否”表示未完成(查看或收到),绿色的“是”表示“报价完成”。

对于 BOGO 的提议

对于折扣优惠

回答:对于这两种提议,男性完成的几率都要低得多。越是忠诚的客户,加入 5-6 年的人使用这两种优惠的机会也越低。比较这两种优惠,女性稍微更多地使用 BOGO,而男性更多地使用折扣。然而,仅仅从外观上看,这两个报价之间并没有太大/显著的区别。

问题 3:人们通常会查看并使用优惠吗?还是他们在没有注意到的情况下使用了报价?

答:在实验时间的前 5 天中,“要约已完成”的峰值略早于“要约已查看”。随着时间的推移,它们同步得更好,这表明大多数人有意识地使用了这个提议。随着时间的推移,“已完成报价”和“已查看报价”之间的差距也在缩小。

Q4:如果存在这样一个群体,那么哪一类人更有可能在没有查看报价的情况下使用报价或进行购买?

我挑选了客户 id,它的第一个要约事件是“offer received ”,随后是第二个事件“offer completed”。他们是跳过“已查看报价”的人。然后,我将他们的人口统计信息与其他人进行了比较。这是项目中最棘手的部分,因为我需要弄清楚如何提取对要约的第二个响应。我是这样做的。

以下是我的分析结果:

答:正如您所看到的,没有显著的差异,这令人失望。这表明,所有客户都有可能在不看我们的产品的情况下使用我们的产品。那么,这可能与我们设计产品的方式更有关系吗?我们来看下一个问题。

Q5:如果有,哪种类型的优惠更有可能在不被查看的情况下被使用?

如您所见,产品的设计的确与众不同。例如,蓝色部分,即报价以“1d7”结尾,明显大于正态分布(~17%)。以“2a4”结尾的报价也比正态分布高出 4–5%。以下是关于这些优惠的信息,按照它们在没有被注意到的情况下被使用的次数排序。

回答:我们看到促销渠道和持续时间起着重要的作用。从这个分析中我们可以得出以下结论。

  • 如果一份工作是通过网络和电子邮件推广的,那么它被发现的机会就大得多
  • 在不查看的情况下用于链接到优惠的持续时间。持续时间越长
  • 与 BOGO 相比,折扣优惠类型也有更大的机会不用看就能使用。

建模和评估

我想调查的主要问题是,谁浪费了这些提议,这个问题已经被之前的数据工程和 EDA 解决了。建立机器学习模型的目的是预测一项提议被浪费的可能性。如果机会很大,我们可以计算商业成本并重新考虑决定。因此,该模型可以帮助最小化“浪费要约”的情况。

对于模型选择,我正在决定是使用决策树还是逻辑回归。我将范围缩小到这两个,因为在这种情况下,拥有预测的类别概率也是有用的。我们可以知道我们对一个特定的预测有多有信心。此外,我们可以设定,如果只有 70%以上的机会,客户会浪费一个报价,我们将考虑撤回一个报价。对我来说,仅仅因为客户有 51%的机会浪费它,就撤销一个报价是没有意义的。

我最终选择了逻辑回归,因为它更稳健。决策树通常需要更多的调整,并且对不平衡数据集等问题更加敏感。我们的数据集与

1- ‘wasted offers’: 31723
0- ‘used offers’: 23499

建模前的一个重要步骤是获得正确的标签。在这种情况下,标签“浪费”意味着客户要么根本没有使用该产品,要么使用后没有查看。以下是我如何创建这个标签。

然后我丢弃所有其他事件,只保留‘浪费的’标签。我将这个数据集与 profile 和 portfolio 数据集合并,以获得我需要的特性。最终,数据框看起来像这样:

我使用 GridSearchCV 来调整逻辑回归模型中的【C】参数。我使用默认的【L2】作为惩罚。原因是我们在数据集中没有太多的特征。代码如下:

最佳模型实现了 71%的交叉验证准确性,75%的精确度分数。对于混淆矩阵,假阳性的数量(15%)多于假阴性的数量(14%),这意味着该模型更有可能在现实中不会被浪费的报价上出错。

为了改进模型,我对多数标签进行了下采样,并平衡了数据集。我使用下采样而不是上采样或 smote 等其他方法的原因是:1)即使在下采样后,我们也有足够的数据 2)根据我的理解,不平衡数据集不是由于有偏差的数据收集过程,而是由于可用样本较少。在这种情况下,使用 SMOTE 或上采样会导致数据集过拟合的问题。更多细节,下面是我深入探讨这个问题时的另一篇文章。

[## 从不平衡数据集到助推算法

不平衡数据集完整工具包

朝向数据科学](/from-imbalanced-dataset-to-boosting-algorithms-1-2-798cd6384ecc)

在平衡数据集后,最佳模型的交叉验证准确性增加到 74%,精确度分数仍为 75%。对于混淆矩阵,假阳性减少到 11%,假阴性减少到 15%。这意味着模型更有可能在现实中想要的报价上出错。通过调整更多的参数或尝试像 XGboost 这样的树模型,该模型有很大的潜力可以进一步改进。但是,由于个人时间和精力的限制,我就此打住了。

总结/概括

总之,我已经向您介绍了我如何处理数据来合并 3 个数据集,以便我可以进行数据分析。我谈到了我如何使用 EDA 来回答我在文章开始时提出的业务问题。在这个过程中,您可以看到我需要如何进一步处理我的数据以适合我的分析。我还强调了处理数据最困难的地方,以及我是如何处理这个问题的。

结果硕果累累。我成功地回答了我提出的所有商业问题。虽然,在调查之后,问这样一个问题似乎是错误的:谁是没有看我们的产品就使用了它的顾客?相反,问题应该是:为什么我们的报价没有被浏览就被使用了?原因是人口统计并不重要,但优惠的设计很重要。

最后,我用逻辑回归建立了一个机器学习模型。我解释了为什么选择模型,如何准备模型处理的数据以及模型的结果。我使用了 3 种不同的指标来衡量模型、交叉验证准确性、精确度分数和混淆矩阵。在这篇文章的最后,我想对商业和潜在的未来研究提出一些建议。

最后建议和未来研究

为了避免或改善不经查看就使用报价的情况,我建议如下:

  • 通过至少 3 个渠道推广产品,增加曝光率
  • 排除持续 10 天的报价,最大值。7 天。如果一个报价真的很难,20 级,客户就不太可能为之努力。与此同时,那些实现这一目标的人很可能会实现这一数额的支出,而不管报价如何。

我的另一个建议是,我相信折扣优惠有很大的潜力。在那些浏览过报价的人中,完成率为 78%。因此,如果公司能够提高折扣优惠的收视率,就有很大的机会刺激更多的支出。

对于以后的学习,还有很多可以做的。最显而易见的两件事是执行一项分析,合并来自信息提供的数据,并改进我当前模型的性能。观察顾客对信息提供的反应以及广告或信息提供是否也有助于 BOGO 和折扣的表现将是有趣的。将我的模型准确率提高到 85%以上会很有帮助。

我的全额回购可以在这里进入

星巴克促销活动:你会花钱吗?

原文:https://towardsdatascience.com/starbucks-promotional-campaigns-will-you-spend-your-money-9e8e965ab3d?source=collection_archive---------79-----------------------

使用 Python 和 ensemble 方法深入挖掘星巴克顾客

埃里克·麦克林在 Unsplash 上的照片

每当星巴克向你提供买一送一的促销活动时,你会感到兴奋吗?然而,你被这个优惠吸引到最近的星巴克店消费了吗?

简介

所使用的数据集包含来自星巴克的模拟数据,这些数据模拟了顾客在他们的 rewards 移动应用上的行为。星巴克每隔几天就会发出一次优惠,可以是饮料的广告,也可以是实际的优惠,如折扣或 BOGO(买一送一)。然而,并不是每个用户都能得到相同的优惠,而且在优惠到期之前,每个优惠都有一个有效期。

通过将年龄和性别等人口统计数据与交易和报价数据相结合,我们希望实现两个目标:

1。报价视图和已完成的预测模型

想象自己是一名收入一般的年轻女性,当你查看手机时,你看到一则广告:星巴克的 BOGO 促销活动将在 3 天后到期。你会使用促销吗?

或者想象一下如果你是一个富裕忙碌的中年男性。你会有时间去看星巴克的广告吗?或者你会直接在最近的星巴克店里使用 BOGO 促销活动?

该模型旨在预测特定人群中的特定客户是否会查看或/和完成星巴克发送的报价。

2。平均支出预测模型

相对于平均交易,星巴克给你的优惠有多有效?如果您收到并查看了星巴克的某些优惠,您会在星巴克消费多少金额?该模型旨在了解会员在看到优惠后直到有效期到期平均会花多少钱。

第一部分报价查看&完成预测模型

由作者拍摄

基于上面的相关图,推广变量(类型、奖励、难度)而不是人口统计属性影响更多的人观看广告。像 BOGO 这样的提议似乎很有吸引力。超过 70%的优惠被会员查看。与只有 57.9%成功率的其他类型的活动相比,这是一个非常显著的数字。

由作者拍摄

然而,故事是不同的其他类型的运动,如信息运动,将通知你,如果有新类型的饮料。只有 55%的会员观看了广告。

由作者拍摄

与报价最相关的人口统计属性是年龄组。如下图所示,年轻成人年龄组(17-25 岁)中有 41.6%的会员甚至不屑于看到报价,而其他年龄组的成功率为 63.1%。

由作者拍摄

这是为什么呢?似乎年轻的成年人群体对 BOGO 的促销活动反应良好。68.2%的人看过 BOGO 的竞选活动,只有 52%的人看过其他类型的竞选活动。

由作者拍摄

现在,让我们继续讨论报价完成与其他变量的关系。请注意,当会员在促销有效期到期前超过最低消费时,优惠即被归类为已完成。

由作者拍摄

发现的一个有趣的注意事项是,2018 年加入的成员(数据集的最新成员)的失败率为 71.5%。它比其他会员多了将近 20%!

由作者拍摄

但是优惠的类型呢?虽然 BOGO 活动是最成功的报价,但折扣活动对报价完成率的影响更大。

由作者拍摄

性别在这里被证明是至关重要的。与女性相比,男性未完成工作的比例高出 14%。

由作者拍摄

我们知道,与女性相比,男性不太可能完成报价。现在,什么样的男人会完成一个提议,什么样的提议足够吸引他们去完成?通过结合上面的另一个见解,我们可以看到折扣非常受欢迎,在 2018 年之前成为会员的男性中有 59%完成了折扣。

由作者拍摄

让我们开始建模。由于有两个分类,即已查看和已完成的报价,因此使用 MultiOutputClassifier,这意味着将有四种不同类型的输出,即未查看和未完成报价的客户(0,0),未查看和完成报价的客户(0,1),已查看和未完成报价的客户(1,0),以及已查看和完成报价的客户(1,1)。两个集成学习模型,梯度提升和随机森林与网格搜索一起使用。

pipeline = Pipeline([
    ('clf', MultiOutputClassifier(GradientBoostingClassifier())) 
    ])parameters = [
    {
    "clf": [MultiOutputClassifier(GradientBoostingClassifier())],
    'clf__estimator__learning_rate':[0.5, 0.25],
    'clf__estimator__n_estimators':[100, 200],
    },
    {
    "clf": [MultiOutputClassifier(RandomForestClassifier())],
    'clf__estimator__n_estimators': [100,200]
    }]grid = GridSearchCV(pipeline, param_grid = parameters, cv=10, return_train_score=False)grid.fit(X_train, y_train)

在训练数据集中以 54%的最佳平均测试分数返回的最佳模型是具有学习率 0.25 和 n_estimators 100 的超参数的梯度增强。

为什么渐变提升比随机森林表现更好?对于不平衡数据集,如用于此模型的训练数据集(只有 8%的标签是未查看和完成报价的客户),梯度提升的性能优于随机森林。Boosting 一步一步地关注困难的例子,这些例子通过加强正类的影响给出了处理不平衡数据集的好策略。

让我们看看模型如何执行测试数据集。

y_pred = grid.predict(X_test)label = ['Offer Viewed', 'Offer Completed']report = classification_report(y_test, y_pred, output_dict=True, target_names=label)confusion_matrix_viewed = multilabel_confusion_matrix(y_test, y_pred)[0]
accuracy_viewed = round(sum(confusion_matrix_viewed.diagonal())*100/confusion_matrix_viewed.sum(), 2)
recall_viewed = round(report['Offer Viewed']['recall']*100,2)
precision_viewed = round(report['Offer Viewed']['precision']*100,2)
confusion_matrix_completed = multilabel_confusion_matrix(y_test, y_pred)[1]
accuracy_completed = round(sum(confusion_matrix_completed.diagonal())*100/confusion_matrix_completed.sum(), 2)
recall_completed = round(report['Offer Completed']['recall']*100,2)
precision_completed = round(report['Offer Completed']['precision']*100,2)print('The overall accuracy of the model on both class in the test dataset is {}%. Accuracy, recall and precision for offer viewed are {}%, {}% and {}%, \
while accuracy, recall and precision for offer completed are {}%, {}% and {}%.'.format(round(grid.score(X_test, y_test)*100,2),\                                                                              accuracy_viewed,recall_viewed,precision_viewed,\                                                                                   accuracy_completed,recall_completed,precision_completed))

该模型在测试数据集中对两个类的总体准确率为 53.85%。已查看要约的准确率、召回率和准确率分别为 71.03%、80.39%和 75.13%,已完成要约的准确率、召回率和准确率分别为 72.44%、70.27%和 66.84%。

第二部分。平均支出预测模型

由作者拍摄

人口统计组属性,如收入、性别和年龄组,在会员在优惠有效期内查看优惠后,主导与会员平均消费的相关性。

被归类为高收入成员的成员通常花费大约 30 美元,中等收入成员通常花费 20 美元,低收入成员通常花费大约 5-10 美元。

由作者拍摄

男性和女性在看到报价后的消费行为是不同的。女性通常花费 25-30 美元,而男性通常只花费 10 美元以下。

由作者拍摄

最有趣的是老年组(60 岁以上)和其他年龄组之间的比较。老年人群花费最多,大约 30 美元,而其他年龄组大约 10 美元。

由作者拍摄

让我们开始建模。梯度推进和随机森林与网格一起用于搜索最佳模型和超参数。

pipeline = Pipeline([
    ('clr', GradientBoostingRegressor()) 
    ])parameters = [
    {
    "clr": [GradientBoostingRegressor()],
    'clr__learning_rate':[0.5, 0.25, 0.1],
    'clr__n_estimators':[100, 200,300],
    'clr__max_depth':[10,20,50]
    },
    {
    "clr": [RandomForestRegressor()],
    'clr__n_estimators': [100,200,300],
    'clr__max_depth':[10,20,50],
    'clr__min_samples_split':[2, 5, 10]
    }]grid_amount = GridSearchCV(pipeline, param_grid = parameters, cv=10, return_train_score=False)grid_amount.fit(X_train, y_train.values.ravel())y_pred_train = grid_amount.predict(X_train)
print(mean_absolute_error(y_train, y_pred_train))
print(mean_squared_error(y_train, y_pred_train))

运行网格搜索后的最佳模型是随机森林,其超参数估计数为 300,最大深度为 10,最小样本分裂为 10。训练数据集上的平均绝对误差和均方误差分别为 5.52 和 186.80。

由作者拍摄

对于这种回归问题,随机森林的表现优于梯度增强的原因是因为数据中存在异常值(见上图)。离群值可能对 boosting 不利,因为 boosting 将每棵树建立在先前树的残差/误差上。异常值将比非异常值具有大得多的残差,因此梯度增强将在这些点上集中不成比例的注意力。

让我们看看它在测试数据集中的表现。

y_pred = grid_amount.predict(X_test)
print(mean_absolute_error(y_test, y_pred))
print(mean_squared_error(y_test, y_pred))

在测试数据集上,平均绝对误差和均方误差分别为 6.33 和 279.52。

与数据集中从 0 到 600 的平均支出范围值相比,6.33 的平均绝对误差听起来令人吃惊,但是我们应该考虑到数据集的平均值只有 15 左右。

第三部。结论&改进

  1. 优惠类型等促销属性会影响会员查看他们收到的优惠的行为。70%的会员会查看像 BOGO 这样的优惠类型。
  2. 在完成报价的过程中,人口属性起着重要作用。与女性相比,男性未完成工作的比例高出 14%。
  3. 对于提供已查看和已完成的模型,梯度增强的性能优于随机森林模型,因为对于不平衡数据集,它的性能优于随机森林。为了改进,欠采样或过采样不平衡类可以解决这个问题。梯度增强模型在测试数据集中的两个类上的总体准确度是 53.85%。已查看要约的准确率、召回率和准确率分别为 71.03%、80.39%和 75.13%,已完成要约的准确率、召回率和准确率分别为 72.44%、70.27%和 66.84%。
  4. 在报价有效期内,不同的人口统计组在他们观看某些报价后,相对于他们花费的平均金钱表现不同。男性通常只花 10 美元以下,而女性通常花 25-30 美元左右。
  5. 对于平均支出模型,随机森林比梯度增强模型表现更好,因为数据集中存在离群值。为了改进,处理异常值可能会解决这个问题。测试数据集中的平均绝对误差和均方误差分别为 6.33 和 279.52。

参考文献

完全归功于 Udacity 和 Starbucks 提供的数据集。你可以在这里看到完整的代码:【https://github.com/dhaneswaramandrasa/starbucks】T2。

  1. http://ecmlpkdd2017.ijs.si/papers/paperID241.pdf
  2. https://medium . com/@ aravanshad/gradient-boosting-vs-random-forest-CFA 3 fa 8 f 0d 80
  3. https://stats . stack exchange . com/questions/140215/why-boosting-method-is-sensitive-to-Outliers #:~:text = Outliers % 20 can % 20 be % 20 bad % 20 for,its % 20 attention % 20 that % 20 points。

Python 中的星图

原文:https://towardsdatascience.com/stars-charts-in-python-9c20d02fb6c0?source=collection_archive---------35-----------------------

使用 Diamonds 和 Matplotlib 创建星图的教程

戴夫·赫林在 Unsplash 上拍摄的照片

钻石是数据科学家最好的朋友。更具体地说,在 Kaggle 上发现的钻石数据集。在本文中,我将通过一个简单的工作流程来创建一个星图(又名蜘蛛图或雷达图)。本教程改编自 Alex 在 Python Charts 的精彩工作流程。本文中的所有代码和所需的数据集都可以在 GitHub 的中找到。

钻石是数据科学家最好的朋友

首先,您需要几个库。我正在运行 Python 3。我使用 Jupyter 笔记本、pandas、matplotlib 和 numpy 创建了这个工作流。如果您的系统中没有这些软件包,可以通过 pip 或 conda 安装它们。

pip install jupyterlab
pip install pandas
pip install matplotlib 
pip install numpy

数据集可以从 Kaggle 下载,大小应该在 3.2 MB 左右。我已经在 Github 上包含了数据集的副本。我在数据文件夹里有数据集。用熊猫加载数据集,删除额外的索引列,我们就可以开始了!

df = pd.read_csv("data/diamonds.csv")
df.drop("Unnamed: 0", axis=1, inplace=True)

3 C 的水平

钻石的 4 C 标准是切割、颜色、净度和克拉。切割、颜色和净度被定义为钻石行业中使用的分类变量。克拉是代表宝石重量的数字。

照片由张浩Unsplash 上拍摄

为了创建星形图,我们需要用数字来表示钻石行业术语。为此,我们需要收集数据集中的级别信息。Cut 由五个级别组成,其中理想为最高级别【4】,一般为最低级别【0】。在颜色的七个等级中, D 为最高等级【6】,而 J 为最低等级【0】。最后,净度由八个级别组成,其中 IF、表示内部无瑕疵为最高级别【7】,而 I1 、内含物级别 1 为最低级别【0】。

显示切割和抛光数据

在我们的数据集中,我们剔除了 3 个偏离下游色谱柱刻度的异常值。

## Cut diamonds that skew carat range
indicies_to_remove = [27415, 27630, 27130]
df = df.drop(indicies_to_remove)

接下来,我们在数据帧中创建新的列来存放通过将字典映射到 C 的列而创建的排名。下面是一个映射示例。

cut={'Ideal':4,'Premium':3,'Very Good':2,'Good': 1,'Fair':0}
df['Cut'] = df['cut'].map(cut) #Note: 'Cut' is a different column

最后,我们需要缩放我们将在星形图中使用的列,以公平地表示数据。

## Convert all rankings and contiguous data to scale between 0-100
factors = ['Cut', 'Color', "Clarity", "carat", "price"]new_max = 100
new_min = 0
new_range = new_max - new_min## Create Scaled Columns
for factor in factors:
    max_val = df[factor].max()
    min_val = df[factor].min()
    val_range = max_val - min_val
    df[factor + '_Adj'] = df[factor].apply(lambda x: (((x - min_val) * new_range) / val_range) + new_min)

然后,我们将缩放后的列划分为子集,用于下游绘图。请注意,我们正在创建一个新的数据框架(df2 ),其中仅包含我们打算在星形图中使用的列。

## Subset scaled columns 
df2 = df[['Cut_Adj', "Color_Adj", "Clarity_Adj", "carat_Adj", "price_Adj"]]
df2.columns = ['Cut', "Color", "Clarity", "Carat", "Price"]

演出的明星

要创建星形图表,我们必须指定要使用的列,并使用 numpy 创建圆形绘图对象。

labels = ['Cut', "Color", "Clarity", "Carat", "Price"]
points = len(labels)angles = np.linspace(0, 2 * np.pi, points, endpoint=False).tolist()
angles += angles[:1]

然后,我们创建一个助手函数,仅通过索引号绘制一个菱形。

def add_to_star(diamond, color, label=None):
    values = df2.loc[diamond].tolist()
    values += values[:1]
    if label != None:
        ax.plot(angles, values, color=color, linewidth=1, label=label)
    else:
        ax.plot(angles, values, color=color, linewidth=1, label=diamond)
    ax.fill(angles, values, color=color, alpha=0.25)

现在魔法开始了!我们可以开始用我们想要的钻石填充我们的星图。最贵的和两个最便宜的怎么样:

## Create plot object   
fig, ax = plt.subplots(figsize=(6, 6), subplot_kw=dict(polar=True))## Plot a new diamond with the add_to_star function
add_to_star(27749, '#1aaf6c', "Most Expensive Diamond")
add_to_star(0, '#429bf4', "Least Expensive A")
add_to_star(1, '#d42cea', "Least Expensive B")

这个数量足以创建一个星图,但是,没有 x 标签,没有方向,也没有自定义风格。让我们改变这一切!

## Fix axis to star from top
ax.set_theta_offset(np.pi / 2)
ax.set_theta_direction(-1)## Edit x axis labels
for label, angle in zip(ax.get_xticklabels(), angles):
    if angle in (0, np.pi):
        label.set_horizontalalignment('center')
    elif 0 < angle < np.pi:
        label.set_horizontalalignment('left')
    else:
        label.set_horizontalalignment('right')## Customize your graphic# Change the location of the gridlines or remove them
ax.set_rgrids([20, 40, 60 ,80])
#ax.set_rgrids([]) # This removes grid lines# Change the color of the ticks
ax.tick_params(colors='#222222')
# Make the y-axis labels larger, smaller, or remove by setting fontsize
ax.tick_params(axis='y', labelsize=0)
# Make the x-axis labels larger or smaller.
ax.tick_params(axis='x', labelsize=13)# Change the color of the circular gridlines.
ax.grid(color='#AAAAAA')
# Change the color of the outer circle
ax.spines['polar'].set_color('#222222')
# Change the circle background color
ax.set_facecolor('#FAFAFA')# Add title and legend
ax.set_title('Comparing Diamonds Across Dimensions', y=1.08)
ax.legend(loc='upper right', bbox_to_anchor=(1.3, 1.1))# Draw axis lines for each angle and label.
ax.set_thetagrids(np.degrees(angles), labels)

那么产量是多少呢?

最贵和最便宜的两颗钻石的星图。Carets 似乎是价格的一大驱动因素。

最物有所值的珠宝

4 C 系列中价格最低、评级最高的钻石是什么?要找出答案,我们必须得到 4 个 C 的总价值,然后除以原始(未缩放)价格。这个部分对包含所有原始列的原始数据帧进行操作。为了计算总数,我们对四个缩放的列求和。

df['Total'] = df['Cut_Adj'] + df['Color_Adj'] + df['Clarity_Adj'] + df['carat_Adj']## Divide Value total by Price
df['4C_by_Price'] = df['Total']/df['price']
df = df.sort_values(by="4C_by_Price", ascending=False)

对我们来说最闪亮的钻石是#31597,最不闪亮的钻石是#26320。这些钻石在星图上如何比较?下面我们来探讨一下:

一个是交易中的钻石,另一个是一大块碳。

结论:

感谢您使用 matplotlib 探索星形图表格式中的一些钻石特征。如果你有任何问题,请在下面或者完整代码的位置 GitHub 库发表。我的名字是科迪·格利克曼,我可以在 LinkedIn 上找到。一定要看看其他一些关于有趣的数据科学项目的文章!

[## 使用 Python 创建照片镶嵌

一步一步的教程,让你自己的美丽的图像

towardsdatascience.com](/creating-photo-mosaics-using-python-49100e87efc) [## 刮胡子,还是不刮胡子,这是个问题

使用深度学习对有胡须和无胡须的照片进行年龄分类

towardsdatascience.com](/to-beard-or-not-to-beard-that-is-the-question-b46864d7e003) [## 使用 Dash 和 SQL 快速浏览圣诞歌曲

使用 SQL 数据库创建 Dash 仪表板的简单项目

towardsdatascience.com](/dashing-through-christmas-songs-using-dash-and-sql-34ef2eb4d0cb)

通过基本的统计数据开始看清事物

原文:https://towardsdatascience.com/start-to-see-things-clearly-with-basic-statistics-4acb2d4c7dc4?source=collection_archive---------57-----------------------

赤裸裸的统计,统计类和现实生活中的情况之间的桥梁,在一个有趣和深刻的方式

马尔科姆·莱特曼在 Unsplash 拍摄的照片

我其实不记得裸体统计是怎么来找我的。大概是这几个月看的一篇关于统计学的文章推荐的吧。

我决定给这本书一个机会,在一开始,我读了以下内容:

我通常知道我不知道的事情——查理斯·惠兰

很有趣,对吧?幸运的是,我提前意识到这本书很有可能值得一读。几个星期后,带着很多注解,我来了。这真的值得吗?

如果您对以下任何一项感兴趣:

  1. 一些真实的社会经济问题是如何被研究的,最重要的是,是什么使得这些问题如此难以解决,以及它们潜在的缺陷;
  2. 一般的分析情境与通常探究的情境有何不同。

…或者,当然,两者兼而有之,你打赌这是值得的。

作为一本统计学书籍,它的基础当然是统计学。因此,重要的是要强调,你可能需要重温一些你在学校或大学里学过的公式和概念,以便完全了解结果背后的分析是如何完成的。如果你从未学习过(或者什么都不记得了),这绝对是一个很好的途径,可以用来指导你的基础统计学学习。

然而,这不是一个关于统计公式或者数学推理的帖子。讲的是分析数据时的视角。

为了让你不被蒙在鼓里,我列出了一些你在阅读时将要面对的概念:

  • 平均值、中值、标准差、方差、异常值和四分位数
  • 相互关系
  • 可能性
  • 中心极限定理
  • 推理
  • 回归分析

好的,上面提到的所有这些和透视有什么关系?

“健康的用户偏好”

这是典型的因果关系误解和看问题时未观察到的差异的混合。

正如书中所写,“定期服用维生素的人很可能是健康的——因为他们就是那种定期服用维生素的人!”。你已经明白了吗?

维生素对人们健康的影响当然非常重要,但是,还有什么呢?让我们进一步探索…让我们分别看看每一部分,坚持两者的相同故事:

  1. 因果关系——关联误解:这是众所周知的情况。简而言之,两件事密切相关的事实并不一定意味着一个变量的变化导致了另一个的变化。正如书中所解释的那样,平均来说,一个家庭拥有的电视越多,学生在 SAT 考试中取得的成绩就越好。因此,电视的数量与良好的测试性能有一定的正相关关系。然而,购买新电视并不会使某个学生在 SAT 考试中表现得更好。看出区别了吗?
  2. 未观察到的差异:那么,上面有什么未观察到的呢?事实上,一个家庭中电视机的数量与家庭的富裕程度密切相关。认为参加额外数学课或有良好互联网接入的学生比那些不参加的学生更容易在考试中表现更好,这不是更合乎逻辑吗?

有时候,在分析情况时,我们倾向于对观察到的结果给自己具体的解释,而简单地忽略其他一切。大多数时候,这是无意中发生的(根据具体情况,这不是或者不应该是一个可以接受的解释)。

具有讽刺意味的是,查尔斯在书中走得更远,在第 7 章探索“紫色睡衣”的例子。

有很多我们日常生活中的例子,这里的要点是将这种认知扩展到我们日常面对的最可能的情况。起始问题是:为什么会这样 ?通常,我们已经在考虑一些见解来解释为什么会发生一些事情。而且,通常,一旦我们看到一个合理的方法来解释它,我们就不再试图更深入地理解这个问题。这不仅是关于服用维生素,也是关于其他一切。

其他条件不变

这是一个来自拉丁语的表达,意思是“其他条件相同”。

所有基于假设检验的例子都依赖于进行“受控实验,其中感兴趣的变量是实验组和对照组之间唯一不同的东西。“让我们再一次用一本书的实际例子。

在第一章中,查尔斯提出:“吸烟会致癌吗?”。你会怎么说?是的,对吗?我也是。然而,正如进一步探讨的那样,“回答这个问题的过程并不像人们想象的那么简单”。为什么?

这是因为“吸烟者和不吸烟者除了他们的吸烟行为之外,很可能在其他方面有所不同。比如?吸烟者很可能会有其他导致以后患癌症的习惯,如锻炼少、不良饮食习惯和酗酒。因此,当然,当你感兴趣的结果是癌症的原因时,吸烟是一个需要分析的重要因素,但是你不应该试图仅仅根据吸烟和不吸烟的习惯来解释癌症的原因。

现在没有办法考虑数据,也不要考虑新冠肺炎。当然,很明显,研究一种新的流行病的演变,同时做出重要的决定,对于世界各地的当局来说是一项非常困难的任务。但是,你有没有试着想一想为什么?

其中一个原因正是我们在这里探讨的。不仅国家本身,而且国家内部的具体区域在几个方面显示出彼此之间非常不同的现实。这就是为什么你可能在一些新闻媒体上听到有人说社会健康政策的应用应该考虑到每个地区的现实。每个地区都将呈现出特定的感染率、死亡率、重症治疗单位(ITUs)占用率、人群隔离率、人口规模、人口分布等诸多差异。出于这个原因,当局的决定不应该是适用于整个国家的一刀切的决定,因为不存在其他条件不变的现实

这些只是这本神奇的书提供的一些例子和思考。我向你保证你会被激怒的。我不想给你更多的剧透,我真的希望这足以抓住你的好奇心。

正如书中提到的那样,“统计就像一把大口径武器:正确使用时很有帮助,但在错误的人手里可能是灾难性的”,而每个统计分析“只是需要良好判断的武器库中的一件武器”。尝试不同的视角,寻求全局,永远不要忘记自己的判断。

1: C. Wheelan,《赤裸裸的统计:从数据中剥离恐惧》(2013),W. W. Norton & Company。

开始在您现有的数据科学项目中使用 Git

原文:https://towardsdatascience.com/start-using-git-in-your-existing-data-science-project-27118c92f86e?source=collection_archive---------54-----------------------

现在开始使用 Git 还不算太晚

照片由 Yancy MinUnsplash 上拍摄

在数据科学中,你通常不是独自工作。使用 git 将有助于您与团队协作。即使你的项目中已经有了几样东西,现在开始使用 Git 还不算太晚。本文将指导您如何从现有的数据科学项目中启动 git 存储库。

我们开始吧!

第一步。准备 Git 账户/软件

  • 如果您还没有 git 帐户,请在线创建。请随意挑选你最喜欢的。我推荐 GitHub 或者 Gitlab
  • git-scm 安装到您的机器上。

第二步。创建存储库

拥有 Git 帐户后,创建一个新的空白项目存储库,并根据自己的喜好命名(与您的数据科学项目相匹配)。项目为空非常重要。不要创建任何文件或使用 Git 提供程序的任何模板。

然后,复制远程存储库 URL。

git lab 资源库(左)和 Github 资源库(右)中的远程 URL 位置(图由作者提供)

第三步。在您的项目目录中启动 Git

在这一步中,我们将在您的工作目录中启动 Git。在窗口操作中,可以从右键菜单中打开 Git Bash 开始。在 Mac 中,您可以使用终端菜单。或者,您也可以使用 VS-Code 中的内置控制台。

在 Window 操作系统上打开 Git Bash(图由作者提供)

然后,我们将使用git init命令启动本地存储库。接下来通过git add .命令将文件添加到本地存储库中。然后,我们使用git commit命令提交存储库中的文件变更。

**$ git init
$ git add .
$ git commit -m 'First commit'**

然后,我们需要使用步骤 2 中的git remote add ...命令,使用远程存储库 URL 将这个本地存储库添加到远程存储库中。通过将我们提交的更改推送到远程存储库,设置并确认一个带有git remote -v的新远程 URL。

**$ git remote add origin <**remote repository URL from step 2**>
$ git remote -v
$ git push origin master**

差不多就是这样!简单对吗?

结论

这篇短文介绍了如何以一种简单的方式在现有项目中启动 Git。如果您有任何问题、意见或建议,请随时给我留言。

安全健康

感谢您的阅读。👋😄

开始使用 Linux 命令快速分析结构化数据,而不是熊猫

原文:https://towardsdatascience.com/start-using-linux-commands-to-quick-analyze-structured-data-not-pandas-f63065842269?source=collection_archive---------29-----------------------

照片由弗拉季斯拉夫Unsplash 上拍摄

有时我们需要快速分析或验证我们的结构化数据。一般来说,人们倾向于使用熊猫,因为它看起来简单而且视觉效果好。熊猫的问题是,如果你有大量数据,它可能会超级慢。

我们还有另一个选择,那就是 Linux 命令。Linux 命令运行速度非常快(即使是在海量数据上),你甚至不需要 IDE/笔记本来运行它。你可以在你的终端上执行它们。

我准备用本教程中著名的 泰坦尼克 数据作为例子。此外,为了更好地显示,我将在 Jupyter 笔记本中编写这些 Linux 命令(仅针对本教程)。

我们开始吧

我们在某个位置有一个名为titanic.csv的 CSV 文件。

行数

我们先检查一下行数。我们可以使用 WC 命令来完成。

wc -<option> <file>

WC 代表字数。它可以读取一个文件的行数(-l)、字数(-w)和字符数。

先睹为快

通过做我们可以轻松地瞥一眼数据。我们可以检查列名和样本值。这和我们在熊猫身上做的一样。

head <file>

如果你想看到一个具体的行数,然后做

head -n <num_lines> <file>

同样,您可以看到数据的tail,它显示了数据的最后一部分。

tail -n <num_lines> <file>

逐列分析

列在结构化数据中很重要,您可以从数据中剪切/提取特定的列并对其进行分析。

我们可以使用 CUT 命令来提取特定的列。

cut -d'<delim>' -f<col_num> <file>

在这里,我删除了第 5 栏和第 6 栏(性别和年龄),而忽略了这两栏。您还可以提供列范围。例如,f1–3将提取第 1、2 和 3 列。

在 Linux 中管道(|)是一个非常有用的操作符。我们可以使用管道在其他命令的输出上运行一个命令,就像我上面做的那样。首先,我提取了 2 列,然后做了标题。我们现在会经常看到管道的使用。

检查列的最小值-最大值

很多时候我们需要知道列的值域。这里我们可以使用排序命令来完成任务。

sort <option> <file>

让我们检查年龄列中的最大值。基本上是泰坦尼克号上年纪最大的人。

我们看到它是 80。首先,我们剪切年龄列,然后以逆序(-nr)对该列进行排序,然后跳过它。

我们可以通过提供标志-n以数字顺序对列进行排序,通过提供标志-nr以相反的数字顺序对列进行排序。如果我们不提供-n标志,那么一列按字典顺序排序。

检查列中的唯一值

在这个数据中,我们有一个名为 cabin 的列,它告诉乘客所在的客舱 ID。让我们看看泰坦尼克号上总共有多少个船舱。

我们看到总共有 149 个船舱。首先我剪切了 cabin 列,然后通过传递-u标志对该列进行排序,该标志只给出唯一的值。然后计算这些唯一值的数量。

在数据中搜索

很多时候,我们需要在数据中搜索文本。我们可以使用 GREP 命令来完成。我假设你已经熟悉了 regex (正则表达式)。

grep <option> "<regex>" <file>

假设我们想要查看乘客姓名以john开头的所有记录。

grep命令搜索所有行中的文本john并打印匹配的行。参数-i在匹配时忽略大小写。我们在执行 grep 时提供了一个正则表达式。

检查列中的空值

让我们检查年龄列中空值的数量。

首先,我们删除年龄列,然后使用^$ regex 清空空行。数一数这样的线。

检查范围内的值

让我们查一下有多少乘客年龄在 10 岁以下。

有 62 名这样的乘客。基本上,如果你知道如何使用正则表达式,你可以在一个命令中做很多这样强大的事情。

最后一个例子:)

假设我们想要检查在车祸中幸存的男性人数。

首先,我选择包含male单词的行。然后剪切第 2(幸存)列,然后重新标记其中值为 1 的行(其中 1 幸存,0 未幸存)。然后最后计算行数。所以我们有 161 个。

我们只需使用一个简单的 Linux 命令就可以完成几乎所有的基本分析,这个命令即使在处理大量数据时也运行得非常快。一旦你开始使用这些命令,你会发现你可以用它做更多的事情。

我希望这篇博客对你有所帮助。请让我知道你的想法。感谢阅读。

立即开始使用 Python 的 Unittest 模块

原文:https://towardsdatascience.com/start-using-pythons-unittest-module-today-17ba0537c5a0?source=collection_archive---------62-----------------------

Python 单元测试完整演练

乔恩·泰森在 Unsplash 上的照片

单元测试

单元测试是代码的基本运行。这是不是 QA。这种方式,你验证你已经写了质量代码,而不是在别人试图使用它的时候就会崩溃的东西。

为什么要测试?

最近,在一家初创公司,我需要为一位同事编写库代码,我给他库代码和一个单元测试脚本。

每次他抱怨的时候,单元测试为我节省了时间来检查他代码中的错误。因为我的工作了,这节省了很多时间,时间是你最宝贵的财富。

照片由 insung yoonUnsplash 上拍摄

单元测试是开发的重要方面。没有你的代码的第一次运行,你怎么知道它是否工作?由于单元测试通常很快很短,通过正确地管理单元测试,您可以看到您是否破坏了旧代码或其他人的代码!

提供如何使用你的代码的例子将会很容易,因为你已经有一个了!

错误而常见的方式

让我们从展示错误的和常规的方法开始。这里有一个简单的类对象:

如你所见,这个类做的不多。它接受一个数字,并对给定的输入进行幂运算。现在,一个标准的开发人员会如何验证这些代码呢?

胡安·鲁米普努在 Unsplash 上拍摄的照片

这个方法好像不太对;以下是几个主要原因。

  • 这是不可持续的——只是分散在许多文件中的小测试,没有任何方法来跟踪甚至重用这些测试。
  • 这很混乱,并且给我们的程序增加了未使用的代码块。
  • 它确保单元测试只发生一次,而不是在发布的每个新版本中验证。

你可能会说——他可以删除它,但是他所有的单元测试工作都是徒劳的,你不会在每个版本中重用它,来改进你未来的代码,或者把你的工作片段给其他用户。

正确的方法

UnsplashKrisjanis Mezulis 拍摄的照片

有许多 python 测试模块,你可以为它们中的许多给出有力的论据,我喜欢 python unittest 有许多原因,它的简单快速有效,并且在标准库中!

让它工作!

  • 测试类必须从 unittest 继承。测试案例
  • 每个测试功能必须在测试 _ 中开始
  • unittest.main() 是运行来测试结果的函数。

三个小小的规则,你就有了一个合适的单元测试,很简单,不是吗?

选项

维多利亚诺·伊斯基耶多在 Unsplash 上拍摄的照片

不仅仅是断言相等。您可以检查任何您喜欢的东西,从数字到类型,提出正确的异常,任何您可以想象的东西,都在一个简单的标准库模块中,由 Python 开发团队维护。

最后的想法

对于每个开发人员来说,单元测试是一个必不可少的工具,Python 单元测试是一个很好的模块。

适当的单元测试将在许多方面节省你的时间,包括未来的错误,破坏同事的代码,甚至是向他人展示他们如何使用你的系统的伟大片段,这种方式增加了你编写的程序实用和有益的几率。

如果你喜欢这些文章,请发表评论,关于 Python 标准库的更多内容,请就你关心的主题发表评论,我会写下来。

我希望你喜欢它!

用 4 个步骤开始您的数据科学之旅

原文:https://towardsdatascience.com/start-your-data-science-journey-in-4-steps-f5b5a6e7e80b?source=collection_archive---------38-----------------------

布拉登·科拉姆在 Unsplash 拍摄的照片

开始数据科学职业生涯的自以为是的路径指南

直到 2018 年 9 月,“人工智能”这个词对我来说毫无意义。我在为皇家邮政寄信,并一如既往地好奇想学习一项不需要我付出体力的技能。编程的想法确实出现在脑海中,但我不认为我足够聪明——毕竟我是一名运动员,高中毕业后没有受过正规教育(除非你想把我的 3 级教练徽章和 BTEC 列入体育项目)。

不到两年,我获得了我认为是我人生旅程中的一个重大成就:我现在是一名顶尖的人工智能作家。

在最初充满喜悦之后,我的思维发生了转变,在我意识到之前,我开始反思我从哪里来…

我所采取的每一项重大行动都是对困难局面的回应,但并不一定非要如此!

我收起了对编程的恐惧,事实上我已经 5 年多没有做过一点数学了,这已经不再让我担心,然而,这只是因为我失去了邮递员的工作——我没有其他选择。我在 2019 年 12 月开始了我的中道之旅,但只是因为新冠肺炎疫情让我休假,我才开始定期发帖——我需要用我的时间做一些有成效的事情,否则我只会在家里无聊,直到我被要求回到工作岗位(如果我被要求回来的话)。

意识到我被动的生活方式是不必要的费力,我决定积极主动,希望在数据科学领域有所作为。

你不需要像我一样!如果你现在正在读这篇文章,那么你今天就有机会决定变得积极主动!在这一点上,我的目标是为你提供帮助我达到现在位置的工具,以便你可以启动你的职业生涯。

不要等待机会,要创造机会!Kurtis Pykes

数据科学家的成就

我们经常看到成为数据科学家的先决条件,它们是多么令人生畏;精通统计学、线性代数、微积分、编程、机器学习等(名单不停)。

都是垃圾!

我是在说这些技能是不必要的吗?见鬼不!你需要具备编程知识,以及使用你选择的编程语言处理数据的能力,但是仅仅对数学有基本的了解就足以开始你的旅程。****

注意:记住这篇文章是关于你职业生涯的开始

使用来自 Dataquest 的摘录,我们来定义数据科学:

提出有趣的问题,然后用数据回答这些问题的过程。一般来说,数据科学的工作流程看起来是这样的:

  • 问一个问题
  • 收集可能有助于你回答那个问题的数据
  • 清理数据
  • 探索、分析和可视化数据
  • 建立并评估一个机器学习模型
  • 传达结果

(来源: Dataquest )。

在开始之前,很容易陷入试图学习一切的困境,我会根据经验告诉你,这将是一场你无法赢得的艰苦战斗——我还没有找到人来证明我在这一点上是错的,如果是你,请留下回应。要发展成为一名数据科学家,你需要更多的数学流利度和其他专业技能,但在旅程开始时,你应该专注于培养必要的技能,让你能够迈出第一步。

1)学习一门编程语言

本世纪的辩论之一,Python 与 r。当我开始学习编程时,我选择了 Python,这只是因为这是我在 2018 年第一次开始学习编程时唯一听说过的语言。

如果让我选择今天先学习哪一个更好,我会选择更容易掌握的一个,因为它们都是非常好的选择,都有许多支持数据科学工作流的包。换句话说,把你自己暴露给这两者,然后决定你觉得哪一个更容易。

你不需要成为 Dan Bader (Python 编程专家)。你的重点应该是理解数据类型、数据结构、语法、函数、条件语句、比较、理解、循环和模块。其余的你可以随着时间的推移学习。

(来源: LinkedIn )

资源

注意:我向 R 用户道歉,因为我只能引用我个人使用过并发现有用的东西。

****学习 Python 3 | code academy——https://www.codecademy.com/learn/learn-python-3

****Python 的搭便车指南**——【https://docs.python-guide.org/ **

用于数据分析的 Pythonhttps://www . Amazon . co . uk/Python-Data-Analysis-Wes-Mckinney/DP/1491957662(这不是附属链接)

****Python 数据科学手册——https://jakevdp.github.io/PythonDataScienceHandbook/

2)学习基础数学

你需要的数学技能的程度完全取决于你想要的角色——如果你刚刚开始,很可能你会去找一个初级/实习生的角色。在此基础上,你需要的数学肯定比你想象的要少。当我开始学习数学时,我觉得它很有趣,并决定学习整个 A-Level 课程大纲,但我可以向你保证,你不需要这样做,而且非常耗时。****

考虑到你对数学有很好的直觉,并且知道如何编码,那么你很好。你知道的足够多,可以获得一个初级数据科学家或实习生的职位-一旦获得这个职位,就要靠你去更深入地研究数学并建立你的数学技能,这将使你的职业生涯进一步发展。

重要的是,你要设定一个停止专注于数学的时间——大约 2-3 个月,取决于你掌握事物的速度。请记住,这是一个人们花了一生的时间来学习,但仍然无法完全攻克的课题。

"如果你不知道什么时候该停下来,你可能会永远停下来. "Kurtis Pykes

资源

****可汗学院|统计——https://www.khanacademy.org/math/statistics-probability

****可汗学院|微分学——https://www.khanacademy.org/math/differential-calculus

****可汗学院|线性代数——https://www.khanacademy.org/math/linear-algebra

****考试答案——https://www.examsolutions.net/a-level-maths/edexcel/

3)学习机器学习

Unsplash 上由 Franck V. 拍摄的照片

如果我们遵循我按时间顺序列出的路径,那么你已经建立了我们的编程技能(我们也会使用重要的数据科学框架,如 SciPy、NumPy、Matplotlib 和 Pandas ),并且已经实践过了(即使用我们学习和/或教授的技能)。此外,你已经在必要的数学方面打下了良好的基础,所以剩下的就是学习机器学习了。

许多人直接进入深度学习,我个人认为这不是最好的事情,因为深度学习的许多基本概念都源于机器学习。也就是说,你可能想学习一些机器学习算法,下面是我要说的 5 个开始:

****注:维基百科和交叉验证的栈交换是上述算法的一个很好的起点。

资源

****使用 Scikit-Learn 和 Tensorflow 进行机器实践学习——https://amzn.to/2ZESDEp

****用 Python 进行机器学习简介——https://amzn.to/32oj6I5

****机器学习(吴恩达)| Coursera——https://www.coursera.org/learn/machine-learning

****深度学习专业化(作者吴恩达)| Coursera——https://www.coursera.org/learn/machine-learning

****注意:机器学习课程在 Matlab 中,你可能想用你选择的语言来重现它,因为这也将是发展你的编程技能和直觉的好练习。

4)不要停止学习

永远不要停止学习!下面的链接非常符合这一点,所以我推荐阅读它们。

** [## 数据科学家如何更快地学习

学会学习的有效策略

towardsdatascience.com](/how-to-learn-faster-for-data-scientist-cfd96d317ce6) [## 学习数据科学的 3 个阶段

了解学习的 3 个阶段,以及我们如何将其有效地应用于数据科学学习

towardsdatascience.com](/3-stages-of-learning-data-science-9a04e96ba415) [## 最重要的数据科学项目

每个数据科学家都必须做的项目

towardsdatascience.com](/the-most-important-data-science-project-458d016ef8a6) [## 如何获得你真正想要的数据科学职位

当承担与人工智能相关的角色时,必须做的事情没有被充分提及

towardsdatascience.com](/how-to-secure-a-data-science-role-you-actually-want-169afc52019b) [## 为您的数据科学事业保持动力

我们可以长期保持动力。

towardsdatascience.com](/staying-motivated-for-your-data-science-career-e845f18421e1)

非常感谢你读到这个故事的结尾。如果您认为我遗漏了什么,或者您想向我指出什么,或者如果您仍然不确定什么,您的反馈是有价值的。发个回应!然而,如果你想和我联系,我在 LinkedIn 上是最活跃的,我也很乐意和你联系。

[## Kurtis Pykes -人工智能作家-走向数据科学| LinkedIn

在世界上最大的职业社区 LinkedIn 上查看 Kurtis Pykes 的个人资料。Kurtis 有一个工作列在他们的…

www.linkedin.com](https://www.linkedin.com/in/kurtispykes/)**

启动人员分析功能:3 个构件

原文:https://towardsdatascience.com/starting-a-people-analytics-function-3-building-blocks-4293ddc160f8?source=collection_archive---------40-----------------------

构建可扩展的人员分析功能的坚实基础。你必须从某个地方开始,你也可以从这里开始。

Alex Kotliarskyi 在 Unsplash 上的照片

人员分析(也称为人力资源分析、人才分析和劳动力分析)本质上是利用员工相关数据来推动业务决策。

这很流行。

数据无处不在,每一秒,每一毫秒,我们都在收集更多的数据。商业领袖已经认识到,利用他们的数据做出商业决策可能会对他们的底线产生巨大的影响。

什么类型的广告活动能产生最多的销售额?什么样的产品利润率最高?我们的目标人群在哪里购物最多?

收集数据,分析数据,然后根据这些见解做出决策已经成为一种期望。随着企业领导人越来越精通数据,迫切需要将这些原则应用到与员工相关的决策中。接下来是人员分析。

如果你想看 超级酷的例子 ,谷歌的 People Analytics 团队已经公开了他们的一些最有影响力的项目。

好吧,你被收买了。您确信 People Analytics 将改变世界,使您的业务效率提高一百万倍,并使您的员工成为这个星球上最积极参与的员工。你希望你的组织从这个新领域中获益。欢迎来到酷小子桌。

但是你从哪里开始呢?

照片由 rawpixel爆发时拍摄

首次开始时,请记住以下三点,这将有助于为您的人员分析功能打下坚实的基础,并迅速获得关注:

  1. 使其准确
  2. 使其可行
  3. 使其可访问

1.使它准确

在理想的情况下,所有的数据都将存储在一个集中管理的数据库中。众所周知,我们生活的世界远非理想,我们的数据通常存在于各种地方,来自各种来源,并以各种格式存在。哦,快乐。

这会让我们的工作变得复杂吗?是的。这是否让我们的工作有时令人沮丧?还有,是的。但是有几件事你可以在早期就确定下来,这会让你在将来省去很多麻烦:

  • 建立数据所有权
  • 只有一个真实的来源
  • 尽早建立信誉

建立数据所有权(或者“管理”,如果你想更花哨的话)。

有许多方法来建立数据所有权以满足您组织的独特需求。但首先,你需要确定:负责什么数据的在哪里你如何保持它安全并确保它准确

哈,就这些?!

同样,这可能看起来势不可挡,但坚持与我无畏的战士。让我们试一个例子。假设薪酬数据由财务部处理,并记录在我们的人力资源信息系统 (HRIS)中。

我们会说,财务部门的 Gracie Lou Freebush 每个月都会在我们的 HRIS 系统中运行一份报告,并将其与招聘部门签署的录取通知书进行核对。她会加密文件并保存到我们的内部服务器上。

就这样,我们建立了数据所有权!

  • Gracie Lou 负责薪酬数据的(或“管家”)。
  • 这些数据存放在我们的 HRIS 系统和我们的内部服务器上。
  • 我们通过对照录取通知书检查数据来确保 的准确性
  • 数据通过加密保持 安全

很简单,柠檬榨汁机。

有单一的真理来源。或者,有一个“资源优势等级”(我只是瞎编的但是跟我在一起)。

如果数据有出入,以什么来源为准?

让我们回到金融界的格雷西·卢。她运行了本月的报告,并根据招聘部门的聘用信检查员工的薪酬数据。

突然,她意识到维克多梅尔林有两个冲突的价值补偿!HRIS 系统的报告显示他的薪酬为 180,000 美元,而他签署的聘用信显示他的薪酬为 18,000 美元。

如果我们已经确定我们的 HRIS 在“资源优势等级”的顶端(因为 HRIS 由招聘经理、运营团队、薪资团队和法律团队审查),我们可能会得出结论,在录用函中有一个数据输入错误,也就是一个打字错误。

在这种情况下,我们的 HRIS 通过了大多数团队的大多数批准,因此我们将它放在我们的源优势层次结构的顶部,而录取通知书到目前为止只由一个人审核。(这个例子是为了说明起见,拜托,看在上帝的份上,对 offer letters 有多个审核步骤)。

随着人员分析的成熟,您使用越来越多的数据源(财务数据、人口统计数据、调查数据等)。等等。等等。)这变得越来越重要。

林赛·亨伍德Unsplash 上拍摄

及早建立信誉。

当你刚开始工作时,花 80%的时间检查你的工作质量。80%.最低限度。我没开玩笑。

如果人们不信任你的数据,他们就不会信任你。

错误时有发生。同样,我们处理的数据极其复杂,在我们的分析中,微小的错误很容易泛滥成灾。你可以在 99%的时间里准确无误,但当出现错误时,人们只会注意到那 1%。

当我寄出一份包含 200 种不同计算方法的 10 页季度报告时,我从未收到过一封电子邮件说“哇,所有这些计算都绝对正确,你做得真好!”然而,我收到了(许多)类似这样的电子邮件,“第 6 页第 34 行的数字实际上应该是 7.2,而不是 7.4。”

每次收到这样的邮件,我都会少活几年。通常,报告显示的是 7.2 而不是 7.4 是有充分理由的。但是,可怕的事实是,有时给我发邮件的人是对的,但确实有错误。这是一种可怕的感觉。振作起来,查理。找一个能帮助你正确看待错误的人谈谈(我可以提供同情和虚拟拥抱),把注意力放在你学到的东西上,并在未来改变它。

当出现错误时,解释是什么导致了错误的发生,以及你采取了什么权宜之计来防止它再次发生。

以下是一些尽可能减少错误发生的方法:

  • 将数据与您之前计算的数据进行比较。今年的营业额和去年的营业额有明显的不同吗?区别有意义吗?
  • 让多人进行计算。这可能是资源密集型的,但也可能是非常有益的,尤其是在开始的时候。通过对一名新分析师这样做,我们意识到他们是用第一个月和最后一个月的平均人数来计算营业额的,而我用的是每个月的平均人数。从技术上来说,两者都可以被认为是“正确的”,但我们需要保持一致。
  • 用手算。别因为这个恨我。这是我最不喜欢做的事。我喜欢自动化,尽我所能让我的过程更有效率。为了做到这一点,我经常有模板或脚本为我进行计算。但是,我总是会选择几个部门,在那里我也会手工进行计算,以确保自动化流程按预期工作。对于那些重视效率的人来说,这可能是痛苦的,但确保准确性是如此重要。
  • 过滤检查。在查看高级结果时,发现错误可能会更加困难。在进行数据检查时,尝试查看小组的结果(例如,按部门、地点等)。)并确保他们的结果是准确的。对于小团队来说,错误更容易被发现。
  • 创建你自己的质量保证清单(这里的例子是)。

照片由斯科特·格雷厄姆Unsplash 上拍摄

2.让它变得可行。

在 People Analytics 中,你可以做很多令人惊讶、精彩、超酷的事情,以至于你不知道从哪里开始。从最基本的开始,给人们他们需要的东西。让你的工作具有可操作性:

  • 使项目与公司目标一致
  • 有冠军
  • 提出切实的建议

项目计划的一个好方法是从现有的业务优先级和目标开始。为了让你的努力产生最大的影响,人们需要关心它,人们需要能够为此做些什么。

一个拥护者或执行发起人,是将目标放在人们关注的最前沿,让人们负起责任,并促进正在完成的工作的人。理想情况下,此人在您的组织中非常显眼,并在游戏中有一些“皮肤”(即,他们在个人或专业上有动力看到目标的实现)。

尽早让这个人加入你的项目。这应该是一种互利的关系:你帮助赞助商实现目标,赞助商帮助推广你的工作。没有执行发起人,项目会很快消亡,没有人使用、阅读或关心你的工作。悲哀。日。一个冠军可以创造一个不同的世界。**

照片由马太·亨利爆出

最后,你需要根据你项目的结果提出切实可行的建议

当我第一次开始时,我会展示我的发现,然后期望人们前进和成功。我以为我的工作是运行分析,而他们的工作是运行分析。我会把我的发现发出去,期望世界会改变。但是,令我懊恼的是,什么都没发生。

有一个关键的差距——我正在分享我的发现,但人们仍然不知道如何与他们一起做。好吧,我们发现教育水平并不是给定职位绩效的重要指标,那又怎样?

我们需要帮助我们的观众理解,不仅仅是我们的发现,还有我们的发现意味着什么,以及他们能为此做些什么。

如果我们发现教育水平不是绩效的重要指标,这可能意味着我们应该改变该职位的选拔流程。通过扩大我们的选择标准,我们可以增加 X%的候选人数量。这也意味着我们可以通过雇佣一个教育程度较低的人来节省 Y 美元,这个人可能会有较低的报酬,但在工作上同样有效。

现在他们正在拾起你放下的东西。他们买你卖的东西。闻你煮的东西…你懂了。

3.让它变得容易理解(理想情况下,也让它变得漂亮)。

在你恐慌之前,你不必出去学一个数据可视化软件(至少现在还没有……)。这可能很简单。它可以在 Excel 中(每个人和他们的妈妈使用它是有原因的,在那个游戏中没有羞耻)。

只要让它可视化,最好是互动的。在消化视觉信息方面,人类拥有超能力。我们做得非常迅速和有效。利用我们的天赋吧!

分享您的数据时,请做到:

  • 视觉的
  • 交互式(例如使用过滤器)
  • 易于访问(例如实时数据访问)

让我们尝试以下两种体验,并思考我们的观众更喜欢哪一种:

选项 1:

Excel 中的计算表。

这里有很多信息,这可能是一件好事。如果您的受众是一直沉浸在这些数据中的人,他们可能需要这种程度的细节。但也很难从这些数据中得出有意义的结论。这里有很多,但是我在找什么呢?营业额多少才算“差”?

选项 2:

在 Excel 中使用部门切片器组合条形图/折线图。

选项 2 是一个更直观的选项。

这非常简单,但与我们之前的情况相比,这已经是一个巨大的进步。现在,我们可以过滤到我们感兴趣的部门,我们的条形图会根据它们是高于还是低于该部门的平均月营业额来改变颜色。

我们可以立即看到,在 1 月和 4 月,营销团队的营业额比平时高。四月的营业额看起来并没有比平时高多少,但是一月的营业额确实比平时高,而且可能值得进一步调查。

例如,我们可能会发现这些人中的大多数在奖金发放后马上就离开了。为了留住我们的员工,推迟发放奖金的时间可能是值得的。

现在事情真的越来越令人兴奋了。

交互性

*领导者往往只关心与他们“相关”的数据。如果你给一个领导发全公司营业额,他们会说好吧,没问题,但是我的部门的营业额是多少?

分享数据时,重要的是让您的结果具有足够的互动性,这样领导者会觉得他们可以缩小他们认为足够具体的群体的范围

每个领导都是自己特别的雪花。有些人喜欢按部门或成本中心过滤,有些人喜欢按位置过滤,有些人甚至喜欢按不同的职位过滤。

然而,我们的工作是拯救领导者,而不是让我们的结果变得如此互动,以至于不再有意义。

首先,牢记保密性之类的事情非常重要(例如,不要显示少于 20 人的小组的结果)。当尺寸变得太小时,结果也就失去了意义。100%的离职率确实令人担忧,但如果该部门/地点/职位只有一个人,就不会如此。

帮助领导了解为什么要限制结果中的互动量,然后坚定自己的决定。

随手可得。

你可以完成有史以来最酷、最具突破性的分析。但是如果没有人看到它——如果没有人可以访问它——它就不算数。人们不能使用他们没有的东西。

让数据易于访问是数据民主化的理念。这并不意味着每个员工都应该拥有进入你的分析的所有原始数据的完全访问权。

这意味着以适当的访问级别将信息送到需要它的人手中。

大多数情况下,当更多的人有更多的机会访问数据时,好事就会发生。显然,始终要考虑隐私问题、道德问题和提供数据访问权限的潜在后果(我在和你说话,扎克伯格)。

建立人员分析功能时,决定如何分享结果至关重要。重要的考虑因素是:

  • ****内容(如仪表盘、报表等。)
  • ****格式(如 Excel、BI 工具、HRIS 系统等。)
  • ****节奏(如每月、每季度等。)

不管你做了什么决定,一个领导者都应该确切地知道如何、在哪里以及何时可以获得他们的结果。当然,这些决策可以是反复的。开始时,您可能会每月用 Excel 发送报告,然后,随着人员分析功能的成熟,您可能会让领导实时访问 Power BI 中的仪表板。

无论你做什么,让你的数据容易消化。见鬼,让它成为一种乐趣。它会让人们回来买更多。

来自爆发Sarah Pflug 的照片

总之,在构建人员分析功能时,首先要做到以下几点:

  1. 使其准确
    -** 建立数据所有权
    --拥有单一的真实来源
    --尽早建立可信度**
  2. 使之可行
    -** 使项目与公司目标一致
    --有一个拥护者
    --提出切实的建议**
  3. 使可访问
    -** 使用视觉效果
    --使其可交互
    --使其易于访问**

继续用你的头撞墙。变得更好了!

从零开始数据科学和分析||大学生的经历

原文:https://towardsdatascience.com/starting-data-science-and-analytics-from-scratch-the-experience-of-an-undergrad-5c6bcb83ad7b?source=collection_archive---------39-----------------------

数据科学、分析是我们都听过的时髦词汇。那么它们是什么呢?一个人如何在这个领域起步?好了,这就是我今天用这篇文章来回答的,希望你会觉得有帮助!

一个人带着对未来和职业的希望和雄心开始他们的大学生活。但是,我们从第一天开始就知道我们对什么有热情吗?我没有。我总是随波逐流,尝试新事物。但是随波逐流并不总是最好的决定,如果你能找到一些指导,这真的很有帮助。

克里斯里德在 Unsplash 上的照片

所以根据维基百科的说法,数据科学是一个统一统计学、数据分析、机器学习以及它们的相关方法的概念,以便用数据来理解和分析实际现象。我们知道,这不是一个最近才出现的新领域,也不是一个独立的实体,而是先前存在的领域的融合。

你需要做的第一件事是在统计学和概率学上建立一个坚实的基础。你必须在描述统计学、概率分布、假设检验、回归、条件概率、贝叶斯定理和可视化方法方面打下坚实的基础。

在这方面,我遇到的最好的书之一是谢尔登·m·罗斯的《工程师和科学家的概率和统计》。你也可以看看印度作家写的类似的书。语言要简单得多,它被 H.C. Taneja 称为“工程和科学的统计方法”。

现在你对数学概念有了很好的理解,让我们来看看语言和工具。

了解 Python 或 R 并不是唯一重要的事情。有各种各样的工具有它们自己不同的应用,像 MySQL,MS Excel,PowerBI,Tableau 等等。

申请分析或数据科学工作时,拥有多样化的技能很重要。

鉴于 Python 和 R 是数据科学中最流行的两种语言,您不需要同时了解这两种语言。如果需要的话,在一个领域拥有专长可以帮助你过渡到另一个领域。我使用 Python,唯一的原因是我是从这个开始的,现在我已经适应了这个环境。所以,下载环境,我用的是 Jupyter 笔记本。开始探索它,做一个基础课程或者查看 YouTube 上关于基础的惊人资源,以便掌握语言、语法和环境。

你不需要去上专门的课程,随着学习的深入,你会学到更多关于这门语言的知识。

一旦你掌握了这门语言,我们就进入实现部分。要开始数据科学,你需要数据。你从哪里得到数据?

我的 go to source 是 Kaggle ,它有针对不同专业水平的各种数据,这些数据可以根据你想要应用的概念进行搜索。

谷歌有自己的数据集搜索引擎,datasetsearch.research.google.com,当你的搜索是数据集特定的而不是技能特定的时候,这就更有用了。

获取数据并不局限于这些来源。你也可以从你自己的来源挖掘数据,你可以从在线平台下载,比如 Twitter,Reddit 等。

一旦你有了数据,你不只是开始建立模型和做出预测。第一步是清理数据。真实世界的数据是肮脏的。您需要将数据转换成您可以使用的形式。

有各种各样的事情需要做。有许多缺失值,您必须看看是否要删除这些行,或者对这些值进行假设-您会假设它是其余值的平均值还是中值等等。您可能需要添加、删除或拆分某些列。有些字符串可以转换成 float 或 int。这些任务取决于数据是什么、数据的用途以及数据有多脏。

接下来,我们做最有趣和最有见地的部分,我们探索数据。显而易见的第一步是计算一些汇总统计数据。你想知道你有多少个数据点,最小值和最大值,平均值,标准偏差。因此你首先会发现描述性统计。

然后我们开始可视化数据。有各种各样的图表可供选择——条形图、直方图、箱线图、散点图等。你可以画出单个的属性来理解分布,或者你可以画出每个变量与可依赖变量的关系来理解相关性。

对于多个属性,您可能希望找到各种属性之间的相互关系。一种简单的方法是使用相关矩阵。

这整个过程被称为“数据探索和可视化”。这是一个庞大的过程,绝不仅限于这些任务。这是重要的一步,因为不知道数据,你就不知道要建立什么样的模型。我可以就这个话题写一整篇文章。

接下来,我们了解我们想要对数据做什么。我们对自己在寻找什么有明确的想法吗?我们有这方面的训练数据吗?

如果是,我们可以对数据应用监督学习技术,如回归、分类等。

否则,我们使用无监督技术让数据自己说话。

这些技术中的每一种都要求你很好地理解它们背后的数学概念。一旦完成这一步,你需要学习各种机器学习算法。例如,在单独回归的情况下,单独的线性回归不适合所有类型的数据,因此我们有多项式回归、随机森林回归等。

但是仅仅知道算法是不够的,你需要知道如何将它们用于数据,也就是如何将它们融入你的代码中。所有这些算法都可以在 Python 库中找到。有些时候你可以直接使用算法,有些时候你需要调整它。

所以第一步:作为初学者,学习有广泛应用的基本算法。这些包括但不限于线性回归、逻辑回归、朴素贝叶斯、k-最近邻、k-均值、主成分分析。

为了了解它们是什么,它们是如何工作的,我看了每一个的 youtube 视频。这只会让你对工作有所了解。

第二步:将它应用到您的数据中。除非你使用算法,否则你不会有效地学习。数据科学不是关于概念的理论知识。

数据科学需要哪些机器学习算法?这些算法是如何分类的?各种技术的不同算法是什么?这些是另一篇文章的问题。

在我结束这篇文章之前,我想根据我的经验给出一些重要的提示:

  1. 多花点时间在编码部分,而不是学习部分。它们是平行的过程——同时学习和应用。不要等到理论概念讲完。
  2. 承担多个小项目,而不是一个大项目。小项目会花费更少的时间,给你成就感,你会学到更多的东西。
  3. Kaggle 不仅保存数据,还保存其他用户的各种笔记本。最初,您可以使用它来理解要采取的方法,但不要复制代码。
  4. 如果你被困住了,不要失去希望,你不知道的,网上有人知道。搜索你的问题,你会惊讶地发现有多少人遇到过类似的情况。

如果你还想知道更多,或者你对这篇文章或即将发表的文章有一些建议,你可以通过 LinkedIn 与我联系。

在新冠肺炎期间开始数据科学

原文:https://towardsdatascience.com/starting-data-science-during-covid-19-199931a6f902?source=collection_archive---------67-----------------------

我学到了什么

马库斯·斯皮斯克在 Unsplash 上的照片

自学一项新技能并不容易。

为了事业自学一套新的技能,绝对不容易。

自学是一种承诺,需要专注和奉献,最重要的是,时间

如果你正在阅读这篇文章,我会假设你很有可能在某个时候听说过数据科学家被归类为 21 世纪最性感的工作。你在谷歌上搜索,看到各种来源的报告称,目前数据科学家短缺,需求将继续快速增长。在你的研究过程中,你发现了吸引每个人注意力的主要东西,他们的薪水。在浏览互联网寻找成为数据科学家所需的一些先决条件时,您开始注意到一些趋势,例如:

  • Python 中的知识
  • 结构化查询语言
  • 统计数字
  • 线性代数
  • 离散数学
  • 结石
  • 机器学习
  • 拥有硕士或博士学位

这个清单还在继续。

突然之间,“21 世纪最性感的工作”听起来像是要花一个世纪的时间才能获得这项工作的技能。

还是会?

时间是我们生命中最重要的东西。回到我上面提到的列表,许多人开始远离学习数据科学,因为他们没有时间去学习一切。

这是百分之百可以理解的。大多数对学习数据科学感兴趣的人无法仅仅离开生活几个月到一年来学习所有这些复杂的主题。我也是有同样问题的人之一,但是后来新冠肺炎来了。

我的故事

新冠肺炎迫使我们许多人(包括我自己)呆在家里,让许多人失业。起初,我对自己说“我应该利用这段自我隔离的时间,最终学会数据科学”。

说起来容易做起来难。

自学一项新技能并不容易。

学习一项新技能,尤其是在当前的世界形势下,由于新冠肺炎和乔治·弗洛伊德被恐怖杀害后在世界范围内点燃的大规模抗议活动。这是一个很难集中注意力和学习的时期,尤其是对我来说,作为一名年轻的非裔美国男性,我目睹了社交媒体上爆发的一切。

然而,在无数次尝试学习数据科学之后,我现在终于看到了进步,为我自己在这个领域的成功铺平了道路。

在过去的两年里,我断断续续地试图学习这门学科。我尝试过各种 MOOC,比如 DataCamp、Coursera、Codecademy、Udacity 等等。

虽然我在学习时理解了这些网站上教授的主题,但我从未能够记住这些信息。我一点也不想诋毁这些网站。它们是非常好的学习资源,许多人利用它们获得了成功。我不是他们中的一员,而需要一种不同的方式。我会学到一些东西,然后第二天就忘了怎么做。这是一个重复的循环,我完成了模块,但没有感觉到我学到了什么。

四月初的某一天,我在 YouTube 上遇到了一位名叫 Ken Jee 的数据科学内容创作者。我看了他的第一个视频,我记得他说过学习数据科学的最佳方式是做项目。

就在那一刻,我的脑海里突然灵光一现。

我在他的 YouTube 频道上浏览了他的一个播放列表,在那里他讲述了如何从项目规划阶段到部署模型来处理一个数据科学项目。我彻底地看完了他的教程系列,并把它作为我自己的项目重新创建。我不仅学到了东西,而且我正在实施它们并将这些概念应用到一个真实的项目中。通过这样做,我开始一点一点地保留我所做的事情。

突然间,事情开始变得有意义了。

在开发我的第一个项目时,我偶然发现了另一个数据科学内容创作者,名叫 Chanin Nantasenamat ,他在自己的 YouTube 频道上化名为 Data Professor。他创建了一个关于如何用 Hugo 和 GitHub 页面制作数据科学作品集网站的教程,我照着做了。这是一个巨大的信心助推器,因为我现在有一个可视化平台来展示我的项目,因为我完成了它们。我会把成品 链接到这里 给那些对它的样子很好奇的人。我最喜欢 Chanin 在他的视频结尾经常说的一句话是“学习数据科学的最好方法是做数据科学”。

未来计划

我现在正在进行我的第二个项目,规划我的第三个项目,并开始在毕马威(KPMG)进行虚拟数据分析实习。我之所以想写这篇文章,是因为我想分享我是如何开始走向成功的故事,因为我现在正在做来激励你。世界正在快速变化,与其在以后讲述我是如何做到的,我想现在就写下来,现在作为我正在努力实现我的目标,并告诉你如果你还没有开始你的数据科学之旅,现在还为时不晚。

我将继续记录我的故事和前进的进程。请随时关注我,并留下来了解我和我的旅程。

使用 Julia 语言和 Jupyter 笔记本开始数据可视化

原文:https://towardsdatascience.com/starting-data-visualization-with-the-julia-langauge-and-jupyter-notebooks-289bc9f0cd09?source=collection_archive---------21-----------------------

使用 Julia 和 Jupyter,您几乎不需要任何编程知识就可以制作出令人印象深刻的数据可视化。

不久前,我写了一篇关于使用 Julia 和在线 Jupyter 笔记本环境 JuliaBox 进行数据可视化的文章。当时 JuliaBox 是一项免费服务;不幸的是,情况不再是这样了——它不贵,但也不是免费的。

这是那篇文章的一个新版本,你可以使用你自己的 Jupyter 笔记本环境(这个环境是免费的)。你需要安装 Jupyter 笔记本,Julia 语言,然后配置它们以便 Jupyter 了解 Julia。

如果这听起来很复杂,别担心,一点也不复杂。

Jupyter 笔记本

你首先需要的是一个 Jupyter 笔记本。如果你已经安装了,那就太好了。如果没有,你应该遵循这篇文章:

## 使用 Anaconda 为数据可视化设置 Jupyter 笔记本

(这篇文章关注的是 Python,但是因为 Jupyter 要求安装 Python,所以这里没有什么不相关的。)

朱莉娅

Julia 是一种相对较新的数据分析语言。它有一个高级语法,旨在易于使用和理解。有人称之为新 Python。

然而,与 Python 不同的是,它是一种编译语言,这意味着尽管它像 Python 一样容易编写,但它运行得更快,因为它被转换为更容易被计算机理解的低级代码。如果您必须处理需要大量处理的大型数据集,这非常有用。

与 Python 相比,Julia 对程序的布局也没有那么挑剔。

Julia 拥有现代编程语言的所有特性,但是在这里,我们将看看 Julia 的数据可视化能力。这些既令人印象深刻又易于使用。

一旦你安装了 Julia 和 Jupyter,你就可以创建运行 Julia 代码的 Jupyter 笔记本,执行它们并导出为 HTML。您可以将可视化保存为标准的 png 文件,并将其保存到您的文档中。

如果您想完成本文中的示例,可以下载数据文件和 Jupyter 笔记本,用于您自己的设置。我会把链接放在文章的最后。

安装 Julia

要安装 Julia,你需要去 https://julialang.org/的下载适合你操作系统的版本。安装很简单,只需按照说明操作。

一旦你安装了它,你需要做几件事情。因此,启动 Julia,您将在如下窗口中看到命令提示符:

第一件事是允许朱庇特和朱莉娅互相交谈。在提示符下键入此内容,然后按:

using Pkg

这告诉 Julia 您将使用包管理器。然后键入以下内容并点击:

Pkg.add("IJulia")

IJulia 是将 Jupyter 和 Julia 联系起来的包裹。您可能需要等待它下载和安装。

一旦你安装了 IJulia,你就可以用 Jupyter 打开一个新的笔记本,用 Julia 代替 Python。

现在你需要添加几个我们将在教程中用到的包。键入以下几行:

Pkg.add("Plots")

Pkg.add("CSV")

Pkg.add("DataFrames")

稍后您将会用到这些软件包。

现在,您可以通过执行以下命令来关闭 Julia:

exit()

或者简单地关上窗户。

现在你可以开始了!所以,使用 Julia 作为内核,启动一个 Jupyter 笔记本,开始行动吧。

朱莉娅·图斯

与大多数其他语言一样,Julia 依赖于特定专业用途的代码库。我们最初感兴趣的一个叫做。这为我们提供了创建数据可视化的能力。

所以我们需要执行的第一段代码是这样的:

using Plots

当你在笔记本的代码单元中输入这个代码并按下 ctrl/enter 执行它时,它会告诉 Julia 加载我们将用来创建可视化的库。

当您第一次执行笔记本中的单元格时,可能需要一点时间来执行。这是因为 Julia 代码是在第一次执行时动态编译的。后续的代码运行要快得多。

[## 用熊猫绘图:数据可视化导论

可视化数据使您有机会深入了解数据元素之间的关系,从而…

projectcodeed.blogspot.com](https://projectcodeed.blogspot.com/2020/02/plotting-with-pandas-introduction-to.html)

你的第一次想象

我通常将不同的代码放入笔记本的新单元中。这意味着我只需要运行我需要的代码,而不是整个笔记本。我建议你也这样做,所以在一个新的单元格中我键入了下面的代码:

x = 1:10; y = rand(10); # These are the plotting data 
plot(x,y, label="my label")

运行它产生了下图:

第一次朱莉娅可视化

令人印象深刻。让我解释一下这是怎么回事。

x = 1:10;y =兰特(10);#这些是绘图数据

这位代码创建两位数据,一位称为
x ,另一位称为 yx 被赋予从 1 到 10 的数字范围的值,而 y 被赋予 10 个伪随机数的范围(每个伪随机数将具有 0 到 1 之间的值)。因此,我们在这里有一个图形的基础:一个范围从 1 到 10 的 x 轴和 x 轴上每个点的 y 值。

下一步很简单。

plot(x,y,label= "我的标签")

这段代码调用一个函数来绘制图表,我们所做的就是给它 x 和 y 值——另外,我们还给它一个标签。

这很简单,但是,当然,我们真的想可视化一些真实的数据。

我有几个表,我在其他文章中用过。这是一组关于过去几十年英国伦敦天气的数据。我是从英国气象局提供的公共表格中推导出来的。

数据记录了每个月记录的最高温度、最低温度、降雨量和日照时数。我有两个文件,一个是完整的数据集,一个是 2018 年的,只有。它们是 CSV 格式的,就像您可以导入到电子表格中一样。

为了处理这些文件,我们需要另一个允许我们读取 CSV 文件的库。

我们可以看到在下一段代码中引用的库,即using CSV,下面一行实际上是将数据读入变量d,这是一个 DataFrame。

using CSV
d = CSV.read("london2018.csv", DataFrame)

运行代码的结果是,我们现在有了一个如下所示的数据表:

来自有意义数据的图表

我们下载的数据是一个表格,有 6 栏:YearMonthTmax (最高温度)、Tmin (最低温度)、Rain (降雨量毫米数)和Sun (日照时数)。

这是数据的子集(仅针对 2018 年),因此Year 列在所有行中具有相同的值。

条形图

所以,我们有的是 2018 年每个月的数据。如果我们想在柱状图中绘制每个月的最高温度,我们可以这样做:

bar(d.Month, d.Tmax)

bar 是一个绘制条形图的函数(还有什么?)并且我们提供了 x 和 y 轴的列。我们通过使用数据表的名称,后跟列的名称来实现这一点。这两个名字用一个点隔开。

这里,我们将列Month 作为 x 轴,将Tmax作为 y 轴,因此我们在表格中绘制了 12 个月中每个月的最高记录温度。

将它放入一个新的代码单元并运行它,您会惊喜地(我希望)看到这个图表:

条形图

折线图

如果你想制作一个折线图,你可以做同样的事情,但是使用函数plot

plot(d.Month, d.Tmax)

折线图

如果您想在同一张图表上绘制最高和最低温度,您可以这样做:

plot(d.Month, [d.Tmax, d.Tmin], label=["Tmax","Tmin"])

请注意,d.Tmaxd.Tmin 这两个值在方括号中组合在一起,并用逗号分隔。这是向量或一维数组的符号。此外,我们还为线条添加了标签,这些标签以相同的方式分组。我们得到了这样一个图表:

散点图

或者散点图怎么样?散点图通常用于查看是否可以在数据中检测到模式。这里我们绘制了最高温度与日照时数的关系图。正如你所料,这是一种模式:一种明显的相关性——日照时间越长,气温越高。

scatter(d.Tmax, d.Sun)

圆形分格统计图表

我们拥有的数据并不适合被描绘成饼图,所以我们将再次生成一些随机数据— 5 个随机数。

x = 1:5; y = rand(5); # These are the plotting data
pie(x,y)

柱状图

现在,我们将加载更多的数据:

d2 = CSV.read("londonweather.csv"`, DataFrame)

这类似于我们一直使用的数据表,但更大,因为它涵盖了几十年的数据,而不仅仅是一年。这给了我们大量的降雨量数据,这样我们就可以看到伦敦在一段较长的时间内的降雨量分布。

histogram(d2.Rain, label="Rainfall")

这是结果。

保存图表

在 Jupyter 环境中看到这些图表当然很好,但是为了有用,我们需要能够保存它们以便在我们的文档中使用它们。

您可以像这样保存图表:

histogram(d2.Rain, label="Rainfall") 
savefig("myhistogram.png")

运行此代码时,不会显示图表,但会以给定的文件名保存。

结论

我希望这是有用的——我们已经查看了 Julia Plots 中可用的基本图表。朱莉娅的故事远比我们在这篇短文中看到的要多,你也可以用情节做更多的事情,但我希望你已经发现这篇介绍已经激起了你探索更多的欲望。

下载

右键单击下面的三个链接下载文件,然后将它们复制到 Jupyter 将使用的目录中。然后在你的文件列表中打开 plotweatherjulia.ipynb

笔记本在这里: plotweatherjulia.ipynb

而数据文件在这里: london2018.csvlondonweather.csv

一如既往,感谢阅读。如果你想知道我什么时候发表新文章,请考虑在这里注册一个电子邮件提醒。

如果你不是一个媒体订阅者,那就注册吧,这样你就可以每月花 5 美元阅读尽可能多的文章。在这里注册我会赚一点佣金。

从深度学习开始

原文:https://towardsdatascience.com/starting-out-in-deep-learning-a83387904538?source=collection_archive---------41-----------------------

我对深度学习教育的动机、经历和未来计划。更新于 2023 年。

图片:大卫·库伯

我在 2023 年反思我在机器学习方面的旅程,我对自从我的第一篇文章以来发生的进步和演变感到惊讶。ChatGPT 和 Dalle-2 正在带来新一轮的创造力和创新,新的人工智能工具正在以令人难以置信的速度发布。

无论背景如何,机器学习和深度学习知识对每个人来说都变得越来越重要。现在,作为一名商业创新和设计思维教练,我相信设计思维和以人为中心的创新和增长方法将导致深度学习解决方案的发展,通过确保以将人类体验放在第一位的方式发展深度学习,推动业务增长和改善人们的生活。让我们努力让所有人都能接受这种教育。

我的第一篇文章介绍了机器学习的基础工作;学习 Python、探索性数据分析、机器学习实践和机器学习理论。我已经达到了很高的知识水平,是时候进入计划的下一阶段了。练习我的机器学习技能,进入深度学习。

这篇更新的文章涵盖了我的动机,深度学习的解释,理论和实践的推荐课程,云平台,人工智能治理和人工智能伦理。

为什么要深度学习?

我一直有强烈的持续学习的愿望,我把深度学习看作是新的挑战和成长的机会。

我认为深度学习是一种可以增强人类能力的工具,可以将理论转化为实践,用以人为本的价值观解决实际问题。

在我的深度学习教育之初,知道从哪里开始是相当令人生畏的。这是一个庞大的主题,很容易陷入困境,并对众多的主题和数学感到沮丧。关键是坚持不懈。

什么是深度学习?

深度学习的定义引发了很多争论。尽管如此,就目前而言,“深度学习是基于人工神经网络的更广泛的机器学习方法家族的一部分”。(维基百科)

近年来深度学习的爆发是由三件事促成的,即大量可用数据、计算能力的提高和算法创新。

深度学习的例子:

  • 自动驾驶汽车,物体检测,决策。
  • 物体分类,视觉搜索,人脸识别。
  • 自然语言处理、垃圾邮件过滤器、Siri、Alexa 或谷歌助手。
  • 大型语言模型。达尔-E 2。
  • 医疗保健。核磁共振扫描,CT 扫描,记录分析。

神经网络是什么样子的?

谷歌开发了这个游乐场,你可以在浏览器中“修补”神经网络。查看操场 TensorFlow 网站。

来源维基百科。

我的深度学习方法

我的深度学习方法有三重,理解足够的理论来解释算法,学习编码,然后实践它们。这种方法让我进入了深度学习专业(理论),Fast。Ai(编码)和 Kaggle(实践)。

Coursera 上的 Deeplearning.ai 专业

吴恩达最初的机器学习课程清晰、结构良好,并且让数学变得可以理解。这让我有信心用吴恩达的最新专业来处理深度学习。

深度学习专业涵盖了神经网络的构建模块、卷积神经网络(例如图像识别、放射学成像)、序列模型(例如语音识别、聊天机器人、语言处理)、关于如何改进您的模型的建议(超参数调整)、构建您的深度学习项目和机器学习策略。

编程练习是用 Python 编写的,有助于阐明讲座的内容。你将建立一个神经网络,图像分类,面部识别,自然语言处理和触发词检测(例如嘿 Siri 或 Alexa)。用数学而不是编程库来构建神经网络提供了某种程度的理解,这是一些更实用的课程所没有涵盖的。虽然这种深度可能不是必需的,但了解幕后发生的事情是有用的。

在 16 周的时间里,这五门课程是分层进行的,但是你可以按照自己的进度来学习。这种专业化教授深度学习最重要和最基本的原则。如果你是一个严格的动手学习者,那么这个课程不适合你。这门课程中理论的融合是对实用的 Fast.ai 课程的补充。

面向编码人员的 Fast.ai 实用深度学习

fast . ai Coders v3 实用深度学习是一门免费的实践课程,旨在教人们用 Python、最先进的深度学习技术编写代码。Fast.ai 旨在通过免费课程、研究和社区让更多来自各种背景的人参与进来,让深度学习更容易使用。引用《斋戒》。Ai 网站。“我希望很多人会意识到,深度学习的最先进成果是他们可以实现的,即使他们不是斯坦福大学深度学习博士。”

Fast.ai 涵盖数据清洗、图像分类、多标签分类;分段 NLP 表格数据;协同过滤;嵌入,规范化,数据伦理和剩余网络。

没有正式的编程练习或测验。尽管如此,我们还是鼓励你根据课堂上学到的知识来设计你的项目。使用最新的艺术技术和内置的 Fast.ai 库,你会学到如何编写你的模型。fast.ai 库建立在开源 PyTorch 库之上。两节课之后,我在 AWS Sagemaker 上写了我的图像分类器。

有一个强大的社区来帮助你应对挑战,并对你的工作提出批评。如果你是一个实践型的学习者,这门课程是为你而设的,即使涉及了反向传播等技术,它们实际上是相对于基础数学而言的。

卡格尔

在深度学习专业化的中途,我休息了一下,并参加了 Kaggle 上的一些机器学习比赛。Kaggle 是一个数据科学社区,拥有强大的工具和资源来帮助您实现数据科学目标。

Kaggle 是测试你技能的好方法。每场比赛都有一个排行榜,个人或团队可以在这里相互竞争。此外,还有一些成功代码的例子,可以帮助您在这个数据科学的熔炉中发展技能。

有四个初学者比赛。数据分类:预测房价。使用手写数字的图像识别和自然语言处理来分析推特上的情绪。来自 Fast.ai 的杰瑞米·霍华德自己也是一名 Kaggle 大师,他建议“如果你很优秀,你应该进入比赛的前 10%”。

我的第一个分数让我进入了前 73%,这是我在长时间学习后的一次觉醒!经过深夜的反复尝试,我达到了我现在满意的分数水平!

  • 机器学习分类介绍。前 5% 749/16523
  • 高级回归技术预测销售价格最高 14% 605/4550
  • 计算机视觉手写数字识别器前 16% 335/2230
  • 预测推特结果的自然语言处理。前 44% 1472/3423

你能从 Kaggle 身上学到什么?

数据准备的重要性不可低估。学习如何清理数据、特征工程、变换、随机化、训练/测试分割对你的输出有巨大的影响。

你如何选择和训练合适的模型?不同的算法用于不同的任务。

评估和调整模型的技巧。关于选择正确指标和超参数调整艺术形式的建议

不要为了那 10%而掉进兔子洞

摘要

Deep learning.ai 和 Fast.ai 将一切解释得如此清楚,以至于你有足够的信心拿起代码和算法并开始使用它们。学习、实践和强化我的知识的最佳方式来自于在 Kaggle 的两门课程和数据科学竞赛之间的交替。

云平台

在某些时候,你的家用电脑将不会快到足以运行深度学习模型。这里有两个选项可以缓解这种情况。

首先,您可以降低模型的复杂性,减少训练数据集或微调参数和超参数。

第二,买个图形处理器。好消息是,您不需要购买 GPU,云中的每个人都可以使用企业级 GPU,但要小心成本!

Google CoLab :这是一个免费的平台,可以访问 Google 的计算、GPU 和 Python 库 Keras、TensorFlow、PyTorch 和 OpenCV。

Kaggle :拥有免费的编码环境,每月获得 30 个小时的 GPU 时间。对于初学者来说,这就足够了,在我看来。

Azure Studio :这消除了数据工程和 Python 编码的复杂性,给业余数据分析师和数据科学家一种更自然的方式来建立模型。Azure 将根据你的容量收费,因此为了降低成本,请确保关闭实例。

AWS sage maker——是一个多合一的人工智能平台。您可以使用 AWS 模型,构建您自己的模型或使用 AWS 托管您的模型。像 Azure 一样,您也可以获得企业级图形处理能力,并且根据处理单元和内存的类型,会有一定的成本。为了降低成本,请确保在完成时关闭实例。我创建了一个简单的 AWS Lambda 作业,以特定的时间间隔关闭我的笔记本。

Kaggle 和 AWS Sagemaker 最适合我的教育工作流程和体验。我在一台笔记本电脑上开发了代码,运行了一个小的训练/测试集,修复了错误,进行了调优,然后上传到两个平台中的任意一个,进行更大的训练/测试集和进一步的调优。

深度学习的设计思维

人工智能有可能极大地改善我们的生活。尽管如此,重要的是要记住,人工智能是人类为人类设计和创造的。设计思维是一种以人为中心的创新和发展方式。它基于对客户需求的理解、创造性想法的产生和快速原型制作。设计思维平衡合意性、可行性和生存能力,以确保深度学习解决方案对客户来说是合意的,在技术上是可行的,并且可以成为可行的、可持续的商业模式。这使得组织可以根据客户的需求而不是历史数据或高风险的赌注来做出决策。

它包括几个步骤,包括提出问题、与客户共情、构思、原型制作、测试、训练模型,以及持续评估和改进解决方案。当应用于深度学习管道时,设计思维确保重点应放在使用数据科学和深度学习来增强人类的能力和体验,以人为中心的设计原则和隐私及道德的重要性为指导。

人工智能治理和人工智能伦理

这里的课程会让你对机器学习和深度学习如何工作有深入的技术理解。当你开始在现实世界中进行机器学习和深度学习时,强大的治理和道德监督是无法在以后添加的。

有越来越多的工具和信息可以帮助组织理解和实施稳健的治理和道德监督。所有这些网站都有附加内容的链接。

世界经济论坛人工智能工具包

该工具包有关于治理、道德、风险、网络安全等方面的深入信息。该工具包详细介绍了采用人工智能的董事会责任。

T3【哈佛大学伯克曼克莱恩中心】T5

有原则的人工智能有八个关键主题。隐私、问责制、安全和安保、透明度和可解释性、公平和不歧视、人的控制、职业责任和促进人的价值。

安全与道德

该团队致力于探索人工智能对现实世界的影响这一复杂的伦理和社会问题。

“通过对道德标准和安全的正确关注,我们有更好的机会发现人工智能的潜在好处。通过研究涉及人工智能的道德和社会问题,我们确保这些主题仍然是我们所做一切的核心。”(深以为然)。

接下来是什么?

在机器学习中,有一个概念叫做过度拟合,这是指你的模型与训练数据拟合得太好,无法对测试数据进行概括。换句话说,我该暂时把学习放在一边了。是时候专注于探索机器学习和深度学习的现实应用,以继续培养我的技能。

如果你想建立你的数字业务,请联系我这里david@davidkolbconsultancy.com或者发邮件给我这里大卫·库伯

从机器学习开始

原文:https://towardsdatascience.com/starting-out-in-machine-learning-a8a12e5fe227?source=collection_archive---------20-----------------------

我对机器学习教育的动机、经验和未来计划 2023 年更新。

图片:大卫·库伯

在我 2018 年休假结束时,我承诺继续探索新技术,我开始研究机器学习。

回想起来,我从未想过那段旅程会把我带到哪里。快进到今天,我已经完成了深度学习的课程,进入了一个简单机器学习竞赛的前 10%,并获得了 AWS 机器学习专业认证。这段经历既有挑战性又有收获,我渴望与那些刚刚开始 ML 旅程的人分享我的见解和成长。这是我 2022 年的原创文章。

我渴望更多地了解这个领域及其潜力,很快就被它的细节淹没了。机器学习是一个庞大的话题,知道从哪里开始是非常令人生畏的。你从数学还是代码开始?我需要博士学位吗?

在一次失败的开始后,我学到了三件事:不要试图学得这么快,从一些好的学习材料开始,练习,练习,再练习。这些都是比较明显的,但是在我渴望进步的时候,我忘记了这些学习原则。

人工智能无处不在,各公司都把自己的运营模式押在了这上面。人工智能将在夺走我们工作的同时丰富我们的生活,这是商业中最热门的话题,而且已经缺乏技能。我觉得是时候对这个领域有更好的技术理解了,从机器学习开始。

《人工智能的超能力》的作者李开复将当前的时刻描述为“实施的时代”,技术开始“溢出实验室,进入世界”找到正确水平的机器学习信息是困难的。要么是覆盖广义机器学习的高级文档,要么是详细的解释。它导致了许多孤立地难以理解的数学、长方程和机器学习概念。

为什么我想学习机器学习?

我一直有强烈的持续学习的愿望,我将机器学习视为新的挑战和增长机会。

使用机器学习作为增强人类能力的工具,将理论转化为实践来解决实际问题。

用 Python、Udemy 进行机器学习、数据科学和深度学习

[## Python 中的机器学习(数据科学和深度学习)

新的!针对 2019 年冬季进行了更新,增加了关于特征工程、正则化技术和调整神经网络的额外内容…

www.udemy.com](https://www.udemy.com/course/data-science-and-machine-learning-with-python-hands-on/)

我开始上这门课是因为我以前上过弗兰克·凯恩的课,我喜欢实用的方法。他在亚马逊和 IMDB 的经历提供了可以应用机器学习的真实世界的例子。这门课程没有对机器学习算法进行学术的、深入的数学覆盖,重点是广泛的实践理解,以及它的应用。

这门课程将教你选择和清理数据的技术,监督和非监督的机器学习算法,如何评估指标,深度学习和神经网络。该课程确实提供了 Python 的概述,这就足够了,但是非编码人员应该在此之前考虑 Python 课程。弗兰克几乎涵盖了你在深入这个领域之前需要了解的所有话题。

密歇根大学 Python 专业应用数据科学

[## 应用数据科学与 Python | Coursera

密歇根大学专业的 5 门课程通过 python 向学习者介绍了数据科学

www.coursera.org](https://www.coursera.org/specializations/data-science-python)

因为我是 Python 的新手,所以我参加了这个课程,以使我的 Python 技能适合数据科学。有一些 Python 专门化。由于我不想专注于某个特定的平台,这个平台吸引了我的注意力,因为它不是(IBM/Google/AWS)。这是一个五门课程的专业,侧重于编程,而不是理论或数学。

这门课程教会了我数据操作和数据清理技术,绘图和数据表示。它涵盖了机器学习,自然语言处理和社会网络,图论与 Python 库 scikit-learn,自然语言工具包(NLTK)和 NetworkX。

每门课程都建立在另一门的基础上,当你在这个系列中前进时,你将建立在这些技术之上。这些作业是相互评分的,让你从不同的角度看人们是如何处理同一个问题的。

Andrew NG 机器学习,斯坦福大学 Coursera

[## 机器学习|课程

机器学习是让计算机在没有明确编程的情况下行动的科学。在过去的十年里…

www.coursera.org](https://www.coursera.org/learn/machine-learning)

我参加 Andrew NG 课程的动机是了解机器学习的本质以及算法背后的直觉。这门课程被认为是对机器学习背后的理论和概念的最好介绍之一。它涵盖了监督学习,非监督学习,深度网络和最佳实践,而不会让你被底层数学淹没。

完成这门课程不需要深入的线性代数或微积分知识。尽管如此,如果你想学习数学,这门课程将为进一步的训练提供基础。编程作业在 Octave 或者 Matlab。虽然用 Python 编写会更好,但编写一个实际的算法并看到它工作是非常令人满意的。这种详细程度有助于您更好地理解像 scikit-learn 这样的 Python 机器学习库。

这个球场周围有一个杰出的社区。这些论坛为你将会遇到的许多问题提供了详细的解释,这是对我所学的更实用的课程的完美补充。

你需要数学吗?

当我开始机器学习时,我的目标是学习足够的数学来理解和编码算法。我采取按需学习数学的方法,首先让自己熟悉算法,然后研究它们背后的数学,最后将算法翻译成代码。我最终理解了基本的线性代数和基本的微积分,理论和实践达到了平衡。

如果数学是一个挑战,从学习线性回归和逻辑回归算法开始。这些将向您介绍成本/损失函数和梯度下降,并为其他算法提供基础。一个很好的建议是在 Excel 中算出算法,这帮助我克服了一些更具挑战性的概念。

也就是说,数学只是机器学习整体应用的一部分。在这个行业多年,我倾向于同意,对于从业者来说,机器学习的主要先决条件是数据分析。这就是领域经验领域专业知识胜过数学的地方。能够识别问题、选择目标和指标、收集和清理数据构成了机器学习应用程序的大部分。

编程;编排

最初编码算法是令人沮丧的,但坚持下去,因为它有助于加强理解。如果你不熟悉 Python,我建议你从额外的课程开始。其中包括用于数据操作和分析的 pandas、用于多维数组和矩阵的 numpy 以及用于数据可视化的 matplotlib。这将为您完成上述课程奠定基础,并开始您的 Python 机器学习之旅。

以人为中心的人工智能

人工智能有可能极大地改善我们的生活。必须记住,人工智能是人类为人类设计和创造的。以人为中心的设计是一种将人放在设计过程最前沿的方法。当应用于人工智能时,这种方法可以确保人工智能产品和服务专注于人类的联系、体验和需求。

人类设计包括移情、定义、构思、原型和测试。这个过程鼓励协作、试验和迭代,以达到以人为中心的、创新的、可取的、可行的和可行的解决方案。

如果你想建立你的数字业务,请联系我这里大卫·库伯或者发电子邮件给我这里david@davidkolbconsultancy.com

下一步是什么?

你可以在下一篇博文中关注深度学习的进展。深度学习起步。

播客

为了补充我的学习,我使用这些音频播客。

机器学习指南,培训课程的绝佳补充。

数据怀疑论播客,涵盖机器学习概念的精美迷你剧集。

TWIML(本周机器学习),与行业从业者的良好对话。

网站

当你的 Python 代码不工作时的堆栈溢出

《媒体上的数据科学》有大量不同层次的机器学习主题的摘要。

Kaggle 是数据科学家和机器学习从业者的在线社区,你也可以参加他们的比赛来测试你的掌握程度。

3BLUE1BROWN 系列如果真的想深入线性代数和微积分的话。

Cassie Kozyrkov 在 Medium 上发表了关于机器学习的严肃观点。

汗学院对线性代数和微积分的另一种观点。

社会影响评价中的 GIS-云集成

原文:https://towardsdatascience.com/starting-over-61d16c1eece1?source=collection_archive---------65-----------------------

从零开始…在疫情的中间。

现在我们开始看到隧道的尽头,经济和社会后果开始出现,不仅对经济的稳定,而且对我们的社会福利制度的稳定构成严重威胁。

回顾 2012 年,在完美经济风暴期间,我发起了一项提案,为马德里的一个相关非政府组织实施一个关于地理信息系统(GIS)的试点项目。

尽管 2012 年和 2020 年的危机起源不同,但两者在社会经济层面的影响可以作为案例研究。

数据库的管理、其与 GIS 平台(如 Esri 的 ArcGIS )的兼容性以及预测模型的开发是试点项目开发过程中出现的几个挑战之一。

在过去十年中,数据库管理和处理领域以及地理信息系统平台方面的技术进步取得了巨大进步,特别是结合了云平台等技术里程碑的发展。

地理信息系统平台已证明其在报告疫情演变能力方面的有用性。照片:克莱班克斯。去飞溅

现在,在新冠肺炎造成的复杂背景下,我想知道云平台的兴起如何帮助研究和分析疫情在社会经济层面的影响。

在云平台上开发的新应用能否为新冠肺炎社会经济影响的 GIS 研究中的大数据管理、预测分析、人工智能或人工智能提供解决方案?

社会影响评估中的地理信息系统(SIA)

由硬件、软件和地理参考数据集成的地理信息系统优化了与非营利组织活动的地理规划有关的问题的解决方案。

在这方面,地理信息系统支持该组织开展的咨询、分析和研究,缩短了分析人员在研究不平等和贫困问题上花费的时间。这优化了组织的生产力和效率。

在 2012 年经济危机最糟糕的时刻,许多慈善和非营利组织在缓冲西班牙经济危机的影响方面做了大量得到认可的工作。此外,对该国城市地区的贫困和社会不平等进行了许多研究。

这意味着这些组织必须在其不同的行政管理级别(如街道、社区、地区)处理大量数据。

这些组织每年生成的信息给分析人员带来了各种各样的困难,特别是在数据处理和解释方面。这主要是由于组织活动产生的数据的数量、异质性和多样性。

事实上,近年来出现了几个专门为非政府组织使用 GIS 技术的机构,以填补直到最近还不存在的空白。

我的建议侧重于为该组织的活动管理实施一个地理信息系统平台,包括其数据管理规划和外部开发战略。

在非政府组织内部管理和操作大量数据的过程中实施地理信息系统,有助于以更有效的方式优化宝贵的资源,并更好地了解其活动产生的信息。

[## 人道主义者的制图和信息管理

此刻,全世界的注意力都集中在一件事上:新冠肺炎疫情。卡通正在适应它的…

www.cartong.org](https://www.cartong.org/)

除了优化信息和大数据的管理之外,GIS 为非政府组织提供的另一个好处是,从质量上提高了非政府组织宣传该地区慈善过程以及该组织所做的任何其他工作产生的影响和外联效益的能力。

在这方面,在采用 GIS 平台之前,在基于网络的 GIS 社会影响评估中有三个关键因素需要考虑

****通过识别管理和操作中的困难,优化组织的内部数据库,并通过促进持续更新,促进其在未来 GIS 项目中使用的标准化。

通过设计和实施与地图生成一样灵活的沟通策略,加强组织工作的沟通,让更多潜在受众了解非政府组织所做工作的范围。

****在分析、管理和组织的数据生产过程中引入新的信息技术工具。地理信息系统将允许在第一阶段确定与该组织的数据管理有关的问题。

云的影响

从大数据和工业生产力解决方案到人工智能(AI)和机器学习(ML)应用的开发,云技术已经成为不同行业不同用途的关键基础设施。

例如,在教育部门,通过响应与在线教育相关的临时需求,大数据管理的发展显示了最相关的云平台特性之一,即灵活性

此外,医疗保健等战略行业的大数据管理是云技术最有趣的方面之一。患者信息的保护和 GDPR 的实施直接影响到医院备份向云的渐进迁移,以及医院网络从云中生成的异构数据的管理。

除了灵活性,更值得注意的方面是云平台的可扩展性可靠性。这一点在管理大量异构数据时尤为明显,例如公共或私人医疗保健系统。医院备份迁移、客户行为预测模型开发、营销活动或零售消费者研究中的成本节约是一大优势。

成本节约、灵活性、无缝维护和易于部署,使云平台成为社会经济、环境和战略基础设施管理等领域 GIS 分析发展的最佳选择。

云平台在 3D 制图的最新发展中展示了它们的潜力。来源:吉斯格罗

GISers 的新机遇

“云 GIS 可以定义为在可扩展的弹性环境中使用虚拟化平台或基础设施的下一代按需 GIS 技术”。

(相关: 云 GIS 定义 )

毫无疑问,云平台为现有技术和基于众所周知的概念(如 GIS)的新兴技术带来了新的机遇。

云技术彻底改变了 GIS 分析师的工作方式。尽管 GEO 部门在其工作流程中采用云平台的速度很慢,但大量 GIS 组织和咨询公司已经将项目转移到了云上。

在地图中生成的大数据现在可以在云中实时管理,由于有了云,最近只为桌面开发的工具现在可以在 Web-GIS 版本中使用。

许多在云中开发的应用程序现在允许管理大型 GIS 数据库存储。

例如,开发机载栅格技术的公司就属于这种情况,这些公司不仅将云作为向客户提供更快、更简单服务的基础,还将其作为在不同领域开发新的有用应用的结构,例如工程和复杂基础设施的维护。

** [## GISGRO -在线 3D 资产管理平台

GISGRO 智能易用的基础设施管理在线平台。使用 GISGRO 建立一个数字孪生…

www.gisgro.com](https://www.gisgro.com/?gclid=CjwKCAjwi_b3BRAGEiwAemPNUxEDd2gGX6SU6t8BdUrXjHf2a9xc7x26NaQ3rzOJMuBIi3nWBWtAfhoC5LcQAvD_BwE)

3D 建模技术广泛应用于灾害和应急管理,特别是在需要快速有效评估的世界偏远地区。

云-GIS 集成的其他优势:

处理大量数据、应用程序、地理空间分析的可能性,以及与其他用户实时共享它们的可能性。

投资回报(ROI)优化。共享和发布地图的时间更少,数据/地图始终可用;

能够选择各种部署、服务和业务模式以最适合组织的目标。

可用性 24H/7 :在未来的地理信息系统项目中,非政府组织将可以在任何时候访问从创建的图层生成的文件,以促进可用性。
在这一点上,实施云技术是有意义的。这将节省外包工作的成本,该机构在未来完全可以做得很好。

建议优先采用 GIS-云模型

在云平台中实施基于 web 的 GIS 之前,要考虑的最重要的方面总结如下:

a)组织活动领域的活动定义。这将允许管理层优化所需的潜在资源。

b)详细了解该组织的工作、空间和主题,详细描述该地区不同行政级别慈善流程的位置。

c)数据库的改进、同质化和标准化。由于数据量巨大,许多非营利组织发现他们的数据库缺乏管理。这不仅将迫使未来的研究,而且内部信息管理的重组。**

开始使用 Python 掌握机器学习的旅程

原文:https://towardsdatascience.com/starting-your-journey-to-master-machine-learning-with-python-d0bd47ebada9?source=collection_archive---------25-----------------------

关于 ML 的一切

了解精通机器学习的基本要求

路易斯·罗查Unsplash 上的照片

机器学习、深度学习、数据科学和人工智能(AI)是当今最常用的一些热门词汇。这些科目的受欢迎程度与日俱增。每个人都试图跳上炒作列车去探索这些领域。据《财富》杂志报道,统计数据显示,在过去的 4 年里,人工智能专家的雇佣量增长了 74%。人工智能被认为是当代人最热门的工作。这可能会导致观众心中产生许多疑问。

是什么让它如此受欢迎?这些字段是什么?什么是机器学习?我如何开始?为什么是 python?

我将在今天的文章中尝试回答所有这些问题,同时详细解释如何开始学习 python 和机器学习(ML)。然后我们会明白你如何调整和掌握你的机器学习技能。

注意:这将是我的“关于机器学习”课程的第一部分。但是,每个后续零件都将是独立零件。你可以根据你的方便以任何顺序阅读这个系列。我将在接下来的文章中尝试涵盖基础知识和大多数机器学习算法。要查看该系列的其他部分,您可以点击此处

为什么 AI 这么受欢迎?

本杰明·戴维斯在 Unsplash 拍摄的照片

人工智能是当今发展最快的领域之一。人工智能的进步正在快速发展。不缺乏开放的职位以及职业机会。每个人都在大肆宣传人工智能将成为下一个大事件。正如现代人工智能最杰出的人物之一安德鲁·吴教授所言

“人工智能是新的电力。”

由于技术的进步和数据的丰富,现代人工智能领域有很多期望。我们有更高质量的图形处理器和更好的技术来计算复杂的过程。

这些字段到底是什么?

人工智能是一个广阔的领域。机器学习、数据科学、统计学、自然语言处理等主题都属于人工智能。深度学习是机器学习的一个子集。

人工智能是—

“能够执行通常需要人类智能的任务的计算机系统的理论和发展,如视觉感知、语音识别、决策和语言之间的翻译。”

要了解更多关于人工智能及其与宇宙的类比,你可以参考这里。在本文中,我们将更多地关注机器学习。我会尝试给出一个更直观的理解机器学习的方法。

什么是机器学习?

机器学习是程序自动学习和提高效率的能力,而无需显式编程。这意味着给定一个训练集,你可以训练机器学习模型,它将理解一个模型到底是如何工作的。在对测试集、验证集或任何其他看不见的数据进行测试时,模型仍然能够评估特定的任务。

让我们用一个简单的例子来理解这一点。假设我们有一个 30,000 封电子邮件的数据集,其中一些被分类为垃圾邮件,一些被分类为非垃圾邮件。机器学习模型将在数据集上训练。一旦训练过程完成,我们可以用一封没有包含在我们的训练数据集中的邮件来测试它。机器学习模型可以对以下输入进行预测,并正确分类输入的电子邮件是否是垃圾邮件。

机器学习方法主要有三种。我们将讨论每一种方法。然后,我将为每种方法列举一些例子和应用。

1。监督学习—

这是使用专门标记的数据集训练模型的方法。数据集可以是二元分类,也可以是多类分类。这些数据集将具有指定正确和错误选项或一系列选项的标注数据。在监督下,即在这些标记数据的帮助下,对模型进行预训练。这种学习可以分为两种算法——

  1. 分类:当输出有选择或特定类别时,这些算法是首选。垃圾邮件过滤的例子可以被认为是一个分类问题。
  2. 回归:当输出变量具有真实值时,算法是首选。这方面的一个例子是预测特定位置的房价。

算法:回归算法(线性回归)、决策树、随机森林和分类算法,如 K-最近邻(KNN)、支持向量机(SVM)、逻辑回归、朴素贝叶斯。

应用:垃圾邮件过滤,肿瘤分类(良性或恶性),用户评论分类为正面或负面评论。

2。无监督学习—

无监督学习是在未标记的数据集上训练模型。这意味着模型没有先验信息。它通过将相似的特征和模式组合在一起来训练自己。无监督学习的一个例子可以是狗和猫的分类。给我们的数据将是一个未标记的数据集,包含狗和猫的图像。无监督算法将发现模式中的相似性,并在不指定数据类型的情况下将狗和猫分别分组。有两种主要的聚类算法—

  1. 聚类:将相似的实体排列成一组簇。如前所述,这种将猫和狗等类别分组为簇的例子。另一个例子是根据具体数据确定癌症的阶段。
  2. 关联:在两个或多个类/用户之间关联相似的模式。这方面的一个例子是推荐系统,其中如果一个特定的人观看一部特定类型的电影,则基于观看了同一部电影的其他用户更喜欢观看的内容向用户给出推荐。另一个例子是,当亚马逊推荐购买了特定商品的买家也更喜欢购买其他类似的商品。

算法: K-means 聚类,主成分分析(PCA),奇异值分解(SVD),层次聚类。

应用:亚马逊、网飞、YouTube 等数字平台的推荐系统,脸书上的好友建议,异常检测。

3。强化学习—

根据维基

强化学习(RL)是机器学习的一个领域,涉及软件代理应该如何在环境中采取行动,以最大化累积回报的概念。强化学习是与监督学习和非监督学习并列的三种基本机器学习范式之一。

强化学习是一种试凑法模型。这是模型通过重复失败来学习的方法。当一个模型没有达到期望的结果时,该模型将重新训练。这可以应用于像下棋这样的概念,在玩了数百万局游戏后,模型将能够学习适当的模式和移动。一个更简单的例子是井字游戏。该模型可以在数百场比赛后学习每一条通往胜利的道路,一旦经过完美的训练,它将永远不会输掉一场比赛。

算法:基于策略、基于值、基于模型的强化学习算法。

应用:模型学习玩游戏像 flappy bird,工业自动化中的机器人技术,交通控制,基于深度学习的强化学习。

我如何开始?

照片由奥斯汀·柯克Unsplash 拍摄

如果你对如何开始你的机器学习之旅感到好奇,那么答案很简单。开始机器学习的最佳方式是探索和深入挖掘围绕机器学习的各种主题。重要的是要了解你是否对这个领域感兴趣和充满激情。机器学习需要编程技能、数学知识,最重要的是学习的意愿和坚持。有很多免费和付费的资源,从中你可以获得很多知识。

我强烈建议观众在 YouTube 上在线查看各种机器学习视频。查看免费代码和训练营也是一个好主意。我认为在开始学习在线付费课程之前,先看看免费的东西是个好主意。一旦你发现你真的喜欢机器学习,并有强烈的兴趣,我会强烈建议你先学习 Python,然后参加由 Andrew NG 在 Coursera 提供的斯坦福大学的机器学习课程。有大量的在线课程可供选择。只要相应地复习课程,并参加最适合你的任何机器学习课程。

为什么是 Python?

来源:照片由 Cookie 在 unsplash 上的 Pom

Python 是一种面向对象的高级编程语言,发布于 1991 年。Python 具有高度的可解释性和高效性。简单来说——Python 很神奇。我最初是从 C、C++和 Java 这样的语言开始的。当我终于遇到 python 的时候,我发现它相当优雅,简单易学,易于使用。Python 对于任何人来说都是最好的方式,即使是以前没有编程或编码语言经验的人也是如此。尽管有一些缺陷,比如被认为是一种“慢”语言,python 仍然是人工智能和机器学习的最佳语言之一。

尽管有像 R 这样的其他语言,Python 在机器学习中如此受欢迎的主要原因如下

  1. 如前所述,python 非常简单和一致。
  2. 与其他编程语言相比,受欢迎程度的快速增长。
  3. 与各种库和框架相关的丰富资源。我们将在本系列的下一部分进一步详细讨论这一点。
  4. 多功能性和平台独立性。这意味着 python 也可以导入用其他编程语言构建的基本模块。
  5. 伟大的社区和持续更新。总的来说,python 社区充满了令人惊奇的人,并且不断更新以改进 python。

要开始使用 python,可以从这里下载。

结论:

我希望你们都喜欢这本书。这将是我的“关于机器学习”系列教程的第 1 部分。我计划涵盖所有关于机器学习的主题。在本系列的下一部分,我们将回顾 python 及其库的所有基础知识。所有这些都是独立的部分,您可以随时查看它们。点击查看该系列的未来部分。谢谢大家坚持到最后,祝大家有美好的一天。

州名到州名缩写人行横道

原文:https://towardsdatascience.com/state-name-to-state-abbreviation-crosswalks-6936250976c?source=collection_archive---------36-----------------------

图片来源:“Via Design Pickle”——更多关于属性

我不得不第一百万次穿过州名和州名缩写。

概观

作为一名数据科学家、研究人员或任何类型的数据从业人员,您已经拥有或将最终拥有一个列出州名的数据集。但是,你需要州名缩写。或者可能正好相反。

对于初学者,甚至是中级数据专家来说,这可能是一项棘手而繁琐的任务。我花了一点时间来分享一个快速(并且在许多用例中容易应用)的方法来解决这个问题。

上面代码的输出。图片来源:“作者截屏”——更多关于属性

警告

  • 只有当负责 clerk.org 的法院的好书记官将 html 表放在适当的位置时,这段代码才会起作用。此外,该表仍然是指定位置的第一个可用表。
  • 只有在 clerk.org 的表格准确无误的情况下,这个代码才会起作用。你应该四处找找其他的桌子。或者,将一个放在容易拿到的地方供自己使用。
  • 此代码假设您已连接到互联网。
  • 这段代码的预期功能还假设原始数据集正确且一致地拼写了每个状态。也没有其他印刷错误。

[## 加入我的介绍链接媒体-亚当罗斯纳尔逊

作为一个媒体会员,你的会员费的一部分会给你阅读的作家,你可以完全接触到每一个故事…

adamrossnelson.medium.com](https://adamrossnelson.medium.com/membership)

感谢阅读

感谢阅读。把你的想法和主意发给我。你可以写信只是为了说声嗨。如果你真的需要告诉我是怎么错的,我期待着尽快和你聊天。Twitter:@ adamrossnelsonLinkedIn:Adam Ross Nelson 在 Twitter 和脸书: Adam Ross Nelson 在脸书

田纳西州新冠肺炎分析

原文:https://towardsdatascience.com/state-of-tennessee-covid-19-analysis-6933b7bd35bf?source=collection_archive---------29-----------------------

这是一篇让州领导和公民更好地了解田纳西州冠状病毒数据的文章,以及为什么严格遵守社交距离如此重要。有很多图表和表格!跟着我。

关于数据限制— 数据分析师总是不愿意使用他们知道不完整、不具代表性或存在固有缺陷的数据。缺乏全面的测试无疑使这些数据集有资格被谨慎对待。

该州确诊病例数量较低——原因如下

测试可用性滞后:根据 tn.gov 的数据,截至 2010 年 3 月 31 日营业结束时,田纳西州目前已经进行了大约每百万人 4011 次测试。Quest 官方表示,他们的平均测试处理时间为 4-5 天,然而,我的一名直系亲属在加州的一家医疗协会工作,负责联络医生和医院管理人员,他们表示测试处理积压了 10 天的等待时间。我的丈夫是当地呼叫中心的经理,他有一个阳性病例——一名被感染的员工在 10 天后终于收到了他的测试结果。像这样符合等待时间的轶事开始被全国性的报道所报道。

即使我们没有获得数据,指数增长仍在发生:这种滞后表明,在过去 10 天左右进行的任何测试实际上都没有实时报告,而是滞后 10 天。根据过去 24 小时内报告的病例数量,我们每天检测大约 1,000 人。1000 次测试乘以 10 天,等于 10000 次未报告的测试。目前大约有 10%的测试呈阳性,所以根据非常粗略的估计,这意味着在 3 月 27 日 20 日写这篇文章时,田纳西州可能有超过 2300 例病例,而不是该州报告的1321 例。但是事情是这样的,指数增长意味着案件会继续指数增长,而测试 不是

田纳西州活跃案例的增长率根据当前图表的线,不包括 3/31/20 处的急剧上升轨迹,当前增长率为. 2915。如果你应用简单的指数增长方程,它预测到 4 月 10 日有 33,000 个病例。增长率为 0.15(明显低于自病例 1 以来的大多数 24 小时内的增长率),预计到 4 月 10 日将有 30,000 例病例。虽然这确实是推测性的,但可以肯定的是,检测报告中的任何积压都意味着该州的实际确诊病例仅在积压开始的最后一天有效。

只有有共同症状的患者才会接受测试:你必须在有资格接受测试之前接受评估,而且评估仅基于最普遍或最严重的症状。这意味着,在任何给定的时间,可能会有几倍以上的轻微和不明原因的病例不符合检测条件——这些人,虽然他们自己不是一个问题——正在成为其余人口的疾病宿主。有几个突出的当地例子说明了这一点。回到 3 月 8 日,一名在& T 塔(蝙蝠侠大楼)的工作的员工被报道为一个积极的症状案例。这个人一定是在病毒传播的窗口期来工作的,因为在病例被确认后,他们关闭了大楼进行深度清洁。这意味着 4 天的测试过程,然后 5-14 天无症状,并能够摆脱病毒。这意味着,从 2 月中下旬开始的几天时间里,共用那栋大楼的 2000 名员工有一定的暴露机会。同样的场景在拥有 1500 多名员工的 Murfreesboro 的 State Farm 呼叫中心上演。测试呈阳性的人已经请了一周的病假——我个人对这种情况有所了解。有多少人被感染了?3 月 12 日,Gulch Crossing 办公大楼因一个阳性病例而被关闭进行清洁——这里住着 800 名工人。有多少像这样的场景在未经测试的情况下发生了?其他国家的数据显示我们很快就会知道。

作为一个州,我们没有获得任何这种数据,也没有用我们报告的数字来说明这一点,这意味着我们没有能力真正为峰值医疗利用率做好准备。

田纳西州的倍增时间平均为 2.75 天:倍增时间是一种控制疾病增长速度的方法。增长率是指数增长方程中的“r ”,它告诉你病毒传播的速度。即使我们在 27 日实际上有 1321 个病例,这意味着三天后我们将有 2600 个病例。六天后我们会有 5200 人。两周内,我们将有近 10,000 个案例。但问题是,在某个时候,速度会开始加快,你会得到更快的传播,因为越多的人被感染,就有越多的人感染其他人。是的,我们的自愿抑制措施肯定有缓解效果。但最重要的是,很可能是机缘巧合给了我们一个宽限期——春假和龙卷风使学校在李州长下达全州范围的命令之前关闭了。学校关闭可能是我们现在看到的抑制曲线的效果——记住所有的缓和都有 10-17 天的滞后。

图 1:包括田纳西州在内的 7 个州的活跃案例(橙色):

https://github.com/nytimes/covid-19-data

在上面的图表中,田纳西州是橙色的,显示了几个类似的南部州,以及爆发时间晚几天的华盛顿和加利福尼亚。田纳西州的增长速度似乎比其他城市慢,原因更可能是 1)病毒在社区传播中的延迟引入,2)学校因龙卷风、春假和冠状病毒而产生的缓解效应,以及主要大学迅速停止校园课程。

图 2:学校关闭日期

数据来源于校区和大学网页。*表示威尔逊县学区因 2010 年 3 月 2 日的龙卷风停课一周

图 3:田纳西州的疫情曲线

https://github.com/nytimes/covid-19-data

上面显示了田纳西州孤立的疫情曲线——橙色是活跃病例,蓝色是每天的新病例。这条曲线与学校停课的时间框架相结合,证实了在中国湖北省和意大利看到的情况。抑制措施的所有效果从实施到看到活动案例下降有 12-14 天的延迟。请看以下来自中国和意大利的图片。

图 4:中国湖北省——全球疫情爆发的中心

图 5:意大利

红线表示颁布镇压措施的日期。蓝/黄条表示该国的活跃病例,深橙色表示每天的新病例。每次实施缓解措施后,大约需要 10-14 天才能看到每天新病例的减少。

在中国,每天新增病例开始下降后,又过了 12 天才看到实际活跃病例总数开始下降。

新冠肺炎和田纳西州及其他州的健康统计

图 6:11 个选定州实施缓解措施的新冠肺炎有效案例及日期

数据来源:【https://coronavirus.jhu.edu/map.html

浅黄色方框表示意大利在伦巴第地区发布停业和居家命令时的病例数。蓝色表示中国在湖北省发布关闭和居家命令时该省的人数。

图 7:美国 11 个州的死亡率

数据来源:https://coronavirus.jhu.edu/map.html

上表显示了这些州目前的死亡率——这通常是对流行病后的真实死亡率进行的回顾性校正。田纳西州极低的数字表明数据报告可能存在滞后,或者在用电高峰之前对相对较少的严重病例进行过度护理的能力。

图 8:美国 11 个州的增长率

数据来源:https://coronavirus.jhu.edu/map.html

上表显示了增长率,即代数指数增长方程中的变量“r”。当病例增长更快时,这个数字会更高。在其他国家,指数增长并没有减缓到持续低于 0.1,直到他们接近最大活跃病例。这意味着他们有效地限制了受感染的人群。不要指望很快在田纳西州或美国其他州看到这种行为。

图 9:美国 11 个州的翻倍时间

数据来源:https://coronavirus.jhu.edu/map.html

上表显示了以天为单位的倍增时间,每天使用增长率数字进行计算。翻倍时间是指以给定的速度将案例翻倍所需的时间。随着增长率上升,倍增时间下降。

图 10:美国 7 个州的年龄人口统计数据、新冠肺炎死亡率以及诊断为糖尿病的人口百分比

数据来源:Census.gov、、https://coronavirus.jhu.edu/map.htmlhttps://www . americasheahelhtrankings . org/explore/annual/measure/Diabeteshttps://memphischoard . com/select-Memphis/data-center/population/https://www . kff . org/other/state-indicator/distribution-by-age/?current time frame = 0&sort model = % 7B % 22 solid % 22:% 22 location % 22,%22sort%22:%22asc%22%7D

上表显示了各相似州 50 岁以上和 65 岁以上的人口统计数据,包括田纳西州(橙色)以及新冠肺炎迄今为止的总死亡率(3/27/20)和各州糖尿病人口的百分比(这是增加新冠肺炎死亡率的一个风险因素)。

图 11:美国 7 个选定州的年龄人口统计、慢性阻塞性肺病和心脏病死亡率

数据来源:Census.gov、https://coronavirus.jhu.edu/map.htmlhttps://www . americasheahelhtrankings . org/explore/annual/measure/Diabeteshttps://memphischoard . com/select-Memphis/data-center/population/https://www.cdc.gov/nchs/pressroom/stats_of_the_states.htmhttps://www . kff . org/other/state-indicator/distribution-by-age/?current time frame = 0&sort model = % 7B % 22 solid % 22:% 22 location % 22,%22sort%22:%22asc%22%7D

上表显示了与左侧 y 轴相关联的彩色条中 50 岁和 65 岁以上人口的百分比。各种类似的州用田纳西(橙色)表示。较大的条形表示百分比超过 50,较小的条形表示百分比超过 65。当前新冠肺炎累积死亡率(2010 年 3 月 27 日)和每个州每 100,000 人的慢性阻塞性肺病和心脏病死亡率(两者都是增加新冠肺炎死亡率的风险因素)显示为与右侧 y 轴相关的线。田纳西州是慢性阻塞性肺病死亡率最高的地区,心脏病死亡率第二高

图 12:特定州和国家的人口密度和 50 岁以上公民

数据来源:Census.gov、https://www . americasheahelhtrankings . org/explore/annual/measure/Diabeteshttps://memphischoard . com/select-Memphis/data-center/population/https://www.cdc.gov/nchs/pressroom/stats_of_the_states.htmhttps://www . kff . org/other/state-indicator/distribution-by-age/?current time frame = 0&sort model = % 7B % 22 solid % 22:% 22 location % 22,%22sort%22:%22asc%22%7D

上图用彩色条显示了给定州和国家的人口密度。蓝线代表 50 岁以上人口的百分比,红线代表每个城市、州或国家 65 岁以上人口的百分比。根据目前可用的文献,从 40 岁开始死亡率增加。黄线表示新冠肺炎各城市、州或国家的当前累积死亡率(如有)。

图 13:根据中国湖北数据得出的按年龄统计的死亡率

数据来源:https://www . world ometers . info/coronavirus/coronavirus-age-sex-demographics/

该图显示了年龄人口统计在评估人群可能风险中的重要性。在中国观察到的死亡风险在 40 岁时增加一倍,并且从那里开始上升。

图 14:已患疾病者的死亡率

https://www . worldometers . info/coronavirus/coronavirus-age-sex-demographics/

该图显示了患有复杂先存疾病的患者的风险有多高,在评估人群风险时也必须考虑在内。疾病预防控制中心估计,大约 33.2% 的美国人口患有高血压,田纳西州高于全国平均水平 38.5% (2017)。

底线是,虽然自愿措施和学校关闭显然会对病例的增长产生抑制作用,但在这个国家有无数自私和粗心的人即使生病也去公共场合的例子,因为他们认为自己购物的权利比其他人生存的权利更重要。人群中风险最高的个体是我们中最脆弱的人群——温顺的人——我们的孕妇、我们敬爱的老人以及已经在与重大健康问题作斗争的人。

新的数据也表明,其他国家和纽约州的年轻人也未能幸免于重症监护室或死亡。纽约大约 25%的住院患者年龄在 20-40 岁之间,40%的患者年龄在 20-54 岁之间。我完全理解田纳西州是一个有自由主义价值观的保守州。但是有一些情况需要强有力的领导干预,数据响亮地显示这是时候了。越多不认真对待这一问题的人暴露出来,反过来又暴露了其他人,越多的脆弱人群将被感染和死亡。

绝对没有证据表明病毒的传播会以任何其他方式发展,但呈指数增长——除非实施严格的学校和企业关闭以及留在家中的命令。在田纳西州没有理由“等着瞧”。到我们“看到”的时候,至少 2 周内扭转趋势就太晚了。德国在 48 小时内增加了 20,000 个案例,这些案例都是建议性的,而不是强制性的限制。两周内会发生很多事。

我再次敦促你们实施更强有力的措施,要求非必要的企业关闭,人们呆在家里,并帮助医疗机构和必要的企业(实际上是必要的企业)为即将到来的疾病高峰做好准备。

最先进的图像分类算法:固定有效网络-L2

原文:https://towardsdatascience.com/state-of-the-art-image-classification-algorithm-fixefficientnet-l2-98b93deeb04c?source=collection_archive---------21-----------------------

结合脸书和谷歌人工智能团队的 FixRes 和 EfficientNet

FixEfficientNet 是一种结合了两种现有技术的技术:脸书人工智能团队【2】FixRes 和谷歌人工智能研究团队首次提出的efficient net【3】。FixRes 是 Fix Resolution 的简称,它试图为用于训练时间的 RoC(分类区域)或用于测试时间的 crop 保持固定的大小。EfficientNet 是 CNN 维度的复合缩放,提高了准确性和效率。本文旨在解释这两种技术,以及为什么它们是最先进的。

FixEfficientNet 已于 2020 年 4 月 20 日与脸书人工智能研究团队的相应论文一起首次亮相1。该技术用于图像分类,是计算机视觉领域的一项任务。它目前是最先进的,在 ImageNet 数据集上具有最好的结果,480M 参数,前 1 名准确率为 88.5%,前 5 名准确率为 98.7%。

但是,让我们更深入一点,以便更好地理解这些组合技术:

理解修复

训练时间

在脸书人工智能研究团队提出 FixRes 技术之前,最先进的技术是从图像中提取随机的像素方块。这被用作训练时间的 RoC。(请注意,使用这种技术会人为增加数据量)。然后调整图像大小以获得固定大小的图像(=裁剪)。然后将其输入卷积神经网络[2]。

RoC =输入图像中的矩形/正方形
crop =使用双线性插值重新调整到特定分辨率的 RoC 像素

列车时间尺度增强

为了更好地理解 FixRes 到底做了什么,让我们来看看数学。改变输入图像中 RoC 的大小会影响给 CNN 的对象大小的分布。对象在输入图像中的尺寸为 r x r 。如果 RoC 现在被缩放,那么它被改变 s,并且对象的大小现在连续地是 rs x rs

对于增强,使用 PyTorch 的 RandomResizedCrop。输入图像的尺寸为H×W,从中随机选择一个 RoC。然后这个 RoC 被调整到一个裁剪尺寸

来源:作者图片。

输入图像( H x W )对输出的裁剪的缩放比例可由以下系数表示:

来源:作者图片。

测试时间

测试时间,RoC 通常位于图像的中心,这导致所谓的中心裁剪。来自训练时间和测试时间的两种裁剪具有相同的大小,但是它们来自图像的不同部分。这往往导致 CNN 的分布出现偏差[2]。

测试时间尺度增强。

如前所述,测试增强不同于训练时间增强(关键词中心裁剪)。作物的大小

关于输入图像是正方形(H=W)的假设,测试增强的比例因子可以表示为

这有什么发现? 在 FixRes 开发出来之前,测试的预处理和训练时间是分开开发的,这导致了偏差。连续地,脸书人工智能团队试图找到一个解决方案,同时执行预处理,并以某种方式同步,这就是 FixRes

来源:作者图片。

如上所述的标准预处理通常会在训练时扩大 RoC而在测试时缩小 RoC。

FixRes 技术采用非此即彼的方法。它或者降低训练时间分辨率并保持测试裁剪的大小,或者增加测试时间分辨率并保持训练裁剪的大小。目的是检索相同大小的对象(这里是乌鸦)以减少 CNN 中的尺度不变性[2]。这看起来像下面这样:

来源:作者图片。

这导致对如何将数据馈送给 CNN 的两个影响:

  1. 图像中对象(此处为乌鸦)的大小因固定缩放而改变。
  2. 不同作物大小的使用对神经元被激活的方式和时间有影响。

变化激活统计的问题

Touvron 等人发现,更大的测试作物和最重要的对象大小的调整导致更好的准确性。然而,这是调整对象大小和改变激活统计之间的权衡。

测试表明,激活图随着图像分辨率的变化而变化。K_test = 224 导致 7×7 的地图,K_test = 64 导致 2×2 的地图,K_test = 448 导致 14×14 的地图。这表明激活分布在测试时变化,并且值在分类器范围之外1

为了解决激活统计的变化问题,提出了两种解决方案:

  1. 参数适应:参数弗雷歇分布用于拟合平均池层。然后,通过标量变换将新分布映射到旧分布,并作为激活函数应用。
  2. 微调:应用校正的另一种方式是模型的微调。微调仅适用于 CNN 的最后几层。

在微调阶段,使用标签平滑1

想看更多这样的故事?

开始使用

高效网络架构[3]

作者预先训练了几个模型,从这些模型中,L2 效率网显示出最好的结果。但是什么是效率网呢?

与大多数图像分类算法一样,有效网络也是基于细胞神经网络的。如果你不知道 CNN 是什么,点击这里。CNN 有三个维度:宽度、深度和分辨率。深度是层的数量,宽度是通道的数量(例如,传统的 RGB 将具有 3 个通道),分辨率是图像的像素。

EfficientNets 引入了复合缩放,它利用了所有三个维度:

宽度缩放 —可以通过增加图像的通道来增加宽度。然而,精度增益下降得相当快。

深度缩放 —是常规且最典型的缩放方式。通过增加深度,可以增加神经网络的层数。但是添加更多的层并不总是能提高网络的性能。大多数情况下,它需要更多的时间,但由于渐变消失,随着层数的增加,性能可能会停滞甚至下降。

分辨率缩放— 这意味着增加分辨率和像素数量,例如从 200x200 增加到 600x600。这种缩放的问题是,精度增益随着分辨率的提高而消失。直到某一点,你的精度可能会增加,但精度增量减少。

所有三个维度的升级会导致精度增量递减,并且所有三个维度的平衡缩放对于实现最佳精度结果是必要的。因此,建议采用复合缩放:

来源:作者图片。

ɸ指定可用的资源,而阿尔法、贝塔和伽玛负责资源的分配。

Touvron 等人1“使用神经结构搜索来开发新的基线网络,并将其放大以获得一系列模型,称为 EfficientNets。”神经架构搜索(NAS)优化了 FLOPS 和精度。

结论

这两种技术的结合产生了目前图像分类中最好的算法,领先于 EfficientNet Noisy Student。在效率和准确性方面,它都是当前领先的算法。由于其 98.7%的前 5 名准确度,仍有改进的可能性,但它已经相当准确了。因此,它仍然要等待,直到这是一种新的技术取代。

由于本文不包含任何实现,您可以使用作者的官方 Github 自行尝试:http://github.com/facebookresearch/FixRes.

作者1的预训练网络如下所示

github 回购截图。

我希望你能理解并喜欢它!

* [## 请继续关注马里乌斯·哈克的新文章

请继续关注 Marius Hucker 的新文章。如果您还没有注册,您将创建一个中型帐户…

medium.com](https://medium.com/subscribe/@hucker.marius)*

参考文献 :

1h .图夫龙、a .韦达尔迪、m .杜泽和 h .杰古(2020 年 b)。修正训练-测试分辨率差异。ArXiv:2003.08237 [Cs] 。http://arxiv.org/abs/2003.08237

[2]h .图夫龙、a .韦达尔迪、m .杜泽和 h .杰古(2020 年 a)。修复列车测试分辨率差异。ArXiv:1906.06423【Cs】http://arxiv.org/abs/1906.06423

[3]谭,米,乐,张庆伟(2020).反思卷积神经网络的模型缩放。 ArXiv:1905.11946 [Cs,Stat]http://arxiv.org/abs/1905.11946

最先进的基础设施代码

原文:https://towardsdatascience.com/state-of-the-art-infrastructure-as-code-4fbd59d92462?source=collection_archive---------11-----------------------

萨阿德·萨利姆在 Unsplash 上拍摄的照片

Gruntwork 的最新抽象层将使您的生活更加轻松

开始

HashiCorp 在几年前推出 Terraform 时,已经彻底改变了代码基础设施。从那时起,Terraform 已经取代了特定于供应商的基础设施,成为像 AWS 的 CloudFormation 这样的代码解决方案。Terraform 抽象了云形成的复杂性,还提供了一个公共基础设施作为代码平台,以迁移到多云环境。一开始,Terraform 的规模变得非常复杂,维护基础架构的模块化方法并不容易,尤其是当您有许多不同的环境具有相似的基础架构时。

Gruntwork 的 Terragrunt 是 Terraform 的一个包装器,致力于解决您的 Terraform 状态管理和配置问题。它还解决了在不同环境中部署类似基础设施的一些问题。

[## 用例

Terragrunt 是 Terraform 的一个瘦包装器,它为使用多个 Terraform 模块提供了额外的工具。

davidbegin.github.io](https://davidbegin.github.io/terragrunt/use_cases/)

古老的原则“不要重复自己”是从良好的软件开发实践中借鉴来的,在良好的软件开发实践中,你创建一个你必须重复做的事情的函数或方法。等同于地形的是一个模块。模块是一段可重复的、独立的代码,可用于部署基础设施。给 这个 一个念。随着 Terraform 被各种规模和背景的工程团队广泛采用,Terragrunt 是一个很好的升级。

来自作者本人,Yevgeniy brik man——terra grunt 的联合创始人

现在……

虽然 Terragrunt 给了我们一些真正重要的功能,并且肯定是对 Terraform 的升级,但 Gruntwork 今天宣布了另一个升级。它只是另一个抽象层,可以防止你在设计 Terraform 模块或编写 Terraform 代码时做出错误的设计决策。

这种抽象将代码库的基础结构分为三个部分

  • 模块目录 —通过组合数百个可重复使用、久经考验的模块来部署基础架构。模块可用于部署数据库或 EC2 服务器。例如,EC2 服务器的模块也可能有 IAM、安全组、DNS 记录设置。
  • 服务目录 —这是两个新抽象层中的第一层。它在底层组合了许多模块,并为您提供了部署服务的选项。服务将包括地形代码、配置管理代码、日志记录&警报、安全性、自动化测试以及应用程序在生产环境中运行所需的任何其他内容。
  • 架构目录 —这只是简单地部署了完整的堆栈,一切都已接入。类似于 AWS 的着陆区,这将建立安全基线。除此之外,它还将具备完整的网络、容器编排、存储、隐私、CI/CD、监控、警报、合规性,以及生产环境中运行的应用程序所具备的几乎一切。

Gruntwork 再次为现有的一系列产品增添了一个伟大的功能,使 SRE、DevOps 和 DataOps 的人们的生活变得轻松。唯一的问题(也是最大的问题)是,你必须有订阅计划才能访问代码。对于投资 IaC 的团队来说,订阅可能是值得的。此外,所有这些代码都完全独立于 Terragrunt,不会将您束缚在其中。它可以与 Terragrunt、Terraform Enterprise 和 Terraform Cloud 配合使用。你可以在这里查看订阅计划

[## 成为 Gruntwork 的订户

为您的团队配置合适的计划。

gruntwork.io](https://gruntwork.io/pricing/?ref=service-catalog-announcement)

2020 年最先进的语言模型

原文:https://towardsdatascience.com/state-of-the-art-language-models-in-2020-2c25c081b558?source=collection_archive---------40-----------------------

突出显示最常见的 NLP 任务的模型。

自然语言处理(NLP)中有许多任务,语言建模机器翻译自然语言推理问题回答情感分析文本分类更多的 …由于不同的模型在不同的领域有所侧重和擅长,本文将重点介绍最常见的 NLP 任务的最新模型。

变压器

自从 Transformer 推出以来,它的变体已经应用于许多(如果不是全部)NLP 任务,实现了最先进的性能。在引入变压器之前,RNN 模型已经是用于序列建模和转导问题的最先进的结构。然而,鉴于 RNN 计算的顺序性质,训练期间的并行化主要受到限制,导致训练效率较低。作者提出了一种编码器-解码器结构,完全依赖于注意机制,而不使用递归结构。

变换器的编码器由 6 层组成,每层由一个多头自注意机制组成,后面是一个前馈网络。在每个子层之前和之后,添加剩余连接和 add & norm 层。解码器具有相同数量的 6 层。然而,在自关注层和前馈层之间插入了一个编码器-解码器关注层。注意遮罩用于隐藏后续位置的标记。

所使用的注意机制被称为缩放的点积注意,它通过来标准化逻辑,以防止由于 softmax 的小梯度而导致的缓慢收敛。此外,本文还提出了多头注意的概念,使得该模型能够关注来自不同表征子空间的信息。在最终分类层之前,来自所有子空间的隐藏状态然后被连接和投影。

在编码器自我关注层中,所有的键、值和查询都来自前一层,允许编码器关注前一层的所有位置。然而,由于注意屏蔽,解码器自我注意只注意到领先位置。另一方面,为了引起编码器-解码器的注意,从先前的解码器层提取查询,而键和值来自编码器隐藏状态。这允许解码器关注编码序列中的所有位置,这在序列到序列任务中是至关重要的。

为了注入相对或绝对的位置信息,位置编码被添加到输入嵌入中。理论上可以是学来的,也可以是固定的;然而,采用正弦位置编码是为了更容易学习和外推至更长的序列。

[## 变压器图解指南

逐个组件的细分分析

towardsdatascience.com](/illustrated-guide-to-transformer-cf6969ffa067)

双向编码器表示转换器

语言模型传统上是单向的,在训练过程中只有先前时间步的单词是可见的。这是为了确保预测的单词不会间接“看到自己”然而,在许多句子级或标记级任务中,前向和后向上下文对于最佳性能都是必不可少的。

2018 年推出了双向编码器表示变压器( BERT )。它在转换器结构中利用屏蔽语言建模来促进双向表示训练。每个输入序列都以一个特殊的【CLS】标记开始,其隐藏状态用于表示分类任务。对于句子对输入,添加了【SEP】标记来指示单个句子之间的边界。每个标记的初始嵌入与片段嵌入和位置嵌入相加,作为变换器的输入。

BERT 模型包括两项预训练任务:

  1. 屏蔽语言模型。在预训练期间,随机选择所有标记中的 15%作为标记预测的屏蔽标记。然而,由于在微调期间不存在【MASK】标记,这导致预训练和微调之间的不匹配。因此,在所有选择要屏蔽的令牌中,只有 80%被替换为【屏蔽】令牌。10%的时间令牌将保持不变,10%的时间由随机令牌替换。作者进行了烧蚀研究,以表明这样的置换率会产生最佳的下游性能。值得注意的是,通过【掩码】的完全替换或通过随机令牌的完全替换导致次优性能。
  2. 下一句预测。对两个句子之间的关系进行建模至关重要,尤其是对于问答或自然语言推理等下游任务。因此,作者提出了下一个句子预测任务来分类一个句子是否是另一个句子的尾随句。当选择句子 1 和 2 进行句子对输入时,50%的情况下,句子 2 是跟在 1 后面的实际句子。另外 50%的时间,随机选择一个句子,作为反面样本。这个简单的任务导致了问答和自然语言推理任务的显著改善。

在预训练之后,通过简单地替换适当的输入-输出对,该模型在各种下游任务上被微调。对于标记级任务,例如序列标记或问题回答,每个标记的隐藏状态被提供给输出层。另一方面,【CLS】隐藏状态用于句子级别的任务,例如蕴涵和情感分析。

研究人员进一步探索专门针对文本分类的 BERT 微调,由三部分组成:

  1. 使用任务内或领域内的训练数据来进一步预训练 BERT
  2. 使用多任务学习进行微调(可选,如果相关任务可用)
  3. 针对目标任务微调 BERT

实现的方法包括长文本预处理、层的选择、层特定的学习速率调整、遗忘和少量学习。

XLNet

前述基于变换器的模型利用自动编码(AE)公式,而不是传统的自回归(AR)语言建模。由于 AE 模型不像 AR 模型那样分解正向产品中的概率,因此它们可以利用两个方向的上下文。因此,缩小了语言建模和实际下游任务之间的差距,后者通常需要双向信息。然而,由于真实数据中缺少【MASK】记号,这导致了预训练和微调之间的差异。此外,BERT 假设预测的记号是彼此独立的,这是过于简化的。

鉴于 AR 和 AE 语言模型的优缺点,XLNet被提出来利用它们的优点,同时最小化它们的局限性。与 AR 模型中使用固定的向前或向后因子分解不同,作者建议最大化因子分解顺序中每个可能排列的可能性。

因为相同的参数集用于所有排列,所以模型将总是能够访问全局环境。因此,它通过提取双向信息超越了传统的 AR 模型。此外,由于没有从损坏的数据重建,它避免了训练前微调差异的问题,以及独立性假设。值得注意的是,应用位置编码是为了保持原始序列顺序。置换只能通过在因式分解顺序中的后续标记上使用注意掩码来实现。

然而,所提出的公式导致变压器模型中两个矛盾的要求:

  1. 当在时间步长 t 进行预测时,隐藏表示 h(t) 应该只包含位置信息,而不包含内容信息
  2. 当在大于 t 的时间步长进行预测时, h(t) 包括令牌 t 的位置和内容

为了解决这个问题,使用了两个独立的流,即内容和查询表示。在计算上,查询流是可训练的,并且内容流用相应的单词嵌入来初始化。

大量的排列导致模型的训练收敛缓慢。因此,作者选择只预测因子分解顺序的最后一段。这样,由于不需要为前导记号计算查询表示,所以节省了速度和存储器。

那么,像 BERT 这样的深度学习模型到底能不能理解语言?Neptune 博客上的这篇文章描述了我们应该从三个方面来理解 NLP

  • 概念界限
  • 技术限制
  • 评估限制

对 NLP 演示感兴趣吗?使用 TensorFlow.js 查看关于文本相似性的现场演示:

[## 使用 TensorFlow.js 通用句子编码器的文本相似性

从学者到构建相似句子分组网络应用的旅程

towardsdatascience.com](/how-to-build-a-textual-similarity-analysis-web-app-aa3139d4fb71)

最先进的 python 项目设置

原文:https://towardsdatascience.com/state-of-the-art-python-project-setup-82a046fc1f20?source=collection_archive---------14-----------------------

为您的下一个 python 项目提供有见解的设置指南

Python 是发展最快的编程语言之一。它的工具正在快速发展以迎头赶上。我写 python 已经超过 10 年了,有时很难跟上所有的新工具。最近,我有机会(也有时间)评估其中一些新工具,这个领域的活动给我留下了深刻的印象。以下是我目前(2020 年 6 月)理想的 python 项目设置。

https://xkcd.com/1987/

依赖管理: pipenv

python 中的依赖管理非常困难和复杂。过去,我曾使用 pip-tools 和 virtualenv 来管理(非常不成功)各种项目的依赖和 env。Pipenv 彻底改变了开发体验。它以更优雅的方式解决了这些问题。Pipenv 将 virtualenv 和依赖关系管理结合到一个简单易用的工具中。您基本上为每个 pipfile 获得了一个自动化的 virtualenv,同时也为确定性构建获得了一个锁文件。Pipenv 还提供了额外的安全性,因为它使用哈希来检查锁定的依赖关系。尽管一些基本的操作,比如添加和安装一个新的库非常慢,但是这些操作很少发生,所以它仍然比其他任何方法都好。

更新:结账诗词也是 pipenv 的改进版。

棉绒:薄片 8-黑色 + 或其他

Flake8 是最受欢迎的蟒蛇皮, black 是最固执己见且简单易用的蟒蛇皮。黑 linter 真的很好,真的是一个基本的蟒蛇林挺好。black 中缺少的两个特性是导入排序和查找未使用的导入/变量。Isort 解决了前者,flake8-black 解决了后者。这些工具提供了非常简单的 CLI 工具来自动修复大多数问题,这使得遵守 linter 规则变得非常容易。虽然我真的希望有一个工具可以将这三者结合起来。

静态类型检查器: mypy

Mypy 是最常见和最广泛使用的 python 静态类型检查器。尽管确保 python 代码定义了正确的类型是一项不小的工作,但这是完全值得的。该工具提供了许多选项来打开和关闭各种不同类型的检查。我真正欣赏的一点是只在任何新代码上运行检查器的选项,这使得将它添加到现有的 repo 并在项目中增量添加类型成为可能。

测试: pytest

这不应该是一个惊喜。Pytest 是最受欢迎的 python 测试框架,拥有超过 6000 个 github stars。Pytest 提供了更简单的接口和更少的样板代码。它速度快,稳定,功能丰富。

代码覆盖率:覆盖率

Coverage 是最常见的 python 覆盖工具,拥有超过 1000 颗 github 星。它与 pytest 配合得很好,并且可以选择仅对项目中任何新编写的代码执行覆盖率阈值。因此,在您现有的 python 项目中稳定地开始实施测试覆盖变得很容易。我在实施代码覆盖方面的唯一问题是,该工具只是以状态代码 2 退出,而没有打印任何可用的错误消息,这使得调试 CI 构建失败的原因变得非常混乱。

IDE: VSCode

这可能是最有争议的选择。紧随其后的是 Jetbrains 的 Pycharm。我两者都用过,最近转向了 VSCode,主要是因为它是免费的,并且有一组令人惊讶的扩展。您可以轻松地在 VSCode 中设置上述所有工具,并通过提交 git 中的设置与团队的其他成员共享这些工具(示例)。VSCode 还使得跨多种语言工作变得容易。Pycharm 不错,但是界面感觉有点笨重,过时,速度慢。此外,由于 jetbrains 试图为每种语言销售不同的编辑器,他们在 pycharm 中为其他语言提供的扩展无法提供与 VSCode 相同的无缝体验。迫不及待想试试 VSCode 和 github 一直在做的在线编辑器。

虽然我对上面的设置很满意,但有一件事我觉得还是有点乱:配置文件。Python 工具现在围绕着使用哪种配置文件格式而分散开来。似乎新的工具正在标准化。toml 配置文件,但现在我的 black、isort 和 coverage 配置在 pyproject.toml 中,flake8 配置在 setup.cfg 中,mypy 设置在 mypy.ini 中。如果我能把所有这些配置放在一个文件中就好了,我可以把它复制粘贴到我所有的项目中。

这里( link )是一个简单的库,上面所有的设置都是在这里配置的。请签出 makefile 并。github/workflows/unit _ tests . YAML 来检查我如何设置 CI。

机器学习和人工智能*行业的现状

原文:https://towardsdatascience.com/state-of-the-machine-learning-ai-industry-9bb477f840c8?source=collection_archive---------35-----------------------

在企业中大规模采用机器学习:ML 平台和 AutoML 【第一部分】

多少 ML 型号才算太多型号

TL;博士:

一般来说,企业和公司,甚至初创公司,都在努力运营和 生产 机器学习模型。

ML 模型封装了模式、规则和知识,实现了业务流程的自动化和优化。它们是数据驱动的应用和 AI*服务的重要组成部分,改善并经常取代传统的基于规则的业务流程,提高生产力和成果。

MLSEV 机器学习学校—slide deckhttps://www . slide share . net/ed slide/Machine-Learning-platformization-automl-adopting-ml-at-scale-in-the-enterprise

从 2012 年到 2018 年,蓝筹技术公司实施了定制的内部使用的 ML 平台(即脸书的 FBLearning、优步的米开朗基罗、Twitter 的 Cortex、AirBnB 的 BigHead),其中许多平台主要基于开源包,并针对各自公司的特定用例进行了深度定制。

从那时起,行业内出现了企业级 ML 平台解决方案的强劲发展,包括来自现有供应商的解决方案(如亚马逊 Sagemaker、微软 Azure ML、谷歌云 ML 等)和该领域的挑战者(如 DataRobot、H2O、BigML、Dataiku)。现任供应商遵循增量战略方法,他们的 ML 服务产品位于现有云服务之上,作为另一个应用层,而不是挑战者采用的 ML 原生方法。

随着 ML 采用率的增加,许多企业正在迅速转向现成的数据科学&机器学习平台,以加快上市时间、降低运营成本并提高成功率(部署和运营的 ML 模型数量)。

鉴于目前的 ML 项目中只有一小部分,POC(概念证明)和模型达到生产和有意义的 ROI,ML 平台和 AutoML ( 自动化机器学习)正在成为增加 ML 模型快速原型和用例验证( ROI 验证)的首选工具。

结论:

  1. 尽管付出了巨大且不断增长的努力,包括过去几年公司对 ML 项目和计划的投资,只有一小部分 ML 模型进入生产并交付切实的成果。那些在许多情况下被证明是有利可图或非常有利可图的。在规模上, Pareto 原则适用于 20%的 ML 计划占 80%的收益,而许多 PoC 项目被放弃或冻结以待以后改进。
    【市场更新:连线,文章-11 月-2020 年公司都在争相使用人工智能——但很少有回报’】*
  2. 证据表明,市场正在接近一个转折点,越来越多的公司倾向于购买(而不是构建)ML 平台和工具,考虑现成的供应商解决方案或混合方法而不是开源
  3. AutoML,以及 API,是 ML 平台不可或缺的组成部分,以提高快速模型原型、ML 用例验证和部署能力。基本原理是通过增加 ML 候选用例的数量和成功率(在生产中部署的 ML 模型)来实现更好的 ROI(投资回报)。
  4. 数据(数量和质量— ML 就绪)、ML 技术债务、MLOps vs DevOps 以及企业 ML 流程和技能仍然是采用的主要障碍。尽管如此,传统的 ML 正在迅速超越炒作周期的顶峰,预计在企业中的主流采用只有 2-3 年的时间。
  5. 未来发展:除了深度学习,在未来十年,人工智能平台有望逐步融入知识表示、推理、规划和优化功能,为实现强大的人工智能铺平道路。

免责声明:本文中的术语 AI (人工智能)特指构建机器学习驱动的应用程序的能力,这些应用程序最终自动化和/或优化业务流程不应与正式意义上的健壮或强大的人工智能相混淆,“至少在这十年和/或下一年不太可能发生的事情”(作者强调)

摘要

幻灯片在此视频 45 分钟在此

【1】释义&上下文【第一部分:本帖】

机器学习平台定义 ML 模型和应用程序是企业中的一级资产 ML 应用程序的工作流程 ML 算法概述 ML 平台的架构 ML 宣传周期的更新

【2】规模采用 ML

机器学习的问题 ML 系统中的技术债务多少个模型是过多的模型对 ML 平台的需求

[3]ML 平台的市场

ML 平台市场参考早期采用者定制构建与购买:投资回报率和技术债务 ML 平台供应商格局

[4]定制构建的 ML 平台

ML 平台市场参考—近距离观察脸书— FBlearner 优步—米开朗基罗 AirBnB—BigHead ML 平台化成为主流

[5]从 DevOps 到 mlop

devo PS<>ModelOps ML 平台驱动型组织领导力&问责制

[6]自动化 ML — AutoML

扩展 ML —快速原型制作和 AutoML 供应商比较 AutoML: OptiML

[7]ML 平台的未来发展

超越深度学习:知识表示、推理、规划和优化

1.定义和背景

T 这里的东西并不是作为一个独特的 ML 平台,产品或者服务。该行业仍然非常分散,术语“ML 平台”、“数据科学平台”或“AI*平台”多次互换使用。

然而,市场上不同的产品和服务有一些共同之处,总结如下:

ML 平台提供了构建 ML 解决方案(主要是预测性和规范性模型)所必需的高级功能。

ML 平台支持将这些解决方案整合到业务流程、基础设施、产品和应用中。

它支持不同技能的数据科学家(和其他利益相关者,如 ML 工程师、数据分析师和业务分析师/专家)在数据和分析管道中完成多项任务,包括以下所有领域:

ML 工作流—资源分配百分比

数据摄取数据准备和转换数据探索和可视化

特征工程

型号选择、评估和测试(以及 AutoML)

部署

监控和解释

维护和协作

作为工具、系统和服务的组合,ML 平台使实验和快速原型成为可能,但它们的 ROI 是在企业运营和业务流程的背景下实现的,远远超出了实验。

参考资料:

Poul Petersen,剖析一个端到端的 ml 应用程序https://www . slide share . net/bigml/ML sev-剖析一个 ML 应用程序

ML 平台研究报告 Papis.io

面向 ML & AI 的企业采用框架*

T 鉴于其在企业中的影响和投资回报率,ML 平台&工具及其产品、ML 模型和数据驱动的应用程序可被视为一流的企业资产。

麦肯锡的全球人工智能调查概述了人工智能*的企业自我报告影响及其优势。

然而,这不仅仅是技术的问题。流程、优先级和人员(领导和责任)在加入和成功部署 ML 驱动的应用和服务中也扮演着不可或缺的角色。

当涉及到 ML 应用程序时,不仅软件开发是不同的,将它们部署和集成到现有系统中也被证明是一个主要的挑战。考虑到 ML 软件开发中的许多差异(更多细节在第 5 节),DevOps 无法充分处理 MLOps(机器学习操作)。

ML 算法

对于数据科学家和领域专家来说,管理 ML 算法以及支持它们的计算和数据转换需求无疑是 ML 平台要解决的关键任务。快速试验并对给定数据集应用不同算法的能力是验证任何用例(假设验证)的关键。

Precisely AutoML(自动机器学习)为这一过程提供了进一步的自动化,使用不同的算法创建许多候选模型,并评估它们的性能,以向给定的预测目标提出最佳模型选项。

ML 算法——监督和非监督(由 BigML 公司提供的#MLSEV)

在实践中,企业中的绝大多数 ML 用例(想想营销、金融、人力资源、制造等)不需要深度学习或神经网络算法,除非有非凡的性能要求,或者在需要处理非结构化数据(例如视频、图像或声音)的特定用例中。

几乎 80–90%的用例利用传统的 ML 算法,如线性回归、逻辑回归、随机森林或集成,与更不透明的神经网络方法相比,它们提供了可靠的结果和进一步的可解释性。

Kaggle 的调查包括近 2 万名受访者(数据科学家是重要的一部分),是监控算法使用的良好代理:

蓝框:传统的 ML 算法-红框:CNN,RNN,DNN 和贝叶斯-来源:Kaggle 数据科学和 ML 2019 年的状态

参考资料:

Kaggle 的数据科学和 ML 现状调查【https://www.kaggle.com/kaggle-survey-2019

麦肯锡— 分析时代

ML 平台架构

或者定制的 ML 平台,开源包和技术是首选(例如优步的例子: HDFSSparkSamzaCassandraMLLibXGBoostTensorFlow ),决定了底层架构的大部分。

要解决的用例以及需要多少实时和静态数据建模是形成平台架构的其他因素。优步服务公司的实时需求(如预测乘车时间)不同于 AirBnB(如推荐者),在访问、处理数据要求和预计预测时间方面与 FICO(如信用评分)也有很大不同,因此具有非常独特的架构需求。

优步的 ML 平台—米开朗基罗,来源:优步工程https://eng . Uber . com/米开朗基罗-机器学习-平台/

例如,在优步的情况下,在线部署的模型无法访问存储在 HDFS 的数据,这使得很难从在线生产数据库中检索关键功能(例如,查询 UberEATS 订单服务以计算特定时间段内餐馆的平均用餐准备时间)。

优步的解决方案是预先计算并在 Cassandra 中存储那些所需的功能,以便满足预测时的延迟要求(来源:优步工程-米开朗基罗https://eng . Uber . com/米开朗基罗-机器学习-平台/ )。

C 商业 ML 平台,与定制的开源平台相反,旨在概括大量不同的 ML 问题和用例。他们的架构需要支持关键功能,同时允许通过抽象层进行充分的定制:

  1. 基础架构(云、混合和本地)的自动部署和自动扩展—分布式
  2. API — RESTful ML 服务—编程 API 化和集成
  3. 高级功能工程— DSL**
  4. 算法和模型的程序化使用
  5. ML 工作流的程序自动化定制— DSL
  6. 前端:可视化和界面
  7. 开发工具:绑定(Python,R,Java,C),库,CLI 工具

** DSL 域特定语言

ML 平台架构概述(BigML 公司提供)

使用 DSL 的 API 和编程自动化— 领域特定语言 —保证了一篇衍生文章。特别是 AutoML,将在本系列文章的第 7 节中讨论。

DSL 在 API 和计算基础设施之上提供了必要的抽象层次,以处理复杂性、自动化和定制。DSL 方法的例子有优步的用于特性选择和转换的 DSL(优步的 ML 平台—米开朗基罗)和 BigML 的用于 ML 工作流自动化的 DSL(whiz ML)。

参考资料:

优步工程-米开朗基罗https://eng . Uber . com/米开朗基罗-机器学习-平台/

Arxiv:关于机器学习和大数据的 DSL 的调查https://arxiv.org/pdf/1602.07637

PAPIS.io 会议录:机器学习 API 的过去、现在和未来http://proceedings.mlr.press/v50/cetinsoy15.pdf

用于 ML 工作流自动化的 DSL【https://bigml.com/whizzml

机器学习炒作周期的更新

随着企业和从业者走过在实践中应用 ML 的学习曲线,机器学习和深度学习作为技术都经历并超越了炒作周期的顶峰,迅速穿越了“幻灭之谷”(调整预期)。Gartner 的最新炒作周期报告反映了这一点,并预测主流采用将在未来 2-3 年内发生。

来源:Gartner 对 DS 和 ML 2019 的炒作周期

紧随其后,新的人工智能平台的功能,如 AutoML,MLOps,可解释的人工智能或强化学习,目前正在进入炒作曲线,迅速成为炒作。这些新的 ML 技术仍然不成熟,还没有准备好被主流或大规模采用。

造 vs 买

几年前,市场已经被分为开源和行业解决方案。

从 2012 年到 2018 年,蓝筹技术公司实施了定制的 ML 平台供内部使用(即脸书的 FBLearning、优步的米开朗基罗、Twitter 的 Cortex、AirBnB 的 BigHead,稍后在第 4 节中有更详细的分析)。

这些平台中有许多主要基于开源包,并针对这些公司的特定用例进行了深度定制。

尽管开源软件包固有的免费性质(购买的成本优势)和几乎无限的定制能力,但是开源的问题伴随着相关的隐藏技术债务,特别是胶水代码(更多细节见第 2 节机器学习系统中的隐藏技术债务)。 D. Sculley 等人,谷歌,NIPS 2015)。

D .斯卡利等人,谷歌,NIPS 2015

从长远来看,正是配置、协调和整合不同开源包(胶合代码)的成本增加了成本,使得构建与购买的商业案例对行业解决方案更具吸引力。

该行业已经看到了企业级 ML 平台解决方案和 MLaaS(机器学习即服务或云 ML 服务)的强劲发展,现在该产品分为行业现任者(如亚马逊 Sagemaker、微软 Azure ML、谷歌云 ML 等)和挑战者(DataRobot、H2O、BigML、Dataiku 等)。

对许多企业来说,一个重要的关键驱动因素是上市时间和竞争力。由于他们难以通过传统的构建研发方法成功地扩展和获得足够多的 ML 模型,许多人迅速转向现成的数据科学&机器学习平台,以加速上市,降低运营成本并提高成功率(部署和运营的 ML 模型的数量)。

参考资料:

机器学习系统中隐藏的技术债务。 D. Sculley 等人,谷歌,NIPS 2015https://papers . NIPS . cc/paper/5656-hidden-technical-debt-in-machine-learning-systems . pdf

Gartner 的人工智能炒作周期https://www . Gartner . com/smarterwithgartner/top-trends-on-the-Gartner-Hype-Cycle-for-artificial-intelligence-2019/

【第一节结束】

这篇文章的配套幻灯片可以通过这个链接获得[ 在机器学习学校#MLSEV 的演讲—3 月 26 日 ]

关于作者:

推特

状态、行动、奖励——强化学习背后的直觉

原文:https://towardsdatascience.com/states-actions-rewards-the-intuition-behind-reinforcement-learning-33d4aa2bbfaa?source=collection_archive---------9-----------------------

强化学习到底是什么,RL 算法在实践中是如何工作的?

2014 年,谷歌以 5 亿美元收购了一家名为 DeepMind 的英国初创公司。这是一个很高的价格,但仅从 DeepMind 产生的宣传效果来看,这项投资似乎已经获得了数倍的回报。ML 的研究人员知道 DeepMind 是因为它在深度强化学习领域的频繁突破。但该公司也吸引了公众的注意力,特别是由于它成功地构建了一种玩围棋的算法。考虑到 DeepMind 在该领域取得进展的频率——alpha go、AlphaGo Zero 和 AlphaZero 在过去几年中的进展——无论是从技术层面还是从影响的角度来看,都很难跟踪到底发生了什么。我打算这么做——提供 DeepMind 在围棋上的成功的高层次观点,并解释他们生产的不同版本的 AlphaGo 之间的区别。

RL 是什么?

与人类认知相比,机器学习是一个成熟的领域。这当然不是巧合。该领域中许多最受欢迎的任务(视觉、语音和自然语言处理)通常属于人类(或自然)智能的领域。由于算法“所做的”是模拟人类,因此自然会想到算法也“如何”模拟人类。因此,像“神经网络是由人脑启发的”这样的说法比比皆是(事实上,这种说法就像“飞机是由鸟启发的”一样正确)

强化学习特别适合这种比较。就其核心而言,任何强化学习任务都是由三个因素定义的——状态、行动和奖励。状态是任务的当前世界或环境的表示。动作是 RL 代理可以用来改变这些状态的事情。奖励是代理人因执行“正确的”行动而获得的效用。因此,状态会告诉代理当前所处的情况,而奖励会向代理发出信号,表明它应该向哪个状态努力。那么,我们的目标是学习一种“政策”,它会告诉你在每种状态下应该采取什么行动,以尽量获得最大回报。这个宽泛的定义可以用来适应我们每天执行的许多不同的任务。

当你开车时,状态是你的车和邻近车的位置和速度。你可以采取的行动是转动方向盘,踩油门或刹车。奖励取决于你在遵守交通规则的情况下多快到达目的地。

当你玩视频游戏(比如说《塞尔达传说》)时,状态就是你在屏幕上的任何信息——你的位置、附近角色或怪物的存在、你拥有的武器和物品。你的行动可以包括移动或攻击。您的奖励取决于您剩余的生命数量以及您从击败敌人中获得的任何金钱或物品。

塞尔达传说游戏状态。资料来源:Deepak Dilipkumar

让我们看一个更抽象的例子——申请研究生院。你所在的州是你目前的研究/工作概况,以及你拥有的关于不同学校的课程和教授的信息。你的行动可能是决定向谁要推荐信,在你的 SoP 上写什么,以及申请哪所学校。奖励当然是一封录取信(或者由于一封拒绝信而产生的负奖励)。

这些例子表明,从强化学习的角度来看,在不同的“具体性”水平上构建无数的任务通常是可能的。然而,重要的是要注意,对于不同的任务,状态、动作和奖励集的范围可能非常不同。例如,塞尔达游戏中的动作场景虽然很广泛,但显然比申请研究生院的动作场景要小一个数量级。这表明,当你已经清楚地定义了状态、奖励和受限的动作集时,将任务框架化为强化学习效果很好。这可以从 RL 成功完成的类任务中看出。

解决 RL 任务

解决 RL 任务的一种常见方法叫做“基于价值”。我们试图根据哪些状态可能带来高回报,给每个状态(或每个(状态,下一个行动)对)分配一个数字。这种将每个状态与特定数值联系起来的实体称为价值函数。如果我们以这种方式学习一个适当的值函数,那么从一个特定的状态,我们可以简单地选择很可能导致下一个高值状态的动作。所以我们现在把我们的任务简化为学习这个价值函数的问题。

为了理解这个学习过程可能是什么样子,让我们看一个更具体的例子——井字游戏。状态是当前的棋盘位置,动作是你可以放置“X”或“O”的不同位置,奖励是+1 或-1,取决于你是赢还是输。“状态空间”是特定 RL 设置中可能状态的总数。井字游戏有一个足够小的状态空间(一个合理的估计是 593 ),我们实际上可以使用一个表格记住每个状态的值。因此,这种方法被称为列表法。这在大多数应用程序中是不实际的(想象一下列出一个棋盘的所有可能的配置并给每个配置赋值),但是我稍后将回到如何处理这个问题。

我们首先给每个状态分配一些初始值,比如说所有状态都是 0(有更好的初始化策略,但是现在这样就可以了)。最初,我们的表格看起来是这样的(假设我们有一些对州进行编号或索引的方法):

然后,我们开始与对手玩井字游戏,我们遵循的一般规则是,在当前状态下采取的行动是导致下一个状态的行动,下一个状态的价值尽可能高。一开始,由于所有的州都有相同的价值,这就意味着只是从合法的行动中随机挑选。但是在几场比赛之后,你注意到当你到达这个位置(你是 X)时:

你得到+1 的奖励。那么与最终状态相关联的值必须是+1。因此,您更新了您的表(假设最终获胜位置的任意指数为 123):

现在,在接下来的几场比赛中,你看到你带领你到 123 的位置(假设这两个位置分别是 121 和 122)也有可能以高回报结束,只要你采取正确的行动:

因此,您再次更新了表格,注意到倒数第二个状态不一定有+1 的全部奖励,因为仍有可能走错一步,最终输掉或听成平局:

我不会进入实际的方程式,但是在一个高层次上,我们看到回报是一种从最终状态“流”回来的东西,并给最终状态赋予一个具体的值。因此,这些终端状态对于确保算法学习正确的值函数极其重要。我曾经有一个 bug,除了指示这些终端状态的标志之外,一切都按预期工作,算法最终几乎什么也没学到。

因此,如果有足够多的训练游戏,奖励会一直流回到最初的状态,并且你从头到尾都有一个好的策略!例如,进行这种“自举”的一种常见方式,即从紧随其后的状态的值中学习一个状态的值,称为时间差异学习

延伸到国际象棋

比如说,这种策略在国际象棋中的效果如何?井字游戏有大约 600 个州。虽然很难计算国际象棋中状态的准确数量,但一个很好的上限似乎是 10⁴⁵ 。世界上所有的计算机都没有足够的内存来存储这么多的状态,所以将所有的值放在一个表中不再是一个好主意。我们如何处理这个问题?

让我们想想我们下棋。随着我们练习得越来越多,我们开始对某些状态有多“好”有了直观的理解。例如,尝试评估这种状态(白棋):

谁赢了?来源:chess.com

你可能知道白棋的位置更好。很可能你以前从未见过这种确切的董事会状态。尽管如此,你已经对象棋中什么构成了一种状态的“善”建立了直觉。你可能数了每一方剩下的棋子数,并注意到黑方有 2 个额外的棋子,而白方有一个额外的骑士和车,这给了那一方优势。如果你是一个更有经验的玩家,你可能已经看到了可能的下一步棋(比如白象可以拿下黑象)和双方控制的棋盘区域。

所以你肯定没有记住每一个可能的棋位的潜在价值——你已经学会了某种通用函数,将棋盘的状态映射到每个玩家的游戏价值。这正是我们希望 RL 的智能象棋算法通过一个叫做价值函数逼近的想法来做的。

首先,我们想出一种方法来表示游戏状态。对于井字游戏,我们可以枚举所有的状态,这意味着每个游戏状态都由一个数字表示。对于国际象棋,一个简单的方法是用一个数字(棋子→ 1,车→ 2 …)表示每一个棋子,然后有一个长度为 64 的列表,该列表编码每个位置上特定棋子的存在(比如说,0 表示空位置)。我们可以将它输入到我们的 RL 算法已经学习的价值函数中,它会吐出一个数字(代表“价值”)或者可能是一个概率(代表黑棋获胜的机会)。

现在实际的 RL 部分非常类似于我们对井字游戏所做的。我们玩了很多游戏,赢了就奖励算法,输了就惩罚算法,随着时间的推移,它将(希望)学习一个代表州值的好函数。唯一的变化是,我们不是从表中查找值,而是通过函数传递输入,并获得相应的值作为输出。有了这个,我们就可以通过观察每一个可能的合法走法所达到的状态来推导出一个下棋的策略,并通过我们的函数传递这些状态中的每一个,以查看哪一个具有最高的值!

这是用 RL 解决国际象棋问题的一种相当幼稚的方式,我们可以用一些复杂的想法来加速计算,改善学习,并最终做出更好的棋。这对于围棋来说尤其重要,因为围棋的状态空间比国际象棋还要大!这可能需要很长时间才能理解,所以我将在这里停下来,在下一篇博客文章中讨论一些关于 Go 的有趣想法。感谢阅读!

原载于 2018 年 3 月 3 日https://deepakdilipkumar . github . io

Python 的静态代码分析

原文:https://towardsdatascience.com/static-code-analysis-for-python-bdce10b8d287?source=collection_archive---------6-----------------------

类型和样式检查、潜在的错误和代码复杂性

图片来自维基共享资源

静态代码分析查看代码而不执行它。它通常执行起来非常快,只需要很少的努力就可以添加到您的工作流程中,并且可以发现常见的错误。唯一的缺点是它不是为您的代码量身定制的。

在本文中,您将学习如何在 Python 中执行各种类型的静态代码分析。虽然本文主要关注 Python,但是任何编程语言都可以进行这种类型的分析。

代码复杂性

约翰·巴克利普在 Unsplash 上的照片

测量代码复杂度的一种方法是圈复杂度,也称为 McCabe 复杂度,定义见 A 复杂度测量:

CC = E - N + 2*P

其中 N 是控制流图中的节点数,E 是边数,P 是条件节点数(if 语句,while/for 循环)。

可以用 radon 在 Python 中计算:

$ pip install radon
$ radon cc mpu/aws.py -s    
mpu/aws.py
    F 85:0 s3_download - B (6)
    F 16:0 list_files - A (3)
    F 165:0 _s3_path_split - A (2)
    F 46:0 s3_read - A (1)
    F 141:0 s3_upload - A (1)
    C 77:0 ExistsStrategy - A (1)

第一个字母表示块的类型(F 表示函数,C 表示类)。然后 radon 给出了行号,类/函数的名称,一个等级** (A、B、C、D、E 或 F),以及实际的复杂度作为一个数字。通常,复杂度低于 10 是可以的。scipy 最复杂的部分复杂度为 61。**

除了 radon,还有各种其他的包和 Flake8 插件:

  • flake 8-注解-复杂性:轻推你命名复杂类型
  • flake 8-认知复杂性:验证认知功能的复杂性
  • flake 8-expression-complexity:确保单个表达式不会太复杂;类似于函数/类的圈复杂度。
  • flake8-functions :报告过长的函数和带有过多参数的函数
  • mccabe :这被一些其他的工具和项目使用
  • wily :跟踪、报告 Python 测试和应用程序复杂性的命令行应用程序。
  • :依靠氡

风格指南

让你的代码看起来更专业。猎人在 Unsplash 上比赛的照片

你可能听说过“pythonic 代码”这个词。这意味着不仅要编写正确的 Python 代码,而且要按照预期的方式使用语言特性(来源)。这肯定是一个固执己见的术语,但是有很多插件向您展示了社区中的大部分人认为 pythonic 是什么。

以类似于其他 Python 项目的风格编写代码是有价值的,因为人们会更容易阅读代码。这一点很重要,因为我们阅读软件的次数比编写软件的次数还要多。

那么,什么是 pythonic 代码呢?

先从 PEP-8 说起:它是 Python 社区在 2001 年编写并接受的一个风格指南。所以它已经存在了一段时间,大多数人都想跟随它。我见过大多数人不同意的主要部分是 79 的最大线长。我总是建议在你 95%的代码库中遵循这个建议。对此我给出了理由

黑人项目的标志。图片来源:黑人投稿人

对于纯代码格式化,您应该使用自动格式化程序。我开始喜欢黑色的因为它不允许定制。黑色格式的代码看起来总是一样的。由于您不能自定义它,所以您不需要讨论它。它只是解决了风格冲突和争论的问题。Black 由 Python 软件基金会维护,可能是 Python 最常采用的自动格式化程序。

Google 的 yapf 是另一个自动格式化程序。

文档字符串

如果写得好,阅读手册会很有趣。千层面烤肉卷有很好的文档。劳拉·德维尔德在 Unsplash 上拍摄的照片

对于文档字符串,有 PEP-257 。所有这些规则在社区中都被广泛接受,但是它们仍然允许各种各样的文档字符串。有三种常用的样式:

  • NumpyDoc 风格文档字符串:由 Numpy 和 Scipy 使用。它以固定的顺序对某些指定的部分如ParametersReturns进行降价。
  • Google 风格 docstrings:一种超薄格式,有Args:Returns:
  • 文档字符串:一种非常灵活的格式,使用重构的文本。

我喜欢 NumpyDoc 格式,因为它非常容易阅读,即使你只是在文本编辑器中使用它。Numpydoc 也得到了编辑器的良好支持。

这里你可以看到三者的对比:

def **get_meta_numpydoc**(filepath, a_number, a_dict):
    """
    Get meta-information of an image. Lorem ipsum dolor sit amet, consectetuer adipiscing elit.
    Aenean commodo
    ligula eget dolor. Aenean massa. Cum sociis natoque penatibus
    et magnis dis
    parturient montes, nascetur ridiculus mus. Parameters
    ----------
    filepath : str
        Get metadata from this file
    a_number : int
        Some more details
    a_dict : dict
        Configuration Returns
    -------
    meta : dict
        Extracted meta information Raises
    ------
    IOError
        File could not be read
    """def **get_meta_google_doc**(filepath, a_number, a_dict):
    """Get meta-information of an image. Lorem ipsum dolor sit amet, consectetuer adipiscing elit.
    Aenean commodo
    ligula eget dolor. Aenean massa. Cum sociis natoque penatibus
    et magnis dis
    parturient montes, nascetur ridiculus mus. Args:
        filepath: Get metadata from this file.
        a_number: Some more details.
        a_dict: Configuration. Returns:
        Extracted meta information: Raises:
        IOError: File could not be read.
    """

def **get_meta_sphinx_doc**(filepath, a_number, a_dict):
    """
    Get meta-information of an image. Lorem ipsum dolor sit amet, consectetuer adipiscing elit.
    Aenean commodo
    ligula eget dolor. Aenean massa. Cum sociis natoque penatibus
    et magnis dis
    parturient montes, nascetur ridiculus mus. :param filepath: Get metadata from this file
    :type filepath: str
    :param a_number: Some more details
    :type a_number: int
    :param a_dict: Configuration
    :type a_dict: dict :returns: dict -- Extracted meta information :raises: IOError
    """

薄片 8

正如阿尔贝托·吉梅诺指出的那样,你应该一直使用棉绒。他们可以检查你的风格,但更重要的是,指出潜在的错误。

是一个包装 PyFlakes、pycodestyle 和 McCabe 脚本的包装器。这是 Python 中林挺最常用的工具。Flake8 太棒了,因为它有太多的插件。我找到了 223 个名称中带有字符串“flake8”的包,并查看了其中的许多包。我还用 trove 分类器Framework :: Flake8查看了包,发现了 143 个包,其中 122 个以flake8-开头。只有 21 个包有 Flake8 框架的 trove 分类器,但没有以flake8-开头,其中只有两个看起来很有趣。

边注:错别字抢注是每个开放包库都要与之斗争的问题(学士论文:编程语言包管理器中的错别字其中有的博文和一篇有趣的后续,学士论文:对包管理器的攻击)。Python 中有它造成伤害的例子( 201720172017201920192019 )。有 pypi-scan 用于查找示例,还有 pypi-parker 用于防止常见的错别字。William Bengtsson 也做了一些类似的事情来加强 Python 社区对这个线程的防范。有关他的项目的更多信息,请参见下面他的文章。package parking 列出了 PyPI 上的软件包数量,我通过查找摘要“防止漏洞利用的软件包”来过滤它们。

[## Python 域名抢注是为了娱乐而非盈利

威廉·本特森| @ _ _ 肌肉

medium.com](https://medium.com/@williambengtson/python-typosquatting-for-fun-not-profit-99869579c35d)

以下是一些有趣的 flake8 插件:

  • 内聚:检查类内聚是否低于阈值。这表明功能应该从一个类中分离出来。
  • flake8-assert-msg :确保 assert 语句有消息
  • flake8-blind-except :防止口袋妖怪异常捕捉
  • flake8-builtins :检查 python 内置的变量或参数。
  • flake8-docstrings :增加 pydocstyle 支持
  • flake8-isort :使用 isort 检查 python 文件上的导入是否按照您期望的方式排序
  • flake8-logging-format :验证(缺少)日志格式字符串
  • flake8-pytest-style :检查基于 pytest 的测试的常见风格问题或不一致之处
  • flake 8-需求:检查/验证包导入需求。它报告缺失和/或未使用的项目直接相关性
  • flake 8-graph QL:Lint graph QL 查询字符串
  • 与黑色搭配很好🎉
  • 模板 8-模拟:使用模拟来检查错误
  • 检查 jupyter 笔记本
  • flake8-pyi : Lint 存根文件
  • flake8-variables-names :查找常见的“无意义”的变量名
  • pep8 命名:对照 pep8 命名约定检查你的代码
  • 熊猫兽医:固执己见的林挺为熊猫编码
  • wemake-python-styleguide :一个固执己见的风格指南/检查器,看起来很受欢迎。不过,我以前没见过这个。

部分 Flake8 探矿者的替代品。它结合了多种工具,但是它很少被使用,因此不如 Flake8 灵活。

第八篇:安全性和缺陷

注意安全,注意警示标志。照片由特洛伊桥Unsplash 上拍摄

  • flake8-bandit :安全测试
  • 在你的程序中寻找可能的错误和设计问题——通常它是无声的,但是当它不是的时候你应该看一看🐻
  • flake8-requests :检查请求框架的使用

Flake8:删除调试工件

这种情况在我身上发生过好几次:我在开发新功能或调试旧功能时添加了一些代码,但后来忘记删除了。它经常被评论者发现,但是没有必要用这个来分散评论者的注意力。

flake8-breakpoint 检查忘记的断点,而 flake8-print 会抱怨每一条打印语句。flake 8-调试器flake8-fixmeflake8-todo 走向相同。

皮林特

[pylint](https://pypi.org/project/pylint/)是 Python 中分布最广的 linters 之一。pylint 的功能肯定与 Flake8 重叠,但有一个功能我很喜欢:检查代码重复❤

$ **pylint --disable=all --enable=duplicate-code .**
************* Module mpu.datastructures.trie.base
mpu/datastructures/trie/base.py:1:0: R0801: Similar lines in 2 files
==mpu.datastructures.trie.char_trie:85
==mpu.datastructures.trie.string_trie:138
            string += child.print(_indent=_indent + 1)
        return stringdef __str__(self):
        return f"TrieNode(value='{self._value}', nb_children='{len(self.children)}')"__repr__ = __str__EMPTY_NODE = TrieNode(value="", is_word=False, count=0, freeze=True)class Trie(AbstractTrie):
    def __init__(self, container=None):
        if container is None:
            container = [] (duplicate-code)

让死代码死去吧

肯尼·奥尔在 Unsplash拍摄的照片

谁没有做过:你删除了一个功能,但是代码可能是方便的。所以你把它注释掉。或者你在它周围加一个if False块。有时通过添加您不需要的配置选项会更复杂。

最简单解决方案是通过一个简单、明确的提交来删除该特性。也许可以添加一个 git 标签,这样以后想再添加的时候就可以找到了。

还有一种代码是死的,但是你忘记了。幸运的是,您可以自动检测到它:

  • flake 8-根除:查找注释掉的(或者所谓的“死的”)代码。
  • vulture :查找 Python 程序中未使用的代码

第八篇:鼓励自己使用好的风格

让一个有经验的开发人员审查你的代码是很棒的。在最好的情况下,你会学到一些新的东西,你可以在所有进一步的项目中应用。有些插件就是这样。由布鲁克·卡吉尔Unsplash 上拍摄的照片

一些插件帮助我学习了一些关于 Python 的知识。例如,以下内容帮助我消除了一些小错误和不一致之处:

  • 帮助你写出更好的理解清单/集合/字典——我喜欢这个😍
  • flake8-executable :检查可执行权限和 shebangs 。文件应该要么是可执行的,有一个标签,要么是不可执行的,没有标签。
  • flake8-raise :发现 raise 语句的改进
  • flake8-pytest :使用 assert 代替 assertEqual

以下新风格的轻推插件旨在推动您使用现代风格的 Python:

这对我来说是最有价值的类别之一。如果你知道更多有助于使用新风格的插件,请告诉我😃

Flake8 元插件

马丁·托马斯通过 imgflip.com 创造形象

Flake8 有一些插件没有增加更多的林挺功能,但以另一种方式改进了 flake8:

有些插件人们可能出于法律原因需要,比如 flake 8-作者、flake 8-版权和 flake 8-许可证。

致 Flake8 插件作者:请确保你列出了你的插件引入的错误代码,并且至少给出了一些你的插件认为不好/好的例子。

类型注释和类型检查

VS 代码的 mypy 插件显示了一个类型问题。马丁·托马斯截图。

在 Python 中是可以的,但是需要你去做。它不是自动完成的。我写了一篇更长的文章,介绍了 Python 中的类型注释是如何工作的。有多种工具可以使用,但我推荐 mypy。您可以使用pytest-mypy通过 pytest 运行它,或者使用flake8-mypy通过 flake8 运行它,但是我更喜欢单独运行它。其主要原因是由 CI 管道给出的输出更干净。

您可以将类型检查(例如通过 mypy)集成到您的编辑器中,但是类型注释本身已经走了很长的路,因为它们记录了预期的内容。

程序包结构

托运之前,请检查您的包裹是否完好无损。托比·斯托达特在 Unsplash 上的照片

pyroma 评估 Python 项目符合 Python 打包生态系统最佳实践的程度。

以下是我项目的一些例子:

$ pyroma mpu 
------------------------------
Checking mpu
Found mpu
------------------------------
Final rating: 10/10
Your cheese is so fresh most pe$ pyroma nox
------------------------------
Checking nox
Found nox
------------------------------
Your long_description is not valid ReST: 
<string>:2: (WARNING/2) Explicit markup ends without a blank line; unexpected unindent.
<string>:3: (WARNING/2) Field list ends without a blank line; unexpected unindent.
<string>:4: (WARNING/2) Explicit markup ends without a blank line; unexpected unindent.
------------------------------
Final rating: 9/10
Cottage Cheese
------------------------------

下一步是什么?

在这个系列中,我们已经有了:

如果您对使用 Python 测试的其他主题感兴趣,请告诉我。

S3 上使用 SSL 的静态托管

原文:https://towardsdatascience.com/static-hosting-with-ssl-on-s3-a4b66fb7cd00?source=collection_archive---------2-----------------------

Photo by 傅甬 华 on Unsplash

上个月,我花了大量时间搜索 AWS 文档,试图找出如何:

  • 主机静态内容…
  • …在 S3 桶里…
  • …使用自定义域名…
  • 和 SSL (HTTPS)连接。

鉴于像雨果杰基尔这样的静态站点生成器越来越受欢迎,这个看起来应该是一个简单的过程。

如果你在这里,你可能会发现这是而不是直截了当。你可能也从半打不同的 StackOverflow 问题和支离破碎的博客帖子中拼凑出了一个解决方案。所以:下面是我目前的剧本,关于如何在 AWS 上用 SSL 托管静态站点。

步骤 1:将域转移到 AWS / Route53

如果您打算从 S3 桶中提供静态内容,并且想要 SSL 支持,那么您将需要一个 CloudFront 发行版。(CloudFront 是亚马逊的 CDN 服务。)从技术上来说,你的域名注册并不一定要在亚马逊进行,这简化了几个步骤。因此,本行动手册的其余部分假设您能够并且愿意将您的域名转移到 AWS。

在 Route53 中转移域名→注册域名屏幕

从您的 AWS 控制台,前往 Route53 → Registered Domains,确认您的域名已经存在,或者点击 Transfer Domain 启动注册转移。【备选路径:在 Route53 中设置一个与您当前注册商的区域设置完全匹配的托管区域,并将域名服务器设置指向您的 Amazon 托管区域中NS记录中列出的服务器。]

步骤 2:创建自定义域 SSL 证书

太好了!您的自定义域已准备好“安全”接下来,您需要从 AWS 证书管理器请求一个证书(在控制台服务列表中找到它)。这相当快,而且免费:

  • 点击申请证书
  • 选择请求公共证书(您想要一个可以被外界使用的证书)
  • 域名编辑框中输入两条记录:yourdomain.com[www.yourdomain.com](http://www.yourdomain.com.)T25。我们将在两个独立的 CloudFront 发行版上使用这个证书。【替代路径:如果您有其他用于访问静态内容的子域,您当然会希望在这里输入这些子域。]
  • 选择 DNS 验证(这让证书管理器通过在 Route53 中自动生成记录来验证您对域的使用)
  • 如果您愿意,可以随意在证书中添加自定义标签。
  • 点击审核,然后确认并请求

发起证书请求后,您可以为每个证书路径向域的托管区域添加一个CNAME记录。或者,更简单的是,只需点击按钮,让 AWS 为您插入记录。

步骤 3:设置您的 S3 时段内容

当我们等待 SSL 证书生成时(这可能需要几分钟),我们可以前往 S3 并设置我们的存储桶。你需要两个水桶:

  • mydomain.com将包含您想要托管的所有静态内容;和
  • www.mydomain.com将流量重定向到mydomain.com

【备选路径:如果您希望从www.mydomain.com获得流量服务,只需翻转下面的说明。]

输入您的域名作为存储桶的名称

首先,创建您的内容 S3 存储桶(上例中的mydomain.com)。如果您愿意,可以使用您的域名作为 bucket 的名称,但是因为我们将在它前面放置一个 CloudFront 发行版,所以这不是一个技术要求。您不需要在 bucket 创建流程的下一个屏幕上配置任何特殊选项。

取消选中“阻止所有公共访问”以允许全世界访问您的内容

确保取消选中“阻止所有公共访问”,这样公共用户就可以看到您的内容。在几次由于开放的 S3 桶的安全设置不严而导致的公开(尴尬)数据泄露之后,亚马逊在这一步上提出了额外的警告和预防措施。然而,在这种情况下,你确实希望这些文件在互联网上到处泄露。

现在,为您的备用域名存储桶重复上述过程。此存储桶将用于将流量重定向到您的主域。

在将您的内容上传到您的主要静态托管桶之后,转到该桶的属性选项卡并编辑静态网站托管设置。您希望使用这个桶来托管一个网站,将索引文档设置为您的默认页面的文件名(例如index.html)。此时,您可以使用静态托管设置中的端点进行测试。

在 S3 存储桶属性选项卡中找到静态网站托管设置

配置 S3 桶来托管一个静态网站

您的 S3 存储桶的最终配置任务是进入托管您的备用域存储桶(例如www.mydomain.com)的属性的静态网站。您希望将请求重定向到您的主域,并将协议设置为https(假设您希望所有重定向流量都被路由到 SSL 连接)。

配置辅助 S3 桶,通过 HTTPS 将流量重定向到主桶

步骤 4:创建 CloudFront 发行版

现在,您的公共证书应该可以使用了。对于这个用例,云前端是 DNS 记录、SSL 证书和 S3 桶之间的连接组织:

所有这些看似不必要的复杂性的原因是,CloudFront 可以处理与自定义域的 SSL 连接,但 S3 不能。(也许,有一天,AWS 会着手构建一个更简单的解决方案,而这篇文章会让人觉得古怪。)

我们将使用两个独立的 CloudFront 发行版:一个专门处理mydomain.com,另一个处理www.mydomain.com。您可以只使用一个响应两个名称的发行版来完成解决方案,但是客户端流量将根据原始请求显示为来自mydomain.comwww.mydomain.com。在双 CF 配置中,对二级域名的请求将一直流向二级 S3 存储桶(www.*),然后被重定向到www-自由路径。

因此:在 CloudFront 中,创建一个 Web 发行版。配置面板中有设置:

  • 来源域名表示内容的来源(来源)应该是什么。通过选择控件,您将看到可用作原点的可用 S3 桶的列表。选择mydomain.com
  • 限制 Bucket 访问:如果启用,该选项要求所有公共流量通过 CloudFront 路由。这并不是 CloudFront 的全部内容,但是如果您想“锁定”您的 bucket 并保证页面总是显示在自定义域名下,那么您会想要使用它。
  • 查看器协议策略:设置为将 HTTP 重定向到 HTTPS 以强制所有连接使用 SSL。没有什么好的理由不这样做。
  • 允许的 HTTP 方法:指定您的站点需要哪些 HTTP 方法。对于我的大多数被动内容网站,默认的 GET,HEAD 设置是检索内容所需要的,但是如果你有 POST 表单,那么你需要调整这个设置。
  • 自动压缩对象:你想减少带宽吗?你当然知道!启用 gzip 压缩。
  • 备用域名 : 非常重要:必须在这里输入mydomain.comwww.mydomain.com,这取决于您正在设置的发行版。当客户端请求到达 Route53 并被路由到 CloudFront 进行分发时,CF 将验证请求的域是否在其域名列表中,以及证书是否与该域匹配。
  • SSL 证书:以上所有工作都归结于这一个设置。选择自定义 SSL 证书并选择您最近创建的 SSL 证书将其绑定到发行版。
  • 默认根对象:存储请求的默认页面,如果请求 URL 中没有包含页面。使用相同的index.html风格的设置,在你的 S3 桶设置中使用。

现在,您可以单击创建分发版,并在 CloudFront 将您的内容复制到边缘节点时,对您的第二个分发版(对于[www.mydomain.com](http://www.mydomain.com)) )) 重复这个练习。

步骤 5:更新域区域设置

在您的 CloudFront 发行版建立起来之后,剩下唯一要做的事情就是为mydomain.com更新 Route53 中的 DNS 设置:

  • mydomain.com.更新或创建一个A记录,它是mydomain.com.的 CloudFront 发行版的别名
  • www.mydomain.com更新或创建一个A记录,该记录与www.mydomain.com的分布有相似的别名。

派对时间

瞧啊。现在,您应该能够使用 HTTP 或 HTTPS 请求访问mydomain.comwww.mydomain.com,并在https://mydomain.com被路由到由 S3 存储桶提供的同一个页面。(作为奖励,你有一个 CDN 做后盾。)

根据您决定如何将新内容复制到您的 S3 存储桶,您将需要调整您的发布过程,包括在新的或修改的文件上传后使mydomain.com的 CloudFront 发行版无效。

动态世界中的静态机器学习模型

原文:https://towardsdatascience.com/static-machine-learning-models-in-a-dynamic-world-ff1ea1b0892c?source=collection_archive---------27-----------------------

历史数据正被用于未来将工作的模型。当世界不断变化时,我们的模型保持不变。

克里斯·劳顿在 Unsplash 上的照片

如果你在学术界或工业界工作,你就要解决现实生活中的问题。我们研究的数据不是合成的,它们来自真实世界的读数。在我们的办公室工作时,从与我们的项目、业务或挑战相关的真实事件中抽象出来;我们往往会与我们正在解决的问题失去联系。很容易将项目视为数字。静态数值、字符串和无意义的 id。我们用二进制存储它们,与现实世界脱节。在这种情况下,很容易忘记现实世界是动态的,数据也是如此。当我们忽视或天真地忘记这一现实,并专注于我们心爱的 KPI 时,问题就开始出现了。这个故事是关于我们的机器学习模型如何保持静态,而数据却随着动态世界的变化而每天变化。

在我之前工作的一家公司发生了一次事故后,我开始对我的模特的表现的连续性有点着迷。简而言之,我们的一个直接负责关键引擎输出的模型开始预测荒谬的结果。最糟糕的是,我们没有发现问题,直到我们接到客户愤怒的电话,花了很长时间调试整个管道,才找到根本原因。该模型输出极高或极低的预测值。回想起来,我们发现堆栈中没有故障组件。没有 bug,没有错误。上游数据引起的问题。从上游消耗的数据,真实世界的读数,已经改变了。

模型是由世界快照建立的

如果您没有采用某种在线学习方式,即模型定期更新,那么您将使用历史数据。您使用数据存储中的一些数据并训练您的模型。你经常这么做。你获取历史数据,通过管道传输,得到你的模型。这里的关键词是历史性的。您处理的是已经过时的数据。回顾过去的同时,你也在为未来构建解决方案。

有了这些数据,你实际上是在世界的快照上开发了你的解决方案。原始数据,真实世界的读数代表快照。这个快照可以是几周、几个月或几年。快照越长越好。尽管如此,这并不能保证未来会遵循您快照中的相同行为。

当世界改变时,模型就会失效

当您处理历史数据时,您就与您的模型签订了合同。您向您的模型保证数据的属性不会改变。作为交换,模型给你一个准确的历史描述。你依赖于你的 KPI。当你超过一个门槛时,庆祝一下。将您的解决方案投入生产。当同样的模型还在那里时,你的合同仍然有效。

现实世界不断变化,我们的上游数据也是如此。如果你不采取额外的步骤,你的模型将会忽略这些变化。你的合同还在。随着变化,当一个重大事件发生时,或者随着时间的推移,您的上游数据开始变化。它可能会发生如此剧烈的变化,以至于上游数据在某个时候可能不再类似于您的模型所依据的历史数据。此时,你违反了你的契约,你的模型开始无声地失败。

演出的连续性

随着世界的变化,我们的数据也在变化,我们需要确保我们的模型仍然做得很好。即使我们可能不做任何事情来使模型走上正确的道路,我们也需要知道性能。为了确保我的模型的性能仍然令人满意,我倾向于进行以下检查。请注意,这些检查是为您所服务的模型/解决方案服务的。

1。上游数据检查

对于这一个,您根据您的项目定义哪个阶段是上游。这个想法是在进入模型之前观察任何阶段的数据,以做出预测。虽然是这种情况,但在将数据输入模型之前的最后阶段可能是一个很好的阶段。

该检查的目的是确保上游数据仍然类似于训练模型时使用的历史数据的分布或遵循相同的模式。一种简单但有效的方法是计算每个固定时间间隔的上游数据的分布,并将其与历史数据的分布进行比较。如果两个分布的相似性很接近,你就是绿色的。否则,您会发出警报,并让解决方案的所有者知道。

2。下游输出检查

下游检查背后的思想与上游数据检查非常相似。在这个例子中,不是检查上游,而是检查模型或服务的输出。与上游检查一样,您可以监控生产中模型输出的分布与历史数据输入时模型输出之间的相似性。监视两个分布之间的相似性,如果它开始偏离,就发出警报。

这两种检查很容易实现。您可以将它们放在一个实时监控仪表板中,或者只是在超过阈值时向存储库的所有者发送一封邮件。就像任何支票一样,知道它们的存在是件好事。

如果你对我在这个故事开始时提到的事件的结局感到好奇,让我继续。变化来自客户端。我们的阅读依赖于运行在客户端的复杂而冗长的框架配置列表。后来很明显,客户改变了一些主要的配置。这一变化对我们的读数影响很大,导致了上游数据的重大变化。因此,输入模型的新数据点与我们用于训练的数据完全不同。只有我们对数据进行一些检查,我们才能意识到这种变化,并采取一些措施使事情朝着正确的方向发展。幸运的是,这一事件没有对业务造成太大影响,几天后一切都恢复了正常。这个有价值的教训让我对我们模型的静态本质更加多疑,并且怀疑我的解决方案在产品中是否仍然如我预期的那样工作。

Python 中的静态类型

原文:https://towardsdatascience.com/static-typing-in-python-55aa6dfe61b4?source=collection_archive---------5-----------------------

Python 初学者

轻松进行类型检查

Battlecreek 咖啡烘焙师Unsplash 上拍摄的照片

Python 是一种 动态 类型化语言。这意味着在给变量赋值时,没有必要声明变量的类型。例如,当你用字符串值'Tom'初始化对象时,你不需要声明对象major的数据类型为string

major = 'Tom'

在像 C 这样的 静态 类型化语言中,你必须声明一个对象的数据类型。字符串被声明为字符数组。

char major[] = "Tom";

用像 Python 这样的动态类型语言编码肯定更灵活,但是人们可能想要注释对象的数据类型并强制类型约束。如果一个函数只需要整数参数,那么向函数中抛出字符串可能会导致程序崩溃。

尽管这是动态类型的主要缺陷之一,Python 3 为程序员引入了几个注释工具来指定和约束对象的数据类型。

函数注释

让我们以一个非常简单的函数foo为例:

def foo(n, s='Tom'):
    return s*n

该函数以ns为参数,返回s*n。虽然它看起来像一个简单而无意义的乘法函数,但是请注意s的默认值是'Tom',它是一个字符串,而不是一个数字。我们可能推断这个函数打算返回一个多次重复字符串s的字符串,确切地说是n次。

foo(3, 'Tom') # returns 'TomTomTom'

这个功能比较混乱。您可能想写冗长的注释文档字符串,解释函数并指定参数和返回值的数据类型。

def foo(n, s='Tom'):
    """Repeat a string multiple times.
    Args:
        n (int): number of times
        s (string): target string
    Returns:
        (string): target string repeated n times.
    """
    return s*n

美国宇航局在 Unsplash 拍摄的照片

Python 为你使用符号:->可选标注 提供了一种更简洁的方式。

def foo(n: int, s: str='Tom') -> str:
    return s*n

函数foo的注释可从函数的__annotations__属性中获得。这是一个将参数名映射到它们的注释表达式的字典。这允许通过运行代码来手动类型检查,而不是自己查看源代码。非常方便。

foo.__annotations__
# {'n': int, 's': str, 'return': str}

可变注释

除了函数参数和返回值之外,还可以用某种数据类型来注释变量。你也可以注释变量而不用任何值初始化它们!

major: str='Tom' # type:str, this comment is no longer necessary
i: int

最好使用这种内置语法而不是注释来注释变量,因为注释在许多编辑器中通常是灰色的。

用于注释更高级类型的变量,如listdict等。,你需要从模块typing中导入它们。类型名称大写,如ListTupleDict等..

from typing import List, Tuple, Dictl: List[int] = [1, 2, 3]
t1: Tuple[float, str, int] = (1.0, 'two', 3)
t2: Tuple[int, ...] = (1, 2.0, 'three')
d: Dict[str, int] = {'uno': 1, 'dos': 2, 'tres': 3}

列表、元组或字典中的元素也可以被注释。那些大写的类型采用方括号[]中的参数,如上所示。

List接受一个参数,它是列表中所有元素的注释类型。固定大小元组中的元素可以逐个进行注释,而可变大小元组中的元素可以通过省略号...进行注释。我们还可以在字典中指定键和条目的类型。

照片由杨奇煜·巴赞内格Unsplash 上拍摄

高级注释

我们提到过List只取一个参数。注释一个混合了intfloat元素的列表怎么样?Union就是答案。

from typing import Union
l2: List[Union[int, float]] = [1, 2.0, 3]

它还支持任何用户定义的类作为注释中的类型。

class FancyContainer:
    def __init__(self):
        self.answer = 42fc: FancyContainer = FancyContainer()

一个 可调用的 也可以使用上述技术进行注释。可调用的是可以被调用的东西,就像函数一样。

from typing import Callable
my_func: Callable[[int, str], str] = foo

警告

首先,类型注释不能完全取代文档字符串和注释。出于可读性和再现性的目的,仍然需要对您的函数进行简要的描述和解释。启用类型注释可以避免让复杂的注释充满数据类型之类的信息。

第二,有件事我应该一开始就告诉你。Python 解释器实际上不会自动进行任何类型检查。这意味着那些注释在运行时没有任何作用,即使你试图传递一个“错误”类型的对象给一个函数。

那么你有没有浪费自己的时间去学习类型注释呢?号码

有许多 Python 模块可以在运行前强制执行这些约束。mypy 是目前最常用的类型检查器,没有运行时开销。

起义广场拍照

外卖

Python 中的类型注释有助于调试和可选的类型检查,后者模拟静态类型。它在项目开发中变得越来越流行,但在更普通的 Python 程序员中仍然很少见。

虽然没有注释并不一定会降低代码性能,但出于健壮性、可读性和可再现性的目的,它仍然被认为是一种良好的实践。

我们仅仅触及了 Python 中静态类型和类型注释的皮毛。Python 3.9 即将对变量注释进行一些升级,所以请继续关注注册我的时事通讯以接收我的新文章的更新。

连 Python 3.8 都没准备好?我掩护你。

[## Python 3.8 中针对 Python 新手的 6 项新特性

请做好准备,因为 Python 2 不再受支持

towardsdatascience.com](/6-new-features-in-python-3-8-for-python-newbies-dc2e7b804acc)

感谢阅读!你觉得这些功能有趣有用吗?下面留言评论!您可能还会发现以下文章很有用:

[## Python 中 4 个易于使用的自省函数

如何在运行时检查对象

towardsdatascience.com](/4-easy-to-use-introspection-functions-in-python-49bd5ee3a2e8) [## Python 初学者应该避免的 4 个常见错误

我很艰难地学会了,但你不需要

towardsdatascience.com](/4-common-mistakes-python-beginners-should-avoid-89bcebd2c628)

股票价格的统计分析

原文:https://towardsdatascience.com/statistical-analysis-of-a-stock-price-e6d6f84ac2cd?source=collection_archive---------6-----------------------

谷歌股价的简单统计分析

作者图片

股票市场总是被认为是对统计学的挑战。有人认为了解市场的统计数据可以让我们战胜市场并赚钱。现实可能大不相同。

在这篇文章中,我将向你展示谷歌股票价格的统计分析。

2008 年,为了获得理论物理学士学位,我必须分析股票价格,以检验股票市场模型的有效性。在本文的下一部分,我将向您展示一些使用 Python 对 Google 股票价格进行的分析。

代码可以在我的 GitHub 存储库中找到,这里:https://GitHub . com/gianlucamalato/machine learning/blob/master/Stock _ market _ analysis . ipynb

下载数据

首先,我们需要获得股票数据。我将使用 yfinance 库下载价格时间序列。

首先,我们必须安装这个库。

!pip install yfinance

然后我们可以导入一些有用的库。

import pandas as pd
import numpy as np
import yfinance
import matplotlib.pyplot as plt
from scipy.stats import skew,kurtosis,norm,skewtest,kurtosistest
from statsmodels.graphics.tsaplots import plot_pacf,plot_acf

我们现在可以得到 2015 年到 2020 年的谷歌价格数据。

name = 'GOOG'
ticker = yfinance.Ticker(name)
df = ticker.history(interval="1d",start="2015-03-15",end="2020-09-10")x = df['Close']

我们现在将使用 x 对象,它包含股票的每日收盘价。

每日收盘价

让我们画出每日收盘价。

作者图片

正如你所看到的,有一个相当不错的看涨趋势。有一些下降,但漂移似乎相当积极。

每日回报

当你对一只股票进行统计分析时,研究它的回报而不是价格本身是非常有用的。

从一天到另一天的回报是两天之间收盘价的百分比变化。

在 Python 中,series 对象有一个 pct_change 方法,允许我们计算这个量。该参数是要使用的滞后。在本文中,我将使用 1 天的滞后时间。

returns = x.pct_change(1).dropna()

结果是这样的:

第一个数字是 (x1-x[0])/x[0] ,第二个是 (x[2]-x1)/x1 以此类推。

这是我们要分析的数据。

收益的概率分布

我们现在要计算一些关于收益概率分布的见解。

直方图和箱线图

让我们先做一个原始的回报直方图。

plt.hist(returns,bins="rice",label="Daily close price")
plt.legend()
plt.show()

作者图片

如你所见,它完全以零为中心,看起来是对称的。然而,我们可以看到这个直方图有似乎不可忽略的尾部。

让我们制作一个箱线图来更好地理解这个数据集的分布。

plt.boxplot(returns,labels=["Daily close price"])
plt.show()

如你所见,它充满了离群值。如果与分布总范围相比,四分位数范围(即盒子的高度)相当窄。这种现象被称为厚尾,在股票分析中非常常见。

主要观察点

让我们计算数据集的一些可观测量。

平均值为:

它非常类似于零,但它是正的这一事实解释了价格时间序列的正漂移。

现在让我们来看看标准差:

比平均值高了不止一个数量级。这显然是离群值的影响。在股票价格分析中,标准差是风险的度量,如此高的标准差是股票被视为风险资产的原因。

让我们来看看中位数:

与平均值相差不大,所以我们可能认为分布是对称的。

让我们检查分布的偏斜度,以便更好地评估对称性:

它是正的,所以我们可以假设分布是不对称的(即零偏度),并且右尾是一个不可忽略的权重。

如果我们对偏斜度进行测试,我们会发现:

非常低的 p 值表明分布的偏斜度不可忽略,因此我们不能假设它是对称的。

最后,我们可以测量峰度(scipy 对峰度进行归一化,因此对于正态分布,峰度为 0)

它和零有很大不同,所以分布和正态分布有很大不同。

峰度测试给出了这些结果:

同样,非常小的 p 值让我们拒绝峰度与正态分布相同(为 0)的零假设。

回报是正态分布的吗?

尽管统计上显著的高峰值和偏态值已经告诉我们收益不是正态分布的,但是 Q-Q 图会给我们图形上清晰的信息。

t = np.linspace(0.01,0.99,1000)
q1 = np.quantile(returns,t)
q2 = norm.ppf(t,loc=np.mean(returns),scale=np.std(returns))plt.plot(q1,q2)
plt.plot([min(q1),max(q1)],[min(q2),max(q2)])
plt.xlim((min(q1),max(q1)))
plt.ylim((min(q2),max(q2)))
plt.xlabel("Daily returns")
plt.ylabel("Normal distribution")
plt.show()

作者图片

直线是我们对正态分布的预期,而蓝线是我们从数据中得到的。很明显,我们的数据集的分位数不能与具有相同均值和标准差的正态分布的分位数相比。

因此,回报不是正态分布的,这使得像几何布朗运动(假设正态回报)这样的模型只是现实的近似。

波动聚类

一旦我们确定了收益概率分布的非正态性,让我们来看看原始的时间序列。

plt.plot(returns)
plt.xlabel("Time")
plt.ylabel("Daily returns")plt.show()

作者图片

很明显,有波动性高的时段,也有波动性低的时段。这种现象被称为波动聚集,在股票市场中非常普遍。实际上,标准偏差会随着时间的推移而变化,这使得时间序列变得不稳定。

仔细看看 20 天滚动标准差,就什么都清楚了。

plt.plot(returns.rolling(20).std())
plt.xlabel("Time")
plt.ylabel("20-days rolling standard deviation")
plt.show()

作者图片

很明显它不是一个常数值,但它有尖峰和振荡。分布的厚尾可能是由这些波动峰值引起的,这产生了不可忽略的异常值。

自相关函数

最后,我们可以绘制部分自相关函数,这使我们对时间序列的自相关性以及这种自相关性在某些 ARIMA 模型中用于预测目的的可能性有所了解。

plot_pacf(returns,lags=20)

作者图片

从这个图中可以清楚地看出,所有滞后之间没有很高的相关性。在 5 和 10 之间有一些滞后,显示了一些相关性,但与 1 相比,这是非常小的。

因此,我们很容易理解,使用一些 ARIMA 模型将是非常无用的。

结论

在本文中,我展示了一个简单的谷歌股票价格统计分析。回报不是正态分布的,因为它们是偏斜的,有厚尾。时间序列不是静态的,因为标准偏差随时间而变化。收益时间序列的自相关性在几乎任何滞后时间都很低,这使得 ARIMA 模型无用。

因此,使用统计学和机器学习来预测股票价格是一个巨大的挑战。使用 LSTM 模型已经取得了一些成果,但是我们还远远没有清楚地用一种赚钱的方式来模拟股票市场。

用一行代码进行统计和可视化探索性数据分析

原文:https://towardsdatascience.com/statistical-and-visual-exploratory-data-analysis-with-one-line-of-code-9953638ea9d0?source=collection_archive---------18-----------------------

NASA 数据集的例子

在我看来,探索性数据分析(EDA)是新数据集中机器学习建模最重要的部分。如果 EDA 没有正确执行,它会导致我们开始用“不干净的”数据建模,这就像一个雪球下山,越滚越大,越滚越坏。

良好的探索性数据分析的基本要素

探索性数据分析的深度可以是您希望或需要的深度,但基本分析需要包含以下要素:

  • 第一个和最后一个值
  • 数据集形状(行数和列数)
  • 数据/变量类型
  • 缺少值和空值
  • 重复值
  • 描述性统计(平均值、最小值、最大值)
  • 变量分布
  • 相关

我喜欢执行手动 EDA 来更好地了解我的数据,但几个月前,阿迪·布朗什坦向我介绍了熊猫概况。由于它需要相当长的处理时间,所以当我想快速浏览小数据集时,我会使用它,我希望它也能加速你的 EDA。

熊猫简介入门

在这次演示中,我将在 NASA 的陨石着陆数据集中进行 EDA。

你已经查过了吗?

好样的,易如反掌!

现在好戏开始了。

点击这里了解更多关于熊猫档案的信息:https://pandas-profiling.github.io/pandas-profiling/docs/

你喜欢这篇课文吗?你可能想查看一下 最好的免费数据科学电子书

统计决策理论

原文:https://towardsdatascience.com/statistical-decision-theory-382b04f517f2?source=collection_archive---------31-----------------------

机器学习的框架

来源

在这篇文章中,我们将讨论一些为开发机器学习模型提供框架的理论。

我们开始吧!

如果我们考虑一个实值随机输入向量, X 和一个实值随机输出向量, Y ,目标是找到一个函数 f ( X )来预测 Y 的值。这需要一个损失函数, L ( Yf ( X )。这个函数允许我们惩罚预测中的错误。常用损失函数的一个例子是平方误差损失:

损失函数是真实结果值和我们的预测之间的平方差。如果f(X)=Y,这意味着我们的预测等于真实结果值,我们的损失函数等于零。所以我们想找到一种方法来选择一个函数 f ( X ),它给出的值尽可能接近 Y

给定我们的损失函数,我们有一个选择 f ( X )的标准。我们可以通过对 x 和 y 上的损失函数进行积分来计算预期平方预测误差:

其中 P( XY )是输入和输出的联合概率分布。然后,我们可以以 X 为条件,计算预期平方预测误差,如下所示:

然后,我们可以逐点最小化该期望平方预测误差,方法是找到值 c ,其最小化给定的误差 X :

对此的解决方案是:

这是 Y 的条件期望,给定 X = x. 换句话说,回归函数给出了 Y、的条件均值,给定了 X. 的知识,有趣的是,k-最近邻方法是从训练数据实现该方法的直接尝试。对于最近邻,对于每个 x ,我们可以求 y 的平均值,其中输入 x 等于特定值。我们对 Y 的估计可以写成:

其中我们对样本数据取平均值,并使用结果来估计期望值。我们也在调整一个区域,它的 k 个邻居离目标点最近。随着样本量变大,邻域内的点很可能接近 x 。此外,随着邻居数量 k 变大,平均值变得更加稳定。

如果你有兴趣了解更多,Trevor Hastie 的《统计学习元素》是一个很好的资源。感谢您的阅读!

统计假设检验简明指南

原文:https://towardsdatascience.com/statistical-hypothesis-testing-b9e641da8cb0?source=collection_archive---------38-----------------------

统计推断的频率主义方法。

拉纳·萨瓦哈在 Unsplash 上的照片

介绍

频数统计 的主要应用之一是一组或多组之间 样本均值和方差 的比较,称为 统计假设检验 。样本 统计量 是一个汇总/压缩的概率分布;例如,高斯分布可以用平均值和标准差来概括。在一位经常出入的统计学家看来,当从背后有未知固定真值的数据中估计时,所述统计是 随机变量——问题是各组相对于这些估计值是否显著不同。

例如,假设研究人员对儿童的成长感兴趣,并且想知道相同年龄(例如 12 岁)的男孩和女孩是否具有相同的身高;该研究人员在某所学校收集随机变量身高的数据集。在这种情况下,身高的随机性是由于抽样人口(他发现的十二岁的儿童)而产生的,而不一定是由于噪音——除非测量方法非常不准确(这导致进入 计量学 的领域)。也许,来自其他学校的不同孩子会导致不同的数据。

假设

假设研究问题公式化为“同龄的男生和女生的身高是否不同?”第一步是提出一个假设,尽管习惯上称为 无效假设【H0】,即同龄的男孩和女孩具有相同的身高(没有差异)。这类似于考虑随机变量身高的可能的两种分布,具有固定的平均值 μ 和标准偏差 σ ,生成身高值——但是不知道男孩( μ1 和女孩( μ2 )的平均值是否相同。(此外,还有一个替代假设(HA ),它通常是零假设的否定。)在这种情况下,零假设是

H0: μ1 = μ2

概率分布的参数可以用 最大似然 方法进行估计,即最大化一个似然函数;众所周知的平均值和标准偏差公式就是从这种方法中产生的。使用这些公式,研究人员计算两个样本均值,他可能会获得它们之间的一些差异。然而,研究人员如何确定这种差异是真实的,而不是随机不相等的零,因为他也可以在这项研究中包括其他(或更多)儿童?

图 1: 样本均值的分布作为样本量的函数。这个分布的标准差随着样本越多越窄(来源:作者)。

在图 1 中,给出了一个带有随机数发生器的模拟。从随机变量 x (例如高度)的高斯分布中抽取样本,其中 μ =156.4,σ= 4.8;在每个子图中,抽取 n 个样本,并计算样本平均值;对于每个样本大小,该过程重复 1000 次,并且样本平均值的相应直方图被可视化。这实质上是不同样本量的样本平均值的分布,很明显,随着样本量的增加,这种分布变得更窄,因为平均值的标准偏差,也称为【s . e .),与样本量的平方根成反比。

**s.e. = σ / sqrt(n)**

一方面, 大数定律 规定,从大量抽样的随机变量中获得的的平均值应该接近于的期望值,并且随着抽取的样本越多,将趋于更接近于期望值。另一方面, 中心极限定理 陈述了样本均值遵循具有真实均值和标准误差的正态分布。****

在图 1 中,对于 n =20,一些样本均值是 154,而另一些是 160——这只是偶然。想象计算两个样本平均值,一个是男孩的,一个是女孩的。如果有差异,那可能只是偶然的,尤其是对于小样本而言。如果收集了足够多的样本,通过计算样本平均值可以更有把握地找到“真实平均值”——但如果没有给出呢?在许多研究中,参与者的数量通常是有限的。

置信区间

这就是所谓的 置信区间 的由来。估计统计量的置信区间是从样本中计算出来的随机区间,该样本包含具有某种指定概率的真值。例如,平均值的 95%置信区间是一个随机区间,其中包含概率为 0.95 的真实平均值。更准确地说,如果我们选取许多随机样本,并计算每个样本的置信区间,这些区间中大约 95%将包含真实均值,如图 2 中的模拟所示。

图 2: 以 100 个估计样本均值为中心的 95%置信区间(上例中 μ =156.4 ,σ =4.8,n = 20——即 z=2.086)。100 个中有 6 个不包括真实平均值(来源:作者)。

这样,图 1 中的分布可以用一个置信区间来近似。为了计算置信区间,来自 t 分布 的分位数 z 对应于所选择的概率 1- α (例如,95%的情况下 α = 0.05)和自由度( df )乘以以两侧样本均值为中心的标准误差。(注意在频率主义者的范式中,随机性和频率这两个概念是如何无处不在的。)

**confidence interval = [μ - z(α/2, df)*s.e., μ + z(α/2, df)*s.e.]**

t 分布是一种连续的概率分布,当估计正态分布总体的样本均值时会出现这种情况,此时样本量较小,总体标准差未知,这种情况很常见。(下面将更详细地讨论 t 分布。)

统计测试

了解随机变量的分布对于选择适当的统计检验是有意义的。更准确地说,像 t-test 这样的参数测试假设随机变量的 正态分布——一个可能不满足的要求。在这种情况下,使用非参数检验是合理的,例如 曼-惠特尼 U 检验 。然而,Mann-Whitney U 检验使用另一个零假设,其中两组的概率分布彼此相关

**H0: p(height1) = p(height2)**

有一大堆统计测试(图 3);使用哪种检验取决于数据类型(定量与分类)、数据是否正态分布(参数与非参数)以及样本是否配对(独立与相关)。然而,重要的是要意识到零假设并不总是相同的,所以结论会稍有变化。

图 3: 统计检验概述(来源:作者)。

一旦假设得到验证,就选择一个测试,并且从大小为 nm 的两个样本中计算出 测试统计量 。在这个例子中,它将是T-统计量 T ,它根据T-分布进行分布(具有 n + m -2 个自由度)。 S 是汇集(聚集)样本方差。此外,值得一提的是 T 与样本大小成比例。

**T = (mean(height1) - mean(height2)) / (sqrt(S) * (1/n + 1/m))S = ((n - 1) * std(height1) + (m - 1) * std(height1)) / (n + m - 2)**

注意 t 统计量与高斯分布相关的-得分、的相似性。z 得分的绝对值越高,其关联概率越低,对于 t 分布也是如此。因此,t 统计的绝对值越高,零假设为真的可能性就越小。**

只是为了提供一些说明,t 统计量遵循 t 分布,因为标准偏差/误差是未知的,必须从(少量)数据中估计。如果已知,我们将使用正态分布和 z 得分。对于较大的样本量,随着标准误差接近零,t 统计量的分布变得越来越正态。(注意,估计的标准偏差也是遵循具有 n-1 个自由度的 卡方分布 的随机变量。)

p 值

如上所述,统计假设检验处理组间比较,目标是在给定估计样本统计的情况下,评估组间差异是否显著。为此,计算充分统计量、它们相应的置信区间和 p 值 。p 值是与使用 T 分布的 T 统计相关联的概率,类似于与 z 得分和高斯分布相关联的概率(图 4)。在大多数情况下,会应用双边检验来评估 T 统计的绝对值。用数学术语来说,p 值是

***p = 2*min{Pr(θ <= T|H0), Pr(θ >= T|H0)}***

图 4: 学生的 t 分布和 p 值背后的直觉(来源:作者)。

因此,p 值是获得测试结果 θ 的最大概率,至少与假设零假设为真的情况下实际观察到的结果 T — 一样“极端”。非常小的 p 值意味着在零假设下,这种“极端”的观察结果是非常不可能的(观察到的数据与零假设“充分”不一致)。因此,零假设被拒绝。

假阳性和假阴性

如果 p 值低于某个阈值 α ,则称该差异为 统计显著性 。拒绝实际为真的零假设称为I 型错误(假阳性),I 型错误的概率称为显著性水平(“某阈值”) α 。当零假设为假时接受零假设被称为第二类错误(假阴性),其概率用 β 表示。当零假设为假时被拒绝的概率称为检验的功效,等于 1- β 。通过对显著性水平 α 更加严格,假阳性的风险可以被最小化。然而,调整假阴性更加困难,因为替代假设包括所有其他可能性。****

实际情况是, α 的选择本质上是任意的;科学上常用小数值,如 0.05(甚至 0.01)。这种方法的一个缺点是必须拒绝或接受零假设,尽管这不是必须的。例如,在贝叶斯方法中,两种假设可以同时存在,并具有一些相关的后验概率(模拟假设的可能性)。

结束语

应该说明的是,置信区间和假设检验之间存在着二重性。无需过多赘述,值得一提的是,如果给定水平 α 的两个置信区间重叠,则零假设被拒绝。然而,仅仅因为差异在统计上是显著的,它可能是不相关的。对于没有意义或不重要的影响,可以观察到小的 p 值。事实上,样本量越大,产生有统计学意义的 p 值所需的最小效应就越小。最后,结论是没有价值的,因为它们是基于坏的(如有偏见的)数据。重要的是保证采样的数据是高质量的并且没有 偏差 — ,这根本不是一件小事。

***** [## 偏见如何扭曲你的预测

理解数据及其分布是精确模型的关键。

towardsdatascience.com](/how-sampling-biases-might-be-ruining-your-predictions-f9e021d79723)*****

概率论和数理统计中的统计不等式

原文:https://towardsdatascience.com/statistical-inequalities-in-probability-theory-and-mathematical-statistics-c2c62f51b852?source=collection_archive---------26-----------------------

一个最棒的列表,它们的证明,以及它们在哪里有用

维基百科上的照片

背景和动机

统计不等式提供了一种界定度量和数量的方法,在对难以计算的数量进行界定时特别有用。它们也是概率论、统计学和机器学习中大量理论的基础。如果你有一个最喜欢的统计定理,迭代数值方法,或机器学习算法,很有可能一些统计不等式在支撑所述方法或方法中起作用。(关于这些不等式的一个应用例子, 请看我那篇关于弱大数定律的证明 )。

在 Medium 上的快速搜索显示,这个主题(据我所知)还没有在平台上覆盖。在我不断努力让更多的人对理解他们正在实现的方法的内部工作方式感兴趣的过程中,我认为这个主题值得一提。

在下面的文章中,我分享了一个包含 4 种统计不平等的“最热门列表”:

  1. 马尔可夫不等式
  2. 切比雪夫不等式
  3. 詹森不等式
  4. 柯西-施瓦茨不等式

这远不是一个完整的列表,而是一个简短的“最热门”的引子。对于下面的每一个不等式,我都给出了它们的证明,并提供了它们在哪里有用以及为什么我们应该关心它们的注释。还要注意,这些不等式中的一些有超出概率论和随机变量的解释。然而,这里只讨论与随机变量相关的上下文。

话虽如此,我们还是开始吧。

1)马尔可夫不等式

2)切比雪夫不等式

3)詹森不等式

4)柯西-施瓦兹不等式

最终想法:

希望以上有见地。正如我在以前的一些文章中提到的,我认为没有足够的人花时间去做这些类型的练习。对我来说,这种基于理论的洞察力让我在实践中更容易使用方法。我个人的目标是鼓励该领域的其他人采取类似的方法。我打算在未来写一些基础作品,所以请随时在 LinkedIn 上与我联系,并在 Medium 上 关注我的更新!

使用 Pandas,NumPy 在 Python 中进行统计推断

原文:https://towardsdatascience.com/statistical-inference-in-pyhton-using-pandas-numpy-part-i-c2ac0320dffe?source=collection_archive---------27-----------------------

在本文中,对 Kaggle 数据集进行了探索性数据分析和统计推断,该数据集包含 2010 年至 2017 年期间向管道和危险材料安全管理局报告的石油管道事故。数据集在这里可用。本文的目的是展示 python 中使用 Pandas、NumPy 和 Matplotlib 的几行代码如何帮助用明显最少的信息对数据集执行统计分析。它还可以作为统计分析初学者的教程,让他们了解统计推断在真实数据集上的应用,重点是:

泊松过程

指数分布

自助抽样

置信区间

这个教程的完整代码可以在这里找到。因此,让我们通过展示一个数据样本来开始分析。

样本数据的前 5 行

感兴趣的变量的汇总统计信息

请注意,Kaggle 数据集中与此分析无关的许多列已被删除。分析的第一步是决定分析的目标是什么。通过查看数据集样本,我的目的是对美国石油管道事故造成的成本和桶油当量损失进行估计。然而,请注意,我们只有 2010 年至 2017 年的可用数据,这告诉我们,该数据集不包含美国所有的管道事故,这就引出了我们的第一个定义。统计推断是利用概率法则来分析来自较大人群的数据样本以了解人群的方法。在这种情况下,美国 2010 年至 2017 年间的石油管道事故是美国所有石油管道事故中的一个样本。现在,让我们计算样本中我们感兴趣的变量的汇总统计数据,即由于输油管道事故导致的成本和石油损失。

查看我们两个变量的汇总统计数据,可以很容易地推断出极值的存在,因为与它们的平均值相比,最大值非常大,而且显著较大的标准差也表明变量的平均值有较大的方差。箱线图是一种更好的可视化总结的方式。

两个变量的方框图中没有方框,这清楚地表明两个变量的较大值明显大于样本的其余部分,因此两个变量的数据都有极值。即使可以使用中位数来估计每次事故的成本或每次事故的桶数损失,数据的分布也是非常不可靠的。在这种分布下,除非可以消除极值,否则很难用模型来拟合变量。在我们的案例中,我们没有足够的信息来得出极端值确实是数据错误而不是过程的一部分的结论。然而,我们在数据样本中有另一个关键变量,它看起来并不那么重要,因为无法对其进行直接汇总统计,这就是事故发生的时间。有了统计建模的知识,我们知道一个熟悉的概率分布,它可以模拟某个区间内的事故频率,这就引出了我们的第二个定义,泊松分布

泊松分布模拟一个过程,在该过程中,平均数量的事件在固定的时间或空间间隔内发生。事件在该区间内发生的概率由参数为 λ 的泊松分布表示,该过程称为泊松过程。对于遵循泊松分布的过程,观察到的事件不能同时发生,并且在不相交的时间或空间间隔中,每个事件的发生独立于前一个事件的发生。

在我们的场景中,如果我们关于美国输油管道事故的假设是正确的,即它们不会同时发生,并且一个事故的发生不会影响另一个事故的发生,那么事故数量, X 是一个服从泊松分布X~泊松(λ)的随机变量。为了估计分布的参数,我们只需计算样本中的事故数量,然后除以总时间跨度。

使用 python 中的 NumPy,可以生成一个来自泊松分布的随机样本来模拟我们的数据,估计 λ 为每月33 起事故。让我们看看分布是什么样的,从中可以推断出什么。

通过概率质量函数,我们现在对数据有了更好的结论,即使每月平均事故数量为 33 起,每月发生 33 起事故的概率仅为 7%此外,在累积分布函数中很容易看出,每月发生 33 起或更少事故的概率为 50%,或者每月发生 33 起或更多事故的概率为 50%,仅知道平均值是不直观的。统计推断允许你对你的数据做出更有意义的结论。

现在让我们说,我们希望以不同的方式来看事故的频率。我们感兴趣的是估计两次事故之间经过的时间,而不是估计某个时间间隔内的事故数量。我们现在感兴趣的汇总统计数据是平均事故间隔时间。这就引出了我们的第三个定义。

指数分布有时用于模拟事件发生前经过的时间。此外,如果事件遵循泊松过程,其速率参数为每间隔事件数,则从任何起始点到下一个事件的等待时间遵循指数分布,其参数为每间隔事件数。

使用熊猫,我们可以计算样本中每个事故的间隔时间。然后,我们使用 NumPy 来估计事故之间的平均时间(小时),作为指数分布的参数。然后,我们绘制样本数据的累积分布函数,随机样本大小为 3000,由指数分布生成,以比较我们的实际数据与指数分布模型的拟合程度。

上图显示,事故样本数据的累积分布与来自指数分布的随机样本的累积分布非常相似,平均事故发生时间相同。因此,用指数分布来模拟输油管道事故之间的时间是合适的。这也巩固了我们之前的假设,即事故的发生是一个泊松过程,在不相交的时间间隔内的事故数量是独立的,不会同时发生。让我们看看输油管道事故样本数据的概率密度函数。输油管道事故样本的概率密度函数是指数分布随机变量的指数衰减。

到目前为止,我们已经能够计算出我们样本的输油管道事故平均间隔时间,并将其用于概率模型。但是我们仍然没有对美国石油管道事故的发生做出任何有意义的结论。仅仅知道一个样本的平均值并假设它适用于在美国发生的所有事故是不够的。那么,我们对样本的平均值有多大把握。如果事故报告和管道运行的所有条件在过去 50 年或过去 100 年中保持不变,如果我们对 2002 年至 2009 年或任何其他时间段的数据进行采样,我们会得到相同的平均事故时间吗?直观的假设是,我们不会在每次对这些数据进行采样时都获得完全相同的平均值。

样本的置信区间有两个相关部分。第一部分是它给出了一个值的范围,即一个下限和一个上限,在这两个值之间可以是总体的真实平均值。第二部分是值域的显著性水平。总的来说,如果数据以同样的方式一次又一次地被采样,真实总体平均值被捕获 x%次的数值范围代表平均值范围的 x%置信区间。因此,为了计算美国数据集中输油管道事故平均时间的置信区间,需要多次重复该过程,以获得真实总体平均值所在的平均值范围。但是重复这个过程,即石油管道事故几次,实际上是不可能的。然而,从理论上讲,使用自举可以根据需要多次重复这些实验。

Bootstrap 抽样是利用重采样数据进行统计推断,即在相同条件下重复实验,可以从样本数据中重复抽样出大小为 n 的随机样本。使用 NumPy,可以很容易地在 python 中为我们的事故数据计算 bootstrap 样本。

100 个 bootstrap 样本的分布绘制在实际数据的顶部,正如预期的那样,样本与实际样本略有不同,但仍接近保持指数分布。上图已被放大,以关注样本的变化。我们现在只需要每个样本的平均值来计算样本平均值的置信区间。从自举样本计算出的统计数据被称为自举复制

上图中的直方图显示了该过程重复 10,000 次时,bootstrap 重复的概率密度或平均事故时间。对于 95%的置信区间,我们需要找到 95%的重复平均值下降的范围。这只是从引导重复的概率密度函数推导出的引导重复的第 2.5 和第 97.5 百分位之间的所有值。

根据这一分析,我们有 95%的把握认为美国发生输油管道事故需要 21.15 至 22.93 小时,或者我们有 95%的把握认为美国每年发生大约 382 至 414 起输油管道事故。利用这一知识,现在我们可以使用每个变量的每个事件的中值来推断美国石油管道事故的成本和损失的桶数。因此,我们有 95%的把握认为,美国每年因输油管道事故造成的损失在 890 万至 960 万美元之间。这是我们通过统计推断了解到的关于美国石油管道事故的有意义的信息。

在本文中,我们围绕美国输油管道事故的基本过程建立了一个统计模型,并得出了关于事故频率和成本的具有统计意义的结论。本文的下一部分将尝试进一步深入数据集,并使用假设检验得出更有意义的结论。

通过置信区间估计的统计推断

原文:https://towardsdatascience.com/statistical-inference-through-confidence-interval-estimation-f6a752ae0d48?source=collection_archive---------38-----------------------

无知和自信之间的平衡

塞巴斯蒂安·科曼摄影在 Unsplash 上拍摄的照片

这辈子你需要的只是无知和自信,然后成功就有把握了。~ 马克·吐温

简介

当《厨艺大师》中的一个野心家展示一道评委们并不全吃的菜时,这是一件耐人寻味的事情。相反,他们优雅地咬一小口,他们雄辩的咀嚼创造了一个最佳的兴奋环境,最后,他们精心策划的判断呈现出对食物质量的洞察力。这一金字招牌拥有来自观众和追求者的强烈信念,它给人一种独特、精确的感觉,并且是那些关心在烹饪这种特定类型的菜肴中实现类似结果的人的良好代表。

粗糙 近似 做法的特定想法同样耐人寻味,这种做法已被视为吸引跨年龄群体的考虑,以提高思维能力。以这样或那样的方式,我觉得当我们在不知道一个假设的宽度的情况下,准确地揭示我们与特定事物的接近程度时,会给人一种巨大的喜悦感。

在这篇文章中(作为我过去的延续),我们将采取谨慎的步骤来面对我们在上面章节中所考察的某些现实中的一些刺激的真实因素。

总体、样本和非抽样误差

目标人群与样本(辛普森图像来源)

一个群体是一项研究试图对其做出推论的所有成员的集合(et al Albright&Winston)。

群体的每个单元被称为一个分散空间分布特征是我们在这个讨论中能够发扬光大的种群的唯一重要属性。

一个样本可能指的是人口中的一小部分,这部分人口比较容易控制,但同时也应该能够被分离出来,并且必须拥有人口的真实素质。

如果我们练习用“目标”和“人口”一起写作或发音,而不是简单的“人口”,那么我强烈认为我们可以缩小我们关于目的的意图,而不是与英语字典的盲目约会。这个不可否认的由两个术语组成的篮子说了一千个单词,消除了大量阅读或解释的需要。

挑选一个样本或一组这样的样本的过程被称为抽样,数据科学已经被赋予各种各样的抽样技术。现在转移和讨论它们中的每一个都是徒劳的,然而,值得一提的是,每一种技术都有其独特的设计和认知方法。这完全取决于相关的人选择什么技术来达到预期的猜测,没有这样的规则刻在石头上。也就是说,我想与我的读者分享我对不同的常用技术的看法。他们中的每一个人都被要求具备四个特征(即实施、代表性、成本和随机性)。种群的分散性和空间分布特征在一定程度上造成了上述四个性状的变异。

表格图——抽样技术象限(来源:Self)

我们从左向右移动得越多,就实现而言,我们获得的技术就越简单。我们越往上走,这项技术就越不能精确地代表一个群体的所有特征。圆圈的大小代表执行的成本。尺寸越大,执行该技术的成本越大。最后,红色涵盖了在选择样本时涉及一定程度的概率或随机性的技术。而蓝色圆圈只关注非概率性的或判断性的技术,其中没有分配随机性。虽然我们将只讨论第二象限中的一种技术,即简单随机抽样,但我重申以上观点纯粹是基于我的公正理解,而非偏见。我不敢说这种观点拥有国家或国际统计机构的签名,因此在盲目接受我的观点之前请记住这一点。它可能与你的故事版本相符,也可能不相符。

Unsplash 上的 bantersnaps 拍摄的照片

现在请允许我澄清为什么我让你在副标题处想象一个无知平衡形象首先,尽管评委在品尝菜肴时吸收了艺术性来评估有抱负的厨师,但还是会有一些误差,因为完成整个菜肴总是被遗漏,并且不可能在规定的时间内完成。其次,抛开前一个错误不谈,尽管评委有设计或认知方面的专业知识,但参赛选手可能会遗漏一些不符合比赛主题或目标的成分或技术。裁判在解释参赛者的陈述时也可能会有一些错误。我会更好地揭示第二种误差可能被称为非抽样误差,而第一种误差更多的是抽样误差。不管这两种类型的错误,平衡是惯例,使表演继续下去,并允许越来越多的参与者包含这个过程。提交一个没有一点误差的猜测问题的答案是不可避免的。我可能会获奖,也可能不会,但这个过程必须能够忽略错误的影响。

非抽样误差的例子

为了防止你打瞌睡,不要看不同种类的非抽样误差的定义,让我们看几个可能导致这种可能性的例子

表格图——无反应偏差(来源:Self)

以上是无响应误差的一个典型案例,它是一种常见的非抽样误差。与 18-29 岁年龄组的投票者相比,非投票者的比例相对较高,他们可能会对高中早期的投票权意识提出质疑,这反过来可能会影响纳税人的投票模式。

表格图——不真实的偏见(来源:Self)

上图显示了一个名为“数据科学生命”的组织所雇用的所有数据分析师的回答。这些回答是首席技术官为猜测 VBA 培训计划的规模而进行的调查的一部分。尽管一切看起来都很好,除了 5%的数据分析师在工作中根本不使用 excel。这听起来可能不可信,因为组织非常清楚每个数据分析师都更新了他/她的年度 Excel 许可证。

表格图——测量偏差(来源:Self)

上图显示了申请人对一家明确需要程序员的公司的职位的反应。像“通常”、“有时”或“很少”这样的选项并不能给招聘人员一个清晰的资格描述,他们应该更关注那些有编程经验或没有编程经验的候选人。因此,问题的设置可能没有真正抓住招聘人员的意图,导致测量偏差。

表格图——自愿反应偏差(来源:Self)

去年毕业的学生一直渴望在校园内有一个休闲区,在那里学生(相对来说是新来的学生)可以与高年级学生一起度过一段美好的时光,交流课程和其他课外活动。经过大量的陈述和说服之后,他们得到了管理层的许可,进行了一项调查,调查的基础是建立成本的决定。二年级学生竭尽全力维护公平手段,但却忽略了向一年级学生宣传这一目标的关键需求。结果显示,90%参与投票的一年级学生不想要夜间咖啡馆,而他们最初是去年的目标观众。因此,当前第一年的心态在某些方面与潜在受访者不同,导致潜在的自愿回答偏差。

总体参数,样本统计

人口与样本特征(辛普森图像来源

我们对儿童辛普森身上的品质起源于人类发展的哪个阶段没有一点概念,无论如何,这些品质允许我们推断人类的具体特性。

群体特征由称为群体参数的度量来描述。大多数情况下,这个值总是存在的,但是除了一些实验情况之外,在现实生活中仍然是未知的。一个样本的特征由一个被称为样本统计量 的度量来描述,这个度量有资格作为 点估计 之后的。我们可以利用样本统计数据得出关于总体的某些结论。均值标准差是总体参数和样本统计常用的两种度量。让我们考虑另一个例子来更详细地讨论上述内容。

采样分布

一家社区免下车餐馆的负责人热衷于改善向经过咖啡馆免下车窗口的顾客提供的服务。作为这一程序的初始阶段,主任要求他的助手在办公室免下车服务框架的最后一个窗口记录为无数客户服务所需的时间。结果包括大约 1184 次帮助。对于这个问题,我们可以假设总体是已知的。(艾尔·奥尔布赖特&温斯顿)

示例数据的前几行(来源:数据

要求是从信息中产生一个直接的大小为 30 的任意样本,然后从选择的样本中计算出一个总体边界(平均值)的标准。这里,样本统计量也可以称为样本均值。

Python Graph-1(来源:数据)

正如我们所说的,总体参数最常见的度量是它的均值,为了估计这个总体参数,最常见的样本特征是样本均值。虽然中位数或其他措施也是限定词,我们会坚持样本均值。上图中的黑色点划线是所有 1184 个记录的服务时间的总体平均值。另一方面,棕色实线是样品的意思。请注意第一张图表,我们只有一个样本,我们只有一个样本平均值,但是当我们不断抽取多个大小为 30 的样本时,我们可以得到平均值的分布,因此我们可以评估分布的平均值,用棕色线表示。另外,请注意,当我们在图表中移动并将它们与第二行进行比较时,我们观察到黑线和棕色线几乎重叠。因此,当给定大小的重复随机样本取自总体值时,所有样本均值趋向于满足总体均值,从而成为总体均值的无偏估计量。这是样本均值的抽样分布的一个关键性质。因此,在人口平均值未知的实际情况下,我们可以依靠这种无偏估计来得出一些关于人口平均值的想法

Python Graph-2(来源:数据)

目前在上图中,我请求您只看到一个变化。我们是否注意到 X 轴的范围突然看起来比它的对应物窄了,在对应物中我们每个样本只取了 30 个单位?因此,在较大的样本中,我们看到的分布较少。所有样本均值的标准差与样本大小(本例中为 100)直接相关。一个抽样分布中所有样本均值的标准差称为标准差。因此,如果我们能够承担增加样本量(例如 100 个> 30 个)的成本,那么我们可能实现样本均值的更小偏差,或者换句话说,更小的标准误差。这也被称为无偏估计量的可变性。

Python Graph-3(来源:数据)

虽然在现实生活中,实际的人口分布可能还不可用,但为了本文的目的,让我们假设我们有来自 1184 个客户记录的人口分布,当我们绘制它时,我们得到一个右偏分布,如上图中蓝色曲线所示。绿色曲线表示样本平均值的抽样分布。这个练习我们已经做了 6 次,每次我们都抽取了 3、5、25、30、50 和 100 个样本。我们限制自己重复 100 次,并故意不改变它。

我们看到,随着样本量的增加,绿色曲线的形状(大约在 30 号之后)逐渐类似于正常的钟形。只要样本量足够大,样本均值的分布将趋于正态分布,而不考虑总体分布可能严重偏斜或正态分布的事实。这给了我们一个被称为中心极限定理(又名 CLT)的神奇定理的微妙概述。

置信区间

到目前为止,在检查上述服务时间示例时,我们已经讨论了如何通过随机抽样获得点估计值或无偏样本统计量。我们知道当我们改变样本大小或重复取样时,这个点估计值会有多大的偏差。我们还检查了对于足够大的样本量,点估计的抽样分布如何非常类似于正态分布。我们现在来看最后一个问题。

餐厅里为接单的顾客服务的平均时间的 95%置信区间是多少?

如果我们重新考虑标准正态分布,我们可能会问,

为了达到 95%的置信区间,我们需要移动抽样分布中所有样本均值的多少个标准差?

Z 分数区域概述(来源:Self)

如果我们还记得上面的图表,它来自我们读过的我的上一篇文章,在 python 中,从 stats.norm.cdf(2) 中减去 stats.norm.cdf(-2) 大约得到 0.9545,而不是精确的 0.9500。这是通过以下方式实现的:

因此,让我们假设点估计值(样本分布中所有样本平均值的平均值)为 55.45 分钟。抽样分布的标准差为 4.46 分钟。我们被要求考虑原始示例中 30 的样本量。因此,标准误差(即抽样分布中所有样本平均值的标准偏差)是 4.46 除以样本大小的平方根。数值为 0.814。由于我们知道原始人口记录,我们还考虑了一个价值为 0.99 的修正系数。最终的标准误差现在是 0.99 * 0.814,接近于 0.81假设点估计值和标准误差值已经给了我们

上区间是{55.45 加(1.96 * 0.81)},下区间是{55.45 减(1.96 * 0.81)}

我们有 95%的把握认为,餐厅中为接受订单的顾客服务的平均时间介于 53.87 分钟和 57.03 分钟之间。

学生的 t 困境

Python Graph-4(来源:Self)

为了简单起见,我们只知道,当样本量很小并且总体标准差未知时,学生的 t 分布是一个很好的选择。请记住这两个条件都需要满足。换句话说,看着图表,我们可能会觉得依赖小样本来估计偏差会导致更大的不确定性,从而导致更分散的分布,正如具有较重尾部的 t 分布所示。虽然在这一点上谈论自由度将会打开潘多拉的盒子,但是知道从样本量中减去 1 就可以得到 t 的自由度值(又名 df)就足够了。要了解更多信息,您可以访问这里。现在,如果我们认识到随着样本量的增加,自由度增加,因此 t 分布逐渐接近正态分布,这是没问题的。如果你能理解这幅图的意图,我会很高兴,因为在我早期,同时想象这两者对我来说是一场噩梦。当样本量小于 30 时,上图是证明使用 t 分布而不是正态分布(或 Z 分布)的许多方法之一。我的来自质量控制领域的读者朋友们可能会认同我的观点。

等于 1.96 的 stats.norm.ppf(0.975)是 stats.t.ppf (0.975,< 自由度 >)

人口比例( )

评估总体参数置信区间的基本要素是点估计、点估计的标准误差和取决于置信水平或样本大小的乘数。我们已经看到了前两个,但只是重温第三个(乘数)可能取决于我们选择的特定分布(正常或学生的 t),基于此,我们可以相应地插入 stats.norm.ppf 或 stats.t.ppf 函数。问题可能是,除了这两个分布之外,我们能不能不使用任何其他分布?当然,我们可以发布必要的尽职调查和调查。

牢记上述基本原则,我们将讨论一种更有趣的人口参数形式,称为人口比例。在这种形式中,我们处理的不是作为一个特征的平均值,而是关于整体的一个份额或部分。例子可以是支持特定候选人的投票者的真实比例的 95%置信区间,在特定城市使用 wifi 网络的家庭的真实比例的 95%置信区间,在给定月份上涨和下跌的股票的真实比例的 95%置信区间,对快餐连锁店提供的服务满意的顾客的真实比例的 95%置信区间,等等。

识别比例估计值的一个简单方法是首先检查是否有任何潜在的提及均值作为特征。其次,在我们抽取了一个给定大小的随机样本后,应该有一个形成比例的成功或失败的概率。例子可以是对候选人投票“是”或“否”,Wifi“是”或“不是”使用,股票“是”或“不是”上涨,客户“是”或“不是”满意,等等。准确地说,样本比例的属性应该是一个二项随机变量

同一家餐馆的经理想要估计平均服务时间,现在他想要执行另一个估计。他在冬季推出了一种新的三明治。他收集了 40 名顾客的样本,要求他们按照 1 到 10 的标准(1 是最差,10 是最好)给这种新三明治打分。他想估计给三明治打 6 分及以上的顾客比例。他认为,这个间隔很可能会在下一次访问时购买一个三明治。据我们所知,40 个客户样本中有 25 个客户的评分为 6 分及以上。(艾尔·奥尔布赖特&温斯顿)

下面的 python 代码可以帮助我们理解,

结论

大多数人使用统计数据就像一个醉汉使用灯柱一样;支持多于照明~ 安德鲁·朗

一个样本更像是从一个总体中提取并推断出该总体的子集。两种主要的抽样类型是概率抽样和非概率抽样。群体框架中的每一个元素都有平等的机会在样本中被选中,这个特殊的过程就是简单随机抽样。如果我们取一个给定大小的样本,评估样本特征(最常见的是均值或比例),并多次重复这两个步骤,我们将得到样本特征的分布,称为抽样分布。当我们测量样本特征的分散程度时,我们会得到一个标准误差。每个随机样本的结果都是不同的,因为选择样本的机会取决于某种概率。实际上,人口的分布可能是未知的,但是如果样本量足够大,抽样分布将类似于正态分布,也称为 CLT。随着样本量的增加,标准误差减小。在估计总体参数时,我们置信度的大小与我们在抽样分布中移动的标准偏差数成比例。这个数量级充当具有标准误差的乘数,乘数的选择取决于总体方差是否已知以及样本量是否足够大。

下面给出了本主题涉及的一些常规&常用代码;

Excel 对等数据(资料来源:Self)

访问本文中使用的“客户服务时间”示例数据集的链接是此处的。

本文的目的不是关注任何特定的工具箱,而是提高认识,熟悉这种性质的问题,然后根据需要使用各种工具箱。我并不羞于欢迎我在各种工具中天真和低效的编程风格,然而,如果我的任何读者希望重现我们在上面读到的形式(而不是数字),这里的是笔记本的链接。

使用置信区间是一种特殊的估计。我们将在下一篇文章中讨论另一种称为假设检验的方法。

guesstimate =比猜测好,但不像估计那样有保证

统计语言模型

原文:https://towardsdatascience.com/statistical-language-models-4e539d57bcaa?source=collection_archive---------23-----------------------

从简单到++包含用例、示例和代码片段

凯利·西克玛在 Unsplash 上的照片

在 NLP 中,语言模型是字母表上字符串的概率分布。在形式语言理论中,语言是字母表上的一组字符串。NLP 版本是形式语言理论的一个软变体。

NLP 版本更适合建模自然语言,如英语或法语。没有硬性的规则规定语言中应该包含哪些字符串,不包含哪些字符串。相反,我们有观察工作。人们写作。人们议论纷纷。他们的话语是这种语言的特征。

重要的是,NLP 统计版本有利于从示例中的字符串学习语言。考虑学习一个识别产品名称的模型。训练集可能包含 iPhone 4 和 iPhone 5,但不包含 iPhone 12。它应该会将 iPhone 12 识别为产品名称。

在这篇文章中,我们将从简单到详细地介绍统计语言模型。涵盖的模型包括:独立模型、一阶马尔可夫模型、k 阶马尔可夫模型、隐马尔可夫模型、条件马尔可夫模型和条件随机场。每个都用真实的例子和用例来说明。

下一个令牌概率

我们将语言定义为字符串的概率分布。在许多用例中,我们真正想要的是给定当前字符串下一个符号的概率。事实证明,这两者是等价的,如1中所述。

考虑字母表上的一个字符串。(字母表可以由字符或单词或其他记号组成。)表示这个字符串 x 1、 x 2、…、 x n .我们可以把 P ( x 1、 x 2、…、 xn )写成P(x1)**P(x【T33*

用例

我们能用语言模型做什么?相当多。

建议自动完成。智能手机会在我们打字时自动给出建议。当我们开始输入查询时,网络搜索引擎会提供自动完成的建议。在引擎盖下,这些是由语言模型驱动的。

辨认笔迹。想象一下,把你的智能手机指向你手写的笔记,并要求它们被识别。也许是数字化和可搜索的。或者至少让它们清晰可辨!

手写识别具有挑战性。甚至人们经常会弄错。有时甚至是他们自己写的!

考虑尝试识别书写糟糕的文本中的单词。纯粹的图像处理方法会产生很多错误。增加一个语言模型可以减少很多。语言模型提供了一个有用的上下文。

例子 1 :让我们用一个简单的例子来看一下。想象一下 OCR 认为下一个单词是数据库e 被误认为是 c 。他们看起来很相似。

现在让我们添加一个根据英语单词训练的语言模型。特别是将高概率分配给看起来像英语单词的字符串,而将低概率分配给不像英语单词的字符串。 bath 会获得大概率,但 axbs 不会。

这个语言模型会知道数据库databasc 更有可能。因此添加它将有助于检测和纠正 OCR 的错误。

通过添加多词语言模型,我们可以进一步提高错误检测和纠正的准确性。这个模型的字母表是词汇。它的高概率字符串模拟高概率单词序列。字母表变得越来越大。字母表里有每一个不同的单词。因此,在避免成本(模型变得过于复杂)的同时,需要小心谨慎地获取其好处。稍后将详细介绍。

多词语言模型还可以帮助填充书面文本中缺失的词。

检测并纠正拼写错误。我们将重新解释同一个例子数据库。最后一个字符, c ,现在是拼写错误。

识别语音。类似的推理在这里也成立。除了模态不同。所表达的基本语言是相同的。这并不是说准确的手写或语音识别很容易。只是添加语言模型会有所帮助。

识别多标记命名实体。多标记命名实体通常具有语言结构。例如,在一个人的名字中,名字通常出现在姓字之前。夹在两者之间的可能是中间名词。作为另一个例子,在美国街道地址中,街道号码通常出现在街道名称之前。正如我们将在后面看到的,这样的实体通常是通过潜在的语言模型来识别的,比如隐马尔可夫模型。

现在我们已经看到了一些用例,让我们深入了解

型号

我们将字符串表示为x 1, x 2,…, x n。

独立。这是最简单的方法。它假设字符串中的所有字符都是独立生成的。

P ( x 1、 x 2、…、xn)=Q(x1)Q(x2)Q(xn*)。

这里 Q 是字母表上的概率分布。

这种方法通常对大型字母表中的长字符串有效。比如有很多单词的文档。文本被看作是单词的序列。字母表是词汇。

在这种情况下,更复杂的方法会很快变得复杂,因此它们需要令人信服地工作,并显著地更好地证明它们增加的复杂性。

这种方法可以有效地检测文档的语言。对于每种语言,我们将训练一个单独的 Q,它是在该语言的训练集中看到的单词的分布。对于表示为单词序列 W1 W2 … Wn 的新文档 W,我们将为我们已经建模的每种语言 L 计算 PL(W)= QL(W1)* QL[W2]…QL[Wn]。我们认为 L = argmax_L PL(W)是 W 的语言。

举例 I1: 按语序训练狗在摇猫尾巴。我们得到 Q(the)=2/7,Q(is) = 1/7,等等。

Python 代码 I1 :没有测试,甚至没有运行。另外,需要一个传令兵。

from collections import Counter
import mathclass IndependentModel:

    **def __init__(self):**
        self.ctr = Counter() **def train(self,words):**
        for word in words:
            self.ctr[word] += 1 **def Q(self,word):**
        return float(self.ctr[word])/self.ctr.values() **def P(self, words):**
        return math.prod(map(lambda word: self.Q(word), words))

练习 I1 :将这段代码片段发展成一个语言识别器。说英语 vs 法语。

一阶马尔可夫模型。这里,一个符号允许依赖于前一个符号。

P ( x 1、 x 2、…、xn)=Q(x1)Q(x2 | x1)Q(xn | xn-1*)

一阶马尔可夫模型由状态转移矩阵 P 描述。 pij 是从状态 i 到状态 j 的概率。表示 xtixt +1 为 jQ ( xt +1, xt )等于 pij

这个马尔可夫模型也可以表示为有向图。如果值 i 后面可以跟一个值 j ,则有一个弧 ij 。这条弧线上有一个概率p(j|I)。图形表示仅仅明确了哪些状态转移概率为 0。

例 1M1: 一阶马尔可夫模型对短短语建模有效。假设我们想从大量的英语文档中发现突出的短语(每个短语包含 2 到 4 个单词)。一阶马尔可夫模型在足够富裕以至于能够做合理的工作,而不会变得太复杂之间取得了良好的平衡。

考虑文本数据挖掘是一个短语。数据挖掘是一种从大型数据集中提取有意义信息的方法

从这个文本,我们将建立马尔可夫图。该图的节点是出现在文本中的不同单词。如果在文本中单词 u 后面至少有一次单词 v ,则从节点 u 到节点 v 有一条弧线。下面显示了一些弧线。

data → mining   mining → is    method → of  extracting → meaningful

我们看到 P ( 数据挖掘 ) = Q ( 数据 )* P ( 挖掘 | 数据 ) = (2/19)1。相比之下, P ( a)=q(a)**p(|a)=(3/19)(⅓)= 1/19<p(数据挖掘可惜, P ( ,a) = P ( 数据挖掘)。所以(是*)会是一个误报,因为它不是一个显著短语。

因此,一阶马尔可夫模型本身虽然有些用处,但也有明显的假阳性。向这种方法添加语法信息,特别是单词的词性标签,可以显著提高其质量。也就是说,(大部分)减少了假阳性而(几乎)没有遗漏真阳性。直觉告诉我们,突出的短语是由有利于某些词类的词组成的,尤其是名词。考虑(数据挖掘)。这两个词都是名词。考虑一下(一个)。‘is’是动词,是冠词。

我们不会详细讨论如何将这两种方法结合起来。主要是马尔可夫模型还是有用的。

Python 代码 1M1 :未测试,甚至未运行。另外,需要一个传令兵。

from collections import defaultdict, Counter
import mathclass FirstOrderMarkovModel: **def __init__(selfs):**
       self.ctr2 = defaultdict(lambda:defaultdict(int))
       self.ctr1 = Counter() **def train(self,words):**
       words_with_sentinel = [‘_B_’] + words
       for i in range(len(words_with_sentinel)-1):
          self.ctr2[words[i][words[i+1] += 1
          self.ctr1[words[i]] += 1 **def Q(self,word,previous_word):**
       return float(self.ctr2[previous_word[word])/
       self.ctr1[previous_word]) **def P(words):**
       p = self.Q(words[0],’_B’)
       for i in range(len(words)-1):
          p *= self.Q(words[i+1],words[i])
       return p

k 阶马尔可夫模型。在这个模型中,一个字符被允许依赖于前面的 K 个字符。

P ( x 1、 x 2、…、xn)=Q(x1)Q(x2 | x1)Q(xn | xn-1、xn-1*

通过将 K 设置为 2 或 3,这种方法可以发现比一阶马尔可夫模型更好的显著短语,而不会导致复杂性的巨大增加。我们说的“更好”是什么意思?考虑一个长度为 3 的短语。称之为 x 1、 x 2、 x 3。一阶马尔可夫模型丢失了信息,因为它假设 x3 独立于给定 x2x1 。二阶模型没有。P(x1)P(x2 |x*1)P(x3 |x*2, x 1)等于 P ( x 1, x

和以前一样,仍然需要把统计方法和语法方法结合起来。

示例 KM1: 我们想对三个单词的产品名称建立一个二阶马尔可夫模型。为什么是二阶?考虑这些编造的例子: 4k 电视三星3k 电视索尼,…想象一下索尼不提供 4k 选项。如果我们使用一阶马尔可夫模型,我们将失去第一个单词(4k 或 3k 或…)和品牌名称之间的相互作用。二阶模型将捕捉这种相互作用。换句话说,产品名称不仅会受到第二个词(在我们的例子中是 tv)的影响,还会受到第一个词(4k 或 3k 或……)的影响。

隐马尔可夫模型

这里,字符串是从具有潜在变量(即隐藏状态)的模型中概率性地生成的。

用符号表示,让 X = x 1、…、 xn 表示一串长度为 nS = s1 、…、 sn 表示一串与 X 相关的状态。符号 xi 由状态 si 产生。

X 称为观测序列;产生 X 的(隐藏)状态序列。

在结构上,HMM 是状态集上的一阶马尔可夫模型。一些州通过弧线与其他州相连。此外,每个状态在可观察的字母表上都有一个概率分布。

该模型生成一对( XS )如下。首先,它生成 s1。然后它以一定概率从 s 1 发出 x 1。接下来,它以一定的概率移动到状态 s 2。这个概率只取决于它来自哪里,即 s 1。发射的是什么,即 x 1,是无关紧要的。接下来,它以一定的概率从 s 2 生成 x 2。事情就是这样。

总之,HMM 生成器在生成状态和从这些状态生成可观测量之间交替。状态转移概率只取决于前一个状态。发射跃迁概率只取决于当前状态,即可观测物发射的状态。

例子 HMM1 :假设我们想要生成与真实句子相似的英语句子。特别考虑具有两种结构之一的句子

Article Noun Verb Adverb
Pronoun Verb

第一个结构的例句是男孩跑得快。第二个结构的例句是她唱

一个真实的句子生成器可以容纳更多的结构。我们选择两个,因为最大的洞察力来自于从一个到两个。

模拟这两种结构的 HMM 看起来像什么?首先,它有助于添加一个开始状态和一个结束状态。HMM 总是从开始状态开始,并在结束状态停止。开始结束状态称为静音。他们不发射任何令牌。

好了,现在来看结构,也就是连接各州的弧线。

begin → article → noun → verb → adverb → end
begin → pronoun → verb → end

请注意,有些状态会显示两次。这仅仅是由于呈现的限制。举个例子。由于 HMM 具有弧线 begin冠词begin代词,这实际上意味着 HMM 可以从 begin 状态以某个概率移动到冠词状态,并以另一个概率移动到代词状态。两个概率之和为 1。从状态开始HMM 必须移动到某个地方。

类似地,从状态动词我们可以移动到状态advorb或者移动到状态 end 。注意,HMM 没有跟踪我们如何到达状态动词,这意味着状态序列开始文章名词 动词 结束也是可能的,尽管我们没有要求这样做。如果我们希望 HMM 能够生成诸如男孩吃了之类的句子,这种类型的概括是好的,否则就是坏的。

训练:我们可以很容易的训练出这个车型的排放参数。我们可以利用这样一个事实,即我们的状态是命名的实体,它们的训练集很容易获得。很容易收集构成冠词的词,构成名词的词等等。

接下来,我们研究训练状态转移概率。例如,我们需要估计从开始状态到结束状态的概率。这是小于 1 的 as 从状态开始我们也可以用状态代词来代替。

为了训练转换,我们假设我们可以访问单词附有词性标签的句子。这种类型的丰富训练集很容易组合。很容易得到大量的句子。通过在每个句子上运行合适的词性标注器,也很容易得到这些句子的词性标注序列。

HMM 的转移概率很容易从这样的训练集中训练出来。事实上,我们只需要每个句子的词性标签序列。让我们来说明这一点。弧线 beginarticle 上的概率估计为第一个标记为 article 的词性标签序列数除以第一个标记为 article代词的词性标签序列数。

两个生成的句子

来看看几个。第一个在下面。

 The     boy     is     fast
           ^       ^      ^       ^
           |       |      |       |
begin → article → noun → verb → adverb → end

我们从状态开始开始,走到,从它发出,走到名词,从它发出男孩,等等。t

第二个在下面。

 She     sings
          ^        ^
          |        |
begin → pronoun → verb → end

我们从开始,走到代词,从中发出,移到动词,从中发出,最后走到结束并停留在那里。

与独立:相比之下,想象一下独立模型生成的句子。单词会根据它们的概率被吐出来,而不考虑想要的结构。

特定位置独立模型 aka 链 HMM

在某些用例中,生成的符号会受到它们在字符串中的位置的显著影响。举个例子,考虑产品名称,比如 iPhone 11佳能相机索尼电视。显然有一些连续的结构。在这些例子中,品牌名称(佳能索尼)先于产品类型(相机电视)。

独立模型的位置特定的一般化适合于这种建模。

P ( x 1、 x 2、…、xn)=Q1(x1)Q2(x2)Qn(xn*

这里 Qi 是字母表上特定于位置的概率分布。所以对于 n 个位置,我们有 n 个分布 Q 1,…, Qn

特定于位置的独立模型可以被视为 HMM,其状态 12 、…、 n 分别表示令牌位置 1 至 n 。这样一个 HMM 的图是一个单向路径 1 → 2 → 3 → … → n 。因此,所有弧上的转移概率都是 1。HMM 的参数是特定位置的发射概率。我们将称这样的模型为链嗯

链式 HMM 几乎不是 HMM,因为它没有任何马尔可夫性。也就是说,将它作为 HMM 调用是有用的。它根据需要提供增强模型的途径。

这种增强版本的一个例子通常用于生物分子序列分析。它的名字叫做简介嗯【3】。简档 HMM 是一个链式 HMM,其中添加了一些明智选择的状态和转换,以在某些位置偏离链。迂回路径在某些其他位置合并回链。迂回路径模拟位置特异性突变。在生物分子序列中,这种突变经常发生。捕获它们的模型更准确地识别模型家族中生物分子序列的成员。

与位置特定链 HMM 不同的增强路径是进入所谓的条件马尔可夫模型(CMM)。我们将在本帖的后面讨论 CMM。在下面的例子中,我们还将说明从链式 HMM 迁移到 CMM 的好处。

CHMM 公园名称示例:假设我们想要模仿美国的国家公园或州立公园名称。比如黄石国家公园、约塞米蒂国家公园、城堡石国家公园……连锁嗯是个不错的选择。

这个 HMM 将从国家公园和州立公园的名称列表中训练出来。我们将设置 n 为列表中一个条目的最大字数。链式 HMM 的特定位置发射概率易于估计。公园名称的标记化版本揭示了其中每个单词的位置。比如约塞米蒂国家公园约塞米蒂是第一个字,国家第二,公园第三。因此,从公园名称中的一个标记,我们可以知道要训练哪个州的排放概率。

上面的模型因其简单性和灵活性而吸引人。只要在一系列公园名称上训练它。随着列表变得更加丰富,模型会自行改进。

这样说,似乎有点不自然。我们心目中公园名称的自然模式是

word+ ( state | national) park

这只是意味着一个公园名称有一两个单词后跟国家后跟公园

下面的模型更接近我们寻求的自然模型。

例子 HMM-Park-Names :这里我们会用到三种状态:前缀 _ 字地区 _ 字公园。state regional_word 会发出 statenational (暂时),概率相等(暂时)。state prefix_word 会发出一个出现在 regional_word 之前的公园名称中的单词。状态 park 将以概率 1(目前)发出单词 park

状态序列的训练集很容易构造吗?我们只需要一些:

prefix_word regional_word park
prefix_word prefix_word regional_word park
…
prefix_word prefix_word prefix_word regional_word park

那为什么不使用正则表达式呢?HMM 更准确。考虑一下某些文本中的短语“国家公园。这个短语不是一个真正的国家公园。HMM 原则上可以通过分配从状态前缀 _ 字发出的非常低的概率来对此建模。**

其实这就把我们带到了如何训练前缀 _ 单词的发射概率这个话题上了?(目前,其他州的排放概率已经确定。)这里有一个简单的方法。列出国家公园和州公园的名称。去掉每个公园名称的最后两个单词。剩下的单词是前缀词。

国家公园可以扩展到放射海滩森林纪念碑、等。(在加州,州立海滩通常归入州立公园。)

为了更好地理解链式 HMM 和基于实体的 HMM 之间的权衡,让我们看另一个涉及两者的例子。

CHMM 产品示例:考虑一个链式 HMM 来对产品名称进行建模。(我们所说的“产品名称”是指特定的产品和产品类别。)我们可以使用一个经过训练的版本来识别非结构化文本中的产品名称,有些甚至还没有经过训练。

这个 HMM 将从产品名称列表中训练出来。培训类似于公园连锁嗯。记住,我们只需要学习(I)状态的数量和(ii)不同状态的排放概率。

这种 HMM 结构简单,易于训练。也就是说,我们下面描述的基于实体的版本可能会更准确。

示例 HMM-产品:

我们可以选择品牌令牌产品类型令牌产品版本令牌产品基本名称令牌作为我们的实体。示例值有 brand_token = 佳能product _ type _ token=相机product _ version _ token= 12,product _ base _ name _ token=iphone。我们的 HMM 的状态就是这些实体。

为什么每个实体的名字都以单词结尾 token* ?因为实体适用于单个令牌。因此,与“智能手机相关联的状态序列将是[ 产品类型令牌产品类型令牌* ]。**

为了训练这个 HMM,我们需要各种实体的训练集。这些训练集可以来自品牌、产品类型等的列表。我们说“派生”是因为如果列表包含多单词条目,我们就不能照原样使用它们。考虑将智能手机列为产品类型。由此我们会衍生出两个例子:智能产品类型令牌手机产品类型令牌

我们还需要状态序列来捕获标记化产品名称中的实体序列。我们可以手动构建这样的训练集。这并不难,因为产品名称往往遵循一些常见的约定。例如,在许多双字产品名称中,第一个名称是品牌,第二个是产品类型。我们已经看到一个例子:佳能相机。因此[品牌 _ 令牌 T23,T24 产品 _ 类型 _ 令牌 T25 应该在状态序列的训练集中。

从产品名称自动导出状态序列

手动构造状态序列会让我们走得很远。几个州序列涵盖了很多产品名称。也就是说,手动方法存在无法扩展到涵盖数百万种产品的强大工业强度模型的风险。产品名称可能跨越州序列的长尾。考虑状态序列[ 产品类型令牌品牌令牌 ]。一些产品名称遵循这一惯例。

事实证明,我们可以从标记化的产品名称中自动构造状态序列。这样,当我们向训练集添加越来越多的产品时,状态序列会自动从中提取出来。

****基本版本:基本思想是获取标记化的产品名称,并为其中的每个单词找到最可能的实体。我们可以这样做,因为我们有各种实体的(单词,实体)对的训练集。

让我们看一个简单的例子。

**canon camera ⇒ [canon,camera] ⇒ [brand_token,product_type_token]**

****精炼版:我们可以把这个基本思路精炼如下。和以前一样,我们对产品名称进行标记。然后,我们通过 HMM 运行令牌序列,以找到最适合它的状态序列。

这种改进使用了来自实体训练集和 HMM 状态转换的信息。因此,它可以更准确。

我喜欢把这种方法称为“引导训练”。我们手动初始化 HMM。这包括播种我们选择的任何状态序列。然后我们可以通过它运行标记化的产品名称,希望发现更多的状态序列。

为了能够发现新的状态序列,在初始化 HMM 时,我们应该允许从所有状态到所有状态的转换。(除了从状态开始到状态结束以及从状态结束的任何外出。)我们可以自动初始化这些转换的训练集,因此这些转换的初始概率非常低,尽管不是零。我们称之为伪训练。

我们通过“引导训练”发现的一些新的状态序列可能存在错误。所以这些应该由人类来审核。尽管如此,尽管有人在循环中,我们可能还是受益了。手动发现新的状态序列比管理自动发现的状态序列要耗时得多。

条件马尔可夫模型

就像 HMM 一样,条件马尔可夫模型(CMM)对(令牌序列状态序列)对进行操作。与 HMM 不同,CMM 被优化用于为给定的令牌序列寻找最佳状态序列。这到底是什么意思?这将在下面的例子中逐渐变得清晰。

也就是说,在本文中,我们不会讨论如何为给定的令牌序列找到最佳状态序列。我们将讨论如何对给定的令牌序列的特定状态序列进行评分。这种评分将暴露 CMM 中的“有条件的”部分。

示例 CMM1(第一部分)**:设想在(记号化的完整人名记号实体)对上训练一个语言模型,目的是用它来解析人名。解析意味着把一个人的名字分解成各个组成部分。如名字和姓氏。**

想想约翰·K·史密斯这个名字。模型应该可以推断出 K 是中间名词。即使训练集不包含从 middle_name_word 发出的 K

CMM 直接将其建模为

**P(state[2] = middle_name_word | state[1] = first_name_word, token[2] = K)P(state[2] = middle_name_word | state[1] = first_name_word)*P(token[2] = K | state[2] = middle_name_word)**

与 HMM 的建模方式相比,这有什么好处。

为了回答这个问题,首先让我们抽象出这个例子的细节。我们有 CMM 的P(S[I+1】|S[I], X [ i +1])对P(S[I+1】|S]这里 X [ i ]是第 i 个令牌,而 S [ i 是它被发出的状态。

CMM 方法可以被视为多项式分类器,其输入是一对( S [ iX [ i +1]),其输出是各种值 S [ i +1】的概率分布。这个公式有助于从输入中提取我们认为合适的任何特征。可能重叠。可能考虑到 S [ i ]和 X [ i +1]之间的相互作用。

我们现在可以在这个问题上使用任何多项式分类器算法。例如(多项式)逻辑回归、决策树或随机森林。

相比之下,HMM 不能捕捉到 S [ i ]和 X [ i +1]之间的交互。它也不能适应任意的特征。它也不能利用复杂的机器学习分类算法。另一方面,CMM 不能利用实体训练集。我们不再学习排放概率。

例子 CMM 1(已完成)**:让我们完成这个例子。从特征开始。从输入( S [ i ], X [ i +1])我们将提取特征状态 = S [ i令牌 = X [i+1】,令牌长度 =在中的字符数也就是我们有三个预测器:状态令牌令牌长度。每个都是绝对的。响应是 S [ i +1]的值。也是绝对的。**

为什么有这些功能?特性状态让我们模拟当前状态对下一个状态的影响。特性令牌让我们使用令牌的实际值作为其状态的预测器。这是有用的。某些令牌有利于某些实体。例如,约翰更有可能是名字而不是姓字。作为额外的奖励,我们可以免费获得状态令牌之间的交互,只要我们的学习算法能够利用它。(如果有互动那就是。)特性令牌长度很有用,因为我们知道令牌的长度有利于某些实体。名字或中间名通常只有一个字符。几乎没有姓。

我们来看几个训练的例子。我们将从(令牌序列状态序列)对开始。

*John   Smith                        John    K    Smith
first  last                         first middle last*

从这些出发,让我们为 CMM 公式推导一些训练实例。(我们不全部展示。)前三列列出了预测值。最后一个列出了响应。

***(previous)** **state**    **token**   **token's length**             **state**
       first          K             1                  middle
       begin         John           4                  first
       first         Smith          5                  last
         …             …            …                  …*

上面的第一个训练实例读作“(前一个状态等于第一个,令牌等于 K ,令牌长度等于 1)”导致下一个状态是中间的”。

示例 CMM 2(草图):考虑解析美国街道地址。为简单起见,假设它们具有以下形式

*street_num_word (street_name_word)+ street_suffix [unit_prefix unit_num_word]*

下面是几对标记化的美国街道地址及其实体。实体名称是缩写的,因此示例可以放在分配的空间中。

*123             Marine           Dr
street_num_word street_name_word street_suffix203             Lake             Forest           Ave
street_num_word street_name_word street_name_word street_suffix123             Main             St            Apt         22
street_num_word street_name_word street_suffix unit_prefix unit_num*

对于我们特性的设计,让我们从关注从令牌中提取的特性开始。令牌的哪些特征区分不同的实体?token 的实际值可以预测是 street_name_word 还是 street_suffix 还是 unit_prefix 。数字的存在预示着它是一个 street_num_word 或者是一个 unit_num_word

鉴于此,我们将从 input ( S [ i ], X [ i +1])中提取特征state=S[I],token=X【I+1】,proportion _ of _ digits _ in _ token【中**

条件随机字段

就像 CMM 一样,CRF 对( S ,X)对进行操作,其中 X 表示令牌序列,S 表示其状态序列。两个模型P(S|X),为给定 X 寻找高概率状态序列 S 的用例进行优化。

CMM 认为这是因为

P(S|X)= product _IP(S[I)| X【I-1】,S【I-1】)(CMM 1)

即状态 S [ i ]的概率是以前一状态 S [ i -1】和当前令牌 X [ i ]为条件的。

通用报告格式限制较少。也就是说,它容纳了更一般的 P(S|X)。

CRF 在无向图上操作,其节点模拟状态,其边模拟状态对之间的直接影响。这些影响是对称的。

在这篇文章中,我们将局限于线性链 CRF。它有这样的结构

**S【1】—S【2】—S【3】—S【n】

这只是模拟了一个状态受到前一个状态和下一个状态的影响。即 S[i]直接受 S[i-1]和 S[i+1]的影响。

在通用报告格式领域,线性通用报告格式是最接近 CMM 的模拟。所以让我们更详细地研究一下。

线性通用报告格式模型 P ( S | X )为

*P ( S |X)正比于 product _Iproduct _ fp(f)e^f(s[I-1】, S [ iX )

如果我们通过记录日志来定义一个分数 C ( SX ),这种直觉会更容易传达。

C ( SX)= sum _ I sum _ f w(f) f(S[I-1],S[i],X) (CRF 2)***

我们称之为 C 是因为我们认为它是一个兼容性函数。作为 S 的函数,C(S,X)在 P(S|X)中是单调的。因此,为了找到得分高的状态序列,C(S,X)同样适用。

什么是 f ?这是一个特征函数,对三元组(S[i-1],S[i]和 X)在某个维度上的兼容性进行评分。正值越多,兼容性越好。 w ( f )是 f 的重量。它控制兼容性的强度和方向。

我们可以选择任意多的特征函数。

在线性条件随机场里,我们有一组可能重叠的特征函数。每个应用于每个边缘。也就是说,他们可以使用来自 X 中标记的任何子集的任何信息。相比之下,cmm 只对( S [ i -1】, S [ i ], X [ i )三元组的兼容性进行评分。

在这一点上,最好看一个具体的例子,具体的特性函数。

示例 CRF 1 :考虑我们之前看到的一个示例的一般化版本。解析全局街道地址。概括地说,我们正在走向全球。

全球的街道地址有许多不同的格式。在某些情况下,街道编号在街道名称之前,在某些情况下在街道名称之后。有些以单位开始,有些以单位结束。(单元的一个例子是“Apt 30”。)这些只是其中的几个变种。

全球街道地址的质量也各不相同,取决于它们是否符合当地的格式。我们希望能够尽可能好地解析低质量的地址。

让我们看两个例子

***123 St Francis St
Rue du Vivier 15***

第一个是美国的,第二个是比利时的。除了街道编号和名称的位置之外,街道关键字的位置也各不相同。(在这些例子中,“St”和“Rue”是街道关键字。)

我们将使用线性链 CRF。

我们应该从标记化的街道地址中提取什么全局特征吗?想到两个:国家语言。****

语言和国家都会影响地址格式。这些因素相互重叠,但也有互补的影响。比利时和法国的地址就是这种情况,都是用法语写的。在某些方面,他们是相似的。在其他方面,他们不是。这是国家的问题。

有鉴于此,我们应该两者兼而有之。

我们将围绕这些构建两个特定的特性函数。

*****F1**: country-edge compatibilities: (S[i-1],S[i], country(X))
**F2**: language-edge compatibilities: (S[i-1],S[i], country(X))***

我们将添加第三个特征函数来优先选择与其标记状态兼容的令牌。

*****F3**: state-token compatibilities: (S[i], X[i])***

训练 : F1 和 F2 可以从标记有国家和语言的(符号化街道地址州序列)对中训练。从 S [ i -1】过渡到 S [ i 兼容国家和语言分数高的,不兼容的不要。可以从训练集中的(状态令牌)对中训练 F3。

延伸阅读

  1. https://www . cl . cam . AC . uk/teaching/1718/R228/lections/le C9 . pdf
  2. 最大熵马尔可夫模型
  3. https://www . ebi . AC . uk/training-beta/online/courses/pfam-creating-protein-families/what-are-Profile-hidden-Markov-models-hmms/#:~:text = Profile % 20 hmms % 20 are % 20 probability % 20 models,the % 20 alignment % 2C % 20 see % 20 figure % 202
  4. cs 838–1 高级 NLP:条件随机字段
  5. 条件随机场:用于分割和标记序列数据的概率模型

统计学习(二):数据采样和重采样

原文:https://towardsdatascience.com/statistical-learning-ii-data-sampling-resampling-93a0208d6bb8?source=collection_archive---------14-----------------------

来源:Iconic Bestiary,via shutterstock

统计抽样是从所有人群中抽取样本的一个子集。如今,机器学习模型变得更加复杂,并且将数百万个参数输入到最新的模型中,例如包含数百万个参数的 BERT 或 ResNet 模型。对于数据集的子样本,训练这样一个复杂的模型是相对高效的,虽然它通常需要几天到一周的时间。对数据进行二次抽样有助于确定参数网格搜索的更好性能。另一方面,在数据重采样方面,该方法为数据群体中的少数群体创建合成数据,或者使用来自原始数据集的复制数据。这有助于模型不过度适应包含大量数据样本的主类。

在本文中,您将了解到:

(1)流行的数据采样方法有哪些

(2)流行的数据重采样方法有哪些

(Python 中数据采样和重采样的应用

数据采样

有两种主要的数据采样方法:

  • 随机抽样:给数据子集等概率被选中。

参见下图 1,我们可以看到有 3 组不同大小的样本,以 1/n 的相等概率选择子样本

图 1:随机抽样

  • 分层抽样:给定每个类中数据集的不同大小,基于占总体的百分比从每个组中选择子集。

从下面的图 2 可以看出,有 3 组不同大小的样本,根据给定的每组相对概率选择子样本。因为有 12、12 和 6 个数据点分散在 A 组、B 组和 c 组中。选择子样本的概率为 2:2:1,由组的大小决定。

图 2:分层抽样

统计重采样:

创建数据集副本的有效方法是估计模型参数。而且,这个过程要重复几次。

两种流行的重采样方法:

  • K-Fold 交叉验证:一个数据集被分成 K 组,一定数量的数据集将被分配给训练数据集,而保留的数据集将被分配给测试数据集。当训练数据集相当小时,应用这种方法以避免过拟合问题。
  • BootStrap: 虽然数据集不遵循任何特定的分布,如正态分布、X 平方分布和 T-student 分布,但 BootStrap 可用于评估数据集下的统计数据和潜在分布。从下面的图中,首先,从原始数据集中抽取一组子样本。然后,我们以固定长度(n)从初始子样本重新取样 B 次,而不考虑从提取中抽取的重复样本。对于每个 bootstrap 样本,使用参数(θ)进行估计。因此,bootstrap 是当一种常见的方法是估计量(θ)采用经验分布函数时,用于逼近概率分布的一种方法。

来源:自举方法介绍

重新采样:

来源: 不平衡数据集的重采样策略

给定不平衡的数据集,我们经常面临的问题是大多数数据属于主要类,而少数数据属于少数类。为了克服这种不平衡数据的模型训练的不良性能,主要建议使用过采样和欠采样技术来产生落入每一类的均匀分布的数据。

现在,我将浏览示例数据集

(A)使用 Python 包的欠采样

python imblearn 中有几种欠采样算法可以应用。(1) ClusterCentroids: 使用 K-means 方法的质心,合成每个类的大小,以减少数据。注意数据应分组为簇,以应用簇形心方法

(2) RandomUnderSampler: 为目标类选择数据子集,以平衡数据集。它通过将替换参数设置为真来启用引导方法,同时从每个类别中独立抽取子样本。

更多关于使用 Python 的欠采样方法的参考可以在 这里 找到

过采样(合成少数过采样技术 SMOTE)

该技术用于在特征空间中选择最近邻,通过添加一条线来分隔样本,并沿着该线产生新的样本。该方法不仅仅是从寡不敌众的类中生成副本,而是应用 K 近邻来生成合成数据。从下面的图 3 中,蓝色圆圈是原始数据,红色圆圈中的另一个蓝点是最近的邻居,粉红色的点是合成的。链接到 文章 了解更多关于 SMOTE 算法的细节。

情节 SMOTE 是如何工作的

动手对信用欺诈数据应用重采样方法:

这些数据用于检测 Kaggle Challenge 的交易是正常交易还是欺诈交易。为了保护信用卡信息中的个人隐私,通过主成分分析(PCA) 方法对特征进行了缩放,并将特征的名称以及总额和类别重新命名为 V1 至第 28 版,其中 0 和 1 表示欺诈交易,0 表示其他交易。

交易数据中不平衡类的百分比

从下面的柱状图可以看出非欺诈数据99.82% ,而欺诈数据0.17%

阶级分布条形图

如何处理这样不平衡的数据集?

子样本。将班级平均分配为 50 人和 50 人,这样模型可以为每个班级学习相同的样本量。

对主要类进行欠采样,并使数据大小与少数类相匹配

平均分布类的条形图

注意:拆分数据用于模型训练和评估

在进行随机欠采样或过采样之前,我们需要分离原始数据帧。目的是测试非来自手动合成数据集的原始数据。

结论:

通过这篇文章,我们了解了一些流行的数据采样和重采样方法。遇到不平衡的数据集问题或拥有庞大的数据集是很常见的。为了克服过拟合问题,进行数据采样方法以从中抽取子样本确实是一种有效的方法,而数据重采样(如过采样和下采样方法)是平衡每类数据的好方法。最后,python 中的代码展示了如何在每个算法上生成数据重采样方法并应用于数据集。享受周末:)

来源:memeshappen.com

感谢您对本文的关注。请在下面留下你的评论,并欢迎任何反馈。作为一个写这篇博客的初学者,我会发表更多与数据科学相关的文章。如果你是数据爱好者,请关注我的 敬请期待:)

统计学习(三)基于树的方法

原文:https://towardsdatascience.com/statistical-learning-iii-tree-based-method-fdade017bee7?source=collection_archive---------58-----------------------

浏览装袋、随机森林和助推的概念。使用 python 进行随机森林和梯度增强的实际体验。

尼基塔·万托林在 Unsplash 上的照片

如今,越来越多的人喜欢应用基于树的模型来处理回归和分类方面的机器学习问题。使用基于树的模型有几个好处,比如输出更好的结果、易于使用以及知道特征的重要性。另一方面,它需要更多的计算能力,并经常导致过拟合问题。基于树的方法可以关注线性回归和分类问题。这篇博客文章将进一步阐明分类问题。

在本文中,您将了解到:

(1)基于树的模型的测量值

(2)介绍装袋、出袋误差、随机森林、助推。

(3)随机森林和梯度增强在 Python 中的应用

基尼指数:I 级总方差的量度,p(i)代表分类到第 I 级的概率。值的范围从 0 到 1,其中 0 表示大多数元素属于某个类,1 表示所有元素随机分布在各个类中。

基尼指数

交叉熵:交叉熵对概率值取对数,优点是照顾低概率值。这种函数将防止概率值减小,并用于分类模型的损失函数。在其他讲座中,熵被称为树分裂指数。熵和交叉熵都可以用于基于树的模型中的分割方法。

交叉熵

基尼指数和交叉熵都被用来确定分类树上分支的分裂。当父节点的基尼指数或交叉熵高于左右子节点的平均值时,就会发生分裂。你可以链接到“关于基尼指数和交叉熵的更多细节”的文章。

制袋材料

装袋的目的是克服决策树的高方差问题。Bagging 是决策树的常用方法,它依赖 bootstrap 来减少统计学习方法的方差,而 bootstrap 是一种常用的统计重采样技术来近似采样分布。假设有 A1,A2,…..一个 n 独立的例子,每个例子都有方差 σ,例子的平均方差给出为 σ /n 。因此平均法有助于减少方差。换句话说,bagging 从训练数据集中获取几个自举样本,并计算所有预测的平均值。的确,装袋可以改善方差的减少,尤其是对于决策树环境下的回归问题。就分类而言,bagging 将对测试集中的预测类进行多数表决。

袋外误差估计

打包总是分别采用增强的示例子集来拟合模型。平均而言,每棵袋装树占总自举观测值的三分之二,剩余的三分之一称为袋外(OOB)观测值。每次模型在第 1 次 OOB 观测时进行预测,根据分类误差对预测类取 RMSE ( 回归)或多数票(分类)。对于 bagging 来说,从大数据集估计 OOB 测试误差相对方便,而对于大的计算资源,则需要交叉验证方法。

随机森林

随机森林是一种在自举训练示例上结合几个决策树的方法。查看树上的每个分割,从所有 p 个预测因子(m∞√p)中以 1/m 的随机样本进行分割,而每个决策树中总共有 m 个预测因子。

变量(特征)重要性

为了解释基于树的方法的结果,树结构图通常是一种很好的方法,可以看出考虑到分裂方法的每个方差中的基尼指数有多高。总体来看,套袋分类树考虑了基尼指数,而 RSS(残差平方和)则是套袋回归树。只要模型变得更复杂,就很难分析袋装树增加时每个方差的重要性。对于回归和分类,当每棵树形成时,RSS 和 Gini 指数的值将在每次分裂中降低。然后,在每棵树中累加减少的值。然后,随机森林模型取所有树中值的平均值,而值越大,预测值对模型性能的影响就越重要。

随机森林装袋法

一般来说,随机森林方法优于 bagging 方法,因为随机森林模型更有效地减少方差,并使其在模型性能上更可靠。在袋装树的集合中,大多数树被顶部的强预测器分割,因此每棵树产生相似的性能并具有高度相关的结果。因此,取高度相关树的平均值比取不相关树的平均值要差得多。另一方面,随机森林能够通过为每次分裂考虑预测因子的子集来避免该问题。由于 p 是每棵树中的预测值,m 是预测值的总数,所以 (p-m)/p 分裂的平均值不仅会选择强预测值,还会选择其他预测值。因此,每棵装袋的树最终都被去相关并更好地减少差异。

从下图可以看出,函数 m ≈ √p 优于其余两个函数,因为 m ≈ √p 用于随机森林分类器中的预测函数,而 m=p 代表打包函数。当参数 p 等于 500 时,我们可以看到,当树在 450 左右生长时,测试误差线变得稳定。

摘自《统计学习导论》第 322 页

助推

与 bagging 不同,boosting 不为每个决策树获取引导样本,而是使用来自前一个树的信息按顺序生长每个树。每一次,树都基于残差来拟合模型。当随后的树被输入到拟合函数中时,残差保持更新。因此,改进的拟合函数允许树以不同的形状生长,这有助于减少残差。同时,这种统计方法学习缓慢,因为收缩参数λ减慢了该过程。

关于三个主要参数的更多细节描述如下:

  • 树的数量(B) :交叉验证用于选择 B。与套袋和随机森林相比,当 B 较大时,套袋会导致过度拟合。
  • 收缩参数(λ) :已知 boosting 的学习率,在 0.01-0.001 之间。为了获得良好的性能,小λ 伴随着 B 的大值。
  • 每棵树中 d 分裂的数量:它指的是增强系综的复杂度。d 变量决定了模型的交互深度,d 输出树中的 d+1 个节点。

摘自《统计学习导论》一书,第 323 页

实践经验:

我们将使用 Python 包遍历应用于示例数据集的基于树的模型。该数据集是《ka ggle:Titanic——灾难中的机器学习》中最受欢迎的用例。这个用例是用机器学习算法预测泰坦尼克号上的生存。kaggle 网站链接:泰坦尼克号数据集。在通过基于树的模型深入研究预测方法之前,让我们先了解一些基本方法,以便为预测准备好训练和测试数据。数据集已经过预处理,以排除空值低相关列,并为文本特征创建虚拟变量

随机森林:

为了生成下面的简单树形图,模型设置有参数 max_depth=5,max_leaf_nodes=15,其中通过相对减少杂质来选择 max_leaf_nodes 。叶节点是下面没有任何子节点的末端节点。

生成树形图的代码片段

随机森林模型中的树图

注:

  • Link1Link2 :关于如何从随机森林模型生成树图的更多细节
  • 需要 GraphViz 开源工具。建议通过 brew 命令行安装,而不是通过 pip

根据模型结果,利用不同的特征对随机森林的分类问题进行预测。使用基尼系数的平均下降值计算特征重要性值

功能重要性代码片段

在 Python 中提升模型

XGBoost V.S. AdaBoost V.S .梯度升压

XGBoost: 应用牛顿推进,提供了到达局部最小值的路径,但不是通过梯度下降。

AdaBoost: 更新误分类数据点的权重

梯度推进:通过残差计算的损失函数更新预测器

几篇很棒的文章给出了每种提升方法的详细信息。
链接 1链接 2链接 3

梯度推进分类器:

梯度增强代码段

随着估计数的增加,模型过度拟合的可能性越大。建议进行参数调整或指定其他参数来克服过拟合问题,而不是最大化决策树的总数。

从下面的图中,我们可以看到整体提升模型的性能比随机森林模型好得多。很明显,深度 1 模型比深度 2 模型显示出更低的测试误差。

摘自《统计学习导论》一书,第 324 页

总之:

  • Bagging 使用 bootstrapped 方法,该方法获取训练数据的多个副本,拟合每个决策树中的每个重复样本,并组合所有树以获得预测模型。
  • 随机森林模型为每个决策树使用 boostrapped 示例。特征重要性值由基尼指数(分类问题)和残差平方和(回归问题)决定。
  • 当新树基于先前的树生长时,提升优于随机森林模型。此外,每棵树的深度越小,模型的性能就越好。在 Boosting 中,每棵树都从以前生长的树中学习,因此需要更多的时间进行训练。
  • 基于树的模型需要超参数调整,因为这通常会导致过度拟合。

来自HAPPY-WISHES.NET

享受漫长的周末!!

感谢令人敬畏的教科书:统计学习导论。我从中学习概念,并推荐读者阅读以了解更多细节。

统计学习(四):支持向量机

原文:https://towardsdatascience.com/statistical-learning-iiii-support-vector-machine-632df8da0b41?source=collection_archive---------51-----------------------

遍历最大间隔分类器、支持向量分类器和支持向量机。

Kit8.net从快门股票

S 支持向量机是一种常用于文本分类的模型。然而,SVM 也是一种适用于线性问题的机器学习算法。了解了 SVM 的概念,如超平面和核,您将更好地了解如何将该模型应用于回归和分类问题!

在本文中,您将了解到:

(1)用最大间隔分类器处理 SVM 上的线性问题

(2)非线性问题 SVM 核的引入

(3)SVM 在 Python 文本分类中的应用

最大间隔分类器

当数据点分布在多于 2 维的空间中时,应用超平面将它们分成两半。从下面的图中,它显示了两类观察结果,蓝点表示一类,紫色点表示另一类。对于左边的一个,它显示有 3 个超平面将数据点分成 2 类。对于右边的一个,数据点被分成两半,yi=1 属于蓝色类,yi=-1 属于紫色类。因此,数据点被分为两类,遵循以下等式:

B0+B1Xi1+B2Xi2+B3Xi3+.....+BpXip > 0 if yi = 1
B0+B1Xi1+B2Xi2+B3Xi3+.....+BpXip < 0 if yi = -1

摘自《统计学习导论》第 340 页

如何决定使用哪个超平面?

最大间隔分类器基于数据点和超平面内的间隔总和的值来决定最佳超平面。分类器通过从训练观察中选取最远的来选择超平面。最大间隔分类器的等式定义如下:

**yi(β0 + β1xi1 + β2xi2 +...+ βpxip)≥ M ∀i=1,...,n**

m 是应该最大化的超平面的边缘。
yi,…,yn∈{-1,1}属于标签
x1,…,xn ∈ Rp 属于训练观测值

分类器将通过选择 B0,B1,B2,…来最大化 M。,Bp 来优化问题。

然而,就非分离问题而言,不存在用于计算值 M >0 的超平面。为了概括这种困境,使用支持向量分类器来计算不可分离情况的软裕度。

支持向量分类器

支持向量分类器,也称为软边缘分类器,允许一些观察值出现在超平面或边缘的对面。

摘自《统计学习导论》一书的方程式,第 346 页

M 是页边距的宽度; C 为非负调谐参数;
ε1,。。。,εn 允许观测在不正确的一侧。如果 εi > 0 ,第 I 次观察出现在错误的一侧。c 是εi 值的总和,它决定了裕度能够承受的严重程度范围。当 C 变得更高时,裕度变得更宽,它容忍更多的数据违规,这导致高偏差和低方差。另一方面,当 C 减小时,裕度缩小,错误侧出现的观测值更少,从而导致低偏倚和高方差。因此,C 决定了支持向量分类器的偏差-方差权衡。从下面的图可以看出,C 从图 1 收缩到图 4,允许在超平面的窄边上出现更少的支持向量。

摘自《统计学习导论》一书,第 348 页

注意:如果边界是线性的以分离观察值,支持向量分类器仅支持 2 类分类。

注意,支持向量分类器仅用于分离 2 类问题,而支持向量机(SVM)能够处理具有多于 2 类分类的更复杂的非线性问题。

支持向量机

支持向量机使用在两个以上类别之间具有非线性边界的核来扩大特征空间。在使用核方法的基础上,我们将通过支持向量分类器的数学概念来处理线性和非线性问题。

根据下面的等式,它表示线性支持向量分类器,因为 SVM 需要观察值的内积。有 a_i⋯ a_n 训练观察。为了优化 F(x)函数,我们需要进行新点 x 和第 I 个观察点的内积。

线性支持向量分类器方程

基于内核的 SVM

  • 基于线性和多项式的内核

内核用于内积的推广。根据等式 1,k(x_i,x _ I’)被称为核函数,用于量化两个观察值的相似性。为了解决多项式问题,来自等式 2 的核函数适合于适应多项式次数 d >1 的高维空间。多项式核函数能够为分布在非线性模式上的数据点绘制灵活的决策边界。

核函数方程

  • 径向内核

径向核是另一个流行的非线性函数。根据下面的等式 3, γ 是一个正的常数。给定一个新的测试观察 x_ij,径向核函数用训练观察 x_i'j 计算欧几里德距离。当测试数据点远离训练数据点时,对两个更远的数据点的平方距离的负常数取指数会导致小的值。γ越大,支持向量分类器的输出性能越好。因此,k(x_i,x _ I’)的输出对支持向量分类器 f(x)函数几乎没有影响,如下面的等式 4 所定义的。换句话说,只有训练观测值 x_i'j 附近的测试观测值 x_ij 会对测试数据的预测类别产生本质上的影响。

核函数方程和基于核的 SVM

应用内核的优势

当应用核时,它减少了计算,同时它只关注位于 K(x_i,x _ I’)上的核函数的边缘的支持向量。另一方面,扩大的特征空间方法需要大的计算能力,因为会有无穷多个数据点落入更高维度的空间中。

Python 中的支持向量机

我们将使用 python Sklearn 包遍历示例数据集上的支持向量分类器。该数据集包括来自 IMDB 的 5 万部电影评论,用于自然语言处理或文本分析。这是用来预测消息是正面的还是负面的。Kaggle 网站链接: IMDB 数据集。SVM 很适合文本分类,所以这将是我们的主要预测文本分类模型。在通过支持向量分类器深入研究预测方法之前,让我们先了解一些基本方法,以便为预测准备好训练和测试数据。

文本数据集的预处理:

  • 剥离 html 标签
  • 删除标点符号
  • 删除停用词
  • 词干:把单词变成词根形式
  • 标记化

文本预处理的代码段

单词袋模型:

输入文本特征需要转换成机器学习模型的数字特征。以下示例通过 CountVectorizer 函数展示了词袋模型方法。它计算单词在整个文档中出现的次数(计数),并输出编码向量。输出向量通常是稀疏的。

CountVectorizer 的代码片段

SVM 模型

以下示例显示了将嵌入文本要素输入到 SVM 模型中。用径向核参数设定模型。

支持向量机的代码片段

sklearn 中 SVM 的参数调整

  • 内核:rbf(默认)、线性、多边形、sigmoid
    RBF:径向基函数内核
  • C:正则化参数
    C 控制误分类观测值的容差。较低的 C 值允许以较低精度为代价的较大裕量,并且对性能具有较低的方差。相反,较高的 C 值绘制较小的边界,对大多数数据点的分类性能较好,在决策函数上表现出较高的方差。
  • 伽马:它影响观察对模型性能的影响程度。较大的 gamma 值会扩大半径,从而考虑更多的观察结果,而较低的 gamma 值会绘制较小的半径。注意到较大的伽玛会导致过度拟合问题

SVM 网格搜索的代码片段

结论

  • 支持向量分类器使用超平面通过最大化边缘值来区分来自两类的数据点。
  • 核被应用于观测值的非线性分离,这减少了出现在标签类中的不正确观测值的出现。与线性核和多项式核相比,径向核对单个观测值的变化不敏感。
  • 为了使文本分类模型具有更好的性能,需要一种彻底的文本处理方法来获得干净的数据集。模型的参数调整可以提高模型性能。

参考:

请继续关注更多关于机器学习概念的初学者友好文章!☺️

统计学习(五):无监督学习

原文:https://towardsdatascience.com/statistical-learning-v-unsupervised-learning-f7adaf147b30?source=collection_archive---------67-----------------------

Web 开发矢量图形在GetDrawings.com

无监督学习是一项具有挑战性的任务,因为模型需要学习没有标签的数据模式,并且如果不将预测与来自观察的标签进行匹配,很难评估结果。例如,用户对商品推荐的购物体验是通过无监督学习来执行的。系统会根据搜索商品的历史和购物车中的商品列表向用户推荐感兴趣的商品。了解聚类分析方法后,您会更好地理解如何为数据集创建聚类标签。

在本文中,您将了解到:

(1)主成分介绍

(2)聚类算法中的 K-Means 聚类和层次聚类

(Python 中 K-Means 聚类在购物数据集上的应用

主成分分析

主成分分析是一种无监督学习方法,产生一组特征 X1,X2,…,Xp,在 n 个观察值上测量,其被认为是来自数据集的代表性变量。PCA 提供了一种工具来生成数据的表示,该表示捕获低维空间中的大部分信息。

主成分

它是 p 个特征 X_1,X_2,…的一组归一化线性组合。,X _ p .
φ_ 11,φ_21,…,φ_p1 的载荷向量构成一条线,使每个观测值 X_1,X_2,…之间的距离平方和最小..,X_p 到数据。为了约束加载向量,我们对φ值的平方和进行归一化,φ值等于 1。根据等式 1,Z_i1 被称为主成分得分。

主成分的数学公式

从下面的图中,左边的图(图 A)显示了第一个主成分。绿线由第一主成分负载向量构成,蓝点是两个特征的平均值。右图显示了旋转后的绿线,第一主成分作为 x 轴,第二主成分作为 y 轴。左下角的紫色圆点具有最大的负值,表明主成分得分 z_i 低于两个特征的平均值,右上角的 z_j 具有最大的正值,表明高于平均值的特征的 z_i 得分为正值。

图 1:带 PCA 的示例数据集

PCA 在缩放数据集上执行得更好。当对未缩放的数据执行 PCA 时,主成分加载向量将对具有较高方差的变量产生较大的值。

PCA 的例子

下面的剧情展示了美国的 15 个州以及城市警察袭击谋杀强奸的特点。就第一个组成部分而言,它在犯罪特征的负荷向量上显示出相似的权重,而在城市人口上显示出较小的权重。另一方面,相对于其他特征,城市人口特征更为重要。一般来说,犯罪特征被放置在彼此附近,这驱动了高相关性。因此,较高的强奸率导致较高的攻击或谋杀率。相比之下,城市人口变量与犯罪特征的相关性较小。进一步分析,加州、内华达州和佛罗里达州的犯罪率较高,但北达科他州等州的犯罪率较低。往第二主成分的垂直线看,加州也有很高的 UrbanPop 值。对于像弗吉尼亚州这样的中间点,它显示了犯罪和城市化的大致平均水平。

图 2:使用 PCA 的犯罪数据集示例

使聚集

k 均值聚类

K-Means 聚类算法是通过最小化类内变异来确定的。组内方差用 W(C_k)来计算,W(C _ k)是一个组内观测值之间差异的总和。

根据等式 3,它计算一个聚类中观测值的聚类内变化的总和,并对 K 个聚类中的值求和。根据等式 4,W(C_k)由第 k 个聚类中的观测值之间的平方欧几里德距离除以第 k 个聚类中的观测值总数来定义。等式 5 是等式 3 和等式 5 的组合。

K-均值聚类的数学公式

每个观察值被分配给 K 个聚类中的一个,因此聚类之间不应有重叠的数据点。然而,为了减少 W(C_k)的 K^n 计算时间,通过在每个聚类内提供局部最小值来优化算法。

从下图可以看出,该算法是通过以下过程实现的。

  • 将每个观察值随机分配给每个集群。
  • 步骤 2a:计算聚类质心
  • 步骤 2b:将数据点分组到附近的聚类质心
  • 在步骤 2a 中的第二次迭代之后:重新计算聚类质心
  • 当每个聚类内的观察距离最小化时,迭代不会停止,直到聚类质心分配完成。

图 3: K 均值聚类算法迭代

分层聚类

执行层次聚类就是绘制树状图的过程。它可以在水平方向上观察,因为在同一层中的分支的接近底部的观察结果更相似,而在融合了更多分支的树的较高层的观察结果则非常不同。创建了(n-1)个聚类,其中对于 1 个分支可以融合最少的 2 个点,并对系统树图进行 2^(n-1 重排,同时可以交换 2 个融合分支的位置。

该算法由相异度度量进行,相异度度量可以通过连接概念——平均、完全、单一和质心来实现。

  • 完全连锁:从每个聚类的所有成对观察值中取出最大相异值
  • 单个连锁:从每个聚类的所有两两观察值中取最小相异值
  • 平均连锁:取每个聚类中所有两两观察值的平均相异值。
  • 质心链接:计算聚类质心内的相异值。

算法

  • 从 n 个观察值中取 2 个成对观察值,并计算差异。每一对被视为一个集群。
  • 迭代从规模为 n,n-1,…,2 的群体开始
  • 融合最相似的两个聚类,这是由聚类间的不相似性决定的。树状图的高度代表聚类的相异程度。一个聚类的融合度越低,这个聚类就越相似。
  • 然后,取 i-1 个剩余聚类并计算聚类间的相异度。当人口数量减少到 2 时,迭代将停止。

如何确定层次聚类使用什么类型的相异度?

以网上购物为例,零售商根据顾客过去的购物经历对他们进行聚类,以识别相似顾客的子群。数据被转换成一个矩阵,其中一行是客户 id,多列是给定购物者购买给定商品的次数。有两种适用的相异度度量。

欧几里德距离:购物者将根据购物体验的频率被分组。也就是说,不频繁的客户更有可能被放入一个集群中。
基于相关性的距离:对所购商品有相似偏好的购物者(购买电子产品等商品的顾客被聚集在一起),即使购买者购买的商品量更大。基于相关性的度量被确定为按项目的类别对客户进行聚类。

您可以通过提供的链接找到更详细的层次聚类信息。

计算相异度时是否缩放特征?

当商品 A 比商品 B 更频繁地被购买时,通过欧几里德距离计算的相异度对商品 A 产生更大的影响,而商品 B 几乎没有影响。然而,物品 B 更可能是具有高价值的物品,并且零售商渴望鼓励顾客购买。此外,频繁购买的商品 A 的购买数量差异较大,与商品 b 相比,这提供了较少的关于购物者整体购物体验的信息

Python 中的 K-Means 聚类

我们将使用 python Sklearn 包对示例数据集进行 K-Means 聚类。该数据集包括超市购物中心的顾客购物历史的 200 个购买条目。这用于客户细分。Kaggle 网站链接:市场篮子分析。K-Means 可以很好地将观察结果聚类到特定的组中,因此这将是我们主要的无监督聚类工具。

对示例数据集应用聚类的目标是:

  • 如何用 Python 中的机器学习算法(KMeans 聚类)以最简单的方式实现客户细分?
  • 谁是你的目标客户,你可以从谁开始营销策略
  • 营销策略在现实世界中是如何运作的

数据集描述:

  • CustomerID,性别:分类特征
  • 年龄、年收入(千美元)、支出分数(1-100):数字特征

特征工程:

我创建了一个手动功能,将包含“”、“【k $】年收入”变量的组进行聚类。

K 均值聚类迭代的代码段

通过上面的代码,创建了集群数量的图表。使用肘方法,我们可以看到 4 是更好的集群数选择。

聚类数图

确定了聚类数后,我将 KMeans 模型拟合到具有 4 个聚类的数据集中。

k-均值属性:

聚类中心 _: 聚类中心的坐标。聚类中相异度最小的最优点。 标签 _: 每个点的聚类标签

K 均值聚类的代码段

下图将每个数据点显示为散点图,红点显示为聚类质心。

K-均值聚类图

从为数据集生成的分类中,我将分类标签指定为一个特征,并将数字特征转换为模型的分类特征。该模型用于根据年龄、年收入和分类的特征来预测每个客户的支出成本水平。

随机森林分类器的代码片段

最后

  • PCA 显示了观察值的低维表示,其解释了方差的良好分数。每个主成分关注不同的特征组。建议对缩放后的数据执行 PCA。
  • 聚类显示了观察值中的同类子群。对于 K-Means 聚类,它根据每个聚类中每个观察值的最小欧氏距离来生成每个聚类中的聚类质心。层次聚类基于相异度将两个观察值融合成一个聚类,并且显示了每个聚类的相似性水平的树状图。

参考:

1:加雷斯·詹姆斯、丹妮拉·威滕、特雷弗·哈斯蒂和罗伯特·蒂布拉尼。统计学习导论。第七版。斯普林格。

请继续关注更多关于机器学习概念的初学者友好文章!统计学习系列到此结束。☺️

集中趋势的统计测量

原文:https://towardsdatascience.com/statistical-measures-of-central-tendency-d8d4fbb70111?source=collection_archive---------22-----------------------

使用均值、中值和众数

照片由 erika mUnsplash 上拍摄

介绍

在统计学中,集中趋势的度量是代表数据点的一组“中间”值。集中趋势描述了集中在中心位置的数据分布,所有其他数据都围绕该中心位置聚集。与分散相反,它测量观察值相对于中心值分散到什么程度。

正如我们将在下面看到的,集中趋势是一个基本的统计概念,但却是一个广泛使用的概念。在集中趋势均值、中值和众数的度量中,最常被引用和使用。下面我们将了解为什么它们在数据科学和分析领域如此重要。

图:集中趋势的概念化测量

1。算术平均值

Mean 是一些数据点的平均值。这是最简单的集中趋势测量方法,取观察值之和,然后除以观察值的数量。

在数学符号中,算术平均值表示为:

其中 xi 是单个观测值,而 N 是观测值的数量

在一个更实际的例子中,如果 3 个餐馆雇员的工资是每小时 12 美元、14 美元和 15 美元,那么平均工资是每小时 13.6 美元。就这么简单。

平均值的应用

  • 我们在日常生活中做各种各样的平均。我们向朋友询问他们社区的平均房租;在搬到一个新的城市之前,我们计算每月的开支。我们每天都在各种情况下使用算术平均值。
  • 企业使用方法来比较一月和二月之间产品的平均日销售额。
  • 在数据科学中,平均值是探索性数据分析(EDA)中的一个基本指标,是各种高级建模的输入。Mean 在计算分类或回归算法中的 RMSE(均方根误差)、MAE(平均绝对误差)准确性度量时在幕后工作。

类型学

平均值有几个变体。这些不经常使用,但是在特殊的用例中是有用的工具。以下是一些例子:

加权平均值在普通平均值中,所有数据点都被平等对待,所有数据点都被分配了相等的权重(隐式)。在加权平均法中,根据目标,一些数据被赋予较高(或较低)的权重。

几何平均与普通平均不同,几何平均将 N 个值相乘,取乘积的 N 次根。因此,对于两个值 2 & 8,几何平均值将是 4。

调和平均值这是另一种平均值,通过取数据点的倒数,然后取它们的平均值,最后取结果的倒数来计算。

均值的局限性

尽管算术平均值是最广为人知的集中趋势的度量,但它不是一个稳健的度量;它对异常值非常敏感。

让我们考虑以下两种情况。在左边,四个值的平均值正好在数据集的中间。然而,在右边,仅仅一个异常值数据(16)改变了“重心”,并使平均值进一步向右移动。为了克服算术平均值的这种局限性,我们有另一种集中趋势的度量方法——中位数。

图:异常值对数据集算术平均值的影响(插图:作者)

2。中位数

列表[2,3,4]的中心是什么数字?答案当然是 3。这是中间值。如果同样的数字排序不同,比如说[2,4,3]呢?现在中位数是 4 吗?不,还是 3 点。所以中值是一个序列中间的数字,在之后,它们被排序(升序或降序)。

假设我们有一个由五个数字组成的列表[4,6,2,10,7],我们想找出中间值。过程很简单:

  1. 数据:[4,6,2,10,7]
  2. 排序列表:[2,4,6,7,10]
  3. 找出中间的数字:6(中位数)

但是如果列表中有偶数[4,7,6,2,10,8]呢?现在中间有两个值,所以在这种情况下,解决方案是取它们的平均值:

  1. 数据:[4,7,6,2,10,8]
  2. 排序列表:[2,4,6,7,8,10]
  3. 在中心找到两个数字:[6,7]
  4. 取平均值:6.5(中位数)

中间值的优点和缺点

为什么是中位数,用它来衡量集中趋势有什么好处?一个重要原因是,与均值不同,它对极端值不敏感。例如,在列表[2,3,4]中,最后一个值可能是 400,而不是 4,但是中值仍然是 3。

中位数的另一个好例子是数据的解释。中位数完美地将数据分成两半,因此,如果霍华德县的中位数收入是每年 100,000 美元,您可以简单地说,该县一半人口的收入高于 100,000 美元,而另一半人口的收入低于 100,000 美元。

但是,有一个明显的缺点。中位数使用数据点的位置,而不是它们的值。这样,一些有价值的信息就丢失了,我们不得不依靠其他类型的测量,如离差测量(下一节)来获得更多关于数据的信息。

用例

中位数的一些应用是众所周知的。你是否注意到美国人口普查局将家庭收入报告为“家庭收入中位数”?还是劳工统计局把美国人的工资报告为“工资中位数”?这是因为通过调查或普查收集的大量数据高度分散,既有极小的值,也有极大的值。在这种情况下,中位数是比平均值更好的分布中心的度量。

图:美国的平均工资和中值工资。( 来源:社保管理局访问时间:2020 年 7 月 19 日 )

3。模式

在一系列数字中,比如说[2,3,4,4],最常见的是 4;那就是模式。它也可以应用于文本数据,例如,集合{"John "、" Kelly "、" Nadia "、" John "、" Michael"}的模式是" John ",因为它在这个名称集合中出现了两次。

一个发行版可以有多个模式,如列表[2,2,3,4,4]所示;这叫做离散变量的双峰分布。按照这个逻辑,有两个以上模式的分销叫做多模式分销。

用例

  • 理解分布的模式很重要,因为频繁出现的值更有可能在随机样本中被选取。
  • 在一个城市中最常出现的名字是什么?风尚有答案。理解模式有助于解决自然语言处理(NLP)领域的更多此类问题。
  • Mode 可以帮助连锁杂货店计算出在一周、一月或一年的不同日子里哪种产品卖得最多。

摘要

总之,中心趋势是统计学和数据科学中的一组重要概念,它衡量一些观察值如何围绕一个中心值定位。算术平均值是数据点的简单平均值,中值是数据集中心的值,模式返回最频繁出现的值(数字或文本)。这些措施在数据科学中有大量的使用案例,从探索性数据分析到分类算法中的准确性度量,再到自然语言处理。

数据科学中的统计陷阱

原文:https://towardsdatascience.com/statistical-pitfalls-in-data-science-ad76e8ec0584?source=collection_archive---------35-----------------------

刻板结果如何改变人们头脑中的数据分布

有很多方法可以从给定的数据集中推断出大量不同的结果,但是也有无限多的方法可以从中得出错误的结论。谬误可以定义为不准确或错误推理的产物,通常导致人们从给出的数据中获得不正确的结果。

照片由 Unsplash 上的 Tayla Jeffs 拍摄

好的一面是,由于长期以来许多人都犯过这些错误,而且这些错误的结果在各个领域都有记载,因此识别和解释这些统计谬误就变得更加容易了。以下是数据科学家应该避免陷入的一些统计陷阱。

樱桃采摘

这可能是最明显和最简单的谬误,也是我们大多数人以前肯定做过的事情。摘樱桃的直觉很简单:故意选择数据点来帮助支持一个特定的假设,以其他拒绝该命题的数据点为代价。

摘樱桃降低了实验发现的可信度,因为它只显示了画面的一面

摘樱桃不仅是对公众的不诚实和误导,也降低了实验发现的可信度,因为它本质上只显示了画面的一面,遮蔽了所有负面的方面。这会让一个实验看起来完全成功,但实际上并非如此。

精选数据与所有数据— 来源

避免摘樱桃最简单的方法就是不摘!本质上,采摘樱桃是从业者有意为之,因此不是偶然的。在整理数据的过程中,为了进一步避免摘樱桃的可能性,人们应该使用来自大量不同背景的数据(尽可能地)来限制通常伴随有限视角而来的偏见。

数据挖掘

大多数人(尤其是那些不熟悉数据科学细微差别的人)认为数据分析意味着从各种数据中挑选出明显的相关性。这并不完全正确,因为数据分析通常需要逻辑推理来解释为什么存在某种相关性。如果没有一个合理的解释,仍然存在着机会相关性的可能性。进行实验的传统方法是定义一个假设,然后检查数据来证明它。相比之下,数据挖掘是一种实践,即做出符合假设的偶然关联,而不对关联的原因提供任何逻辑见解

数据挖掘有时被描述为从数据集中寻找比它实际包含的更多的信息

数据挖掘的一个分支是假因果关系,关于相关性的错误假设可能导致研究的最终失败。通常,两个事物之间的相关性会诱使我们相信一个事物导致了另一个事物,或者是由另一个事物导致的。然而,通常是巧合或其他外部因素导致一种或两种效应发生。数据科学家必须始终挖掘比表面上看起来更深的东西,超越简单的相关性,以收集证据来支持研究假设。

相关性并不意味着因果关系

过度拟合

过度拟合是大多数机器学习和数据科学从业者都很熟悉的一个术语。过度拟合是指创建一个极其复杂的模型的过程,该模型过度适应数据集,并且在一般化的数据上表现不佳。

用机器学习的术语来说,当一个模型在训练集上表现得非常好,但在测试数据集上却不能给出类似的结果时,就会发生过度拟合。John Langford 给出了实践中最常见的过度拟合类型的全面描述,以及帮助避免它们的技术这里

数据过度拟合— 来源

大多数数据科学家构建基于数学的模型来理解数据点之间的潜在关系和相关性。一个足够复杂的模型倾向于完美地拟合所提供的数据,给出高精度和最小的损失。也就是说,复杂的模型通常是脆弱的,当提供其他数据时会崩溃。简单模型通常更稳健,更善于根据给定数据进行预测。

辛普森悖论

辛普森悖论是一个很好的例子,它强调了在整理和实验数据时对真实世界良好直觉的需要。数据科学家需要认识并接受这样一个事实,即大多数数据是一个更大、更复杂的领域的有限表示。辛普森悖论展示了试图从单一角度看待复杂情况而将其过于简单化的危险。

辛普森悖论是以统计学家爱德华·休·辛普森的名字命名的,他在 1951 年的一篇技术论文中描述了以他名字命名的统计现象。陈述起来很简单,但对于没有接受过统计培训的受众来说,这往往是一个困惑的原因——当数据被分组时出现的趋势或结果,当数据被组合时,这种趋势或结果会逆转或消失。

当数据按特定类别分组时,总体趋势发生逆转— 来源

一个简单的例子可以很好地解释辛普森悖论。假设我们选取了板球比赛中两个击球手 A 和 B 的击球得分。在我们收集的数据中,A 总体上比 B 得分更多。但是,如果我们查看 A 和 B 的终身统计数据,就会发现 B 比 A 得分更多。

辛普森悖论,在某些方面,可以认为是无意的摘樱桃。这通常是由分布中的一个变量引起的,这个变量被恰当地命名为潜伏变量,它将数据分割成多个独立的分布,而且它们通常很难识别。

我们需要知道我们在寻找什么,并恰当地选择最佳的数据观点,给观众一个公正和完整的事实陈述

为了避免陷入辛普森悖论,数据科学家必须了解他们的数据,并对围绕和影响数据的一般因素有一个基本的概念。基于所有这些情况,应该以这样的方式收集和查看数据,即结果不仅美化假设(摘樱桃),而且如果从独立的角度来看也不会改变。

生存偏差

算法偏差最近获得了很多关注,并成为一个热门话题。然而,统计偏差和统计本身一样古老。生存偏差可以最好地描述为从不完整数据中得出结论。这些在使数据分析不准确方面起着至关重要的作用。

当数据集中提供的数据先前已经经过过滤过程时,会出现生存偏差。这会导致错误的推论,并会影响大量的分析。意识到偏差通常在数据科学领域非常重要,因为人类倾向于研究成功的结果并从中得出推论,而忽略伴随的失败。

只看成功的首席执行官,我们看不到完整的数据集,包括不成功的首席执行官和地球上可能碰巧早餐吃燕麦片的其他人

由于生存偏差来自不完整的数据集和研究输入,数据科学家可以应用一些技术来避免生存偏差,同时从数据中进行推断。这些包括但不限于多个数据输入、假想场景、对数据的上下文理解以及测试时增加的数据。

赌徒谬误

赌徒谬误是人类思维倾向于从数据中的常规相关性得出推论的另一个例子。赌徒谬误指出因为某件事最近发生得更频繁,所以现在不太可能发生(反之亦然)。然而,这在现实生活中并不成立。例如,如果一枚硬币连续 3 次正面朝上,人们会认为不可能连续 4 次正面朝上。然而,这是错误的,因为硬币仍然有相同的概率正面或反面落地。

同样的事情也发生在数据上。当多个数据点开始显示类似的未解释的相关性或矛盾时,数据科学家通常倾向于依靠直觉,而不是逻辑解释和公式,这往往会在推断推论时导致灾难性的后果。

当从数据中得出推论时,人们倾向于根据以前的经验凭直觉,而不是逻辑解释

理解“赌徒谬误”需要两个关键点:大数定律及其与回归均值的关系。大数定律表明,多次执行完全相同的实验的所有结果的平均值应该接近期望值,并且期望值和原始值之间的差异将与所进行的实验次数成正比。

向均值回归的概念还引入了回归谬误,该谬误假设当某件事情发生时,它异常地好或坏,随着时间的推移,它会回复到平均值。这种谬误经常被用来为研究或模型预测中产生的异常值寻找解释。

避免一个错误是朝着正确方向迈出的一步。避免谬误是迈向更好推论的一步。

统计陷阱:选择偏差

原文:https://towardsdatascience.com/statistical-pitfalls-selection-bias-18a05e3cf5a1?source=collection_archive---------34-----------------------

数据帧字节

迈克·贝当古的对话,我们讨论了选择偏差的常见统计和数据陷阱。

在每一集的 DataFramed、DataCamp 播客 中,我都会邀请行业和学术界的嘉宾来观看与数据科学实践相关的短片。我收到了很多对这些片段的脚本的请求,所以已经开始在媒体上发布它们。

下面是来自“统计陷阱”部分的关于选择偏差的对话,我有幸与统计学家、物理学家、统计建模和高性能统计计算平台 Stan 的开发者Mike betan court共同制作了这个对话。此对话出现在 本,DatFramed 第一集,19:25:

HBA :现在到了称为统计陷阱的环节。我现在和迈克尔·贝坦科特在一起,他是开源统计建模平台 Stan 的核心开发人员,他也在聚会上自称是曾经和未来的物理学家,伪装成统计学家。怎么了,迈克?

雨果,谢谢你邀请我。我在聚会上很有趣。

HBA :今天你在这里讲述一个常见的统计陷阱:选择偏差

MB :确实。在我们收集数据的任何时候,选择偏差都可能存在。然而,在谈论普遍性之前,我想首先通过考虑一个最著名的选择偏差的例子来证明它是多么微妙,这个例子来自统计学家亚伯拉罕·瓦尔德对二战的一项分析。

盟军军方感兴趣的是如何最有效地利用他们有限的资源来补充从战斗任务中返回的受损飞机的装甲。返回的飞机会在特定的位置受到损坏
,普遍的想法是在他们观察到损坏的地方增加更多的保护。

然而,这种想法隐含地假设返回的飞机代表了全部受损飞机。然而,Wald 和他的团队认识到,返回的飞机实际上是一个有偏见的样本,因为他们没有包括那些从未从任务中返回的飞机。

一旦他们理解了数据中的这种选择偏差,他们推荐了看似违反直觉的策略,即在返回的轰炸机未受损坏的地方加强装甲。他们意识到,如果潜在的损伤均匀分布在每架飞机上,那么返回飞机上的损伤实际上证明了什么损伤是可存活的。另一方面,对未受损区域的损害可能是至关重要的,会阻止飞机返航。

返回飞机的受损部分显示了它们可能遭受损坏但仍能返回家园的位置;在其他地方被击中的人无法幸存。(图为假设数据。)图片来自维基百科

HBA :这是选择偏差的一个例子,对吗?

MB :对,正是。统计学中最常见的陷阱之一是误解手头的数据完全代表了正在研究的系统。如果这是真的,随着我们收集越来越多的数据,我们将能够推断出关于该系统的任意精确的见解。

不幸的是,在实践中,我们的测量永远不会像假设的那样完美,事实是,每当我们收集数据时,我们都会忽略一些数据。如果我们想在实践中确保准确的推断,那么我们必须考虑这些选择偏差是如何破坏我们的数据的。特别是,我们必须考虑我们的测量过程如何优先忽略具有某些属性的数据,同时保留其他属性。

如果我们不这样做,那么我们从非常大的数据集中得出的推论将总是受限于它们能告诉我们多少关于我们正在分析的系统的信息。

HBA :选择偏差会是一个多大的问题?你如何对抗它?

选择偏差的确切后果既取决于选择机制本身,也取决于我们在给定的应用中需要多精确的推理。例如,如果我们是一家公司,我们试图了解利基人口如何与我们的产品互动,那么即使很小的选择偏差也会严重扭曲我们的洞察力。

最终,量化这些影响的大小,并确定是否需要考虑选择偏差的唯一方法是建立一个完整测量过程的数学模型。幸运的是,有越来越多的工具来促进这种复杂的建模,特别是像 Stan 这样的概率编程语言。

HBA :迈克,感谢你对选择偏差常见统计陷阱的精彩描述。

雨果,谢谢你邀请我。

链接:

股票价格的统计特性

原文:https://towardsdatascience.com/statistical-properties-of-stock-prices-15145be752a2?source=collection_archive---------13-----------------------

模拟股票市场的动态

图片由皮克斯拜的 Gerd Altmann 提供

在本文中,我将分析股票价格的统计特性。首先,我将证明,与大多数人的想法相反,收益的分布不是高斯分布。然后我将考虑 Lévy 分布,它有宽尾,因此在预测可能的崩溃和其他罕见事件时更有效。最后,将考虑相关性。同样,与从一开始相关性就为零的常识相反,真实的金融数据只有在某个时间间隔δt *(在此时间间隔之前,它是一个衰减的指数函数)之后才变得不相关。

股票价格的统计分析

股票价格的动态行为通常基于以下假设:

  1. 交易的连续性意味着报价之间有一个非零的间隔
  2. 价格演变为一个随机过程和基本面随机变量

等式 1:描述股票价格动态的随机过程中的随机变量。

它们都是独立同分布的(或 i.i.d. ),并且具有有限的均值 μ 和方差 σ。

3.ln S (t)的价格动态是一个扩散过程。扩散是某个物体从一个其浓度高于其他大多数地方的位置向外扩散的“T21”。

图 1:扩散过程的例子。当屏障被移除时,溶质扩散填充整个容器。

随机变量的增量被假定为高斯型。这个模型被称为几何布朗运动 (GBM)。一个 GBM 是以下随机微分方程 (SDE)的解:

方程 2:描述 GBM 的 SDE。

其中 W(t)是维纳过程或布朗运动其中 μ 称为漂移 σ 是波动率。解决方案是:

方程 3:方程的解。2.

图 2:图中显示了漂移μ变化时的几个 GBM 示例。

标准差 σ ( t )的指数接近 0.5,这意味着价格变化是独立的。

现在作为等式的结果。1,有限区间内的总报价数发散。因此,由中心极限定理

具有高斯分布。

图 3:CLT 的图示。通过对新的随机变量求和的“平滑化”,原来的密度分布收敛到一个高斯分布(来源)。

假设 1 显然是理想化的。我们应该建立一个 S ( t )和一个离散时间随机过程的模型,在这个过程中,报价有时会出现

其中δt 是一个有限区间。物理学家已经非常详细地研究了这些离散过程的性质。

股票收益

物理研究通常关注价格增量,而不是价格本身。如果δS(n)<<S(n),δt 很短,价格变化很慢(例如,在没有崩盘的情况下),可以做如下近似:

等式 4:随机变量的选择。

比较几何布朗运动的蒙特卡罗模拟;

图 4:布朗运动的蒙特卡罗模拟例子。

通过模拟布朗运动:

使用年度漂移 μ =10%,年度波动 σ =20%和相同的一组正态分布随机数 X ( n )我们获得了图 X(来自 W. Paul 和 J Baschnagel ),显示了非常可靠的一致性。

图 5:对于每日现货价格 S(t ),几何布朗运动(实线)和布朗运动(虚线)的蒙特卡罗模拟之间的比较。两者的漂移、波动性和选择的高斯随机数集是相同的()。

因此,可以对股票价格使用加法(而不是乘法)模型:

等式 5:回报的加性模型。

在加法模型中,价格增量相加,与乘法模型相反,在乘法模型中,连续的价格比率相乘。

数学插曲

莱维分布

等式 6:李维分布。

是由法国数学家p . le vy和苏联数学家 A.Khintchine 引入的非负随机变量的概率分布。Lévy 分布考虑了尖峰值(正的过度 cu 尖峰值)。

图 6:高斯分布和李维分布的比较。

Lévy 分布是一种稳定分布,其意味着拥有这种分布的独立随机变量的线性组合将具有相同的分布(取决于位置和比例参数)。因此,它们具有缩放属性:

等式 7:稳定分布具有标度特性。

图 7:自相似过程的例子。

然而,李维分布具有发散的标准偏差。此外,他们的最大值更大和更窄,我们知道这不会发生在真实的金融序列。

图 8:雪佛龙股票每日价格差异的对数和高斯分布之间的比较。尾巴更肥,最大值更大更窄(来源)。

这可以通过使用截断参数截断尾部来解决。截断征税飞行的一个例子是:

等式 8:截断的李维分布。

其中 Na 归一化常数。

图 9:法国数学家 p . le vy(来源)和苏联数学家 A.Khintchine ( 来源)

伯努瓦·曼德尔布罗是第一个注意到资产价格比高斯分布预测的更频繁地遭受巨大波动的人之一(它们更像是尖峰厚尾)。

在一篇著名的论文中,H. E. Stanley 和 R.N. Mantegna 使用了一组 1984-1989 年期间的 P500 数据来确定

等式 9:股票变动的定义 l。

图 10:美国物理学家 H. E. Stanley ( 来源)和意大利物理学家 R.N. Mantegna ( 来源)。

使用间隔δt = 1,…,10 分钟。他们的结果如下图所示。

图 11:S&P500 的价格变化 l 相对于δt = 1 分钟的 l/ σ 的概率分布。高斯曲线(窄曲线)与勒维分布的最佳拟合进行比较。后者在 l/σ ≤ 6 时要好得多,但在 l/σ ≥ 6 时呈指数下降(来源)。

下列 Lévy 分布非常符合 l/σ ≤ 6 的数据:

等式 10:l/σ≤6 时,Lévy 分布与数据非常吻合。之后,衰减是指数级的。

这个李维分布有两个主要的重要性质:

  • 它们的稳定性(自相似性)
  • 它们是概率空间中的吸引子

图 12:收敛到独立同分布稳定吸引子的过程示意图(来源)。

在截断生效之前,截断的 Lévy 分布在很长一段时间内保持自相似。

相关

几何布朗运动假设δS 的相关性为零。为了测试这个假设,我们使用下面的相关函数:

等式 11:价格-价格相关性。

相关函数可以具有区间[-1,1]内的值,但是有三种情况特别相关,即:

如果服从 1 和 2,我们会:

等式 12:高斯过程的价格-价格相关性。

取而代之的是。10 成为从 1 到 0 的指数衰减(在大约δt *≈15 分钟处),在小时间具有强相关性:

等式 13:价格-价格相关函数衰减的指数逼近。

然后,我们得出δt * > 15 分钟的价格分布的候选值。在δt 之后,once 可以认为价格变化是I . I . d .*。分布由下式给出:

等式 14:当δS 已经是独立同分布时,δt * > 15 分钟后价格变化的概率分布..

N*因子卷积的累积分布为:

等式 15:等式 15 卷积的累积概率分布。14

图 13:S&P500 与真实数据的累积概率分布。

我们注意到一些事情:

  • 分布方程。14 可以很好地用截断的 Lévy 分布来描述,其中 α = 3/2(拟合了 c 和λ)
  • 卷积很好地逼近了 T > >δT *处的概率,但是随着 T 的增加,卷积的形状收敛为高斯型
  • 随着 T 的增加,真实的财务数据穿过累积分布(在开始处下方,在尾部处上方)
  • 根据所分析的市场,向高斯分布的收敛需要几天到几周的时间

在 Stanley 和 Mantegna 之后,我将快速分析 DJIA(道琼斯工业平均指数)的动态。他们找到了 DJIA 30 只股票的最大和最小相关系数。最大值是 0.73,位于可口可乐和宝洁之间,如下图所示。

图 14:可口可乐和宝洁公司 ln S(t)的时间演变。

他们还测量了强相关性保持强的特征时间尺度。他们发现,从 1990 年到 1994 年,相关性从 0.73 到 0.51 不等,这表明股票是强同步的。

我的 Github 和个人网站 www.marcotavora.me 有一些关于金融和其他主题的有趣材料,如物理、机器学习、深度学习和数学。看看吧!

行动中的统计意义

原文:https://towardsdatascience.com/statistical-significance-in-action-84a4f47b51ba?source=collection_archive---------20-----------------------

数据科学

以及实际应用中的例子

图片来源:维基百科

《行动博客》前情提要:我们研究了中心极限定理,以便更好地理解正态分布背后的基本定理。如果你还没有阅读,我鼓励你去阅读!

[## 中心极限定理的应用

以及实际应用中的例子

towardsdatascience.com](/central-limit-theorem-in-action-1d4832599b7f)

今天,我们将观察另一个重要的统计学概念并进行假设检验。我将不仅用一个具体的、吸引人的例子,而且用简单的术语来解释的统计显著性。我将使用我用来解释中心极限定理的同一数据集——截至 2018 年 186 个国家的预期寿命。

让我们再来看看中央极限定理中最重要的情节和计算:

世界平均预期寿命的平均值( )为 73,标准差(σ)为 7,几乎呈正态分布。使用中心极限定理,通过将总体标准偏差除以样本大小的平方根,计算出标准误差为 0.57。

想象一下,一个流浪者统计学家发现了一个只有 50 人居住的岛屿。所有居民都非常健康,年龄超过 73 岁。她做了一个小调查,了解到岛上的平均寿命是 76 岁。此外,她发现岛上的每个人都在进行间歇性禁食。考虑到平均寿命为 73 岁,这是一个耐人寻味的案例!

现在,我们好奇的统计学家想知道间歇性禁食是否是抛开所有其他可能的决定因素,活得更长寿、更健康的途径。因此,她决定进行一项实验研究,在这里她寻找这个问题的答案:

间歇性禁食会增加人类寿命吗?

为了理解流浪者统计学家的研究及其结果的意义,我们需要理解以下术语:

  1. 无效假设和替代假设
  2. 标准正态分布和 Z 得分
  3. p 值
  4. 显著性水平

不要被他们吓倒,我会遵守我的简单承诺。😉

1.无效假设和替代假设

假设是关于变量之间关系的陈述。假设检验是一种检验假设、观察、主张或实验结果的方法,用来检验你的结果是否具有统计学意义。假设检验是围绕两个对立的主张构建的:零假设和替代假设。

零假设要么描述总体/样本的当前状态,要么声明样本和总体参数之间没有差异替代假设,与零假设相反,要么描述人口/样本的未来或期望状态,要么声明在样本和人口参数之间存在差异

我们的统计学家为她的研究设定了如下无效假设和替代假设:

  • 零假设:间歇性禁食不会增加平均寿命。( ≤ 73)
  • 另一种假设:间歇性禁食会增加平均寿命。(> 73)

她的目标是观察间歇性禁食是否会导致增加(从 73 到 76。)的人类平均寿命,这使得假设检验成为单尾定向检验

2.标准正态分布和 Z 得分

许多定理假设总体或样本服从正态分布。正态分布的广泛使用源于根据标准偏差评估数据点的简易性。让我们记住正态分布的重要性质:

  • 这是一个连续的对称分布。
  • 68%的数据位于 1 以内,95%的数据位于 2 以内,99.7%的数据位于平均值的 3 个标准偏差以内。

标准正态分布是均值为 0,标准差为 1 的特殊正态分布。任何正态分布都可以通过从每个数据点减去平均值并除以标准偏差来转换为标准正态分布。这个过程叫做标准化

具有累积概率和 z 分数的标准正态分布。图片来源:维基百科

Z 值是标准化过程中应用于数据点的计算结果。在上面的标准正态分布中,z 得分位于 x 轴上(z 得分为正值表示该值高于平均值,z 得分为负值表示该值低于平均值),而累积概率值位于累积百分比栏上且位于分布下方。

z 分数计算。图像来源: Z 工作台

Z 值根据数据点到平均值的距离来定义数据点的位置,平均值由标准差来衡量。例如,通过查看上面的 z 得分和累积百分比:

  • 随机变量小于等于 1 的概率为 84.1% (P(x ≤ 1) = 0.841)。
  • 随机变量大于或等于 2 的概率为 2.3% (P(x ≥ 2) = 0.023)

我们可以从 z 得分计算概率值,缩写为 p 值,反之亦然。

3.p 值

P 值是在假设零假设正确的情况下,获得至少与测试期间实际观察到的结果一样极端的测试结果的概率。【来源:维基百科】。我用更简单的话来说:

在零假设为真的情况下,p 值表示获得至少与实际结果一样极端的测试结果所涉及的随机机会或噪声的百分比。

让我们在我们的上下文中进一步分析 p 值:

  • 法国是一个均值为(x̄) 83 的样本,来自一个均值为( ) 73、标准差为(σ ) 7 的正态分布。
  • 当我们计算 z 分数(83–73)÷7 时,它是 1.42。这使得法国比平均水平高出 1.42 分。
  • 我们的世界,因此零假设是:“法国的平均预期寿命比全球平均水平高 1.42 点

比方说,我们从法国抽取了一个样本,发现平均预期寿命实际上比全球平均水平低 1 个百分点,p 值为 0.16。这意味着,在一个零假设为真的世界里,我们有 16%的随机机会测量出法国的平均预期寿命至少比全球平均水平低 1 点。

换句话说,如果法国的平均预期寿命实际上比全球平均水平高 1.42 点,我们仍然会测量出它至少低 1 点,大约 1/6 的时间是因为噪音。因此,p 值越低,结果越显著,因为它不太可能是由随机机会或噪声引起的。

p 值可以用 z 表或 R 或 Python 中的库来计算。我们好奇的统计学家将从Python 的 scipy stats 包和来自同一个库的 norm 对象中获得一些帮助来表示标准的正态分布。此外,为了计算 p 值,她将使用 norm 对象的累积密度函数(cdf)方法。对于给定的 z 得分,该方法将产生与上述标准正态分布中的累积百分比相同的概率值。

为了完成她的实验研究,剩下的唯一缺失部分是显著性水平——用α表示。

4.显著性水平

显著性水平(α) 是阈值 p 值,用于决定测试结果是否具有统计显著性。它也代表了在我们的测试/研究中我们可以容忍多少随机性。显著性水平通常设置为 0.05、0.01 或 0.001。

如果测试结果的 p 值小于显著性水平(α),那么我们可以断定所获得的测试结果在统计上是显著的,并且它们不是由于随机机会或噪声

在开始实验之前设置显著性水平是很重要的。否则就不是客观测试了。我们好奇的统计学家也知道这一点,并将显著性水平设为 0.05。最后,她要完成研究,观察行动中的统计意义!

我们的漫游者统计员迄今为止执行的步骤:

  1. 她决定进行一项实验研究来回答这个问题:
  • 间歇性禁食会增加人类寿命吗?

2.她确定了无效的替代假设:

  • 零假设:间歇性禁食不会增加平均寿命。( ≤ 73)
  • 替代假设:间歇性禁食增加平均寿命。(> 73)

3.她设置了测试统计并计算了 p 值:

  • 50 名健康老年人的发现只是世界平均寿命分布的又一个样本。因此,她将测试统计数据确定为岛上每个人都进行间歇性禁食的平均预期寿命,并将 p 值计算为:

4.她确定显著性水平为 0.05:

  • α右侧的区域称为临界区域。表示 p 值小于显著性水平的区域。如果测试统计值落在这个区域内,她将得出结论,测试结果具有统计学意义。(对于单尾定向测试,p 值为 0.05 的 Z 得分为 1.64)

当她把所有的碎片放在一起,揭示一个更健康更长寿的生活之路:

测试统计落入临界区域,这意味着测试结果具有统计学意义,她拒绝零假设!

有统计学意义的证据表明,间歇性禁食增加了平均预期寿命,显著性水平为 0.05。获得的测试结果不是随机的。

在平均预期寿命为 73 岁的世界中,由于随机噪声,获得 50 个样本均值为 76 的概率(p 值)为 0.0015,小于 0.05。

测试结果在统计学上是否被称为显著取决于显著性水平。当 p 值设置为 0.001 时,测试统计数据将不再落入临界区域。(对于单尾定向测试,p 值为 0.001 的 Z 得分为 3.09)

在这种情况下,我们会得出结论,测试结果没有统计学意义,并接受零假设。(间歇性禁食不会增加平均寿命)

统计显著性的实际应用

我们好奇的统计学家的测试被称为 z 测试。如果我们的样本量少于 30,或者有两个样本进行比较,那么这将是一个 t 检验。如果我们比较了两个或更多样本,这将是一个 ANOVA(方差分析)测试

从社会科学到物理学,几乎每个学科都使用假设检验和统计显著性。我们可以使用它们来比较机器学习环境中不同模型的性能。我们可以自信地进行假设检验,并使用统计显著性确定哪一个表现更好。这里有一篇我喜欢的关于统计学意义在机器学习中的使用的文章:

[## 比较哪种机器学习模型性能更好

自信地比较机器学习模型

towardsdatascience.com](/compare-which-machine-learning-model-performs-better-4912b2ed597d)

感谢阅读!如果你想更深入地了解统计意义的“作用”,你可以看看这个 Deepnote 笔记本。我这个吸引人的例子来源于 Gapminder 的公开数据,可以在这里找到。

对于评论或建设性的反馈,您可以通过回复、 TwitterLinkedin 联系我!保持安全和健康👋

借助 Python 的统计意义

原文:https://towardsdatascience.com/statistical-significance-with-the-help-of-python-1fbb318ce216?source=collection_archive---------9-----------------------

奥占·阿克多安在 Unsplash 上的照片

使用 Python 检查一个结果是否纯粹是由于偶然。

“使用广告为我们的产品创造更多收入”。"减肥药比服用安慰剂的人减轻了更多的体重.""电池' A '的寿命是其竞争对手的十倍."这些类型的语句经常出现。当查看数据时,很容易做出一个快速的假设,即某个变量导致了某个结果。对这些结论过于草率会导致很多问题。在数据科学中,能够确定一个结果是否是由于偶然可以帮助选择一个模型以及检查采样误差的方法。

确定统计显著性是建立一个结果不完全是由于偶然的信心的方法之一。我们来看看什么统计显著性是如何用 p 值来确定的。

这个例子将使用 Python 来展示如何在你的 code/ jupyter 笔记本中表示统计意义。建议您了解一些 Python 基础知识。我们还将使用以下 Python 库 NumPyMatplotlibPandas 。如果你对它们都不熟悉,我建议你使用提供的链接。

数据

我们将查看来自 kaggle.com 的"电子商务愿望中的夏装销售"数据集。如果你不熟悉Wish.com,它是一个在线电子商务平台。这些数据是在 2020 年 8 月通过抓取网站上所有列在“夏季”类别下的项目收集的。您可以通过单击上面的链接,了解有关数据获取方式以及每一列/变量的更多信息。数据集显示,公司有个人资料图片的项目比公司没有个人资料图片的项目具有更大的总销售额(以欧元计)。我们将尝试确定这一结果是否有统计学意义。

关键概念

  1. 通过确定零假设和替代假设进行假设检验
  2. p 值和 p 值阈值
  3. 检验统计量
  4. 排列测试
  5. 使用 p 值来确认或拒绝零假设

假设检验

为了建立统计显著性,我们必须提出一个零假设和一个替代假设。零假设是指变量对我们的最终结果没有影响。另一个假设是变量对最终结果有影响。

对于这个例子,我们的无效和替代假设将是:

  • 零假设:平均而言,当一家公司有简介照片时,一件商品的总销售额(以欧元计)与一家公司没有简介照片时的总销售额(以欧元计)相同
  • 另一种假设:平均来说,如果一家公司有个人资料图片,一件商品的总销售额(欧元)会比没有个人资料图片的商品的总销售额(欧元)高

P 值阈值

p 值将在后面进行深入解释,但我们现在将简要介绍一下。在开始测试之前,确定我们的 p 值阈值总是很重要的。在确定零假设是否为真时,p 值是我们量化结果稀有程度的一种方法。p 值越低,结果就越不像是纯粹由于偶然。****

p 值阈值是我们将选择的一个数字,如果超过这个数字,我们就可以断定我们的零假设为真。我们选择多高或多低,我们希望这是基于我们的测试。如果我们要测试某个需要非常精确的东西的统计显著性,我们可能会选择一个非常低的阈值,比如 0.001。对于不需要太多精确度的测试,比如销售额或网站参与度,我们会更高。标准阈值是 0.05,即 5 %。由于我们着眼于销售,我们将采用标准门槛。如果我们的 p 值低于 0.05,我们将拒绝零假设。

准备我们的数据

一旦我们从 Kaggle 下载了数据集,我们就可以使用 pandas 将它读入数据帧。

我们感兴趣的有 3 列“价格”、“单位 _ 售出”和“商家 _ 个人资料 _ 图片”。在继续之前,我们将采取以下步骤。

  1. 除了上面提到的三列之外,我们将删除所有其他列。
  2. 检查是否有任何丢失的值。
  3. 使用 df.describe()来确定是否有任何值看起来不准确并且可能给出意外的结果。
  4. 删除或更正我们认为可能包含不正确信息的任何行
  5. 通过将“price”列乘以“units_sold”列,计算每件商品产生的欧元总额。

下面是用于获取上述集合的 python 代码。

*** 使用多行注释语法来表示输出***

准备好数据集后,让我们将数据集分成两组。一个将包含公司有个人资料图片的项目(a 组),另一个将包含公司没有个人资料图片的项目(b 组)。

一旦分成两组,我们将找到每组总销售额的平均值。我们还将查看每个组中有多少行,因为这将有助于我们稍后确定如何构建我们的随机组。

检验统计量

现在我们有了两组总销售额的平均值,我们可以用它来确定我们的测试统计。检验统计量是一个数值,我们将使用它来确定两组之间的差异是否是随机的。在这种情况下,测试统计将是使用个人资料图片和不使用个人资料图片的总销售额的平均差异。我们的测试统计大约是 33,184 欧元。

排列测试

我们现在的目标是多次重新创建我们的两组,以查看我们的测试统计偶然发生的可能性。一个排列测试是我们将如何完成这个目标。

我们将在 Python 中采取以下步骤:

  1. 创建一个空列表来保存 1000 个平均差异。这将是我们生成的采样分布。
  2. 初始化“总销售额”的一个系列
  3. 做一个将迭代 1000 次的 for 循环。
  4. 对于 For 循环的每次迭代,我们将把每次总销售额随机放入“a”组或“b”组。为了重新创建这两个组中的大小差异,我们将给出 14.4%的机会将值归入“a”组,85.6%的机会将值归入“b”组。这个百分比是基于我们之前确定的行数。
  5. 一旦我们的随机组“a”和随机组“b”形成,我们将找到每组的平均值。
  6. 然后,我们将从随机组“a”中减去随机组“b”的平均值,并将其添加到步骤 1 中初始化的列表中。
  7. 最后,我们将创建一个直方图来可视化这个采样分布的频率。

随机化平均差异的直方图

从直方图中,我们可以看到均值中最常见的差异大约为 0。这与我们的测试统计非常不同。事实上,甚至没有显示测试统计值。p 值将为我们提供一种方法来量化均值差异的随机样本分布中检验统计值的次数。

p 值

在我们生成的抽样分布中,大部分值都以平均差 0 为中心。如果纯粹是偶然的话,这两个组更有可能产生相同的总销售额(零假设)。但是,由于观察到的测试统计量不接近 0,因此有可能是拥有一张剖面图导致了数据集中的平均差异。

让我们看看抽样分布,以确定 33,184 或更高的值出现的次数。然后我们可以将频率除以 1000。这将给我们 33,184 或更高的平均差异纯粹是由于随机机会的概率。

这个概率被称为 p 值。如果该值很高,这意味着测试统计很可能是随机发生的,并且配置文件图片可能不起作用。另一方面,低 p 值意味着我们观察到的平均差异是由随机机会引起的概率很小。

让我们创建一个 for 循环,它将检查我们的测试统计在我们随机生成的均值差异组中出现了多少次。然后我们将得到这个计数,并除以我们的总迭代次数(1000)。我们的输出将是 p 值。

结果

之前我们决定 p 值阈值为 0.05。0 小于 0.05,这意味着我们可以排除我们的测试统计是随机的结果。我们现在可以拒绝我们的零假设,并确认我们的替代假设。

最后的想法

统计显著性是检查数据和确定变量是否对最终结果有影响的一种很好的方法。在这个例子中,我们在 Python 的帮助下采取了一些步骤来确定拥有一张个人资料图片对一个商品的总销售额结果的统计意义。

虽然我们能够在 p 值的帮助下量化这种显著性,但我们仍然应该回过头来看看数据集。在做出任何重要结论之前,有几个问题需要解决。

  1. 我们来自 Wish.com 的样本数据集非常有限。它只包含夏季服装项目。最好能获得更多的数据,涵盖更长的时间段和更多种类的项目
  2. 售出物品数量不准确。在网站上,出售的项目计数列在范围,即 1000+,2500+等。收集数据时,加号肯定已经被删除了。最好能得到实际的数字。
  3. 虽然我们很快找到了异常值,但我们没有彻底检查这些项目,以确定是否有任何其他原因导致了简介图片组中的总销售额较高。可能还有一些我们没有考虑到的其他关联。

虽然可能需要更多的信息来决定是否有一个个人资料图片会导致更多的销售,但我们已经通过确定 p 值在正确的方向上迈出了一步。我们可以说,根据这个测试,拥有一张个人资料照片对 Wish.com 上一件商品的总销售额有着统计上的显著影响。

统计显著性是数据科学中的一个有用工具,当您需要知道一个结果是显著的还是偶然发生的时,应该理解并使用它来帮助做出决策。

带代码的 R 中的统计模拟—第一部分

原文:https://towardsdatascience.com/statistical-simulation-in-r-part-1-d9cb4dc393c9?source=collection_archive---------13-----------------------

破解数据科学面试

Ace 数据科学访谈

https://www.flickr.com/photos/86689809@N00/157763181/

这是关于统计模拟的两篇文章的第一部分。如果您还没有看过第 2 部分,请点击这里:

[## Python 中的统计模拟,第 2 部分

任何数据科学面试最重要的部分!

towardsdatascience.com](/statistical-simulation-in-python-part-2-91f71f474f77)

介绍

在过去的几个月里,我收到了一些顶级科技公司的数据科学面试。几乎所有的面试官都要求我对一个真实的商业场景进行统计模拟,但我没能给他们留下深刻印象。

你知道,这些都是合理的问题,如果我以前接触过这个话题,并不难回答。

直到今天,我已经花了数百个小时学习模拟,准备接下来的技术面试。

统计模拟是一个相当广泛的领域,不可能在一篇文章中涵盖所有细节。作为一个初学者,我计划通过一系列的帖子来展示模拟的细微差别和应用。

定义

现实世界中,事情是随机发生的,有无限多种可能。我们可能只能观察到一部分,而不是全部的可能性。

模拟派上了用场,并提供了与现实世界结果相匹配的可能性分布的快速概览。通过研究模拟结果,我们可以洞察真实世界。

照片由照片爱好Unsplash 上拍摄

生成随机数

让我们从最简单的代码开始,然后进入更复杂的场景。

命令 runif(x,min=a,max=b) 在 a 和 b 之间的范围内生成 x 个值。

library(dplyr)set.seed(2)
runif(25,min=0,max=10)

随机值

set.seed() 函数为 R 的随机数生成器设置一个种子,这样我们每次运行代码时都会得到一致的相同值。否则,我们会得到不同的结果。自己试试。

为了得到整数,我们使用 圆整 函数,如下:

runif(25,min=0,max=10) %>% 
  round(.,digits = 0)

围捕它

这里的管道, % > % ,来自magritter包,可以让你写出更干净易懂的代码。它可以用简单的英语翻译成‘那么’

在英语中,上面两行代码的意思是:

  1. 生成 25 个介于 0 和 10 之间的数字
  2. 然后 ( % > % ),将数字向上舍入到最接近的整数。

试试如果你把数字调整为 1 会发生什么。

生成随机数的另一种方式是通过的 样本 函数生成:

> sample(x, size, replace=TRUE, prob=NULL)
  • x:一个向量或正整数
  • size:一个非负整数,给出可供选择的项目数
  • 替换:有替换的样本,还是没有?
  • prob:概率权重向量,用于获取被采样向量的元素

(更多信息请参考 R 文档,链接)

一个简单的例子。

set.seed(24)
sample(seq(1,10),8)

set.seed() 函数使结果可重现。

上面的代码从序列[1,10]中生成 8 个数字的随机样本。正如你所看到的,我们没有为替换和选择的概率设定规则。

默认情况下,R 将替换设置为 FALSE,并采用相等的选择概率。

x = 1:10
sample(x,replace=TRUE)

替换重采样的过程被称为 引导 ,这是一个更高级的主题,将在下一章讨论。

除了数字,我们还可以对单词进行采样,如下所示:

set.seed(1)
sample(letters,18)

相等和不相等的选择概率

#场景 1 等概率

我们以相等的概率从序列[1,5]中生成大小为 10 的随机样本。

equal_prob_dist = sample(5,10000,***prob=rep(0.1,5)***,replace=T)
hist(equal_prob_dist)

同等概率

如果我们设置 prob=rep(0.1,5),那么数字 1 到 5 将被平均采样,如上面的直方图所示。

#场景二不等概率

如果选择的概率不相等(例如,一个装载的骰子),分布看起来像什么?

我们从概率不等的序列[1,5]中生成大小为 10 的随机样本

unequal_prob_dist = sample(5,10000,***prob =c(0.1,0.25,0.4,0.25,0.1)***, replace=T)
hist(unequal_prob_dist)

不平等的概率

我们为序列设置以下选择概率规则:

1 & 5: 0.12 & 4: 0.25 3: 0.4

事实证明,数字 3 是选择最多的,1 & 5 是选择最少的。

如果感兴趣的问题需要对选择概率进行不同的处理,这些相等/不相等的场景会非常有帮助。

数据框中的样本观测值

为了对数据框或列表中的观察值(行)进行采样,我们不直接对行进行采样,而是对对象中的索引进行采样。

head(mtcars)

# step 1: create an index vector for the elements/rows 
index <- seq_len(nrow(mtcars))

# step 2: sample the index vector
set.seed(12)#to obtain a random sample of 10
sample_index <- sample(index,10)# step 3: to show the sampled elements/rows 
mtcars[sample_index,]

应用

在这一节中,让我们进行一些实践,并解决现实生活中的业务场景。

问题 1:有两个六面骰子。如果把它们一起掷出,掷出 7 的概率是多少?

set.seed(1)
die = 1:6# sample 10000 times with replacements for dice 1
die1 = sample(die,10000,replace = TRUE,prob=NULL)# sample 10000 times with replacements for dice 2
die2= sample(die,10000,replace=TRUE,prob = NULL)# the combined value of die_1 and die_2 
outcomes = die1+die2# the probability of getting a 7
mean(outcomes == 7)

同样,我们可以用一个 来代替 循环来达到同样的目的。

set.seed(1)
for (i in 10000){
 die_1 = sample(die,prob=NULL,replace=TRUE)
 die_2 = sample(die,prob=NULL,replace=TRUE)
 die_sum = die_1+die_2
 print(mean(die_sum==7))
}

这两种结局几乎一样。

问题 2:你有两个骰子。掷出 2,3,4,5,6,7,8,9,10,11,12,13 的概率是多少?

除了模拟每一种结果,还有一种更简单的方法来获得我们需要的东西,那就是使用sappy

sapply(2:13,function(x) mean(outcomes==x))

根据 R 文档,sapply()函数是一个“用户友好的版本和默认情况下的lapply包装器,通过应用simplify2array()返回一个向量、矩阵或者如果simplify = "array"的话,一个数组。sapply(x, f, simplify = FALSE, USE.NAMES = FALSE)lapply(x, f)相同

简言之,该函数将函数 mean(outcomes) 应用于序列【2,13】。

问你一个问题:如果你有 3 个骰子,掷出 7 的概率是多少?

问题 3:生成 10000 个值的随机样本,其中包含多少个独特的观察值?不包括多少?

set.seed(1)
n=10000included_obs = length(unique(sample(1:n, replace = TRUE)))
included_obsmissing_obs = n-included_obs
missing_obs

采样后,我们用【unique()】来寻找有区别的观测值,用【length()来计数。在 10k 样本中,对 6316 个不同的案例进行采样,而对 3684 个(10k-6316)案例不进行采样。

进一步注意,我们在 10k 中只得到 6316 的原因是我们用替换进行采样,因此一些数字被重复采样。换句话说,一些数字被多次采样。

问题 4:用随机分配的 0 和 1 生成一个 m*n 矩阵。

(鸣谢 R-bloggers 上的讨论, 此处 )

在最初的帖子中,作者介绍了多种方法,我在这里重点介绍第一种方法。

首先,我们可以使用 for 循环。

m <- 10
n <- 10# create an empty matrix
m00 <- matrix(0,m,n)for (i in 1:m) {
   for (j in 1:n) {
     m00[i,j] <- sample(c(0,1),1)
 }
}m00

这里, matrix(0,m,n) 通过 m*n 创建一个空矩阵,两个 for 循环规定了每个单元格的值。

大多数时候,R 中的 循环的 可能不是最有效的解决方案,如果样本量足够大,我们将使用其他选项。

考虑到这一点,作者贡献了使用 apply() 函数的第二种方法。

m <-10
n<-10m0 <- matrix(0,m,n)apply(m0,c(1,2),function(x) sample(c(0,1),1))

到目前为止,除了 apply() 函数之外,其他的应该都很熟悉了。它返回“通过将函数应用于数组或矩阵的边距而获得的向量/数组/值列表”(原始定义,链接)。

它具有以下形式:

> apply(x, margin, fun,…) 
  • x:一个数组或矩阵
  • margin:一个向量,给出函数将要应用的下标。对于矩阵,1 表示行,2 表示列。 c(1,2) 表示行和列,其中 x 已命名 dimnames,可以是选择维名的字符向量
  • 乐趣:要应用的功能

问题 5:抛硬币 10 次,模拟过程 10000 次。显示抬头数量的分布。

# create an empty list 
total_heads = c()# use a for loop to simulate coin-flipping 10 times 
# repeat it for 10,000 timesfor (i in 1:10000){
 sum_heads = sum(round(runif(10,0,1)))
 total_heads = c(total_heads, sum_heads)
 }hist(total_heads)

在这里,我将解释三行代码,其余的就不言自明了。

  1. 为(1:1000 中的 1)。 不像其他编程语言,你要把范围指定为 1:10000。
  2. sum(round(runif(10,0,1))) 。这是一种结构化的编码方式,有三个独立的功能:runif() → round() → sum()。它首先运行 runif()函数,最后运行 sum()。基本上,代码行生成 10 个介于 0 和 1 之间的随机数,将其四舍五入为最接近的整数(0 或 1),最后求和。
  3. total _ heads = c(total _ heads,sum_heads)。 由于 total_heads 开头是一个空列表,我们用这行代码把 sum_heads 的值赋给 total_heads。

感谢您的阅读!

这是一篇关于统计模拟的介绍文章,我们将在接下来的文章中探讨更高级的话题。

敬请期待!

Medium 最近进化出了它的 作家伙伴计划 ,支持像我这样的普通作家。如果你还不是订户,通过下面的链接注册,我会收到一部分会员费。

[## 阅读叶雷华博士研究员(以及其他成千上万的媒体作家)的每一个故事

作为一个媒体会员,你的会员费的一部分会给你阅读的作家,你可以完全接触到每一个故事…

leihua-ye.medium.com](https://leihua-ye.medium.com/membership)

喜欢读这本书吗?

请在 LinkedInYoutube 上找到我。

还有,看看我其他关于人工智能和机器学习的帖子。

异常检测的统计技术

原文:https://towardsdatascience.com/statistical-techniques-for-anomaly-detection-6ac89e32d17a?source=collection_archive---------11-----------------------

克莱门斯·弗兰卡在 Unsplash 上拍摄的照片

快速评估异常和异常值的五种统计工具

异常和欺诈检测是一个价值数十亿美元的行业。根据尼尔森报告,仅 2010 年全球信用卡欺诈金额就高达 76 亿美元。在英国,2018 年欺诈性信用卡交易损失估计超过 10 亿美元。为了应对这些类型的财务损失,我们使用了大量资源来识别每个行业中的欺诈和异常情况。

在数据科学中,“离群值”、“异常”和“欺诈”通常是同义词,但也有细微的区别。“异常值”通常指的是从人群中脱颖而出的数据点。然而,当这种异常值完全出乎意料且无法解释时,它就成了异常值。也就是说,所有异常都是异常值,但不一定所有异常值都是异常值。然而,在本文中,我将这些术语互换使用。

理解和检测异常值之所以重要,原因有很多。作为一名数据科学家,当我们准备数据时,我们会非常小心地了解是否有任何数据点无法解释,这些数据点可能输入错误。有时,我们会过滤完全合法的异常数据点,并删除它们以确保更好的模型性能。

异常检测也有巨大的工业应用。信用卡欺诈检测是引用最多的一种,但在许多其他情况下,异常检测是开展业务的重要组成部分,如检测网络入侵、识别仪器故障、检测肿瘤细胞等。

从简单的统计技术到复杂的机器学习算法,一系列工具和技术被用于检测异常值和异常值,这取决于数据的复杂性和所需的复杂度。本文的目的是总结一些简单而强大的统计技术,可以很容易地用于异常值的初步筛选。虽然复杂的算法是不可避免的,但有时简单的技术就足够了。

下面是五种统计技术的入门。

1) Z 分数

Z-score 可能是最简单的一种,但对于异常检测却是一种有用的统计方法。在统计分布中,Z 得分告诉您给定数据点与人群中其他数据点的距离。从技术上来说,Z-score 衡量一个给定的观察值距离平均值有多少标准差。Z 值为 2 意味着数据点距离平均值有 2 个标准偏差。

要计算 Z 得分,您只需要两个参数:均值和标准差,它们在任何编程语言中都很容易获得(例如在 Python 中,您只需将函数describe()应用于数据框)。

一旦获得这两个参数,任何给定数据点的 Z 得分都可以使用以下简单公式计算:

2)修改的 Z 分数

使用均值和标准差很容易计算 z 得分,但它有自己的局限性。在一些情况下,这不是一种理想的技术,例如:

  • 数据不是正态分布的
  • 数据/样本量小

除此之外,Z-score 对极值也很敏感(因为它的一个参数-均值-本身对极值也很敏感),因此它可能无法适当地筛选异常值。

为了克服这些缺点,对标准 Z 分数进行了一些修改:

  • 使用中值代替平均值作为参数,因为中值对异常值不太敏感
  • 中位数绝对偏差(MAD)用于代替标准偏差
  • 这些值乘以一个常数,使其约等于 SD(对于正态分布数据,MAD 约等于 0.6745*SD)

将它们放在一起,等式如下所示:

3)四分位距(IQR)

如果你从小到大排列数据,中点称为中位数。中位数将数据分成两半。这两半的中点被称为四分位数T4。

换句话说,你可以将数据分成三个四分位数——第一、第二和第三(第二个四分位数有一个名字——中位数)。所以四分位数间距是第一和第三个四分位数之间的距离。使用 IQR 的异常检测背后的理论是,如果一个数据点离第一和第三四分位数太远,它可能是一个异常值。

IQR 可以单独用于异常值检测,但下面的箱线图使用相同的算法理论,可能比 IQR 更直观。

4)箱线图

箱线图更好地展示了 IQR,但也提供了额外的信息。

在下面的盒状图中,盒子的长度是 IQR,最小和最大值由胡须表示。胡须通常延伸到盒子两侧的 1.5IQR 距离。因此,这些 1.5IQR 值之外的所有数据点都被标记为异常值。

我在 boxplot 上写了一篇关于离群点检测的独立文章,其中有一个例子和一小段 Python 代码,你可能想看看。

5)直方图

异常值检测的最后一个统计工具是分布图或直方图。这是另一种以可视化和程序化的方式跟踪异常值的方法。例如,请看下图:

分布数据以检测潜在的异常值

仅从这个分布图就可以很清楚地看出,虽然数据集中的大多数值都被分组在一起,但仍有相当多的值似乎与众不同。因此,您可以过滤这些值,并检查这些值是否异常。

但是,如果数据的分布是倾斜的,有时您可能需要应用数据转换技术(如对数或平方根)。例如,如果我们将对数应用于上述相同的数据,数据就变成近似正态分布,并讲述关于异常值的不同故事。

记录转换后的数据以过滤潜在的异常值

摘要

本文的目的是介绍五种简单的统计技术——z 得分、修正的 z 得分、IQR、箱线图和直方图,它们通常在数据科学中用作异常值/异常检测的粗过滤器。有时这些简单的技术对于异常检测来说已经足够好了,但有时我们需要转向更复杂的机器学习算法——kNN、SVM、DBSCAN 等。—我以后文章的一个主题(敬请关注!).

如果你喜欢我的文章,欢迎在推特上关注我。

python 中 MCAR 的统计测试…

原文:https://towardsdatascience.com/statistical-test-for-mcar-in-python-9fb617a76eac?source=collection_archive---------13-----------------------

你是否想知道在调查中遗漏的“年龄”是否与被调查者的“薪水”有关?您是否想过分析数据集中各种缺失值之间的关联?你怎么能确定缺少数据是因为没有明确的模式?—这些问题的答案相当简单—本文将向您展示如何在 python 中以统计方式证明数据缺失时变量之间的关系。

图片来源: unsplash

自从我在 R 中发现 LittleMCAR 的测试,以找出变量缺失之间的关联的重要性,我就一直在用 python 搜索类似的测试。本文将阐明如何在 python 中执行类似的测试。在本文中,我将带您浏览一组代码,这些代码分析分类数据中的缺失值。

在深入测试缺失数据机制之前,让我们先清楚地理解它们。

假设我们有一个数据集,我们需要分析那些缺少值的列以及变量之间的关系。通过分析这些机制,我们可以更好地决定如何处理它们。

任何数据集中有三种不同的数据丢失机制。

1.完全随机失踪:(MCAR)

2.随机失踪:(三月)

3.不是随意失踪:(MNAR)

MCAR:

是什么意思? 当缺失的数据点不遵循任何特定的推理或模式时。例如,您有所在社区居民的人口统计数据。但是变量“中间名”下有 50%的值缺失。这 50%的数据是数据 MCAR 的完美例子。在大多数条目中,中间名是空白的,这背后没有模式或特定的原因。

怎么处理? 在数据 MCAR 的情况下,可以采用以下方法。

a. 列表式删除:如果数据集的任何变量/列中有缺失数据,则删除记录。只有当丢失的数据数量很少时,这种方法才最有效,比如在一个数据集中,只有 2%的数据完全随机丢失。

b. 成对删除:成对删除仅删除统计方法中使用的变量之一缺失的情况。

在内部,它沿着相关矩阵的相同路线工作。在两个变量之间缺少值的情况下,(成对地)寻找相关矩阵考虑了这两个变量的所有完整情况。假设这个场景中的案例数是 n。

当采用另一组变量并计算相关矩阵时,完整病例的数量将不同于 n。

这是列表式成对删除的主要区别。

成对删除的优点是数据丢失最少。当一个数据集在几乎所有变量中都存在大量缺失值时,成对缺失值处理将是更明智的选择。

c. 均值、中值&众数插补:缺失值也可以替换为各个变量的均值、中值和众数。

三月:

什么意思? 缺失数据点时遵循一种模式。我们再举一个同样的例子,你所在社区的居民人口统计数据。但这一次,几个年龄超过 45 岁的男人的工资不见了。

这里,数据中的缺失归因于另一个变量的数据。因此,它遵循“随机丢失”机制。MAR 可能是最难理解的,因为它的名字。

怎么处理? 由于这种机制涉及到一种关系,这里的最佳选择是采用一种插补技术——均值、中值、众数或多重插补——这将是本文的范围

MNAR:

是什么意思? 当缺失数据点跟随其数据的模式时,意味着遵循 MNAR 机制。举个例子,在你所在社区居民的同一个人口统计数据中,假设工资超出一定数额时,少了几个男性的工资。(比如一百万)

在这里,它遵循一个“不是随机丢失”的机制。通常,当数据丢失不是 MCAR 或 MAR 时,它倾向于遵循 MNAR。

怎么处理? 既然在 MNAR 的案例中存在自诱导关系,那么避免它们的最好方法就是做一些数据收集或者对缺失数据建模。

我们需要分析缺失值机制的原因是,我们需要了解估算缺失值的最佳方法,以便我们的 ML 模型的准确性不受影响。

让我们开始编码吧…

我已经将这个 Kaggle 数据集用于分析。让我们首先将这些数据放入数据框,并检查数据集中缺失值的总数。我现在已经从数据集中删除了 timestamp 变量,因为我在这里的目标是处理缺失值及其关系。我还将性别列的值替换为最小类别——“男性”和“女性”。

正如我们在下面的屏幕截图中看到的,在一些列中有缺失值——State、Self-employee、work_interfere 和 comments 有很多缺失数据。

现在,在所选的数据集中只有一个数值变量,但其中没有缺失值。所以,让我们在一个单独的数据框架中分离分类变量。

既然我们已经分离了具有完全和不完全情况的分类变量,我们需要使用传统的卡方检验来分析每个变量的完全和不完全情况之间的关联。独立性和克莱姆系数测试。

独立性的卡方检验用于确定两个分类变量之间是否存在关联。卡方检验使用列联表或交叉表。测试以检查这些类别中的频率。

克莱姆系数是两个名义变量之间关联的量度,给出 0 到+1 之间的值。

来源:维基百科

来源:维基百科

以下函数计算数据集中所有变量组合的克莱姆系数值。

来源:堆栈溢出

在将卡方检验和克莱姆逻辑应用到我们的数据框架后,我们得到以下输出。

正如我们在上面看到的,对于完全的情况,当一个列与它自己比较时,克莱姆系数是最高的。“独立”栏显示卡方检验显著性的结果。如果卡方的 p 值是<0.05, the association is going to be dependent.

We perform the same analysis for incomplete cases too.

Here, Cramer’s Coefficient is Nan for few rows because the number of incomplete cases for a few of the variables could have been 1.

Generally, the accepted category for any Cramer’s coefficient association is taken from a standard set of intervals.

Depending on the above criteria, let’s segregate our output into four different data frames –

1. cramer_high
2。克莱姆 _ 温和
3。cramer_low
4。如果有的话

以下是变量之间具有高关联性

1.自营职业者和非雇员

2.治疗和工作干扰

3.寻求帮助和健康计划

其中,“自雇&工作干扰”在我们的数据集中有缺失数据。

不完全情况下的克莱姆 V 告诉我们,在缺失数据中,在“自雇者”和“雇员人数”(大于 0.5)变量之间有很强的关系。

我们的另一个有缺失数据的变量“work_interfere”也是如此。一个人是否正在接受精神疾病的治疗,会极大地影响疾病干扰他白天工作的方式。

然而,当您查看这两个变量的 chisq 测试结果时,完全和不完全情况下的结论没有区别。这意味着这种关联不可能仅仅是由于这两个变量的数据缺失。

至于缺失值的第三个变量——“状态”,它在“远程工作”、“技术公司”、“自雇”、“同事”和“评论”之间具有中等强度的关系。

在这里,如果您看到,chisq 测试输出中有一个差异,即“state”与“remote_work”以及“state”与“tech_company”,它表示这两个变量在完全情况下是独立的,但在不完全情况下却是相关的。

换句话说,在“状态”中有一些关于失踪的东西,这取决于那个人是在家工作还是为科技公司工作(也就是相当强烈的失踪联想)。

进一步的步骤..

由于数据集中缺失值的变量之间存在固有的关系,因此数据被视为随机缺失(MAR)。因此,与其删除缺失的记录,不如采用一种插补技术,如“模式”插补,或者采用一种稍微先进的技术,如多重插补。

这样,我们将保留数据集中的大部分信息,并且最终不会影响准确性。

时间序列的统计检验

原文:https://towardsdatascience.com/statistical-test-for-time-series-a57d9155d09b?source=collection_archive---------11-----------------------

它决定了模型是否可以使用。

斯科特·格雷厄姆Unsplash 上拍照

最近,我发表了一篇关于使用 ARIMA 模型进行预测的文章,该模型的数据本身就是 1970 年至 2015 年的二氧化碳排放量。这篇文章突然受到许多读者的关注,这是我在媒体上的获奖文章之一,下面是我的出版物,

[## R 中 ARIMA 模型的时间序列预测

从勘探到预测 1970 年至 2015 年的二氧化碳排放数据。

towardsdatascience.com](/time-series-forecasting-with-arima-model-in-r-77f4e2ae7abb)

文章发表后的几天,有一些建设性的意见来到我这里。我犯了一个错误。我已经测试了 ARIMA 模型,它通过了显著性测试,但是它不是静态的。

正如我在模型中提到的,在我对数据进行差分后,数据看起来是稳定的,它可以用于下一步。这是一个错误,所以我必须写这篇文章来澄清它。

在本文中,我将向您展示为什么在应用模型之前有必要进行统计测试,尤其是显著性测试,以及在我们基于显著性测试使序列平稳后会是什么样子。

为什么要进行显著性检验?

显著性检验是决定你能否继续分析的一个步骤。测试根据有效的假设量化你的证据。

假设你相信一个真实的陈述,你想知道它是否值得进一步分析。

如果你的证据可能与陈述不符,你就不能继续。然而,如果不太可能,你可以继续。

静态测试

在这一节中,我将使用我上一篇文章中的数据,即印度尼西亚从 1970 年到 2015 年的二氧化碳排放量,我将向您展示如何测试数据的平稳性。

扩展的迪基-富勒(ADF) T 统计检验

在我们找到选择哪个自回归(AR)和移动平均(MA)参数之前,我们必须测试数据是否是平稳的。

我们可以使用扩展的 Dickey-Fuller (ADF) t 统计检验来做这件事。ADF 检验是检验数列是否有单位根的检验。如果存在,则该序列具有线性趋势。然而,如果不是,我们可以说模型是静止的。

为了计算 p 值,我们可以在 r 上使用 tseries 库中的 adf.test 函数。

给定数据,之前我们已经计算过一次差异数据,这是 ADF 测试的 p 值,

这个系列仍然不重要。因此,我们必须再次区分这个系列,这是 ADF 测试的 p 值,

现在,我们有一个稳定的数据,我们可以继续我们的模型发现。连续剧长这样,大家怎么看?

型号识别

在我们得到数据的完美平稳形式后,我们可以确定哪个自回归和移动平均参数符合模型。为此,我们可以用自相关函数(ACF)和部分自相关函数(PACF)来标识绘图。你可以看到下图,

基于该图,我们知道 ACF 和 PACF 图随着时间的推移有一个到零的尾部。因为这样,我们假设 ARIMA 模型的参数是 1,2,1。

型号诊断

在我们确定参数之后,我们对模型进行诊断。我们可以使用 r 上 astsa 库中的 sarima 函数对模型进行诊断,对于 ARIMA(1,2,1),下面是结果,

正如我们在 p 值上看到的,AR(1)并不显著。因此,我们不会将 AR(1)用于我们的模型。当我们用 ARIMA(0,2,1)再次应用后,结果看起来像这样,

因为所有参数都很重要,所以我们有一个很好的数据模型。我们将使用的模型是 ARIMA(0,2,1)。

残差分析

在我们得到完美的模型之后,我们必须检查这个模型是否超越了残差分析。这是必要的,因为如果模型的残差不具有正态分布,我们就不能使用该模型。

这里显示了通过使用 sarima 函数从残差得到的图,

正如我们在这里看到的,该模型在其残差上有一个平稳序列,并且每个滞后也没有任何显著的自相关。此外,Ljung-Box 测试没有通过蓝线。因此,该模型满足进行预测的要求。

预测

为了进行预测,我们可以使用 R 上的 astsa 库中的 sarima.for 函数来做这件事。这是天气预报的样子,

我不喜欢说这个,但是结果比上一个更糟。在前一篇文章中,二氧化碳排放量约为 904.186 千吨。现在,二氧化碳排放量将在 1024782 千吨左右。

请注意,二氧化碳排放量不包括森林火灾排放量。正因为如此,我们必须认真考虑气候变化。

结论

总之,正如你在预测结果上看到的,这是一个界限,随着年份的增长,这个界限变得越来越大。所以我们不能说这是确切的数字,但至少我们知道这个数字是如何增长的。

如果政府知道如何减少二氧化碳的排放量,这张图表就不会出现。然而,如果没有政策来阻止它,图表可能会发生。

我不得不再次引用这句话来结束这篇文章。

“所有的模型都是错误的,但有些是有用的”——乔治·博克斯

参考

1 Stoffer,D. S. & Shumway,R. H. 时间序列:一种使用 R (2019)的数据分析方法,Taylor & Francis Group。
【2】Hyndman,R.J. & Athanasopoulos,G. 预测:原理与实践 (2018),第 2 版,OTexts。
【3】平稳性测试 。Rpubs.com。

感谢您阅读我的文章,您也可以在下面查看我以前的文章:

[## 用 R 整理数据

为什么你应该在它上面投资更多,为什么这使你的分析变得容易得多

towardsdatascience.com](/tidy-data-with-r-f3d078853fc6) [## 基于 R 的文本挖掘:收集和清理数据

印度尼西亚最大媒体上的推文评论案例研究

towardsdatascience.com](/text-mining-with-r-gathering-and-cleaning-data-8f8b0d65e67c)

统计测试:如何为你的数据选择最好的测试?

原文:https://towardsdatascience.com/statistical-testing-understanding-how-to-select-the-best-test-for-your-data-52141c305168?source=collection_archive---------1-----------------------

这篇文章面向有抱负的数据科学家和机器学习(ML)学习者和实践者。

亚历克西斯·莫拉·安古洛在 Unsplash 上的照片

他的职位不适合经验丰富的统计学家。这是面向数据科学家和机器学习(ML)学习者&从业者,他们和我一样,没有统计学背景。

对于一个来自非统计背景的人来说,统计学最令人困惑的方面, 是基本的统计测试 ,什么时候使用哪种测试?。这篇文章试图指出最常见的测试和相关关键假设之间的区别。

目录

  1. 术语:(本帖关键术语)
  2. 统计检验(假设检验)
  3. 统计假设
  4. 参数测试
  5. 参数测试流程图
  6. 处理非正态分布(非参数检验)

1)术语:

因变量和自变量

自变量通常被称为“预测变量”,是一个被操纵的变量,以观察对因变量的影响,有时被称为结果/输出变量。

  • 自变量->预测变量
  • 因变量->结果/输出变量

变量类型

区分变量类型之间的差异很重要,因为这在确定采用正确的统计检验类型时起着关键作用。有两个主要类别:

  • 定量 : 表示事物的数量(如一包烟的数量)。两种不同类型的定量变量是:
  1. 连续(又名):用于描述度量,通常可以分为小于一的单位(如 1.50 公斤)。
  2. 离散(又名区间):用于描述计数,通常不能分割成小于 1 的单位(如 1 支香烟)。
  • 分类 : 表示事物的分组(例如不同种类的水果)。三种不同类型的分类变量是:
  1. 序数:表示有顺序的数据(如排名)。
  2. 名义:代表集团名称(如品牌或物种名称)。
  3. 二进制:表示结果为是/否或 1/0 的数据(如左或右)。

变量类型汇总(图片由作者提供)

2)统计测试

统计学就是关于数据的。光有数据是没意思的。我们感兴趣的是对数据的解释。

在统计学中,一个非常重要的事情是统计检验,如果统计“是对数据的解释”,统计检验可以被认为是“调查我们关于世界的想法的正式程序”。

换句话说,每当我们想要对数据的分布或一组结果是否不同于另一组结果做出断言时,数据科学家必须依赖假设检验。

假设检验

使用假设检验,我们尝试使用样本数据解释或得出关于总体的结论,评估关于总体的两个互斥陈述,以确定哪个陈述最受样本数据支持。

假设检验有五个主要步骤:

步骤 1) 陈述你的假设为一个零假设(Ho)和替代假设(Ha)。

步骤 2) 选择一个显著性水平(也称为α或α)。

步骤 3) 以一种被设计用来检验假设的方式收集数据。

步骤 4) 执行适当的统计测试:计算 p 值,并与显著性水平进行比较。

步骤 5) 决定是“拒绝”零假设(Ho)还是“拒绝失败”零假设(Ho)。

注意:虽然具体的细节可能会有所不同,但是你在测试一个假设时所使用的程序总是会遵循这些步骤的一些版本。

如果你想进一步了解假设检验,我强烈推荐这两篇关于假设检验的好文章。

[## 假设检验|带有简单示例的逐步指南

假设检验是一种使用统计学调查我们对世界的想法的正式程序。最常见的是…

www.scribbr.com](https://www.scribbr.com/methodology/hypothesis-testing/) [## 现实生活中的假设检验

用数学解决现实世界的问题

towardsdatascience.com](/hypothesis-testing-in-real-life-47f42420b1f7)

3)统计假设

统计测试对被测数据做出一些常见假设(如果违反这些假设,则测试可能无效:例如,得出的 p 值可能不正确)

  1. 观察值的独立性:您在测试中包含的观察值/变量不应该相关(例如,来自同一个测试对象的几个测试不独立,而来自多个不同测试对象的几个测试是独立的)
  2. 方差的同质性:被比较的每组内的“方差”应该与组内其余方差相似。如果一个组比其他组有更大的方差,这将限制测试的有效性。
  3. 数据的正态性:数据服从正态分布,正态性是指检验的分布是正态分布(或钟形),均值为 0,标准差为 1,对称的钟形曲线。

来源:https://study lib . net/doc/10831020/the-bell-curve-the-standard-normal-bell-curve

4)参数测试

参数测试是那些只能用符合上面提到的 【三个统计假设】 的数据运行的测试。最常见的参数测试类型分为三类。

回归测试:

这些测试用于测试因果关系,如果一个或多个连续变量的变化预测了另一个变量的变化。

  • 简单线性回归:测试预测变量的变化如何预测结果变量的变化水平。
  • 多元线性回归:测试两个或更多预测变量组合的变化如何预测结果变量的变化水平
  • 逻辑回归:用于描述数据,解释一个因变量(二元变量)与一个或多个名义变量、序数变量、区间变量或比率水平自变量之间的关系。

比较测试:

这些测试寻找变量均值之间的差异:均值比较。

  • T 检验用于精确比较两组的平均值(如男性和女性的平均身高)。
  • 独立 t 检验:检验不同人群相同变量之间的差异(例如,比较狗和猫)
  • ANOVAMANOVA 测试用于比较两组或更多组的平均值(如儿童、青少年和成人的平均体重)。

相关性测试:

这些测试寻找变量之间的关联,检查两个变量是否相关。

  • 皮尔逊相关:检验两个连续变量之间的关联强度。
  • Spearman 相关性:测试两个顺序变量之间的关联强度(它不依赖于正态分布数据的假设)
  • 卡方检验:检验两个分类变量之间的关联强度。

参数测试总结(图片由作者提供)

5)流程图:选择参数测试

该流程图将帮助您在上述参数测试中进行选择。对于非参数替代,检查以下部分。

参数测试流程图(图片由作者提供)

6)处理非正态分布

虽然正态分布在统计学中占有中心位置,但许多过程遵循非正态分布。许多数据集自然符合非正态模型:

-事故数量往往符合“泊松分布”

-产品的寿命通常符合“威布尔分布”。

非正态分布的例子

  1. 贝塔分布。
  2. 指数分布。
  3. 伽玛分布。
  4. 逆伽马分布。
  5. 对数正态分布。
  6. 物流配送。
  7. 麦克斯韦-玻尔兹曼分布。
  8. 泊松分布。
  9. 偏斜分布。
  10. 对称分布。
  11. 均匀分布。
  12. 单峰分布。
  13. 威布尔分布。

那么,我们如何处理非正态分布呢?

当您的数据应该符合正态分布,但却不符合时,我们可以做一些事情来处理它们:

  • 如果您的样本量足够大(通常超过 20 个项目),我们仍然可以运行参数测试,并尝试相应地解释结果。
  • 我们可以选择用不同的统计技术来转换数据,迫使它符合正态分布。
  • 如果样本量很小,有偏差,或者如果它代表另一种分布类型,您可能会运行非参数测试

非参数测试

非参数检验(下图)对数据不做太多假设,当三个统计假设中的一个或多个被违反时,它是有用的。

注意:非参数测试做出的推论没有参数测试强。

非参数测试(图片由作者提供)

希望这篇文章对你有帮助。如果您有任何反馈,请告诉我。非常感谢你的阅读!

参考

1统计方法。2020.非正态分布—如何统计。[在线]可在以下网址查阅:https://www . statisticshowto . com/probability-and-statistics/non-normal-distributions

[2]Scribbr。2020.选择正确的统计测试|类型和示例。[在线]地址:https://www.scribbr.com/statistics/statistical-tests

统计思维:理解相关性

原文:https://towardsdatascience.com/statistical-thinking-understanding-correlation-5f7c63934699?source=collection_archive---------20-----------------------

从头开始的数据科学

建立对什么是相关性以及它告诉你什么的直觉

统计学是应用数据科学的核心,理解统计学会让你成为更好的数据科学家。即使——或者尤其是如果——你花了大部分时间去钻研现成的库,而不需要从零开始建立机器学习模型,你也会从理解支撑你的模型的统计力学中受益。当您调用某一类型的模型时,了解计算机正在为您做什么样的统计工作,对于选择在给定情况下使用哪个模型、了解数据将需要什么样的处理以及适当地调整您的模型来说,是非常关键的。

数据科学的学生,尤其是走训练营路线的职业中途改变者,可能会发现学习统计的本质有点令人生畏-像许多复杂的领域一样,统计有其自己的术语和符号,需要学习。不管是好是坏,许多人作为数据科学家工作,只有最低限度的统计学基础,但对统计学原理的某种直觉应该是先决条件。对一些甚至不需要任何数学知识的原则有一个好的内在感觉将会大有帮助。这些原则中首先是相关性。

相关性/独立性

对于任何类型的应用数据科学或分析来说,相关性可能是最重要的概念。两个变量相关意味着什么?简单地说,这意味着我们可以知道变量是相关的,因为它们以某种方式一起运动。也许一个上升,另一个下降,或者两者一起上升。这与一个变量的运动导致另一个变量上升或下降不同——可能有第三个看不见的变量在控制另外两个变量——但如果它们相关,知道其中一个变量的值仍会给你关于第二个变量的信息。

许多人在开始统计学课程时接触到了相关性,首先是皮尔逊相关系数的公式和一组显示不同相关性水平的图表,如下所示:

具有不同相关水平的分布

在最左边的图中,我们的 x 和 y 变量之间只有很低的相关性。右边是非常高的相关性;这两个变量似乎是同步移动的,当 X 增加时,Y 也总是跟着增加。皮尔逊相关系数的值很好地反映了重要的趋势,右边的锁步关系由接近 1 的值表示,左边的低相关性由接近 0 的值表示。当然,变量也可以是负相关的,其中 Y 值通常随着 X 的增加而下降:

正相关与负相关

因此,皮尔逊系数似乎能告诉我们很多信息,并且作为一种相关性的衡量标准几乎无处不在(如果你遇到一个“相关系数”的参考,并且没有具体说明,可以肯定它指的是皮尔逊系数)。尽管它很有用,但是,我想从计算这个奇异值转移到关注它对变量更广泛相关的意义。首先,统计学的新学生倾向于将相关值与两个变量之间的关联程度相混淆。相关系数并不是这样工作的。相关系数接近 1 仅表示 X 和 Y 变量协同移动:可以预期 Y 会随着 X 的上升而上升,而不是随着 X 的上升而上升多少。增加线的斜率实际上不会改变相关系数的值:

相关系数相同的三个分布

另一方面,皮尔逊系数实际上只是众多不同的相关性度量之一。为什么会有不同的相关性度量?变量可以有很多不同的关联方式。考虑以下几点:

这些变量看起来应该是相关的,不是吗?

希望您能马上看到 X 和 Y 变量是相关的,但是它们之间的皮尔逊系数接近 0。为什么会这样?皮尔逊系数是线性相关的度量,这两个变量之间的关系不是线性的!当 X 小于 0 时,Y 值随着 X 的增加而下降,但当 X 大于 0 时,Y 值随着 X 的增加而上升,这一事实混淆了这一度量。幸运的是,还有其他方法来衡量相关性。对于这种特殊情况,您可能会考虑距离相关性。也存在考虑可变等级而不是数量的其他相关性度量。

为什么这如此重要?

在某种程度上,相关性是所有应用数据科学的核心。当两个变量相关时,知道其中一个可以帮助你预测另一个。变量之间的关系可能是复杂的和非线性的,这就是为什么认为相关性不仅仅是一个单一的系数是很重要的。真正重要的不是任何特定相关系数的值,而是两个变量的值是否相关。尽管皮尔逊系数为 0,但形成上述抛物线的两个变量是相关的,知道 X 变量的值可以很好地暗示 Y 变量的值。

在现实世界中,变量的测量往往是有噪声的——你的测量可能会高一点或低一点,这取决于你如何或何时测量。变量之间的关系也可能混淆,这意味着还有第三个不可测量的变量独立地影响着你所关注的一个或两个变量。因此,判断两个变量是否有关联并不总是容易的。有用的关系可能被统计噪声掩盖。许多机器学习只是试图梳理出有用的相关性的聪明工具,即使并不立即清楚这些关系是什么。

“低相关性”仍然很有意义

我想把焦点从单一系数转移开的另一个原因是,低系数本身并不意味着没有非常有意义的事情发生。许多统计学导论课程在警告人们“伪相关”的危险方面做得很好,在伪相关中,两个彼此无关的变量由于随机机会而看起来相关(特别是当样本很小时)。你可以找到许多这种虚假相关性的例子,我特别喜欢泰勒·维根收集的那些例子:

Nic 凯奇电影会导致人溺水吗?泰勒·维根收集的惊人的虚假相关性

然而,入门课程往往不会花足够的时间关注相反的问题,其中真实的关系被低相关系数所掩盖。低相关系数可能与非常有意义的效果相关联。如果某种影响有许多不同的、独立的原因,尽管有因果联系,但这种影响和每个变量之间的相关系数可能很低。为了举例说明,请考虑我生成并绘制的以下 50 个点:

点的集合

看起来 X 和 Y 变量之间有很强的相关性吗?大概不会。皮尔逊系数是微不足道的 0.17。这个 X 变量在试图预测 Y 的模型中有用吗?你的第一个想法可能是否定的,但是如果我解释我是如何生成这些数字的,你可能会改变主意。我模拟滚动 6 个骰子,一半是六边形,另一半是二十边形,把数字加起来。上面画出的 X 变量只是这些滚动中的第一个。

因为总数是从如此多的卷中得出的,并且每个卷都是独立的,所以任何单个卷的相关系数都不可能很高。但是,如你所见,单独的低系数并不意味着变量是无用的。我在上面绘制的 x 变量(以及其他 5 个卷)具有真正的解释力。你需要完全准确地预测总数,只需要六次独立掷骰的结果,如果没有这一次,你永远也不会完全准确。

因果关系

找到相关性的下一步是考虑因果关系。你可能听说过 intro stats 的咒语“相关性不等于因果关系”。知道两个变量以某种方式联系在一起并不等同于知道它们是如何联系在一起的。您可以通过简单地查看数据来判断 X 和 Y 是否相关,但是 X 和 Y 有很多种关联方式。X 可以影响 Y,或者 Y 可以影响 X,或者其他变量可以影响两者。仅仅从数据上你无法判断哪一个是正确的。

例如,许多研究发现,学习一种乐器的孩子在学校表现更好。这类研究经常被用作证据,证明学习一种乐器能让孩子在学校表现更好;父母可能会听说他们,并决定他们的孩子应该学习钢琴,或者为学校音乐项目争取更多的资金。虽然我赞成学校的音乐项目,但这里的关系可能不像“教一个学生小提琴,然后看着他们的成绩上升”那么简单。首先,有许多令人困惑的因素,尤其是社会经济地位——有更多可支配收入的家庭更有可能负担得起一个感兴趣的孩子的乐器和音乐课。另一方面,因果关系可能实际上是反过来的——也许在学校表现好的学生更有可能想要学习一种乐器。那种专注并决心在数学课上出类拔萃的孩子也更有可能坚持学习一种乐器,直到他们看到令人满意的结果。

我们无法从观察性研究中判断到底是什么导致了什么,这一事实对政策有着重要的影响。也就是说,重要的是要记住,你不需要知道因果关系是如何流动的,相关性才具有预测能力。考虑一个大学招生官在看申请人。了解到长期学习音乐的学生往往在大学表现更好,在其他条件相同的情况下,官员可能会倾向于选择演奏乐器的学生入学。在某种程度上,对他们来说,为什么存在这种联系并不重要,他们不一定关心音乐学习是否让学生做得更好,或者是否有其他因素在起作用,他们关心的是这种关系的存在让他们能够更好地预测学生未来的表现。

相关性会使你的样本产生偏差

你经常听到“随机样本”这样的说法,不随机的样本可能会有偏差,但是样本“随机”是什么意思呢?我们处理的大多数看似随机的过程(也可能是宇宙中的一切,尽管这是另一个哲学话题)实际上都是确定的。抛硬币是“随机”的,因为你不太可能知道它会以哪种方式落地,但它是完全确定的,因为它是正面还是反面落地完全取决于硬币在空中的旋转和运动,而这又完全取决于硬币从你手中弹离的角度和力度。类似地,计算机不能以真正随机的方式行动。如果你让你的计算机生成随机数或随机取样,它将生成“伪随机数”,看起来适当随机,但实际上是从混沌但最终确定的物理过程、算术运算或两者的某种组合中得出的。

为什么需要随机数,我们如何判断伪随机数是否足够“随机”?其中一个关键是,随机数(或通过随机方法选择的样本)是独立的,与我们正在研究的任何东西都不相关。即使这些方法不是真正“随机”的,通过掷硬币或掷骰子来选择样本也很有效,因为掷硬币或掷骰子的结果与样本中的项目无关,反之亦然。

我提出这一点是因为许多数据科学是使用完全不是随机的数据池完成的。例如,公司拥有大量客户数据,他们可能想要挖掘这些数据以获得某种洞察力,但是,根据定义,你只能拥有关于你的客户的客户数据。这通常会限制你从数据中合理做出的推断,特别是因为你想要研究的变量与样本的收集方式相关。

例如,我曾经做过一个项目,研究人们对汽车的满意度。进行了一项调查,人们回答了关于他们汽车的基本信息(品牌、型号、年份等)。),他们是否遇到了汽车的某些问题以及他们的总体满意度。该团队试图模拟出一个人对自己的汽车的满意度,一些人惊讶地发现,随着车龄的增长,该模型预测的满意度会更高。当然,人们会对老式汽车不太满意?

这是一个样本选择方法和目标变量(满意度)相关的案例。毕竟,如果你真的对你的车不满意,你更有可能在你能负担得起的情况下尽快换掉它。开同一辆车十五年的人大概都喜欢开那辆车。讨厌自己车的人不会把车开那么久。在所有其他条件相同的情况下,你可能会认为人们更喜欢新车而不是旧车,但是通过调查得出的样本不会有旧车和不满意的司机的交集。

这并不意味着调查没有用,也不意味着你不能在你的模型中包括车龄。事实上,年龄最终成为了一个非常有用的满意度预测指标,正是因为这种相关性的;如果你告诉我你已经开同一辆车很长时间了,那么你这么做的部分原因是因为你喜欢它(或者至少不讨厌它),这不是一个坏的赌注。然而,这种相关性确实限制了模型的用途。如果你已经做了这样的分析,一家汽车公司问你如何提高客户满意度,回答“嗯,开老爷车的人往往对老爷车很满意,所以你应该给你的客户老爷车”不会有太大帮助。

统计上无关紧要的烟雾

原文:https://towardsdatascience.com/statistically-insignificant-smoke-f86ede4a8289?source=collection_archive---------29-----------------------

夸大统计签名卡

资料来源:https://unsplash.com

假设你正在开会,看着某人展示一个图表。该图显示了一个重要的小客户群的关键绩效指标的趋势。我们都经历过。

演讲者指着图表中的一个尖峰,告诉人们忽略它,因为它的“样本量”很小,缺乏“统计意义”。人们点头,演示继续进行。

坚持住。结论可能是对的,但推理是错的。

首先,图表不是基于一个样本。该图基于整个段。只是刚好是一小段。

这意味着采样没有方差或偏差,这反过来意味着尖峰确实发生了。然而,油价飙升是否重要,是否值得采取后续行动,则是另一回事了。

这是怎么回事?小人口规模正与小样本规模混为一谈。但是这种区别实际上关系到我们如何解释数据。

让我们通过浏览这两个场景来深入了解一下。

关于小群体:

假设我们有两个小村庄——村庄 A 和村庄 B——每个村庄有 5 个居民。我们想比较这些村庄的平均收入水平。这些村庄所有 10 个人都有干净的收入数据。

我们的计算显示,A 村的平均年收入为 50k 美元,b 村为 60k 美元。这种差异是 100%真实的,因为我们查看了这两个村的所有数据。还有,感觉是实质性的区别;B 村的人平均多赚 20%的钱。

现在,事实证明 B 村的平均收入更高,因为有一个人每年挣 10 万美元。这个人决定搬到另一个村庄,现在 B 村的平均收入下降到 51k 美元。1000 美元的差异仍然是 100%真实的,因为我们仍然在看所有公民的数据,但这感觉不再是实质性的。只需要一个人动一动!

这个故事的寓意是什么?在处理小群体(例如,小部分客户)时,我们在解释指标峰值时一定要小心,因为单个异常值或几个新数据点的添加都会改变事情。波动性更大。但这与统计显著性或抽样无关。

关于小样本量:

这就是统计学意义发挥作用的地方。

想象两个大城市,每个都有数百万居民。我们想知道这些城市的平均家庭收入水平是否不同,但是我们没有这些城市的任何收入数据。

所以我们使用假设检验和抽样:

  1. 创建一个无效假设和一个替代假设。无效假设是平均收入水平相同。另一个假设是平均值不同。
  2. 从每个城市随机抽取样本。
  3. 拒绝或接受零假设。通常,您会根据测试统计来计算p-值(除非您是反频率主义者)。我们可以不严格地**将p-值视为当其为真时拒绝零假设的机会(犯类型 1 错误)。在大多数情况下,当p-值小于 0.05 时,人们会舒服地拒绝零假设并声称有统计学意义。

我们的样本越小,我们就越有可能犯第二类错误——也就是说,当确实存在差异时,我们无法拒绝零假设。

那么有哪些外卖?

→我们不应该如我的题目所暗示的那样忽视统计学意义。这是一个完全合法的框架,经常应用于许多不同类型的应用程序,从药物测试到市场营销。但它不适用于小群体的尖峰图。

→如果我们处理的是小规模人群,我们不能说指标中的所有峰值和谷值在统计上无关紧要,就自动放弃它们。这只是在吹统计烟雾时应用了错误的框架。

→为什么这很重要?这不仅仅是关于使用正确的统计学术语(尽管那样会很好)。真正的问题是:如果我们总是对每一个小群体异常做出相同的(错误的)全面诊断,我们将不可避免地错过一些重要的东西。在某些时候,所有大客户群都是小群体。

**从技术上讲,p-值是在假设零假设为真的情况下,获得至少与观察结果一样极端的结果的概率。当零假设为真时,它实际上不是拒绝零假设的概率,因为p-值是基于频率主义推理(与贝叶斯推理相反),因此不提供关于假设的任何概率度量。见此处

具有统计意义的编年史

原文:https://towardsdatascience.com/statistically-significant-chronicle-d1b498c476e9?source=collection_archive---------29-----------------------

t 检验、单因素方差分析和事后检验——这些是什么,何时使用哪一种,如何使用?

在我之前的文章的一篇中,我们谈到了统计学意义的基础,我得到了一些非常有希望的反馈,这让我回到这里尝试涵盖更多的概念。

先从 t-tests 开始吧。当我们不知道总体均值和标准差时,进行 t 检验,以找出两组的均值之间的差异。该检验背后的基本假设是,它假设样本来自具有正态分布的总体。我将用一个例子来更好地解释这一点:

有两家你喜欢的不同的餐馆。其中一个平均评分 3.5,另一个平均评分 3.7。你需要带你的约会对象去这些餐馆之一。你应该选择评分高的那个吗?我想你应该这么做,因为这是一个约会,但是如果第一个的人均花费是 30 美元,而第二个是 60 美元呢?评分的差异是否有统计学意义,足以让你的钱包负担翻倍?找出答案的唯一方法是对餐馆 A v/s B 的评级集进行 t-test。选择两个地方的所有评级数据集,并对它们进行 t-test。这样你就回答了这个问题:评分的差异是否足够显著(或者仅仅是一个巧合)?当然,我不建议与你的约会对象分享你进行了 t 测试来选择地点,但我希望我成功地向你展示了这个测试的用例。

在你的约会中这样说话,你 100%可能(参考我以前文章中的影响大小)不会有 p < 0.05 的第二次约会

下一部分是如何进行 t 检验。我将在 python 上发布一个简单的代码片段来说明这一点,并为您解释结果。为了同样的练习,我将挑选The Rocks Cafe&Dare Cafe作为问题中的两家咖啡馆。首先要做的是检验正态假设。这里我指的是样本来自正态分布的总体。疯狂的假设,对!如何检查收视率的总体,以确定收视率是否呈正态分布!常识告诉我,它应该是正态分布的,但有办法检查这一点吗?可能有…但这不是简单的事情。因此,虽然我在这里假设它们是正常的,并继续前进,但我也将展示在你不打算简单地说“常识”的情况下该怎么做,以及假设结果在这种情况下如何不同。****

**#Getting the Dataset ready!
import itertools
import numpy as np
ratings = [1,2,3,4,5]
ratings_rocks=[27,35,111,402,526] #number of 1,2,3,4 and 5 rating for The Rocks
ratings_dare=[9,4,6,51,156] #number of 1,2,3,4 and 5 rating for Dare
ratings_rocks_list=list(itertools.chain.from_iterable(itertools.repeat(x, y) for x,y in zip(ratings,ratings_rocks)))
ratings_dare_list=list(itertools.chain.from_iterable(itertools.repeat(x, y) for x,y in zip(ratings,ratings_dare)))
print ("Rating for Rocks is: "+str(np.mean(ratings_rocks_list)))
# Rating for Rocks is: 4.239782016348774
print ("Rating for Dare is: "+str(np.mean(ratings_dare_list)))
# Rating for Dare is: 4.508849557522124**

现在我们已经准备好了数据集,让我们创建两者的平均值和标准差,然后是标准误差和自由度,以获得… Naah…所有这些…您需要做的就是从 scipy.stats 库中运行 ttest_ind 以获得以下内容

**from scipy.stats import ttest_ind
stat, p = ttest_ind(ratings_rocks_list, ratings_dare_list)
print('t=%.3f, p=%.4f' % (stat, p))
#t=-3.943, p=0.0001**

如果你碰巧交换了这两个列表,改变的只是 t 值的符号。不要太在意 t 值,因为它与 p 值相关联,如果你能读出校正后的 p 值,那就没什么意义了。因此,这里的结果表明,即使两家咖啡馆的评分相差 0.25,这也是一个相当大的差异,值得你为约会换个地方。

然而,我认为强调学生的 t-test(我们刚刚在上面检查过的那个)是最好的实践是公平的,因为我们的处理能力非常有限。现在我们有了更好的计算能力,使用像 Wilcoxon 测试这样的东西是更好的选择,它不会形成像我们在上面所做的假设一样的假设,比如人口的正态分布。让我们用 Wilcoxon t 检验(2 样本 Wilcoxon 检验也称为曼惠特尼 U 检验)做同样的事情,看看我们得到什么样的结果。

**from scipy.stats import mannwhitneyu
stat, p = mannwhitneyu(ratings_dare_list, ratings_rocks_list)
print('t=%.3f, p=%.4f' % (stat, p))
#t=98019.500, p=0.0000**

由此,我们看到结果表明了同样的事情,尽管由于两个测试背后的基本方法和假设,两个场景中的 p 值是不同的。如果你要比较两个不同的样本,我会推荐使用这种方法,而不是学生的 t 检验,因为学生的 t 检验方法假设了正态性。

让我们转到另一个场景。如果我想比较 3 个不同的咖啡馆,而不是 2 个不同的样品/咖啡馆,会怎么样?一种方法是对 A 和 B,A 和 C,B 和 C 做 Wilcoxon t 检验,很简单!但是如果我们有 4 家甚至 10 家咖啡馆呢?这些组合将会不断增加。为了处理这种情况,我们做了一个叫做单向方差分析的测试。单向方差分析(ANOVA)用于确定三个或三个以上独立(不相关)组/样本的平均值之间是否存在任何统计学显著差异。

这里需要注意的是,单因素方差分析可以用来替代多组的 t 检验,但从数学上来说,它更像是一个回归模型,用于建立因果关系。

例如,如果我们去看我的关于分段的文章,一旦我从层次聚类方法中得到一个聚类,我就对这些聚类进行方差分析,以确定这些聚类是否实际上是不同的,给定所有特征中的这些差异。

执行 ANOVA 的最好方法是使用下面的代码集

**from statsmodels.formula.api import ols
formula='y~C(X1)+C(X2)'
results = ols(formula, data=df).fit()
results.summary()**

在上面的公式中需要注意的是,它借用了 R,这就是为什么你看到的格式有点非 pythonic 化。作为对上面代码的总结,您将得到如下表格

上面代码的总结

我们来试着解读一下上表。正如您可能已经猜到的,首先要注意的是总体概率(F 统计量),它表示结果的 p 值。这表明在总体水平上,这些组是否不同。如果是,那么你继续检查每个独立变量的 P>|t|,这表明这些变量中的哪些在模型中实际上是不同的。在上面的例子中,我们可以看到,由于这个值小于 0.05,只有 x2 是显著不同的。当然,这里还有其他重要的参数,我们应该关注,其中最重要的是调整后的 R2,它解释了 y 中有多少可变性是由 x 中的可变性解释的,这表明了模型的稳健性或完整性,但这是另一天的讨论。暂且这么说吧,光看这些参数应该就够我们用的了。

应该注意的是,多重共线性经常会影响单个 t 检验的结果。这是一个特别常见的情况,通常可以通过正确阅读此表来解释。多重共线性的一个症状是单个系数不显著,但总体 p 值显著。

让我们假设方差分析给我们的结果是各组之间有显著差异。那么下一个问题来了——那又怎样?为了回答这个问题,我们使用事后测试。

事后分析的字面意思是“在此之后”,只有当你已经确定方差分析在要求的水平上是显著的,它才应该被应用。事后测试确定了两组之间的实际差异。让我们回到我举的电影例子。一旦我确定集群差异在总体水平上是显著的,我就继续应用 Tukey 测试,这是一种事后测试。使用下面的代码:

**import statsmodels.stats.multicomp as multi
for col in city_final.columns:
    mc1=multi.MultiComparison(city_final[col],city_final['Cluster'])
    res1=mc1.tukeyhsd(alpha=0.05)
    print col
    res1.plot_simultaneous()
    plt.show()
    print res1.summary()**

有了上面的 cole 代码片段,我开始为所有分类列创建一个家族式的检查,以找出聚类之间的不同之处。作为上面代码的结果而创建的一个图的例子是

Tukey 测试示例图

上面的图表明,对于这个特定的特征,其中 0 和 2 分类彼此非常相似,分类 1 具有显著更高的值(p<0.05 水平,因为这是我们在上面的代码中使用的)。我们记下了每个集群的所有主要特征,瞧,我们有了这 3 个集群的定义。

我希望通过这些例子和代码片段,我已经使事情变得更容易理解了,并且您不再是(了!)被下面的 xkcd 帖子搞糊涂了:)

统计学家也应该学习张量流

原文:https://towardsdatascience.com/statisticians-should-learn-tensorflow-too-58309441d3c2?source=collection_archive---------38-----------------------

统计学和机器学习在某种程度上一直存在分歧。下面是 TensorFlow 如何弥合这一差距。

委婉地说,统计学家总是带着一定程度的怀疑看待机器学习。

虽然统计学依赖于科学方法,并与任何学术领域一样受到同样的辩论和审查,但机器学习已经获得了“黑箱”方法的恶名,即数据只是被插入模型以产生结果,而结果不一定可靠。

来源:图片由 ArtsyBeePixabay 拍摄。

也就是说,如果知道如何正确利用统计学和机器学习,这两者的结合会非常强大。

以下是我个人经验中的一些例子,说明 TensorFlow 是如何变得更加“统计友好”的,以及为什么这个软件库应该得到统计界更多的关注。

1。TensorFlow Probability 是一个被低估的概率编程工具

TensorFlow 最初发布于 2015 年,2018 年 6 月发布了第一版 TensorFlow Probability。

这个库结合了概率编程深度学习的能力,以便对大型数据集进行统计分析。具体来说,TensorFlow Probability 强调了贝叶斯方法,它补充了 Python 中的 PyMC3 库,pym C3 库也实现了贝叶斯建模和统计分析。

我预计这个图书馆将对未来的统计学家变得越来越重要。随着数据集变得越来越大,人们越来越重视概率在时间序列分析中的作用,张量流概率在处理这两个方面非常有效。

在新冠肺炎事件发生之前,我一直在做一个关于酒店取消预订的兼职项目。该项目的部分目的是运行一些时间序列模型来预测给定酒店每周取消预订的数量。

然而,一个纯时间序列模型有其局限性,因为它不能解释极端情况下的时间,即全球疫情关闭酒店并导致取消预订的大幅增加。从这个角度来看,如果以今天的数据为模型,ARIMA 或 LSTM 等模型仍将被证明是非常不准确的。

也就是说,如果同样的数据用张量流概率建模会怎么样?

来源:Jupyter 笔记本输出

在查看该图时,我们可以看到,虽然也给出了线性预测,但该预测是基于后验分布建模的,以确定结果的范围。例如,我们可以看到,在极端情况下,取消订单可能会超过每周 500 个。

这使得酒店可以询问——在什么情况下酒店每周会有超过 500 次的取消预订——以及如何防止这种情况发生?

在进行预测时,张量流概率考虑到了不确定性,我预计这将变得越来越重要。

2。Keras 和 R 的兼容性强

从 TensorFlow 版本开始,Keras 已经成为库的默认 API。

Keras 用于快速直观地生成深度神经网络。这种神经网络可用于设计分类和预测任务,以及用 LSTM 模型进行时间序列分析。

但是,Keras 也能够在 R 环境中运行,这一点不一定广为人知。

这为基础统计分析与机器学习模型的结合提供了一个强大的平台。

一个例子(在下面的参考文献部分引用)是使用序列模型来预测血糖水平。

该库附带了可视化训练和验证损失的工具,就像在 Python 中一样:

资料来源:RStudio

然而,R 用户也可以利用 R 中的许多统计函数来促进分析。虽然像 Python 中的 pyplotseaborn 这样的库也可以生成相关图,但是使用 r

资料来源:RStudio

此外,R 还附带了一个名为 MLMetrics 的便利库,可以轻松计算损耗和精度指标。

从这个角度来看,希望利用机器学习的统计学家可以很容易地使用 Keras 在 R 中完成工作,而不是为了利用机器学习解决方案而必须学习 Python。

3。与微软的 InterpretML 等可解释库结合使用时非常直观

最近,人们越来越重视让机器学习模型变得可解释。也就是说——让模型输出容易被人类理解。

例如,来自微软的 InterpretML 库的 DiCE 擅长于通过生成不同的反事实解释。例如,假设我们正在构建一个分类模型,以预测客户是否会根据不同的属性取消酒店预订,例如他们的原籍国、交付时间、客户类型等因素。

在本例中,DiCE 能够获取客户未取消预订的实例,并生成反例,即特征参数的变化会使客户更有可能取消预订。

来源:Jupyter 笔记本输出—解释

当使用 Keras 构建顺序模型时,DiCE 通过保留模型训练参数对此进行补充,即使数据本身必须在一段时间后删除,例如,由于数据隐私法规等。

从这个角度来看,机器学习正在发展到一个重点,即让结果更加直观和易于理解——从这个例子中我们已经看到,TensorFlow 可以在这方面很好地补充其他 ML 库。

4。必要时能够跨其他领域同时构建模型

你可能是一名统计学家,但你能肯定地说你永远不需要跨另一个学科构建算法吗——例如自然语言处理或图像分类?

学习张量流和神经网络的美妙之处在于,不同领域的模型配置实际上可能非常相似。

例如,我第一次接触 LSTM(长短期记忆)网络是通过一门自然语言处理课程。然而,由于这种模型的序列性质(或理解观察值之间的依赖性的能力),我了解到 LSTM 模型在建模不稳定的时间序列数据时实际上是非常有效的。这个模型不一定适合所有情况——如果一个时间序列有一个很强的趋势,那么更传统的模型,如 ARIMA 模型,往往会更好地工作。

然而,我发现自己使用 LSTM 来完成某些时间序列任务,因此在这种情况下,机器学习仍然与时间序列学科相关。

作为另一个例子,学习如何将 CNN(卷积神经网络)用于分类任务,可以更容易地理解如何使用相同的网络进行图像分类。通过这种方式,理解张量流神经网络如何运行也有可能打开其他学科的知识。

结论

作为一个经常使用时间序列和统计方法的人,我发现 TensorFlow 在这些领域使用机器学习时非常有用。

我预计,随着数据量越来越大——越来越需要机器学习来及时有效地处理这些信息——同时仍然允许对结果进行直观的解释。

出于这些目的,我对 TensorFlow 印象深刻,它将继续成为我的数据科学工具包中的重要参考。

免责声明:本文是在“原样”的基础上编写的,没有担保。本文旨在提供数据科学概念的概述,不应以任何方式解释为专业建议。

参考文献

统计与概率:概率导论

原文:https://towardsdatascience.com/statistics-and-probability-introduction-to-probability-3922a8596ab8?source=collection_archive---------16-----------------------

乔希·阿佩尔在 Unsplash 上的照片

想象你在一场比赛中。主人给你呈现了三扇门。其中一扇门后是一辆全新的奥迪,其余两扇门后是山羊。主人让你从这三扇门中选择一扇门,然后打开剩下的两扇门中的一扇门,展示一只山羊。现在告诉我,你是坚持你最初的门还是切换到另一个未打开的门去拿你的奥迪?

这就是著名的天魔堂问题。如果我告诉你,通过学习概率的基础知识,你有更大的机会赢得这场比赛,并带着一辆全新的奥迪回家,会怎么样?当谈到机器学习时,统计和概率是被广泛忽视的主题。很多人倾向于忽略它们,因为它们看起来很难,可能没有机器学习那么酷。但是,为了理解和掌握一些最常用的机器学习算法背后的核心概念,至少熟悉统计和概率的基础知识是很重要的。这篇文章的目的是给你一个关于概率及其各种类型的有价值的介绍。除此之外,我们还需要解决天魔厅的问题,所以让我们来看几件重要的事情。

可能性

顾名思义,概率只不过是对一个事件发生的可能性的估计。也被称为边际概率,它只是一个反映事件发生可能性的数字。它可以是 0 到 1 之间的一个数字,也可以表示为一个百分比值。让我们一步一步来。

实验

我们将在概率论的背景下定义一个实验,概率论是数学的一个分支,专门研究概率。一个实验被定义为一个程序,虽然可以重复无数次,但仍然有一组明确定义的可能结果。

随机 v/s 确定性实验。图片作者。

一个实验可以有两种类型,我们根据结果来区分它们。两者都有一个例子:

  • 随机实验:掷骰子可以得到 6 个值中的一个-
  • 确定性实验:将一些特定的数字相加总会得到相同的结果

事件

一个事件是一个结果,或者更确切地说是一组我们可以计算概率的实验结果。实验的所有可能结果的集合形成了样本空间。所以我们可以说事件基本上是样本空间的子集。
比方说,我从钱包里拿出一枚硬币,然后抛硬币。这里的实验是抛硬币——可能的结果是什么?
可能是正面也可能是反面——你知道其中一个会是结果,但你不能说是哪一个。这意味着有两种可能性——正面着地或反面着地。

随机变量

在这样的情况下,正如前面提到的,我们说这个实验是随机的。任何代表这种随机实验结果的变量被称为随机变量。但是,你能说正面事件发生的可能性有多大吗?还是反面?

概率论直觉

因为翻转正面是这两个可能场景中的一个事件——{正面或反面}——我们说这个事件有 50%的概率是正面。同时也可以说有 50%的几率翻跟头。

正面还是反面?照片由rupixen.com

如果我们扩展这一逻辑,我们可以提出一个类似的方法,可以应用于其他领域和问题。让我们再研究一个这样的问题。

作者图片

假设我们有一个包。我们在袋子里放了三个不同颜色的球——{蓝色 O,绿色 O,红色 O}。
能知道拉出红球 O 的可能性有多大吗?
按照和我们掷硬币实验相同的逻辑,我们看到这里有三种可能的结果。当我们从袋子里拿出一个球时,我们可以得到这三种颜色中的一种。因此,我们得到红色的概率应该是 1/3。

同样可能发生的事件

为了让这一切以这种方式发生,也就是为了让这种直觉发挥作用,请注意,这些事件都有同等的可能性。这意味着每个事件都有完全相同的可能性或完全相等的机会发生。我们得到正面的可能性和得到反面的可能性一样大。同样,我们从袋子里拿出红色球的可能性和我们拿出绿色球的可能性一样大。不存在偏见或其他任何有利于某一事件的因素,它们都有相同的发生机会,因此这些事件被称为同等可能性事件。

形式定义

对于同样可能发生的事件,例如上述事件,概率公式表明,对于每个事件,概率将是特定事件可能发生的方式的数量与可能结果的总数的比率。换句话说,一个事件发生的概率是该特定事件发生的方式数与可能结果总数的比率。

如果你再看一遍,你可能会注意到这是怎么回事:

举个例子,看看这个:

在掷骰子上掷出 4 的概率是 1/6。图片作者。

概率的性质

  • 所有概率都在 0 到 1 之间,包括 0 和 1
  • 概率为 0 意味着事件是不可能的,它不可能发生
  • 概率为 1 意味着事件肯定会发生

独立事件

从概率上讲,如果一个事件的结果不影响另一个事件的结果,那么这两个事件就被称为是独立的。一个例子是滚动一对骰子——其中一个骰子的结果不会影响第二个骰子的结果,我们可以得到总共 36 种不同的结果组合。

一对骰子的组合。图片作者。

但是谈论从一副洗牌的纸牌中抽出一张牌,每一次移动都会改变概率。假设我们想找出从一副洗得很好的牌中抽出方块 a 的概率。在第一次尝试中抽出这张卡的概率是 1/52。但假设第一步出黑桃 7,那么第二次出方块 a 的概率是 1/51,这意味着这不是独立的事件。

照片由 杰克·汉密尔顿

联合概率

为了解释什么是联合概率,我们将快速浏览另一个有趣的主题,集合论——处理集合的数学分支,简单地说,就是对象或元素的集合。看这张维恩图:

集合论举例。图片作者。

正如我们所看到的,有三个圆圈 A、B 和 C 相互交叉,每一个都代表某种东西。交叉区域的标签中也有奇怪的小符号— 。在集合论中,这些符号表示交集。如果我们认为 A、B 和 C 是集合,∩将表示这些集合中的那些元素,它们是这个符号两边的集合所共有的。例如,我们为了举例而假设——
A = { 4,22,10,19,97 }
B = { 30,3,9,19,97 }
这将暗示 A ∩ B = { 19,97 }

让我们再举一个例子——
事件 A =关注足球的人(我指的是英式足球,为了我亲爱的美国读者)
事件 B =关注板球的人
事件 C =关注 F1 的人

A ∩ B =同时关注足球和板球的人

A ∩ B ∩ C =关注所有这些运动的人

现在回到联合概率,我们可以把它定义为两个或两个以上事件同时发生的概率。在我们上面的例子中,(A ∩ B)是同时喜欢足球和板球的人。随机选择的一个人同时喜欢足球和板球的概率将是 P(A ∩ B)。如果你看上面的文氏图,这个人会出现在事件 A 和 B 相交形成的区域。

联合概率是一个重要的统计量,你可以找到各种各样的小问题来练习。这个概念要求两件事同时发生,而纸牌给了我们很多这样的情况,比如:

  • 抽到一张既红又 2 的牌的概率有多大?
  • 抽出一张既红又奇数的牌的概率有多大?

对于独立事件,联合概率仅仅是它们的边际概率的乘积。因此,如果事件 A 和 B 是独立的:

-> P(A ∩ B) = P(A) * P(B)

条件概率

条件概率是在已知其他事件已经发生的情况下,某一事件发生的概率。所以如果 A 和 B 是两个事件,条件概率可以告诉我们,如果事件 B 已经发生,事件 A 发生的可能性。等等,这听起来很像联合概率。别担心,我们之前读过掷骰子的例子,现在让我们再看一遍。让我们来看两个事件:

  • 事件 A —掷出数字 4
  • 事件 B —掷出一个偶数

从我们所知道的,我们可以很容易地弄清楚这一点:

条件概率例子。作者图片

将这些作为两个独立的事件很好,但是如果我们确定事件 B 已经发生了,会发生什么呢?如果我们确定骰子已经掷出一个偶数,你认为得到 4 的概率是 1/6 吗?简短的回答是否定的。现在我们知道我们的结果肯定是一个偶数,我们的可能结果集从{1,2,3,4,5,6}减少到{2,4,6}。这意味着现在从这一组中掷出 4 的概率应该是 1/3——所以我们得到 4 的机会是以前的两倍。显然,仅使用忽略事件 b 的新信息的边际概率是不明智的。如果我们将这种方法形式化,我们将得出:

条件概率——给定 B 已经发生的概率。

联合概率和边际概率就是这样走到一起,形成条件概率的。左手边的术语 P(A/ B)代表这样的陈述——假设事件 B 已经发生,事件 A 发生的概率。例如,让我们谈谈云和雨(以及它们让你感觉如何?).假设你想知道今天多云,有多大可能下雨。我们所需要的是雨和云出现的联合概率以及雨的边际概率,我们就能找出这一点。

让我们做另一个示例问题来解决这个问题。这里我们有一个学习天体物理学和艺术的学生的维恩图(一群有趣的学生)。如果他们正在研究天体物理学,我们能找出他们研究艺术的可能性吗?

条件概率例子。图片作者。

从图像中我们可以计算出这些东西:

  • p(天体物理学)= 112/358
  • p(艺术)= 240/358
  • p(天体物理学∩艺术)= 6/358

现在,我们想知道一个已经在学习天体物理学的学生学习文科的概率:

P(艺术/天体物理学)= P(天体物理学∩艺术)/ P(天体物理学)
= > 6/112

这给了我们学习这两个科目的学生与只学习天体物理学的学生的比例,这就是我们如何找到条件概率的。

现在,让我们回到我们的蒙蒂霍尔问题。这个问题有很多解决方案,打开维基百科页面就会看到所有的解决方案。

[## 蒙蒂·霍尔问题

蒙蒂霍尔问题是一个脑筋急转弯,以概率谜题的形式,大致基于美国电视…

en.wikipedia.org](https://en.wikipedia.org/wiki/Monty_Hall_problem)

我们将讨论“简单解决方案”。看这张表,假设我们总是选择门 1:

作者图片

正如你所看到的,一个简单的结果表格显示,如果你换成 2/3,你有更高的概率赢得比赛。让我们快速浏览一下这个例子。在第一个场景中,我们的奥迪在 3 号门后面。我们已经选择了 1 号门,所以主人将打开 2 号门来展示一只山羊。如果我们选择 1 号门,我们就输了。如果奥迪在 2 号门后面,主人会打开 3 号门露出一只山羊,再次切换到这里将为我们赢得比赛。这意味着 2/3 次的交换会导致胜利。只有在情景 3 中,如果他们选择留下,我们就赢了——这有 1/3 的概率。

在这篇文章中,我想给你们简单介绍一下概率的所有概念,我希望你们喜欢这篇文章,请在评论中告诉我你们对内容的看法!
快乐阅读!

原载于 2020 年 10 月 3 日【https://thedatascienceportal.com】

[## 数据科学门户

大家好,欢迎来到数据科学门户网站。这个空间致力于学习和理解所有令人兴奋的…

thedatascienceportal.com](https://thedatascienceportal.com)

统计:集中趋势

原文:https://towardsdatascience.com/statistics-central-tendency-5e514a2f98fd?source=collection_archive---------34-----------------------

数学和 Python 编码示例,解释汇总数据的有用方法

照片由 Unsplash 上的agency followeb拍摄

在我们寻求汇总数据的过程中,无论是通过数据表还是视觉效果,我们都希望呈现数据的整体。然而,我们常常希望有一个点能够代表手头的数据。在数据序列中使用任何极值只能解释序列的一端。因此,使用一个中心值,其中一些观测值比它大或小,这可能是有用的。这样的一种度量叫做。然而,一个中心点能说明整个故事吗?您知道有些值比中心趋势值大或小,但是它并不涉及数据的分布或异质性。这就是 色散 的措施。这两个概念构成了许多高级统计概念的基础。

本文的目的是描述集中趋势的不同度量,并介绍一些简单的 python 代码来解释如何在实践中看到它们。我将在后续文章中尝试分享一些关于 色散的知识。

图 1:图像中绘制数据的集中趋势和分散

集中趋势

下图可以很容易地展示不同的集中趋势指标:

图 2:集中趋势的不同度量

从图中可以明显看出,集中趋势可以分为 3 类——均值、中值和众数。在我们进入每一个细节之前,有必要看一下由 Udny Yule 教授定义的理想的集中趋势测量的必要性质

  • 该度量需要基于数据中的所有观察值,
  • 基于所有的观察,
  • 受采样波动的影响尽可能小
  • 严格定义、易于计算、易于理解和
  • 有可能做进一步的数学工作

考虑到这一点,让我们看看下面不同的集中趋势的措施。此外,这里值得注意的两个概念是人口样本。 总体是数据集中所有可能观察值的集合,而样本是使用不同技术从总体中抽取的子集。

平均

平均值是通过对一个数据系列中的所有观察值进行各种数学运算来计算的:

  • 算术平均值:最容易计算的度量之一,算术平均值定义为一个数据序列中所有观测值的总和除以该序列中所有观测值的计数。数学上,

这里要注意的一个有趣的 A.M .特性是,如果一个系列中的每个观测值以相同的常数增加或减少,新系列的 A.M .也会以相同的常数增加或减少。

  • 几何平均值:几何平均值定义为一个数据序列中 n 个观测值乘积的第 n 个根。数学上,**

如果计算可以更进一步,很容易看出对数的使用可以使计算更容易。

  • 调和平均值:调和平均值是一个数据序列中所有观测值倒数的算术平均值的倒数。通过使用倒数,调和平均值对较小的观测值给予较高的权重,对较大的观测值给予较低的权重,因此在数据中有一些非常大或非常小的观测值时很有用。数学上,

三种类型的平均值之间的有用关系是(查看下面的 Python 代码进行演示):

这个关系有一个详细的数学证明,我将在正文中跳过,在后续版本中单独提供。

中位数

在一系列的观察中,中位数被定义为最中间的值。在一个离散序列中,如果观测值的计数是奇数,那么中位数就是有序序列的第(N+1)/2- 个观测值。然而,如果离散序列有偶数个观察值,则中位数近似为有序序列的第(N/2)和第(N/2)+1- 个观察值的算术平均值。

例如,如果有一系列观察值:8,12,151,7,5,10,8,9,11。有序数列(升序)为:5,7,8,8,9,10,11,12,151。该系列有 9 个观察值,因此(9 + 1)/ 2 =第 5 个观察值是中间值,即 9。现在,假设我们添加另一个观察值,比如 6。新的有序序列是:5,6,7,8,8,9,10,11,12,151。该系列现在有 10 个观察值,这是偶数。因此,中位数是(10/2)=第 5 次和(10/2+1)=第 6 次观察的算术平均值,即(8 + 9)/2 = 8.5。

如果有离散或连续数据的频率分布,而不是上述的单个序列,会怎么样?

图 3a(左)和图 3b(右):不同类型数据的频率表

我们参考类似图 3a 和 3b 的频率表。3a 中的表格稍微简单一些,所以让我们先来解决这个问题。这里的观察总数是 250,这是偶数。因此,中位数将是第 N/2 = 125 次观察。通过查看累积频率(图 4),可以确定第 125 次观察。在列出离散观察值的表 3a 中,我们预计第 125 次观察值为 5。为什么?有 112 个观察值≤ 4。接下来的 25 个观察值为 5。因此,给定 112 + 13 = 125,这意味着在最后 4 次观察之后的第 13 次观察应该是 5,因此是中值。

图 4:查看累积频率(即,直到特定点的观察总数)有助于确定中值

接下来,我们来看 3b。按照上面的方法,我们可以发现中位数位于 46-55 级,但我们不知道一个确切的点。能找到吗?答案是肯定的。更多的时候,可以通过绘图从数据中得到答案。本例中的累积频率可针对重量等级的每个限值进行计算(如图 4 ),并绘制成图表:

图 5:一个卵形图,显示了小于特定重量值(磅)的累计观察计数。)

假设数据中有 3000 个观察值(N),中值将是第 N/2 = 1500 个观察值,位于 135-144 磅范围内(这是中值类别)。根据上面的图表(图 5),如果你在横轴上画出对应于纵轴上累积频率= 1,500 的点,你会发现重量约为 137 磅。因此,平均体重约为 137 磅。这种曲线被称为卵形。这可以概括为一个数学公式:

当这些值被替换时,本例的中值为 136.96。

方式

众数被定义为在一系列观察中最频繁出现的值。考虑像 9、1、10、9、3、7、4、9、5、6 这样的简单序列,模式是 9,因为它出现得最频繁,即 3 次。一个系列中可以有多个模式,也可以没有模式。例如,10,11,13,11,10,15,17,12 有两种模式,即 10 和 11,而像 2,6,3,2,6,3 这样的序列没有模式,因为所有元素都具有完全相同的频率。模式可以通过观察数据序列来计算。在如图 6 所示的连续分布的情况下,有一个数学公式可以使用。

图 6:员工时薪数据

50-60 美元级别的频率最高,因此是模态级别。在具有范围的连续分布的情况下,计算模式值的数学公式如下:

代入上述示例中的值,此数据的模式为 56。

集中趋势的不同度量的比较

我们已经在文章的前面看到了集中趋势的理想性质。让我们比较基于属性的集中趋势的不同度量,并看看它们的一些最常见的用法:

图 7:集中趋势的不同度量的比较

一些 Python 代码来观察中央趋势

本节并不打算介绍或教授 Python 编程语言,但下面嵌入的代码将帮助对 Python 有基本熟悉的用户从各种数据序列中计算集中趋势。

本文介绍了计算集中趋势的基本原则,还介绍了新时代的计算资源,如 Python,它可以使计算海量数据的任务变得更加容易!集中趋势是所有进一步高级统计工作的基础概念,在处理高级数据分布之前需要很好地理解。

下一个需要理解的最重要的概念是离差的度量,我将在我的下一篇文章中解释这个概念。

阅读我下一篇用数学公式和 Python 编码描述离散度的文章 这里

人工智能统计学(第一部分)

原文:https://towardsdatascience.com/statistics-for-ai-part-1-4f4a0bef04e?source=collection_archive---------35-----------------------

构成复杂算法基础的向量和矩阵概念

介绍

在许多机器学习算法中,输入和输出都是向量(数字的集合)。我们处理的输入——图像、声音、颜色等,必须转换成数字,以便计算机能够理解和处理。在 ML 中,向量是一个数字数组。向量的一个例子是 X=[x1,x2,x3,…..,xn】。类似地,张量可以定义为维数大于 2 的数字数组。彩色图像是张量的一个例子,因为它具有 3 维,即长度、宽度和通道。标量被认为是 0 阶张量,而矢量被认为是 1 阶张量。这里要注意一点,通常一个 60×60 像素的图像(以 60 为例),或者一个 60×60 的矩阵被展开成大小为 3600 的单列矩阵。矩阵被认为是二阶张量。视频数据可以被视为 4 阶张量-Nx×Ny×3 是 3 维,时间是第 4 维。

标量、向量和张量的可视化解释。图片由 Mukesh Mithrakumar 提供

视频数据可以被视为 4 阶张量-Nx×Ny×3 是 3 维,时间是第 4 维。在任何给定时刻,如果我们希望知道特定像素的值,必须指定 4 个参数:像素 x 位置、像素 y 位置、它所属的通道以及时刻。在缺少任何一个参数的情况下,不能确定像素的精确值。

一个像素在时间上的变化,由玛格丽特·西莫埃斯拍摄

一些基本的矩阵运算

一些基本的矩阵运算,作者图片

矩阵相加是通过将一个矩阵 A 的位置(I,j)值与另一个矩阵 B 相加得到结果矩阵 c 来实现的。现在,有时一个矩阵的维数可能与另一个不匹配,就像上图中的示例,其中矩阵 A 的维数是 2X3,而 B 的维数是 1X3。现在,如果我们使用 NumPy 库或 MATLAB,广播就完成了,这意味着创建了矩阵 B 的重复行,然后进行加法。像加法一样,矩阵乘法发生在矩阵的所有元素上,如上图所示:在 kσA(I,k)B(k,j)的值上。

一些基本的矩阵运算,作者图片

Hadamard 乘积是运算中两个矩阵之间的逐元素乘积。为了实现这一点,矩阵应该具有彼此相同的大小。运算中矩阵的点积总是产生一个标量积。为了产生两个向量的点积,一个向量(a.T)的转置应该与另一个向量(b)相乘。转置是一种行和列互换的操作,即 A(i,j)=B(j,I)。只有当 A × A-1 = A-1 × A = I 时,A 的逆才是 A-1

向量的范数

向量的规范,作者的图像

我们使用范数的原因是,它告诉我们一个向量或张量有多大。范数基本上将向量或张量映射为标量值。在上图中,坐标为(3,4)的向量 v 的大小为 5。我们可以说向量 v 的范数是 5。

两个图像的接近程度,作者的图像

如前所述,一个 60X60 的图像被展开成一个列向量,比如 V1。向量 V1 保存图像中 3600 个位置的像素值。类似地,矢量 V2 将具有第二图像的像素值。这些向量绘制在图像右侧的图表上。通过计算两个向量之间的差并取其范数,我们可以推断出这两个图像的相关程度。差异越小,图像之间的相似性越大,反之亦然。范数是度量向量、矩阵等的长度的一种方法。

如果长度为 0 的向量在数学上是 0 向量,则范数是满足以下三个性质的函数 f:

  1. f(x)=0 意味着 x=0
  2. f(x+y)≤ f(x)+f(y)
  3. f( α x)=l α lx

第二个等式也被称为三角形不等式,它表示两条边的长度大于第三条边的长度。

这里,两个向量 x 和 y 有一个合成向量 x+y,它总是满足三角不等式规则。对输入向量的任何标量乘法(α)将导致标量与向量的范数的直接相乘。在下图中,提到了欧几里德范数、1-范数、p-范数和无穷范数的公式。

规范类型,按作者分类的图像

线性组合

向量集{V1,V2,V3,…,Vn}的线性组合是通过将每个向量乘以相应的标量系数并将结果相加给出的,即α1 v1+α2 v2+α3V3+…..+ αnVn

在下图中,矢量 V3 可以看作是矢量 V1 和 V2 的线性组合。V3 可以表示为两个向量 V1+2V2 的和。此外,矩阵乘法可以用列的线性组合来解释。

一个线性组合的例子,作者图片

跨度

一组向量的跨度是通过原始向量的线性组合得到的所有向量的集合。

向量的跨度示例,图片由作者提供

如上图所示,坐标(1,0)和(0,1)的范围是整个 2D 空间。任何向量都可以写成 V1 和 V2 的线性组合。类似地,坐标(0,0,1)、(0,1,0)和(1,0,0)的跨度是整个 3D 空间,因为任何向量都可以由上述三个向量的线性组合来表示。矩阵中所有列的跨度称为列间距。只有当 B 位于 a 的列空间时,方程 AX=B 才有解。

更多的话题将在后续的博客中讨论。敬请期待!!

人工智能统计学(下)

原文:https://towardsdatascience.com/statistics-for-ai-part-2-43d81986c87c?source=collection_archive---------51-----------------------

构成复杂算法基础的向量和矩阵概念

今天我打算讨论以下主题:线性独立性、特殊矩阵和矩阵分解。

线性独立性

如果这些向量中没有一个可以写成其他向量的线性组合,那么这个向量集就是线性无关的。例如,V1=(1,0)和 V2=(0,1)。在这里,V2 不能用 V1 来写。然而,V3 (3,4)是线性相关的,因为 V3 可以表示为 3V1+4V2。

数学上,s={V1,V2,…。,Vn}线性无关当且仅当线性组合α1V1+α2V2+…..+αnVn=0 意味着所有αi=0。

矩阵运算

矩阵可以将一个向量转换成另一个向量。例如,V 是 Nx1 向量,w 也是 Nx1 向量。

矩阵乘法通过保持形状,图像由作者

矩阵的迹

矩阵的迹由其对角元素的和给出。对于矩阵 A,其迹将是行和列具有相同值的所有元素的总和。

矩阵的轨迹,作者的图像

一些属性

  1. Tr(A+B) = Tr(A)+Tr(B)
  2. Tr(AB) = Tr(BA)
  3. Tr(A) = Tr(A.T) (A.T 表示矩阵 A 的转置)

矩阵的行列式

NxN 矩阵的拉普拉斯展开由以下公式给出:

矩阵的行列式,作者图片

行列式实际上表示由列向量形成的体积。对于 2x2 向量,它表示面积。

解释空间中的 2x2 向量,图片由作者提供

矩阵的可逆性

只有当 det(A)不为 0 时,矩阵 A 的逆矩阵才有可能。请注意,这自动意味着的列必须是线性独立的。考虑下面的矩阵。

矩阵 A,作者图片

请注意,V1、V2……,Vn 是向量,如果任何向量,比如说 Vn,可以写成其余向量的线性相关向量,比如 Vn=α1V1+α2V2+…..+αn-1Vn-1 然后,我们可以做一个简单的列操作,即最后一列=最后一列- (α1V1+α2V2+…..+αn-1Vn-1),这将产生充满零的列。这会使矩阵的行列式为 0。对于一个 2x2 矩阵,我们将有两个向量 V1 和 V2。如果 V1 和 V2 是线性相关的,像 V1=2V2,那么由这两个向量形成的面积将为零。一个聪明的说法是,这两个向量相互平行。

特殊矩阵和向量

  1. 对角矩阵:只有对角元素不为零,其余所有元素为零。如果 I 不等于 j,则 D(i,j) = 0。
  2. 对称矩阵:如果一个矩阵及其转置矩阵相等,则称该矩阵对称。
  3. 单位向量:具有单位长度的向量。向量的 2-范数是 1。
  4. 正交向量:如果(X.T)Y = 0,则两个向量 X 和 Y 是正交的
  5. 正交矩阵:如果一个矩阵的转置等于它的逆矩阵,那么我们可以说这个矩阵是正交的。此外,所有列都是正交的。正交矩阵可用于旋转保持体积的向量。
  6. 标准正交矩阵:如果一个矩阵的逆矩阵等于它的单位行列式转置矩阵,则称这个矩阵是标准正交的。

正交矩阵,作者图片

正交矩阵,作者图片

特征分解

特征分解对于正方形对称矩阵非常有用。让我们看看这个术语的物理意义。

每一个实矩阵都可以认为是旋转和拉伸的组合。

向量乘法,作者图片

对向量 v 进行运算,生成向量 w,由作者生成图像

这里,A 可以被认为是一个算子,它拉伸并旋转一个向量 v 以获得一个新的向量 w。矩阵的特征向量是那些只在矩阵的作用下拉伸的特殊向量。特征值是特征向量拉伸的因子。在下面的等式中,当与特征向量 a 一起操作时,向量 v 被拉伸了λ的值

向量 v 的特征值λ,图片作者

比如说,A 有 n 个线性无关的特征向量{V1,V2,…..,Vn}。将所有向量串联成一列,我们得到一个特征向量矩阵 V,其中 V=[V1,V2,…..,Vn】。如果我们将相应的特征值连接成一个对角矩阵,即λ=diag(λ1,λ2,…,λn),我们得到 A 的特征分解(因式分解)如下:

作者图像的特征分解

实对称矩阵有实特征向量和实特征值。

实对称矩阵,图像 y 作者

二次型与正定矩阵

二次型可以解释为“加权”长度。

二次型,作者图片

二次型,作者图片

正定(PD)矩阵的所有特征值都大于零。半正定(PSD)矩阵具有大于等于零的特征值。PD 矩阵具有对于所有 X,(X.T)AX 大于 0 的性质。例如,如果 A=I 或单位矩阵,则(X.T)I(X)=(X.T)(X)大于 0。PSD 矩阵具有对于所有 X,(X.T)AX 大于等于 0 的性质。类似地,负定(ND)矩阵的所有特征值都小于零。半负定(PD)矩阵的所有特征值都小于等于零。

奇异值分解

如果 A 是一个 MxN 矩阵,那么

奇异值分解,作者图片

  1. u 是一个 MxM 矩阵并且是正交的
  2. v 是一个 NxN 矩阵并且是正交的
  3. d 是一个 MxN 矩阵和对角线
  4. U 的元素是 A(A.T)的特征向量,称为左奇异向量
  5. (A.T)A 的特征向量,称为右奇异向量
  6. D 的非零元素是平方根(λ((A.T)(A))),这意味着(A.T)(A)的特征值的平方根,称为奇异值

结束

谢谢,请继续关注更多关于人工智能的博客。

数据科学统计学 Python 描述性统计初学者指南

原文:https://towardsdatascience.com/statistics-for-data-science-a-beginners-guide-to-descriptive-statistics-in-python-9e0daa30809a?source=collection_archive---------16-----------------------

使用 Excel、Python 和真实业务问题的集中趋势、分散性、标准差和相关性的工作示例

照片由 Unsplash 上的agency followeb拍摄

介绍

统计学是数据科学中非常需要的组成部分。为什么是统计学?简单来说,在开发任何模型之前,我们需要 100%确定我们正在处理的数据。总的想法是,“建议对任何机器学习算法使用干净的数据”,否则模型最终会产生与预期相反的结果。把它想象成一个画家,他开始画肖像,但是使用的调色板不够干净。这会产生一幅将要被拍卖的画还是会留在房子的一个角落里?

但是等等。统计没那么简单。在使用任何假设或方法之前,需要验证多种基本理论。我们都熟悉钟形曲线或用于展示数据正态分布的曲线。如果你熟悉统计学的基本原理,你会意识到正态分布是一个概率函数,它描述了一个变量的值是如何分布的X 轴表示数据点,Y 轴表示给定点的概率密度估计值。迷茫?稍后我会解释清楚。但总的想法是,作为一个初学者,我们不需要为统计学的每一个组成部分而烦恼,而是专注于更有用的部分。

图一。图示了钟形曲线或正态分布图。图片致谢—可在此处找到

统计类型

统计可分为描述性推断性。描述统计学讨论数据汇总、表格、图形和图表,而推断统计学是一种讨论样本总体参数的方法。所有足球迷,梅西在一个赛季打进 48 球是描述性统计。关于他赢得冠军联赛决赛的机会,这告诉了我们什么,这是推断性的统计数据。我们如何从对梅西表现的描述转向他赢得冠军联赛的概率反映了统计之旅?它更多的是回答“是什么?”vs .“还可能是什么?”。

统计学中的重要术语

  • 群体 —给定场景中所有可能数据的范围。例如,在银行有贷款账户的所有客户
  • 样本 —来自给定人群的一组观察值。例如,上个季度在银行有贷款账户并选择客户关怀服务的所有客户都是一个样本。他们与我们最初谈到的客户是相同的,但是,我们只是过滤掉了那些在上一个季度选择了客户服务的客户,因此这是一个样本
  • 参数 —与总体相关的数字汇总或数值。例如,在银行有贷款账户的所有客户的平均债务
  • 统计 —与样本相关的数字汇总或数值。例如,在一周开始时选择客户服务机构的客户的平均呼叫次数

通常不会观察到群体,原因是在处理数据时,我们无法访问问题空间的每个实体。此外,在整理过程中经常会出现数据泄漏或数据丢失。因此,每个数据都被视为总体的一个子集。

数据类型

数据类型是统计学的重要组成部分,因为它决定了可以对数据执行的描述或推理操作的类型。如下图所示,所有变量(通常指属性、数据、列)都可以分为两类:定性的和定量的。定性数据允许计数、图形、绘图、模式等操作,而定量数据允许均值、中值、模式、标准差、四分位数等操作。

图二。说明了变量类别。图片来源——由作者使用 Excel 开发。

数据和直方图

原始数据以收集数据的原始格式表示数字和事实。需要将原始数据转换成可用于决策的形式。提取的数据→转换成信息→然后用于获取关于场景的知识。描述性统计更多的是将数据转化为信息。现在开始,让我们先看看频率分布。频率分布用于将原始数据分类成信息。使用频率分布的一个常见示例是使用直方图分析不同时段的数据计数。

数据范围被分成多个仓。然后,这些箱用于计算每个组下的记录数。例如,我们可以访问 K Mart 封锁后两周的销售数据。我们希望分析不同时段的销售价值。在下面的例子中,我们可以观察到,在过去的两周中,有三个实例观察到的数字在 44 到 46 之间。利用这一点,我们可以分析,销售数字在不同的日子里是不同的,还是在锁定后是相似的?你怎么想呢?

图 3。使用直方图获得的销售数据的分布。图片来源——由作者使用 Excel 开发。

理解中心趋势

从这里开始,我们将举例来理解统计的概念。K Mart 超市记录了他们在墨尔本的商店在封锁后的销售额。现在,他们使用一个中心趋势来分析他们在九月最后一周的业务进展情况。以下是店长想要回答的三个问题。
1。平均销售量是多少?
2。上周销售额的中位数是多少?
3。大部分日子的“销量”都差不多吗?

图 4。显示了九月最后一周的销售汇总。图片来源——由作者使用 Excel 开发。注意在求和函数中,I 的范围是从 1 到 n,而不是从 0 到 n。

图 5。显示了九月最后一周商店的销售额中值。图片来源——由作者使用 Excel 开发。请注意,数据按升序排列,以计算中值。

使用图 4 和图 5,我们可以回答锁定后观察到的趋势。一般来说,观察到的平均销售量约为 85 台,而中位数和众数分别为 80 和 50。该模式为我们提供了锁定后观察到的趋势的更大画面。我们能否推断出 K Mart 锁定后的销售量通常为 50 件?

理解分散

简单地说,离差表示分布围绕中心趋势的扩散程度。范围是所有度量中最简单的。它被计算为给定数据中最小值和最大值之间的差。如果最大数据等于最小数据,则意味着所有的观察结果都是相同的。然而,当差异大于 0 时,我们可以推断数据是分散的。例如,在下图中,当我们按天查看销售量时,我们可以推断最小和最大销售额分别为 30 和 65。因此,这里的范围是 65-30,也就是 35。离差的变化提供了锁定后观察到的销售范围的图片。

注意:范围不适用于最大值或最小值变得极端的情况,即如果最小值太小或最大值太大,我们应避免使用范围。

下面这个例子中的中值是多少?

图 6。说明了九月最后一周的销售趋势。图片来源——由作者使用 Excel 开发。请注意,数据按升序排列,以计算中值。

观察数量= 14,因此中值是第 7 和第 8 个值的平均值(n/2 + ((n/2) + 1)) 次观察除以 2,因此为 45。第 7 和第 8 个值分别为 45 和 45。

一级方程式赛车。展示了从一组数据点计算 Q1 和 Q3 的过程。该配方是作者使用乳胶开发的。

让我们分别计算一下 pq 。对于 Q1p=floor(1*(14+1)/4) 为 3, q=(1*(14+1)) MOD 4 也为 3。 MOD 是除法运算的模或余数,下限取一个值的最小整数(例如,3.7 的下限是 3)。所以Q1 = X3+3/4(X4—X3)其中 X3 和 X4 是有序集合中的第三和第四个值。因此,根据下面的例子,X3 和 X4 分别是 40 和 42,因此 Q1 = 40+(3/4)(42–40)= 41.5,类似地,Q3 = 50+(3/4)(52–50)= 50.5。四分位数范围由 Q3-Q1 给出,即 50.5–41.5 = 9。

离差提供了关于数据的广泛信息,并被用作检测和处理异常值的关键概念。离差提供关于数据分布的信息,并回答关于变量趋势的关键问题。

图 7。展示了九月最后一周销售的箱线图。图片来源——由作者使用 Excel 开发。

箱线图展示了销售数字是如何分布的。注意,中位数是 45,Q1 和 Q3 值分别是 41.5 和 50.5。IQR 被表示为 Q3-Q1=9。任何超过 Q1-1.5 倍或 Q3+1.5 倍的值,即 28 和 64,都被视为异常值。由于 65(9 月 30 日观察到的销售数字)超出上限,因此被视为异常值。

标准偏差

标准差是对一组值或观察值的变化量或离差的度量。标准差计算为方差的平方根。方差是衡量数据点与平均值相比有多远的指标。低标准偏差表示值更接近平均值,而高标准偏差表示数据的极端值或偏斜度。像离差这样的标准差被用作分析数据分布的度量。

是时候拿起计算器算一算了。方差和偏斜度的公式显示在图像的右侧。标准差可用于回答许多问题,包括:

  • 我们是否观察到销售的变化?—是,观察最小和最大数值
  • 销售数字相差多少?—平均销售数字介于 38 和 54 之间,这是平均值的+- 1 标准偏差
  • 有多少天观察到了上面提到的这种趋势?— 79%的销售数字介于 38 和 54 之间,这意味着尽管我们观察到了销售的变化,但与分布相比,这种变化还不够显著

图 8。显示了九月最后两周销售的标准差。图片来源——由作者使用 Excel 开发。

相互关系

相关性是对两个变量之间关联程度的度量。它为一个变量相对于另一个变量如何变化提供了一些方向性。相关性可以在-1 到+1 之间,其中-1 表示两个变量负相关,即如果一个变量增加,另一个变量减少,反之亦然。相关性为 0 表示两个变量之间没有关系,即一个变量的增加或减少不会影响另一个变量。+1 的相关性表明,如果一个变量增加,则另一个变量显示类似的趋势。永远记住,相关性并不意味着因果关系。只说关联度。

图 9。说明了两个变量 X 和 y 之间的相关系数。图片来源-由作者使用 Excel 开发。

为什么要为这些统计数字伤透脑筋呢?

统计数据有助于我们理解以下内容:

  • 任何 KPI 的平均值(关键绩效指标,如销售额、客户数量、NPS、收入、购物篮等。)
  • 均值、中值和众数是缺失值最常用的插补方法之一
  • 这些中心趋势帮助我们验证数据的质量,并将它们与领域知识结合起来。例如,对于杂货店来说,与一年中的其他时间相比,在节日期间平均销售量会增加。当获得一个数据并观察到平均数字时,如果中心趋势与已知的显著不同,我们需要检查数据质量
  • 线性回归、逻辑回归、神经网络遵循某些假设,这些假设使用相关性、异常值检查等进行验证

使用 Python 实现

这个数据集最初来自国家糖尿病、消化和肾脏疾病研究所。数据集的目的是基于数据集中包含的某些诊断测量结果,诊断性地预测患者是否患有糖尿病。从一个较大的数据库中选择这些实例有几个限制。特别是,这里的所有患者都是至少 21 岁的皮马印第安血统的女性。数据集在这里可用。

属性(列)信息:

  1. 怀孕次数
  2. 口服葡萄糖耐量试验中 2 小时的血浆葡萄糖浓度
  3. 舒张压(毫米汞柱)——血压
  4. 三头肌皮褶厚度(毫米)
  5. 2 小时血清胰岛素(微单位/毫升)
  6. 体重指数(体重公斤/(身高米) )
  7. 糖尿病谱系功能——根据家族史对糖尿病可能性进行评分的功能
  8. 年龄(岁)
  9. 类别变量(0 或 1) — 0 表示非糖尿病患者,1 表示糖尿病患者
import warnings
warnings.filterwarnings(‘ignore’)import pandas as pd
import numpy as npimport matplotlib.pyplot as plt   
import seaborn as sns#from sklearn import metrics#from sklearn.model_selection import train_test_split# To enable plotting graphs in Jupyter notebook
%matplotlib inline 
sns.set(color_codes=True) #adds a good background to our plots

将数据加载到熊猫中

#Load the file from local directory using pd.read_csv which is a special form of read_tablepima_df = pd.read_csv(“pima-indians-diabetes.csv”)
print(pima_df.shape)
print(pima_df.size)pima_df.head(10)

产出 1。数据的形状和大小。图片来源——由作者使用 Jupyter Notebook 开发。

计算中心趋势

#Central tendency calculations
print(‘MEAN: \n’,pima_df.mean())
print(‘\r \n’)print(‘MEDIAN: \n’,pima_df.median())
print(‘\r \n’)print(‘MODE: \n’,pima_df.mode())
print(‘\r \n’)print(‘Q1-Quartile 1: \n’,pima_df.quantile(q=(0.25,0.50,0.75)))

产出 2。数据的描述性统计。图片来源——由作者使用 Jupyter Notebook 开发。

检查色谱柱血浆是否呈正态分布

mean=pima_df[‘Plas’].mean();
median=pima_df[‘Plas’].median();
mode=pima_df[‘Plas’].mode();fig, ax = plt.subplots(figsize=(10,6)); # — — — — — — — — -Setting size of the canvassns.distplot(pima_df[‘Plas’]);plt.title(‘Distribution plot if Plas variable’);plt.axvline(mean,color=’green’,label=’Mean’); 
plt.axvline(median,color=’blue’,label=’Median’);
# plt.axvline(mode[0],color=’red’,label=’Mode1')
# plt.axvline(mode[1],color=’red’,label=’Mode2')plt.legend();

产出 3。Plas 属性分布。图片来源——由作者使用 Jupyter Notebook 开发。

相关性检查

# # Pairplot using s
corr = pima_df.corr();
print(corr)
# sns.heatmap(corr, annot = True);fig, ax = plt.subplots()
fig.set_size_inches(10, 10)plt.title(‘Heat Map of Correlation \n’)sns.heatmap(corr,annot=True,cmap=’YlGnBu’,vmin=-1,vmax=1, linewidths=.5, center=0);

产出 4。糖尿病数据中数值属性的相关图。图片来源——由作者使用 Jupyter Notebook 开发。

异常值检查

plt.figure(figsize=(15,10))
pos = 1
for i in pima_df.drop(columns = {‘class’}).columns:
 plt.subplot(3, 3, pos)
 sns.boxplot(pima_df[i])
 pos += 1

产出 5。糖尿病数据中数值属性的箱线图。图片来源——由作者使用 Jupyter Notebook 开发。

关于作者:高级分析专家和管理顾问,帮助公司通过对组织数据的商业、技术和数学的组合找到各种问题的解决方案。一个数据科学爱好者,在这里分享、学习、贡献;你可以在 LinkedIn Twitter上和我联系。

数据科学统计学——实用技巧、误解、课程和学习计划

原文:https://towardsdatascience.com/statistics-for-data-science-practical-tips-misconceptions-curriculum-and-learning-plan-66e40e443fd2?source=collection_archive---------51-----------------------

通过利用统计数据将数据转化为见解来回答重要问题

布拉德利·邓恩在 Unsplash 上拍摄的照片

在这个高度互联的世界中,数据正以前所未有的速度生成和消费。尽管我们很享受数据的超导性,但它也会招致滥用。数据专业人员需要接受使用统计方法的培训,不仅是为了解释数字,也是为了揭露这种滥用,保护我们不被误导。

没有多少数据科学家接受过正式的统计培训,也很少有好的书籍和课程提供从数据科学的角度学习这些统计方法。

通过这篇文章,我打算阐明

  • 为什么学统计学——常见误区关于学习统计学,
  • 课程 —你应该掌握的主题和概念
  • 学习统计学 —如何成为从业者而不是应试者
  • 实用技巧获得使用 Python 的实践经验

统计学和机器学习

机器学习的核心是以统计学为中心的。如果你没有很好地掌握统计基础知识,你就无法用机器学习解决现实世界的问题。

数学方程式、希腊符号和精心定义的概念使得个人很难对这门学科产生兴趣。

我们可以通过简单明了的解释、节奏适当的教程和动手实验来解决这些问题,从而用应用统计方法解决问题。

从探索性数据分析到设计假设检验实验,统计在解决所有主要行业和领域的问题中发挥着不可或缺的作用。

任何希望深入了解机器学习的人都应该学习统计方法如何形成回归算法、分类算法的基础,如何利用从数据中学习的过程,以及如何帮助从未标记的数据中提取意义。

为什么要掌握统计学

每个组织都在努力成为数据驱动型组织,这也是我们见证数据科学家和分析师需求增长的原因。现在,为了解决问题,回答问题,制定战略,我们需要理解数据,统计提供了一系列工具来产生这些见解。

从数据到知识

孤立地看,原始观察只是数据。我们使用描述性统计将这些观察转化为有意义的见解。我们可以使用推断统计来研究小样本数据,并将我们的发现推广到整个人群。

回答问题

  • 什么特性最重要?
  • 我们应该如何设计实验来开发我们的产品策略?
  • 我们应该衡量哪些绩效指标?
  • 最常见和预期的结果是什么?
  • 我们如何区分噪音和有效数据?

所有这些都是数据团队每天必须回答的常见重要问题。这些答案有助于我们做出有效的决策。统计方法不仅帮助我们建立预测模型项目,而且帮助我们解释结果。

机器学习项目每一步的统计数据

几乎每一个机器学习项目都由以下任务组成,而统计在几乎所有的任务中都扮演着核心角色。方法如下:

  • 定义问题陈述— 使用探索性数据分析(EDA)和数据挖掘。
  • 初始数据探索— 使用汇总统计和数据可视化。
  • 数据清理— 使用异常值检测、插补等方法。
  • 数据准备和设置转换管道 使用数据采样和特征选择方法、数据转换、缩放、编码等。
  • 模型选择&评估— 算法开发需要使用统计假设测试和估计统计。
  • 微调模型— 根据统计性能指标,我们调整超参数来微调或更改模型。

作为一名数据科学家,你应该学会什么来解决问题

一般技能

  • 如何为有效决策定义统计上可回答的问题?
  • 计算和解释常见的统计数据,以及如何使用标准的数据可视化技术来交流发现。
  • 了解数理统计是如何应用到领域,概念,如中心极限定理和大数定律。
  • 从位置和可变性的估计中做出推论 (ANOVA)。
  • 如何识别目标变量和自变量之间的关系?
  • 如何设计统计假设检验实验,A/B 检验等。
  • 如何计算和解释性能指标,如 p 值、alpha、type1 和 type2 误差等。

重要概念

  • 入门— 了解数据类型(矩形和非矩形)、位置估计、可变性估计、数据分布、二进制和分类数据、相关性、不同类型变量之间的关系。
  • 统计量的分布 —随机数、大数定律、中心极限定理、标准误差、
  • 数据抽样和分布— 随机抽样、抽样偏倚、选择偏倚、抽样分布、自举、置信区间、正态分布、t 分布、二项式分布、卡方分布、f 分布、泊松和指数分布。
  • 统计实验和显著性检验— A/B 检验,进行假设检验(空/备择),重采样,统计显著性,置信区间,p 值,alpha,t 检验,自由度,ANOVA,临界值,协方差和相关性,效应大小,统计功效。
  • 非参数统计方法— 等级数据、正态性检验、数据标准化、等级相关性、等级显著性检验、独立性检验

你应该如何学习统计学

大多数大学都设计了统计学课程,通过检查学生是否能解方程、定义术语、识别推导方程的图形来测试他们的填鸭式能力,而不是专注于应用这些方法。

对于有抱负的从业者,您应该遵循一个循序渐进的过程,使用可执行的 python 代码学习和实现不同问题的统计方法。

自下而上的方法可能不是学习应用统计学的正确方法,因为它太理论化了,使主题变得枯燥和压抑。

接下来…

我将遵循代码优先的方法,针对上述每个主题创建一系列教程,以便我们能够理解和可视化这些概念的意义和应用。

如果我错过了任何细节,或者如果你希望我涵盖统计学的任何其他方面,请回复这个故事,我会将它添加到课程中。

数据科学与 Harshit

通过这个渠道,我计划推出几个涵盖整个数据科学领域的系列。以下是你应该订阅频道的原因:

请随时在 TwitterLinkedIn 上与我联系。

统计:测量数据的分布

原文:https://towardsdatascience.com/statistics-gauge-the-spread-of-your-data-7aa9368a5bf3?source=collection_archive---------23-----------------------

离差的度量提供了一个数学工具箱来理解数据的分布

米歇尔·波罗在 Unsplash 上的照片

当你想要对你手头的数据做一个完整的探索时,你不仅想要确定中心点,就像我在我的上一篇文章中提到的那样,你还想要知道数据分布的极限和各种其他点。例如,假设有一个本科生班级,有人声称这个班级的平均体重是 70 公斤。这是开始时的一些信息,但他接着补充道:

  • 最小重量为 45 千克,最大重量为 92 千克→ 告诉您数据的范围或极限值
  • 25%的学生体重低于 50 公斤→ 如果您将数据按体重分成 4 个子集,则可以看到最低权重的 1/4 体重低于 50 公斤
  • 平均而言,重量偏离平均值 4 千克→ 告诉您数据的集中程度或分散程度,例如,使用 4 千克这样的值,可以说学生之间的重量差异不大;而如果该值为 10,人们会说学生的体重与平均值相差很大

上面的例子引用了一些常见的不同离差度量的例子,这些例子将在本文中描述。与我上一篇关于集中趋势的文章类似,这篇文章将描述一些常见的离差度量以及我们通常如何计算它们。

离差的度量

图 1:不同的常用离差度量

请注意两种重要的度量类型— 绝对度量相对度量。此外,像集中趋势的措施,也有某些期望的分散措施的性质。G.U. Yule 教授还定义了理想离差测量的一些特性:

  1. 应该严格定义
  2. 基于所有的观察
  3. 容易计算
  4. 容易理解
  5. 进一步的数学处理是可能的
  6. 受抽样波动的影响较小

有了这些性质,现在让我们来看看一些最常见的离差度量。

离差的绝对度量

范围

范围是所有离差度量中最简单的。本质上,它测量数据序列中最大值和最小值的差异,并提供两个极端观测值之间的分布幅度。数学上,

所以,从数学上来说,这很简单。让我们看看它是否满足理想离差度量的所有性质及其优缺点。

优点:

  • 这很容易计算
  • 这很容易理解

缺点:

  • 它没有考虑到所有的观察结果
  • 它受采样波动的影响很大。例如,如果有一个系列 10、15、17、21、25、28,则范围是 28–10 = 18。但是,如果添加新值 40,范围会立即增加到 40–10 = 30。
  • 如果数据分布有一个开放端,则无法计算范围
  • 分布的形式不是由范围捕获的。请看这两种分布,它们的形状截然不同,但范围完全相同:

图 2:数据的两个非常不同的频率分布的范围是相等的(50–0 = 50)

四分位数间距和四分位数离差

顾名思义,这两种方法是基于四分位数的差异。如果将数据序列分成 4 等份,每 1/4 的最大值点称为四分位数。让我们考虑下面的例子:

图 3:识别分布中的四分位数

上图显示了第一(基于频率的最低 25%)和第三(基于频率的最高 25%)四分位数。什么是第二个四分位数?如果凭直觉思考,数据的 50%点本质上就是中位数。四分位数间距是第三个四分位数和第一个四分位数的差值。在图 2 的表格中,Q3 在 6 和 7 之间,而 Q1 在 1 和 2 之间。通过插值,我们可以找到精确的值,但是如果我们考虑 Q1 = 1,Q3 = 6,那么四分位数范围是 Q3-Q1 = 6–1 = 5。四分位数离差(Q.D .)等于半四分位数范围或四分位数范围的一半。这种情况下,Q.D. = (Q3-Q1)/2 = 2.5。

为了获得精确的值,我们可以从分布中插入 Q1 和 Q3 的值:

现在让我们看看四分位数离差/四分位数间距的优势:

优点:

  1. 易于计算和理解
  2. 甚至可以对开放式分布进行计算
  3. 不受原产地变化的影响

缺点:

  1. 并非基于数据中的所有观察值,因为仅使用第三和第一四分位数进行计算
  2. 进一步的数学处理是不可能的

因此,四分位偏差从多方面改善了简单范围

平均绝对偏差

简单地说,平均绝对偏差计算一个观察值与其所属数据系列的平均值或任何其他指定点(如中位数)的绝对差值,然后对所有观察值进行平均(使用算术平均值)。直观地注意到,如果系列中的所有观测值在量值上相等,则该度量的值将为零。此外,这种方法不受与平均值的差值方向(大于或小于平均值)的影响,因为它考虑的是绝对差值。

如果我们必须计算图 3 中分布的平均绝对偏差,结果将是:

现在让我们来看看这项措施的一些优点和缺点:

优点:

  1. 基于所有的观察
  2. 不会随着原点的改变而改变

缺点:

  1. 不容易计算或者理解
  2. 没有考虑偏差的符号,这使得它难以用于进一步的数学处理

标准偏差

标准差是广泛使用的离差度量,与算术平均值一起,最常用于描述数据分布的形状和规模。标准偏差被定义为观察值与算术平均值的平方差之和的平均值的平方根。它也被称为“”。在数学符号中,**

标准差的一些重要性质

  1. 标准差不受原点变化的影响。因此,如果我们有一个数列 y = x-c,那么:

2.如果 y 和 x 之间的关系是 y = ax + b,并且 a 和 b 是常数,则:

**

3.如果有多个数据系列,

4.请注意,如果一个系列中的所有观察值都相等,那么标准差将为零

现在让我们来看看 S.D .的一些优点和缺点,

优点:

  1. 基于所有的观察
  2. 可以进行进一步的数学处理(参见上面的属性 3)
  3. 考虑平均偏差的符号
  4. 独立于起源的变化
  5. 受抽样变化影响最小

缺点:

  1. 稍微难以计算
  2. 受规模变化的影响

因此,标准差是满足理想离差度量的大多数性质的离差度量,因此被广泛使用。

离差的相对度量

在日常统计分析中,离差的相对度量不如绝对度量那样广泛使用,但它们最重要的用途是应用于我们需要无量纲度量的情况,并可用于比较不同计算单位的不同数据集。一些常见的相对离差度量是:

  1. 四分位数离差系数:

2.变异系数:**

3.平均偏差系数:**

结论

与集中趋势相结合的离差度量是有助于汇总数据的最重要的度量。这些度量让我们对数据分布有了初步的印象。如今大多数统计工具都有计算这些的内置函数。

Python 编码计算离差度量

注:所有图片(除了头中的 Unsplash 图片),数据和编码归作者所有。

统计学-第一部分:贝叶斯如何补充 Frequentist。

原文:https://towardsdatascience.com/statistics-how-bayesian-can-complement-frequentist-9ff171bb6396?source=collection_archive---------40-----------------------

多年来,学者们一直使用所谓的频率统计来评估实验操纵是否有效果。

Frequentist 统计基于假设检验的概念,假设检验是一种基于数学的方法,用于评估你的结果是否是偶然得到的。该值越低,的重要性就越大(用频率主义者的术语来说)。出于同样的原因,您可以使用相同的方法获得不重要的结果。这些“负面”结果中的大部分在研究中被忽视,尽管知道哪些操作没有影响有巨大的附加值。但那是另一篇文章;)

事情是这样的,在这种情况下,没有发现任何影响,频率主义者的统计数据是有限的,在他们的解释力,因为我将在这篇文章中争辩。

下面,我将探讨频繁主义者统计的一个局限性,并提出一种替代频繁主义者假设检验的方法:Bayesian统计。我不会对这两种方法进行直接比较。如果你感兴趣的话,那里有相当多的读物。我更愿意探索为什么频率主义者的方法存在一些缺点,以及这两种方法在某些情况下如何互补(而不是像有时争论的那样认为它们是相互排斥的)。

这是两个帖子中的第一个,在这里我将关注频率主义者的统计数据无法理清证据缺失和证据缺失之间的关系。

证据缺失与证据缺失

背景

在 frequentist 的世界中,统计通常输出一些统计度量(t,F,Z 值…取决于您的测试),以及全能的 p 值。我在另一篇文章的中讨论了仅使用 p 值的局限性,您可以阅读这篇文章来熟悉其计算背后的一些概念。简而言之,如果 p 值显著(即低于任意决定的阈值,称为 alpha 级别,通常设置为 0.05),则确定您的操作最有可能产生影响。

然而,如果(这种情况经常发生),你的 p 值> 0.05 呢?在频率主义者的世界里,这样的 p 值不允许你在缺乏证据和缺乏效果之间进行区分。

让大家稍微理解一下,因为这是关键的一点。换句话说,频率统计在量化影响的存在方面相当有效,但在量化影响不存在的证据方面相当差。文献见此处

下面的演示摘自荷兰神经科学研究所的一些工作,那是我从事神经科学研究的时候。最近发表了一篇关于这个主题的非常好的论文,我鼓励你去阅读。下面的代码是受纸质资源库的启发,用 R 编写的。

模拟数据

假设我们生成一个均值=0.5,标准差=1 的随机分布。

np.random.seed(42)
mean = 0.5; sd=1; sample_size=1000
exp_distibution = np.random.normal(loc=mean, scale=sd, size=sample_size)
plt.hist(exp_distibution)

图 1 |描述从以 0.5 为中心的正态分布中随机抽取的直方图

这就是我们的实验分布,我们想知道这个分布是否与 0 有显著的不同。我们可以运行一个单样本 t 检验(这是可以的,因为分布看起来非常高斯,但你应该从理论上证明参数测试假设得到满足;让我们假设它们是)

t, p = stats.ttest_1samp(a=exp_distibution, popmean=0)
print(‘t-value = ‘ + str(t))
print(‘p-value = ‘ + str(p))

相当不错的 p 值,会让每一个博士生的脊柱都幸福得发抖;)注意,在这种样本量下,几乎任何事情都变得有意义,但让我们继续演示。

现在让我们尝试一个以 0 为中心的分布,它不应该与 0 有很大的不同

mean = 0; sd=1; sample_size=1000
exp_distibution = np.random.normal(loc=mean, scale=sd, size=sample_size)
plt.hist(exp_distibutiont, p = stats.ttest_1samp(a=exp_distibution, popmean=0)
print(‘t-value = ‘ + str(t))
print(‘p-value = ‘ + str(p))

这里,我们有一个预期的分布,它与 0 没有显著的不同。这就是事情变得有点棘手的地方:在某些情况下,frequentist 统计无法真正区分 p 值> 0.05 是否是缺乏证据,以及缺乏证据,尽管这是一个关键点,可以让你完全排除实验操纵产生影响。

让我们假设一种情况:

你想知道操纵是否有效果。这可能是你沟通中的一种新颖的营销方式,对生物活动的干扰,或者是你正在发送的邮件中的“有图片无图片”测试。你当然有一个对照组来和你的实验组进行比较。

收集数据时,您可以看到不同的模式:

  • (一)两组不同。
  • ㈡这两个群体的行为相似。
  • (iii)您没有足够的观察数据来得出结论(样本量太小)

虽然选项(I)是不利于null hypothesis H0的证据(即,你有证据表明你的操纵产生了影响),但使用 frequentist 统计数据无法解开情况(ii)(= H0 的证据,即不存在的证据)和(iii)(=无证据,即不存在的证据)。但是也许贝叶斯方法可以给这个故事增加一些东西...

p 值如何受效应和样本量的影响

第一件事是说明频率统计有缺点的情况。

进场背景

我要做的是绘制频率主义者 p 值在改变效应大小(即,你的控制,这里的平均值=0,和你的实验分布之间的差异)和样本大小(观察或数据点的数量)时的表现。

让我们首先编写一个函数来计算这些 p 值:

def run_t_test(m,n,iterations):
    """
    Runs a t-test for different effect and sample sizes and stores the p-value
    """
    my_p = np.zeros(shape=[1,iterations])
    for i in range(0,iterations):
        x = np.random.normal(loc=m, scale=1, size=n)
        # Traditional one tailed t test
        t, p = stats.ttest_1samp(a=x, popmean=0)
        my_p[0,i] = p
    return my_p

然后,我们可以用不同的样本和效果大小来定义我们想要测试的空间的参数:

# Defines parameters to be tested
sample_sizes = [5,8,10,15,20,40,80,100,200]
effect_sizes = [0, 0.5, 1, 2]
nSimulations = 1000

我们终于可以运行函数并想象:

# Run the function to store all p-values in the array "my_pvalues"
my_pvalues = np.zeros((len(effect_sizes), len(sample_sizes),nSimulations))for mi in range(0,len(effect_sizes)):
    for i in range(0, len(sample_sizes)):
        my_pvalues[mi,i,] = run_t_test(m=effect_sizes[mi], 
                                n=sample_sizes[i], 
                                iterations=nSimulations
                               )

我将快速可视化数据,以确保 p 值似乎是正确的。输出将是:

p-values for sample size = 5
Effect sizes:
          0       0.5       1.0         2
0  0.243322  0.062245  0.343170  0.344045
1  0.155613  0.482785  0.875222  0.152519

p-values for sample size = 15
Effect sizes:
          0       0.5       1.0             2
0  0.004052  0.010241  0.000067  1.003960e-08
1  0.001690  0.000086  0.000064  2.712946e-07

我想在此提出两点主要看法:

  1. 当样本量足够大时(下半部分),p 值的行为与预期一致,并随着效应量的增加而降低(因为您有更强的统计能力来检测效应)。
  2. 然而,我们也看到 p 值对于小样本量并不显著,即使效应量相当大(上图)。这是非常惊人的,因为效果大小是相同的,只有数据点的数量不同。

让我们想象一下。

形象化

对于每个样本大小(5、8、10、15、20、40、80、100、200),我们将计算落入显著性水平仓中的 p 值的数量。

我们先来比较两个均值相等的分布,也就是我们有一个效应大小= 0。

图 2 |效应大小= 0 的每个“显著性”箱中 p 值的数量

从上图中我们可以看出,t 检验计算出的大多数 p 值对于均值为 0 的实验分布并不显著。这是有道理的,因为这两种分布在它们的意义上没有什么不同。

然而,我们可以看到,在某些情况下,我们确实获得了显著的 p 值,这可能发生在使用从总体中抽取的非常特殊的数据点时。这些通常是假阳性,这也是为什么重复实验和复制结果很重要的原因;)

让我们看看,如果我们使用一个平均值与对照组相差 0.5 的分布,会发生什么情况:

图 3 |效应大小的每个“显著性”箱的 p 值数量= 0.5

现在,我们清楚地看到,增加样本量显著提高了检测效果的能力,对于低样本量,仍然有许多不显著的 p 值。

如下图所示,正如预期的那样,您会看到对于高度不同的分布(效应大小= 2),显著 p 值的数量会增加:

图 3 |效应大小的每个“显著性”箱的 p 值数量= 2

好了,这就是样本和效应大小如何影响 p 值的例证。

现在的问题是,当你有一个不显著的 p 值时,你并不总是确定你是否错过了这个效应(比如说因为你的样本量很小,由于有限的观察或预算)或者你的数据是否真的表明没有这个效应。事实上,大多数科学研究都有一个统计能力的问题,因为他们的观测数据有限(由于实验限制、预算、时间、出版时间压力等……)。

由于研究中的数据实际上是一个相当低的样本量,你可能仍然想从基于低样本量的非显著结果中得出有意义的结论。

在这里,贝叶斯统计可以帮助你对你的数据更进一步;)

请继续关注下面这篇文章,在这篇文章中,我探索了泰坦尼克号和波士顿的数据集,以展示贝叶斯统计在这种情况下是如何有用的!

你可以在下面的回购中找到这个笔记本:https://github.com/juls-dotcom/bayes

数据科学统计学

原文:https://towardsdatascience.com/statistics-in-data-science-8ee52459e282?source=collection_archive---------44-----------------------

决策的艺术

分析、预测和分类

威廉·艾文在 Unsplash 上的照片

数学可能是最重要的主题之一,是几乎所有技术进步的核心。没有数学,数据科学领域就不会存在。从自然语言处理到高级人工智能,数据科学的所有子领域都建立在三个定义明确的数学领域之上。在每个数据科学领域的核心,你会发现概率论、线性代数和统计学的应用。我写过关于概率论和线性代数在数据科学中的应用的文章。

[## 数据科学中的概率论

数据科学中最常用的 4 种概率分布

towardsdatascience.com](/probability-theory-in-data-science-bacb073edf1f)

然而,在本文中,我们将讨论数据科学中的最后一个数学元素,统计学。统计学作为一门学科主要是在过去的一个世纪里发展起来的。相比之下,概率论——统计学的数学基础——是在 17 世纪到 19 世纪基于托马斯·贝叶斯、皮埃尔·西蒙·拉普拉斯和卡尔·高斯的工作而建立的。与概率论的纯理论性质不同,统计学是一门涉及数据分析和建模的应用科学。

[## 5 线性代数在数据科学中的应用

ML、CV 和 NLP 中的线性代数

towardsdatascience.com](/5-applications-of-linear-algebra-in-data-science-81dfc5eb9d4)

统计学涉及数据科学的所有步骤,从清理、探索和分析数据的第一步,到提出回归模型来匹配数据,再到最终使用这些知识根据这些数据进行预测。统计学是原则和参数的集合,可帮助数据科学家获得有关其数据的信息,以便在面临不确定性时做出决策。使用统计学有助于我们揭示数据中的秘密,并使用这些秘密来创建更好、更准确的预测模型。

在本文中,我们将讨论在数据科学中使用统计学的四种方法。我们将讨论数据的分析和分类、显著性检验、回归和预测,最后,我们将讨论数据的分类。

让我们开门见山吧…

分析和分类数据

当我们开始一个新的数据科学项目时,我们从不同的来源获得数据。该数据可以来自先前与用户的交互;从关于天气的传感器,它可能是一个图像或视频流,或者它可能仅仅是通过消息或语音通道发送的一些文本。原始数据的问题在于,它是非结构化的,难以分析。计算机擅长发现模式和处理结构化数据;这就是为什么我们需要将原始数据转换为结构化数据,以便对其执行不同的处理。

作者图片(使用 Canva 制作)

结构化数据有两种基本类型:数字型分类型数字数据有两种形式:连续,如温度或持续时间或湿度;以及离散,如事件发生的计数。另一方面,我们有分类数据,它只接受一组固定的值,比如一周中的几天、特定内容中的国家名称等。分类数据也有两种类型,二进制数据,它只能取两个值中的一个,即 0/1、是/否或真/假。另一种类型的分类数据是序数数据,其中分类是有序的;这方面的一个例子是数字评级(1、2、3、4 或 5)。

探索性数据分析

探索性数据分析(EDA)是数据科学中使用的一种技术,用于为建模准备数据。它基本上是关于清理和了解你的数据;这样做,你要么从它那里得到你需要的答案,要么为将来的建模发展出解释结果的直觉。执行 EDA 以获得关于数据的不同种类的信息。

  1. 数据采样。
  2. 填充缺失值。
  3. 在数据中寻找模式。

EDA 可以使用 Pandas 库在 Python 中完成;我们可以使用 Matplotlib 和 Bokeh 来可视化数据。

例如,这里我使用了来自 R 数据集的集合的数据集Titanic

显著性检定

作者图片(使用 Canva 制作)

显著性检验(也称为假设检验)广泛用于传统的统计分析中,旨在帮助我们了解一个事件的结果是否是随机的。为了进行测试,我们收集两个变量 A 和 B 的数据,因此 A 和 B 之间的任何观察到的差异必定是由于以下原因之一:

  1. B 的变化是随机的,与 a 无关。
  2. A 和 B 之间存在真正的依赖关系

对随机实验进行统计假设检验,以评估随机机会是否是观察到的两个变量之间差异的合理解释。统计假设是一种保护研究人员不被随机机会愚弄的方法。有两种假设:

  • 零假设: 两个分类变量是独立的(它们的值之间没有关系,任何相关性都是由于偶然)。
  • 备选假设: 这两个分类变量是相依的。

有许多不同类型的显著性检验;但是,在本文中,我将重点介绍三种最常用的方法:卡方检验、学生 t 检验和方差分析检验(ANOVA)。

卡方检验

卡方检验通过计算代表两个数据独立的概率的值“p”来检查两个分类变量是否相关或独立。该测试仅适用于分类数据(分类中的数据),如性别{男性、女性}或颜色{红色、黄色、绿色、蓝色},不适用于数值数据,如身高或体重。

“学生”t 检验

t 检验告诉你变量之间的差异有多显著;换句话说,它让你知道这些差异是否是偶然的结果。为了使 t 检验准确,每个样本中的观察值应该是正态分布的,并且它们应该具有相同的方差。

方差分析检验(ANOVA)

ANOVA 测试是一种发现事件或实验结果是否重要的方法。换句话说,它们帮助我们弄清楚我们是否可以拒绝零假设或接受替代假设。我们正在测试样本,看它们之间是否有差异。ANOVA 测试有两种类型单向双向:

  • 单向有一个独立变量。比如大米的种类。
  • 双向有两个自变量。比如大米的种类和热量。

回归和预测

作者图片(使用 Canva 制作)

在数据科学中使用统计学的主要原因是为了能够得出一个问题的答案:变量 X 与 Y 相关吗?如果是的话,它们之间的关系是什么,我们可以用这个关系来预测 Y 的未来值吗?

我们可以用回归来模拟两个变量相互作用的方式。回归描述了两个变量之间的关系,例如,X 是否随着 Y 的增加而增加?还是 Y 随着 X 的增大而减小?有几种类型的回归,线性回归,逻辑回归,多项式回归,逐步回归,岭回归,套索回归和弹性回归。然而,在大多数数据科学项目中,我们使用线性和逻辑回归。

线性回归

在线性回归中,因变量是连续的,其中自变量可以是连续的或离散的。线性回归使用不同点之间的最佳拟合直线在因变量(Y)和一个或多个自变量(X)之间建立关系。这条拟合线通常被称为“回归线”

逻辑回归

逻辑回归用于找出一个事件成功或失败的概率。当要预测的变量是二元的(0/ 1,真/假,是/否)时,经常使用逻辑回归。逻辑回归通常用于分类问题,通常需要大量样本才能准确发挥作用。

分类

作者提供的图片(使用 Canva 制作)

数据科学家经常面临需要自动决策的问题。例如,一封电子邮件是合法的还是垃圾邮件,一个广告是否可能被点击。这类问题称为分类问题。分类也许是预测的最重要的形式;有时,我们需要将数据分成二进制类别,或者更有序的类别。逻辑回归可用于分类问题,用于分类的其他算法:朴素贝叶斯、随机梯度下降、决策树、随机森林和支持向量机。作为分类算法的一个例子,让我们讨论一下朴素贝叶斯和 K-最近邻算法。

朴素贝叶斯

朴素贝叶斯分类器是一组基于贝叶斯定理的分类算法。这是一个算法家族,所有算法都有一个共同的原则。贝叶斯算法的基本假设是变量是独立的,并且对因变量有相同的影响。这种算法只需要少量的训练数据,与更复杂的方法相比速度非常快。然而,已知朴素贝叶斯估计并不那么准确。

k-最近邻

k-最近邻算法并不试图构建一般的内部模型,而是仅存储训练数据的值,然后在分类过程中使用这些值。根据每个点的 k 个最近邻的简单多数投票来计算分类。该算法是实现最简单的算法之一,对于有噪声的训练数据是鲁棒的,并且如果训练数据是重要的,则该算法是有用的。

数据科学完全是关于数学,关于计算概率,求解一些方程以找到变量之间的关系,以及使用统计学来估计、分类和预测未来数据。好的一面是,你不需要手工做任何数学运算,像 Pandas、Scikit 和 Matplotlib 这样的库在隐藏数据科学背后的复杂数学方面做得很好。这就是为什么这里最重要的方面是理解事物如何工作的逻辑,然后从那里开始。

参考

1迪格尔,P. J. (2015)。统计学:21 世纪的数据科学。皇家统计学会杂志:A 辑(社会统计), 178 (4),793–813。

[2]布鲁斯,p .,布鲁斯,a .,&格德克,P. (2020)。数据科学家实用统计:使用 R 和 Python 的 50 多个基本概念。奥莱利媒体。

ML 中的统计学:为什么样本方差除以 n 仍然是一个好的估计量

原文:https://towardsdatascience.com/statistics-in-ml-estimating-population-variance-1f484184f247?source=collection_archive---------22-----------------------

理解为什么我们在样本方差中使用(n1 ),以及为什么使用 n 仍能给出一个很好的总体方差估计量。

来源:皮沙贝彼得 H

本文讨论我们如何估计正态分布的总体方差,通常表示为【σ。通常,我们使用样本方差:

但是,我们为什么要用 (n - 1) 而不是 n 来除平方和,其中 n 代表样本大小,从而得到样本方差,这一点并不直观。在统计学中,这通常被称为 贝塞尔修正 。另一个可行的估计量是用平方和除以样本量得到的,它是总体方差的最大似然估计量 (MLE):

哪个比较好?

通过应用 偏差-方差分解柯克兰定理 ,本文试图解决这些问题。它的结论是:

  • 我们在样本方差中使用(n1),因为我们想要获得总体方差的无偏估计量。
  • 将平方和除以 n 仍然给了我们一个很好的估计值,因为它具有更低的均方误差 (MSE)。

我们还将回顾一个用 Python 实现的实验,从数值上验证我们的结论。敬请期待!

假设我们有一个样本 x₁x₂ 、…、 xi、其中所有 xi 都是独立同分布 ( iid )根据 N(μ,σ ) 。我们正在考虑总体方差 σ 的两种估计量:样本方差估计量和 MLE 估计量。

评估估计量:偏差、方差和均方误差

我们将首先引入一些度量来评估这些估计量,即偏差方差和 MSE。假设我们正在估计总体参数 θ 并且我们的估计量是数据的函数,那么我们可以定义:

直观地说,偏差衡量我们的估计偏离潜在参数的程度。因为我们的估计值会随着数据而变化,所以方差衡量的是它们偏离不同数据集平均值的期望值。MSE 是一个综合的度量,可以分解为(偏差+方差)如下。

在下面几节中,我们将应用柯克兰定理来推导我们两个估计量的偏差和方差,并进行比较。

采样离散

科克伦定理通常用于证明 方差分析 (ANOVA)中使用的统计数据的概率分布。我们将跳过证明,简单地将其应用于我们的情况。

科克伦定理表明,从标准正态生成的一组 iid 随机变量的平方和具有 卡方分布(n - 1) 自由度。换句话说:

因此,

由此可见,样本方差是总体方差的理想无偏估计量。然后我们可以写出它的方差和 MSE:

极大似然估计量

以同样的方式,我们可以导出总体方差的 MLE 估计的偏差、方差和均方误差。

由此我们知道了为什么我们一般会用平方和除以 (n - 1) 来计算样本方差。MLE 估计量是总体方差的有偏估计量,它引入了向下的偏差(低估了参数)。偏差的大小与总体方差成正比,并且随着样本量的增加而减小。

我们发现极大似然估计具有较小的方差。差距的大小与人口方差成正比。此外,

我们可以看到,随着样本容量的增大,MLE 估计量对样本方差的优势减小。写出 MSE 并比较:

我们发现极大似然估计量也有一个较小的均方误差。正如预期的那样,缺口的大小与总体方差成正比,并且随着样本量的增加而减小。

数值实验

在本节中,我们将验证上面得出的结论。我们将从 N(0,σ ) 中生成 100,000 个大小为 n 的样本。 X 形状为 n × 100000 ,每个列向量代表一个形状为 n × 1 的样本。

我们将从 n = 10 和 σ = 1 开始。请注意参数ddof的使用,因为它指定了从估计量的样本量中减去什么。

正如所料,最大似然估计引入了向下偏差,而样本方差估计的向下偏差可以忽略不计。同时,极大似然估计具有较低的方差和均方误差。

我们将改变样本大小和总体方差的配置,看看样本方差估计量和最大似然估计量之间的偏差、方差和均方误差会发生什么变化:

正如所料,样本方差估计量和最大似然估计量之间的偏差、方差和均方误差随着总体方差的增加而增加,随着样本量的增加而急剧减少。检查我用来生成可视化效果的代码:

这篇文章是何坤宇写的。Kunyu 目前是芝加哥大学计算分析专业的硕士生。他发现理解统计建模和机器学习技术、将它们应用于真实世界的数据并帮助创建金融服务行业的端到端解决方案是一件有趣的事情。在 LinkedIn 上联系昆玉!🐷

[## 昆玉何-即将上任的全球量化策略非周期分析师-美银美林…

芝加哥大学正在接受理学硕士计算分析项目培训的数据科学家。对…充满热情

www.linkedin.com](https://www.linkedin.com/in/kunyuhe/)

统计数据是最好的开端

原文:https://towardsdatascience.com/statistics-measures-are-the-best-starter-86241bb39576?source=collection_archive---------43-----------------------

发起一个成功的数据科学项目

卢卡斯·布拉塞克在 Unsplash 上的照片

统计学是通过使用实验数据发展人类知识的科学和实践。它基于统计学理论,统计学理论是应用数学的一个分支。在统计理论中,随机事件和不确定性由概率论建模。如果你想有一个有意义和有效的数据科学项目,你必须对原始数据和领域知识有很好的理解。借助初步的统计工具和可视化图表,您可以对数据及其行为有更深入、更直观的理解。

统计包含许多基本概念,包括描述性统计和推断性统计,描述性统计使用平均值或标准差等指标对样本数据进行汇总,推断性统计从随机变化的数据中得出结论。描述性统计可以用来总结人口数据。数字描述符包括连续数据类型(如收入)的均值和标准差,而频率和百分比在描述分类数据(如教育)方面更有用。为了对整个人口得出有意义的结论,需要推理统计。它使用样本数据中的模式来推断所代表的人口,说明随机性。计算统计学,或统计计算,是统计学和计算机科学之间的接口。它是计算科学(或科学计算)的领域,具体到统计的数学科学。

统计实践包括计划、总结和解释不确定的观察结果。因为统计学的目的是从现有数据中产生最佳信息,一些作者认为统计学是决策理论的一个分支。问题解决和改进方法,如六西格玛,在测量和分析步骤中使用统计过程方法,通过实验和样本找出过程。在随机化实验中,实验方案中规定的随机化方法指导统计分析,这通常也由实验方案规定。例如,测量系统分析(MSA)是一种实验和数学方法,用于确定测量过程中的变化对整个过程可变性的影响程度。

在本文中,我想介绍最适用和最方便的统计概念,它们将有助于启动一个成功的数据科学项目。

均值或平均值

Mean 或 average 是数字集合的总和除以集合中的数字个数。该集合通常是一组实验或观察研究的结果,或者经常是一组调查的结果。在数学和统计学的某些上下文中,术语“算术平均值”是首选的,因为它有助于将其与其他平均值(如几何平均值和调和平均值)区分开来。

差异

方差是随机变量与其均值的方差的期望值。通俗地说,它衡量一组数字偏离平均值的程度。方差在统计学中有着重要的作用,使用方差的一些概念包括描述性统计、统计推断、假设检验、拟合优度和蒙特卡罗抽样。

标准偏差

标准差是一组值的变化量或离差的度量。低标准偏差表示这些值倾向于接近集合的平均值(也称为期望值),而高标准偏差表示这些值分布在更大的范围内。

错误

从零假设出发,可以识别两种基本形式的错误:第一类错误,其中零假设被错误地拒绝,给出“假阳性”。第二类错误,即零假设未能被拒绝,群体间的实际差异被遗漏,从而给出“假阴性”。

方差分析

ANOVA 是统计假设检验的一种形式,大量用于实验数据的分析。假设零假设为真,如果一个测试结果被认为不太可能是偶然发生的,那么这个测试结果(从零假设和样本计算出来的)被称为具有统计显著性。当概率(p 值)小于预先指定的阈值(显著性水平)时,统计上显著的结果证明拒绝零假设是正确的,但仅当零假设的先验概率不高时。

卡方检验

卡方检验,也称为χ2 检验,是一种统计假设检验,当检验统计量在零假设下为卡方分布时有效,特别是皮尔逊卡方检验及其变体。皮尔逊卡方检验用于确定在列联表的一个或多个类别中,预期频率和观察频率之间是否存在统计上的显著差异。

相关性和依赖性

相关性或依赖性是两个随机变量或二元数据之间的任何统计关系,无论是否是因果关系。在最广泛的意义上,相关性是任何统计上的关联,尽管它通常指的是一对变量线性相关的程度。依赖性现象的常见例子包括父母及其子女的身体状况之间的相关性,以及商品价格和消费者愿意购买的数量之间的相关性,如所谓的需求曲线所示。

皮尔逊相关系数

皮尔逊相关系数是两个变量的协方差除以它们的标准差的乘积。定义的形式涉及一个“乘积矩”,即均值调整随机变量乘积的均值(关于原点的一阶矩);因此名字中有一个修饰语积矩。

回归分析

回归分析是一组统计过程,用于估计因变量和一个或多个自变量之间的关系。回归分析最常见的形式是线性回归,其中研究人员根据特定的数学标准找到最符合数据的直线。

斯皮尔曼等级相关系数

两个变量之间的 Spearman 相关性等于这两个变量的等级值之间的 Pearson 相关性;皮尔逊相关性评估线性关系,而斯皮尔曼相关性评估单调关系(无论是否线性)。如果没有重复的数据值,当每个变量都是另一个变量的完美单调函数时,就会出现+1 或-1 的完美 Spearman 相关性。

“学生”t 检验

如果测试统计量中的比例项的值已知,则当测试统计量遵循正态分布时,最常应用 t-测试。当比例项未知并被基于数据的估计所取代时,测试统计遵循学生的 t 分布。例如,t 检验可用于确定两组数据的平均值是否存在显著差异。

概率论

概率论是从计算的角度对可能事件的研究。换句话说,概率论是处理随机事件分析的数学分支。随机测试是这样一种实验,在进行测试之前,所有可能的结果都是已知的,但是在进行测试之前,不清楚会出现哪种结果,并且可以在相同的条件下以期望的频率进行测试。概率论的核心由随机变量、随机过程和事件组成。概率论除了解释随机现象,还考察不一定随机的现象,但通过多次重复测试,结果遵循特定的模式。考察这些模式的结果就是大数定律和中心极限定理。

时间序列分析

时间序列分析包括用于分析时间序列数据的方法,以便提取有意义的统计数据和数据的其他特征。时间序列预测是使用模型根据以前观察到的值来预测未来值。虽然回归分析常用于检验一个或多个独立时间序列的当前值会影响另一个时间序列的当前值的理论,但这种时间序列分析不称为“时间序列分析”,它侧重于比较单个时间序列或多个相关时间序列在不同时间点的值。间断时间序列分析是对单一时间序列的干预分析。

在以后的文章中,我将帮助您了解更多关于其他重要概念的知识,以此作为成为一名专业数据科学家的基础知识。

参考

扬-威廉·罗米恩(2014 年)。《统计哲学》。斯坦福哲学百科全书。

佩科兹,埃罗尔(2009)。经理统计指南。埃罗尔·佩科兹。ISBN 9780979570438。

nikoletseaes,M.M. (2014 年)“统计学:概念和实例。”ISBN 978–1500815684

弗里德曼,D.A. (2005)统计模型:理论与实践,剑桥大学出版社。ISBN 978–0–521–67105–7

西亚达提,萨曼。(2010).高级统计学简评。10.13140/2.2 . 3510.84804/1。

统计学第二部分:贝叶斯拯救

原文:https://towardsdatascience.com/statistics-part-ii-bayesian-to-the-rescue-877cc18c8bfd?source=collection_archive---------51-----------------------

在这篇文章中,我将比较 frequentist 和贝叶斯统计的结果,并解释这两种方法如何互补,特别是对于 frequentist 方法产生的不清楚的结果。

作为概念的第一个证明,我将使用著名的 Titanic 数据集,每个第一个 Kaggle 用户在注册时都会接触到这个数据集。这些统计数据当然可以应用于任何其他数据集。我选择了 Titanic 数据集,因为它的变量范围很大,读者可能已经知道这些数据了。

对于那些不熟悉这个数据集的人来说,它提供了一系列变量,可以用来预测当时沉船事故中幸存的可能性。你会在网上找到各种方法来分析这个数据集,以及机器学习技术来预测存活率。

我从网上下载了它,你可以在这里找到我使用的确切数据集。

仅供参考,变量如下所示:

[print(i) for i in df.columns]PassengerId
Survived
Pclass
Name
Sex
Age
SibSp
Parch
Ticket
Fare
Cabin
Embarked

缺乏证据

如果你自己做分析,你会发现一些变量在预测存活率方面相当不错。出于论证的目的,也因为我认为它提供了一个很好的解释力,让我们看看可变年龄:

df.Age.plot(kind='hist')

图 1 | Titanic 数据集中年龄列的直方图。

因为我们想研究年龄对存活率的影响,所以我们相应地把它分开:

(df.groupby('Survived')
.apply(lambda d: pd.Series({
    "std": d.Age.std(),
    "sem": d.Age.std() /  d.Age.count(),
    "avg": d.Age.mean()
}))
.plot(kind='barh', 
       y = "avg", 
       legend = False, 
       title = "Mean Age per Surival Class +/- std", 
       xerr = "std"
      ));

图 2 |每个存活类别的平均年龄。误差条显示分布的标准偏差。

从一个简单的柱状图来看,在事故中幸存和未幸存的乘客的年龄似乎没有太大的差别。观察误差线,我们可能会认为这些分布没有显著的不同。

让我们用统计学来检验一下。

为了演示贝叶斯统计,我将使用开源软件 JASP ,它提供了一个用户友好的界面。有许多其他的软件包可以让你从代码中运行贝叶斯统计。由于读者可能不精通代码,我使用这个软件来展示如何运行基本的贝叶斯测试。

让我们首先加载 JASP 的泰坦尼克号数据集:

图 3 |泰坦尼克号数据集在 JASP 装载时的截图

上面你可以看到 JASP 自动以一种很好的可读方式重新组织列中的数据。

JASP 允许你用频率主义和贝叶斯方法进行基本的统计测试。虽然我通常使用 SciPy 运行我的统计数据,但是将这两种方法都嵌入到一个软件中还是不错的,这样您就可以很容易地比较输出。

让我们首先从经典的频率主义方法开始。

下面,你会看到一个 JASP 窗口的截图,当你想做一个独立的样本测试时,它会弹出来,如果我们想测试幸存的乘客是否与死于悲剧的人有明显不同的年龄,这就是我们应该做的。

图 4 | Frequentist 独立样本 t 检验。

如您所见,有许多选项可以更改,例如测试的类型(如果您想进行非参数测试,则为 Student、Welch、Mann-Whitney),您是否有测试的假设(单边或双边测试)。此外,如果想要使用 JASP 浏览数据集,还可以获取更多描述性统计数据。

我将运行一个标准的学生测试,即参数测试。在此之前,我们应该检查分布是否满足参数测试的假设,但是为了演示的目的,让我们假设它们是满足的。

非常令人惊讶的是,测试显示了两种分布之间的显著差异(t(712) = 2.067,P = 0.039),即,在零假设下,观察到的年龄差异是不可能的。p 值确实与典型的 0.05 阿尔法水平调情,表明根据 frequentist 统计,这种影响是显著的,但如果我可以补充的话,不是很有说服力。

在继续之前,我们应该看看 p 值之外的其他指标(效应大小,见这里,但因为这篇文章是关于比较频率主义者和贝叶斯方法,我就继续。

现在让我们看看贝叶斯独立样本 t 检验会显示什么。

图 5 | Frequentist 独立样本 t 检验。

贝叶斯检验输出所谓的贝叶斯因子(BF ),它是零假设 H0 对替代假设 H1 的相对预测性能。查看此处了解更多关于贝叶斯因子的信息。

虽然我不喜欢任意阈值的概念,但是这些想法对于得出关于数据的有意义的结论是有用的。

在频率主义者的世界里,典型的任意阈值是 0.05,低于这个阈值,效果据说是显著的。

在贝叶斯世界中,根据 Jeffreys 的初始分类,可以使用以下命名法:

  • BF < 1/3: evidence 反对零假设
  • 1/3 < BF < 3 : Anecdotical evidence
  • BF > 3:证据零假设

在我们的例子中,我们选择 BF10,它表示 1 假设下的数据的似然性与零假设下的数据的似然性的比较(数学术语:p(数据| H1) / p(数据| H0))。

回到我们的测试。我们在主窗口中发现了一些有趣的选项,允许您进行单面或双面测试(“Alt。假设”,在 JASP 用“+”表示),以及 BF 操作,允许您计算每次比较比率,BF10(高 1 对高 0)和 BF01(反向比较)。

我建议你也探索一下 nice plots 选项,它将允许你可视化你的先验和后验分布(这是一个单独的帖子……)。

让我们进行测试:

在我们的例子中,我们得到 BF = 0.685,这意味着我们的数据在 H1 统治下比在 H0 统治下多 0.685 倍。根据杰弗里斯的初步分类,这说明 H0 缺乏证据,也就是说,我们不能得出结论,年龄不影响泰坦尼克号事故中的生存可能性。我在这里坚持:由于 BF 不低于 1/3 ,我们不能说他们已经获得了年龄对生存没有影响的证据。在这种情况下,可能需要更多的数据来观察 BF 如何随着更多的累积数据而发展。

我喜欢用下面的话来思考贝叶斯因素:“我应该在多大程度上改变我的信念,即年龄对泰坦尼克号灾难的生存可能性有影响?”。答案是贝叶斯因子。根据你之前的信念(也就是所谓的之前的,你可以根据你从数据中已经知道的东西进行调整),BF 会有所不同,这取决于效果的强度。

在这里,我似乎不应该改变我的信仰。

正如你所看到的,虽然频率主义者的方法会得出年龄影响的结论,但贝叶斯方法会说在得出结论之前需要更多的数据。在这种情况下,最好的办法是收集更多的数据,以获得效果的证据,或者证明效果不存在的证据。

效果的证据

现在让我们使用另一个著名的数据集,波士顿住房数据集,来探索另一种情况。你可以在帖子开头给出的回购上找到这个数据集。

下面我画出了查尔斯河上每个位置的房屋价格(你应该在最初的比赛中预测到)。

(df_housing.groupby('chas')
.apply(lambda d: pd.Series({
    "std": d.medv.std(),
    "sem": d.medv.std() /  d.medv.count(),
    "avg": d.medv.mean()
}))
.plot(kind='barh', 
       y = "avg", 
       legend = False, 
       title = "Mean price per river location +/- std", 
       xerr = "std"
      ));

图 6 |每个河流位置的平均房价。误差条显示分布的标准偏差。

正如我们所看到的,真实值(靠近查尔斯河)的价格高于虚假值。
现在,让我们从统计学的角度来探讨这一观察结果。

我不会在这里显示 JASP 结果的截图,但只有结果。

frequentist 独立样本 t 检验显示两种分布之间的差异非常显著(t( 504 ) = -3.996, p < 0.001),即在位于查理斯河上和远离查理斯河的住房之间观察到的房价差异非常显著。

让我们看看贝叶斯测试能得到什么。

贝叶斯方法证实了具有非常高的 BF 值的观察结果,表明该数据在 H1 假设下的可能性是在 H0 下的 270 倍。

现在,我们有最后一个案例要探索:贝叶斯统计将允许我们在没有影响的情况下得出结论。

缺席的证据

到目前为止,一切顺利。在前面的例子中,我们看到这两种方法都是有意义的,并且在效果较高时同时出现。现在让我们来看看另一个变量,我们可以更清楚地使用贝叶斯方法的力量。

与其看一个可能显示价格差异的变量,不如看另一个变量:“zn”变量,即 25,000 平方英尺以上地段的住宅用地比例

首先,让我们看看一个常客会怎么说:

然后,贝叶斯会说:

频率主义者会说没有影响,但同样,我们不知道是否真的没有影响,或者我们是否缺乏统计能力…

贝叶斯理论说我们有一个 BF10 = 0.284。该值低于 1/3,根据上述术语,这一次,我们的数据为 H0 提供了适度的证据,即位于或远离查理斯河的位置不会导致工业区的比例更高。换句话说,我们有证据表明不存在影响,我们可以从进一步的模型和解释中完全排除这个变量,以简化我们的分析。

这一结论与“缺乏证据”的情况相反,我们之前在泰坦尼克号数据中使用可变年龄发现了这种情况。在这种特殊的情况下,我们不应该从我们的模型和分析中去掉年龄,因为我们没有明确的证据表明它在我们观察到的效应中不起作用。

结合频率主义和贝叶斯方法

这种统计检验的最有力的方法可能是报告频率主义和贝叶斯方法。这是我们在最近的出版物中所做的,以适应频率论者和贝叶斯评论者,并证明为什么一些变量从进一步的协变量分析中被去除,而其他的被保留

欢呼感谢阅读:)

六月(June 的缩写)

你可以在下面的回购处找到这个笔记本:https://github.com/juls-dotcom/bayes

重新审视统计学

原文:https://towardsdatascience.com/statistics-revisited-5541f0bb9c4b?source=collection_archive---------20-----------------------

入门

在这里,我将尽力把统计概念分解成各种容易理解的方式,同时作为我学习过程中的总结笔记。

人口诉样本

很多时候,我们进行小样本的调查,仅仅是因为调查整个人口是不可行的。然后,这个样本允许我们对实际人口进行推断。统计学的研究很大程度上回答了这个问题:我能有多大的信心相信样本结果说的是人口的真相?

这种对总体进行归纳的方法叫做推断统计学。在此之前,让我们回顾一下我们在早期学校生活中会遇到的一些基本的描述性统计数据。

描述性统计

平均值、中值和众数是寻找数据集中平均值的常见方法。以下是更好地描述和可视化数据集的一些其他方法:

方程式1

算术平均值是通过将数据集中所有数字的总和除以数据集中的数字计数获得的。一个常见的例子是确定班上学生的平均身高。

方程式[2]

虽然不如算术平均值直观,但在处理百分比时,可以很容易地联系到几何平均值。例如,确定一段时间内投资的平均回报。

数据集的众数是出现最频繁的值,而中位数是有序数字列表中的中间数字。与中位数的概念相似,四分位数将有序的数字列表分成四个相等的部分,所需的四分位数位于中断位置。

作者图片

为了更好地显示数据集中数字的分布,可以使用箱线图快速显示最大值、最小值和四分位数位置。箱线图的不同形状揭示了数据中的偏斜度。箱线图也有助于识别是否存在异常值。

作者图片

数据集的范围提供了其可变性的非常基本的概述,即各个点围绕平均值分布的程度。衡量可变性的更好方法是计算其方差和标准差。

方程式[3]

方程式[4]

虽然这些方程可能看起来吓人,但方差只是取每个数据点和平均值之间的差的平均值。差值被平方以消除正值和负值的影响。由于方差现在具有大得多的量级(由于平方函数),标准差取方差的平方根,使得它变得与数据集“相关”。

作者图片

从上面的例子可以看出,计算出的方差和标准差分别是 146.58 和 12.11。将这两个值与原始数据集值进行比较,与方差值 146.58 相比,平均值 12.11 的分布可被认为更“相关”。

推理统计

既然我们已经在一定程度上概括了描述性统计,让我们重温一下之前被问到的问题:我能在多大程度上相信样本结果真实地反映了总体情况?

假设我们想确定一个新生婴儿的平均体重。通过收集 8 个婴儿的体重样本,发现样本均值为 3.2kg。另一个由 20 个婴儿组成的样本显示样本均值为 3.4kg。直观地说,我们应该更相信哪个均值?

方程式[5]

这个例子说明了估计误差的概念——在确定总体参数时,我们的“最佳猜测”应该是什么。从方程[5]可以看出,当样本量 N 增大时,标准差减小,其中 s 为样本的标准差。这在一定程度上表明了样本均值可能存在多大的变化。

既然知道样本之间和样本内部也存在差异,那么点估计(即取特定值的总体参数)似乎不是一个可行的选择。取而代之的是引入了一个置信区间,它是一个数字范围,人口参数被认为落在这个范围内。

形状像钟形曲线的正态分布通常用于确定置信区间。这是因为中心极限定理(CLT)带来的独特观察。CLT 指出,如果总体有一个有限的均值和标准差,当用替换从总体中取出足够大的随机样本时,样本均值的分布将近似呈正态分布。

值得注意的是,我们不一定知道人口数据遵循什么分布。类似地,每个样本将遵循一个未知的随机分布。然而,当抽取足够多的样本时,由于中心极限定理,它们的平均值将遵循正态分布。下图说明了这一点。

作者图片

从创建的正态分布图中,我们可以直观地看到估计的总体均值在哪里。标准差是通过将每个样本平均值视为一个数据点来计算的。然而,如果只有一个样本,并且假设分布为正态分布,则可以根据等式[5]将标准偏差估计为平均值的标准误差。

为了构建置信区间,我们需要首先将正态分布转换为 z 分布,或者称为标准化正态分布。这样,分布最终将取平均值 0 和标准差 1。

方程式[6]

作者图片

在正态分布中,平均值、中值和众数相等,曲线关于平均值对称。曲线下的总面积为 1,表示 100%的概率。z 分数是沿 z 轴的值,对应于平均值的标准偏差数。在不同的 z 分数下,z 表确定由这些分数限定的总面积。面积还表示位于此区间内的观测值的百分比,有时称为 p 值。因此,我们可以用表示为置信区间的概率置信度来估计统计量。

作者图片

如果样本量 n 很小(< 30), and/or the population standard deviation is unknown, we use a t-distribution instead. Also having a bell shaped curve, the t-distribution has a lower peak and fatter tails compared to a z-distribution, resulting in a more conservative confidence interval given the same significance level. We can think of this as a way of penalizing the estimate since less reliable information is provided.

Image by author

Instead of referring to the z-table, the t-table is used instead. One point to note when using the t-table is that the degrees of freedom (D.O.F) is used instead, where D.O.F = n -1)。D . o . f 是指最终计算中可自由变动的数值数量。在这种情况下,D.O.F = n -1,因为在已知样本均值和样本标准差的情况下,n 中的最后一项必须是固定值。

置信区间和显著性水平的概念在统计学和机器学习技术中被广泛使用。虽然它确实以相对较高的置信度提供了总体参数的一系列估计值,但当平均值实际上位于规定的置信区间之外时,就有可能出现误差。更多内容将在我下一篇关于假设检验的文章中介绍。敬请期待!

使用统计学改进线性回归

原文:https://towardsdatascience.com/statistics-supporting-linear-models-bfc24fb9781f?source=collection_archive---------6-----------------------

关于线性回归的数学基础以及如何使用它来提高拟合优度的详细帖子。

当试图解决复杂问题时,简单而复杂的方法往往被低估。这个故事旨在展示线性回归仍然非常重要,以及我们如何提高这些算法的性能,成为更好的机器学习和数据科学工程师。

Unsplash 上的 Pietro Jeng 拍摄

作为机器学习领域的新生,你首先要学习的是简单的一元线性回归。然而,在过去的十年左右,基于树的算法和神经网络在商业规模上盖过了线性回归的重要性。这篇博文的目的是强调为什么线性回归和其他线性算法仍然非常重要,以及如何提高这些基本模型的性能,以便与 XGBoost 和 Random Forests 等大型复杂算法竞争。

线性回归-最佳拟合线(图片由作者提供)

如何提高线性模型的性能:

许多自学成才的数据科学家首先通过学习如何实现各种机器学习算法来开始编写代码,而没有真正理解这些算法背后的数学。通过理解这些算法背后的数学,我们可以了解如何提高它们的性能。

线性回归背后的数学对模型将接收的数据做了一些基本假设:

  • 没有异质
  • 无多重共线性
  • 自相关
  • 正态分布
  • 线性

让我们更深入地研究其中的一些假设,并找到改进我们模型的方法。

线性度:

线性模型试图通过给定的数据点拟合一条直线。它看起来类似于下面给出的图表。

然而,这种模型无法拟合不是线性绘制的数据点。考虑一个关系 y = x + c +-(噪声)。这个函数的图形是抛物线。拟合一条穿过该图的线不会得到很好的拟合。

(图片由作者提供)

我们需要通过应用指数、对数或其他变换来变换独立变量,以获得尽可能接近直线的函数。

这意味着,通过平方每一项,将自变量从 x 变为 x,我将能够拟合一条穿过数据点的直线,同时保持良好的 RMSE。

因此,在建立最终模型之前,我们需要弄清楚我们的自变量是与每个因变量直接相关,还是与这些变量的变换直接相关。

无异方差(恒定方差)

考虑这样一种情况,你受雇于一份月薪 3000 美元的工作,而你的生活费用总计 2950 美元。你每个月只剩下 50 美元可以在闲暇时花。你可以选择花掉这笔钱或者存起来。无论如何,这不会立即带来显著的变化。您的银行余额变化很小(在 0 到 50 美元的范围内)。10 年后,你现在是一家跨国公司的首席执行官,月薪超过 10 万美元。你的生活费用总计 25,000 美元。现在你可以选择花掉剩下的 75,000 美元或者只花掉其中的一部分。月底你银行余额的变化可能在 0 到 75000 美元之间。与 10 年前相比,这里的范围要大得多。随着时间的推移,你能存的最少和最多的钱之间的差额也在增加。

线性回归假设数据点之间的方差不作为因变量的函数而增加或减少。

图表应该看起来更像这样,以符合良好的线性模型。

在这种情况下,线性模型的标准误差将不可靠。

如何检测:

  • 戈德费尔特-量子试验

此函数返回 F 统计量和 p 值。

  • 布鲁施-帕甘试验

该函数返回拉格朗日乘数统计量、p 值、f 值和 f p 值。

无多重共线性

考虑一个问题陈述,其中要求您根据地块的长度、土地面积以及与学校和公共基础设施的距离来预测房地产的成本。这里很明显,两个独立变量(图的长度和面积)直接相关。随着长度的增加,面积也增加。这种相关性会影响线性回归的性能。

如何识别这一点:

  • 使用皮尔逊相关。

皮尔逊相关热图[图片由作者提供]

如何解决这个问题:

  • 删除两个变量中的一个
  • 创建一个函数,使用相关特征创建一个新的自变量,并删除相关特征。

分布正态性

这是人们在建立线性模型之前通常会忘记的最重要的因素之一。数据集中的连续变量需要服从高斯分布,这一点很重要。

高斯分布它是一种关于均值对称的概率分布,表明接近均值的数据比远离均值的数据出现的频率更高。在图表形式中,正态分布将显示为钟形曲线。

偏离高斯分布的度量称为偏斜。可以使用 scipy 模块在 python 中计算分布的偏斜度。

Seaborn distplot 图[图片由作者提供]

在上图中,黑线是指我们希望达到的高斯分布,蓝线代表给定数据在变换前的核密度估计(KDE)。

修正数据的偏斜度可以极大地提高线性模型的准确性。

可应用于固定偏斜度的变换:

  • 对数转换:如果数据是右偏的,即分布在右端有一个长尾,这种方法效果最好。

  • 指数变换:用幂“c”提升分布,其中“c”是任意常数(通常在 0 到 5 之间)。

  • Box-Cox 变换:这种变换在至少 80%的情况下修正了偏斜度。这无疑是修复偏斜的最有力的工具。这里λ是用于将非正态分布拟合为正态分布的值。如果您想要执行逆 box-cox 运算来获取初始数据,您将需要该值

  • 倒数变换:用它的倒数/逆来替换这些值。

自相关:

自相关的教科书定义是:

自相关是指数据中不同观察值的相同变量之间的相关程度。

让我们借助一个例子来理解这一点。自相关的概念经常在时间序列数据的上下文中讨论,其中观察发生在不同的时间点,因此我们将以一个虚构的公司(XYZ 公司)的股票价格为例。在过去的三天里,这家公司的股票价格一直稳定在 50 美元左右。从这个数据中,我们可以推断第 4 天的股价将很有可能在同样的 50 美元左右。但是,这不能从现在开始 2 个月左右说。这种类型的数据被称为自相关数据,在这种数据中,彼此距离较近的数据点比距离较远的数据点相关性更强。

对线性回归的影响:

  • 这将影响直线的拟合优度,因为自相关会影响标准误差。然而,这些系数是无偏的。
  • 在存在自相关的情况下,诸如 p 值、t 值和标准误差的统计测量将是不可靠的。

如何检测自相关的存在:

  • Durbin-Watson 检验:这是通过比较连续的误差项来检查它们是否彼此正相关/负相关。1.5–2.5 之间的值会告诉我们,自相关在该预测模型中不是问题。

使用 python 计算 Durbin-Watson 评分

杜宾-沃森检验中的 0-1.5 表示显著正相关,而 2.5+表示显著负相关。

然而,当连续但等间距的数据点之间存在自相关时,该测试无法检测到自相关。(例如:每周五的股票价格为 52.50 美元+-0.5 美元)。

  • Breusch-Godfrey 测试:这比之前的测试稍微复杂一些。简单地说,这个测试要求你建立一个模型,计算每个数据点的误差项,并尝试预测时间 t 时的误差项,作为所有前面的误差项的函数。

该测试也可以使用 statsmodels 模块来执行。点击链接查看他们的官方测试文档。

结论

我希望这个故事对你有所启发。祝您在数据科学之旅中好运

统计:用数据可视化讲述故事

原文:https://towardsdatascience.com/statistics-telling-stories-with-data-visualization-904ceddf2afb?source=collection_archive---------37-----------------------

图片说千言万语。数据的可视化为人类思维创造基于洞察力的行动做好了准备。

Unsplash 上由 Adeolu Eletu 拍摄的照片

在我早先的帖子中,我已经写了关于有效使用表格从原始数据中获取洞察力的文章。无论表格在捕捉数据的细微差别方面多么有效,有时太多的数字会使它看起来很麻烦。在这种情况下,你如何从数据中分辨出一个故事?在本文中,我将尝试提出一些有效的技术来图形化地表示数据。

在我开始之前,一个有效的问题是,当提到“图片”或“视觉”时,你会想到什么?我猜是某种艺术形式。你会想到挂在你房间墙上的肖像或者更著名的艺术作品,比如蒙娜丽莎等。挖掘数据也是一样,这是一件艺术品,完全取决于你如何最好地利用图像向你的观众传达一个驱动点。这完全取决于你想要解决的最终目标。

因此,任何一篇博客文章都很难给你一个准确的方向,告诉你在每种情况下应该画什么样的图表。相反,这篇文章将:

  1. 解释可视化的需求
  2. 描述有效可视化所需的步骤
  3. 演示数据可视化操作
  4. 简单概述如何使用最常用的工具之一——MS PowerPoint 来创建这些可视化效果

将使用它的读者需要使用他/她自己的直觉,并随着经验的增长来让这些人讲述故事。

为什么我们需要可视化?

世界正面临海量数据。你可能会多次听到类似“数据是新的石油”或“是核能”这样的话。但是,全世界每秒钟产生的数万亿个数据点对您来说意味着什么?很可能只是一串数字。是的,在某个时间点上,你可以用表格来总结,但是超过这个时间点,大脑就处理不了了。有没有更简单的理解方式?为什么我们不利用足够的图像或者本质上的数据可视化呢?数据可视化可以以有效的方式排列数据,使人类更容易理解数据的组成,突出任何模式或异常值,将一组数据与另一组数据进行比较,并确定它们之间的任何关系(如果有的话)。

做得好的视觉化可以讲述一个故事。2020 年,任何人脑海中浮现的数据都是新冠肺炎。如果在任何时间点,你想知道感染在任何国家(比如印度)的进展情况,最简单的方法就是查看每日确诊病例图表:

图 1:印度每日新冠肺炎确诊病例

看图表,想一想在这个简单的表示中你能看到什么?印度从 2020 年 1 月底的 0 例增加到 5 月中旬的每天约 3500 例感染。从 3 月底到 4 月初,病例开始略有增加。虽然 4 月份稳步增长,但 5 月份的大幅增长令人担忧。所以,看看仅仅画一个线形图是如何让你想到至少 3 个观察值的!想想成千上万的数据点,也就是成千上万人的新冠肺炎测试结果,这些数据点已经被这条简单的曲线概括出来了!

如果你想添加更多的信息会怎样?不如我们想知道随着时间的推移,复苏的进展如何?看着图表,思考你能推断出的见解。此外,请注意图表和纵轴标题是如何改变的,以讲述故事的关键。添加了图例,以解释哪条曲线显示确诊病例与恢复。

图 2:印度每日确诊和恢复的新冠肺炎病例

让我们再举一个例子。你有没有想过,在 LinkedIn 上,当你有成千上万的联系人和关注者时,有没有一种方法可以了解他们在职业和社交方面是如何与你联系在一起的?LinkedIn 有一张地图可以让你看到它们。看看下面的视频,由 DJ Patil 解说,讲述了在 2014 年之前,他们如何通过酷炫的可视化让您能够更好地了解您的网络连接:

视频:昔日的 LinkedIn 网络地图

虽然上述功能已于 2014 年停止使用,但它曾是 LinkedIn 最酷的功能之一。然而,一些最近的开源工具,如 Python,可以创建一些类似的视觉效果,如果不是完全相同的话。

我们谈到了数据可视化的细微之处。但是有没有什么缺点?看看新冠肺炎的图表。它是否显示每天确诊和/或康复病例的确切数量?它无法向你展示政府、科学家和一线医护人员等特定群体工作可能需要的准确数量或精确度,这可以通过表格表示法获得。然而,它们提供了一个近似的理解,这对于一个更大的群体来说是有好处的,他们正在跟踪感染增长并祈祷“曲线变平”。同样,一个好的视觉化的故事需要很长时间来创作。

如何开始?

在一个满是观众的房间里,当你想分享一条信息时,你有时可能想在白板上画图。那你脑子里在想什么?或许,传达你的信息的最好方式是什么?最容易传达信息的绘画形式是什么?所以,你可以想象你需要遵循几个步骤:

图 3:实现有效可视化的步骤

数据可视化在行动

为了观察各种类型的视觉化活动,我们需要理解它们在不同情况下的必要性。以下是它可以对您的数据做的三件重要的事情:

图 4:可视化有什么帮助?

让我们先从第一件事开始,分解组件。这些时候,你有数据,你希望了解它是由什么组成的。例如,如果您希望了解工厂中工人的构成,以下是几种可视化方法:

图 5: 饼状图显示万名员工中不同年龄员工的比例

接下来, 100%堆积柱形图(如下图 6) 可以显示一个组中的子组。在这个例子中,我们可以很容易地找到年龄组内的性别构成。注意我们如何通过更好地使用颜色来更好地推断。

图 6: 100%堆积柱形图,显示各年龄组中男性与女性的百分比

此外,请注意这些图表如何帮助在比例的基础上比较(我们的第二个关注领域,根据图 4)。如果需要基于绝对差异的比较,类似图 7 的堆积柱形图(非 100%) 会有所帮助。

图 7:堆积柱形图,显示各年龄组中男性与女性的数量

条形图是柱形图的扩展,在柱形图中,条形水平移动,而不是垂直移动。另外,看一下树形图进行构图对比:

图 8:显示通过积累以及与其他组比较的构成的树形图

用于定量数据的其他非常重要的绘图技术有面积图瀑布图

图 9:面积图

图 10:瀑布图

我们已经看到了一些图表,展示了如何将数据分解为粒度成分,以及一些比较这些成分数据的方法。还有一些其他方法可以比较不同时间和不同静态点的数据成分。看看上面图 1 和图 2 中的新冠肺炎感染和恢复计数图表。这些是折线图,这些图比较感染和恢复的数量如何随时间变化,或者比较两个时间点

也可以使用简单的柱形图来显示一段时间内以及某个时间点的比较。例如,在 XYZ 公司的员工中,您可能想知道他们在哪个州上学:

图 11:条形图

请注意,如果您想要绘制多个信息,但这些信息遵循相同的单位刻度,您可以在水平轴上为每个类别或时间点创建多个条形图。

让我们转到可以通过可视化展示的统计分析。第一种类型始终是显示数据分布的直方图。例如,如果您希望了解 XYZ 公司工人的身高分布,直方图将给出相同的解释:

图 12:工人身高分布直方图

请注意,这看起来很像柱形图,但本质上,与柱形图有很大的不同。首先,直方图显示分布,而柱形图比较类别或时间段,目的是不同的。接下来,直方图可以处理连续形式的数据,其范围被分组到多个区间中。

破译数据的分布给你一个特定变量的可能值,比如身高和它们出现的频率如果您要为工人订购防护装备,您可以使用直方图大致了解订购数量,而不是测量 10,000 名工人中每个人的准确身高,这非常耗时。

虽然像身高这样的变量通常遵循 正态分布 (类似钟形曲线的形状),但现实生活中有许多其他变量并不如此。举例来说,让我们考虑一下,如果工人在工作中受伤,他们可以提出工伤保险索赔。

图 13:显示工人保险索赔分布的直方图

现在我们已经看到了分布图,可视化在统计分析中的另一个重要用途是理解关系,这将我们带到散点图

图 14:散点图

另一个用于数据统计分析的非常有用的图表是箱线图(或有时称为“箱线图”)。它可以使用多种度量来描述数据,如最小值、第一个四分位数、中值、第三个四分位数和最大值。例如,如果您想了解 XYZ 公司的 3 种产品的数据,在您收到对某一产品的第一次投诉之前过了多少个月呢?假设您收集了 5000 台便携式冷却器、智能逆变器和中央空调系统的数据。你如何代表?

图 15:箱线图

虽然上面解释的技术有助于在许多情况下可视化数据,但是还有许多其他创新的方式来可视化数据,如人口统计图(参见下面的示例)、热图等。拥有多个仪表盘构建器和开源工具,如 Tableau、Qlikview、R-Shiny、Python 等。可以创建许多具有这种可视化效果的很酷的仪表板。回顾这些工具超出了本文的范围,但是我们将看看一个常用的工具,Microsoft PowerPoint,它可以构建这些图表的大部分。

图 16:使用微软 PowerPoint 的世界地图

使用常用工具创建可视化

上面显示的所有图表都是用微软的 PowerPoint 制作的,如果你使用的是微软 Office 系统,PowerPoint 是一个非常常用的工具。因此,你实际上不需要购买花哨的工具来使用可视化创建有效的故事。然而,这对于中等规模的数据集来说是正确的。如果您的数据很大,那么可能需要寻找能够处理大小的替代方法。下面是在 PowerPoint 中创建可视化效果的一步一步的简单方法:

图 17:使用 Microsoft PowerPoint 开发可视化

结论

在本文中,我们看到了使用图片从数据开发多个故事的多种技术。当你有大量的数据流,并且你不打算钻研复杂的数学时,数据的可视化可以训练你的思维来推断重要的结论。虽然现在有多种工具来开发可视化,但要从中等大小的数据开始,除了 Microsoft Excel 和 PowerPoint 等常用工具之外,不需要任何东西。随着当今世界数据量的不断增长,构建一个能够轻松查看数据并理解可见模式的策略以更好地制定分析方法是势在必行的。所以,选择今天你最容易得到的数据集,看看你能创造出什么样的视觉效果!

留守家园——新冠肺炎的故事

原文:https://towardsdatascience.com/stayathome-a-story-of-covid-19-6aeeba2b6c?source=collection_archive---------75-----------------------

居家养老运动的趋势与前景分析

来源https://unsplash.com/@anastasiiachepinska

冠状病毒病(新冠肺炎)是由一种新发现的冠状病毒引起的传染病来源。2019 年 12 月下旬,中国武汉市报告了首例新型冠状病毒病例[ 来源 ],此后该病毒在全球范围内传播。因此,世卫组织宣布它将在 2020 年 3 月 11 日前成为全球疫情。截至 2020 年 5 月 23 日,在 188 个国家和地区报告了超过 520 万例病例,超过 338,000 人死亡,约 205 万人已经康复。自从疫情公告以来,许多国家已经决定完全或部分封锁他们的国家,许多人在家里学习、工作和祈祷,这导致了在家活动。想了解更多关于冠状病毒的信息,请看cdc.gov

家庭旅馆

2020 年,StayAtHome 已经成为世界各地的一项运动,作为各国政府为缓解新冠肺炎疫情而限制人口流动的行动。这场运动命令社会呆在家里,除了必要的任务。一个几乎相似的术语是一级防范禁闭,但一些权威人士认为一级防范禁闭有可能被误解,人们会认为它包括挨家挨户的检查。

本文的目的是了解人们对居家养老活动的趋势和看法

数据源

本文使用的数据都是包含 #stayathome 或短语“呆在家里”的推文。新冠肺炎首例病例于 2019 年底报告,并于 2020 年初开始引起世界关注。因此,数据收集的时间范围在 2020 年 1 月 1 日到 2020 年 5 月 20 日之间。收集的推文仅限于英语推文。收集的推文总数为 3571374 条。在收集的数据集上应用了一系列数据清理步骤,如删除重复、删除转发和提及。数据清洗后的推文总数为3570271

趋势

图 12020 年 1 月 1 日至 2020 年 5 月 10 日与 StayAthHome 活动相关的推文总数趋势

自 2020 年 3 月 9 日以来,与 StayAtHome 运动相关的推文数量开始增加,并于 2020 年 3 月 23 日达到峰值。高峰出现在许多国家在接近该日期时做出重要决定的时候。随着冠状病毒病例达到 1600 例,澳大利亚于周一(2020 年 3 月 23 日)开始一级防范。英国首相鲍里斯·约翰逊告诉英国公众:“你必须呆在家里。”2020 年 3 月 23 日星期一。美国的一些州也宣布在 2020 年 3 月 22 日至 24 日进行封锁,如康涅狄格州马萨诸塞州密歇根州纽约州威斯康星州堪萨斯市堪萨斯州俄勒冈州。此外,还有其他国家在接近该日期时做出了同样的决定,如希腊、利比亚和德国[ 消息来源 ]。

在 2020 年 3 月 23 日之后,趋势是下降的,最低数字发生在 2020 年 5 月 10 日,这是数据收集时间范围的最后一天。随着澳大利亚等几个国家放松封锁,这一数字预计将进一步下降。

相关标签

图 2 显示了与#StayAtHome 本身旁边的 StayAtHome 活动相关的前 25 个标签。确认#StayAtHome 与#covid19 和#冠状病毒高度相关。许多人试图通过使用#stayhomesavelives、# socialdistancing 和#staysafe 来提醒社会。标签中的另一个发现是关于地点的,例如#NHS 代表英国,#indiafightscorona 和# jantacurfew 来自印度。此外,在疫情爆发期间,人们还在推特上谈论复活节、音乐/艺术表演和在家工作。

图 2stay home 活动的相关标签

主题建模

上一节通过标签讨论了推文的背景。通过文本本身来理解推文会很有趣。一种方法是进行主题建模。

主题建模是一种用于发现出现在文档集合中的抽象“主题”的统计模型。有许多不同的算法可用于执行主题建模,如 LDADMMNMF双项等。LDA 将用于此写作。如果你对 LDA 的技术方面感兴趣,我建议你阅读论文,或者下次我可能会写另一篇关于它的文章。

如前所述,趋势自 2020 年 3 月 9 日开始增加,因此,在执行主题建模时,将仅使用自 2020 年 3 月 9 日以来的 3,451,390 条推文。在执行 LDA 时,其中一个步骤是定义主题的数量。从 2 到 20 个主题的可能数量的列表被应用于该算法,并且最佳模型是具有 8 个主题的 LDA。以下是每个话题的热门词汇。

话题一: 时间、工作、制作、小孩、日子、学校、妈妈、孩子、家、父母、好、吃、人、夜、爱、年、事、神、食物、思念 话题二: 订单、关闭、测试、工人、人、面具、必备、ppl、罚款、到期、警察、增加、健康、办公室、医院、穿、组、开、打、走 trump,reopen,start,wanna
话题 4: 天,时间,今天,观看,制作,玩,享受,好,爱,自由,伟大,阅读,学习,在线,展示,明天,星期,快乐,开始,直播 话题 5: 人,病毒,传播,政府,停止,死亡,covid,电晕,制作,封锁,国家,告诉,唐,冠状病毒 更新、支持、总、三月、花费、关注、服务、每日、数字、积极 话题 7: 停留、安全、家庭、健康、家庭、拯救、周末、拯救 _ 生活、爱情、消息、covid、洗手、希望、避免、每个人、保护、关怀、生活、时间、美好 话题 8: 人、工作、唐、做、家、天

解读

此解读纯属作者角度。

主题 1 包含孩子、日子、学校、妈妈、孩子、父母可能与学校关闭和需要在家照顾他们的父母有关。

主题 2 包含测试、人员、口罩、必需品、医院、佩戴可能代表新冠肺炎测试,高度鼓励人们佩戴口罩以帮助防止疾病传播

主题 3 包含州、州长、扩展、开放、抗议、发布、特朗普可以代表美国的封锁扩展,并向美国总统发布关于打开封锁的抗议

主题 4 包含日、时间、观看、玩、享受、在线、表演可以表示与游戏和表演相关的常见家庭活动。

主题 5 包含人、病毒、传播、政府、停止、死亡、covid、电晕、制造、战斗、疫情、倾听、规则、公共可能代表来自用户的声音以对抗疫情

主题 6 包含病例、covid、视频、分享、死亡、帖子、安全、团队、更新、支持、总计、三月、花费、服务、每日、数量、阳性可以代表阳性或死亡病例数量的更新,尤其是在 2020 年 3 月期间。

主题 7 包含、安全、家庭、健康、家庭、储蓄、周末、储蓄 _ 生活、爱、消息、covid、洗手、避免、保护、护理、生活、时间、好可以与在家中保持安全和健康以及通过洗手避免新冠肺炎相关。

主题 8 包含人物、工作、家庭、薪酬、周可能与在家工作有关

话题比例

尽管 LDA 假设一个文档包含不止一个主题,但是如果每条 tweet 都用其主导主题来标记,那将会很有趣。通过这样做,可以计算出每个主题的 tweets 数量。

图 3 基于主导话题的推文比例

这表明,与在家工作相关的话题(话题 8)和来自用户的反对疫情的声音(话题 5)占总推文的 40%以上。这与许多人由于这场危机被迫在家工作的事实相一致,人们倾向于在社交媒体上讨论新冠肺炎的传播,并希望这场疫情能够尽快结束。

评论

如果你有兴趣进一步分析这个数据集,我在这里发布了数据集

资源: Github

如果您有任何反馈或进一步的讨论,请通过 LinkedIn 联系我。

#StayAtHome —他们是对的吗?

原文:https://towardsdatascience.com/stayathome-are-they-right-99f764a0b1de?source=collection_archive---------52-----------------------

我们在哪里,我们将会在哪里?西班牙数据案例研究。

每天新闻和媒体都告诉我们,建议呆在家里——但是我们有办法从数学上证明或否定这种说法吗?我们将处理西班牙的数据,但这些原则可以适用于任何国家。

在这篇文章中,我们将用基本的数学来证明或反驳这种说法——但是如果你不喜欢数学,也有图表

疾控中心Unsplash 上拍摄的照片

呆在家里的整个想法是避免不必要的社会接触,并与外界保持距离。通过这样做,我们大大降低了疾病的增长率。

但是这有多重要呢?

事实证明,很多。

在继续之前,请记住我不是任何类型的医学专家,下面写的一切都是基于纯(简单)数学。此外,使用的数据集可以从这里下载。

案例:西班牙

我不住在西班牙,也没有亲近的人住在那里,但事实证明,西班牙现在是欧洲“最热”的地方。

在写这篇文章的时候,我们已经有了截止到 2020 年 4 月 3 日的累积数据。到目前为止,西班牙有 119.199 例确诊病例。让我们快速想象一下病毒随时间的移动:

从这里开始,谁知道多久曲线会开始看起来像你的平均逻辑曲线。

但是,在得出结论之前,我们需要更多信息,我们还对某个时间段的平均增长率感兴趣,比如说过去 7 天。这可以通过简单地将今天的确诊病例数除以昨天的数字来获得,结果应该接近于 1。

在指数增长阶段,如果我们比较 4 月 2 日和 4 月 3 日,这个数字将一直大于 1,大约为 1.06——这意味着 4 月 3 日西班牙的确诊病例比前一天多了大约 6%。

一旦西班牙接近拐点,我们可以预计增长率将持续在 1 左右,并从那里开始走下坡路。

如果你感兴趣,以下是西班牙的增长因素:

我们可以清楚地看到这个因素在减少,但是谁知道接下来会发生什么。

现在让我们做一点数学计算。

计算出的生长因子是过去 7 天生长因子的平均值,我们将用它来证明呆在家里、保持个人卫生和避免社交聚会是多么重要。生长因子的平均值大致为 1.0888

对你来说,这听起来可能没什么——但这就是为什么你错了。如果西班牙在接下来的 30 天内有大致相同的 8.88%的日增长率,则确诊病例的预期数量可以计算如下:

其中:

Xt:今天确诊病例数

n:未来的天数

α:平均增长率

一旦我们输入数字,就会得到一个惊人的结果:

这意味着,如果不采取额外措施让人们留在室内,增长率保持大致不变,我们可以预计,30 天内,仅在西班牙,就有 153 万人受到感染!请记住,只有当一切都保持不变时,这才是,这很可能不会发生。

然而,如果我们遵循政府制定的规则(或实施新的、更严格的规则),设法将平均增长率降低到比如说 1.05,情况就会大大改善:

嗯,这个数字无论如何都不小,但是 515K 听起来比 1.53M 好多了。

带回家的点

总之,如果你对数学不感兴趣,我有别的东西给你。我已经准备了一张(可能)很好看的图表,显示了西班牙在 3 种不同增长率下的确诊病例数:

  • 1.0888 —过去 7 天的平均值
  • 1.05 —之前讨论过的一个
  • 1.03 —更优的比率

这是图表:

现在,不可否认的是,更多的人会被感染,不幸的是,更多的人会死亡——但是通过实施更严格的规则,我们可以确保增长不会遵循红色曲线,而是在蓝色和绿色曲线之间的某个位置。

感谢阅读,保重,待在家里。

编者按: 走向数据科学 是一份以数据科学和机器学习研究为主的中型刊物。我们不是健康专家或流行病学家,本文的观点不应被解释为专业建议。想了解更多关于疫情冠状病毒的信息,可以点击 这里

喜欢这篇文章吗?成为 中等会员 继续无限制学习。如果你使用下面的链接,我会收到你的一部分会员费,不需要你额外付费。

[## 通过我的推荐链接加入 Medium-Dario rade ci

作为一个媒体会员,你的会员费的一部分会给你阅读的作家,你可以完全接触到每一个故事…

medium.com](https://medium.com/@radecicdario/membership)

为您的数据科学事业保持动力

原文:https://towardsdatascience.com/staying-motivated-for-your-data-science-career-e845f18421e1?source=collection_archive---------81-----------------------

我们可以长期保持动力

汤姆·希尔斯在 Unsplash 上的照片

有一天,你起床完成 Coursera 的作业,参与关于人工智能的社交媒体讨论和/或从事那个项目,无论是来自 Kaggle 还是你自己的项目,你说你会放在你的简历上……你第二天醒来,突然之间昨天的动力消失了,你真的找不到它了。

我不知道是否每个学习数据科学的人都会经历一次动机的低迷。尽管如此,我还是做了。

太可怕了。我非常沮丧和担忧,不知道“我的现实会不会和我脑海中的形象一致”。情况变得如此糟糕,以至于我甚至不想看到任何人谈论任何与数据科学有关的事情,所以我停用了我的 Twitter 账户,我停止了收听播客,我买的所有书籍都在我跺脚时蒙上了灰尘。

等等!!

我不鼓励你做同样的事情。如果我预先知道我缺少什么,以及推动我们行业的领导者去追求他们的梦想的驱动力是什么,那么我可能不会有那个小阶段——尽管,如果我没有那个阶段,我今天可能不会写这篇文章。我从我的经历中学到的是我希望与你分享的,因为它是我每天醒来渴望面对生活的基础。

照片由安特·汉默斯米特Unsplash 拍摄

理解动机

要深入了解什么是动机,这些信息足以填满一般大小的自助书籍,但是如果要我总结什么是动机,我会将其描述为“在试图达到目标时,不断驱使我们克服挑战和障碍的力量或缺乏”。当我们缺乏动力时,在几次失败的尝试后或面对艰难的挑战时,放弃几乎是不可避免的。

我们常常没有给予动机与它在我们生活中的影响相称的尊重。事实是,如果我们不利用我们的动机,那就很难超越并真正享受我们每天所做的事情。

“动机不像电灯开关,动机是一种流动”——未知。

我们可以阅读所有我们想要的埃里克·托马斯的名言,但不清楚动机从何而来,如何运作,我们就会不断地缺乏我们真正想要的东西。

概念化动机

现在最合理的问题是“动机从何而来?”想想太阳吧——它可以自我维持并持续很长时间。这是我们在听播客,或者联系顶级凯格勒时希望达到的动机。这并不持久,它更像是一杯酒——我从来没有喝过酒,所以我不知道任何酒的名字——而不是范式的转变。

戴维·蒙涅在 Unsplash 上的照片

太阳内部由三个主要部分组成:核心,辐射区和对流区。在这个例子中

地核:地核位于太阳的中心,是太阳最热的区域。在这个地方,会发生核聚变反应,为太阳提供能量。

辐射区:辐射这个名字的意义在于描述能量通过这一层以光子和热能的形式向外传播的方式。

对流区:对流这个名称也描述了能量流动的主要模式。辐射带附近的热物质上升,冷却了太阳表面,然后又冲向辐射带,形成了所谓的对流。我们称太阳表面(严格来说太阳没有表面)为光球层,这是光线逃逸的地方。

注意:观看下面的视频,获得更深入的直觉。由于我不是一个合格的天文学家,我只是出于好奇才了解它。

那么这和我们的激励系统有什么关系呢?

"最终变成光的电磁辐射就是在地核内部形成的."

我们可以将太阳的内部构成与我们的动机系统联系起来,如下所示:

  1. 核心目的
  2. 辐射层—驱动因素
  3. 对流层——识别

我们的激励系统有几层,一直延伸到表面。我们可以看到表面,虽然真正的能量从哪里来才是核心。

“从为什么开始”——西蒙·西内克

激励系统

核心:目的

塞尔吉奥·皮德蒙特Unsplash 上拍摄的照片

就像太阳一样,我们的核心是巨大能量被召唤并流向外层的地方,这就是为什么我之前把动机描述为一种流动——它从内向外流经各层。我们可以把我们的核心定义为我们的“为什么”或者更好的“目的”。

明确我们为什么会增强聚集在我们核心的能量,这是我们动力系统中最热的区域——能量随着向外层的流出而减少。然而,为了获得清晰,我们必须问自己明确的问题。是的,没错,回答正确的问题会给我们一个更清晰的目标,让我们与那些消极的人区分开来。

为什么我想成为一名数据科学家?

为什么我想成为一名卡格尔大师?

为什么我想开始定期写关于人工智能的博客?

这些问题需要一定程度的自我意识,因为这些问题的答案应该带来意义和进展,因为这些是动力的持续因素或“让火燃烧的东西”。当一件事有意义时,它会给对我们重要的人或事增加价值,而进步是我们继续前进的动力。

当能量从目的中释放出来时,它应该被导向某些东西

辐射层:驱动

照片由丹金Unsplash 上拍摄

不断看到问题?这些是我们激励系统中的驱动力。他们放大了核心,我们的目的。例如,看到所有正在努力进入数据科学领域的人,在你的投资组合中没有任何数据科学项目,或者希望提高你的数据科学技能以获得更好的薪酬工作(甚至最终可能创办自己的公司),这些都可能是驱动因素。

驱动力很重要,因为它们为你的超越创造了有利的环境。你可以看到需要修复的地方,然后进去。你的司机的重要性也可能会在你内心产生一种紧迫感,例如,你可能会因为疫情而处于失业的边缘,但你有一个依赖你的家庭。这些是司机!

对流层—识别

MD 杜兰Unsplash 上的照片

这就是已经过渡到数据科学的天文学家可能会让我明白的地方,因为对流描述了由较热且密度较低的材料上升的趋势以及较冷且密度较高的材料在重力影响下下沉的趋势导致的流体内部的运动,从而导致热量转移——来源于牛津词典。然而,当我将对流区描述为动机系统的一部分时,我主要指的是产生光的对流区的表面——即光球层。

这是我们动机系统的最外层,包括任何形式的外部认知,它可能是我们动机的一种形式。例如,我们可能需要数据科学社区的尊重、表扬、赞美、加薪、鼓励、反馈等。这些都在产生光的对流层的表面。

如果你记得我之前提到过对流——当辐射带附近的物质上升到太阳表面,然后又下降。我们得到的认可又下降了,这让我们看到了更困难的问题,为我们提供了更多改进的空间。

当我们看着激励我们的人时,这就是我们所看到的。通常,我们试图将我们的动机建立在这一点上,并向内工作,现在你可能会发现这并不是它是如何工作的!

结论

如果我们要为我们的数据科学事业创造持久和自我维持的动力,我们必须能够从我们正在做的事情中获得意义。不仅如此,它必须是有趣的,并且尽可能与工作无关。一个快乐的数据科学家不是在工作,而是在尽自己的一份力量让世界变得更美好。

如果您认为我遗漏了什么,或者您想向我指出什么,或者如果您仍然不确定什么,您的反馈是有价值的。发个回应!

然而,如果你想和我联系,我在 LinkedIn 上是最活跃的,我也很乐意和你联系。

[## Kurtis Pykes -人工智能博客-走向数据科学| LinkedIn

在世界上最大的职业社区 LinkedIn 上查看 Kurtis Pykes 的个人资料。Kurtis 有两个工作列在他们的…

www.linkedin.com](https://www.linkedin.com/in/kurtispykes/)

您可能感兴趣的其他一些故事:

[## 数据科学家如何更快地学习

学会学习的有效策略

towardsdatascience.com](/how-to-learn-faster-for-data-scientist-cfd96d317ce6) [## 当你试图成为一名数据科学家时感到沮丧的原因

将最优秀的人与众不同的隐藏技能

towardsdatascience.com](/the-reason-youre-frustrated-when-trying-to-become-a-data-scientist-2d2b8b402811) [## 学习数据科学的 3 个阶段

了解学习的 3 个阶段,以及我们如何将其有效地应用于数据科学学习

towardsdatascience.com](/3-stages-of-learning-data-science-9a04e96ba415)

蒸汽推荐系统

原文:https://towardsdatascience.com/steam-recommendation-systems-4358917288eb?source=collection_archive---------22-----------------------

这篇文章是关于 Steam 网站上的推荐系统的。

梁、谢一凡在浏览

的销售网站时。我们沉迷于那些商家的种类和品种。由于网站的设计,我们可以很容易地点击和购买。有时候,这种购买看起来很烦很晕,人们被困在商家里,找不到他们的 gorals,很多平台有成千上万的用户和游戏。因此,大多数网站都致力于让每个用户都喜欢和适合商家,让每个用户都有良好的游戏体验。

本文将游戏售卖平台“Steam”的推荐系统设计成五个部分,分别是基于人气、基于质量、基于内容、协同过滤、规模上的推荐。我们将介绍我们的项目从获取数据,建立模型,以及我们使用的算法和我们最终得到的结果。

下面是 GitHub 上这个项目的源代码链接:

https://github . com/AlbertNightwind/Steam-recommendation-system

关于蒸汽的介绍

什么是 Steam
Steam 是一个在线、跨平台的游戏分发系统,拥有约 7500 万活跃用户,总计约 1.72 亿个账户,托管超过 3000 款游戏,这使其成为本文介绍的这类作品的理想平台。该数据集包含超过 3000 个游戏和应用程序的记录。

Steam 是由 Valve 提供的视频游戏数字发行服务。它于 2003 年 9 月作为一个独立的软件客户端推出,作为 Valve 为其游戏提供自动更新的一种方式,并扩展到包括第三方发行商的游戏。Steam 还扩展到了一个在线网络和移动数字店面。

https://store.steampowered.com/search/?filter = globaltopsellers&OS = win

数据集
我们使用了 NumPy、pandas、requests、sys 的一个包,通过 Steam Spy 的 API 获取我们需要的数据,并使用 JSON 进行存储。
目的
根据游戏的受欢迎程度、游戏描述的相似程度、游戏的质量、玩家对游戏的偏好,向游戏玩家推荐相应的游戏,使 steam 获得更高程度的客户满意度

建立推荐系统的步骤
第一部分:基于人气的推荐
对于 Steam 网站的新用户来说,他/她所知道的都不算什么,也许让那些新用户了解这个网站最高效的方法就是给他们一些其他以前用户拥有的最受欢迎的游戏。而且这些热门游戏没有时间限制。自从他们出现在这个网站上,他们一直是受欢迎的游戏。

1.在做推荐之前,我们首先需要提取 app_id、游戏名称、拥有者、价格,所以我们需要做的第一步是通过请求访问 steam API,提取两周前 100 名游戏的相关数据,通过 JSON 将数据保存为 CSV 格式,以备后用。接下来,我们将使用 pandas 将数据转换为数据帧格式。

2.我们根据拥有者的数量对游戏进行降序排列(在这一部分,我们认为默认拥有者最多的游戏在这里最受欢迎)

以下是 Steam 网站上热门项目的所有者排名,其中一些实际上不是游戏而是软件:

按所有者数量列出的顶级项目

Part2:基于质量的推荐
由于 Steam 是一个非常全面的网站,所以很直接的我们就可以得到其拥有者最热门的游戏,这对于冷启动用户来说是一个很好的开始。但是这种方法是否能让一些普通用户满意呢?也许答案不是“是”。那些受欢迎的游戏总是有更多的用户,更多的正面或负面评论。从商业角度来看,游戏所有者被事实所说服。他们更关心游戏的质量,而不是销量。然而,一些游戏有更多的所有者,也许是因为媒体的宣传,著名的游戏工作室以及 Steam 网站本身。总的来说,因为玩家对于游戏的配合,网络游戏总是比非网络游戏拥有更多的用户。从普通用户的角度来看,他们中的许多人更关心这个游戏是否得到大多数留下评论的用户的积极评价。因此,所有评论的积极评论率(我们这里对“基于质量”的定义)可以很好地评估这款游戏在用户中是否具有良好的质量。

用户评论最多的 10 款游戏

1.我们首先还提取 app_id、游戏名称、所有者价格、正面评论和负面评论。然后我们把它们存储在 JSON 里,分别列出了每款游戏的所有评论,因为 app_id 是不可变的。这样就可以观察每款游戏的正面评价和负面评价的数量。

2.接下来,我们将每款游戏的评论集合起来,在原始数据框中增加了两列,分别是正面评论数和负面评论数,但正面评论数和负面评论数是独立的,也就是说,如果 A 的正面评论数相对低于游戏 B,但游戏 A 的总评论数远低于游戏 B,在这种情况下,显然游戏 A 的正面率更高。为了让分析更准确,更直观,我们增加了一栏好评率,也就是用好评数除以总评论数,这样我们就很容易在商品评论中看到一个好评的比例。

在这一步的最后,我们根据游戏的好评度对它们进行了排序。排序后,游戏对应的 ID 保持不变。

结果是:

按正比率排序的游戏

第三部分:基于内容的推荐

对于第 3 部分,我们认为该项目将集中于游戏的描述,因为游戏的描述不是直接从 Steam API 访问的,我们必须访问 Stem 网站来浏览这些描述。

因此,我们通过唯一的游戏 id 来访问每个游戏的描述,因为每个游戏都有一个通用的网站标准格式,我们首先复制通用的 HTTP 格式,然后我们将这些通用的 HTTP 格式与每个游戏的唯一 id 连接起来,然后将它们与每个游戏的数据帧存储在一起。然后我们通过 HTTP 请求访问它们,并首先将它们存储到一个新的 DataFrame 列中。
在这一部分中,我们想用对每一款游戏的描述来分析两款游戏之间的相似性,并根据相似性向玩家推荐合适的游戏。(如果玩家 A 喜欢玩游戏 A,并且游戏 A 和游戏 B 有很高的相似度,我们假设玩家 A 会喜欢游戏 B)

1.我们首先组装链接,我们可以得到游戏的描述。

这一步的结果是:

游戏及其 HTTP 描述

2.接下来,我们使用漂亮的汤包来解析这些游戏的描述,我们首先移动我们不需要的项目,如停用词和一些会妨碍我们的符号。

然而,从 HTTP 请求中得到的每个结果都是 HTTP 文本,其中包括许多 HTTP 标签和格式。为了看到纯粹的游戏描述,我们绝对需要删除它们。因此,我们在这里使用 python 的正则表达式。通过正则表达式对数据进行清洗后,得到了数据描述列。每个游戏的信息,后面是游戏描述。我们得到的一个清晰的描述是:

下一步,我们将使用这些游戏描述来提出我们的建议。诚然,这里的游戏描述是代表“内容”的。

由于基于内容的模型与这些内容文本相联系,它与自然语言处理领域有一些内在的联系,我们将在这里重点介绍一个基本的自然语言处理模型 TF-IDF,它专注于内容文本中每个单词的权重。每个单词的权重将不仅通过其在该内容文本上的频率来加权,而且通过所有文本集的频率来加权,并且 TF-IDF 的算法是:

https://www . search engine journal . com/TF-IDF-can-it-really-help-your-SEO/331075/

以下是每个游戏描述示例中每个单词的 TF-IDF 值:

TF-IDF 值格式

在我们得到每个单词的 TF-IDF 值后,这里使用线性核来计算这个游戏的描述 TF-IDF 权重和其他游戏的描述 TF-IDF 权重。由于 python 中的 Tf-IDF 矢量器会产生一些“文本中的单词权重”矢量,下图显示了这些矢量的一个示例,这里我们有一个包含两个文本的文本:“这是非常奇怪的非正式形式,这非常好”,如图所示,第一个数字是文本编号,第二个数字是这个示例文本集中单词的编号。然后就是这个词在这篇课文里的 TF-IDF。这里将使用值线性核来乘以这些向量。线性核的基本原理是:如果有两个维数相同的矩阵,这些矩阵中相同位置的一些大值会使它们的乘法结果在线性核计算的最终矩阵中仍然很大。

然后我们会把线性核计算出来的这些结果做一个序列,如果结果高,我们会把它们作为这个游戏最相关的推荐。这里我们列出了 10 大推荐。

基于内容的 10 大推荐

推荐结果在主观和客观上都比较激进,比如对于游戏《传送门 2》,最相似的游戏是自己,然后是《传送门 1》,反之亦然。同样,对于游戏《传送门 2》的其中一个推荐《Left 4 Dead 2》,我们也可以看到另一个推荐是《Left 4 Dead》。这是一个有趣的现象,因为对于一个游戏的所有推荐,这些推荐在人类认知中仍然彼此具有内在的关系。

第四部分:协同过滤推荐

数据获取
我们通过随机搜索用户的 steam 名称(也就是说我们假设了一些任意的名称,比如“43”等)来获得这些链接。)并将他们的 steam ids 与网站格式放在一起。然后我们得到所有这 10 个链接,包括用户的个人资料。https://steamidfinder.com/该网站将通过粘贴 Steam_ID 或一个随机的用户名让我们访问用户的个人资料,我们需要这样做,因为有时我们无法在 Steam 网站上通过用户名访问用户。

用户的个人 steam 信息链接

然后我们使用 requests.get()通过这 10 个链接获取播放时间信息。

数据修改

然而,steam 网站和 steam API 上都没有关于这些用户持续评分的记录。实际上,在 Steam 平台上,用户只给出“推荐”或“不推荐”,也就是二元评价,正面和负面,即使在用户网站上,仍然没有一星到五星等连续评分的机制。为了获得关于用户-游戏交互的连续评分,我们必须假设一种用户游戏评分交互机制。因为用户对游戏的关注度可以通过游戏的播放次数来反映。我们可以假设播放时间是关于用户兴趣的相当有说服力的信息。

因此,这里我们假设游戏时间中位数是兴趣的一个非常重要的部分。为了比较平均游戏时间,我们将比较每个用户在该游戏上的平均游戏时间和所有用户在该游戏上的平均游戏时间,然后我们将使用算法将这两个平均游戏时间的比较分成从 1 到 5 的范围,这将帮助我们填写连续评分数据框。

至于用户玩一个游戏的平均时间,我将它们与这个游戏的用户总玩时间进行比较。考虑到大多数用户会给游戏一个正面评价,如果他们玩这些游戏的时间不是很长,他们仍然喜欢这个游戏,除非这个游戏相当糟糕,这里我们选择“永远前 100”,所以他们都是非常受欢迎的游戏,他们大多数都有相当高的正面率,超过 90%。因此,我给出了一个积极的评级标准。在本节中,我假设如果一个用户的游戏时间大于这个游戏所有用户的游戏时间中位数(游戏时间中位数)。我假设这个用户对这个游戏的评分是 5;如果用户的游戏时间小于中值游戏时间但大于中值游戏时间的 0.8 倍,则评级被假定为 4;如果用户的游戏时间小于中值游戏时间的 0.8 倍,但大于中值游戏时间的 0.5 倍,则评级被假定为 3;如果用户的游戏时间小于中值游戏时间的 0.5 倍但大于中值游戏时间的 0.1 倍,则评级被假定为 2;如果用户的播放时间小于 0.1 乘以中值播放时间,则评级被假定为 1。

由于该用户的档案列表中没有“不玩时间”游戏,我认为该用户没有表达他/她对该游戏的偏好,该游戏的评分为 0。

现在,我们有了从 1 到 5 的连续评级,并将它们与其他信息一起存储为数据帧格式,数据帧如下所示:

这是我们使用余弦相似度时,第 7 项的推荐结果。

第五部分:大规模推荐及结果评估

在这一部分中,我们仍然使用我们在第 4 部分中修改的数据。

在这一部分,我们将重点介绍大数据平台上的推荐,这次我们选择 Spark ALS 作为在大数据平台上运行的算法。Spark ALS 可以将每个输入会话放入一个特殊的数据结构 Spark RDD。在我们的项目中,我们使用一种输入数据格式,它由 User_id、game_id 和用户对这个游戏的评价组成。这三个特征将被视为 CSV 数据列,然后它们将被 spark 会话读取。在这一部分中,每个用户的播放时间数据,不能通过 Steam API 获得,因此,我们必须访问每个用户的个人资料,但是,对于那些没有设置他们的资料或使他们的资料私人化的人,我们不能从他们那里获得播放时间信息。因此,我们必须一个接一个地访问那些公共配置文件,并获得我们所需要的信息。因此,在这一部分中,数据集可能比先前建议的数据集小得多

火花 ALS

ALS 是一种矩阵分解算法,它将一个高维的用户-项目交互矩阵分解成两个低维矩阵,在这个用户矩阵中,行代表用户,列是潜在因素。在项目矩阵中,行是潜在因素,列代表项目。在论文[5]中,因式分解矩阵模型学习将评级矩阵因式分解成用户和项目表示,这允许模型为用户预测更好的个性化项目评级。

通过矩阵分解,不太知名的项目可以像流行项目一样具有丰富的潜在表示,这提高了推荐系统推荐不太知名项目的能力。我们使用基于隐式评级的交替最小二乘法(ALS)来构建推荐模型。

结果
对于 spark 推荐的结果,我们通过 user_id 和推荐次数设计了一个个性化的推荐,然后 part 会给出 Spark ALS 计算的关于该用户在这 10 款游戏上的模拟评分。如前所述,我们必须按照用户 ID 逐一查看 steam 网站上的每个公共用户资料,然后获取数据,因此数据集的容量不是很大。随着越来越多的用户的原始评分数据被输入到 Spark 工作流程中,该用户对 Spark 制作的热门项目的模拟评分将会更高,这些模拟评分按降序分组。

Spark ALS 制作的推荐结果数据框架

评估

在包含游戏评级的游戏推荐之后,我们使用 RMSE 作为我们推荐的结果评估。随着数据集的扩大,RMSE 评价将得到改善。这意味着我们的推荐会有更高的用户评分。

结论
在这个项目中,我们只使用了一些基本的技术来模拟一个推荐系统。一个成熟的推荐系统不仅由单一的技术组成,还包括商业策略。
由于实际情况混合了许多复杂的因素,我们构建了一个模型,使多种技术能够叠加。如果要完成一个更加完善的推荐系统,我们需要更多的探索和研究。

未来工作

在未来,我们将深入研究协同过滤及其在几个评估中的表现。一些复杂的算法,如 PCA 和 SVD 可以很好地补充我们的推荐系统。我们将考虑二元评级和连续评级的建议。然后,我们仍然希望对游戏描述数据使用更多的 NLP 文本分类。

感谢您的阅读!欢迎任何反馈。万事如意!

参考

[1]https://galyonk . in/some-things-you-should-know-on-steam-5 eaffcf 33218?gi=6052b30aa193

[2]https://towards data science . com/large-scale-jobs-recommendation-engine-using-implicit-data-in-py spark-CCF 8d F5 d 910 e

[3]https://spark . Apache . org/docs/2 . 2 . 0/ml lib-collaborative-filtering . html

[4]https://spark . Apache . org/docs/2 . 2 . 0/ml-collaborative-filtering . html # cold-start-strategy

[5]https://towards data science . com/prototyping-a-recommender-system-step-by-step-part-2-alternating-least-square-als-matrix-4a 76 c 58714 a 1

[6]https://towards data science . com/python-data-预处理-使用-熊猫-data frame-spark-data frame-and-考拉-dataframe-e44c42258a8f

调查性新闻的偷拍:一把双刃剑

原文:https://towardsdatascience.com/steeling-faces-for-investigative-journalism-a-double-edged-sword-8d7d3719ad5?source=collection_archive---------53-----------------------

人脸识别技术的开源研究与验证介绍(上)

一个伪造的 VK 资料偷走了我的脸,可以通过 FindClone 发现

偶然发现了自己的脸。我注册了 FindClone.ru,这是一项俄罗斯服务,允许任何有电话号码的人搜索 VK 社交媒体账户的个人照片(俄罗斯的脸书)。你提供一张照片,他们会告诉你照片是谁。

FindClone 在新闻调查中非常有用。我用它来工作。王高·托勒在他给 Bellingcat 的曝光中提到过它(看它的行动。Bellingcat 俄国问题负责人克里斯托·格罗泽夫用它揭露了一名 GRU 黑客的身份。

我想知道 FindClone 在我自己的脸上有什么可以提供的。我上传了一张旧的个人资料图片,看,有一个匹配。有人偷走了我的脸,把它变成了他们的。

有趣的是,我的出生日期与模仿者使用的日期相差不远(但年份完全错误,真实的我更年轻,眨眼)。还有,模仿者说他是单身,我不是。叶夫根尼甚至有了一个追随者,一个名字为埃琳娜·阿贡科娃的账户,她因违反 VK 的条款和条件而被屏蔽(我想知道那个账户是否也是假的)。

这位叶夫根尼 T10 使用的我的图像是在伦敦南岸的英国 BFI 拍摄的。就是左上方那个,穿白领衬衫的我(周围有浅绿色圈)。我用一个英国电话号码注册了 FindClone,添加了我的照片,直到出现了一些建议。有一个真正的阳性匹配和一些奉承的假阳性。例如,我与波拉特(第 7 排,来自电影海报图片)和瑞安 _ 雷诺兹(第 5 排,来自古龙水包装盒)的脸匹配。

我用一个电话号码注册了 FindClone,添加了我的图片。有一个真正的阳性匹配和一些奉承的假阳性。我被配上了波拉特(第 7 排)和瑞安 _ 雷诺兹(第 5 排)的脸

有人偷了我的照片,我并不沮丧,但我认为这仍然是不可思议和不道德的。更令人恼火的是,FindClone 的面部识别算法将我与波拉特和瑞安·雷诺兹匹配起来(他们两个我都不喜欢)。

作为一名对虚假信息和假新闻感兴趣的调查记者,我对 FindClone 和面部识别的潜在价值很感兴趣。

警察用面部识别软件监视我们。作为道德调查记者和公民,我们现在可以密切关注他们(当然,只能在合法的范围内)。

在线冒充有多普遍,尤其是在虚假的社交媒体账户中?很常见。典型的服务挣扎。像 Tinder 这样的在线约会服务做得最多。虚假的个人在平台之外撒谎。脸书收紧了使用真实身份的要求。

脸书重新注册时的注意事项(2018 年出台的新名字政策,不允许使用假名字)。更多信息点击这里

作为一名调查记者,建立一个欺骗账户是在收集到足够的信息之前保持不被发现的一种方式(这也相当常见)。当研究一个有争议的故事时,保持低调会有所帮助,直到你的包里有足够的证据给你的编辑。

当你这么做的时候,帮你自己一个忙,在选择一个假的个人资料/名字/图片(或者根本没有图片)的时候要有创造性。作为调查记者,我们仍然必须尊重他人的隐私。

股票图像配置文件

用股票图片伪造社交媒体个人资料非常普遍。让我们想象一下,我们被迫用假身份报名参加 VK。错误的做法是使用免费股票图片平台的股票图片,如 Dreamstime(我希望你能得到更广泛的点击,这里。不要做)。这是假账户中的一个流行选项。

FindClone 可以对我们的调查有所帮助。让我们搜索“猛男垃圾背景男性时尚”。我知道,很具体。但是请原谅我。我们在屏幕上看到这个人,一个面部特征鲜明的金发男模特。

在免费股票图片平台 Dreamstime 上搜索。一个照片模型出现了(我这样做是因为我知道 VK 有很多假冒这个人的假账户)。在你寻找和描写谁的时候要合乎道德。

让我们前往 FindClone 并上传模特的图片。

你看到我看到的了吗?这家伙不仅是一个受欢迎的股票图像模型。大量可能是虚假的账户利用他的脸来冒充(虚假)身份。如果你正在调查虚假信息和虚假社交媒体账户——你发现了一系列最近建立的 Twitter 账户,你想检查一下——比较股票照片可能会给你第一手线索。

这是因为模仿者和恶作剧者也可能只是懒惰的人类(除非他们不是人类或懒惰)。

一名伊朗秘密特工的假资料(来源:SECUREWORKS)

一个简单的面部检查可能有所帮助的著名例子是 Mia Ash 的案例。这是一个假的女性资料,结果是一个伊朗黑客。伪装得很差,但很好(我知道这一点,因为我调查了当时的情况,并采访了 SecureWorks 的专家)。

参与此案的专家表示,“黑客组织不辞辛苦地建立一个如此长时间运行的、有血有肉的角色”是很罕见的。但是,如果与其他公开来源的数据相比,这些图像可能很容易引起争议。

通过搜索我收到的男性股票模型的 VK 帐户结果,我们找到了一张,似乎是我们男人的真实私人照片。它显示他和两个熟人或朋友在一起。我们可以分析背景来检查图像是在哪里拍摄的。我忍住了,因为我尊重这个家伙的隐私,他没做错什么。

俄罗斯社交媒体平台 VK 上的一名男性股票模特(左)和朋友们在一起

简而言之,FindClone 非常强大,可以支持对可疑帐户的验证。这对于虚假社交媒体账户分析非常有用。我最近遇到了一个案例,一个声称对我的工作感兴趣的客户找到了我。他或她只在 Linkedin 上与调查记者交朋友,没有任何记录(无论是在新闻方面,还是在任何其他方面),并且几乎与另一个同名、相同教育背景、来自相同地区的账户完全匹配。给账号背后的人指出来之后(我们聊了一会儿),这个账号就在平台上神秘消失了。巧合吗?有可能。但是机会是如此的渺茫。值得谨慎。

一个名为 Robinson Zhang 的人伪造了 Linkedin 个人资料帐户,他说他在 R&C 资本公司工作,“一家总部设在香港的国际咨询公司”(纽约时报报道)

有证据表明,Linkedin 成为间谍机构招募特工的首选工具。《纽约时报》的一项调查发现,有证据表明中国特工利用该平台联系外国公民,其中也包括前政府官员。但是要小心,误报的可能性总是存在的(Linkedin 上有一大堆其他罗宾逊·詹的个人资料)。

为开源调查创建自己的面部识别系统有多容易?

这太简单了,简单得令人害怕。让我们更进一步,从我通过 FindClone 找到的图像(在我身上)建立一个面部识别数据库。让我们假设你遇到了一张新面孔,并想检查它是否与你的人的图像数据库中的条目相匹配(这是我第一次上传到 FindClone 的我自己的图像)。

我很快从 FindClone 结果中截取了 23 张图片。第 24 个是我知道是我的那个(被叶夫根尼·普利什金偷走)。

我们快速安装 一个叫做 face_recognition 的 python 库。这是目前最简单和最容易的孩子玩即插即用的面部识别软件。

我们运行以下命令,将 FindClone 搜索结果中的图像(FindClone 中的“known_images”文件夹)与“new”图像(My_Image 文件夹中的 my image)进行比较。

$ face_recognition。/known_images 文件夹/。/My_Image 文件夹/

当我运行这个命令时,我得到了五个选项。一张是假冒的 VK 社交媒体账户从我这里偷走的脸。其他的都很接近。换句话说,我们将可能的 me 的命中列表减少到了一堆可以看到的帐户。

如果您使用成百上千个可能匹配的图像进行调查,并且想要减少嫌疑人的列表,这可能会很有用。

我得到了 Ben_New(上传的图像)和 Ben(数据库中的图像)之间的正确匹配

仅供参考(可以说是一个愚蠢的标题,引用了 1982 年詹姆斯·邦德的电影)

在我的 Medium 账户上,我出现了一张照片,照片中我的半张脸被一条鲜红色的条纹遮住,这是我在公共场合戴口罩的承诺。

如果我们对来自我的媒体账户的图片和其他五张图片(来自谷歌图片的随机媒体)进行测试,这个系统足以产生匹配。

这个算法足够复杂,可以定位我扔给它的五幅图像中的两幅。

甚至连眼镜都不重要

事实上,眼镜和口罩并不是匹配人脸的大障碍,我不必解释这对于#OSINT 调查来说是多么不可思议的强大(同样,对于执法领域来说也是如此)。

想象一下,对于一个戴着口罩或留着大胡子的人,你只能从糟糕的视频片段中获取一个图像。你仍然可以将它与你的嫌疑人资料库中的一组图像进行匹配。

“胡子、青春、帽子”测试

让我们看看胡子是否重要。我也有一张我年轻得多的照片。头饰像帽子一样重要吗?

面部识别匹配各种干扰因素

我戴着帽子的图片很容易与我从网上得到的另一堆图片匹配。

冬帽形象搭配我戴鹿角的和留胡子的。

胡须的形象与戴着冬帽的形象相匹配

我十岁时的形象无人能比。这稍微限制了#OSINT 调查的使用。但是总有变通的办法,比如让人变老(一个在线工具叫做 C hangemyface ,例如,如果你正在寻找一个年长的人,但是你手头只有一张他们年轻时的照片)。

我的自画像与那堆照片中的错误图像匹配,但它仍然是匹配的

其他发现:我找不到穿蓝色西装的自画像的直接匹配(要么是验证我糟糕的绘画技巧,要么是人工智能的问题?,我不确定)。但它确实为自拍和戴眼镜的黑白照片找到了匹配。

这要么是难以置信的好,要么是难以置信的坏。python 库声称,它在 Wild benchmark(这是一个用于人脸验证的公共基准,也称为配对)中的标记人脸上具有 99.38%的模型准确率。

我注意到,一般来说,系统很难匹配有胡子的人。同样,如果你在网上搜索一些去除胡须或添加胡须的方法(我可以想象,化妆也有类似的例子。您可以在某些地方将其添加到图像中)。

此外,如果您的图像得到多个匹配,可以增加或减少容差值,以使面部比较更严格/不严格。你甚至可以计算“面部距离”,以防你采用数据驱动的方法。还有吨的其他例子。我建议您仔细阅读它们,以防在您的 OSINT 调查中偶然发现一个特定的用例(再次强调,当您这样做时,请站在道德的角度)。

例如,您可以运行一个视频,当 python 库在您的存储库中找到一个熟悉的面孔时,它会提醒您。如果你有一个很长的视频,比如人群中的示威者或警察,这可以节省你大量的工作(一个漂亮的视频讲解器提供了这个教程,展示了如何用 python 库操作相机)。

布法罗警察部队案件

6 月 4/5 日,新闻媒体报道称,一名和平的老年抗议者被布法罗警察推搡,摔倒在地,开始流血。这是一起不必要的、无法形容的警察暴行。在撰写本报告时,受害者仍处于危急状态。

两名警官被停职,两名警官现在被指控犯有重罪袭击。两名警官被认出,一名被记者认出,因为他制服上的姓名标签在录像中清晰可见(亚伦·托加尔斯基)。但还有第三个官员,他也是整个视频的关键人物(视频是由当地电台 WBFO 拍摄的)。

第三名军官的姓名牌仍然未知:更新:姓名牌应该是“J. LOSI”

当他跑向另外两个警察时,他是进入现场的一个人,似乎在帮助推那个抗议者。

他也是那个将试图跪下来帮助/检查流血抗议者状况的警察拉回的人。在他的头盔上,这位警官写了“PL1”。

该视频迅速火了起来。这位官员的形象非常模糊。让我们看看 python 系统是否可以将 Robert McCabe(一号警官)和 Aaron Torgalski(二号警官)的面部——由伊利县地方检察官办公室提供——与第三名警官进行匹配。

面部识别算法正确地指出了第三名警官(仍未确认身份)和另外两名警官之间的区别(纽约时报发布的照片)

正确:前两个被指控的警官和第三个不匹配

我们还可以在手头的视频上测试面部识别算法,测试另一张模糊的图像。事件发生后,有一张照片是从不同的角度拍摄的,我推测是记者/摄影师拍摄的。

很明显是同一个人(J. Losi)。但是想象一下对比图像来自一张模糊的 Instagram 或脸书照片(仅供参考,我检查了整个水牛城警察局的 Instagram 和脸书账户,这些家伙不在那里。在他们的网站上,也没有这个人的照片。如果你有线索,请联系我。

我们将一位摄影师拍摄的图片(左图)与视频截图(右图)进行比较

该算法能够进行正确的连接。

我们看到面部识别算法在一群同事中找到了合适的警察

我们现在看到了面部识别软件有多么强大,我们可以自由和无限制地使用它。我们测试了它在不同方面的表现以及存在的问题。现在是时候做你自己的新闻调查了。

更新:

这个故事的快速更新。第三个军官,名字标签不可读的那个,叫约翰·洛西。名牌上写着 j .洛西。这位警官也出现在另一张照片中,他正和其他警官一起跪下。让我们快速检查一下算法是否能从视频中识别出他。

我们找到匹配的了。尽管有头盔,该算法可以将 Losi 从视频锁定到其他图像。

澄清:我想强调的是,这一分析并不是要指责第三名警官(尽管,很明显,他拉起了他的同事——他打算检查受害者——警官罗伯特·麦凯布,让他继续前进)。从视频中无法直接看出 Losi 是否有意推搡受害者。他本可以首先阻止罗伯特·麦凯布推被害人。我不是来评判这个的。所有这些工作表明,确认身份和面孔之间的联系并使这一过程自动化是可能的。

结论:一把双刃剑

很明显,这类软件需要进行一些道德斗争。将这样一个强大的工具放在罪犯或任何怀有恶意的国家黑客和机构手中(或计划继续限制记者)是很危险的。

但是,对于开源调查,我们需要务实,我们已经看到了该系统在哪些方面以及如何表现出色。

令人担忧的一面:可怕的是,任何人都可以根据自己的意愿构建面部识别系统。从公共网站(如社交媒体平台)收集数据从来都不是一件难事。但是专业人士可以扩大规模。这是个问题。

社交媒体公司试图让任何人都更难从社交媒体账户上窃取图像和个人信息。

脸书现在明确地在他们的 robots 文件(该文件告诉搜索引擎爬虫可以或不可以从脸书请求哪些页面或文件)的开头警告你。上面写着“除非你有明确的书面许可,否则爬脸书是禁止的。”

Instagram 以图像为主,与我们在帖子中谈到的面部图像识别设置相关。其他#OSINT 专家(特别是杰克·克雷普斯)提到了 Instalooter ,一个抓取 Instagram 图片的工具。我不确定它是否还在运行,但是如果你在办案的话,它可能会有所帮助。

专家指出,除了 2018 年脸书的数据封锁,Instagram 还受到了数据访问限制,使其不那么可靠(再次强调,如果你这样做,保护人们的隐私,保持理智)。

GDPR 也值得考虑。专家强调,如果你试图从社交媒体平台上抓取个人数据,被起诉的几率会增加。你,一个守法的侦探,不应该对此掉以轻心。在欧盟,个人必须给你许可(明确同意)。否则,在 GDPR 治下搜集欧盟居民的个人数据是非法的。

但我们不要自欺欺人。如果专业机构或精通技术的黑客想在社交媒体上保存图片,总有办法做到(我们记者应该密切关注这种操作)。

FindClone 的更多信息:FindClone 是一个相当温和的在线面部识别应用程序版本。它取代了一个专业(也更令人担忧)的选项,一个叫做 SearchFace 的服务。过去,SearchFace 为有问题的角色提供了一个平台,告知出演色情电影的女性的家人,分享她们的秘密。这是不道德的,充其量是不道德的。肇事者这样做是为了引起“道德上的愤怒”,声称性行业的女性是腐败和欺骗性的。“有人可以利用这样一项服务来轻易攻击无辜的人,这令人深感担忧。

作为用户服务的 SearchFace 去年被关闭,但此后其背后的组织似乎又活跃起来。它现在正在积极推广其追捕新冠肺炎锁定破坏者的能力,这是另一个潜在的问题/不道德/不道德的努力。

广告声称,NtechLab 解决方案的算法在识别违反隔离的人方面表现出了很大的有效性,同时跟踪潜在传染性和及时通知各自当局之间的社会互动。

我不同意他们的观点,即面部识别应该商业化,以追捕那些违反封锁规则的人。这是一个调查记者可能想要更深入研究的话题。

感谢你阅读这篇文章。如果你有问题/想法/意见,请通过我的质子邮件账户联系:techjournalism11@protonmail.com

自然语言处理中的词干,是什么?

原文:https://towardsdatascience.com/stemming-of-words-in-natural-language-processing-what-is-it-41a33e8996e2?source=collection_archive---------13-----------------------

词干提取是几乎所有自然语言处理(NLP)项目中最常见的数据预处理操作之一。如果你是这个领域的新手,即使你遇到过这个词,你也可能不知道这是什么。您可能还会混淆词干化和词汇化,这是两种类似的操作。在这篇文章中,我们将通过一些例子来看看词干到底是什么。我希望我能用简单的语言为你解释这个过程。

堵塞物

简单来说,词干化就是去掉一个词的一部分,或者说把一个词简化为它的词干或者词根的过程。这可能不一定意味着我们将一个单词减少到它的字典根。我们使用一些算法来决定如何砍掉一个单词。在很大程度上,这就是词干化与词干化的不同之处,词干化是将一个单词简化为它的词典词根,后者更复杂,需要非常高的语言知识水平。我们可能会在另一篇文章中讨论词汇化。在这篇文章中,我们将坚持使用词干并看几个例子。

假设我们有一组单词—发送、已发送和正在发送。这三个单词都是同一个词根的不同时态。所以在我们词干之后,我们将只有一个词——发送。类似地,如果我们有单词——ask、ask 和 asked——我们可以应用词干算法来获得词根— ask 。词干就是这么简单。但是(总有但是),很遗憾,没那么简单。我们有时会有并发症。而这些并发症被称为过梗欠梗。让我们在接下来的章节中了解更多。

过度堵塞

过度词干化是一个过程,其中一个单词的大部分被砍掉,超过了所需的部分,这反过来导致两个或更多的单词被错误地缩减为同一个词根或词干,而它们本应被缩减为两个或更多的词干。比如大学宇宙。一些词干算法可能会将两个单词都简化为词干 univers ,这意味着两个单词的意思相同,这显然是错误的。因此,当我们选择词干提取算法以及尝试优化模型时,我们必须小心谨慎。你可以想象,词干下是相反的。

底部堵塞

在词干提取中,两个或多个单词可能被错误地简化为多个词根,而实际上它们应该被简化为同一个词根。例如,考虑单词“数据”和“基准”有些算法可能会把这些词分别简化为 datdatu ,这显然是错误的。这两者都必须简化为同一个词干 dat 。但是试图优化这样的模型可能会反过来导致词干过多。所以我们在处理堵塞时必须非常小心。

我希望这有助于理解什么是词干以及词干的两种不同的错误。如果对此还有任何困惑,请在下面的评论中告诉我,我会尽力消除你的任何疑问。

原载于 2020 年 2 月 19 日我的 个人博客

词干化与词汇化

原文:https://towardsdatascience.com/stemming-vs-lemmatization-2daddabcb221?source=collection_archive---------2-----------------------

将单词截断到其词根或基本单位

词干化和词汇化是自然语言处理领域中的文本规范化技术,用于为进一步处理准备文本、单词和文档。在这篇博客中,您可以通过一种非常实用的方法来研究词干化和词汇化,包括词干化和词汇化的背景、应用,以及使用 Python nltk 包(Python 提供的自然语言包)对单词、句子和文档进行词干化和词汇化的方法

在自然语言处理中,你可能希望你的程序承认单词“kick”和“kicked”只是同一个动词的不同时态。这可以是将不同种类的单词简化为核心词根的概念。

堵塞物

词干化是产生词根/基本词的形态变体的过程。词干程序通常被称为词干算法或词干分析器。

通常,当搜索文本中的某个关键词时,如果搜索返回该词的变体,会有所帮助。例如,搜索“船”也可能返回“船”和“划船”。在这里,“boat”将是[boat,boater,boating,boats]的词干。

词干法是对相关单词进行编目的一种有些粗糙的方法;它基本上是从字母的末端开始,直到到达词干。这在大多数情况下工作得相当好,但不幸的是,英语有许多需要更复杂过程的例外。事实上,spaCy 没有包含词干分析器,而是选择完全依赖于词汇化。

波特·斯特梅尔

最常见也是最有效的词干提取工具之一是马丁·波特在 1980 年开发的波特算法。该算法采用了五个阶段的单词缩减,每个阶段都有自己的一组映射规则。在第一阶段,定义简单的后缀映射规则,例如:

*# Import the toolkit and the full Porter Stemmer library*
import nltk

from nltk.stem.porter import *p_stemmer = PorterStemmer()words = ['run','runner','running','ran','runs','easily','fairly']for word in words:
    print(word+' --> '+p_stemmer.stem(word))

输出

run --> run
runner --> runner
running --> run
ran --> ran
runs --> run
easily --> easili
fairly --> fairli

注意词干分析器如何将“runner”识别为名词,而不是动词形式或分词。此外,副词“容易地”和“相当地”源于不寻常的词根“easili”和“fairli”

雪球斯特梅尔

这有点用词不当,因为 Snowball 是由 Martin Porter 开发的词干语言的名字。这里使用的算法更准确地称为“英国斯特梅尔”或“斯特梅尔”。它在逻辑和速度上都比最初的 Porter stemmer 稍有改进。由于 nltk 使用名称 SnowballStemmer,我们将在这里使用它。

from nltk.stem.snowball import SnowballStemmer

*# The Snowball Stemmer requires that you pass a language parameter*
s_stemmer = SnowballStemmer(language='english')words = ['run','runner','running','ran','runs','easily','fairly'for word in words:
    print(word+' --> '+s_stemmer.stem(word))

输出

run --> run
runner --> runner
running --> run
ran --> ran
runs --> run
easily --> easili
fairly --> fair

在这种情况下,词干分析器的表现与波特斯特梅尔相同,只是它用“fair”更恰当地处理了“fairly”的词干

词干有它的缺点。如果给定了标记 saw,词干化可能总是返回 saw,而词汇化可能返回 see 或 saw,这取决于标记是用作动词还是名词

词汇化

与词干化相反,词汇化不仅仅是减少单词,而是考虑一种语言的全部词汇,对单词进行词法分析。“was”的引理是“be”,“mice”的引理是“mouse”。

词汇化通常被认为比简单的词干提取更能提供信息,这就是 Spacy 选择只使用词汇化而不使用词干提取的原因

词汇化查看周围的文本来确定给定单词的词性,它不对短语进行分类。

*# Perform standard imports:*
import spacy
nlp = spacy.load('en_core_web_sm')def show_lemmas(text):
    for token in text:
        print(f'{token.text:{12}} {token.pos_:{6}} {token.lemma:<{22}} {token.lemma_}')

这里我们使用一个 f 字符串通过设置最小字段宽度和添加 lemma 哈希值的左对齐来格式化打印的文本。

doc = nlp(u"I saw eighteen mice today!")

show_lemmas(doc) 

输出

I            PRON   561228191312463089     -PRON-
saw          VERB   11925638236994514241   see
eighteen     NUM    9609336664675087640    eighteen
mice         NOUN   1384165645700560590    mouse
today        NOUN   11042482332948150395   today
!            PUNCT  17494803046312582752   !

请注意,“saw”的引理是“see”,“mice”是“mouse”的复数形式,然而“18”是它自己的数字,而不是“8”的扩展形式。

结论

关于引理化需要注意的一点是,用一种新语言创建一个引理化器比用词干算法更难,因为在引理化器中我们需要更多关于语言结构的知识。

词干化和词元化都产生词尾变化单词的基本分类,因此唯一的区别是词干可能不是一个实际的单词,而词元是一个实际的语言单词。
词干提取遵循一种算法,对单词进行分步处理,这样速度会更快。然而,在词汇化中,你也使用语料库来提供词汇,这使得它比词干化慢。此外,你可能必须定义一个词类来得到适当的引理。

以上几点表明,如果速度是集中的,那么应该使用词干,因为词条分类器扫描语料库会耗费时间和处理。这取决于您正在处理的问题,它决定了应该使用词干分析器还是词法分析器。

感谢何塞·波尔蒂利亚在整个期间给予的帮助

注意 GitHub repo 中给出了所有解释的代码,并提供了更多示例,以增强您的知识并更好地掌握这个主题。此外,关于停用词和词汇的额外概念也包括在内。点击下面的链接:-

[## jn aditya-beri/词干化 vs .词汇化

通过在 GitHub 上创建一个帐户,为 aditya-beri/Stemming-vs-lemma 化开发做出贡献。

github.com](https://github.com/aditya-beri/Stemming-vs-Lemmatization.git)

这只是对什么是词干化和词汇化以及它们如何工作的一个小小的窥探。如有任何疑问和澄清,请随时回复本博客。

使用 Azure 在云上部署 ML 模型的分步方法

原文:https://towardsdatascience.com/step-by-step-approach-of-deploying-ml-model-on-cloud-with-azure-b7139cde7683?source=collection_archive---------36-----------------------

详细解释了如何使用 Flask app 将 GitHub repo 链接到 Azure 来部署 ML 模型

照片由 Waldemar Brandt 在 Unsplash 上拍摄

耶!!我建立了我的第一个 ML 模型,接下来我要做什么??我如何以及在哪里部署它?🙄

任何绝对的初学者在构建他们的第一个机器学习模型后都可能会遇到上述问题,本文将揭开如何在云上部署模型并实时检查结果的神秘面纱。

在这里,我将向您介绍一种在 Azure 上部署模型的可行方法,一旦您获得了 web 应用程序的 URL,您就可以与任何人共享它,它将全天候运行在服务器上😎

如今有了各种各样的工具,有许多不同的方法来部署一个模型。下面是我们将在本文中使用的工具。

下面是我们将要执行的步骤。

👉第一步:创建一个 ML 模型

这里我们关注的是部署的步骤,而不是训练模型的步骤。因此,我采用了一个样本数据,并在 Jupyter Notebook 中建立了一个线性回归模型。目的是当收入和家庭规模为独立变量时,预测每月的食品杂货支出。

完成线性回归模型后,将其另存为。pkl 文件以如下二进制模式写入。对于完整的数据集(Expenses_Prediction.csv)和代码(LR_Model.py),点击此处

pickle.dump(lr_model, open(‘E:\\lr_model.pkl’,’wb’))

👉第二步:创建 HTML 表单

为了预测费用,我们需要从表单中提供的新输入值中收集数据,然后使用我们的线性回归模型来预测输出,并在表单中显示结果。因此,我们正在创建一个简单的 HTML 表单,它将在浏览器中显示如下。

你可以在这里找到代号为 index.html 的代号

👉第三步:创建烧瓶应用

Flask 是一个用于在 Python 中构建 web 应用的框架。为了托管 HTML 表单,我们需要创建 Flask web 应用程序。要安装 Flask,请使用命令! pip 安装烧瓶

下面是理解 flask app 代码的快照,该代码名为 app.py。你可以在这里获得代码

将所有文件放在同一个文件夹中,您就可以在本地系统中测试这个 web 应用程序了。打开 Anaconda 提示符,进入 files 文件夹,输入 python app.py

复制网址( http://127.0.0.1:5000/ )并粘贴到你的网络浏览器中,点击回车。一旦提供了输入值,就可以预测费用。

如果您能够做到这一点,现在是时候在云上部署 web 应用程序了。

👉步骤 4:创建配置文件。

我们需要创建以下两个配置文件来继续部署。

Procfile:在 Procfile 中提到下面单行代码,这个文件不应该有任何扩展名。这是将要首先执行的文件。它使用 Gunicorn,这是一个用于 WSGI 应用程序的纯 Python HTTP 服务器,它充当 web 应用程序和 web 服务器之间的纽带。确保保存的文件没有扩展名。

requirements . txt:在此提及你所有的库及其依赖关系。txt 文件及其版本如下。

👉第五步:在 GitHub Repo 中提交文件。

GitHub 中创建一个帐户,并将所有文件上传到一个存储库中。如果您以前没有创建过存储库,请查看这里的内容

请确保将您的 index.html 放在模板文件夹中。你可以从我的 GitHub [ 这里 ]查看文件

👉第六步:将 GitHub Repo 链接到 Azure 并部署。

使用链接[ 此处 ]在 Azure 中创建您的免费帐户。

按照以下步骤将 GitHub repo 链接到 Azure

登录后,点击“应用服务

点击添加。如下填写 Web 应用程序中的详细信息。创建一个新的“资源组”。在实例详细信息中输入“名称”。点击审核+创建

点击创建后,你会看到下面的消息。点击“转到资源”。

点击左侧窗格中的部署中心

点击 GitHub 。第一次连接 GitHub,Azure 会要求授权。连接后,点击继续。

点击“应用服务构建服务”并继续。

在代码部分,“组织”会在连接 GitHub 后自动更新。选择所需的储存库并继续。

单击完成。

这将需要几分钟的时间来完成,同时您会看到状态为正在运行

完成后,您将看到状态为“成功”。点击左侧窗格中的概述

从右上角复制“ URL ”并粘贴到您的网络浏览器中。

你可以看到这个网址是用 Azure 域创建的。提供输入值并单击预测按钮。你可以看到预计的费用。

又来了,耶!!你的机器学习模型现在运行在云上。👍

总结

本文的目的是让您轻松理解部署,谁正试图迈出在云中部署模型的第一步。稍后,您可以探索各种方法,比如为自动部署创建管道,以及在云上训练模型,等等。作为数据科学专业人员,应该了解运行模型的端到端方法。

你可以从我的 GitHub 档案中获得完整的代码和文件

感谢阅读,快乐学习!🙂

逐步 AWS EC2 设置教程

原文:https://towardsdatascience.com/step-by-step-aws-ec2-set-up-tutorial-eae94213fd15?source=collection_archive---------33-----------------------

本文非常简单地介绍了设置 AWS EC2 实例的过程。我们会经历

  1. 实例初始化。
  2. 安装必要的软件和机器学习包。
  3. 将文件从本地文件传输到远程实例

对 AWS EC2 的快速解释将有助于我们了解我们在做什么。亚马逊弹性计算云(EC2)是亚马逊云计算平台亚马逊网络服务(AWS)的一部分。AWS 允许人们租用虚拟计算机来运行他们自己的程序和应用程序。AWS“实例”是一个虚拟机,由用户启动,并配置有任何所需的软件。用户可以根据需要创建、启动和终止他们的服务器实例,按秒为活动服务付费,并指定他们的代码部署和数据存储的地理位置,因此有了术语“弹性”

通过 Pixabay 将图像放大 200 度

1.设置 EC2 实例

首先,打开位于 https://console.aws.amazon.com/ec2/的亚马逊 EC2 控制台,点击“运行实例”。您应该会看到下面的页面出现。单击启动实例。

我笔记本电脑的截图

选择您想要使用的虚拟机类型。Amazon 机器映像是预先配置的虚拟机,充当您的实例的模板。

如果你是 Mac 用户,选择一个 64 位的 Linux AMI 是个好主意。

我笔记本电脑的截图

如果你知道你将在你的虚拟机上运行深度学习模型,那么就有专门针对这个目的的 ami。当然,可以设置基本的 Amazon Linux AMI 来运行这些相同的模型。

我笔记本电脑的截图

您还可以更改您的地理位置,以更改要部署的实例的位置。不同地理位置的价格会略有不同,我用的是 us-east-1。

接下来,选择实例类型来设置实例的存储和大小。T2.micro 默认设置为类型,符合亚马逊免费层的条件。我发现我总是在 t2.micro 实例上耗尽内存,所以要考虑需要多少内存。

接下来,单击 Review and Launch,让 AWS 向导为您设置默认配置。

我笔记本电脑的截图

接下来,检查您的实例,并根据需要修改安全组。点击启动!

我笔记本电脑的截图

您必须指定一个密钥对。如果您已经有了一个 AWS 密钥对,您可以选择使用那个密钥对。如果没有,您将选择创建新的密钥对。输入密钥对的任意名称。然后,单击下载密钥对。这将是您能够下载该密钥对的唯一时间。将它移动到某个安全的位置,或者某个你不会删除它的地方。您需要这个密钥对来允许您进入您的实例。就当是密码吧。现在,启动您的实例!

我笔记本电脑的截图

既然您的实例已经启动,接下来我们必须通过 SSH 连接到实例。在 EC2 实例仪表板上,单击实例名称旁边的按钮,然后单击 Actions。Actions 下应该会出现一个下拉菜单,然后单击 Connect。

我笔记本电脑的截图

您将看到此窗口,用于连接到您的实例。

我笔记本电脑的截图

打开“终端”并转到储存您的密钥对的文件夹。运行 chmod 命令来更改您的密钥对的权限。然后,运行 ssh 命令进入您的实例。每次重新启动计算机以进入实例时,都需要重新运行 chmod 命令来修改密钥对的权限。

2.软件安装

现在,简单的部分!接下来就是安装需要的软件和机器学习包,比如 Python3,Conda,Pytorch 等。从这里开始,我假设我们从基本的 Amazon Linux AMI 开始,因为深度学习 AMI 往往已经安装了这些包。

Yum 是 Amazon Linux AMI 上的默认安装程序。

$ sudo yum update 
$ sudo yum install emacs

要安装 pip,请使用:

$ curl https://bootstrap.pypa.io/get-pip.py -o get-pip.py
$ python3 get-pip.py

安装 Anaconda。

$ cd /tmpcurl -O [https://repo.anaconda.com/archive/Anaconda3-5.3.1-Linux-x86_64.sh](https://repo.anaconda.com/archive/Anaconda3-5.3.1-Linux-x86_64.sh) $ sha256sum Anaconda3-5.3.1-Linux-x86_64.sh $ d4c4256a8f46173b675dd6a62d12f566ed3487f932ba
b6bb7058f06c124bcc27 Anaconda3-5.3.1-Linux-x86_64.sh $ bash Anaconda3-5.3.1-Linux-x86_64.sh $ source ~/.bashrc (or open up a new terminal)

让我们得到 Numpy 和 Scipy。

conda update -n base -c defaults condaconda install numpy scipy

还有 Pytorch。

conda install pytorch torchvision -c pytorch

最后,Git!

sudo yum install git-all

现在,我们准备运行代码。

3.传输文件

要在本地目录和远程实例之间传输文件,可以运行

$ scp -i /path/my-key.pem /path/to/file [ec2-user@publicDNS.compute-1.amazonaws.com:~/path/to/location](mailto:ec2-user@publicDNS.compute-1.amazonaws.com:~/path/to/location)

然而,对于在特定的本地位置传输许多文件,我更喜欢使用 FileZilla。从 https://filezilla-project.org/下载 FileZilla。

在文件下,点击站点管理器。

我笔记本电脑的截图

在站点管理器窗口中,单击新建站点。将协议设置为 SFTP。将主机设置为您的公共 DNS。这个公共 DNS 可以通过进入 EC2 实例管理控制台,点击您的实例,并在描述框中复制公共 DNS (IPv4)下的条目。将端口设置为 22。用户将是 ec2 用户。最后,导航到本地计算机上保存的密钥对文件。单击连接。

我笔记本电脑的截图

现在,您可以将文件从本地文件拖到远程 EC2 实例。

我笔记本电脑的截图

输出文件同样可以通过 FileZilla 或 scp 传输回您的本地机器。

现在,您可以 SSH 到您的实例中,虚拟地运行您的所有代码!

资源:

1https://docs.aws.amazon.com/transfer/latest/userguide

使用 Plotly Express 的逐步条形图

原文:https://towardsdatascience.com/step-by-step-bar-charts-using-plotly-express-bb13a1264a8b?source=collection_archive---------25-----------------------

回答“我在看什么?”

布兰登·莫温克尔Unsplash 上拍摄的照片

作为一名有抱负的数据科学家,我喜欢摆弄数据集,解开隐藏在行和列背后的故事。我做的第一件事就是用条形图来显示数据。这让我熟悉了信息,并制定了未来分析的游戏计划。

如果您还不是会员,请在此获得您的中级会员资格!

数据集

我决定找一个简单的数据集,让我可以专注于绘图而不是清理。我发现“一见钟情结婚”数据集符合我的需求,因为它有一个健康的组合数字分类数据。这个电视节目已经成为一种隔离的罪恶快感。在这个系列中,两个人被随机配对,他们可以在一个梦想的地方度假三周后决定结婚与否。数据集可以在这里找到。

导入库

第一步是导入我将使用的所有库。是一个用于在 Python 中创建静态、动画和交互式可视化的库。 Plotly Express 是 Plotly v.4 的一个新的高级 Python 可视化库,允许使用简单的语法绘制复杂的图表。

一旦库被导入,我就使用 read_csv() 函数加载我的文件,并将其转换成熊猫数据帧。

import pandas as pd
import plotly.express as px
from plotly.subplots import make_subplotsdf = pd.read_csv("Data/mafs.csv")

让我们来看看数据框

当我有了我的熊猫数据框架后,我会做两件事。首先,我查看标题名和存储在每一列中的变量类型。

print(df.info())

图由作者提供

这告诉我,在我的数据集中有 17 列,一些存储' 对象 '类型,我喜欢把它们看作字符串,还有' int64 '类型,它们是简单的 64 位整数存储。

其次,我查看数据帧的第一行。

print(df.iloc[0])

通过将 index [0]改为任意整数,我也可以找到任意行的信息。

图由作者提供

这告诉我,在这个电视节目中,参赛者杰米·奥蒂斯-赫纳在比赛时 27 岁,职业是护士。更重要的是,这位选手在电视节目中决定结婚,至今仍是已婚。幸运的女孩!

“是对否”简单条形图

我的第一反应是绘制出同意结婚的人和愿意保持单身的人的数量。该信息可在“决策”栏中找到,该栏中的值为“是”或“否”。

df1 = df.groupby(["Decision"]).count().reset_index()

fig = px.bar(df1**,** y=df.groupby(["Decision"]).size()**,** x="Decision"**,** color='Decision')
fig.show()

通过使用 groupby() 函数,我能够对数据集中的行进行洗牌,以便按照决策结果对它们进行组织。剩下要做的唯一一件事就是选择 x 轴和 y 轴来产生所需的信息。

图由作者提供

从图表中可以清楚地看到,70%的参赛者在三周后决定结婚,这是一个惊人的高成功率。也许这就是这部剧已经播了 10 季的原因吧!

“每个地点的婚姻”堆积条形图

我想做的第二件事是看看地理位置是否会影响成功夫妇的数量。为此,我在 x 轴上标出了位置,在 y 轴上标出了“是”和“否”的数量。

df2 = df.groupby(['Location'**,**'Decision']).size().reset_index(name='Decision_qt')
df2_yes = df2[df2['Decision']=='Yes']
df2_yes.set_index('Location'**,** inplace=True)

fig = px.bar(df2**,** x="Location"**,** y="Decision_qt"**,** color='Decision'**,** barmode='stack')
fig.show()

同样,使用 groupby() 函数,我首先根据位置对我的行进行分组,然后进行决策,本质上是在一个组内创建一个组。我还创建了一个名为 Decision_qt 的附加列,它保存每个位置的“是”和“否”答案的数量。

图由作者提供

除了芝加哥和达拉斯(所有参赛者都决定在那里结婚!)我们可以看到,地点对情侣的成功率影响不大。在这一点上,我要补充的是,我们只在每个地点调查大约 6 到 12 个人,更大的样本量会产生更可靠的信息…

已婚与离异比率条形图

现在,接下来我想调查的是在节目中结婚后离婚的人数。为了绘制这个比率,我需要遵循三个简单的步骤。

准备第一个数据集

我创建了一个 dataframe ' df_married' ,它根据位置和状态对行进行分组。我还创建了一个额外的列‘Maried _ Qt ’,每行包含已婚人口的总数。最后,我修改这个数据集,只保留已婚参与者的行。

df_married = df.groupby(['Location'**,**'Status']).size().reset_index(name='Married_qt')
df_married = df_married[df_married['Status']=='Married']

准备第二个数据集

现在我想统计每个地点的参与者总数。这也是通过使用 groupby() 函数并使用 size() 函数对每个组中的行求和来实现的。

df3 = df.groupby(['Location']).size().reset_index(name='Participants_qt')

执行除法和绘图

为了执行分割,我们首先必须将两个数据帧的索引设置为位置(比率是在同一城市结婚和离婚的夫妇之间取得的)。除法的结果保存在名为“ ratio_Married ”的列中

# Division
df_married.set_index('Location'**,** inplace=True)
df3.set_index('Location'**,** inplace=True)df3['ratio_Married'] = (df_married['Married_qt'] / df3['Participants_qt'])# Plotting
df_married.reset_index(inplace = True)
df3.reset_index(inplace = True)
fig = px.bar(df3**,** x='Location'**,** y='ratio_Married'**,** color='Location'**,** barmode='stack')
# fig.show()

绘图时,从数据帧 df3 中分别在 x 轴和 y 轴选择数据帧对应的位置和比率列。

这个剧情没有前两个乐观。超过 50%同意结婚的夫妇后来离婚了。在亚特兰大和南佛罗里达,没有一个参赛者仍然和他/她的对手结婚…

分步子情节特征

这花了我一点时间才弄明白,这就是为什么我超级兴奋地分享!当试图比较和对比图或条形图时,创建支线剧情会非常有用。当东西放在一起时,潜在的关系可以很容易地显现出来。

为了制作一个有多个支线剧情的图形,第一步是指定支线剧情的数量和它们的位置。在我的例子中,我选择让我的数据在同一行不同列(并排)。类型“xy”表示坐标系(例如也可以是极坐标)。

subfig = make_subplots(rows=**1,** cols=**2,** specs=[[{"type": "xy"}**,** {"type": "xy"}]])

现在我们创建两个子图,指定它们的轴和值。

第一个副情节

这和文章开头的是对否条形图一样。需要注意的是,plotly express 只支持 series。这意味着我需要使用 pd 将我想要绘制的信息从熊猫数据帧转换成一个系列。系列() 功能

df4 = df.groupby(["Decision"]).size().reset_index(name='Total_YesNo')
y1=pd.Series(df4['Total_YesNo'])

subfig.add_bar(row=**1,** col=**1,** y=y1**,** x=["Yes"**,** "No"])

第二副情节

在第二张图中,我绘制了每个位置的是对否的比率。x 轴和 y 轴值被转换成序列,并传递到子图上进行绘制。

df5 = df.groupby(['Location']).size().reset_index(name='Participants_qt')
x2=pd.Series(df5['Location'])
y2=pd.Series(df3['ratio_YesNo'])

subfig.add_bar( row=**1,** col=**2,** x=x2**,** y=y2)
subfig.show()

结果!

Github 知识库

所有代码都可以在 Github 上的 Married.py 文件中找到

非常感谢你的阅读!

如果你喜欢我的作品,如果你能在这里跟随我,我将不胜感激。

如果您对如何改进有任何问题、建议或想法,请在下面留下评论或通过 LinkedIn 这里取得联系。

一步一步:建立一个有气流的数据管道

原文:https://towardsdatascience.com/step-by-step-build-a-data-pipeline-with-airflow-4f96854f7466?source=collection_archive---------2-----------------------

构建气流数据管道,以监控错误并自动发送警报电子邮件。故事提供了详细的步骤,并配有截图。

构建气流数据管道

每次我们部署新软件时,我们会每天检查两次日志文件,看看在接下来的一两周内是否有问题或异常。一位同事问我,有没有办法监控错误,如果某个错误出现 3 次以上,就自动发送警报。我现在正在跟踪气流过程,这是一个用气流构建数据管道来监控异常的完美用例。

什么是气流?

Airflow 是一个开源的工作流管理平台,它于 2014 年 10 月在 Airbnb 开始,后来被开源,在 2016 年 3 月成为 Apache 孵化器项目。气流设计遵循“配置即代码”的原则。1

在 Airflow 中,DAG(或有向非循环图)是您想要运行的所有任务的集合,以反映它们的关系和依赖性的方式组织。[2]

Airflow 使用 Python 语言创建其工作流/DAG 文件,对于开发者来说非常方便和强大。

分析

我们的日志文件保存在服务器上,有几个日志文件。我们可以通过 sftp 命令获取它们。将所有日志文件下载到一个本地文件夹后,我们可以使用 grep 命令提取所有包含异常或错误的行。以下是错误日志的示例:

/usr/local/air flow/data/2020 07 23/log in app . log:140851:[[]]23 Jul 2020/13:23:19196 错误 session id:u 0 ukvlfdnmsmicbuozo 86 LQ 8 ocu =[log in app]Dao。AbstractSoapDao-getNotificationStatus-服务异常:Java . net . sockettimeoutexception:读取超时

接下来,我们需要逐行解析错误消息并提取字段。和上面的例子一样,我们想知道文件名、行号、日期、时间、会话 id、应用程序名、模块名和错误消息。我们将把所有这些信息提取到一个数据库表中,稍后,我们可以使用 SQL 查询来汇总这些信息。如果任何类型的错误发生超过 3 次,它将触发发送电子邮件到指定的邮箱。

整个过程非常简单,如下所示:

监控错误日志的工作流

气流操作员

气流提供了很多有用的运算符。操作符是一个单一的任务,它提供了一种实现特定功能的简单方法。例如, BashOperator 可以执行 Bash 脚本、命令或命令集。 SFTPOperator 可以通过 SSH 会话访问服务器。此外,气流允许任务之间的并行,因为一个操作符对应一个任务,这意味着所有操作符可以并行运行。Airflow 还提供了一种非常简单的方法来定义任务之间的依赖性和并发性,我们将在后面讨论它。

履行

通常,气流在 docker 容器中流动。阿帕奇在 Docker Hub 发布气流图像。一张更受欢迎的气流图由 Puckel 发布,配置良好,随时可用。我们可以从 Puckel 的 Github 库中检索 docker 文件和所有配置文件。

安装 Docker 客户端并提取 Puckel 的存储库后,运行以下命令行启动 Airflow 服务器:

docker-compose -f ./docker-compose-LocalExecutor.yml up -d

第一次运行气流

第一次运行脚本时,它会从 Docker Hub 下载 Puckel 的 Airflow 镜像和 Postgres 镜像,然后启动两个 Docker 容器。

气流有一个很好的 UI,可以从 http://localhost:8080 访问。

气流 UI 门户

从 Airflow UI 门户,它可以触发 DAG 并显示当前运行的任务的状态。

让我们开始创建 DAG 文件。创建新的 DAG 非常容易。首先,我们定义一些默认参数,然后用 DAG 名称 monitor_errors 实例化一个 DAG 类,DAG 名称将显示在 Airflow UI 中。

实例化新的 DAG

工作流的第一步是从服务器下载所有日志文件。Airflow 支持运行任务的并发性。我们为一个日志文件创建一个下载任务,所有的任务可以并行运行,我们将所有的任务添加到一个列表中。 SFTPOperator 需要一个 SSH 连接 id,我们将在运行工作流之前在 Airflow 门户中配置它。

创建下载任务

之后,我们可以刷新 Airflow UI 来加载我们的 DAG 文件。现在我们可以看到我们的新 DAG - monitor_errors -出现在列表中:

气流中显示的新 DAG

单击 DAG 名称,它将显示图形视图,我们可以在这里看到所有的下载任务:

图表视图中的所有下载任务

在我们触发 DAG 批处理之前,我们需要配置 SSH 连接,以便 SFTPOperator 可以使用这个连接。点击管理菜单,然后选择连接来创建一个新的 SSH 连接。

创建 SSH 连接

要在不输入密码的情况下访问 SSH 服务器,需要使用公钥登录。假设公钥已经放入服务器,私钥位于 /usr/local/airflow/。ssh/id_rsa 。将密码字段留空,并将以下 JSON 数据放入额外字段。

{
  "key_file": "/usr/local/airflow/.ssh/id_rsa",
  "timeout": "10",
  "compress": "false",
  "no_host_key_check": "false",
  "allow_host_key_change": "false"
}

好了,让我们启用 DAG 并触发它,一些任务变成绿色,这意味着它们处于运行状态,其他任务保持灰色,因为它们在队列中。

任务正在运行

所有任务完成

当所有任务完成后,它们以深绿色显示。让我们检查下载到 data/ 文件夹中的文件。它将创建带有当前日期的文件夹。

所有日志都下载到该文件夹中

看起来不错。

接下来,我们将提取日志文件中包含“异常的所有行,然后将这些行写入同一文件夹中的文件(errors.txt)中。 grep 命令可以在一个文件夹的所有文件中搜索某些文本,也可以在搜索结果中包含文件名和行号。

Airflow 检查 bash 命令返回值作为任务的运行结果。如果没有发现异常,grep 命令将返回 -1 。Airflow 将非零返回值视为失败任务,然而事实并非如此。没有错误意味着我们都很好。我们检查 grep 生成的 errors.txt 文件。如果文件存在,无论它是否为空,我们都将此任务视为成功。

创建 grep_exception 任务

grep 异常

刷新 DAG 并再次触发它,图形视图将如上所述进行更新。让我们检查文件夹中的输出文件 errors.txt。

在 errors.txt 中列出最后 5 个异常

接下来,我们将逐行解析日志,提取我们感兴趣的字段。我们使用一个 PythonOperator 通过一个正则表达式来完成这项工作。

使用正则表达式解析异常日志

提取的字段将保存到数据库中,供以后查询使用。Airflow 支持任何类型的数据库后端,它在数据库中存储元数据信息,在这个例子中,我们将使用 Postgres DB 作为后端。

我们定义了一个 PostgresOperator 来在数据库中创建一个新表,如果这个表已经存在,它将删除这个表。在真实的场景中,我们可能会将数据追加到数据库中,但是我们应该小心,如果由于某种原因需要重新运行某些任务,可能会将重复的数据添加到数据库中。

在 Postgres 数据库中创建一个表

要使用 Postgres 数据库,我们需要在 Airflow 门户中配置连接。我们可以修改现有的 postgres_default 连接,这样在使用 PostgresOperatorpostgreshawk时就不需要指定连接 id。

修改 postgres_default 连接

配置 postgres_default 连接

太好了,让我们再次触发 DAG。

解析错误日志

任务成功运行,所有日志数据都被解析并存储在数据库中。Airflow 提供了一种查询数据库的便捷方式。在“数据分析菜单下选择“临时查询,然后输入 SQL 查询语句。

即席查询

Postgres 数据库中的错误日志

接下来,我们可以查询表并统计每种类型的错误,我们使用另一个 PythonOperator 来查询数据库并生成两个报告文件。一个包含数据库中的所有错误记录,另一个是统计表,以降序显示所有类型的错误。

定义任务以生成报告

好的,再次触发 DAG。

生成报告

文件夹中会生成两个报告文件。

两份报告

在 error_logs.csv 中,它包含数据库中的所有异常记录。

报告所有例外情况

在 error_stats.csv 中,它列出了出现的不同类型的错误。

报告不同类型的异常

在最后一步,我们使用一个分支操作符来检查错误列表中的最高出现次数,如果它超过阈值,说 3 次,它将触发发送电子邮件,否则,静静地结束。我们可以在气流变量中定义阈值,然后从代码中读取该值。这样我们就可以在不修改代码的情况下更改阈值。

在气流中产生一个变量

定义任务以检查错误号

branch pythonooperator返回下一个任务的名称,要么发送电子邮件,要么什么都不做。我们使用 EmailOperator 发送电子邮件,它提供了一个方便的 API 来指定收件人、主题、正文字段,并且易于添加附件。我们用 DummyOperator 定义一个空任务。

电子邮件任务和虚拟任务

要使用电子邮件操作符,我们需要在 YAML 文件中添加一些配置参数。这里我们定义 Gmail 帐户的配置。您可以在这里输入您的密码,或者使用应用程序密码作为您的电子邮件客户端,这样可以提供更好的安全性。

- AIRFLOW__SMTP__SMTP_HOST=smtp.gmail.com
- AIRFLOW__SMTP__SMTP_PORT=587
- AIRFLOW__SMTP__SMTP_USER=<your-email-id>@gmail.com
- AIRFLOW__SMTP__SMTP_PASSWORD=<your-app-password>
- AIRFLOW__SMTP__SMTP_MAIL_FROM=<your-email-id>@gmail.com

到目前为止,我们创建了工作流中的所有任务,我们需要定义这些任务之间的依赖关系。气流提供了一种非常直观的方式来描述依赖性。

dl_tasks >> grep_exception >> create_table >> parse_log >> gen_reports >> check_threshold >> [send_email, dummy_op]

现在,我们完成了所有的编码部分,让我们再次触发工作流来看看整个过程。

当任何类型的错误数量超过阈值时发送电子邮件

在我们的例子中,有两种类型的错误,它们都超过了阈值,它将在最后触发发送电子邮件。邮件附有两份报告。

电子邮件提醒

我们将阈值变量更改为 60,并再次运行工作流。

将阈值更改为 60

工作流结束,不发送电子邮件

如您所见,它不会触发发送电子邮件,因为错误数小于 60。工作流无声地结束。

让我们回到 DAG 视图。

DAG 视图

它列出了所有活动或非活动 DAG 以及每个 DAG 的状态,在我们的示例中,您可以看到,我们的 monitor_errors DAG 成功运行了 4 次,在最后一次运行中,15 个任务成功,1 个任务被跳过,这是最后一个 dummy_op 任务,这是预期的结果。

现在,我们的 DAG 计划每天运行,我们可以根据需要更改计划时间,例如每 6 小时或每天的特定时间。

Airflow 是一个强大的 ETL 工具,它被广泛应用于许多一级公司,如 Airbnb,Google,Ubisoft,Walmart 等。它也受到主要云平台的支持,如 AWS、GCP 和 Azure。它在数据工程和数据处理中发挥着越来越重要的作用。

密码

https://github.com/kyokin78/airflow

参考

1https://en.wikipedia.org/wiki/Apache_Airflow

[2]https://airflow.apache.org/docs/stable/concepts.html

[3]https://github.com/puckel/docker-airflow

无需编码的逐步花卉分类

原文:https://towardsdatascience.com/step-by-step-flower-classification-without-coding-c652a7f73251?source=collection_archive---------57-----------------------

如何不用写一行代码就部署一个人工智能模型

弗朗切斯科·帕尔马和艾萨克·罗萨写的

今天,你可以在高速公路上开着自己的无人驾驶汽车看报纸,在没有收银员的情况下购买食品杂货。但是,如果你去看医生、律师或农民,还没有智能机器能显著地帮助他们的核心活动。在没有做出判断的情况下,这似乎有点怪异。

难以获得新技术和缺乏专家是远未解决的问题。然而,对于传统的专业类别、学术研究人员和主题专家来说,有大量的数据分析用例

照片由 Hitesh ChoudharyUnsplash 上拍摄

好消息是,今天用于开发人工智能应用的部分最先进技术已经公开。开源库和深度学习框架的兴起使这种技术的传播成为可能。通过迁移学习我们可以用比以往更少的图像或文本数据来训练执行深度学习模型。这意味着医生可以在他们的 X 射线图像上使用自动驾驶汽车中使用的相同模型。如果你有兴趣,你可以看看 Fast.ai抱脸是如何工作的。

然而,对这些框架的访问仍然局限于具有编码技能的人。因此,技术的成熟度和潜在用户的可访问性之间的不平衡产生了对无代码人工智能越来越大的影响。

当然,根据定义,无代码使它不那么复杂。由于它没有编写人工智能应用程序复杂,所以它没有同样的影响力和能力。

无论是现在还是将来,无代码平台都不可能完美地取代一个组织良好的数据专家团队。

无代码 AI 的主要限制是它的严格性。无代码程序不是根据客户需求定制的,可能不支持特定问题所需的工作量。另一个限制是难以运用商业知识来提高绩效或施加约束。

除了它的局限性之外,在过去的几年中,对无代码解决方案的关注无疑一直在上升。您可以在此处找到对现有供应商的详细回顾。

在本文中,我们将在一个花卉分类项目中试用乔托Giotto 是一个基于云的无代码平台,允许用户非常容易地开发、部署和共享基于他们自己的数据问题构建的人工智能应用。它分为五个步骤(从数据选择到部署),用户可以选择一些参数或自动完成整个过程。到目前为止,它支持图像分类问题,但是其他数据类型和任务据说很快就会出现。

数据和问题

正确标记文件夹对使用 Giotto 很重要

无代码人工智能并不意味着神奇的人工智能:提供良好的数据仍然是一个优先事项,否则模型性能很容易下降。

在这个例子中,我们使用花的图像对 102 种植物进行了分类。分类的目标是能够通过在程序中上传植物的花的图片来正确地评估植物的种类。

数据集由 5400 幅花的图像组成,每类大约 50 幅图像,总共 102 个类。给定一幅图像,问题是正确分类它的类别,即花的种类。数据组织在子文件夹中,每个子文件夹包含单独/不同类别的图像。为了能够使用 Giotto,尊重这样的文件夹结构是至关重要的(上图)。数据可在这里获得。

数据选择

第一步:数据选择,导入数据。(视频:1:40)

登录并创建项目后,系统会提示我们选择数据类型和任务。对于我们的应用程序,我们选择了图像和图像分类。

导入数据后,我们可以在可视化步骤中快速浏览一下。

预处理

第二步:预处理。所有数据扩充方法的可视化。(视频:2 分 25 秒)

深度学习模型工作得很好,但众所周知它们是数据饥渴的。即使我们在解决迁移学习的问题上迈出了一大步,一个模型通常会在有大量特定任务图像的情况下表现得更好。数据科学中使用的一个技巧是对原始图像进行修改,以人为增加数据集的大小。使用 Giotto,可用的修改包括裁剪、缩放、亮度、旋转等。

没有试图成为一个明显的队长,一个更光明的雏菊仍然是雏菊。只要我们试图区分雏菊和其他花,用原始雏菊和更亮的雏菊喂养模型应该会增加模型可以学习的雏菊样本的数量。因此,在大多数情况下,这也会提高其性能。

此外,在某些情况下,通过从数据中去除系统噪声,数据扩充也可能有益于模型。想象一下,如果你用一个数据集训练机器,其中所有的雏菊面朝右,所有的向日葵面朝左。一旦机器学会了,如果你给它一个面朝右的向日葵的图像,它可能会告诉你这是一朵雏菊。旋转(翻转)工具避免了这种情况,使机器的花面向两侧。

即使为您的数据选择所有的转换非常诱人,但这并不总是最好的主意。例如,如果你正在对颜色很重要的东西进行分类,处理亮度可能会导致性能下降。

在我们的案例中,我们选择了所有可用的数据扩充,因为它们都不会对模型的执行产生不利影响。

在下一个可视化步骤中,你可以看看修改后的图像样本(上图)。如果一个转换看起来不好,你可以随时回来删除它。

型号选择

第四步:型号选择。选择正确的设置对我们的模型正常运行至关重要(视频:2:50)

在模型选择中,主要有两个选择:模型类型和超参数。目前,Giotto 分别支持不同的 resNet 大小和一个历元数范围。

resNet 的大小基本上就是网络的层数。例如,resNet 34 将代表 34 层神经元。一般来说,“越深越好”适用于模型选择,前提是您为模型提供足够的数据。然而,较大的网络也可能导致较大的运行时间和成本。

历元数是整个数据集通过神经网络的次数。或者换句话说,网络“看到”数据的次数。乔托有一个很酷的提前停止规则:如果从一个时期到下一个时期,表现没有改善,训练就停止了。

最后,您可以选择最适合您的问题需求的度量标准。在可能的选择中,我们有准确性、AUC、F1 分数等等。

至于所有的步骤,如果你不知道选择什么参数,你可以直接自动选择并得到结果。

在我们的例子中,我们选择了具有 10 个时期的 resNet34。

结果

第四步:结果。通过检查性能报告,我们评估设置的充分性。(视频:3:02)

一旦模型完成运行,您就可以可视化它的性能。花些时间仔细检查这里的所有细节是很重要的。

首先是对任务的总结,主要描述了所使用的数据。然后是模型总结,它概括了之前选择的模型参数。最后,我们得到了训练的实际性能,如准确性、最难分类的图像和混淆矩阵。也可以下载 PDF 格式的摘要。

在我们的例子中,机器用我们的设置训练只花了 7 分钟。结果是令人满意的,在 1180 幅图像的验证集上测量的准确率为 95%。

部署

第五步:部署。在我们的例子中,我们选择运行一个 web 应用程序,而不是 docker。(视频:4:13)

现在模型已经训练好了,您有两个选择。您可以将它作为 Docker 映像下载并离线使用,也可以将其部署在一个用户友好的 web 应用程序中,以便与其他用户轻松共享。一旦部署(web 应用程序或 Docker),该模型可用于对看不见的图像进行分类。

在我们的案例中,我们将模型部署在一个 web 应用程序上,您可以在这里访问(密码:Loveflowers8)。

结论

我们已经证明,在几分钟内完成令人满意的图像分类任务,而无需编写一行代码是可能的。结果是一个可以在新图片上使用并与其他用户分享的网络应用程序。

无代码 AI 很可能永远不会取代数据科学家。然而,对于缺乏人工智能最新技术的人来说,它仍然是一个可靠和用户友好的替代选择。

参考文献:

** [## 当今使用的人工智能的 10 个有力例子

机器还没有接管。至少现在还没有。然而,它们正在渗入我们的生活,影响着我们如何…

www.forbes.com](https://www.forbes.com/sites/robertadams/2017/01/10/10-powerful-examples-of-artificial-intelligence-in-use-today/#19b198fb420d) [## 无代码/低代码人工智能:新的商业模式和数据科学家的未来

无代码 AI 和低代码平台:正在使用什么商业模式,数据科学家的未来是什么?

towardsdatascience.com](/no-code-low-code-ai-new-business-models-and-future-of-data-scientists-a536beb8d9e3) [## 乔托

停止编码。启动人工智能

giotto.ai](https://giotto.ai/)**

规划 A/B 测试的逐步过程

原文:https://towardsdatascience.com/step-by-step-for-planning-an-a-b-test-ef3c93143c0b?source=collection_archive---------28-----------------------

起草 A/B 测试的初学者终极指南

介绍

继我之前的 帖子 关于通过实验发展科学文化的重要性之后,我将解释如何恰当地计划一个实验。我希望这篇博文可以作为那些不确定该做什么的人的起点。

为了避免这篇文章太长,我将只涉及计划过程,我将在以后的博客文章中涉及实验的其他方面。规划过程包括:

  1. 设定假设
  2. 获取度量的基线数字
  3. 最小可检测效应
  4. 功效分析(确定完成实验所需的样本量)
  5. 估计实验的持续时间
  6. 与利益相关者讨论

我将只讨论使用频率主义方法的最简单和最常见的实验形式(即 A/B 测试,也称为双变量测试),这对大多数人或组织来说已经足够了。

第一步:从假设开始

就像我们在学校被认为的那样,一个实验从一个假设开始。你可能有多个假设想要测试,但总是有一个主要的。这里我举两个例子:

  1. 你在一家电子商务公司工作,你认为在结账时显示折扣金额可以提高结账率。
  2. 您不再需要提供电话号码和地址来注册会员。你认为这会提高转化率。

我个人认为将这些陈述转换成更多的统计形式是很有用的,因为这些陈述更清晰,并且减少了在衡量具体指标时出错的机会。例如,在第一种情况下,我会写:

【检出率(单尾)
【h₀:】对照组和治疗组的检出率没有差异。 治疗组的 H₁:检出率比对照组的检出率高

我们希望拒绝零假设,并得出结论:治疗组的检出率在统计学上显著高于对照组。(斜体格式)

在大多数情况下,会有一些您想要测量的次要指标,您也可以用相同的格式来写它们。虽然总是想要衡量改善是很常见的,但是你也应该总是考虑你的治疗可能带来的不利影响。例如,在第二种情况下,我还会考虑将付费会员转化为次要指标,我可能会假设新的注册过程对一些人来说可能显得不安全,并阻止他们成为付费会员。然后,我会将我的二级指标写成:

【付费会员转化率(双尾)
【h₀:】对照组和治疗组的付费会员转化率没有差异。 H₁:对照组和治疗组的付费会员转换率存在差异。

我们希望不会拒绝零假设,并得出治疗组和对照组的付费会员转换率之间不存在统计学显著差异的结论。**

因此,实验不应该被认为是一种测量治疗是否带来改善的方法,它也可以用来测量治疗是否造成伤害。

步骤 2:获得当前度量的基线

这是很重要的,因为它将是我们所需样本量计算的一部分。其次,它帮助我们了解当前的数字。

第三步:对你来说什么是有意义的效果尺寸?

给定足够的样本量,我们通常能够找到两组之间有统计学意义的差异,即使只有非常微小的差异。这是因为我们估计的置信区间随着样本量的增加而减小。下图显示了在不同样本量下,一个均值为 0.1 的分布和另一个均值为 0.15 的分布。这很直观,因为随着样本量的增加,我们对均值的估计更有信心,这也是分布变窄的原因。这也意味着,如果您想要有把握地检测两个群体之间的微小差异,对样本量的要求会增加。

说明分布如何随着样本量的增加而变窄。

因此,决定什么样的改变被认为是有意义的,足以让你采取行动,这是非常重要的。例如,如果您发现通过在结账页面显示折扣金额,结账率在统计上显著提高了 0.05%(从 15.3%到 15.35%)。你真的应该实施改变吗?这也就是通常所说的最小可检测效应(MDE ),我将在以后的文章中详细介绍。

决定一个有意义的效果大小并致力于此,可以防止你在实验后偏离最初的计划。如果 1%的变化是一个足够好的信号,可以向所有人推广这种疗法,那么要确保只有当效果超过 1%时你才会这么做。

尽管理论上人们不应该这样做,但是由于样本大小的要求会随着 MDE 的变化而变化,我发现在考虑 MDE 时,考虑我的实验中可以得到的估计样本大小是很有用的。如果我不希望在我的实验中有太多的样本,我就不能把我的 MDE 设置得太小。

步骤 4:执行功率分析

这可能是其他文章中讨论最少的部分。设置目标显著性值、目标统计功效和分配比率(通常为 1),并计算在特定分配比率下,在目标显著性值和统计功效下检测所需 MDE 所需的样本量。

***目标显著性值,𝛂:当零假设正确时,我们拒绝零假设的概率为𝛂 %,常见值为 0.01、0.05 和 0.1,取决于犯此类错误的成本,成本越高,您的𝛂应该越低。

目标统计功效,1-𝜷:当 MDE 有实际的显著变化时,我们有%的 1-𝜷机会未能剔除空值,常见值为 0.8,0.85,0.9 和 0.95,0.99。这取决于当有实际变化时错过这种变化的代价有多大,代价越高,你的𝜷应该越低,因此目标统计功效越高。***

分配比率:治疗组与对照组的比率,在给定固定样本量的情况下,通常设定为 1 表示最高统计功效。

设置好这些实验参数后,我会拿出这个表,里面包含了一个实验计划的精华。

+----------------------------+---------------+
| Metric                     | Checkout Rate |
| Estimated Baseline Value   | 0.15          |
| Target Value (Effect Size) | 0.18 (0.081)  |
| Target Significance Value  | 0.05          |
| Target Statistical Power   | 0.95          |
| Allocation Ratio (N2 / N1) | 1             |
| Number of groups           | 2             |
| Total Sample Size Required | 6618          |
+----------------------------+---------------+

以下是计算所需样本量的 3 种方法:

  • Python
import math
from statsmodels.stats.power import TTestIndPoweralpha = 0.05
p = 0.15
p2 = 0.18
var_base = p * (1 - p)
var_target = p2 * (1 - p2)
cohen_d = (abs(p2 - p) / math.sqrt((var_base + var_target) / 2))analysis = TTestIndPower()
analysis.solve_power(effect_size=cohen_d, power=0.95, nobs1=None, ratio=1.0, alpha=alpha, alternative='larger')# Output 3308.6546478905598
  • R
library(pwr)alpha = 0.05
p = 0.15
p2 = 0.18
var_base = p * (1 - p)
var_target = p2 * (1 - p2)
cohen_d = (abs(p2 - p) / sqrt((var_base + var_target) / 2))
pwr.t.test(d = cohen_d, sig.level = alpha, power = 0.95, type = "two.sample", alternative = 'greater')# Output
Two-sample t test power calculation 

              n = 3308.654
              d = 0.08088928
      sig.level = 0.05
          power = 0.95
    alternative = greater

NOTE: n is number in *each* group

G*Power 软件截图

在决定所需的样本量时,我经常给误差留有余地,因为在实验过程中有很多事情可能出错。当这些错误发生时,您可能需要移除一些实验样品,以防止它们影响您的结果。例如,可能有另一个营销活动引入了有利于对照组的偏见。

如果您在实验过程中意识到这些事件,这是很好的,然后您可以从您的实验样本中排除这些事件,这样您的实验仍然会运行,直到它达到目标样本大小。但我经常发现,直到实验结束后,才意识到所有这些运动的部分是不可能的。然后你会意识到,在排除这些无用的样本后,你没有足够的样本量来结束这个实验。多给多少空间将取决于你对正确执行实验的信心。

步骤 5:估计实验的持续时间

给定所需的样本量,估计在给定流量或容量的情况下,需要多长时间才能达到目标样本量。根据经验,通常会有一些季节性影响,如一周中的某一天或一天中的某个小时。例如,根据这些季节性因素,你的实验对象对治疗的反应可能不同。因此,如果你认为你可以在几天内达到你的样本量,我会建议在大多数情况下扩展到一周甚至两周,以获得更稳健的结果。

如果需要几个月才能达到目标样本量,那么您可能需要增加 MDE 来减少所需的样本量。这样做的好处是你可以节省时间,但坏处是你的治疗必须有足够大的影响,让你自信地拒绝你的无效假设。

第六步:与利益相关者讨论

与你的工程师讨论如何进行实验。常见问题包括:

  1. 要记录哪些额外事件?
  2. 如何给用户分配治疗?
  3. 如何将这些事件传输到您的数据仓库中进行实验监控?
  4. 实验过程中会出现什么问题,你有什么后备计划?

结论

在这篇博文中,我描述了如何设计一个简单的双变量实验的一步一步的过程。我希望这篇博文能帮助你开始在你的团队中计划一些实验。但是,我没有涉及更多的方面,我希望将来能涉及这些方面,例如:

  1. 实验过程中需要监控的常见事项
  2. 实验中常见的陷阱
  3. 超过 2 个实验变量
  4. 全因子实验设计
  5. 实验的常用统计检验

最后但同样重要的是,适当地计划你的实验以减少在实验过程中出错的机会,或者更糟的是,以错误的结果结束实验,这是极其重要的。开始时计划好这些可能很费时间,但是你练习得越多,最终会越快。

如何挽救亏损的交易策略?(第一部分)

原文:https://towardsdatascience.com/step-by-step-forex-trading-strategy-optimisation-part-1-b1516753b42e?source=collection_archive---------22-----------------------

一步一步的教程来拯救一个看似有希望的交易策略

戴维·冯迪马尔在 Unsplash 上拍摄的照片

来自《走向数据科学》编辑的提示: 虽然我们允许独立作者根据我们的 规则和指导方针 发表文章,但我们并不认可每个作者的贡献。你不应该在没有寻求专业建议的情况下依赖一个作者的作品。详见我们的 读者术语

这些天网上外汇交易大师的数量之多,让我无法在 YouTube 上推荐。获得兰博基尼金像奖有那么容易吗?在这篇博客中,我将讲述我是如何优化一个很好的老式均线交叉策略的,这个策略在我的案例中肯定是行不通的,并试图使它成为一个有利可图的策略。在开始优化我们的策略之前,我们将从创建我们的交易系统开始,获取我们需要的数据,定义我们的进场逻辑,评估表现。事不宜迟,让我们一头扎进去;当然,在我注意到之前,我的蓝宝已经在去我车库的路上了(除了我甚至没有车库)

来源: 9GAG

免责声明:我目前没有用这个策略交易,这个博客也不是一个财务建议。请自担风险使用。

系统交易

交易系统,一个听起来非常花哨和复杂的词,实际上只不过是一套精确的规则,可以自动定义进场和出场逻辑,所有这些都不需要任何人为的努力。由于规则集的精确本质,系统测试可以用历史数据集进行可靠的测试,也称为回溯测试。通过观察统计上有代表性的和重复的过去的行为,我们就能够估计系统交易策略盈利的信心水平。

交易系统通常由几个部分组成:

  1. 数据连接:数据为王。没有数据,我们就无法制定和评估战略。我们最多只能猜测。根据你的交易策略,你也许可以使用每日数据,这些数据可以从 https://www.investing.com/的网站免费获得。如果你正在做日内交易,就像我打算在这个系列的博客中做的那样,你肯定需要更精细的数据。为此,您需要从 OANDA、Interactive Brokers 等经纪人那里获取数据。
  2. 特征工程:众所周知,金融时间序列是异方差的(基础数据方差变化的统计说法)。因此,价格时间序列本身无法提供稳健的进入和退出逻辑。特征工程是为以后定义进入和退出逻辑而生成附加特征的过程。这些特征的例子可以是移动平均线、指数移动平均线等。
  3. 进入信号&条件:信号和条件非常相似,但概念不同。以 MACD 交叉为例,每当线交叉,这将是一个进入信号。然而,只有在所有条件都满足的情况下才会开仓,也就是说,价格需要高于 200 周期移动平均线才能确认趋势。
  4. 出舱信号&条件:如果出舱为我们登陆月球创造了机会,出舱则确保我们的飞船足够稳定,能够持续整个旅程。好吧,也许这不是一个好的比喻,但好的退出逻辑可以救我们的小命。当趋势失去动力时,它锁定利润;在任何亏损的交易让我们损失惨重之前,它减少了我们的损失。说到退出逻辑,一般有四个不同的概念:(1)止损,(2)跟踪止损,(3)止盈,(4)进场时间。

数据采集

理论上,交易系统可以在任何市场或具有内在货币价值的流动商品上发展。在这篇博文中,我们将使用 GBP。美元作为我们的基础资产。我们从 OANDA v20 API 获取了从 2014 年 1 月到 2020 年 9 月大约 6 年的 30 分钟分笔成交点数据。这个过程实际上很简单:(1)在 OANDA 创建一个练习帐户,(2)在这里生成一个访问令牌(当然要安全地存储它),以及(3)按照 Vladimir 这里的指示操作。或者,您也可以从 backtrader 获取数据,我将在另一篇博客文章中介绍这一点。

我们从 OANDA 下载的数据集的收盘价

初始交易策略

既然我们已经对数据进行了分类,是时候制定我们的策略了。这次我们要用均线交叉。但是为了增加趣味,我们将使用三角移动平均线(TMA ),而不是简单的移动平均线(SMA)。众所周知,SMA 非常容易受到异常值的影响。另一方面,TMA 是更平滑的趋势线。虽然平滑的移动平均线会增加价格运动和信号之间的滞后,但它也最小化了假突破的风险,因为趋势会在进场信号到来之前得到更好的确认。那么,我们如何计算这个 TMA 呢?一个 n 周期 TMA 其实只是过去 n 个 n 周期 SMA 的平均值。听起来像是绕口令,但让我加入一些数学公式来描绘这幅图:

n 周期简单移动平均线

n 周期三角形移动平均线

换句话说,TMA 和 SMA 之间有几个关键区别:

  1. TMA 是平均值的平均值;而 SMA 是平均值;
  2. TMA 对价格变化的反应比 SMA 慢;
  3. TMA 有时可以让你在一个趋势中停留更长时间,产生更大的利润;另一方面也是如此。

让我们为我们的 30 分钟数据集创建两个 TMA 序列,周期分别为 3 和 30。现在,我们可以随机选择周期,并逐步优化它们,直到我们达到最优。

df['fast_tma'] = df['Close'].rolling(3).mean().rolling(3).mean()
df['slow_tma'] = df['Close'].rolling(30).mean().rolling(30).mean()

英镑的收盘价。2014 年 1 月 5 日至 2014 年 1 月 10 日的美元,含 3 期 TMA 和 30 期 TMA

我们从简单的交易逻辑开始,慢慢增加复杂性,这通常是个好主意。通过这种方式,我们可以在调整交易策略之前更好地理解交易策略的行为和潜力。首先,让我们只定义进场信号,并在相反的信号产生时退出:

  • 多头进场:当(1)快速 TMA 已经穿过慢速 TMA 上方,并且(2)当前价格位于交叉杆的高点时,1 手的未平仓头寸
  • 短线进场:当(1)快速 TMA 已经穿过慢速 TMA 下方,并且(2)当前价格处于交叉杆的低点时,开仓 1 手

第一个信号的假突破;价格跌破交叉杆低点后的短线进场

不在交叉点处进场的直觉是测试趋势,让回撤更接近较慢的 TMA 系列,潜在地筛选假突破,只和长期趋势交易。如上图所示,2014 年 1 月 3 日上午有一个多头设置,但由于达到了多头进场价格,该设置从未被触发。假突破后很快出现下跌趋势,当价格跌破交叉杆的低价时,就会触发空头设置。

评估和滑动

有了初步的策略,让我们来看看性能。我们将使用 2014 年 1 月 1 日至 2019 年 12 月 31 日的数据进行评估(即样本内数据),并在我们完成战略优化后,将 2020 年的精彩数据用于未来分析(样本外数据)。重要的是,我们从我们的回溯测试中保留一个前进集,以避免过度拟合,并增强我们最终策略的健壮性。相反,如果我们拥有样本数据集中的所有数据,我们就可以针对整个数据集中的每个趋势变化优化我们的时间策略。虽然这可以提供惊人的评估结果,但这绝不是现实的,因为精确的模式不会重复。这种在未来未知数据中策略表现的显著恶化被称为过度拟合。

我们对样本内和样本外数据集的划分

如果我们将初始交易策略应用于样本内数据集,假设我们交易 1 手英镑。每输入一个美元(即 100,000 单位的货币),我们将得到以下数字:

6 年内利润超过 17,000 美元。我们已经在去月球的路上了吗?

振作起来,我们要在水下潜水 900 天。我们能屏住呼吸那么久吗?

甜蜜黑暗主题中我们战略的关键人物

乍一看,这种交易策略似乎已经相当可行了。然而,如果我们更多地关注水下图表,它显示了我们距离峰值股本的百分比有多低,我们可以注意到该策略有一个相对较长的复苏周期,最长的一个周期跨越 2.5 年。想象一下,处于负面情绪中,两年多都没有恢复,这听起来肯定不像是最有趣的过山车。如果我们接着研究表格中的一些交易数据,似乎会对我们的诊断有更多的见解:

  1. 利润百分比&平均值。成功交易中的棒线:盈利百分比计算为所有盈利交易的百分比,而平均值。成功交易中的棒线是根据我们的成功头寸在市场中的 30 分钟棒线的平均数计算的。由于平均获利棒线几乎是相反棒线的 4 倍,我们可以说这个策略在长期趋势中运作良好。这也解释了为什么长期趋势之间的周期波动更大,因此对于我们的趋势跟踪策略来说,这也解释了为什么成功率相对较低。话虽如此,如果我们的风险管理做得好,低胜率仍然是合理的。
  2. 利润系数:计算为毛利润对毛亏损的绝对值。所以,越高越好;与此同时,利润系数低于 1 是一个大禁忌。正如我们在表中看到的,当进入多头头寸时,我们的策略相当糟糕。公平地说,可怜的英镑正在贬值,所以趋势对我们不利。但是,这仍然暗示了我们可以将外部进入信号收紧一点,以避免误报。
  3. 比率平均值。赢:平均。损耗:以 Avg 的绝对值计算。在平均值上赢得交易。成功交易,可以作为我们回报风险比的代表。能够以超过 2 的比率盈利并不太坏,因为这意味着我们可以承受每赢一笔交易就输两笔交易。鉴于我们甚至没有优化任何止损或获利策略,这个数字预计会增加。

现在我们有了初步的诊断,是时候加入一些现实的东西了,也就是佣金和滑点。这些基本上分别是,经纪的零花钱和网络延迟的补偿。如果我们总共支付 3 点的费用(0.5 的佣金和 2.5 的滑点),那么之前 50 美元的利润交易将变成仅仅 20 美元的利润,但是,嘿,20 美元就是 20 美元!玩笑归玩笑,让我们来看看我们更真实的权益曲线、水下图表和其他汇总统计数据。

残酷的现实打在我们的脸上。

哎唷…用这种策略,我们永远不会在真正的市场中获利…

老实说,这些数字看起来很可怕。但是,不要对自己(自己)太苛刻,如果市场这么好打,巴菲特就不会是这样的传奇。另外,我们只选择了两个任意的输入参数,没有止损,也没有获利。

步骤 1:优化输入参数

为了挽救我们糟糕的策略,我们必须首先为 TMAs 找到一组更可行的参数。在下图中,我们使用快速 TMA 周期和慢速 TMA 周期的不同组合重新运行了回溯测试。如果我们的快速 TMA 周期为 1,慢速 TMA 周期超过 50,看起来这个策略实际上是有利可图的。

不同 TMA 参数组合的性能

确定了最佳参数的大致区域后,让我们进行更精细的网格搜索。从下图可以看出,当快速 TMA 的周期为 1,慢速 TMA 的周期为 62 时,该策略表现最佳。但是请注意,样本内数据的最佳性能并不意味着样本外数据的最佳性能。当谈到优化策略时,最好有一个更稳定的策略,而不是一个对样本数据来说可能过拟合的策略。经验丰富交易系统开发人员默里·鲁杰罗曾经说过:

如果你不喜欢相邻的数字,你就有问题了,因为很可能你会得到相邻的一组参数的结果。

因此,我们不选择慢 TMA 周期为 62,而是选择 65,其中相邻参数具有相似的利润。

跳过高峰,走向稳定的高原

参数排序后,即使考虑了 3 个点的滑点和费用,我们的策略仍然盈利,如下图所示:

现在,我们又在谈论绿色了

哦,不太好,超过 3 年的下降

从红色到绿色,这是一个非常大的进步。看看这些数字,我们可以看到,通过增加慢速 TMA 的周期数,赢仓的平均棒线数增加了 50%以上,这与拥有更慢的慢速 TMA 来捕捉更长趋势的直觉相符。我们还可以看到,我们的风险回报比从 2.11 增加到了 3.88。另一个亮点是我们的最大提取比例将从 40%降至约 14%。然而,我们的策略仍远未达到可交易的水平,其最长提款期为 1167 天。

第二步:优化进入时间

由于外汇市场昼夜不停地运转,在一天的不同时间有不同的参与者,从 APAC 到欧洲,然后到美洲,再回到 APAC。这就带来了一个问题,什么时候进入英镑是最好的?美元市场。众所周知,这一对的大部分货量来自欧洲和美洲。如果我们能为进场信号找到一个最佳的时间滤波器,我们也许能驾驭这些大交易量驱动的趋势。让我们看看,如果我们对进场信号应用 4 小时窗口滤波器,我们的策略表现如何。(例如,09:30 意味着仅允许从 09:30 到 13:30 的进入信号)

再说一遍,让我们跳过高峰,走向稳定的高原

同样,尽管从 05:00 GMT 到 09:00 GMT 的进入信号为我们提供了样本内数据的最佳性能,但我们宁愿选择更稳定的选择。在这种情况下,我们的选择将是 13:00–17:00,相邻参数显示类似的利润。

PNL 变得更加稳定

我们仍然需要在超过 2.5 年的时间里削减开支

通过将条目限制在 13:00 GMT 到 17:00 GMT,我们已经将最大提款百分比降低到大约 10%,提款期减少到大约 980 天。仔细观察这些数字,我们可以看到进场限制正在帮助我们做多,平均净利润从每手-8 美元增加到每手+22 美元,同时损害了短期表现。这可能意味着我们需要开发另一种策略来优化短期性能。

结论(迄今为止)

在这篇博客中,我们已经讲述了如何开发一个简单的 TMA 交叉交易策略,这个策略在理论上看起来是有利可图的,直到我们把 3 点的佣金和滑点计算在内。通过优化 TMA 参数和进场时间窗口,我们挽救了这个看起来很糟糕的策略,并使其再次盈利。以下是一些高水平的结果:

通过优化我们看似无望的战略,我们成功做到了:

  1. 提高我们战略的利润系数,
  2. 提高我们的回报风险比,
  3. 提高策略进入长期趋势的能力
  4. 降低最大提取百分比,以及
  5. 缩短最大提款期

也就是说,这一战略还远未准备好部署。我们仍有超过 2.5 年的缩减期,6 年的总利润为 18.57%,因此我们仍有很大的改进空间。在本系列的后续部分中,我们将继续在以下几个方面改进这一策略:

  1. 带止损和跟踪止损逻辑的风险管理
  2. 基于获利逻辑的风险管理
  3. 蒙特卡罗法分析
  4. 向前分析
  5. 更多

[## 如何挽救亏损的交易策略(第二部分)

通过风险管理改进交易策略的逐步指南

medium.com](https://medium.com/datadriveninvestor/how-to-save-a-losing-trading-strategy-part-2-8d4f713068eb)

放弃

本报告中表达的想法和观点仅代表我个人,不一定代表我公司的观点。本报告旨在提供教育,不应被理解为个人投资建议,也不应被理解为购买、出售或持有任何证券或采取任何投资策略的建议。

参考文献

柯林斯(2004 年)。。瓦森多夫联合公司。

Tomasini,e .,& Jaekle,U. (2019 年)。交易系统第二版:系统开发和投资组合优化的新方法。)。哈里曼之家。

在你走之前…

感谢你加入我的第一个媒体博客。让我知道你在评论中的想法,以及这篇文章如何改进。如果你能通过 embed affiliate 链接获得书籍以支持该系列,我们将非常感激。暂时,保持坚强,继续相信我们的蓝宝就在眼前;我们将在博客的下一部分继续这个旅程。

再见!

分步指南-用 Python 构建预测模型

原文:https://towardsdatascience.com/step-by-step-guide-building-a-prediction-model-in-python-ac441e8b9e8b?source=collection_archive---------1-----------------------

使用长短期记忆预测模型的动手练习

Unsplash 上由 Austin Distel 拍摄的照片

来自《走向数据科学》编辑的提示:虽然我们允许独立作者根据我们的规则和指导方针发表文章,但我们并不认可每个作者的贡献。你不应该在没有寻求专业建议的情况下依赖一个作者的作品。详见我们的读者术语

在这篇文章中,我将向你展示如何构建一个可以预测特定股票价格的程序。这是一个在金融领域使用机器学习的伟大工程。如果我们想要一台机器为我们做预测,我们肯定应该用一些数据好好训练它。首先,对于刚接触 python 的人,我将向您介绍一下。然后,我们将开始研究我们的预测模型。正如副标题中提到的,我们将使用苹果股票数据。如果你想知道是否可以免费获得这些数据,答案是肯定的。股票数据可以在纳斯达克官方网站上找到。纳斯达克(全美证券交易商自动报价协会)是一个电子股票交易所,拥有 3300 多家上市公司。

苹果股票数据可以从这里下载。在这个网站上,你还可以找到不同公司的股票数据,并使用不同的数据集练习你的技能。我迫不及待地想看到我们的预测准确性结果,让我们开始吧!

目录:

  • Python
  • 图书馆
  • 了解苹果股票数据
  • 数据操作
  • 数据可视化
  • LSTM 预测模型

计算机编程语言

Python 是一种通用编程语言,在分析数据方面越来越受欢迎。Python 还能让您快速工作,更有效地集成系统。世界各地的公司都在利用 Python 从他们的数据中收集知识。Python 官方页面如果你想了解更多

[## 面向金融的 Python 完全初学者指南

使用亚马逊股票数据的简单实践

towardsdatascience.com](/python-for-finance-the-complete-beginners-guide-764276d74cef)

图书馆

首先,我们必须安装一些库,这样我们的程序才能工作。下面是我们将要安装的库的列表:pandas、numpy、keras 和 tensorflow。必须安装 Tensorflow,keras 才能工作。

Keras 是为人类设计的 API,不是为机器设计的。Keras 遵循减少认知负荷的最佳实践:它提供一致而简单的 API,最大限度地减少常见用例所需的用户操作数量,并提供清晰可操作的错误消息。它还有大量的文档和开发人员指南。

参考: https://keras.io

我们可以使用 Pip 库管理器安装这些库:

pip install pandas numpy keras tensorflow

安装完成后,让我们将它们导入到代码编辑器中。Python 中已经包含了 Matplotlib,这就是为什么我们不用安装就可以导入它。

import pandas as pd
import numpy as npimport matplotlib.pyplot as plt
%matplotlib inline
from matplotlib.pylab import rcParams
rcParams['figure.figsize']=20,10from keras.models import Sequential
from keras.layers import LSTM,Dropout,Densefrom sklearn.preprocessing import MinMaxScaler

了解苹果股票数据

其次,我们将开始将数据加载到一个数据帧中,在我们开始操作它之前查看它是一个好的做法。这有助于我们理解我们有正确的数据,并获得一些关于它的见解。

如前所述,在本练习中,我们将使用 Apple 的历史数据。我认为苹果会是一个很好的搭配。和我一起完成这个项目后,你会学到一些技巧,让你有能力使用不同的数据集来练习。

我们将使用的数据框架包含过去一年(2019 年 9 月 16 日-2020 年 9 月 15 日)苹果股票的收盘价。

读出数据

import pandas as pddf = pd.read_csv('aapl_stock_1yr.csv')

头部方法

为了对数据有所了解,我们要做的第一件事是使用 head 方法。当您在 dataframe 上调用 head 方法时,它会显示 dataframe 的前五行。运行这个方法后,我们还可以看到我们的数据是按日期索引排序的。

df.head()

作者图片

尾部法

另一个有用的方法我们称之为尾部方法。它显示数据帧的最后五行。假设您想查看最后七行,您可以在括号之间输入整数 7。

df.tail(7)

作者图片

现在我们对数据有了一个概念。让我们进入下一步,即数据操作,并为预测做好准备。

数据操作

子集化

正如您在前面的截图中看到的,我们的数据框架有 6 列。我们需要全部吗?当然不是。对于我们的预测项目,我们只需要“日期”和“结束/最后”列。那么让我们去掉其他的柱子吧。

df = df[['Date', 'Close']]df.head()

作者图片

数据类型

现在,让我们检查列的数据类型。因为收盘价值中有一个“$”符号,所以它可能不是 float 数据类型。当训练数据时,字符串数据类型不能用于我们的模型,所以我们必须将其转换为浮点或整数类型。

作者图片

在我们将它转换为 float 之前,让我们去掉“$”符号。否则,转换方法会给我们一个错误。

df = df.replace({'\$':''}, regex = True)

太好了!现在,我们可以将“收盘价”数据类型转换为 float。我们还将把“日期”数据转换成日期时间类型。

df = df.astype({"Close": float})df["Date"] = pd.to_datetime(df.Date, format="%m/%d/%Y")df.dtypes

作者图片

索引栏

这将是一小步。我们将数据帧的索引值定义为日期列。这将有助于数据可视化步骤。

df.index = df['Date']

数据可视化

我将与你分享一个简单的折线图,只是为了让你对过去一年的股价变化有一个概念。我们还将在最后使用可视化方法来比较我们的预测和现实。

plt.plot(df["Close"],label='Close Price history')

作者图片

LSTM 预测模型

在这一步中,我们将完成大部分编程工作。首先,我们需要对数据做一些基本的调整。当我们的数据准备好了,我们将使用它来训练我们的模型。作为神经网络模型,我们将使用 LSTM(长短期记忆)模型。当基于时间序列数据集进行预测时,LSTM 模型非常有效。

数据准备

df = df.sort_index(ascending=True,axis=0)data = pd.DataFrame(index=range(0,len(df)),columns=['Date','Close'])for i in range(0,len(data)):
    data["Date"][i]=df['Date'][i]
    data["Close"][i]=df["Close"][i]data.head()

作者图片

最小-最大缩放器

scaler=MinMaxScaler(feature_range=(0,1))data.index=data.Date
data.drop(“Date”,axis=1,inplace=True)final_data = data.values
train_data=final_data[0:200,:]
valid_data=final_data[200:,:]scaler=MinMaxScaler(feature_range=(0,1))scaled_data=scaler.fit_transform(final_data)
x_train_data,y_train_data=[],[]
for i in range(60,len(train_data)):
    x_train_data.append(scaled_data[i-60:i,0])
    y_train_data.append(scaled_data[i,0])

LSTM 模型

在这一步,我们定义了长短期记忆模型。

lstm_model=Sequential()
lstm_model.add(LSTM(units=50,return_sequences=True,input_shape=(np.shape(x_train_data)[1],1)))
lstm_model.add(LSTM(units=50))
lstm_model.add(Dense(1))model_data=data[len(data)-len(valid_data)-60:].values
model_data=model_data.reshape(-1,1)
model_data=scaler.transform(model_data)

训练和测试数据

该步骤包括列车数据和测试数据的准备。

lstm_model.compile(loss=’mean_squared_error’,optimizer=’adam’)
lstm_model.fit(x_train_data,y_train_data,epochs=1,batch_size=1,verbose=2)X_test=[]
for i in range(60,model_data.shape[0]):
    X_test.append(model_data[i-60:i,0])
X_test=np.array(X_test)
X_test=np.reshape(X_test,(X_test.shape[0],X_test.shape[1],1))

预测函数

在这一步中,我们使用在上一步中定义的测试数据来运行模型。

predicted_stock_price=lstm_model.predict(X_test)
predicted_stock_price=scaler.inverse_transform(predicted_stock_price)

预测结果

差不多了,让我们检查一下模型的准确性。我们有大约 250 行,所以我用 80%作为训练数据,20%作为测试数据。

train_data=data[:200]
valid_data=data[200:]
valid_data['Predictions']=predicted_stock_price
plt.plot(train_data["Close"])
plt.plot(valid_data[['Close',"Predictions"]])

准确性可视化(红色:实际,绿色:预测)[图片由作者提供]

[## 每当贝希克居文出版时收到电子邮件。

每当贝希克居文出版时收到电子邮件。通过注册,您将创建一个中型帐户,如果您还没有…

lifexplorer.medium.com](https://lifexplorer.medium.com/subscribe)

恭喜你。!您已经创建了一个 Python 程序来预测一家公司的股票收盘价。现在,你对如何在金融中使用机器学习有了一些想法,你应该在不同的股票上尝试一下。希望你喜欢读我的文章。从事像这样的动手编程项目是提高编码技能的最好方式。

我很高兴你今天学到了新东西。如果您在执行代码时有任何问题,请随时联系我。😊

我是贝希克·居文,我喜欢分享关于编程、教育和生活的故事。订阅我的内容,保持灵感。泰,

AWS 弹性容器服务的逐步指南(附图片)

原文:https://towardsdatascience.com/step-by-step-guide-of-aws-elastic-container-service-with-images-c258078130ce?source=collection_archive---------12-----------------------

部署您的容器并配置为访问 AWS 资源

在这篇文章中,我将展示使用 AWS ECS 部署 docker 容器的过程,并配置它来访问其他 AWS 资源。现在,让我们直接进入核心。

先决条件:对 docker,AWS 的基本了解,你需要有一个具有管理员权限的 AWS 帐户。

建造一个容器

如果您已经准备好要部署的容器,那么您可以跳过这一部分。如果没有,我写了一个最简单的 python 项目这里是,其中有 docker 容器最基本的结构:

ecs-example:
    |_ model
    |    |_ run.py
    |    |_ sample.txt
    |
    |_ docker-entrypoint.sh
    |_ Dockerfile
    |_ requirements.txt

主文件run.py驻留在model文件夹中,它所做的只是将sample.txt上传到s3 (S3 是 AWS 存储数据的简单存储系统)

docker-entrypoint.sh定义了在容器开始时运行的命令

**#!/usr/bin/env bash** export PYTHONPATH=.

python3 model/run.py

所以当容器启动时,它会调用上面写的run.py并将指定的文件加载到 s3。

现在看看我们的Dockerfile

FROM python:3.7-slim

ENV *APP_DIR* /ecs-example

RUN mkdir -p ${*APP_DIR*}

WORKDIR ${*APP_DIR*}

ADD ./requirements.txt ${*APP_DIR*}
RUN pip install -r requirements.txt

COPY ./model ${*APP_DIR*}/model
COPY ./docker-entrypoint.sh ${*APP_DIR*}/docker-entrypoint.sh

ENTRYPOINT ${*APP_DIR*}/docker-entrypoint.sh

它做以下事情,

  1. 设置工作目录
  2. 安装所需的软件包
  3. 将本地文件复制到 docker 容器中
  4. 在容器的起点设置起点

现在我们的演示项目已经设置好了,让我们构建并标记我们的容器,并将它推送到您自己的 docker hub。

在项目根目录中,执行以下操作

docker build -t ecs-example .
(Optional) docker run ecs-example

标记并推送至私有回购

docker tag ecs-example {YOUR_REPO_ACCOUNT}/ecs-example:v1
docker push {YOUR_REPO_ACCOUNT}/ecs-example:v1

现在转到您的私有 docker 注册表,您应该会在您的回购中看到它,如下所示:

现在我们已经将项目装箱并发布了,让我们开始部署吧。

在 ECS 上部署

ECS 代表弹性集装箱服务。顾名思义,这是一项专门用于管理 docker 容器的服务,但其优势在于简化了容器部署的过程,并避免了来自用户的繁重工作。简而言之,这可能是在云上部署容器的最简单的方式,并且具有适当的标准。(有关更多信息,您可以在此处阅读文档

ECS 概述

首先,去你的 AWS 控制台,搜索弹性容器服务或者仅仅是 ECS。

你开始的最快方法可能是点击首页的Get Started按钮,并遵循指导,但在这篇文章中,我们将手动构建每个组件,我相信这将使你对每个部分有更深的理解,而且对于我们的容器来说,访问 S3,它需要额外的配置,这是“开始”不允许的。

首先,我们来了解一下 ECS 中的组件,

  1. 容器定义:定义你的容器镜像、环境变量、存储挂载等等。
  2. 任务定义:包装你的容器,是你部署的蓝图,为你的容器指定角色,如何拉取图像等等。
  3. 服务:管理要部署多少容器实例,它应该驻留在哪个网络中等等。
  4. 集群:包含 VPC、子网等。

创建一个集群

首先,让我们创建一个集群。选择边栏上的集群并选择Create Cluster

选择Networking only,并选择下一步。Networking only是为 Fargate taks 建造的。与 EC2 任务相反,

Fargate 启动类型允许您运行您的容器化应用程序,而无需供应和管理后端基础架构。当您使用与 Fargate 兼容的任务定义运行任务时,Fargate 会为您启动容器。

基本上,使用这种类型,AWS 可以为您处理大部分基础设施,因此您最不用担心。

下一步,输入您的集群名称(这里我使用 ecs-example-cluster),选择创建新的 VPC (如果您没有的话),然后启用容器洞察(这将提供 CloudWatch 监控和帮助调试)。

并点击创建。您的集群应该马上就准备好了。

为您的集群设置了一组资源。现在让我们转到任务定义。

创建任务定义

现在让我们开始创建您的容器蓝图。在工具条上,选择任务定义并选择创建新的任务定义

选择 Fargate (如果您希望 AWS 为您处理 infra),它将引导您:

创建任务角色

为您的任务定义命名。并为您的容器选择一个任务角色,但是等等,什么是任务角色?如输入中所解释的,

任务角色 :可选的 IAM 角色,任务可以使用它向授权的 AWS 服务发出 API 请求。在 IAM 控制台中创建一个 Amazon 弹性容器服务任务角色

记得我们的容器需要上传一个文件到 S3 吗?因此,要允许您的容器访问 s3,它需要一个角色来授权它这样做。(更多信息,请点击此处获取官方文档)

现在在一个新标签页中打开 AWS 控制台。

选择服务 IAM →选择角色创建角色

对于选择可信实体类型部分,选择 AWS 服务

对于选择将使用这个角色的服务,选择弹性容器服务

对于选择您的用例,选择弹性容器服务任务并选择下一步:权限

对于我们访问 s3 的服务,选择 Amazons3FullAccess (这不是授予 S3 对服务的完全访问权的最佳实践,您可能需要通过创建新的策略来将服务限制到某个桶)。

对于添加标签(可选),输入您想要与 IAM 角色关联的任何元数据标签,然后选择下一步:查看

对于角色名称,输入您的角色名称。对于本例,键入ECSs3AccessTaskRole来命名角色,然后选择创建角色来完成。

现在回到任务定义

将您刚刚创建的角色选择到任务角色中。

对于任务执行 IAM 角色,该角色有助于从 docker 寄存器中提取图像,因此如果您还没有该角色,我们首先需要创建它。角色创建过程与上面类似,您可以在这里按照步骤操作。(这里创建的角色名称是ecsTaskExecutionRole!)

而对于任务大小,我们都选择最小,当然我们的任务简单,不需要太多资源。

任务执行角色不同于我们刚刚创建的任务角色,如创建过程中所述:

任务执行角色 :这个角色是任务需要的,代表你拉容器镜像,发布容器日志到 Amazon CloudWatch。

任务角色 :可选的 IAM 角色,任务可以使用它向授权的 AWS 服务发出 API 请求。在 IAM 控制台中创建一个 Amazon 弹性容器服务任务角色

从堆栈溢出到这里的一个很好的区别解释。

添加容器

现在最重要的是,让我们来看看容器的定义。输入以下内容:

对于图像* ,输入您的私人图像注册表 url。勾选私有存储库认证,因为我们的映像驻留在 docker hub 上的私有回购中。为了让我们的服务访问我们的私人注册表,我们需要告诉代理我们的帐户和密码。AWS 上管理秘密的方式是使用秘密管理器

创建秘密

再次转到 AWS 控制台→选择机密管理器→存储新机密→其他类型的机密

输入纯文本:

{
  "username": {YOUR_DOCKER_ACCOUNT},
  "password": {YOUR_DOCKER_PWD}
}

选择下一步,给你的秘密一个名字,其他的就用默认的。

创建后,你应该有这样的东西:

点击您的秘密,您可以检索您的秘密 ARN,并输入这个 ARN 到上面的容器定义!

虽然我们已经在容器中输入了我们的秘密,但是请记住,fargate 代理使用任务执行角色从您的私有注册表中提取图像,您可以这样理解这个过程:

因此,下一步是将这个秘密添加到我们上面创建的执行角色中。

向任务执行角色添加机密

现在再次转到 IAM 下的执行角色,添加内联策略:

选择 Json 格式并输入、

{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Effect": "Allow",
            "Action": [
                "secretsmanager:GetSecretValue"
            ],
            "Resource": [
               {YOUR_SECRET_ARN}
            ]
        }
    ]
}

我知道很累,但我们就要完成了!现在我们的任务定义完成了!回到我们的任务定义,保留其他为默认,并点击创建

创建服务并部署任务定义

我们已经完成了最难的部分,现在我们需要的是创建最后一个组件——服务并部署我们的任务!

在侧面板上,单击集群

选择 ECS-示例-集群

在服务选项卡下,选择创建,并输入以下内容:

选择下一步,对于 VPC,只需选择我们在创建集群会话中创建的 VPC 和子网,其他保持默认,最后创建服务。

现在转到“service”选项卡,您应该会看到作业正在运行…

为了验证我们的工作,请转到 s3,您应该看到(前提条件是,您应该在此之前创建了您的存储桶):

搞定了。我们的容器成功部署,文件上传到 S3!

删除集群

要删除我们的集群,首先删除我们的服务,然后删除集群,这需要几分钟才能生效。

如何使用谷歌 Colab 在书籍上训练 GPT-2 的逐步指南

原文:https://towardsdatascience.com/step-by-step-guide-on-how-to-train-gpt-2-on-books-using-google-colab-b3c6fa15fef0?source=collection_archive---------8-----------------------

我是如何成为一名***员的

共产主义者的人工智能是用 GPT-2 训练的。它阅读马克思、法农、葛兰西、列宁和其他革命作家的书籍。该项目旨在看看 GPT-2 能理解多深的哲学思想和概念。
结果相当有趣,也很有希望,因为我们见证了 A。我合乎逻辑地扭曲了我们给它的任何句子,使之成为抨击资本主义和为“工人”而斗争的借口。只要有可能,它就呼吁革命。

这是使用无条件生成的样本生成的——没有人的输入

此外,在介绍了无政府共产主义作家克鲁泡特金之后,我注意到“共产主义人工智能”倾向于使用更具攻击性的词语。另一方面,当我们介绍德·波伏娃的《第二性》(The Second Sex)时,《共产主义者人工智能》(The Communist A.I)有点错过了这本书的重点,在某些时候谈到了资本家的恋物癖——或者说它错过了重点?

而讨论人工智能的话语和哲学很有趣,比如回答“一个人如何变得自由”的问题,这篇文章旨在展示一个简单的分步指南,告诉你如何只用 GPT-2、谷歌 Colab 和你的谷歌硬盘创建你自己的人工智能角色。那我们开始吧。
如果你想阅读更多关于共产主义人工智能的信息,请点击此链接

准备您的 Google Colab 笔记本

我们将使用 Google Drive 来保存我们的检查点(检查点是我们最后保存的训练模型)。一旦我们训练好的模型被保存,我们就可以在任何时候加载它来生成有条件和无条件的文本。

首先,把你的 Colab 的运行时间设置为 GPU,以后你会感谢我的。
使用以下代码连接您的 Google Drive:

from google.colab import drive
drive.mount('/content/drive')

现在您已经连接了 Google Drive,让我们创建一个检查点文件夹:

%cd drive
%cd My\ Drive
%mkdir NAME_OF_FOLDER
%cd /content/
!ls

现在让我们克隆我们将使用的 GPT-2 存储库,它来自 nnsheperd 的 awesome 存储库(它来自 OpenAI,但添加了令人敬畏的 train.py),我添加了一个 conditional_model()方法,该方法允许我们一次传递多个句子,并返回一个包含相关模型输出样本的字典。它还让我们避免使用 bash 代码。

[!git clone](https://github.com/mohamad-ali-nasser/gpt-2.git) [https://github.com/mohamad-ali-nasser/gpt-2.git](https://github.com/mohamad-ali-nasser/gpt-2.git)

现在让我们下载我们选择的模型。我们将使用相当不错的 345M 型号。我们将使用该型号而不是 774M 或 1558M 的原因是训练时 Colab 中可用的 GPU 内存有限。也就是说,如果我们想使用预训练的 GPT-2,而不需要对我们的语料库进行任何微调或训练,我们可以使用 774M 和 1558M。

%cd gpt-2
!python3 download_model.py 345M

现在模型已经安装好了,让我们准备好语料库并加载检查点,以防我们之前已经训练过模型。

# In Case I have saved checkpoints
!cp -r /content/drive/My\ Drive/communist_ai/gpt-2/checkpoint/run1/* /content/gpt-2/models/345M

下载文本并将其合并到一个语料库中

让我们创建并移动到我们的语料库文件夹,并获得这些文本。

%cd src
%mkdir corpus
%cd corpus/
!export PYTHONIOENCODING=UTF-8

我在 Github 存储库中有我的文本,但是您可以用您需要的任何链接替换 url 变量。你也可以手动将你的文本文件上传到 Google Colab,或者如果你的 Google Drive 中有文本文件,那么只需将 cd 放入该文件夹即可。

import requests
import osfile_name = "NAME_OF_TEXT.txt"if not os.path.isfile(file_name):
    url = "https://raw.githubusercontent.com/mohamad-ali-nasser/the-
           communist-ai/master/corpus/manifesto.txt?
           token=AJCVVAFWMDCHUIOOUDSD2FK6PYTN2"
    data = requests.get(url)with open(file_name, 'w') as f:
         f.write(data.text)
f.close()

现在文本已经下载完毕,使用下面的代码将多个文本文件合并成一个文件。如果您将只使用一个文本文件,请忽略此代码。

# Get list of file Namesimport glob
filenames = glob.glob("*.txt") # Add all texts into one filewith open('corpus.txt', 'w') as outfile:
       for fname in filenames:
            with open(fname) as infile:
                  outfile.write(infile.read())
outfile.close()

下载库和 CUDA

现在我们已经准备好了一切,让我们准备环境。我们将从安装需求文件开始。(如果你碰巧用你本地的 Jupyter 笔记本来使用 GPT-2,那么在使用 download_model.py 之前安装需求文件)

# Move into gpt-2 folder
%cd /content/gpt-2!pip3 install -r requirements.txt

现在,以下是可选的,因为如果您想使用 774M 型号和 1558M 型号,它们是必需的。我使用过没有这些的 334M,但我还是建议这样做,尤其是 CUDA,因为你的模型会运行得更快,这些可能会修复一些你可能会遇到的随机错误。

!pip install tensorflow-gpu==1.15.0
!pip install 'tensorflow-estimator<1.15.0rc0,>=1.14.0rc0' --force-reinstall

现在安装 Cuda v9.0:

!wget [https://developer.nvidia.com/compute/cuda/9.0/Prod/local_installers/cuda-repo-ubuntu1604-9-0-local_9.0.176-1_amd64-deb](https://developer.nvidia.com/compute/cuda/9.0/Prod/local_installers/cuda-repo-ubuntu1604-9-0-local_9.0.176-1_amd64-deb)
!dpkg -i cuda-repo-ubuntu1604-9-0-local_9.0.176-1_amd64-deb
!apt-key add /var/cuda-repo-*/7fa2af80.pub
!apt-get update
!apt-get install cuda-9-0!export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:/usr/local/cuda-9.0/lib64/

重启运行时并移回 GPT2 文件夹

%cd gpt-2

让我们训练模型:

现在是我们一直在等待的时刻,对模型进行微调。复制下面的一行程序并运行它。

!PYTHONPATH=src ./train.py --dataset src/corpus/corpus.txt --model_name '345M'

该模型将加载最新的检查点,并从那里开始训练(似乎加载以前训练过的检查点并添加到其中会导致您在使用 Colab 中的 345M 时遇到内存问题)。
还可以指定批次数和学习率。批次数量真正的整体好处是训练的速度,默认的批次大小是 1,增加批次大小会导致你遇到内存问题,所以要小心你增加多少,特别是当你在一个 GPU 上运行时,我使用的批次大小是 1,尝试 2 或 4,并在评论中添加你的结果。

虽然提高学习率可以提高训练的速度,但它可能会导致模型卡在局部最小值(梯度)甚至超调,因此我建议保持学习率不变,或者如果损失停止下降,则降低学习率。默认学习率为 0.00001。

!PYTHONPATH=src ./train.py --dataset src/corpus/corpus.txt --model_name '345M' --batch_size 1 --learning_rate 0.00001

该模型将每 1000 步保存一个检查点。你可以持续运行它几分钟、几小时或几天,这完全取决于你,只要确保如果你有一个小文本,你不要过度拟合模型。
要停止模型,只需“停止”它,它将保存最后一个训练步骤(因此,如果您在步骤 1028 停止,您将有两个检查点 1000 和 1028)。
注意:当在训练 Colab 时停止模型时,它可能看起来没有反应并保持训练,为了避免这种情况,在它训练时,清除输出,然后停止它,这将节省您的几次点击。

现在模型已经训练好了,让我们将检查点保存在 Google Drive 中:

!cp -r /content/gpt-2/checkpoint/ /content/drive/My\ Drive/checkpoint

将新保存的检查点复制到模型的目录中

!cp -r /content/gpt-2/checkpoint/run1/* /content/gpt-2/models/345M/

生成条件文本

import os
%cd src
from conditional_model import conditional_model
%cd ..

运行下面的代码,了解该方法的参数是什么:

conditional_model??

我建议设置一个种子,这样你可以得到一些可重复的结果。参数语句接受一个字符串或字符串列表,并返回一个字典,其中输入作为键,输出样本作为值。

现在来看看魔术:

conditional_model(seed=1,sentences=['How are you today?', 'Hi i am here'])

你现在已经根据你选择的书籍对你的 GPT-2 进行了微调,并且创建了你自己的人工智能,祝贺你!!

如果你觉得这个教程有帮助,请分享并开始 GitHub repo—https://github.com/mohamad-ali-nasser/gpt-2。谢谢

别忘了跟着共产主义者 A.I

LinkedIn 上联系,在 Twitter 上关注。

您也可以查看我的组合网站,了解更多项目。

编码快乐!

分步指南:使用 Python 进行数据科学的比例采样

原文:https://towardsdatascience.com/step-by-step-guide-proportional-sampling-for-data-science-with-python-8b2871159ae6?source=collection_archive---------14-----------------------

从头开始使用 python 理解数据科学所需的比例采样的概念和实现

图片由 jakob5200 来自 Pixabay

骰子的形象让我想起了我小时候玩的游戏,比如蛇和梯子或者鲁道。

掷骰子时,在任何时间间隔可能出现的数字的可能性是 1-6。六个通常是最好的结果,而一个在大多数情况下可能不是很好。

然而,如果你能比其他数字更多次地掷出数字 6,这不是很棒吗?

这个技巧正是比例采样所实现的,我们将在下一节中进一步研究其逐步实现的细节。但首先,让我们理解这些概念的必要性。

数学在数据科学和机器学习中扮演着重要的角色。

概率统计就是这样一个基本要求。概率涉及预测未来事件发生的可能性,而统计学涉及对过去事件发生频率的分析。我们利用这些概念来处理机器学习和数据科学问题的一个重要方面叫做采样

在统计学、质量保证和调查方法学中,抽样是从统计总体中选择个体子集,以估计总体特征。统计学家试图用样本来代表所讨论的人口。

基本上,抽样是统计分析中使用的一个过程,其中从一个较大的总体中抽取预定数量的观察值。

与测量整个人口相比,抽样的两个主要优点是成本更低和数据收集更快。

有许多抽样方法,如随机抽样、均匀抽样等。在本文中,我们将主要分析比例抽样的逐步方法。

比例抽样是一种按重量比例选取元素的方法,即对象的重量越大,被选中的机会就越大。

参考前面所述的骰子示例,像五或六这样的较大数字比像一或二这样的较小数字更有可能被选中。

让我们通过一些一步一步的程序实现和一些 python 代码来理解这一点。

林赛·亨伍德在 Unsplash 上的照片

比例取样的逐步方法;

执行比例采样所需导入的唯一附加库是 python 中的 random 模块。该模块可以按如下方式导入:

import random

这个模块是唯一的额外要求。剩下的步骤可以用简单的 python 代码来执行。

在我们继续之前,让我们定义我们的输入。作为一个例子,我将使用一个从 1 到 6 的数字列表来表示骰子。你可以随意选择你的问题的任意输入。

A = [1,2,3,4,5,6]

第一步:

计算输入的所有元素的总和。

Sum = A[0] + A1 + ……。+ A[n]
其中,n =已定义输入的最后一个元素的索引

代码:

在上面的代码块中,我们将输入列表存储在变量“a”中。我们将继续计算列表中所有元素的总和。我已经使用了上面提到的简单方法,但是如果你觉得舒服的话,你也可以使用一个具有高级功能的更紧凑的方法。

第二步:

计算输入列表中每个元素的归一化总和。

A0 ' = A[0]/Sum;a1 ' = A1/Sum;………..
其中,A’表示每个元素的归一化和

代码:

下一个代码块计算分配给输入的每个元素的归一化和。我使用了一个字典变量“C”来相应地存储这些值。

第三步:

使用所有标准化值计算每个元素的累积和。

A0 ~ = A0’;A1 ~ = A0 ~+A1 ';…….
其中,A~代表每个元素的累积和

代码:

上面的代码块使用我们在上一步中找到的标准化值来计算每个元素的累积和。我使用了另一个字典变量‘D ’,它将存储所有需要的累积值。

第四步:

在(0,1)范围内选择一个随机值。

r =随机均匀(0.0,1.0)

如果 r≤ A0~ =返回 choice-1;
else 如果 r≤ A1~ =返回 choice-2;
………..依此类推,直到覆盖所有元素。

代码:

在下一个代码块中,我使用了我们在程序开始时导入的随机模块。使用 0-1 范围内的随机数,我们可以计算加权和出现的概率。

观察代码,尝试直观地理解我们在上面的代码块中试图实现的内容。与较小的数字相比,较大的数字有更大的机会被选中,因为它们之间的桥梁在范围内出现得更高。

如果你对这一步感到困惑,我强烈建议你试着把它写在纸上,并解决这个计算是如何工作的。

现在让我们进入最后一个代码块,并理解最后一步。

第五步:

最终实现。

代码:

上面显示的最后一个代码块用于随机数生成和计数。上面的函数用于运行第一个定义的函数 99 次,并检查每个发生可能性的计数。

期望的输出对于数字 6 具有最高的计数,对于数字 5 具有第二高的计数,依此类推,直到我们对于数字 1 具有最少的计数。

第一次运行的一个输出示例如下所示。

注意:由于我们使用的是随机函数,每次输出都会不同。所以如果你得不到和我一样的输出也不用担心。要考虑的重要事情是哪个数字的计数最大。

输出:

[6, 5, 4, 3, 2, 1]
count of 6 is 30
count of 5 is 24
count of 4 is 20
count of 3 is 11
count of 2 is 10
count of 1 is 4

每次运行程序时,输出可能会有所不同。不要求您获得如上所示的相同输出。出现这种情况的原因是因为我们使用了随机模块。需要注意的要点是,与其他数字相比,最大的重量数字具有更高的计数。

这样,我们成功地实现了比例抽样。这个概念在数据科学的许多方面都非常重要,在这些方面,需要给予较大的权重更高的优先级。

骰子的引用就是一个很好的例子。如果我有这个骰子,那么我赢得游戏的机会会高得多!

Sebastien Gabriel 在 Unsplash 上的照片

结论:

至此,我们已经到了文章的结尾。我们理解数学对于数据科学的重要性,特别是在使用骰子的例子所需的概率和统计方面。

然后,我们进一步讨论了采样的主题及其在数据科学领域的优势。然后,我们具体探讨了比例抽样技术,一步一步的指南和完整的代码。

如果你对我们今天在这篇文章中提到的比例抽样有任何疑问,请在评论区联系我。

看看我的其他一些文章,你可能会喜欢读!

[## 2020 年及以后最受欢迎的 10 种编程语言

讨论当今 10 种最流行的编程语言的范围、优缺点

towardsdatascience.com](/10-most-popular-programming-languages-for-2020-and-beyond-67c512eeea73) [## 必须使用内置工具来调试你的 Python 代码!

python 调试器模块指南,包含有用的代码和命令。有效且高效地利用这一工具…

towardsdatascience.com](/must-use-built-in-tool-for-debugging-your-python-code-d5f69fecbdbe) [## 带有完整代码片段和有用链接的 5 个最佳 Python 项目创意!

为 Python 和机器学习创建一份令人敬畏的简历的 5 个最佳项目想法的代码片段和示例!

towardsdatascience.com](/5-best-python-project-ideas-with-full-code-snippets-and-useful-links-d9dc2846a0c5) [## OpenCV:用代码掌握计算机视觉基础的完全初学者指南!

包含代码的教程,用于掌握计算机视觉的所有重要概念,以及如何使用 OpenCV 实现它们

towardsdatascience.com](/opencv-complete-beginners-guide-to-master-the-basics-of-computer-vision-with-code-4a1cd0c687f9)

谢谢你们坚持到最后。我希望你们都喜欢这篇文章。祝大家有美好的一天!

ECDFs 分步指南——强大的直方图替换

原文:https://towardsdatascience.com/step-by-step-guide-to-ecdfs-a-robust-histogram-replacement-8b2309ac9c1c?source=collection_archive---------43-----------------------

用 ECDFs 一劳永逸地抛弃宁滨偏见

照片由尼克·费因斯Unsplash 上拍摄

每个人都喜欢好的数据可视化。尽管如此,他们不应该把解释留给观众,就像直方图一样。今天我们将回答宁滨偏差如何在分析中误导你,以及如何用 ECDF 图的力量来防止这个问题。

这篇文章回答了以下问题:

  • 直方图有什么问题——什么时候应该避免使用它们
  • 如何用 ECDFs 替换直方图——一种更健壮的检查数据分布的方法
  • 如何在单个图表中使用和解释多个 ECDFs 比较不同数据段之间的分布

事不宜迟,我们开始吧!

直方图有什么问题?

正如来自数据营的贾斯汀·博伊斯所说——宁滨偏见——我完全同意。这意味着在直方图上使用不同的区间大小会使数据分布看起来不同。不要相信我的话,下面的例子不言自明。

首先,我们将导入几个用于数据分析和可视化的库,并直接从 web 加载 Titanic 数据集:

import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
import seaborn as sns
sns.set()

df = pd.read_csv('https://raw.githubusercontent.com/datasciencedojo/datasets/master/titanic.csv')

如果您不熟悉数据集,下面是前几行的样子:

作者图片

df.dropna(subset=['Age'], inplace=True)

接下来,让我们声明一个可视化直方图的函数。它需要很多参数,但在我们的例子中最重要的参数是:

  • x–表示我们要为其绘制直方图的单个属性
  • nbins–直方图应该有多少个箱
def plot_histogram(x, size=(14, 8), nbins=10, title='Histogram', xlab='Age', ylab='Count'):
    plt.figure(figsize=size)
    plt.hist(x, bins=nbins, color='#087E8B')
    plt.title(title, size=20)
    plt.xlabel(xlab, size=14)
    plt.ylabel(ylab, size=14)

plot_histogram(df['Age'], title='Histogram of passenger ages')
plot_histogram(df['Age'], nbins=30, title='Histogram of passenger ages')

我们将使用提到的函数两次,第一次用 10 个面元制作直方图,第二次用 30 个面元制作直方图。结果如下:

有 10 个条块的直方图:

作者图片

有 30 个条柱的直方图:

作者图片

数据是相同的,但不同的箱大小会导致宁滨偏差——由于视觉表现的细微变化,对相同数据的感知不同。

我们能做些什么来解决这个问题?ECDF 的阴谋终于来了。

ECD fs——更强大的直方图替换

ECDF 代表经验累积分布函数。别担心,它没有听起来那么花哨,也相对容易理解。

像直方图一样,ECDFs 显示单个变量的分布,但方式更有效。我们之前已经看到了直方图是如何由于不同的 bin 大小选项而产生误导的。ECDFs 就不是这样了。ECDFs 显示每一个数据点,并且该图只能以一种方式解释。

将 ECDFs 视为散点图,因为它们也有沿 X 轴和 Y 轴的点。更准确地说,这是 ECDFs 在两个轴上显示的内容:

  • x 轴——我们正在测量的量(上面例子中的年龄)
  • Y 轴-值小于相应 X 值的数据点的百分比(在每个点 X,Y%的值小于或等于 X)

为了实现这种可视化,我们需要先做一些计算。需要两个阵列:

  • X —排序数据(从最低到最高排序年龄列)
  • y-最大值为 1 的均匀间隔数据点列表(如 100%)

以下 Python 片段可用于计算 Pandas 数据帧中单个列的 XY 值:

def ecdf(df, column):
    x = np.sort(df[column])
    y = np.arange(1, len(x) + 1) / len(x)
    return x, y

这是一个非常简单的问题。不过,我们还需要一个函数。这个是用来做一个实际的图表的:

def plot_ecdf(x, y, size=(14, 8), title='ECDF', xlab='Age', ylab='Percentage', color='#087E8B'):
    plt.figure(figsize=size)
    plt.scatter(x, y, color=color)
    plt.title(title, size=20)
    plt.xlabel(xlab, size=14)
    plt.ylabel(ylab, size=14)

让我们使用这个函数来制作一个年龄属性的 ECDF 图:

x, y = ecdf(df, 'Age')

plot_ecdf(x, y, title='ECDF of passenger ages', xlab='Age')
plt.show()

作者图片

但是等等,我该怎么解读这个?这很容易。这里有几个例子:

  • 大约 25%的乘客年龄在 20 岁或以下
  • 大约 80%的乘客年龄在 40 岁以下
  • 大约 5%的乘客年龄在 60 岁或以上(1——百分比)

那不是很容易吗?但是等等,派对不会就此结束。接下来我们来探讨如何绘制和解释多个 ECDFs。

多个 ECDFs

在 Titanic 数据集中,我们有 Pclass 属性,它表示乘客类别。即使在今天,这种等级组织也是旅行中的典型,因为头等舱是为较富裕的人保留的,其他的舱是其他人所在的地方。

借助 ECDFs 的强大功能,我们可以探索乘客年龄是如何在各个阶层中分布的。我们需要调用ecdf()函数三次,因为船上有三个类。代码的其余部分归结为数据可视化,这是不言自明的:

x1, y1 = ecdf(df[df['Pclass'] == 1], 'Age')
x2, y2 = ecdf(df[df['Pclass'] == 2], 'Age')
x3, y3 = ecdf(df[df['Pclass'] == 3], 'Age')

plt.figure(figsize=(14, 8))
plt.scatter(x1, y1, color='#087E8B')
plt.scatter(x2, y2, color='#f1c40f')
plt.scatter(x3, y3, color='#e74c3c')
plt.title('ECDF of ages across passenger classes', size=20)
plt.xlabel('Age', size=14)
plt.ylabel('Percentage', size=14)
plt.legend(labels=['Pclass = 1', 'Pclass = 2', 'Pclass = 3'])
plt.show()

结果可视化如下所示:

作者图片

正如我们所看到的,第三个班级(红色)有很多孩子,而第一个班级(绿色)没有这么多孩子。第一个班级的学生年龄也很大:

  • 只有 20%的头等舱乘客年龄超过 50 岁
  • 只有 20%的二等舱乘客年龄超过 40 岁
  • 只有 20%的三等舱乘客年龄超过 34 岁

这些只是粗略的数字,所以如果我犯了一两年的错误,不要引用我的话。现在您知道了如何使用和解释 ECDFs。让我们在下一部分总结一下。

离别赠言

不要把任何东西留给数据科学中的个人解读。仅仅因为你喜欢在柱状图中看到 15 个柱,并不意味着你的同事也喜欢。如果直观地解释,这些差异可能会导致不同的数据解释。

ECDFs 就不是这样了。现在,您已经对它们有了足够的了解,可以将它们包含在下一个数据分析项目中。乍一看,它们似乎令人望而生畏,但我希望这篇文章做出了必要的澄清。

感谢阅读。

加入我的私人邮件列表,获取更多有用的见解。

喜欢这篇文章吗?成为 中等会员 继续无限制学习。如果你使用下面的链接,我会收到你的一部分会员费,不需要你额外付费。

[## 通过我的推荐链接加入 Medium-Dario rade ci

作为一个媒体会员,你的会员费的一部分会给你阅读的作家,你可以完全接触到每一个故事…

medium.com](https://medium.com/@radecicdario/membership)

原载于 2020 年 10 月 23 日 https://betterdatascience.com

在数据科学面试中解释你的 ML 项目的逐步指南。

原文:https://towardsdatascience.com/step-by-step-guide-to-explaining-your-ml-project-during-a-data-science-interview-81dfaaa408bf?source=collection_archive---------1-----------------------

在结尾有一个额外的样本脚本,让你谨慎地展示你的技术技能!

这是我最近开始的 面试问题 系列的第二部分。在 第 1 部分 中,我们谈到了另一个与扩展您的 ML 模型有关的重要数据科学面试问题。一定要去看看!

Pinterest

面试可能会令人生畏,但解释一个你付出血汗的项目却不应该!

一个典型的开放式问题经常在面试(第一轮和第二轮)中出现,它与你的个人(或兼职)项目有关。这个问题可以有多种形式,例如:

  • 你能给我们介绍一下你最近完成的一个项目吗?
  • 你能告诉我们你参与一个具有挑战性的项目的时候吗?
  • 你参与过哪些有趣的项目?

相信我,这个问题是你在面试中遇到的最好的事情。它让你把谈话引向你喜欢的方向,把注意力集中在你有信心的主题/ML 框架/算法上!

在这篇文章中,我们将解码如何挑选一个有趣的项目,如何组织我们的答案以便我们不会错过任何重要的细节,并且学习一些应该成为你答案一部分的时髦词汇。所有这一切都在 10 个简单的步骤中完成!

第一步:选择一个项目。

不用说,在选择一个项目来展示你的技术实力时,要确保它能与你申请的公司产生共鸣。

例如,对于一家电子商务公司,我会选择零售数据集,对于一家金融科技公司,我会选择贷款申请数据集,而对于一家医疗保健公司,我会选择新冠肺炎或乳腺癌数据集。诀窍是根据你的目标受众选择一个项目。我向 Kaggle 发誓,我会提供高质量的数据集和一些分析笔记本来帮助你开始。

此外,在你的 kitty 下拥有一些来自不同部门的端到端项目实际上是一个好主意。

第二步:解释数据源。

开始你的解释,具体说明你从哪里得到的数据。

这些数据可能是你在上一家公司提供/收集的。也许你做这个项目是为了好玩,通过 Kaggle 提取了所需的数据。你甚至可以提到它是一些在网上免费提供的开源数据。也许你使用第三方 API(Twitter 数据经常发生)挖掘数据(当然是道德上的)。无论是哪种情况,确保你透露了数据的来源。此外,简要概述数据集中的一些列/特征。

第三步:解释你在这个项目背后的目标。

请具体说明你在这个项目中想要达到的目标。

这可能是一个区分批准和拒绝贷款申请的分类问题,一个预测房价的回归问题,一个推荐系统的冷启动问题,一个为目标广告寻找相似用户的聚类问题。从面试官的角度来看,绝对清晰地解释项目内容是最重要的。

步骤 3:准备数据集。

这是您讨论数据清理、数据争论、处理异常值、多重共线性、重复删除、特征工程、特征标准化等以及处理它们的技术的地方。

这个想法是要提到你用来针对上述每个数据准备步骤的实际技术。例如,明确声明,库克距离超过平均值 3 倍的观察值被视为异常值。超过 10 的 VIF (方差膨胀因子)值被视为表示多重共线性。一个热编码(或标签编码)用于处理分类数据。数字数据经过缩放/标准化以确保所有特征都在同一比例上。进行了 80:20 列车测试分割以确保没有数据泄漏。使用 t-SNE 图来查看类之间的可见分离(在分类问题的情况下)。

步骤 4:陈述 KPI 或绩效指标

对你的研究问题最重要的是什么——准确度、精确度、回忆、假阳性、假阴性等等?

每个 ML 模型都有一些你试图优化的指标。它可能因人而异,因问题而异,因利益相关者而异,甚至因部门而异。医疗保健数据科学家必须确保他(或她)的模型具有更少的假阴性,因为如果进行不正确的癌症诊断,可能会让患者付出生命的代价。另一方面,安装在购物中心的检测商店扒手的系统不得不担心太多的误报,因为这将意味着给无辜的购物者带来巨大的尴尬。

此外,如果出现分类问题,请确保您指定了您的数据集是不平衡的还是平衡的,这主要是因为您对性能指标的选择在很大程度上取决于您的数据集中类的分布。

步骤 5:基线模型

你怎么知道你创建的模型比现有的更好呢?

这是经常被忽视的一步,但却非常重要。我见过很多人在面试官的后续问题是— 时答非所问,那么请告诉我,你为什么认为你的模型很好?

有一个可以用来比较最终模型的基线是很重要的。更多的时候,你可以通过快速的谷歌搜索来选择一个基线——在 MNIST 数据集上达到的最高准确率是多少?或者网飞的推荐系统 Cinematch 的准确度如何。如果你找不到你的领域/问题的基线,你总是可以自己创建一个。

基线模型是一种设置简单并且有合理机会提供良好结果的模型。例如,在冰淇淋销售的时间序列预测的情况下,我的基线(阅读:愚蠢)模型可能只使用今天的数据来预测明天。**

第六步:解释培训过程

解释为什么选择特定的算法。

总是从基本的开始,使用交叉验证抽查几个算法,然后选择具有最高性能指标值的算法(在步骤 4 中指定)。根据我的经验,这总是归结为两三种算法,它们的性能只有细微的差别。在这三个中,我个人倾向于选择像 Random Forest、XG Boost、CART 等这样的组合模式。(特别是因为它们倾向于通过将来自多个模型的预测组合在一起来提高预测准确性)。

但是嘿,那是我的推理!您可能很乐意选择线性回归作为您的首选模型,特别是因为它很容易向非技术风险承担者解释。总而言之,一定要记得和你的面试官分享你的模特选择决定。

步骤 7:解释模型调整过程

你是如何提高你的模型的准确性的?在这个过程中,你遇到了哪些挑战?

诀窍是谈论你如何提高精度同时防止高方差(或过拟合)问题。谈谈 超参数调谐 采用网格搜索还是随机搜索。另外,说明你是否使用了某种过采样/欠采样技术来平衡你的数据集?在你的 ML 工作流程中强调管道的使用,以避免数据泄露和随后的过度拟合。解释你如何使用 学习曲线 来跟踪损失函数。

至于挑战,这些都是个人经历所特有的。我将在最后的示例脚本中解释我最大的挑战。

第八步:模型部署流程

你的模型是放在你的 Jupyter 笔记本里,还是放在外面让其他人也能欣赏?

通常,面试官在寻找潜在的数据科学新人,他们知道如何将他们的模型包装在一个漂亮的小容器中并向世界展示。这可以是 web 应用程序或 API 的形式。我强烈建议多走一步,学习如何做其中的一项。完全的初学者可以查看这篇关于如何使用 Flask 框架将模型部署为 API 的文章。

第九步:准备一些备份问题!

如果你要做一些不同的事情,那会是什么?如果我要改变这个项目中的条件 X,你的方法会如何改变?

一旦你解释完你的项目,像上面这样的问题肯定会被问到。而且很多时候,这是一个好兆头!这意味着面试官在倾听,并真诚地想知道更多关于你的工作。试着为你的项目想一些不同的事情——例如,我会试着获得无偏见的数据(例如,一个有相等的男性和女性代表的数据),我会用堆叠模型做实验,我会用不同的分类阈值重新评估我的混淆矩阵,等等。

第十步:记得呼吸!

不要急着完成!享受这个过程,为你的观众编织一个美丽的故事。

我知道将一个耗时 3-4 周的项目浓缩成 90 秒钟的电梯营销会有多难。但问题不在于你做了多少工作,而在于你能把多少工作有效地传达给面试官。所以呼吸…

顶空

现在,用一个示例脚本把它们结合起来!!!

额外收获:这个问题的答案样本

问——那么,你能告诉我们你最近做了什么项目吗?

肯定的。我做了很多,特别是在锁定的情况下,但我想我会选择我最喜欢的,因为它为我清除了许多数据科学基础。博士实习期间,我在给一家专门给二手车贷款的公司提供咨询。他们试图在尽可能短的时间内实现评估贷款申请流程的自动化。所以基本上,我处理的是一个二元分类,但是是一个不平衡的分类问题——被批准的申请数量远远多于被拒绝的申请数量。

由于数据不平衡,我决定使用 F1 作为性能指标,因为它减少了误报和漏报。该数据集由该公司自己提供,包含年龄、汽车类型、贷款金额、存款、信用评分等特征。作为探索性数据分析阶段的一部分,我使用 Cook's distance 处理异常值,使用 VIFs 处理多重共线性,删除重复项,使用 KNNImputer 处理缺失值,并对数据执行 80:20 分割。分类特征和数字特征分别被热编码和归一化。所有的分析都是使用 SkLearn 进行的。

对于基线模型,我选择了一个简单的模型,仅使用申请人的信用评分来预测申请结果。有了它,我的 F1 成绩达到了 56%。对于模型选择,我首先抽查了一些算法,如 SVM、LR、KNN、NN 和 RF,它们给出了最好的交叉验证分数。我使用 GridSearch CV 继续进行超参数调优,并能够在测试集上获得等于 74%的 F1 分数。我还尝试使用 SMOTEENN 库对罕见的类进行过采样,但这对提高性能没有太大帮助。有帮助的是使用 RF 的方差重要性图做了一些特征减少,最后我的 F1 分数大约是 82%。

我对此很满意,并决定在该公司提供的以前从未见过的测试集上测试我的模型。我惊讶地发现它的表现不如我预期的那样好。然后我参考了几篇博客文章,意识到我做错了什么。显然,一次性编码分类特征对于基于树的模型是不好的,特别是因为我们创建了许多二进制稀疏特征,并且从分裂算法的角度来看,它们都是独立的。因此,连续变量被自动赋予更高的重要性,并被选择在树的顶部进行拆分。为了缓解这个问题,我从 SkLearn 转到了 H2o 框架,它不需要对分类特征进行一次性编码。虽然我的 F1 分数大致保持不变,但我的 H2o 模型在看不见的数据集上概括得更好。

结尾注释

这就是展示你的 ML 项目的详细指南。确保你的回答不遗漏任何细节。至于我在开头谈到的时髦词汇,这里有几个词肯定会给你的面试官留下深刻印象:

超参数调谐

交叉验证

ML 工作流管道

偏差-方差权衡

过/欠采样

集合模型

缩放、标准化、一次热编码

特征简化、特征工程

绩效指标、混淆矩阵

我喜欢写循序渐进的初学者指南、操作指南、面试问题、解码 ML/AI 中使用的术语等。如果你想完全访问我的所有文章(以及其他媒体上的文章),那么你可以使用 我的链接这里* 注册。*

** [## 面试官最喜欢的问题-你会如何“扩展你的 ML 模型?”

您正在构建一个生产就绪的 ML 模型吗?

towardsdatascience.com](/interviewers-favorite-question-how-would-you-scale-your-ml-model-56e4fa40071b) [## 了解 Python 导入,init。py 和 pythonpath —一劳永逸

了解如何导入包和模块(以及两者之间的区别)

towardsdatascience.com](/understanding-python-imports-init-py-and-pythonpath-once-and-for-all-4c5249ab6355) [## 我将如何从零开始向一个 5 岁的孩子解释甘斯:第 1 部分

GANs 背后的基本直觉、目标函数、生成器和鉴别器架构以及深入的伪代码…

medium.com](https://medium.com/swlh/how-i-would-explain-gans-from-scratch-to-a-5-year-old-part-1-ce6a6bccebbb) [## 如何使用 AutoKeras 用一行代码建立图像分类模型?

甚至不需要知道 Conv2d、Maxpool 或批处理规范化层是做什么的!

medium.com](https://medium.com/analytics-vidhya/how-to-use-autokeras-to-build-image-classification-models-using-one-line-of-code-c35b0c36e66e)**

循序渐进:如何创建具有地图功能的交互式仪表盘

原文:https://towardsdatascience.com/step-by-step-how-to-create-interactive-dashboard-with-map-features-512e6e44a8f0?source=collection_archive---------27-----------------------

图片由 janjf93 来自 Pixabay

演示是许多数据科学项目中最关键的部分。当你准备一个演示文稿时,也许你不喜欢花时间清理数据。但是演示对你的同事/客户/顾客的影响非常大。简单明了很有必要,尤其是在向一个非技术人员解释结果的时候。

空间数据的重要性?

空间数据是需求最大的数据类型之一。因为空间数据可以帮助我们;

  • 更好的理解哪里的答案?
  • 确定关系
  • 识别模式
  • 作出预测

地图当然是显示空间数据的好方法。如今,你不需要任何 GIS 软件来创建和发布地图。BI 工具现在能够创建专题地图。

有许多商业智能工具可以帮助你创建强大而有效的图表、仪表盘、可视化工具,如 Tableau、Qlik Sence、Power BI、Looker、Microstrategy 等。

在这篇文章中,我将一步一步地解释如何用 Tableau Public 创建一个交互式仪表盘。您可以在我的 Github 资源库中找到我将在本教程中使用的数据。

  • 伦敦行政区:从 Airbnb 内部获取的该城市街区的 GeoJSON 文件
  • LondonBoroughProfile: 从大伦敦当局获取的伦敦自治市档案的 CSV 文件

步骤 1:安装 Tableau Public 并创建概要文件

Tableau Public 是一款免费软件,允许任何人连接到电子表格或文件,并为 web 创建交互式数据可视化。你可以使用 这个链接下载 Tableau Public for windows and Mac。

然而,你需要创建一个个人资料来展示你在互联网上的形象。

步骤 2:将你的文件连接到 Tableau Public

打开 Tableau 公共应用,可以看到左上角的“连接”区域。

作者照片

来连接你的空间文件 (LondonBorough。选择空间文件,浏览你的文件并打开。当您打开您的空间文件连接屏幕出现如下所示。您的文件必须包括多重多边形类型的几何列。

作者照片

要添加您的表格数据(londonboroughprofile . CSV)点击连接区域的添加按钮,然后选择“文本文件”。

作者照片

浏览您的 LondonBoroughProfile.csv 文件并点击打开。现在你有 2 个连接和 2 个文件,一个是空间文件,另一个是“文本文件”

作者照片

如果您想预览您的表格数据,您可以点击“查看数据”按钮并预览您的数据。

作者照片

作者照片

要创建两个文件的关系,选择 LondonBoroughProfile.csv 文件,拖放到关系区域。

作者照片

现在,您必须选择两个文件的公共列(区名)。LondonBoroughs.geojson 的专栏名称为“街区”,LondonBoroughProfile.csv 的专栏名称为“区名

作者照片

创建文件之间的关系后,您可以看到如下所示的连接。

作者照片

步骤 3:创建地图图幅

要创建地图可视化,点击左下方的第 1 页

作者照片

现在你有了两个表格和几十个属性,根据它们的类型(字符串、数字、日期、地理角色等)显示不同的图标。)

作者照片

要创建伦敦区地图,请选择放置在 LondonBoroughs.geojson 下的几何列,拖放 Sheet1 area。

作者照片

现在你有了伦敦行政区的基本地图。你需要用一些外观特征来配置你的地图,比如标签、颜色、工具提示等等。

创建标签:选择邻居,拖拽至标签

作者照片

作者照片

创建专题地图:选择一个你想作为专题地图查看的特征(在 LondonBoroughProfile.csv 下),拖放到彩色区域。在本教程中,我选择了“2014/2015 年每千人口犯罪率”

作者照片

现在,您有了一个基于犯罪率的专题地图。您可以通过改变颜色、标签等来配置外观特征。您可以添加过滤器,图例,标题等,以获得一个更容易理解的地图。

作者照片

添加新特性作为工具提示:工具提示为我们提供了关于属性的附加信息。因此,您可以添加更多的属性,当光标在地图上移动时,用户可以进行交互。选择一个或多个属性,拖放到工具提示区域。在本教程中我选择了“2015 年就业率(%)”“2017 年平均年龄”“汽车数量,(2011 年人口普查)”属性并重命名如下图所示;

  • 就业率
  • 平均年龄
  • 汽车数量

作者照片

步骤 4:创建图表

要创建新图表,请单击左下角的新工作表

作者照片

创建新工作表后,将出现一个空工作表。选择区名称,拖拽到列区。选择犯罪率,拖拽到行区域。

作者照片

要着色并添加标签,选择犯罪率,拖放以着色,再次拖放以标记犯罪率

作者照片

“伦敦金融城”区没有数据,因此您需要从图表中移除该记录。单击行政区名称的箭头并选择过滤器。然后取消选中伦敦城

作者照片

作者照片

步骤 5:创建仪表板

您可以创建更多包含不同图表的工作表。最后,您可以将这些工作表组合成一个仪表板。要创建新的仪表板,请单击“新建仪表板”按钮,此时将显示空仪表板。

作者照片

将尺寸更改为“自动”

作者照片

将 Sheet1(专题地图)和 Sheet2(条形图)拖放到仪表板区域。

如下图所示,我放置了这两张纸。

作者照片

如果你想看到所有可视化的交互,你需要设置“用作过滤器”按钮。

作者照片

因此,如果您从地图或图形中选择一个区,您会动态地看到其他图形的结果

作者照片

第六步:发布

最后,您准备了一个包含地图和图表的仪表板。现在,您需要将此仪表板发布到您的 Tableau 公共个人资料。点击文件并选择另存为 Tableau Public As

作者照片

作者照片

保存仪表板后,您的 Tableau 公共个人资料会自动打开。您可以使用全屏按钮来最大化您的仪表板。

作者照片

你可以在我的 Tableau 公众号 找到我的仪表盘。

感谢你阅读我的帖子,希望你喜欢。如果您有任何问题或想要分享您的意见,请随时联系我。

一步一步实现:Keras 中的 3D 卷积神经网络

原文:https://towardsdatascience.com/step-by-step-implementation-3d-convolutional-neural-network-in-keras-12efbdd7b130?source=collection_archive---------1-----------------------

深度学习

了解如何实现您自己的 3D CNN

来源

在本文中,我们将简要解释什么是 3d CNN,以及它与普通的 2d CNN 有何不同。然后我们会一步步教你如何用 Keras 实现自己的 3D 卷积神经网络。

本文将围绕这四个部分展开:

  • 1】什么是 3D 卷积神经网络?
  • 2】3d 数据是什么样的?(如 MNIST)
  • 3】现在如何实施?!
  • 4】但是然后一个 3d?为什么

1]什么是 3D 卷积神经网络?

不管我们怎么说,3d CNN 仍然是一个与 2d CNN 非常相似的 CNN。不同之处在于以下几点(非穷尽列举):

3d 卷积层

最初,2d 卷积层是输入和不同滤波器之间的逐条目乘法,其中滤波器和输入是 2d 矩阵。(图 1)

图 1(版权所有:自有)

在 3d 卷积层中,使用相同的操作。我们在多对 2d 矩阵上进行这些操作。(图 2)

图 2(版权所有:自有)

填充选项和幻灯片步长选项的工作方式相同。

3d 最大池图层

2d Maxpool Layers (2x2 filter)是从输入中提取一个 2x2 小正方形的最大元素。(图 3)

图 3(版权所有:自有)

现在,在 3d Maxpool (2x2x2 内核)中,我们寻找宽度为 2 的立方体中的最大元素。此立方体代表由输入的 2x2x2 区域界定的空间。(图 4)

图 4(版权所有:自有)

请注意,操作的数量(与 2d CNN 层相比)乘以所使用的过滤器的大小(不管该层是最大池还是卷积层),还乘以输入本身的大小。

2]3d 数据是什么样子的?

那么 3d CNN 的数据点是什么样的呢?

描绘它的一种方法是使用下面的图像(图 5):

图 5(版权所有:自有)

其他可用于 CNN 的现有数据集有:

3] 现在如何实现?!(预处理和实现)

你可以自己试试我们正在使用的来自 Kaggle 的数据集上的代码。

需要导入的库如下:

首先,由于数据集有点特殊,我们使用下面的 to helper 函数在将它们提供给网络之前对它们进行处理。

另外,数据集存储为 h5 文件,因此要提取实际的数据点,我们需要从 h5 文件中读取数据,并使用 to _ categorical 函数将其转换为向量。在这一步中,我们还要准备交叉验证。

最后,3d CNN 的模型和语法如下:(架构是在没有太多改进的情况下挑选的,因为这不是本文的重点)

请注意,与 2d CNN 相比,对于相同数量的层,参数的数量要高得多。

供您参考,经过小样本训练,我们得到了以下准确度和损耗。(图 6)

图 6(版权所有:自有)

4]但是然后一个 3d?为什么

3d CNN 碰巧有许多应用,例如:

  • IRM 的数据处理和由此得出的推论
  • 自驾
  • 距离估计

好了,差不多就这些了。我希望你尝试一下这项技术!源代码结束这里

感谢您的阅读,如果您喜欢,请关注我、我的网站和我的脸书页面!

[## 经典神经网络:什么是真正的节点和层?

一个节点和一个层在数学上代表什么?简单易懂的幕后概念介绍。

towardsdatascience.com](/classical-neural-network-what-really-are-nodes-and-layers-ec51c6122e09) [## 卷积神经网络:为什么它们对图像相关学习如此有效?

快速解释为什么 CNN 现在几乎总是用于计算机视觉任务。

towardsdatascience.com](/convolutional-neural-networks-why-are-they-so-good-for-image-related-learning-2b202a25d757)

使用 Travis-CI 为您的 Python 项目构建最小 CI/CD 管道的分步教程

原文:https://towardsdatascience.com/step-by-step-tutorial-to-build-a-minimal-ci-cd-pipeline-for-your-python-project-using-travis-ci-c074e42f0c65?source=collection_archive---------21-----------------------

使用 Travis-CI、Codecov 和 Pypi 自动构建、测试和发布您的 Python 包。

Philipp Wüthrich 在 Unsplash 上的照片

如果您想在自动发布/部署包之前,节省在多种环境中测试 python 代码的时间,那么构建 CI/CD 管道非常有用。这也是一种及早发现错误并确保开发过程的一致性和可重复性的方法。

我最近参与了一个项目,该项目实现了一种相对较新的方法,将深度学习模型应用于结构化数据,该方法的细节可以在这里找到:使用半监督学习为结构化数据训练更好的深度学习模型。我想建立一个 CI/CD 管道来完成以下任务:

  • 在每次合并请求时自动测试代码的。
  • 计算并显示主分支的测试覆盖率
  • 如果登台分支上的构建通过了测试,python 包 /wheel 的自动部署到 PyPi。

为了做到这一点,我使用了 Github、 Travis-CICodecov、这两个软件对开源项目都是免费的。

步骤:

1)登录

第一步是使用您的 Github 帐户登录 Travis-CI,然后转到 settings 并激活您想要处理的存储库:

然后用 Codecov 做同样的事情:

最后是 PyPI,您需要通过转到 account setting 来生成一个访问令牌:

2)将 PyPI 令牌添加到 Travis-CI:

要自动发布包,您需要将 PyPI 令牌作为环境变量添加到 Travis-CI 中。在设置中:

3)代码

代码需要有一个 setup.py 文件以及一个 requirements.txt (如果需要的话)。例如,我的代码依赖于多个像 Tensorflow 或 Pandas 这样的库,所以我需要一个这样的需求文件:

**pandas**==**1.0.4
numpy**==**1.17.3
scipy**==**1.4.1
matplotlib**==**3.1.1
tensorflow_gpu**==**2.0.1
tqdm**==**4.36.1
scikit_learn**==**0.23.2
tensorflow**==**2.3.0**

您还需要实现一些测试,并将它们放在 tests/文件夹中。我的代码中的一个测试示例是在合成训练集上运行一个小训练,并通过在测试集上运行一个评估来检查网络是否学习了:

**from** deeptabular.deeptabular **import** (
    DeepTabularClassifier,
)
**import** pandas **as** pd
**import** numpy **as** np
**import** tensorflow **as** tf
**from** sklearn.metrics **import** accuracy_score

**def** test_build_classifier():
    classifier = DeepTabularClassifier(
        cat_cols=[**"C1"**, **"C2"**], num_cols=[**"N1"**, **"N2"**], n_targets=1, num_layers=1
    )
    df = pd.DataFrame(
        {
            **"C1"**: np.random.randint(0, 10, size=5000),
            **"C2"**: np.random.randint(0, 10, size=5000),
            **"N1"**: np.random.uniform(-1, 1, size=5000),
            **"N2"**: np.random.uniform(-1, 1, size=5000),
            **"target"**: np.random.uniform(-1, 1, size=5000),
        }
    )
    df[**"target"**] = df.apply(
        **lambda** x: 1 **if** (x[**"C1"**] == 4 **and** x[**"N1"**] < 0.5) **else** 0, axis=1
    )

    test = pd.DataFrame(
        {
            **"C1"**: np.random.randint(0, 10, size=5000),
            **"C2"**: np.random.randint(0, 10, size=5000),
            **"N1"**: np.random.uniform(-1, 1, size=5000),
            **"N2"**: np.random.uniform(-1, 1, size=5000),
            **"target"**: np.random.uniform(-1, 1, size=5000),
        }
    )
    test[**"target"**] = test.apply(
        **lambda** x: 1 **if** (x[**"C1"**] == 4 **and** x[**"N1"**] < 0.5) **else** 0, axis=1
    )

    classifier.fit(df, target_col=**"target"**, epochs=100, save_path=**None**)

    pred = classifier.predict(test)

    acc = accuracy_score(test[**"target"**], pred)

    **assert** isinstance(classifier.model, tf.keras.models.Model)
    **assert** acc > 0.9

4)管道

Travis-CI 中使用的管道被编写为 YAML 文件。例如,deeptabular 存储库中使用的是:

**language**: python
**python**:
  - **"3.6"** - **"3.7"
install**:
  - pip install -r requirements.txt
  - pip install codecov
  - pip install pytest-cov
  - pip install .
**script**:
  - pytest --cov-report=xml --cov=deeptabular tests/

**after_success**:
  - codecov

**deploy**:
  **provider**: pypi
  **user**: __token__
  **password**: $TEST_PYPI_TOKEN
  **distributions**: **"sdist bdist_wheel"
  skip_existing**: true
  **on**:
    **branch**: staging

首先选择要使用的 python 版本:

**python**:
  - **"3.6"** - **"3.7"**

然后安装库的需求加上库本身,pytest 和用于测试的 Codecov:

**install**:
  - pip install -r requirements.txt
  - pip install codecov
  - pip install pytest-cov
  - pip install .

运行测试并将测试覆盖结果写成 XML 格式:

**script**:
  - pytest --cov-report=xml --cov=deeptabular tests/

将覆盖报告推送到 codecov:

**after_success**:
  - codecov

最后,将包作为 zip 和 wheel 发布到 PyPI:

**deploy**:
  **provider**: pypi
  **user**: __token__
  **password**: $TEST_PYPI_TOKEN
  **distributions**: **"sdist bdist_wheel"
  skip_existing**: true
  **on**:
    **branch**: staging

然后将包推送到 PyPI:

测试覆盖结果可以在 Codecov:

结论:

就是这样,每当有代码被推送到任何分支时,这个管道就运行测试,如果 staging 分支发生变化,就将包发布到 PyPI。

参考资料:

  1. https://dev . to/oscarmcm/distributing-pypi-packages-using-API-tokens-in-travisci-1n9i
  2. https://docs.travis-ci.com/user/languages/python/

代码:

https://github.com/CVxTz/DeepTabular

将 Kubernetes 部署到您的 GCP 云的分步指南

原文:https://towardsdatascience.com/step-by-step-tutorial-to-deploy-kubernetes-to-your-gcp-cloud-171e739eedc2?source=collection_archive---------18-----------------------

实践教程

用动手练习揭开 Kubernetes 的神秘面纱!

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

介绍

作为一名在实践中的数据科学家,我感受到了将数据处理、模型训练和推理的传统例行程序推入具有( CI/CD )持续集成/持续部署的集成管道的趋势,其概念是从 DevOps 借用的。至少从我的角度来看,有两个主要原因。一个是建模正在走出原型阶段,进入生产中模型的大规模采用,无论是作为一个附件还是应用程序。另一个原因是将整个建模体验带到云中的需求增加,以及模型开发的增强编排。

在这种需求的驱使下,我开始了我的技能提升之旅,使用了适合建模转型的工具,比如 Kubernetes。它现在很受欢迎,并获得了易于扩展、可移植性和可扩展性的声誉。这篇博客在这里特别展示了它提供的组件。然而,当我开始我的研究并得到它的时候,我感到被所有这些概念和“官方指南”淹没了,因为我不是一个训练有素的软件开发人员。我一点一点地咀嚼所有这些材料,并开始获得更完整的图片,即使我没有丰富的 DevOps 背景。我的笔记和理解都在这个教程中,我希望这对于那些也需要在 Kubernetes 中提升自己的人来说是一个简单而成功的开始。

一言以蔽之的库伯内特

Kubernetes 将自己定义为一个生产级的开源平台,在计算机集群内部和之间协调应用程序容器的执行。简而言之,Kubernetes 是一个为你组装几台计算机来执行应用程序的管理者。它是执行您分配给它的任务的指挥中心:安排应用程序、定期维护、扩展容量和推出更新。

来自 Kubernetes 的聚类图

Kubernetes 集群最基本的组件是主节点和节点。主服务器是管理器,是集群的中心。节点是虚拟机或物理计算机。每个节点都有一个 Kubelet 来管理它并与主节点通信。由于节点是一个虚拟机,我们还应该有 Docker/Container 作为工具来执行我们的应用程序。

Kubernetes 应用程序

现在我们知道了 Kubernetes 的基本知识,我们可能会开始想从数据科学家的角度来看它能做什么。以我的观点和经验,我确实发现 Kubernetes 的概念非常吸引人,尤其是当你认为建模最终应该作为应用程序/服务产品化的时候。当我们想让最终用户访问模型时,它阻碍许多产品设计者的问题,如可伸缩性和可扩展性也将是考虑的一部分。

谷歌提供了一份他们内部解决方案的应用程序列表。但是我们在这里想要实现的是根据我们的需求和目的来使用和定制 Kubernetes。因此,本教程将自下而上,从基础开始设置 GCP,一直到在 Kubernetes 集群上部署应用程序。

步骤 0。GCP 设置

在本教程中,我们将使用 Google Kubernetes 引擎来建立一个 Kubernetes 集群。但是在开始之前,请确保满足以下先决条件:

  1. GCP 获得一个账号,登录控制台
  2. 在控制台中,启用 Kubernetes Engine AP I .你可以在 API 库中找到一个库 API,只需搜索名称即可。

API 库(图片由作者提供)

3.安装 gcloud 。您可以使用基于网络的终端或您自己的计算机终端。要在 GCP 控制台中找到基于 web 的终端:

单击红色框中的图标(图片由作者提供)

建议按照官方指南安装 gcloud,但为了方便起见,您也可以使用以下命令:

4.安装 kubectl。这一步很简单:设置 gcloud 后,输入命令:

gcloud components install kubectl

第一步。Kubernetes 设置

一旦我们完成了前面的所有步骤,项目现在可以使用 Google Cloud SDK 来创建一个托管的 Kubernetes 集群。

  1. 要使用 gcloud 创建容器集群:
gcloud container clusters create \
--machine-type n1-standard-2 \
--num-nodes 3\
--zone <compute zone from the list linked below> \
--cluster-version latest \
<CLUSTERNAME>
  • 机器类型:用于节点的机器类型。
  • num-nodes :要在每个集群区域中创建的节点数量。您可以将其设置为 1 来创建一个单节点集群,但是构建一个 Kubernetes 集群至少需要 3 个节点。稍后可以使用 gcloud 命令调整大小。
  • zone :计算集群的 zone (例如 us-central1-a)。

如果集群创建正确,它将显示如下信息:

2.为了测试新设置的集群,我们可以使用 kubectl:

kubectl get node

3.接下来,我们将授予用户执行管理操作的权限

kubectl create clusterrolebinding cluster-admin-binding \
  --clusterrole**=**cluster-admin \
  --user**=**<GOOGLE-EMAIL-ACCOUNT>

4.安装。Helm 是 Kubernetes 应用程序的包管理器。您可以使用导航图来搜索要部署到 Kubernetes 的应用程序/包。Helm Chart 是预设的抽象概念,用来描述如何将包安装到 Kubernetes

curl https://raw.githubusercontent.com/helm/helm/master/scripts/get-helm-3 | bash

安装 Helm 后,我们可以通过调用以下命令来检查集群中安装了什么:

helm list

现在你的 Kubernetes 已经准备好了!祝贺🤓

第二步。Kubernetes 的应用

以 JupyerHub 为例

在开始安装过程之前,从较高的层次进行检查并了解它的样子总是有帮助的。在前面的步骤中,我们已经完成了安装 Helm 的 Kubernetes 集群的设置。现在,我们想为它部署一个应用程序,并开始使用它。对于这里的例子,我将使用可以服务多个用户的 JupyterHub。下面是这个练习的结构,以便于参考。

安装结构(图片由作者使用 LucidChart 提供)

  1. 安全设置
  • 生成代理安全令牌。出于安全考虑,强烈建议不要在没有 SSL 加密的情况下运行 JupyerHub。用openssl rand -hex 32简单生成。将生成的令牌保存在记事本中以备后用。
  • 向您的[代理](http://penssl rand -hex 32)添加令牌。它可以在配置文件中设置,也可以使用或存储为环境变量。然而,由于我们已经安装了 Helm,我们可以使用helm来模板化yaml文件以添加 SSL 令牌。下面是您用上一步生成的令牌提供给yaml的格式。我们稍后将把它添加到配置文件中。
**proxy:**
  **secretToken:** "<SSL_Token>"

2.添加配置

JupyterHub 就如何设置配置提供了非常全面的指南。我正在添加一些有用的自定义数据科学的目的。您也可以参考指南来设置您的定制或使用参考此处的来导航您的需求。

  • 图片:我们可以从这里提供的综合列表中添加数据科学笔记本图片。还有,记得用标签代替latest。你的图片标签可以在 DockerHub 中找到,数据科学笔记本的标签信息可以在这里找到。
  • 内存:我们为你的用户指定存储限制。这将向 Kubernetes API 发送请求。

如果您只想遵循示例,只需复制并粘贴上面的内容,并替换必要的凭证。使用nano config.yamlvim config.yaml创建yaml文件并替换内容。

3.用舵安装。以下脚本将使用helm upgrade安装 JupyterHub。有关该命令的详细信息,请查看此处的以供参考。

对于将来使用helm的升级,我们不需要创建名称空间。

JupyterHub 的指南对这一部分做了非常透彻的解释,我个人认为阅读起来非常有帮助。RELEASE指定您希望如何从helm命令调用,NAMESPACE是您希望与kubectl一致的内容。

在 helm 开始安装的时候休息一下,一旦安装完成,你将会看到 JupyterHub 的结束信息。如果您需要对该步骤中的任何问题进行故障诊断,请参考指南或使用kubectl get events检索日志并自己找出发生了什么。

4.检查状态并测试您的 JupyterHub。正确设置后,我们应该通过调用以下命令看到集线器准备就绪:

kubectl —-namespace=jhub get pod

要通过集群访问集线器,请调用以下命令来获取 IP 地址:

kubectl --namespace=jhub get svc proxy-public

将您的外部 IP 复制并粘贴到一个新的浏览器,它应该会将您导航到 JupyerHub 登录页面。您可以将自己的 JupyterHub 用于 Kubernetes 集群。

JupyterHub 界面(图片由作者提供)

请注意,我们没有为用户设置任何身份验证,所以我们只需输入随机的用户名和密码即可开始。但是,如果您正在寻找更多的安全性来保护您的集群,请检查此链接来设置您的 JupyerHub 身份验证。

打扫卫生。&最终想法

如果你什么都不做就让云闲置,那它就不便宜。所以如果你不再需要你的集群,建议将删除它。

# Retrieve the cluster **gcloud container clusters list**# Delete the cluster**gcloud container clusters delete <CLUSTER-NAME>**

我从这个例子的实现中学到了很多,希望你也有同感。Kubernetes 并不完全是神秘的,作为一名数据科学家,即使没有事先培训,也可以理解基本原理并获得实际应用。我将继续用 Kubernetes 写我的研究、想法和应用,并用简单明了的语言揭开的神秘面纱。和平!🤗

分步教程:用 BeautifulSoup 抓取维基百科

原文:https://towardsdatascience.com/step-by-step-tutorial-web-scraping-wikipedia-with-beautifulsoup-48d7f2dfa52d?source=collection_archive---------1-----------------------

我的室友和我讨论了她对瑞典高抑郁率的观察。我们得出了抑郁率和缺少阳光之间的联系。我决定通过收集自己的数据并进行分析来支持我的假设。

我使用 Beautiful Soup,这是一个易于使用的 Python web 抓取工具。我喜欢这个工具的原因是它易于使用和理解。库的文档可以在这里找到。

准备

假设:一个国家的日照时间越少,这个国家的抑郁率就越高。

要收集的数据:

  • 国家名称
  • 他们的抑郁率
  • 他们的日照时间

要使用的资源:

开始

import requests
import urllib.request
import time
from bs4 import BeautifulSoup
import numpy as np
import pandas as pd
from urllib.request import urlopenurl = 'https://en.wikipedia.org/wiki/Epidemiology_of_depression'html = urlopen(url) soup = BeautifulSoup(html, 'html.parser')

右键单击页面,然后转到检查。单击上面显示的图标,选择网站中要检查的元素。

我们对从表格中提取信息感兴趣。这可以用一行代码轻松完成。通过检查,我们发现这张桌子被贴上了<table>标签。

find_all('table')扫描整个文档寻找标签<table>

tables = soup.find_all('table')

find_all()是一个简单有效的方法,在本教程中会经常用到。

收集数据

因为“,”,看起来DALY rate列中的数据在收集时将是一个字符串。创建一个函数,通过使用 re.sub()将字符串处理成整数,这是一个返回与正则表达式匹配的子字符串的方法。

import re
def process_num(num):
    return float(re.sub(r'[^\w\s.]','',num))

测试功能

num1 = float(re.sub(r'[^\w\s.]','','1,156.30'))
num1

产量:1156.30

我们来分析一下。

第 6–7 行:我们注意每一行都在<tr>标签下。这给了我们一个想法,我们将通过找到所有的标签<tr>来得到这些行

第 9–10 行:通过查找所有<td> tags来提取行

第 14 行:由于第一行的len(cells)是 1,我们设置条件跳过第一行,从其他行提取。

第 15 行:因为cells是 3 个单元格的列表,我们使用第一个单元格提取排名,使用第二个单元格提取国家名称,使用第三个单元格提取 DALY 比率。

把数据放入pandas.DataFrame

df1 = pd.DataFrame(ranks, index= countriescolumns = ['Rank'])df1['DALY rate'] = ratesdf1.head(10)

使用与上述相同的方法从第二个网站收集日照时数。请记住,这两个网站的数据有两个不同之处:

  • 同一个国家的日照时数有多种数据。因此,我们可能希望取这些数据的平均值,以获得每个国家的小时数。为了取平均值,我们简单地使用两个字典,country_sunscount,它们具有相同的关键字但不同的值。
  • 第二次数据中的一些国家在第一次数据中没有。因此,我们只想从第一个数据中的国家收集数据,这些数据存储在上面创建的变量countries中。

结果:

789.14 3
Country: Benin, Sunshine Hours: 263.05
515.99 2
Country: Togo, Sunshine Hours: 258.0
710.25 3
Country: Ghana, Sunshine Hours: 236.75
866.0500000000001 4
Country: Cameroon, Sunshine Hours: 216.51
344.03999999999996 2
Country: Gabon, Sunshine Hours: 172.02
1334.54 5
Country: Nigeria, Sunshine Hours: 266.91
711.91 2
Country: Sudan, Sunshine Hours: 355.95
336.1 1
...

清理数据

使用 join 方法连接我们之前收集的两个数据。

df2 = pd.DataFrame.from_dict(country_suns,orient='index', columns = ['Sunshine Hours/Year'])df = df1.join(df2)df.info()

结果:

<class 'pandas.core.frame.DataFrame'>
Index: 192 entries, United States to Japan
Data columns (total 3 columns):
Rank                   192 non-null int64
DALY rate              192 non-null float64
Sunshine Hours/Year    122 non-null float64
dtypes: float64(2), int64(1)
memory usage: 11.0+ KB

我们意识到最后一列中有空值,因为第一个来源中的一些国家不在第二个来源中。有许多方法可以处理缺失值。但是现在,只需删除缺少值的行,就可以直观地看到我们得到了什么。

df.dropna(inplace=True)

将数据可视化

import matplotlib.pyplot as plt
import seaborn as snssns.scatterplot('Rank', 'Sunshine Hours/Year', data=df)

这里似乎没有很强的相关性。看一下相关系数。

如果要使用不同的工具处理数据,请保存数据。

df.to_csv('wiki-2.csv')

结论

相关性没有我想象的那么强。但是我们没有考虑到不同的因素,如确定抑郁率的指标的准确性,国家的大小(国家越大,日照时数/年的变化越大),GDP,人口等。应该收集更多的数据以获得更准确的结果。但在此之前,要为自己感到骄傲,因为你刚刚学会了网络搜集,这是数据科学中最重要的过程之一。

本教程的 Github 库可以在这里找到:https://github.com/khuyentran1401/Web-Scrapping-Wikipedia

我喜欢写一些基本的数据科学概念,并尝试不同的算法和数据科学工具。你可以在 LinkedInTwitter 上联系我。

如果你想查看我写的所有文章的代码,请点击这里。在 Medium 上关注我,了解我的最新数据科学文章,例如:

参考

1抑郁症流行病学,维基百科

[2]根据日照时间列出的城市列表,维基百科

[3]Varun Choudhary,如何抓取网站而不被列入黑名单(2019),Hackernoon

循序渐进:Python 中的 Twitter 情感分析

原文:https://towardsdatascience.com/step-by-step-twitter-sentiment-analysis-in-python-d6f650ade58d?source=collection_archive---------0-----------------------

图片由皮克斯拜的 Gerd Altmann 提供

通过分析人们分享的推文,了解人们对一个话题的看法不再困难。情感分析是 NLP(自然语言处理)最流行的用例之一。

在这篇文章中,我将使用“Tweepy”,,这是一个易于使用的 Python 库,用于访问 Twitter API。您需要有一个 Twitter 开发人员帐户和样本代码来做这个分析。你可以在我的 Github 库中找到 Jupyter 笔记本代码。

这篇文章的目的是分析人们对伦敦第二次封锁的看法。

步骤 1:安装并导入库

在分析之前,需要使用 安装 textblobtweepy 库!pip 在你的 Jupyter 笔记本上安装 命令。

# Install Libraries
!pip install textblob
!pip install tweepy

您需要导入将在这个情感分析项目中使用的库。

# Import Librariesfrom textblob import TextBlob
import sys
import tweepy
import matplotlib.pyplot as plt
import pandas as pd
import numpy as np
import os
import nltk
import pycountry
import re
import stringfrom wordcloud import WordCloud, STOPWORDS
from PIL import Image
from nltk.sentiment.vader import SentimentIntensityAnalyzer
from langdetect import detect
from nltk.stem import SnowballStemmer
from nltk.sentiment.vader import SentimentIntensityAnalyzer
from sklearn.feature_extraction.text import CountVectorizer

Tweepy 支持 OAuth 1a(应用程序用户)和 OAuth 2(仅应用程序)身份验证。身份验证由 tweepy 处理。AuthHandler 类。

OAuth 2 是一种身份验证方法,其中应用程序在没有用户上下文的情况下发出 API 请求。如果您只需要对公共信息进行只读访问,请使用此方法。

您首先注册我们的客户端应用程序,并获得一个消费者密钥和秘密。然后创建一个 AppAuthHandler 实例,传入我们的消费者密钥和秘密。

认证之前,你需要有 Twitter 开发者账号。如果没有,可以通过使用此 链接 进行申请。获得 Twitter 开发者账户通常需要一两天,有时甚至更长时间,你的申请才会被 Twitter 审核。

步骤 Twitter API 的认证

# Authentication
consumerKey = “Type your consumer key here”
consumerSecret = “Type your consumer secret here”
accessToken = “Type your accedd token here”
accessTokenSecret = “Type your access token secret here”auth = tweepy.OAuthHandler(consumerKey, consumerSecret)
auth.set_access_token(accessToken, accessTokenSecret)
api = tweepy.API(auth)

在您认证之后,您需要使用 tweepy 获取文本,并使用 Textblob 从文本中计算出中性极性复合参数。

第三步:获取带有关键词或标签的推文

#Sentiment Analysisdef percentage(part,whole):
 return 100 * float(part)/float(whole)keyword = input(“Please enter keyword or hashtag to search: “)
noOfTweet = int(input (“Please enter how many tweets to analyze: “))tweets = tweepy.Cursor(api.search, q=keyword).items(noOfTweet)
positive = 0
negative = 0
neutral = 0
polarity = 0
tweet_list = []
neutral_list = []
negative_list = []
positive_list = []for tweet in tweets:

 #print(tweet.text)
 tweet_list.append(tweet.text)
 analysis = TextBlob(tweet.text)
 score = SentimentIntensityAnalyzer().polarity_scores(tweet.text)
 neg = score[‘neg’]
 neu = score[‘neu’]
 pos = score[‘pos’]
 comp = score[‘compound’]
 polarity += analysis.sentiment.polarity

 if neg > pos:
 negative_list.append(tweet.text)
 negative += 1elif pos > neg:
 positive_list.append(tweet.text)
 positive += 1

 elif pos == neg:
 neutral_list.append(tweet.text)
 neutral += 1positive = percentage(positive, noOfTweet)
negative = percentage(negative, noOfTweet)
neutral = percentage(neutral, noOfTweet)
polarity = percentage(polarity, noOfTweet)
positive = format(positive, ‘.1f’)
negative = format(negative, ‘.1f’)
neutral = format(neutral, ‘.1f’)

这篇文章中的场景是这样的,用户应该键入关键字或标签( lockdown2 london )并键入想要获取和分析多少条推文( 2500 )。

因为有限制,tweets 参数的数量很重要。

作者图片

在收到 2500 条关于“封锁伦敦”的推文后,让我们看看有多少条推文表达了这种情绪

#Number of Tweets (Total, Positive, Negative, Neutral)tweet_list = pd.DataFrame(tweet_list)
neutral_list = pd.DataFrame(neutral_list)
negative_list = pd.DataFrame(negative_list)
positive_list = pd.DataFrame(positive_list)
print(“total number: “,len(tweet_list))
print(“positive number: “,len(positive_list))
print(“negative number: “, len(negative_list))
print(“neutral number: “,len(neutral_list))

你会收到 2500 条推文。

  • 1025 条推文(41.0%) 包含正面情绪
  • 580 条(23.2%) 条推文中包含负面情绪
  • 895 条(35.8%) 条推文包含中性情绪
#Creating PieCartlabels = [‘Positive [‘+str(positive)+’%]’ , ‘Neutral [‘+str(neutral)+’%]’,’Negative [‘+str(negative)+’%]’]
sizes = [positive, neutral, negative]
colors = [‘yellowgreen’, ‘blue’,’red’]
patches, texts = plt.pie(sizes,colors=colors, startangle=90)
plt.style.use(‘default’)
plt.legend(labels)
plt.title(“Sentiment Analysis Result for keyword= “+keyword+”” )
plt.axis(‘equal’)
plt.show()

作者图片

让我们看看推文列表。

tweet_list

作者图片

第四步:清理推文以分析情绪

当你查看 tweet 列表时,你可以看到一些重复的 tweet,所以你需要使用 drop_duplicates 函数删除重复的记录。

tweet_list.drop_duplicates(inplace = True)

作者图片

我们的新数据框有 1281 条独特的推文。

首先,我创建一个新的数据框(tw_list)和一个新的特征(text),然后使用 lambda 函数清洗文本,清洗 RT、link、标点符号字符,最后转换成小写。

#Cleaning Text (RT, Punctuation etc)#Creating new dataframe and new features
tw_list = pd.DataFrame(tweet_list)
tw_list[“text”] = tw_list[0]#Removing RT, Punctuation etc
remove_rt = lambda x: re.sub(‘RT @\w+: ‘,” “,x)
rt = lambda x: re.sub(“(@[A-Za-z0–9]+)|([⁰-9A-Za-z \t])|(\w+:\/\/\S+)”,” “,x)
tw_list[“text”] = tw_list.text.map(remove_rt).map(rt)
tw_list[“text”] = tw_list.text.str.lower()
tw_list.head(10)

作者图片

第五步:情感分析

现在,我可以使用清理后的文本再次计算极性、主观性、情绪、负面、正面、中性和复合参数。对于所有计算的参数,我在数据框中创建新要素

#Calculating Negative, Positive, Neutral and Compound valuestw_list[[‘polarity’, ‘subjectivity’]] = tw_list[‘text’].apply(lambda Text: pd.Series(TextBlob(Text).sentiment))
for index, row in tw_list[‘text’].iteritems():
 score = SentimentIntensityAnalyzer().polarity_scores(row)
 neg = score[‘neg’]
 neu = score[‘neu’]
 pos = score[‘pos’]
 comp = score[‘compound’]
 if neg > pos:
 tw_list.loc[index, ‘sentiment’] = “negative”
 elif pos > neg:
 tw_list.loc[index, ‘sentiment’] = “positive”
 else:
 tw_list.loc[index, ‘sentiment’] = “neutral”
 tw_list.loc[index, ‘neg’] = neg
 tw_list.loc[index, ‘neu’] = neu
 tw_list.loc[index, ‘pos’] = pos
 tw_list.loc[index, ‘compound’] = comptw_list.head(10)

作者图片

您可以根据情绪将数据框分为 3 组。对于这一个,创建 3 个新数据帧(tw_list_negative、tw_list_positive、tw_list_neutral)并从原始 tw_list 数据帧导入

#Creating new data frames for all sentiments (positive, negative and neutral)tw_list_negative = tw_list[tw_list[“sentiment”]==”negative”]
tw_list_positive = tw_list[tw_list[“sentiment”]==”positive”]
tw_list_neutral = tw_list[tw_list[“sentiment”]==”neutral”]

让我们计算情感特征的值,并查看总百分比。

单列中 count _ values _ 的函数

def count_values_in_column(data,feature):
 total=data.loc[:,feature].value_counts(dropna=False)
 percentage=round(data.loc[:,feature].value_counts(dropna=False,normalize=True)*100,2)
 return pd.concat([total,percentage],axis=1,keys=[‘Total’,’Percentage’])#Count_values for sentiment
count_values_in_column(tw_list,”sentiment”)

作者图片

你可以通过使用情绪推文的数量来创建一个图表。

# create data for Pie Chart
pichart = count_values_in_column(tw_list,”sentiment”)
names= pc.index
size=pc[“Percentage”]

# Create a circle for the center of the plot
my_circle=plt.Circle( (0,0), 0.7, color=’white’)
plt.pie(size, labels=names, colors=[‘green’,’blue’,’red’])
p=plt.gcf()
p.gca().add_artist(my_circle)
plt.show()

作者图片

现在你可以准备使用 1281 条推文创建 worcloud,这样你就可以知道哪些词在这些推文中使用得最多。要创建 worcloud,首先让我们定义下面的函数,这样你就可以再次使用 wor cloud 来处理所有的推文,正面推文,负面推文等等。

#Function to Create Wordclouddef create_wordcloud(text):
 mask = np.array(Image.open(“cloud.png”))
 stopwords = set(STOPWORDS)
 wc = WordCloud(background_color=”white”,
 mask = mask,
 max_words=3000,
 stopwords=stopwords,
 repeat=True)
 wc.generate(str(text))
 wc.to_file(“wc.png”)
 print(“Word Cloud Saved Successfully”)
 path=”wc.png”
 display(Image.open(path))

定义了这个函数后,你就可以查看所有推文的 wordcloud 了

#Creating wordcloud for all tweets
create_wordcloud(tw_list[“text”].values)

作者图片

针对具有积极情绪的推文的词云;

#Creating wordcloud for positive sentiment
create_wordcloud(tw_list_positive[“text”].values)

作者图片

针对带有负面情绪的推文的词云;

#Creating wordcloud for negative sentiment
create_wordcloud(tw_list_negative[“text”].values)

作者图片

我们来计算一下推文长度和字数。因此,你可以看到基于不同情绪的推文中使用的单词和字符的密度。

#Calculating tweet’s lenght and word count
tw_list[‘text_len’] = tw_list[‘text’].astype(str).apply(len)
tw_list[‘text_word_count’] = tw_list[‘text’].apply(lambda x: len(str(x).split()))round(pd.DataFrame(tw_list.groupby("sentiment").text_len.mean()),2)

作者图片

round(pd.DataFrame(tw_list.groupby(“sentiment”).text_word_count.mean()),2)

作者图片

应用计数矢量器可在生成矢量表示之前对文本数据进行预处理,使其成为高度灵活的文本特征表示模块。在计数矢量器之后,可以用两个或三个或者任何你想要的来分析单词。

应用词干分析器还可以提供单词的词根。所以你可以排除来自同一个词根的单词,比如;

  • 连接
  • 关系
  • 连接的
  • 连接
  • 连接

来源于“连接”。如果您应用词干分析器功能,您可以认为这些单词是相同的

#Removing Punctuation
def remove_punct(text):
 text = “”.join([char for char in text if char not in string.punctuation])
 text = re.sub(‘[0–9]+’, ‘’, text)
 return texttw_list[‘punct’] = tw_list[‘text’].apply(lambda x: remove_punct(x))#Appliyng tokenization
def tokenization(text):
    text = re.split('\W+', text)
    return texttw_list['tokenized'] = tw_list['punct'].apply(lambda x: tokenization(x.lower()))#Removing stopwords
stopword = nltk.corpus.stopwords.words('english')
def remove_stopwords(text):
    text = [word for word in text if word not in stopword]
    return text

tw_list['nonstop'] = tw_list['tokenized'].apply(lambda x: remove_stopwords(x))#Appliyng Stemmer
ps = nltk.PorterStemmer()def stemming(text):
    text = [ps.stem(word) for word in text]
    return texttw_list['stemmed'] = tw_list['nonstop'].apply(lambda x: stemming(x))#Cleaning Text
def clean_text(text):
    text_lc = "".join([word.lower() for word in text if word not in string.punctuation]) # remove puntuation
    text_rc = re.sub('[0-9]+', '', text_lc)
    tokens = re.split('\W+', text_rc)    # tokenization
    text = [ps.stem(word) for word in tokens if word not in stopword]  # remove stopwords and stemming
    return texttw_list.head()

应用 countverctorizer 后,两个结果显示所有 1281 条 tweets 有 2966 个独特的单词。

如果您看一下我们的数据框,您会看到一些新功能,如点状、标记化、不间断、词干化。

作者图片

现在,您可以应用 coun 矢量器将所有 2966 个唯一的单词视为一个新功能。

#Appliyng Countvectorizer
countVectorizer = CountVectorizer(analyzer=clean_text) 
countVector = countVectorizer.fit_transform(tw_list[‘text’])
print(‘{} Number of reviews has {} words’.format(countVector.shape[0], countVector.shape[1]))
#print(countVectorizer.get_feature_names())1281 Number of reviews has 2966 wordscount_vect_df = pd.DataFrame(countVector.toarray(), columns=countVectorizer.get_feature_names())
count_vect_df.head()

作者图片

您可以按降序对值进行排序,以查看最常用的单词

# Most Used Words
count = pd.DataFrame(count_vect_df.sum())
countdf = count.sort_values(0,ascending=False).head(20)
countdf[1:11]

作者图片

建立 n 元模型有助于我们预测最有可能出现在这个序列之后的单词。首先让我们创建一个函数,然后构建 n2_bigram,n3_trigram 等。

#Function to ngram
def get_top_n_gram(corpus,ngram_range,n=None):
 vec = CountVectorizer(ngram_range=ngram_range,stop_words = ‘english’).fit(corpus)
 bag_of_words = vec.transform(corpus)
 sum_words = bag_of_words.sum(axis=0) 
 words_freq = [(word, sum_words[0, idx]) for word, idx in vec.vocabulary_.items()]
 words_freq =sorted(words_freq, key = lambda x: x[1], reverse=True)
 return words_freq[:n]#n2_bigram
n2_bigrams = get_top_n_gram(tw_list[‘text’],(2,2),20)n2_bigrams

作者图片

#n3_trigram
n3_trigrams = get_top_n_gram(tw_list[‘text’],(3,3),20)n3_trigrams

作者图片

最后,你可以使用 tweets 来分析情绪,你可以意识到哪些词最常用,哪些词一起使用。

感谢你阅读我的帖子,希望你喜欢。如果您有任何问题或想要分享您的意见,请随时联系我。

Python 中使用 Selenium 的分步 Web 抓取项目

原文:https://towardsdatascience.com/step-by-step-web-scraping-project-using-selenium-in-python-3be887e6e35c?source=collection_archive---------17-----------------------

选择网站,在 Python 中设置 Selenium,抓取数据并分析。

Selenium 是数据科学中的一个强大工具。它的用途之一是自动收集网站上公开的数据。使用 Python 中的 Selenium,您可以自动化 web 浏览器访问网站上的数据,收集并存储在 MySQL、CSV 文件等中。

这个项目是在华沙大学数据科学研究生学习期间与 T2 的 Jorge Bueno Perez 和 T4 的 Noam Shmuel 一起完成的。

在这个分步指南中,您将看到如何使用 Selenium Python 从网站www.openaq.org获取数据,并创建如下图所示的箱线图。

最终结果将是这样的:

显示 2020 年不同欧盟国家空气污染的箱线图

箱线图显示了欧盟国家 PM 2.5 空气污染水平的数据。 PM 2.5 是在空气中测量的颗粒物。简而言之,数字越大,空气质量越差。

我们将通过 Selenium 实现什么自动化:

从网站收集 PM 2.5 数据的手动过程

本文涵盖以下主题:

  1. 选择网站
  2. 在 Python 中设置 Selenium
  3. 从网站抓取数据并存储
  4. 使用 Python 中的 Seaborn boxplot 分析数据

1.选择网站

在你决定删除哪个网站之前,一个自然的问题来了——从网站上删除数据合法吗?

如果你想知道网站上是否允许抓取,首先你应该检查链接上的信息:在网站的末尾添加“robots.txt”。例如:www.examplewebsite.com/robots . txt

让我们看看我们是否能废弃 Facebook.com。当你打开链接www.Facebook.com/robots . txt你会看到以下信息:

上面明确写着你需要脸书的特别授权才能销毁这些数据。为了更好地理解 Robots.txt,请点击查看更多信息。

总是建议在知识共享协议下许可的、有开放数据源的或在 Robots.txt 中不禁止抓取的网站上使用抓取。

由于这个项目是非商业性的,并且网站【www.openaq.org】有开放的数据,可以通过多种方式访问,我们决定用它来进行抓取。他们甚至鼓励人们在他们令人敬畏的 FAQ 中使用数据做好事,值得一查!

www.openaq.org

收集什么数据?

在这个网站上,我们决定删除关于国家和 PM 2.5 信息的数据。为了做到这一点,我们希望过滤 PM 2.5,并为每个国家访问位置卡。然后复制 PM 2.5 数据(是一个数字)。基本上,我们想做的和下面的 gif 一样。

从网站收集 PM 2.5 数据的手动过程

看起来很累很无聊吧?访问大约 100 个国家的页面,每个国家有多达 15 个位置。喔喔喔!!!不会吧。但好消息是 Selenium 可以为我们实现自动化。但是!我们需要设置这个。

2.在 Python 中设置 Selenium

你应该在你的电脑里安装 Selenium。只需在命令提示符下键入pip install selenium(对于 Windows)并按回车键。有关安装的更多详细信息,请参见 Selenium 文档

从命令提示符安装 Selenium

然后你需要一个驱动程序,作为 Selenium 访问你的浏览器的桥梁。就我而言,我为 Mozilla Firefox 下载了一个 geckodriver 。取决于您的版本,您可以从这里下载:

火狐:https://github.com/mozilla/geckodriver/releases

考虑到你下载了 geckodriver ,将其解压,并复制粘贴geckodriver.exe到你的 python 所在的文件夹中。

将 geckodrive.exe 复制粘贴到 python app 所在的文件夹中(我的案例)

创建一个. py 文件并导入主库和包。

Selenium 的主要库和包

然后我们需要找到到我们的geckodriver.exe的路径,并用 python 代码设置 webdriver,如下所示。

Python 中的 WebDriver 设置

3.从网站抓取数据并存储

抓取工作流程如下所示:

刮擦 4 步工作流程

3.1 获取过滤器中的国家名称

我们需要与过滤器中的国家名称完全相同的拼写。从过滤器中获取值似乎有点困难。相反,我们可以从这个链接中获得所有国家的名称。它们将具有相同的拼写。

如果您右键单击国家名称并转到 Inspect 元素,您将看到国家名称保存在 class card__title 中。

废弃国名代码的主要部分如下所示:(全称)

结果是一个保存在 CSV 文件中的国家列表。

3.2 获取每个国家页面的链接

我们希望有网站时,每个国家都在过滤器中选择迭代。我们将使用刚刚生成的 CSV 文件中的国家名称。

我们要删除的链接:

以奥地利网站为例

代码:

Github Gist 上的代码

此步骤的结果是生成包含国家/地区& country_url(某个国家/地区的网站)的 CSV 文件。完整的代码是这里是。这些链接将在下一步中使用。

在步骤 3.2 中生成的 CSV 文件

3.3 从一个国家的页面,获取每个位置卡的链接

基本上,我们希望获得访问每个位置卡的链接:

访问每个位置卡的链接

我们可以通过类名删除位置卡的链接,并检索 href。

检查位置卡标题、类名和 href 的元素

刮位置卡链接功能及代码:(全代码)

3.4 打开位置卡,废弃 PM 2.5 数据

这是刮的最后一步。由于我们有每个位置卡的链接,我们可以访问每个卡上的 PM 2.5 数据并将其废弃。此外,我们将废弃同一页上的位置城市和国家。

AT2KA21 的位置卡

用 XPath 获取 PM 2.5 数据并分成不同的变量:(完整代码)

用 XPath 获取 PM 2.5 数据,Github Gist 上的代码

获取位置细节并分解成变量:

获取位置细节,Github Gist 上的代码

如果您看到完整的代码,我们会将在这一步收集的所有数据保存到 CSV 文件中。

步骤 3.4 的结果

4.使用 Python 中的 Seaborn boxplot 分析数据

在我们创建 Seaborn 箱线图之前,有几个数据操作步骤。过滤数据 PM 2.5 > 0;日期创建于 2020 年,仅限欧盟国家:

Github Gist 上的过滤代码

Seaborn Boxplot 的背景:

Github Gist 上的 Seaborn Boxplot 代码

结果是:

显示 2020 年不同欧盟国家空气污染的箱线图

逐步使用 Flask & Python 部署自定义对象检测

原文:https://towardsdatascience.com/step-by-step-yolo-model-deployment-in-localhost-using-python-8537e93a1784?source=collection_archive---------2-----------------------

自定义对象检测本地主机部署

照片由埃米尔·佩龙Unsplash 上拍摄

你只看一次(YOLO)是一个最先进的,实时对象检测系统。最新版本是 YOLOV5。这些 YOLO 型号以速度著称。他们可以在几秒钟内检测到视频帧中的多个对象。与 EfficientDet 和 RetinaNet 等模型相比,YOLO 模型的推理时间更短。YOLO 以其检测图像/视频中物体的速度而闻名。如果您的使用案例更关注多个对象的实时检测,那么 YOLO 是最合适的。现在,我们有 YOLO V5,它的小型版本大约有 476 FPS

在本文中,我将带您完成在 localhost 中部署您自己的定制 YOLO 模型的步骤。

那我们开始吧

在这里,我将简要介绍所有其他步骤,因为我们的议程是部署模型并在我们的网站上使用它。

  1. 抓取图像进行标注:这是第一步。在这里,你可以去谷歌搜索你想要定制的图片。或者,您可以四处查看并单击对象的照片,然后为模型收集这些照片。这是你的选择,你希望你的模型有多好。
  2. 给你的图片贴标签。为这一步提供大量数据,因为这对您的准确性至关重要。您可以使用任何工具来标注数据。没有自动标记自定义数据的方法。你必须手动操作。这是客体滞留中最令人沮丧也是最费时的部分,但是如果你把你的奉献给这一部分,你肯定会得到一个丰硕的成果。我使用了“LabelImg”工具进行标注。要了解更多关于“LabelImg”工具如何工作的信息,请阅读本文如何为对象检测标记图像
  3. 选择物体检测算法这里,我们将使用 YOLO-泰尼。并且,您可以在此处参考自定义对象检测代码。https://github.com/pranjalAI/Yolo-tiny-insurance还有许多其他方法用于对象检测,如 SSD、Yolo 等。
  4. 从第 3 步获得 Yolo 权重文件后,您需要转换 Yolo 生成的暗网模型。权重文件到 TensorFlow 服务,以便我们可以使用 TensorFlow 服务到我们的网页。

如果你已经到达这里。干杯!!你做得很好。您已经准备好将您的模型投入生产。

威尔·斯图尔特在 Unsplash 上拍摄的照片

皈依。重量文件是暗网格式到 TensorFlow 格式,你需要按照以下步骤。

暗网转张量流

克隆这个目录https://github.com/pranjalAI/tensorflow-yolov4-tflite

使用命令提示符进入目录。

照片由沙哈达特·拉赫曼Unsplash 上拍摄

现在,您需要安装一些依赖项/库。

安装库

如果您安装了 anaconda,那么您需要按照这个步骤在一个环境中安装所有需要的库。这将创造一个新的环境。环境名可以在。yml 文件。

# Tensorflow CPU
conda env create -f conda-cpu.yml
conda activate yolov4-cpu# Tensorflow GPU
conda env create -f conda-gpu.yml
conda activate yolov4-gpu

如果您没有安装 conda,那么请使用 pip 命令。我建议使用康达。

# TensorFlow CPU
pip install -r requirements.txt# TensorFlow GPU
pip install -r requirements-gpu.txt

因此,创建了具有各自依赖性的新环境。现在,要使用新创建的环境,您需要激活它。(这一步是为那些正在使用康达创造环境的人准备的。)

粘土堤Unsplash 上拍照

激活环境

康达激活 yolov4-gpu

这里“yolov4-gpu”是环境名。您可以在中更改它。yml 文件。(这一步是为那些正在使用康达创造环境的人准备的。)如果您正在使用 pip,则直接进行下一步。

现在,如果您进入了刚刚克隆的文件夹,并且已经激活了环境,最后,您需要在克隆的文件夹中进行两项更改。

首先,复制并粘贴您的自定义。重量文件,你用你的 Yolo 模型训练,到'数据'文件夹,并复制和粘贴您的自定义。“数据/类/”文件夹中。

其次,您需要对代码进行的唯一更改是在“core/config.py”文件的第 14 行。更新代码以指向您的自定义。名称文件如下所示。(我的习俗。names 文件称为 custom.names,但您的名称可能不同)

注意:如果你使用的是预先训练好的 yolov4,那么确保第 14 行仍然是 coco.names

开始了。!现在,我们需要一个命令行来使代码 TensorFlow 兼容

[## 程序员的 9 个方便的 Python 函数

根据我个人的脚本编写经验

medium.com](https://medium.com/better-programming/9-handy-python-functions-for-programmers-cc391a59acc7)

python save_model.py - weights。/data/your _ weight _ file . weights-output。/check points/yolo-tiny-416-input _ size 416-型号 yolov4

这里,416 是您在训练 yolo-tiny 时在配置文件中定义的图像大小。运行上述命令后,您将获得一个. pb 文件

现在,您需要在检测对象时给出这个文件夹的位置。现在,喝杯茶。搜索您可以使用的任何 HTML 模板。我们可以在这里讨论一些 HTML 的东西,但是,我们将在下次做。这里,我假设您已经准备好了一个演示网页。

照片由曼基·金Unsplash 上拍摄

使用 flask 服务 TensorFlow 模型

现在我们有了 TensorFlow 服务模型。现在,我们需要使用 flask 将它提供给我们的网页。

现在,将这个最终的对象检测和裁剪代码粘贴到您获得 TensorFlow 服务模型的同一个根文件夹中(检查上面的步骤)。

现在,您的 flask 应用程序将调用它来检测图像。

最终演示

工作演示

所以,恭喜你!您刚刚使用 Flask 在本地主机上部署了第一个自定义对象检测模型。尝试使用您的自定义对象,并对您部署的自定义对象检测模型进行注释。

在你走之前……

如果你喜欢这篇文章,并且想继续关注更多关于 Python &数据科学精彩文章——请点击这里https://pranjalai.medium.com/membership考虑成为一名中级会员。

请考虑使用我的推荐链接注册。通过这种方式,会员费的一部分归我,这激励我写更多关于 Python 和数据科学的令人兴奋的东西。

还有,可以随时订阅我的免费简讯: Pranjal 的简讯

用 Python 升级你的正则表达式游戏

原文:https://towardsdatascience.com/step-up-your-regex-game-in-python-1ec20c5d65f?source=collection_archive---------13-----------------------

Python 中使用正则表达式的高级文本操作

照片由本·怀特Unsplash 上拍摄

正则表达式(RegEx)是最好的工具之一。我可能有偏见,因为我的大部分工作都集中在自然语言处理(NLP)上,但是不管有没有 NLP,我发现自己一次又一次地求助于正则表达式。

我绝不是专家,有很多东西我不知道——但是我已经经常使用正则表达式好几年了,所以我对它们足够了解。

在这篇文章中,我想分享一些 regex 方法,我认为它们稍微高级一些,但是非常有用。我们还将包含实际的代码,以便我们能够正确地理解正在发生的事情。我们将涵盖:

**Look-ahead/behind Assertions** - (?>= ) | (?= ) | (?>! ) | (?! )
**Modifiers** - (?sm)
**Conditionals (If|Else)** - (...)?(?(1)True|False)

前瞻/后见断言

这些是我用过的最有用的正则表达式方法。

靠近页面顶部是我的名字,在 HTML 中是我的用户名。看起来是这样的:

<a href="/**@jamescalam**?source=post_page-----22e4e63463af----------------------" class="cg ch au av aw ax ay az ba bb it be ck cl" rel="noopener">James Briggs</a>

假设我们现在感兴趣的是从页面的 HTML 中提取用户名,我们已经提取了所有的<a>元素,并将使用 RegEx 来识别和提取用户名。

我们可以做一些乱七八糟的事情,像这样:

if '<a href"/@' in a:
    username = a.replace('<a href="/', '')
    username = username.split('?source')[0]

但是使用后视和前瞻断言,我们会得到更动态、更灵活的逻辑,如下所示:

if bool(re.search(r'**(?=<\/)'@.*(?=\?source)**', a)):
    username = re.search(r'**(?=>\/)'@.*(?=\?source)**', a).group()

这里将从这个(或任何文章)页面上的<a>元素中提取任何用户名。但是它看起来很复杂——所以让我们把问题简化一点。

向后看

后视断言告诉我们的 regex to assert 任何潜在的匹配都是在之前给出给断言的模式。让我们比较有和没有这个断言的正则表达式:

这里,我们没有使用回顾断言——因为我们只搜索 hello world ,我们返回两个匹配。截图来自 Regex101

通过为' 1: '添加一个回顾断言(突出显示),我们只匹配前面有' 1: '的 hello world 。截图来自 Regex101

在这里,我们告诉我们的断言,断言1: 先于hello world

当然,我们也可以仅将第一个 hello world 与"1: hello world"匹配,但是这将在我们的匹配中包括"1: "——无论什么包含在我们的断言中,在匹配的输出中都不包括

  • 回顾过去——我们在回顾我们的模式。
  • 断言 —我们断言这个其他模式的存在,但是我们并不匹配它(例如包含在我们输出的文本中)。

向前看

我确信,在理解了“看- 后面的断言之后,一个“看- 前面的断言的行为是可以预见的。让我们确保我们的 hello world 后面跟着一个**,**:

通过为''添加一个前瞻断言(突出显示),我们只匹配后面跟有逗号的 hello world 。截图来自 Regex101

底片

我们刚刚讨论的两个断言都是肯定的断言——我们断言我们的匹配模式在我们的断言模式之前/之后。

然而,我们经常需要断言我们的模式是而不是紧挨着另一个。为此,我们分别使用回顾和前瞻断言的否定形式— **(?<! )****(?! )**

负的后视断言(左)和负的前视断言(右)。截图来自 Regex101

在实践中

为此,我们将使用安然电子邮件数据集。我们有两列,filemessage——我们想要的一切都在message中。如果我们看一下第一个message列,我们会发现:

我们希望从这些数据中提取出Message-IDDate

我们可以这样写:

def boring_extract(msg):
    msg = msg.splitlines()
    **msg_id** = ''.join(
                 msg[0].replace(
                     'Message-ID: <', ''
                 ).split('.')[:2]
             )
    **time** = msg[1].replace('Date: ', '')[-5:]

现在,这看起来很糟糕,并且将需要很长时间来运行——它也根本不是动态的,如果由于某种原因,数据或DateFrom开关位置中的某个字段丢失了,该怎么办?—代码会被破解。

这就是我们使用正则表达式的地方,严重依赖于前瞻和后视断言。让我们比较使用和不使用正则表达式的代码:

**Message-ID**

**No RegEx**
msg = msg.splitlines()
msg_id = msg[0].replace('Message-ID <', '')
msg_id = msg_id[0].split('.')[:2]
msg_id = ''.join(msg_id)**With RegEx**
msg_id = re.search(r'**(?<=Message-ID: <)**\d+.\d+**(?=.)**', msg).group()

**Date**

**No Regex**
msg = msg.splitlines()
time = msg[1].replace('Date: ', '')[-5:]**With RegEx**
time = re.search(r'**(?<=Date: )**.***(?= \(\w\w\w\))**', msg).group()

Message-IDDate正则表达式中,我们都以**(?<= )**开始,以**(?= )**结束——分别是积极的后视和前瞻断言。对于上面的例子,我们为msg_idtime输出如下:

**[Out]:** 18782981.1075855378110

**[Out]:** Mon, 14 May 2001 16:39:00 -0700

修饰语

同样,RegEx 的一个非常有用的特性。修饰符允许我们修改正则表达式的行为。

例如,以单行修饰符**s**为例——这将把.*的行为从包括新行改为包括新行:

不带单行全局修改器(左)和带单行全局修改器(右)—右上角的标志 s 表示我们已经应用了该修改器。截图来自 Regex101

只需添加这个标志就可以改变正则表达式的行为。有一大堆不同的修改器,我们甚至可以合并它们来创建更具体和独特的行为。这些改性剂中最常见的包括:

**Single line [s]** - Allows the **.** metacharacter (which matches everything **except** newlines) to match newlines too**Multi-line [m]** - **^** and **$** now match the **beginning/end of lines**, rather than default behavior of matching beggining/end of entire string**Insensitive [i]** - Upper **and** lower-case characters are matched, e.g. **A = a****Extended [x]** - **Ignores whitespace**. To include spaces, they must be escaped using **\**. Also allows comments inside the regex with **#****ASCII [a]** - Match to **ASCII-only** characters, rather than the full Unicode character set

在 Python 中,我们可以用两种方式实现这些修饰符。

(1)修饰符标志在表达式之外实现,作为函数的附加参数,它们应用于整个正则表达式。添加单行修饰符和不敏感修饰符将如下所示:

re.match('[a-z]+01.*', text, **re.S|re.I**)

注意,我们使用按位 OR (|)将多个修饰符串在一起。

(2)行内修饰符在表达式中使用(? )语法——其中修饰符标记跟在?后面。实现单行和不敏感修饰符只需要(?**si**),就像这样:

re.match('**(?si)**[a-z]+01.*', text)

根据语言的不同,RegEx 实际上可以支持模式子部分中的修改行为——使用内联修饰符(? )来启动行为,使用(?- )来关闭修饰符:

使用内联修饰符修改正则表达式的一个子部分——注意这在 Python 中不会起作用。

然而,这个负的内联修饰符在 Python 中不受支持,一个内联修饰符(放在任何地方)将影响整个模式——而不仅仅是它的一部分。

我从未遇到过这样有用的问题——所以我不认为我们在这方面错过了什么。

条件句(If | Else)

RegEx 中的条件语句真的很酷——尽管可能有点特殊。

就像 Python 中的if else语句一样,我们可以在正则表达式中集成相同的逻辑。它的工作原理是说:

好吧,我们的模式匹配吗?(hello)?(?(1)

如果是这样——现在我们匹配模式 A,(?(1) world|

否则—我们匹配模式 b。bye)

合在一起,这给了我们(hello)?(?(1) world| bye)

使用条件语句的正则表达式示例。截图来自 Regex101

第一部分是我们的捕获组**(hello)**——分配给(1),因为它是我们的正则表达式中的第一个捕获组。通过添加?,我们使这个匹配成为可选的(否则,它将只在 true 时匹配)。

然后我们问一个问题?(1)——意思是捕获组(1)匹配吗?

如果匹配,我们的正则表达式将尝试匹配逻辑语句中的第一个参数world

或者,如果捕获组(1)不匹配—我们的正则表达式将尝试匹配语句中的第二个参数bye

如果我们在 Python 中测试,我们会看到相同的结果:

本文到此为止,在处理文本时,在 RegEx 中使用这三个特性可以给代码带来巨大的变化。它们都是我生活中不可或缺的特征。

我希望您从这篇文章中学到了一些东西,并且会像我一样发现这些特性很有用。如果您有任何建议或问题,请随时通过 Twitter 或在下面的评论中联系我们。

感谢阅读!

有兴趣学习更多的正则表达式吗?我写了这篇关于使用正则表达式解析 Python 代码来构建自动文档工具的文章,请随意尝试一下!

[## Python 的自动文档

编写代码很无聊,为什么要浪费时间呢?

towardsdatascience.com](/auto-docs-for-python-b545ce372e2d)

Jupyter 用户的生产力提示

原文:https://towardsdatascience.com/stepping-into-intermediate-with-jupyter-f6647aeb1184?source=collection_archive---------21-----------------------

数据科学

使用 Jupyter 笔记本和 JupyterLab 让您的工作流程更加高效

里卡多·戈麦斯·安吉尔在 Unsplash 上的照片

**Table of Contents**[**Introduction**](#6439)1\. [Startup files](#9431)
2\. [Auto reload](#809c)
3\. [Multi-cursor](#fe1b)
4\. [Exit confirmation](#e064)
5\. [Update you python packages](#4b45)
6\. [Copying cells from another file](#83e1)

介绍

要成为一个高效的 Jupyter 用户,有几件事你需要知道。在这篇文章中,我将通过六个技巧来提高你的工作效率。这些提示在 Jupyter 笔记本和 Jupyter 实验室都有效。

有关 Jupyter hacks 和版本控制的更多信息,请阅读这些文章。

启动文件

如果你一次又一次地输入同样的东西,启动文件就是你的解决方案。Jupyter 笔记本将自动访问启动文件夹中的文件。一般 Mac 中默认位置是/Users/<your_profile>/.ipython/profile_default/startup

您可以通过在 Jypyter 笔记本单元中运行这个命令来找到您的启动目录。

get_ipython().profile_dir.startup_dir

输出可以是这样的。

'/Users/<your_profile>/.ipython/profile_default/startup'

当您启动 Jupyter Notebook 时,可以在此目录下创建一个或多个要运行的文件。

例如,创建一个名为 00-startup.py 的文件,并添加以下代码。

import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
get_ipython().magic('matplotlib inline')

当你使用魔法%时,你需要使用如上图所示的get_ipython().magic()

重启你的 Jupyter 笔记本。可以不用进口熊猫或者 Numpy。

您可以根据需要添加更多库。示例

[## 如何在 Docker 上运行 Jupyter 笔记本

不再有 Python 环境和包更新

towardsdatascience.com](/how-to-run-jupyter-notebook-on-docker-7c9748ed209f)

自动重新加载

当你修改一个导入的文件时,你必须重启内核。但是autoreload在进入执行单元之前会自动重新加载模块。

您可以将它添加到其中一个单元格中并执行它。

%load_ext autoreload
%autoreload 2

通过保存修改后的文件,它可以在另一个文件中自动重新加载。

如果您想一直启用此设置,您可以将其添加到~/.ipython/profile_default/ipython_config.py

如果没有文件,可以先打ipython profile create

ipython profile create
[ProfileCreate] Generating default config file: '/Users/yourname/.ipython/profile_default/ipython_config.py'
[ProfileCreate] Generating default config file: '/Users/yourname/.ipython/profile_default/ipython_kernel_config.py'

第 31 行左右:

# ~/.ipython/profile_default/ipython_config.py

c.InteractiveShellApp.exec_lines = ['%autoreload 2']

c.InteractiveShellApp.extensions = ['autoreload']

自动重新加载正在运行。

多光标

您可以用光标选择多个位置。点按您想要开始的位置,按下 Option 键,拖移光标,开始键入。您可以使用 Cmd+右箭头键跳到每一行的最右边。

退出确认

有多少次你在按 Ctrl+C 键关机后输入 y 并按下 return 键?您可以通过按 Ctrl+C 两次来跳过它。

更新您的 python 包

你是否定期更新 python 包?

检查您需要更新的软件包。这将列出过时的软件包。

pip list -o
# or
pip list --outdated

你可以运行install -U来更新一个包。

pip install -U package

如果你想一次更新所有的包,在你的终端上运行这个。

pip list --outdated --format=freeze | grep -v '^\-e' | cut -d = -f 1  | xargs -n1 pip install -U

pip check验证哪些已安装的软件包具有兼容的依赖关系。如果发现问题,需要使用pip install 'packagename==0.14.1'安装正确的版本。

其他有用的命令有:

pip 参考

从另一个文件复制单元格

在 Jupyter Notebook 中,您可以通过按 cmd+v 两次从另一个文件复制粘贴。如果你只按一次,你会得到下面的警告。在 JupyterLab 中,您需要使用c来复制一个或多个单元格,并使用v将其粘贴到另一个文件中。

我希望这些建议能帮助你提高工作效率。你最喜欢的小费是什么?

通过 成为 会员,获得媒体上所有故事的访问权限。

https://blog.codewithshin.com/subscribe

关于 Jupyter 的更多文章

[## 使用 Jupyter 笔记本进行版本控制

Jupytext 分步指南

towardsdatascience.com](/version-control-with-jupyter-notebook-b9630bc5996e) [## Jupyter 的技巧和窍门

Jupyter 技巧和提示的集合

medium.com](https://medium.com/series/jupyter-hacks-and-tips-1b1a3a10bc79) [## 如何在 Jupyter 中创建一个有吸引力的气泡图

从 Github repo 抓取数据的分步指南

towardsdatascience.com](/how-to-create-an-attractive-bubble-map-5cf452c244e9) [## 手把手的 Jupyter 笔记本黑客

您应该使用的技巧、提示和快捷方式

towardsdatascience.com](/hands-on-jupyter-notebook-hacks-f59f313df12b) [## 用 Jupyter 笔记本写作的 7 个基本技巧

第一篇数据科学文章指南

towardsdatascience.com](/7-essential-tips-for-writing-with-jupyter-notebook-60972a1a8901)

赢得系统设计面试的步骤

原文:https://towardsdatascience.com/steps-to-ace-the-system-design-interview-1908ffb77b9b?source=collection_archive---------33-----------------------

约翰娜·布格特在 Unsplash 上的照片

(这个帖子也在我的博客里)

澄清

系统设计面试和编码面试一样,不仅测试候选人的技术技能,还验证候选人是否能解决一个没有很好定义的问题。问题问得模糊笼统。候选人的工作是找出需求并提出合适的设计。应聘者在得到问题后马上投入设计是一个常见的错误。对于 Twitter 上的 design 这样的问题,你可能需要弄清楚需要考虑哪些核心功能,注册?简介?文字推文?视频/图片推文?时间线?其他技术要求可能是每秒读写?请求的峰值/平均值?用户基本位置?

工作解决方案的关键组件

一旦你有了需求,你就可以开始考虑系统或者子系统的结构,如果它是针对一个以上的特性的话。首先找出一个可行的解决方案总是好的,而不是试图提出一个完美的最优解决方案。试着想出一个包含所有必要组件的简单系统。在白板上展示系统。组件包括应用服务器、数据存储(SQL 或 NoSQL)、代理、CDN、消息队列、事件总线等。选择基本解决方案所需的组件。解释为什么需要这些组件,它们应该如何连接在一起,以及用户如何与系统交互。

列出 API

API 是组件间通信的表达。能够设计一套逻辑 API 是候选人的优势。对于 RESTful API,最好遵循 REST 惯例,使用适合 CRUD 等资源操作的 HTTP 动词。路径应该是代表资源的名词。这也有助于展示您可以在设计中正确地使用查询参数和请求体。

最佳化

然后,你需要优化系统。当考虑优化时,你需要优化正确的东西。最好是针对常见用例进行优化。例如,如果从数据库中读取数据比向数据库中写入数据更常见,那么在数据请求者和持久数据存储之间引入缓存是有意义的。它有助于更快地提供热数据,并且缓存失效的频率会降低,因为写操作并不多。但是,为写入密集型系统引入缓存会对性能产生负面影响,因为这将经常导致缓存失效。其他优化可以是根据用户的位置将请求分配到不同的数据中心。将数据库划分为碎片来处理请求。正确设计表中的键,使请求流量均匀分布到分区。

可量测性

随着用户群的增长会怎么样?毫无疑问,您将需要设计一个水平可伸缩的系统。水平可伸缩性意味着系统可以通过增加越来越多的商用计算能力来处理更多的请求。这比增加一台服务器的马力更具成本效益。

交易

毫无疑问,你听说过很多流行的软件来构建一个分布式系统。比如 MongoDB,ElasticSearch,Memcached,Kafka 等等。然而,随意向面试官抛出这些流行语并不足以打动他们。对你来说,解释选择和为什么不选择另一个是很重要的。比如 MongoDB 给你的好处有哪些是 MySQL 不会的?也许你的应用程序并不关心数据模型之间的关系,比起强一致性,它更喜欢更好的性能。再比如,为什么你会更喜欢用 Kafka 构建事件驱动的系统。也许您的业务逻辑是一个长流程,需要异步完成。也许你有一些子系统需要知道这个事件。

错误处理

软件从来都不是完美的,所以作为候选人,你应该解释你的系统是如何处理错误的。一个关键点是,您能够识别单点故障,并提供解决方案来降低整个系统的故障率。另一个常见的错误场景是流量太大,系统无法处理。一种常见解决方案是节流。节流是限制系统请求数量的过程。通过限制每个客户端的请求数量,系统可以具有相对可预测的工作负载。因此,它也有助于计划社交。

临终遗言

这些是您在系统设计面试中需要考虑的一些要点。如果您想了解更多关于系统设计的技术细节,我推荐使用设计数据密集型应用研究系统设计作为准备的参考。祝你好运。

以前的帖子:

我关于 FAANG 访谈的帖子

我关于金融和科技的帖子

神经网络、计算机视觉和自动驾驶汽车之间的关系

原文:https://towardsdatascience.com/stereo-vision-neural-nets-and-demand-in-autonomous-vehicles-6a9b6e6de41c?source=collection_archive---------41-----------------------

自动驾驶汽车(AV)正在大力发展,许多公司在这方面投资了数百万美元。2017 年,福特投资 Argo AI 生产自动驾驶技术。Argo AI 随后与卡耐基梅隆大学合作,在 T2 投资了 1500 万美元用于 AV 研究。

其他公司也纷纷效仿,包括韩国汽车制造商现代和日本巨头丰田分别投入17 亿6 . 67 亿

来源:Self,特斯拉网络卡车大会 via Carscoops |有些公司确实比其他公司更挣扎

管理咨询公司麦肯锡公司(Mckinsey & Company)估计,2015 年至 2030 年将是以研发为重点的 AVs 商业化应用的第一个时代。据预测,从 2030 年及以后,消费者将更频繁地购买 AVs。目前,随着买家的疲惫,公司正努力与目标市场建立联系,需求增加可能还需要一段时间。

研究兴趣和资金随时可用,因此现在是试验各种 AV 技术的最佳时机,如视觉系统。当前的视觉系统通过用景深数据辅助其运动估计算法来充当车辆的眼睛。最大的两个竞争对手是激光雷达(光探测和测距)和立体视觉

什么是激光雷达为什么要用?

激光雷达是一种激光扫描仪,它产生点云,提供周围环境的 3D 重建,允许深度和海拔估计。

来源:丹尼尔 l 卢 via 维基媒体旧金山十字路口的点云

激光雷达的工作原理是将一束光射到一面旋转的镜子上,光线被反射到多个方向。一旦射线返回,它被反射回扫描仪,扫描仪测量物体有多远。

来源: Steven Waslander via ME597 在滑铁卢大学用于激光雷达的旋转镜和扫描仪

由于光的波粒二象性,光线可以表示为正弦函数。发出的光线和返回的光线会产生相移。给定相移和已知射线波长,计算距离;这个过程重复得非常快,并产生一个详细的地图。

来源: Steven Waslander via ME597 在滑铁卢大学激光雷达扫描仪应用的相移&距离推导演示

由于扫描仪和反射镜所需的精度,激光雷达系统可能会很贵,根据所需的自主性和应用水平,市场价格从 1 000 美元到 75 000 美元不等。

立体视觉呢?

立体视觉是一种有趣的替代方式,它使用多相机设置来估计深度,令人惊讶的是,它是基于人类如何做到这一点的!

实验时间到了

现在试试这个:闭上你的右眼,把你的手指放在你的面前,集中注意力。现在闭上另一只眼睛,重复这个动作。

如果你很难做到这一点,不要担心,有一个 Wikihow 可用

好了,现在你做完了,你的手指动了一下,对吗?

别担心,你的眼睛工作正常,这是它们的几何学的结果。你所经历的现象被称为视差,当从两条不同的视线看到一幅图像时,这种现象就会发生,因此,图像看起来会移动。在这种情况下,两条视线就是你的眼睛。

将几何学用于视差的动机

用双眼正面盯着一个物体会产生深度,因为我们自己的视觉似乎是会聚的。这类似于一张透视照片,所有平行线相交于某个遥远的地平线点。

来源:Diego Delso via Wikimedia|透视信息丢失,相机需要额外处理才能重现

然而,相机拍摄的图像不能像我们的眼睛那样创造深度。

图像将世界的 3D 视图转换成 2D 投影。更正式地说,这导致一条线转变成一个点。在欧几里得空间,即包含在 2D 平面中的几何空间中,平行线不能像在透视图像中那样与相交(透视图像属于射影空间)。这由左边所示的线表示,尽管它对应于不同距离处的独特点,但相机无法分辨。从摄像机的角度来看,它看到的是一个点 x 而不是线 OX

来源: OpenCV 文档 |立体设置涉及极线几何关联两个相机投影;注意尾线如何穿过可能解决方案处的l’

相机不能像我们的大脑一样相互通信,以帮助我们的眼睛产生图像。这导致在不同角度拍摄的同一图像的两个平面投影。所有深度信息都已丢失。然而,通过对两个投影进行三角测量,应用一些几何图形,并使用视差,相机可以相互关联以解析地求解距离。

上面显示的双摄像头设置是深度估计的基础,它被称为立体视觉。

有关坐标转换和相机的更多信息,请阅读这篇关于相机校准的文章

数学估算深度

推导和量化深度的视差效果是数学密集型的。如果你只对主公式感兴趣,请跳到这一小节的末尾。

有关推导,请参考上一小节中的图表。

假设两个摄像机都位于中心 OO’处,它们在 X 处会聚。

线 OX 在左投影平面上显示为一个点 x 。然而,当从右投影平面观察时,有一组对应的点,x’,它们在称为极线l’的平面中形成一条线。这表示深度并证明点 x 实际上是一条线OX;现在的任务是确定 x T21 在哪里。

沿着 OX 可以画出称为延长线的特殊线条,在O’处汇合。通过检查每条核线可以找到点 x ,直到找到一条与 x 相交的核线,这个解就是核线约束。多个 X 的指示,每一个都与一个特定的外延线相匹配,暗示该点的可能解决方案 x.

来源: OpenCV 文档 | 通过外极线 O'X 解决外极线约束;注意在 xOf、x’o’f 和 OO’x处形成的三个相似三角形

现在,这个问题可以从自上而下的角度重新审视。

给定对极线约束的特定解, x ,其在相对平面中的对应点,x’,视线 OX 和相对相机的对极线,O’x,深度可以被求解。

x 和 x’在不同的深度。

两条线, OXO’x处于不同的角度,但是可以通过等价的三角形来关联,这就是为什么差(x-x’)等于参数: B,f,Z(下面等式中的)。(x—x’)的差值就是视差 : 视差误差的数值度量。

更正式地,视差指的是两个相似区域的坐标距离(从任一图像投影来看)。视差与 深度 、Z、成反比关系,通过求解等价三角关系得到证明。

对于更近的物体,视差更明显,这表明当同一点出现在两个投影的不同位置时,视差很大。由于反比关系,它必须对应于一个短的深度。

用前面一节中展示的实验来验证上述假设。你的观察应该与定义的数学关系相匹配。

来源: OpenCV Docs | 视差计算用于隔离,求解深度:Z

x 的值通过极线约束求解,并且x’通过检查对面摄像机的图像投影得知。给定相机、 B焦距f 之间的一些距离,然后可以计算出 Z

将此应用于场景的所有像素产生一个视差图,它通过颜色指示深度。

来源: OpenCV 文档 |浅灰色物体更近,深灰色物体更远视差图

有关立体视觉和 3D 重建的更多信息,请访问 OpenCV 的文档Rich Radke 博士的 ECE6969 课程

立体视觉的缺陷与改进

虽然立体视觉不贵,但它的主要问题是处理时间。理想情况下,在 AVs 中,大多数系统将接近实时工作。然而由于解决极线约束需要很长时间,立体视觉系统本身无法足够快地工作。为了减少计算时间,正在研究使用机器学习来改进立体声系统并加速它们。

通过机器学习的立体视觉

在深入神经网络的细节之前,理解什么是图像是关键:一个图像是一个 2D 数字数组,每个数组元素是一个像素值。

由于这种结构,卷积神经网络(CNN)是理想的,因为它们在图像上应用滑动过滤器,将图像下采样为代表其可能值的单个向量。向量被传递到一个完全连接的网络,该网络为每个值分配概率,并输出最可能的匹配作为预测。

来源: Aphex34 via Wikimedia |典型的神经网络架构:对图像进行子采样,馈入全连通层并输出预测

为了了解更多关于 CNN 和神经网络的知识,迈克·庞德博士提供了简短的解释,正式的概念可以在斯坦福大学的视频讲座中找到。

罗,G. Swing,Urtasun Via 多伦多大学计算机科学系暹罗 CNN 架构学习分发

至于立体系统,图像被分割成左右两个投影,一次分析一个小区域。两个投影都被馈送到一个 连体 CNN ,其同时为左右投影中的对应区域上的视差创建一组可能的概率分布。然后,该组可能性被传递到一个全连接层,该层输出原始图像的单个片上最可能的视差分布

这意味着网络以被称为概率分布连续函数的形式输出差异的可能值的范围

概率分布代表结果发生的可能性,其中组结果显示在 x 轴上。随机变量包含这些结果作为可能的值。每个结果都有相应的可能性显示在 y 轴上。

来源: Atakbi1 via Wikimedia |一种叫做高斯分布的概率分布,最大值在中心(平均值)。以上 CNN 产生独特的概率分布

按照上面的 CNN,x 轴将填充视差值,y 轴填充这些差异是正确的可能性。CNN 学习并预测分布的形状。通过找到分布的最大值点,使用单独的算法来找到最可能的视差。

暹罗 CNN 设计允许对应于不同图像区域的差异被关联,这可能表明那些区域是同一表面的一部分。

暹罗 CNN 架构的扩展

先前的网络比较了左右投影并优化了匹配成本。这意味着在两个投影中搜索指向同一部分的补片。一旦找到,每个补片将被用于计算视差,给出该补片相对于平面的位置。由于已经找到了精确的点,这些网络围绕着解决极线约束的过程工作。

上面讨论的连体 CNN 是对过去网络的改进。通过改变优化参数来学习可能差异的分布,消除了计算差异的需要。取而代之的是,选择最有可能的视差,这使得连体 CNN 架构比其前身运行得更快。

Martin thoma via Wikimedia|扩展深度估计,共同解决语义分割等其他视觉任务

在过去,网络已经实现了组合解决方案,其中统一解决了对象识别和深度估计。因此,找到相关的差异可以扩展连体 CNN 设计,以允许其他视觉任务

自主视觉的未来

行业领导者 Waymo 使用激光雷达系统,特斯拉创始人埃隆·马斯克发表评论

"..任何依赖激光雷达的人都注定要失败..”

双方显然存在激烈的竞争和相互矛盾的观点。康奈尔大学的研究人员支持立体视觉,尽管公众担心它在无人驾驶汽车中的功效和安全性。

特斯拉不仅仅使用立体视觉;它的车辆实现了立体摄像机、雷达和地图绘制,以提供具有竞争力的精确度。尽管需要更多的技术,立体声系统的运行成本仍然低于激光雷达。

虽然安全至关重要,但企业必须盈利才能继续运营。对消费者来说,最大的障碍之一是市场价值,它直接与用于汽车设计的技术联系起来。正如开头提到的,AVs 还处于起步阶段,随着更多的研究和开发,很多东西都会改变。只有时间能证明哪种视觉系统更胜一筹。

解开 Stigmergic 独立强化学习

原文:https://towardsdatascience.com/stigmergic-reinforcement-learning-why-it-tells-us-1-1-3-4d50dfa9cb19?source=collection_archive---------50-----------------------

因为 1+1=3

JESHOOTS.COMUnsplash 上拍照

群优化是“多智能体学习”保护伞下的众多子领域之一。它信奉“人多力量大”的理念我们的代理人越多,我们能完成的就越多。这个领域试图使用极其大量的简单智能体来解决问题,每个智能体都为一个比自身更大的目标做出贡献。换句话说,群体优化利用了一个概念:

多主体系统比其单个组成部分的总和具有更大的灵活性、健壮性和潜力。

群体优化最流行的分支之一是 stigmergy。Stigmergic 算法允许代理通过环境使用本地信息间接协调。一个主体的行为会在环境中留下“痕迹”,并刺激其他主体的后续行为。然后,我们重复。

我们可以把斯蒂格利茨看作一种使用简单规则的方法论。每个代理都有一个很小的、全面的规则手册可以遵循,指导他们如何修补周围环境或与他人互动。如果每个规则书都设计正确,那么它们动作的组合最终会完成一些任务。

这种“级联动作”的想法在自然界中经常可以找到。蚂蚁和白蚁利用信息素间接相互交流,让它们能够搭建桥梁或建造复杂的巢穴。甚至在细菌中也观察到了群体行为,特别是粘细菌,其中群体行为由复杂的控制系统指导。

在这篇文章中,我们探索了 Stigmergic 独立强化学习,一种新的大规模多智能体学习方法。

萨阿德·萨利姆Unsplash 上拍摄的照片

动机

可扩展性是多智能体强化学习(MARL)的最大障碍之一,因为状态和动作空间随着智能体数量的增加呈指数增长。虽然已经提出了独立的学习算法来应对这一挑战,但是这些方法往往会遇到非平稳性问题。要了解更多关于 MARL 及其障碍的背景,请随意查看这篇文章:

[## 多主体强化学习:要点

好像一个机器人学习一切还不够

medium.com](https://medium.com/swlh/the-gist-multi-agent-reinforcement-learning-767b367b395f)

斯蒂格利茨独立强化学习(SIRL)提出了一种算法,它在显式联合学习和其独立对应学习之间提供了一种平衡。换句话说,该算法在大范围内协调不同的独立学习代理。

照片由埃里克·沃德Unsplash 拍摄

系统结构

斯蒂格利茨由四个主要部分组成:

  • 媒介:代理间接相互通信的方法或环境的一部分
  • 动作:原语,允许代理与环境或其他代理交互,通常改变其状态
  • 痕迹:一个特工留下的信号,用来和其他人间接交流
  • 条件:触发或允许执行某些动作的事件

使用这些公式,我们可以比经典的强化学习更容易地表示代理之间的间接协调。

在给定的条件下,代理在执行动作之后在介质中留下痕迹。

当这些痕迹由于许多起作用的因素而在介质中积累和混合时,它们各自根据应用相应地响应这些信号。在一个位置累积的轨迹越大,代理对特定信号的响应越剧烈。

照片由陈乐德Unsplash 上拍摄

在 SIRL 的表述中,环境媒介是分离的实体。我们可以把环境想象成一个物理状态的集合,在这个集合中代理可以表现、描述和定位他们自己。另一方面,媒介可以被认为是环境的一个特定部分,通过它传播信息。这种分离用于区分 SIRL 和经典的 RL 算法。SIRL 框架的其他部分将在随后的章节中概述。

避免冲突

冲突避免用于隐式协调代理,即使每个代理只有本地信息。这里有一个想法:让代理竞争动作机会,只允许一部分代理在给定的时间内执行动作。为此,每个代理都有一个评估模块和一个行为模块,每个模块都有自己的一套神经网络。

李灿明Unsplash 上拍照

评估模块测量代理的动作优先级给定其当前本地状态。换句话说,从评估模块获得更高回报的代理人更有可能执行他们的行动。

行为模块在给定本地状态和评估模块许可的情况下选择要执行的适当动作。因此,在确定行动时,总有两个步骤:

  1. 将本地状态传递给相应的评估模块,并使用协调信道与附近的代理进行比较
  2. 仅当代理在第一步中拥有足够高的动作优先级时,将相同的本地状态传递给相应的行为模块以选择适当的动作

这些数学公式将在本文后面讨论。

介质及其属性

在 SIRL,数字信息素(trace)用于代理之间的间接通信。这些信号存储在包含信息素分布的地图(介质)中,并向代理提供相关的状态空间信息。我们可以把这种表示想象成一个热图,由虚拟代理集中存储或者在指定代理之间分开。

数字信息素只是数字。数字越大,信号越强。如前所述,它们可以组合、混合和累积。SIRL 通过引入三个属性对此进行建模。当不同的信息素结合时,它使用线性叠加。此外,这些信息素不局限于单一空间,而是扩散到周围区域。最后,信息素的量级随着时间的推移而衰减。扩散率和衰减率是可调的超参数。

Katarzyna UrbanekUnsplash 拍摄的照片

数学

吸引子选择

我们假设每一个智能体都能在有限的范围内感知数字信息素。让我们将吸引子定义为信息素图中包含非零数量数字信息素的任何块。该块将对附近的代理有效地探索本地状态空间具有吸引人的效果。然而,对于代理选择一个动作,他们首先需要选择一个吸引子来进行它的动作(即。向吸引子移动)。代理选择特定吸引子的概率由下式给出:

概率代理 I 选择吸引子 j

其中 d_ij 是从代理 I 到吸引子 j 的距离。ε是位置 j 处的信息素的大小,xi 是范围内所有吸引子的集合,D 是某个单调函数。例如,在论文的实验中,函数 D 看起来像这样:

1中使用的 d 函数示例

这个概率值直观上是有意义的。我们可以看到,随着距离的增加,选择吸引子的概率降低。类似地,随着信息素数量的减少,概率也减少。所选吸引子的位置被连接到代理的本地状态,并被传递到评估和行为模块。

然而,有些人可能会问,为什么我们不简单地选择信息素强度和距离的最佳组合的吸引子呢?我们不希望我们的代理人聚集在一起,因为这违背了避免冲突的目的。实际上,最理想的是随机地选择吸引者。

信息素放置

在将本地状态传递给评估和行为模块之后,我们决定是否执行一个动作。如果有,我们就在环境中放置信息素:

信息素更新方程

其中 a 代表由一个代理投放的数字信息素的固定数量,b 是衰减率,如果一开始没有代理的话就应用。衰变有助于去除无用的吸引子久而久之。

奖励

我们假设传统的 RL 框架,试图最大化预期的累积回报。因此,我们将状态转换的奖励定义如下:

过渡奖励

其中 p 是比例因子。给定代理 I 和选择的吸引子 j,我们奖励使代理更接近吸引子的行为。

动作优先级

请记住,每个代理都有一个评估网络,它输出与它所拥有的操作优先级成比例的值。该值越高,越有可能允许执行某个操作。

由于我们希望最大化我们的总体预期回报,我们直觉地希望给予给定其本地状态下具有较高预期回报的代理行动优先权。因此,我们将我们的行动优先级定义为价值函数(V):

价值函数与政策

代理的状态值越高,它获得的操作优先级越高。随后,行为模块根据其策略选择一个概率最高的动作。我们还将 R_tilde 定义为:

其中该价值函数(V)表示目标价值网络的输出。目标价值网络定期复制价值网络的参数,并用于在训练时增加稳定性。同样,行为模块除了其政策网络之外,也同时拥有价值网络和目标价值网络。

定义所有的损失

我们快到了!接下来,我们定义每个代理中评估和行为模块的损失函数。评估模块的价值损失定义为:

评估网络损耗函数

代表代理 I 的 TD 误差平方。行为模块的值损失与上面类似。此外,它的政策损失类似于优势行动者批评家的损失,我们用计算出的优势函数来衡量负概率:

行为模块更新

注意变量 R 不再有波浪号。这些奖励由行为模块的目标值函数而不是评估模块的目标值函数定义,使其成为不同于以前的变量。

现在我们有了所有这些损失,我们可能会试图单独优化每个代理的模块。然而,这将有效地将算法简化为代理之间的独立学习。换句话说,每个代理人只优化自己的政策,而不考虑其他人,失去了我们最初开始优化的协调概念。

联邦培训

但是等等!我们的建筑还有最后一部分!在这里,我们解释联邦培训模块。虽然这是一个虚拟代理,但它包含与其他代理相同的体系结构和部件。它负责通过平均优化来优化每个智能体的神经网络模块。更正式地说:

v”上标表示属于联邦培训模块的参数。此外,“p”表示动量项,“l”表示学习率。更新仅对在该时间步中执行动作的代理求和结果,θ表示那些代理的每个相应模块的参数。在这里,我们通过对这些代理的梯度进行平均来更新联邦教练的参数。然后,因为联邦训练器具有相同的模块结构,我们能够将这些新参数发送回代理。实际上,我们已经做了几件事:

  • 更新了执行动作的每个代理的参数
  • 允许单个代理不仅根据他们的表现,还根据其他代理的表现来更新他们的策略
  • 在通常具有指数增长的状态和动作空间的上下文中,将更新缩小到线性 梯度组合

结果

论文中进行的实验涉及到像素组,每个像素组都是一个代理,它们按照数字的形状排列。例如,像素在 150 次迭代后学会了如何形成数字“4 ”,如下所示:

实验结果如1所示

SIRL 与其他四种方法进行了比较。

  • JL:仅使用行为模块共同学习最佳行为
  • IRL:类似于 JL,但输入向量只包含自相关本地状态
  • JL-O:类似于 JL,但是用代理的精确坐标代替吸引子
  • IRL-O:类似于 IRL,但是用代理的精确坐标代替了吸引子

SIRL 与它的竞争对手相比表现良好,在较少的训练周期内教会它的特工形成精确的队形。

数字 4 的相似性度量,如1所示

结束语

SIRL 提出了一种新的方法来解决多智能体系统的可扩展性问题。它为超大型系统中的强化学习提供了一种有前途的分散方法,并可以被视为从多机器人运动到交通信号控制等更复杂领域中基于群体的强化学习的起点。不管怎样,很明显,代理人通过合作所能完成的要比他们个人潜力的总和更大。它可能只是告诉我们,有时候,1 + 1 = 3。

参考

1 X. Xu,R. Li,Z. Zhao,和 H. Zhang,用于多智能体协作的 Stigmergic 独立强化学习 (2019)。

[2] F. Heylighen,stigmargy 作为一种普遍的协调机制:组成、种类和应用 (2015)。

从经典到最新,这里有讨论多代理和单代理强化学习的相关文章:

[## 纳什均衡介绍:朋友还是敌人 Q 学习

让机器人打破平衡

towardsdatascience.com](/multi-agent-rl-nash-equilibria-and-friend-or-foe-q-learning-4a0b9aae3a1e) [## 分层强化学习:封建网络

让电脑看到更大的画面

towardsdatascience.com](/hierarchical-reinforcement-learning-feudal-networks-44e2657526d7)

还在为你的机器学习模型解析用户代理字符串吗?

原文:https://towardsdatascience.com/still-parsing-user-agent-strings-for-your-machine-learning-models-use-this-instead-8928c0e7e74f?source=collection_archive---------31-----------------------

用这个代替

Emile Perron 在 Unsplash 上的照片

包含在用户代理字符串中的信息可以使用低维嵌入来有效地表示,然后在下游的机器学习任务中使用。

究竟什么是用户代理字符串?

当用户与网站交互时,浏览器向服务器发送 HTTP 请求,以获取所需的内容、提交数据或执行其他操作。这种请求通常包含几个,即指定给定请求参数的字符键值对。一个用户代理字符串(下面称为“UAS”)是一个 HTTP 请求头,它描述了代表用户的软件(图 1)。

图一。当向服务器发送请求时,浏览器充当用户的代理。用户代理字符串描述浏览器的属性。

UAS 的最初目的是 内容协商 ,即根据各自 UAS 中包含的信息(例如,图像格式、文档语言、文本编码等)确定提供给用户的最佳内容的机制。).这些信息通常包括浏览器运行环境的详细信息(设备、操作系统及其版本、地区)、浏览器引擎和版本、布局引擎和版本等等(图 2)。

图二。典型 UAS 及其元素的示例。

虽然为不同的浏览器提供不同的网页被 T2 认为是一个坏主意,但是现在,UAS 仍然有许多实际的应用。最常见的是网络分析,即报告流量构成以优化网站的有效性。另一个用例是 web 流量管理,包括阻止讨厌的爬虫,减少网站上不需要的访问者的负载,防止点击欺诈,以及其他类似的任务。由于它们包含丰富的信息,UAS 也可以作为机器学习应用的数据源。然而,后一种用例至今没有得到太多的关注。在这里,我解决了这个问题,并讨论了一种从机器学习模型的 UAS 创建信息特征的有效方法。这篇文章是我最近在两个会议上演讲的摘要— 为什么是 R?R 语言的企业应用 。下述示例中使用的数据和代码可从 GitHub 获得。

作为机器学习模型特征的 UAS 元素

UAS 元素通常可以作为用户特征的有用代理,例如生活方式、技术成熟度,甚至富裕程度。例如,通常从高端移动设备访问网站的用户可能不同于从运行 Windows XP 的台式计算机上的 Internet Explorer 访问同一网站的用户。当没有其他人口统计信息可用于用户时(例如,当一个新的、未被识别的人访问一个网站时),具有针对这些特征的基于 UAS 的代理可能特别有价值。

在某些应用中,区分人类和非人类 web 流量也是有用的。在某些情况下,这很容易做到,因为自动化网络爬虫使用包括单词“bot”(例如,Googlebot/2.1 (+http://www.google.com/bot.html))的简化 UAS 格式。然而,一些爬虫不遵循这个惯例(例如,脸书机器人在其 UAS 中包含facebookexternalhit两个字),识别它们需要一个查找字典。

从 UAS 创建机器学习功能的一个看似简单的方法是应用一个解析器,提取单个 UAS 元素,然后一次性编码这些元素。这种方法在简单的情况下可以很好地工作,当只有高级的和容易识别的 UAS 元素需要转换成特征时。例如,确定用户代理的硬件类型相对容易(移动对桌面对服务器,等等)。).几个高质量的、基于正则表达式的解析器可以用于这种特性工程(例如,参见“ua-parser”项目及其语言选择的实现)。

然而,当想要使用组成 UAS 的所有 元素并从中提取最大信息时,上述方法很快变得不切实际。这有两个主要原因:

  • 现有的关于用户代理头格式的建议没有以任何方式实施,在现实世界中,人们可能会遇到各种各样的 UAS 规范。因此,众所周知,对 UAS 的一致解析非常困难。此外,每天都有新的设备、新版本的操作系统和浏览器出现,这使得维护高质量的解析器成为一项艰巨的任务。
  • 可能的 UAS 元素及其组合的数量是天文数字。即使有可能对它们进行一次性编码,得到的数据矩阵也会非常稀疏,而且太大,不适合目前数据科学家通常使用的计算机的内存。

为了克服这些挑战,可以应用降维技术,将 UAS 表示为固定大小的向量,同时最小化原始信息的损失。当然,这个想法并不新颖,因为 UAS 只是简单的文本串,这可以通过使用各种自然语言处理方法来实现。在我的项目中,我经常发现脸书研究人员开发的 fastText 算法( Bojanowski 等人,2016 )产生了特别有用的解决方案。

描述 fastText 算法超出了本文的范围。然而,在我们继续举例之前,有必要提一下这种方法的一些实际好处:

  • 它不需要数据,也就是说,一个运行良好的模型只需要几千个例子就可以训练出来;
  • 它适用于短的结构化文档,如 UAS;
  • 顾名思义,训练快;
  • 它可以很好地处理“词汇之外的单词”,也就是说,它可以生成有意义的向量表示(嵌入),即使是在训练期间没有看到的字符串。

fastText 实现:选择您的武器

fastText 的官方实现可以作为独立的 C++库和 Python 包装器获得。这两个库都有很好的文档记录,并且易于安装和使用。广泛使用的 Python 库gensim有自己的算法实现。下面我将演示如何在 r 中训练快速文本模型。

围绕 fastText C++库有几个 R 包装器(参见[fastText](https://github.com/mlampros/fastText)[fastrtext](https://github.com/pommedeterresautee/fastrtext)[fastTextR](https://cran.r-project.org/web/packages/fastTextR/index.html))。然而,可以说在 R 中训练和使用 fastText 模型的最简单的方法是通过[reticulate](https://rstudio.github.io/reticulate/)包调用官方的 Python 绑定。将fasttext Python 模块导入到 R 环境中可以按如下方式完成:

# Install `fasttext` first 
# (see [https://fasttext.cc/docs/en/support.html)](https://fasttext.cc/docs/en/support.html))# Load the `reticulate` package 
# (install first, if needed):
require(reticulate)# Make sure `fasttext` is available to R:
py_module_available("fasttext")
## [1] TRUE# Import `fasttext`:
ft <- import("fasttext")# Then call the required methods using 
# the standard `$` notation, 
# e.g.: `ft$train_supervised()`

用快速文本学习 R 中的 UAS 嵌入

下面描述的例子基于来自whatismybrowser.com数据库的 200,000 个独特的 UAS 样本(图 3)。

图 3。本文示例中使用的 UAS 示例。数据存储在纯文本文件中,其中每行包含一个 UAS。注意,所有 UAS 都被标准化为小写,且没有应用其他预处理。

在 R 中训练一个无监督的 fastText 模型就像调用类似下面的命令一样简单:

m_unsup <- ft$train_unsupervised(
   input = "./data/train_data_unsup.txt",
   model = "skipgram",
   lr = 0.05, 
   dim = 32L, *# vector dimension*
   ws = 3L, 
   minCount = 1L,
   minn = 2L, 
   maxn = 6L, 
   neg = 3L, 
   wordNgrams = 2L, 
   loss = "ns",
   epoch = 100L, 
   thread = 10L
)

上述命令中的dim参数指定了嵌入空间的维数。在这个例子中,我们希望将每个 UAS 转换成大小为 32 的向量。其他参数控制模型训练的过程(lr —学习速率、loss —损失函数、epoch —历元数等)。).要理解所有参数的含义,请参考官方的 fastText 文档

一旦模型被训练,就很容易计算新案例的嵌入(例如,从测试集中)。下面的例子展示了如何做到这一点(这里的关键命令是m_unsup$get_sentence_vector(),它返回一个向量,该向量是由构成给定 UAS 的单个元素的嵌入的平均值):

test_data <- readLines("./data/test_data_unsup.txt")

emb_unsup <- test_data %>% 
  lapply(., function(x) {
    m_unsup$get_sentence_vector(text = x) %>%
      t(.) %>% as.data.frame(.)
  }) %>% 
  bind_rows(.) %>% 
  setNames(., paste0("f", 1:32)) # Printing out the first 5 values
# of the vectors (of size 32)
# that represent the first 3 UAS
# from the test set:emb_unsup[1:3, 1:5]
##      f1       f2    f3    f4      f5
## 1 0.197 -0.03726 0.147 0.153  0.0423
## 2 0.182  0.00307 0.147 0.101  0.0326
## 3 0.101 -0.28220 0.189 0.202 -0.1623

但是,我们如何知道经过训练的无监督模型有没有用呢?当然,测试它的一种方法是将通过该模型获得的 UAS 的矢量表示插入到下游的机器学习任务中,并评估最终解决方案的质量。然而,在跳到下游建模任务之前,人们还可以直观地评估 fastText 嵌入有多好。众所周知的 tSNE 地块(Maaten&hint on 2008;参见这个 YouTube 视频可能特别有用。

图 4。通过无监督快速文本模型获得的嵌入的 3D tSNE 可视化。该图中的每个点对应于测试集中的一个 UAS。根据用户代理的硬件类型对点进行颜色编码。

图 4 显示了使用上面指定的 fastText 模型从测试集中为 UAS 计算的嵌入的 3D tSNE 图。尽管该模型是以无监督的方式训练的,但它能够产生反映原始用户代理字符串的重要属性的嵌入。例如,人们可以看到关于硬件类型的点的良好分离。

根据定义,训练受监督的快速文本模型需要标记的数据。这就是现有的 UAS 解析器通常可以提供很大帮助的地方,因为人们可以使用它们来快速标记数以千计的训练样本。fastText 算法支持多类和多标签分类器。标签的预期(默认)格式是__label__<value>。以这种方式格式化的标签(在多标签模型的情况下,可能由空格分隔)将被预先添加到训练数据集中的每个文档。

假设我们对强调 UAS 硬件类型差异的嵌入感兴趣。图 5 示出了适于训练相应模型的标记数据的例子。

图 5。适用于训练监督快速文本模型的标记数据示例。

在这种标记数据上训练监督快速文本模型所需的 R 命令类似于我们之前看到的:

m_sup <- ft$train_supervised(
    input = "./data/train_data_sup.txt",
    lr = 0.05, 
    dim = 32L, *# vector dimension*
    ws = 3L, 
    minCount = 1L,
    minCountLabel = 10L, *# min label occurence*
    minn = 2L, 
    maxn = 6L, 
    neg = 3L, 
    wordNgrams = 2L, 
    loss = "softmax", *# loss function*
    epoch = 100L, 
    thread = 10L
)

我们可以通过在标记的测试集上计算精度、召回率和 f1 分数来评估所得到的监督模型。这些指标可以跨所有标签计算,也可以针对单个标签计算。例如,以下是与标签“移动”相对应的 UAS 的质量指标:

metrics <- m_sup$test_label("./data/test_data_sup.txt")
metrics["__label__mobile"]## $`__label__mobile`
## $`__label__mobile`$precision
## [1] 0.998351
##
## $`__label__mobile`$recall
## [1] 0.9981159
##
## $`__label__mobile`$f1score
## [1] 0.9982334

对这个监督模型的 tSNE 图的视觉检查也证实了它的高质量:我们可以看到关于硬件类型的测试用例的清晰分离(图 6)。这并不奇怪,因为通过训练监督模型,我们提供了支持信息,帮助算法创建特定于任务的嵌入。

图 6。使用监督模式下训练的 fastText 模型获得的嵌入的 3D tSNE 可视化,标签对应于硬件类型。

结论

本文证明了 UAS 中包含的丰富信息可以使用低维嵌入来有效地表示。生成这种嵌入的模型可以在无监督和有监督模式下训练。无监督嵌入是通用的,因此可以用于任何下游机器学习任务。然而,只要有可能,我会建议训练一个特定任务的监督模型。将 UAS 表示为固定大小的向量的一个特别有用的算法是 fastText。它的实现可以在当今数据科学家使用的所有主要语言中获得。

在你走之前

寻找类似的数据分析或建模?我提供数据科学咨询服务,所以联系

随机、批量和小批量梯度下降

原文:https://towardsdatascience.com/stochastic-batch-and-mini-batch-gradient-descent-demystified-8b28978f7f5?source=collection_archive---------14-----------------------

为什么我们在实现深度神经网络时需要随机、批量和迷你批量梯度下降?

资料来源:www.unsplash.com

这是一个详细的指南,它应该回答我们在实现深度神经网络时为什么以及何时需要随机、批量和小批量梯度下降的问题。

简而言之 : 我们需要这些不同的实现梯度下降的方法来解决我们在训练神经网络时肯定会遇到的几个问题,这些问题是损失函数和噪声梯度的局部最小值和鞍点。

关于这一点的更多内容将在下面的文章中解释——nice;)

目录

  1. 1.简介:让我们回顾一下梯度下降
  2. 2.训练神经网络时的常见问题(局部最小值、鞍点、噪声梯度)
  3. 3.分批梯度下降
  4. 4.随机梯度下降
  5. 5.小批量梯度下降
  6. 6.带回家的信息

1.简介:让我们回顾一下梯度下降

在我们讨论实现梯度下降的不同方法之前,我认为最好先回忆一下梯度下降到底是什么。

当我们训练神经网络时,我们希望它学习执行特定的任务。这项任务可以简单到预测某一特定市场对某一产品的预期需求,或者对皮肤癌进行分类。

不管这个任务,我们在训练期间的唯一目标是最小化目标/损失函数。对于预期需求的预测,这是一项回归任务,该损失函数将是均方误差(MSE)损失函数:

等式 1 均方误差损失函数

对于分类任务,我们希望最小化交叉熵损失函数:

等式 2 交叉熵损失函数

然而,在我们能够最小化损失函数之前,神经网络必须计算输出。这是在前向传播步骤中完成的,此时网络接收输入特征向量,在隐藏层中执行若干点积和非线性运算,并输出预测。(关于正向传播步骤 的更详细解释,请参考本文 )。该步骤如下图所示:

图一。深度神经网络。图片来源:自己的作品

计算隐藏值以及最终预测向量 y 的方程式如下:

情商。3 正向传播

预测 y 和基本事实标签(我们实际想要预测的值)都包含在损失函数中,以计算指示网络预测准确度的定量度量。

损失函数的较低值导致预测和标签之间的较低误差,反之亦然。

为了获得损失函数的最低可能值,我们必须调整神经网络的参数,即权重和偏差。

这就是梯度下降发挥作用的地方。

我们必须计算损失函数相对于这些权重和偏差的负导数(梯度)。在下一步中,这些参数朝着该梯度的方向更新。以下等式表示任意权重矩阵的更新步骤。

情商。4 更新步骤

每次执行更新时,权重和偏差越来越接近损失函数将具有全局最小值的最优值集。这种预测将尽可能接近我们想要预测的真实标签。

梯度下降是神经网络训练和整个深度学习领域的支柱。这种方法使我们能够教会神经网络执行任意任务,而无需为其显式编程。

只要神经网络能够最小化损失函数,网络最终将能够做我们想要它做的事情。

梯度下降训练时会遇到问题

当然,和往常一样,说起来容易做起来难。当沿着损失函数的负梯度下降到最佳权重时,我们肯定会面临多个问题,例如局部最小值鞍点、噪声梯度,这些问题会使我们的训练过程更加困难。

常规梯度下降的不同方法,即随机梯度下降、批量梯度下降和小批量梯度下降,可以正确处理这些问题,尽管不是每种方法都能解决所有问题。由您决定哪种方法最适合您当前的问题。

正因为如此,我们将在下面更详细地讨论实现梯度下降算法的不同方法以及它们独特的优点和缺点。

但是首先我想简要地解决局部最小值、鞍点和噪声梯度的问题,让你们更好地理解为什么我们首先需要这些不同种类的梯度下降。

2.训练神经网络时的常见问题

局部最小值和鞍点

不幸的是,损失函数并不总是有好的形状。事实上,它们可以呈现非常复杂的形状,例如:

图 2 三维损失函数。资料来源:www.mathworks.com

因此,损失函数通常具有局部最小值和鞍点。

这些 2D 图形示意性地显示了局部最小值和鞍点在二维空间中的样子:

图三。局部最小值和鞍点。来源:自己的作品。

x 轴是任意权重值,而 y 轴是损失函数值。假设我们在神经网络的训练期间获得权重,该权重产生鞍点或局部最小值所在的损失函数值。

在这种情况下,你可以清楚地看到,斜率,或者说损失函数的梯度,变得无限小,因为损失函数在这一点上是平坦的。这种情况的直接后果是梯度陷入局部最小值或鞍点,并且由于权重保持不变,学习无法进一步进行。

在实践中,鞍点是一个比局部最小值大得多的问题,尤其是在处理成千上万个权重参数时。

为什么会这样?

损失函数所在的对应维度空间具有与权重参数数量相同的维度数量。鞍点意味着在高维空间中的当前点,损耗在一个方向下降,而在另一个方向上升。如果你在十万维空间,你可以想象这种情况会经常发生。

相反,一个局部最小值意味着损失函数在我当前点的所有方向上增加。

可以想象,这在高维空间是不太可能的。不管你是否有一个鞍点或局部最小值,梯度下降的常规实施将在训练中遇到困难。

即将推出 : 面向软件开发人员、数据分析师、学者和行业专家的高级深度学习教育,旨在加速向人工智能职业的过渡。

更多详情请看:www.deeplearning-academy.com

www.deeplearning-academy.com

嘈杂的梯度

训练神经网络时的另一个问题和限制因素是,我们计算的梯度可能变得非常嘈杂。当进行梯度下降时,我们(通常)计算训练集中每个单个特征标签实例对的损失,并通过推导关于权重参数的损失函数来获得梯度。

这样做的结果是,单个数据样本上的每个计算梯度只是指向损失函数的最高增长率的真实梯度的粗略估计。

这导致数据集中每个要素-标注实例对的计算梯度的方向和值略有不同。我们说这些梯度是有噪声的或者具有很高的方差。

结果,在训练期间,我们不直接走向损失函数的全局最小值,而是梯度做一些之字形运动。梯度的噪声会导致网络的训练时间更长。

为了更好地理解这一点,让我们来看一个嘈杂的梯度视觉例子。下面的视频展示了带噪声梯度的梯度下降过程。

噪声梯度向损失函数的局部最小值移动。来源:自己的作品。

梯度朝着位于三维空间中的损失函数的全局最小值移动。您可以注意到,在训练集中的每个单个数据实例上计算的负梯度并不直接指向损失函数的全局最小值。

相反,梯度在方向和值上略有不同。正因为如此,我们正在做这些曲折的运动,而不是直接走向全球最小值。

在下一节中,我们将看看如何使用梯度下降来更新神经网络的权重的不同变化。虽然我们仍然要使用我们以前学过的梯度下降法,但是有几种方法可以使用计算出的梯度来更新网络权重。

在下文中,我将向您介绍三种技术,即、**、小批量梯度下降*** 。每种权重更新技术都有其优点和缺点。*

根据问题的不同,您可能更喜欢一种方法。先说批量梯度下降。

3.批量梯度下降

请考虑一个数据集,其中我们有 N=6 个标记的数据实例。每个实例都有 4 个特征(学历武学*** )和一个标签 y 。***

在训练过程中,神经网络为每个实例计算一个预测,该预测与地面真实标签进行比较。给定预测和标签,我们可以将两者都放入损失函数,并计算给定样本的损失函数的梯度。

到目前为止,一切顺利。在这一点上,我们可以使用计算出的梯度来更新我们的网络权重,使之接近最优权重,从而最小化损失函数。

然而,在批量梯度下降过程中,我们不会马上进行。

相反,在处理完数据集的所有数据实例后,权重只更新一次。具体来说,在批量梯度下降期间,计算并求和数据集中每个实例的梯度。

最后,累积的梯度除以数据实例的数量,即 6。这样,我们得到了数据集中所有数据实例的平均梯度。权重现在在该平均梯度的负方向上更新。****

对于我们的数据集,我们必须计算并求和该数据集中六个样本的梯度。然后,我们将梯度的总和除以 6,并用这个平均梯度执行单梯度下降,以更新神经网络的权重。

情商。5 用批量梯度下降更新步骤。

在这个等式中, θ 代表任意的权重值。

批量梯度下降的优势

  • ****计算效率高:正如你可能已经猜到的,这种技术的计算要求较低,因为每次采样后都不需要更新。
  • ****稳定收敛:另一个优点是权重收敛到最优权重是非常稳定的。通过计算和平均数据集中每个样本的所有单独梯度,我们得到了真实梯度的非常好的估计,指示损失函数的最高增加。

Barch 梯度下降的缺点

  • ****较慢的学习:批量梯度下降的缺点是学习过程要慢得多,因为我们在处理完 N 个样本后只执行一次更新。
  • ****局部极小值和鞍点:另一个缺点是,在学习过程中,我们可能会陷入损失函数的局部极小值,永远不会达到神经网络获得最佳结果的全局最优值。这是因为我们计算的梯度或多或少是一样的。我们实际上需要的是一些噪声梯度。方向值的这种小偏差将允许梯度跳出损失函数的局部最小值,并继续向全局最小值更新。另一方面,干净的梯度更容易陷入局部最小值。

4.随机梯度下降

与批量梯度下降相反,我们可以执行随机梯度下降。这种方法可以被认为是批次梯度的对立面。

请考虑我之前介绍的数据集。对于每个实例,在数据中,我们再次进行预测,将预测与标签进行比较,并计算损失函数的梯度。

然而,在这种情况下,我们在每个数据实例已经被神经网络处理之后更新权重。这种方法也经常被称为在线学习。****

对于我们的小数据集,我们计算每个数据实例的梯度,并更新神经网络的权重六次:

****

情商。5 用随机梯度下降更新步长。

换句话说:这个等式执行六次——每个数据实例一次。

随机梯度下降的优势

  • ****即时性能洞察:随机梯度下降让我们立即洞察神经网络的性能,因为在这种情况下,我们不必等到数据集结束。
  • ****更快的学习:相应地,随机梯度下降可以导致更快的学习,因为在处理每个数据实例之后执行更新。

随机梯度下降的缺点

  • ****噪声梯度:与我们平均梯度以获得最终梯度的批量梯度下降相反,在随机梯度下降中,我们使用每个单独的梯度来更新权重。这些梯度可能非常嘈杂,并且在方向和值方面有很大的差异。这意味着我们对每个样本计算的梯度仅仅是指向损失函数增加的真实梯度的粗略估计。换句话说,在这种情况下,我们有很多噪声。然而,这一事实可以避免训练期间的局部最小值,因为高方差会导致梯度跳出局部最小值。
  • ****计算密集:随机梯度下降比批量梯度下降计算密集得多,因为在这种情况下,我们更频繁地执行权重更新。
  • ****无法确定全局最小值:另一个缺点可能是梯度下降法无法确定损失函数的全局最小值。由于这种噪音,要找到并保持一个全局最小值会更加困难。

5.小批量梯度下降

第三种也是最后一种重量更新技术称为小批量梯度下降。想象一下,这种方法结合了其他两种方法的优点。对于小批量梯度下降,我们必须将我们的训练集分成大小为 n 的批量

例如,如果我们的数据集包含 10,000 个样本,那么合适的大小 n 应该是 8,16,32,64,128。

类似于批量梯度下降,我们计算并平均小批量数据实例中的梯度。梯度下降步骤在每个小批量样品处理后进行。

请再次考虑我们的小数据集。在小批量梯度下降的情况下,我们可以将这六个数据实例分成大小为 n=2t 的批量,总共留给我们三个小批量:

我们为每个小批量中的两个数据实例计算两个梯度,将它们相加,然后除以 2,得到该小批量的梯度平均值:

情商。7 用小批量梯度下降更新步骤。

我们将使用这个平均梯度来执行梯度下降步骤。在这种情况下,我们将做梯度步骤总共三次。

小批量方法是实现深度学习中梯度下降算法的默认方法

小批量梯度下降的优势

  • ****计算效率:就计算效率而言,该技术介于之前介绍的两种技术之间。
  • ****稳定收敛:另一个优点是更稳定地收敛到全局最小值,因为我们计算 n 个样本的平均梯度,这导致更少的噪声。
  • ****更快的学习:由于我们比随机梯度下降更频繁地执行权重更新,在这种情况下,我们实现了更快的学习过程。

小批量梯度下降的缺点

  • ****新的超参数:该技术的一个缺点是,在小批量梯度下降中,引入了一个新的超参数 n ,称为小批量。已经表明,学习率之后的小批量大小是 神经网络整体性能的第二个最重要的超参数 。出于这个原因,有必要花时间尝试许多不同的批量大小,直到找到一个最终的批量大小,它与其他参数(如学习速率)一起工作得最好。

带回家的信息

  • 在训练神经网络时,局部最小值、鞍点和噪声梯度是常见的问题
  • 批量梯度下降可以防止梯度的噪声,但我们会陷入局部最小值和鞍点
  • 对于随机梯度下降,我们很难确定全局最小值,但通常情况下,不要陷入局部最小值
  • 小批量方法是实现深度学习中梯度下降算法的默认方法。它结合了其他方法的所有优点,而没有它们的缺点

原载于 https://www.deeplearning-academy.com。****

机器学习的随机梯度下降解释清楚

原文:https://towardsdatascience.com/stochastic-gradient-descent-for-machine-learning-clearly-explained-cadcc17d3d11?source=collection_archive---------49-----------------------

随机梯度下降是当今大规模机器学习问题的标准优化方法。它用于从逻辑回归到人工神经网络的各种模型的训练。在本文中,我们将用线性回归来说明梯度下降和随机梯度下降的基本原理。

形式化我们的机器学习问题

正如你可能知道的,监督机器学习在于找到一个函数,称为决策函数,它最好地模拟数据的输入/输出对之间的关系。为了找到这个函数,我们必须将这个学习问题公式化为一个最优化问题。

让我们考虑以下任务:找到将输入空间、变量 X 映射到输出空间、变量 Y 的最佳线性函数。

Y 变量对 X 变量的绘图(图片作者: GitHub 链接)

当我们试图通过线性函数来模拟 XY 之间的关系时,允许学习算法选择的函数集合如下:

术语 b 就是截距,在机器学习中也叫偏差
这组函数就是我们的假设空间。但是我们如何选择参数 a,b 的值,以及我们如何判断这是否是一个好的猜测?

我们定义了一个叫做损失函数的函数,它在结果 Y. 的上下文中评估我们的选择

我们将损失定义为平方损失(我们可以选择另一个损失函数,如绝对损失) :

平方损失惩罚实际 y 结果和通过选择参数组 a、b 的值估计的结果之间的差异。这个损失函数在单个点上评估我们的选择,但是我们需要在所有的训练点上评估我们的决策函数。

因此,我们计算误差平方的平均值:均方误差

其中 n 是数据点的数量。
该函数取决于定义我们假设空间的参数,称为经验风险

Rn(a,b) 是参数的二次函数,因此其最小值总是存在,但可能不是唯一的。

(图片作者: GitHub 链接)

最终,我们达到了最初的目标:将学习问题公式化为优化问题!

事实上,我们所要做的就是找到决策函数,即 a,b 系数,使这种经验风险最小化。

这将是我们可能产生的最好的决策函数:我们的目标函数

在简单线性回归的情况下,我们可以简单地对经验风险进行微分,并计算 a,b 系数来抵消衍生产品。用矩阵符号来计算这个解更容易。方便的是将常量变量 1 包含在 X 中,并将参数 ab 写成单个向量 β。因此,我们的线性模型可以写成:

我们的损失函数变成了:

最小化我们的等式的向量β可以通过求解下面的等式来找到:

我们的线性回归只有两个预测器( ab ,这样 X 就是一个nX2矩阵(其中 n 是观测值的个数,2 是预测值的个数)。如你所见,要解这个方程,我们需要计算矩阵**(x^tx)然后求逆。

在机器学习中,观察值的数量通常非常多,预测值的数量也非常多。因此,该操作在计算和存储方面非常昂贵。

梯度下降算法是一种迭代优化算法,它允许我们在保持低计算复杂度的同时找到解决方案。我们将在本文的下一部分描述它是如何工作的。

潜入梯度下降原理

梯度下降算法可以用下面的类比来说明。想象一下,你半夜在山里迷路了。你什么也看不见,因为一片漆黑,你想回到位于谷底的村庄(你试图找到均方误差函数的局部/全局最小值)。为了生存,你制定了以下策略:

  1. 在你当前的位置,你感觉到了山的陡度,找到了坡度最陡的方向。最陡的斜率对应于均方误差的梯度。
  2. 你沿着这个方向下山,走一段固定的距离,然后停下来检查你是否还在正确的方向上。这个固定距离就是梯度下降算法的学习速率。如果你走得太久,你可能会错过这个村庄,最终会在山谷另一边的斜坡上。如果你走得不够,到达村庄将需要很长时间,并且有陷入小洞的风险(当地的最小值)。
  3. 你重复这些步骤,直到满足你设定的标准:例如,两个步骤之间的高度差非常低。

最终,你会到达谷底,或者你会陷入局部最小值…

既然你已经用这个寓言理解了原理,那就让我们深入到梯度下降算法的数学中去吧!
为了找到使均方误差最小的 ab 参数,该算法可以实现如下:

  1. 初始化 ab 的值,例如 a =200,b=-200
  2. 计算相对于 ab 的均方误差的梯度。坡度是当前位置最陡坡度的方向。

然后通过减去梯度乘以步长来更新 ab 的值:

η ,我们的固定步长。

ab 的更新值计算均方损失。

重复这些步骤,直到满足停止标准。例如,均方损失的减少低于阈值 ϵ.

梯度下降算法图解(图片作者: GitHub Link )

在下面的动画中,您可以看到由梯度下降算法执行的参数 a 的更新,以及我们的线性回归模型的拟合:

梯度下降算法的动画(图片作者: GitHub 链接)

由于我们正在拟合具有两个预测值的模型,我们可以在 3D 空间中可视化梯度下降算法过程!

渐变下降 3D 动画(图片作者: GitHub 链接)

梯度下降:这会扩展到大数据吗?

在梯度下降算法的每次迭代中,我们必须查看所有的训练点来计算梯度。

因此,该算法的时间复杂度为 O(n)。计算一个非常大的数据集需要很长时间。也许我们可以计算梯度的估计值,而不是查看所有的数据点:这种算法被称为迷你批次梯度下降

小批量梯度下降包括使用大小为 N 的随机子集来确定每次迭代的步进方向。

  • 对于一个大的数据子集,我们得到一个更好的梯度估计,但算法较慢。
  • 对于一个小的数据子集,我们得到一个更差的梯度估计,但算法计算解决方案更快。

如果我们使用一个大小为 N=1 的随机子集,称之为随机梯度下降。这意味着我们将使用一个随机选择的点来确定步进方向。

在下面的动画中,蓝线对应随机梯度下降,红线是基本梯度下降算法。

随机梯度下降 3D 动画(图片作者: GitHub 链接)

我希望这篇文章能帮助你理解这个基本的优化算法,如果你喜欢它,或者如果你有任何问题,请不要犹豫发表评论!

你可以在我的 GitHub 上找到我做的实现随机梯度下降和创建动画的代码:https://GitHub . com/baptiste-monpezat/random _ gradient _ descent

你也可以在我的博客上找到原帖:https://baptiste-monpezat . github . io/blog/random-gradient-descent-for-machine-learning-clearly-explained

随机梯度下降&动量解释

原文:https://towardsdatascience.com/stochastic-gradient-descent-momentum-explanation-8548a1cd264e?source=collection_archive---------19-----------------------

实施随机梯度下降

先说随机梯度下降法(SGD),这可能是我们听过最多的第二著名的梯度下降法。正如我们所知,传统的梯度下降法通过将每个参数推向其梯度的相反方向来最小化目标函数(如果您对普通梯度下降法有困惑,可以查看此处的以获得更好的解释)。

尽管批量梯度下降保证了凸函数的全局最优,但是考虑到您正在训练具有数百万样本的数据集,计算成本可能会非常高。随机梯度下降通过给数据集增加一些随机性来拯救。在每次迭代中,SGD 随机洗牌并更新每个随机样本上的参数,而不是完全批量更新。

SGD 实施

让我们来看一个具体例子的实现。我们的优化任务被定义为:

这里,我们试图用两个参数a, b最小化y — f(x)的损失,上面计算了它们的梯度。

样本生成将是:

我们生成了 100 个xy的样本,我们将使用它们来找到参数的实际值。

SGD 的实现很简单:

只有一行加法np.random.shuffle(ind),它在每次迭代中打乱数据。我们还设置a_list, b_list来跟踪每个参数的更新轨迹,优化曲线将是:

签名于

SGD 降低了计算成本,并可能避免停留在局部最小值,因为它可以通过每次随机选择新样本跳到另一个区域。但这样做的缺点是,如果不适当降低学习速率,它会持续超调。所以在实际用例中,SGD 总是和一个衰减的学习率函数耦合在一起(更多解释此处)。

为了使更新跟踪更加平滑,我们可以将 SGD 与小批量更新结合起来。

小批量 SGD

这里所说的小批量是基于一小批渐变而不是每一项来更新参数。这有助于减少差异,并使更新过程更加顺畅:

每次我们再次混洗数据,但是这次按照以下公式对每批的梯度进行平均更新:

通过将批量大小设置为 50,我们得到了更平滑的更新,如下所示:

小批量 SGD

动力

最后,还有一个概念,动量,与 SGD 相结合。它通过引入一个额外的术语γ来帮助加速收敛:

在上面的等式中,θ的更新受上次更新的影响,这有助于在相关方向上加速 SGD。

实现是不言自明的。通过设置学习率为 0.2,γ为 0.9,我们得到:

动量-新加坡元

结论

最后,这绝对不是探索的终点。动量可以与小批量相结合。而且你还测试了更灵活的学习率函数,它随着迭代而变化,甚至在不同的维度上变化的学习率(完全实现这里)。

到目前为止,我们在所有维度上使用统一的学习率,但是对于不同维度上的参数以不同频率出现的情况,这将是困难的。接下来,我将介绍自适应梯度下降,它有助于克服这个问题。

参考:

  1. https://ml-cheat sheet . readthedocs . io/en/latest/gradient _ descent . html
  2. http://d2l.ai/chapter_optimization/sgd.html
  3. https://ruder . io/optimization-gradient-descent-descent/index . html # gradient descent optimizationalgorithms
  4. http://d2l.ai/chapter_optimization/momentum.html

随机模拟帮助你掌握统计学的概念

原文:https://towardsdatascience.com/stochastic-simulation-helps-you-grasp-concepts-of-statistics-befdba517404?source=collection_archive---------27-----------------------

统计学的概念可能很难理解。不要绝望。简单的基于 Python 的模拟可以帮助提炼概念。

图片来源: Pixabay (免费用于商业用途)

模拟有助于提炼概念

掌握与统计相关的概念可能很难

你是否觉得掌握统计分析的概念——大数定律期望值置信区间p 值——有些困难和麻烦?

你并不孤单。

我们人类的大脑和精神还没有进化到能够处理严格的统计方法。事实上,一项关于人们为什么努力解决统计问题的研究揭示了人们对复杂而非简单、更直观的解决方案的偏好——这常常导致问题完全无法解决。

你可能从诺奖得主丹尼尔·卡内曼的名著《思考,快与慢》中知道,我们的直觉并不存在于我们的理性所在的同一个系统中(见下面的视频)。

图片来源:作者用 Pixabay 制作的拼贴画

我们擅长处理少量的数字。人脑的短期工作记忆大约在7–8 项/数左右。

因此,每当一个过程以数千或数百万的规模出现时,我们 往往会对那个过程的‘固有性质’失去把握。那些只表现在大数极限的规律和模式,在我们看来是随机的,毫无意义的。

统计学处理的是大数,统计建模和分析中几乎所有的理论和结果都只在大数极限下有效。

** [## 巨大的数字会产生一个心理黑洞

一万亿。一个古戈尔。一个亿。树(3)。在零和无限之间的某个地方有许多有限的东西,但是…

www.livescience.com](https://www.livescience.com/26870-ginormous-numbers-boggle-the-mind.html)

数据科学/机器学习植根于统计学——怎么办?

在这个数据科学和机器学习的时代,核心统计概念的知识被认为是在这些领域取得成功的关键,这可能会让数据科学从业者和正在学习该行业的人感到担忧。

但是不要绝望。有一个非常简单的方法可以解决这个问题。而且它叫‘模拟’。特别是离散的、随机的、基于事件的模拟。

因此,每当一个过程以数千或数百万的规模出现时,我们往往会失去对那个过程的“内在本质”的把握

让我给你看一个最简单的例子

图片来源: Pixabay

掷骰子的期望值

假设我们掷出一个(公平的)骰子,有 6 个可能的面——1 到 6。骰子面从集合{1,2,3,4,5,6}中取值的事件由随机变量表示。在正式的设定中,任意随机变量的所谓‘期望值’(用 E[ X ] 表示)由下式给出:

其中 f(x)概率分布函数 (PDF)或概率质量函数 (PMF),即描述可能取值分布的数学函数。**

对于掷骰子的情况,随机变量 X 是离散的,即它只能假定离散值,因此它有一个 PMF(而不是一个 PDF)。这是一个非常简单的 PMF,

这是因为随机变量在样本空间{1,2,3,4,5,6}上具有“均匀概率分布”,即任何骰子投掷都可以产生这些值中的任何一个,完全随机,并且不会偏向任何特定值。因此,期望值为,

因此,根据理论,3.5 是掷骰子过程的期望值。

****是最可能的值吗?不会。因为一个骰子连 3.5 的面都没有!那么,这个量是什么意思呢?

****是某种概率吗?否。因为该值明显大于 1,并且概率值始终介于 0 和 1 之间。

****这是否意味着我们可以预期这张脸最多出现 3 次或 4 次(3.5 次是 3 次和 4 次的平均值)?不。因为 PMF 告诉我们,所有的面孔出现的可能性都是一样的。

幸运的是,统计学的一个基本原则提供了答案,即大数定律,该定律认为,从长远来看,期望值就是随机变量将取的所有值的平均值

注意短语“从长远来看”。我们如何证实这一点?我们能模拟这样的场景吗?

我们当然可以。简单的 Python 代码可以帮助我们模拟场景,验证大数定律

拯救巨蟒

定义一个有骰子面的数组和一个模拟单掷的函数。

扔几次骰子,

您可能已经注意到,对于每次调用dice_throw(),我都使用np.random.choice()函数从数组dice中随机选取一个项目。如果您运行这段代码,您将在您的机器上得到一个完全不同的序列。

我们留下了统计数据,我们在一个模拟区

图片来源: Pixabay (免费用于商业用途)

停下来,意识到正在发生什么。

我们不再处理形式概率和定义。我们正在模拟一个随机事件——掷骰子——就像在现实生活中一样。这就是模拟的诱惑。它在你的计算硬件上构建了一个真实生活的复制品:-)

我们可以把所有的编码留在身后,就这么做——掷骰子,记下面部,冲洗并重复——真的。但要验证遵循这条路线的大数定律,将需要大量的时间。

这就是为什么我们有了计算机和 Python 编程语言,不是吗?

所以,我们只是模拟它足够长的时间,保持一个运行平均值,并绘制它。这是我得到的。

我们不再处理形式概率和定义。我们正在模拟一个随机事件——掷骰子——就像在现实生活中一样。

最初,移动平均线相当疯狂,四处移动。随着模拟次数的增加,平均值收敛到 3.5,正如理论所预期的那样。

这样,我们再回来统计,借助模拟。大数定律可以通过重复刺激随机事件来验证——只需很少的编程。**

用模拟处理置信区间

一些基本定义

人口 :我们要测量某个属性的全部集合。我们(几乎)永远无法获得足够的总体数据。因此,我们永远无法知道人口属性的真实值。

样本 :我们可以收集的总体数据的一部分(子集),它有助于我们估计总体的特性。因为我们不能测量总体属性的真实值,所以我们只能估计它们。这是统计学家的中心工作。

统计量 :统计量是样本的函数。这是一个随机变量,因为每次你取一个新的样本(来自同一人群)你将得到一个新的统计值。例如样本均值或样本方差。这些是对人口的良好(无偏)估计。

置信区间 :统计量的一个范围/界限(由我们选择)。我们需要这个最小/最大界限来量化我们抽样的随机性质的不确定性。让我们以平均值的置信区间为例进一步阐明这一点。

根据我们抽取样本的地点和方式,我们可能会得到很好的总体代表性,也可能得不到。所以,如果我们 多次重复抽取样本的过程 ,在某些情况下样本会包含总体的真实均值,而在另一些情况下,它会漏掉它。

我们能说一下我们成功抽取包含真实均值的样本的比例吗?

这个问题的答案在置信区间里。如果满足一些假设,那么我们就可以计算出包含某个分数的真实均值(当我们大量采样时)的置信区间。

下面给出了必要的公式。我们不会讨论这个公式的细节,也不会讨论为什么在这个公式中使用特殊的 t 分布。读者可以参考任何本科水平的统计文本或优秀的在线资源来理解基本原理。

** [## z 和 t 分布的置信区间

1)理解置信区间的概念,并能够为均值构建一个置信区间 2)理解何时(为了什么…

pages.wustl.edu](https://pages.wustl.edu/montgomery/articles/2757#:~:text=The t-distribution incorporates the,less than the sample size.)

置信区间图解:图片来源(公立大学课程资料)

我们能说一下在抽取包含真实均值的样本时成功的比例吗?这个问题的答案在置信区间里。

实际效用如何?

请注意定义和过程,以了解置信区间的真正实际用途。

当你计算均值的 95%置信区间时,你不是在计算任何概率(0.95 或其他)。您正在计算两个特定的数字(样本均值的最小和最大界限),如果我们重复这个过程,它将创建一个包含真实总体均值(未知)的值范围。

这就是实用之处。我们不会重复这个过程。我们只是抽取一次样本,构建这个范围。

如果我们可以重复这个过程一百万次,我们将能够验证声称在 95%的情况下,真实平均值位于这个范围内。

但是在现实生活中,采样一百万次是非常昂贵的,而且是完全不可能的。因此,置信区间的理论计算为我们提供了最小/最大范围,仅来自样本的一次抽取。这太神奇了,不是吗?

但是在模拟中,我们可以实验一百万次!

是的,模拟是神奇的。我们可以重复抽样过程一百万次,并验证我们的理论置信区间真正包含总体均值(大约 95%的时间)的说法。

让我们用一个工厂生产的真实例子来验证一下。假设在一个工厂中,某台机器平均生产 20 吨产品,标准差为 5 吨。这些是真实的总体均值和标准差。因此,我们可以编写简单的 Python 代码来生成一年(52 周)的典型生产运行,并绘制它。

然后,我们可以编写以下函数对过程进行任意次模拟,以计算置信区间真正包含总体均值的次数。记住,我们知道这种情况下的总体均值——是 20。

如果我们运行这个函数 10,000 次,每次都计算 C.I .是否包含真实平均值,然后检查频率/比率,我们得到以下结果。

这些比率惊人地接近理论计算值 0.9 (90%)和 0.99 (99%),不是吗?

我们可以重复抽样过程一百万次,并验证我们的理论置信区间确实包含总体均值的说法。

模拟是大规模数据科学的有力工具

在上面的例子中,我们讨论了均值的置信区间。但我们可以围绕任何其他统计数据构建 C.I .比如方差或 T2 分位数。我们甚至可以构建两个实验之间的平均差异的的置信区间。在每种情况下,确切的公式和计算可能略有不同,但想法是相同的。

随着流程复杂性的增加,我们处理的不是一个而是多个相互关联的流程,在实践中计算简单的汇总统计数据可能并不总是可行的。对于大型数据科学和分析任务,我们必须掌握随机模拟的艺术来处理这种情况。

仿真综述与思考

在本文中,我们展示了模拟理解统计估计概念的能力,如期望值置信区间。事实上,我们没有机会重复统计实验数千次,但我们可以在计算机上模拟这个过程,这有助于我们以清晰直观的方式提取这些概念。

一旦你掌握了模拟随机事件的艺术,你就可以用一种新的分析武器来研究随机变量的性质和它们背后深奥的统计理论。

例如,你可以用随机模拟来研究,

  • 许多随机事件的均值收敛于正态分布(用数值实验验证中心极限定理)
  • 看看当你以这种或那种方式将许多统计分布混合或转换在一起时会发生什么?你会得到什么样的分布呢?
  • 如果一个随机事件不遵循理论假设,结果会是什么样的异常行为?在这种情况下,模拟可能是你唯一的朋友,因为如果假设不成立,标准理论就会失效。
  • 深度学习网络的运行会出现什么样的统计特性?

对于学习数据科学和机器学习的基本原理来说,这些练习的重要性怎么强调都不为过。

**

如果你喜欢这篇文章,你可能也会喜欢我关于随机模拟和使用 Python 的统计概念的其他文章。

** [## Python 中的蒙特卡罗集成

一个著名的赌场启发的数据科学,统计和所有科学的把戏。用 Python 怎么做?

towardsdatascience.com](/monte-carlo-integration-in-python-a71a209d277e) [## 用 Python 实现布朗运动

我们展示了如何模拟布朗运动,在广泛的应用中使用的最著名的随机过程,使用…

towardsdatascience.com](/brownian-motion-with-python-9083ebc46ff0) [## 如何从头开始生成随机变量(不使用库)

我们通过一个简单的伪随机生成器算法,并显示如何使用它来生成重要的随机…

towardsdatascience.com](/how-to-generate-random-variables-from-scratch-no-library-used-4b71eb3c8dc7) [## 用简单的 Python 例子揭开假设检验的神秘面纱

假设检验是数据科学的基础。我们使用简单的真实例子来演示这个概念,使用…

towardsdatascience.com](/demystifying-hypothesis-testing-with-simple-python-examples-4997ad3c5294)

喜欢这篇文章吗?成为 中等会员 继续 无限制学习 。如果您使用下面的链接, ,我将收取您的一部分会员费,而不会对您产生额外费用

[## 通过我的推荐链接加入媒体

作为一个媒体会员,你的会员费的一部分会给你阅读的作家,你可以完全接触到每一个故事…

medium.com](https://medium.com/@tirthajyoti/membership)****

使用生成对抗网络的随机天气生成器

原文:https://towardsdatascience.com/stochastic-weather-generator-using-generative-adversarial-networks-a9856b0f83ef?source=collection_archive---------33-----------------------

使用 GANs 对多元分布建模

作者图片

被困在付费墙后面?点击这里使用我的朋友链接阅读这个故事!

G 世代模型已经被用于不同领域的无数应用中——从定量金融到水文气候研究的建模和最小化尾部风险,再到研究极端天气的联合影响。生成模型的强大之处在于它能够封装整个依赖结构和数据集的潜在概率分布。这非常有用,因为使用生成模型,我们不仅可以创建数据集的未来表示,还可以对新的真实数据点进行采样,从而保持原始训练数据集之间的交叉相关性。

生成对抗网络(GANs)是由good fellow et al .(2014)首先提出的一类新的生成模型。从那时起,GANs 在机器学习社区中被广泛采用,以解决无监督的机器学习问题,包括图像/文本生成和翻译。在本文中,让我们探索如何使用 GANs 来模拟离散时间随机过程,并按需创建可信的样本来构建天气数据的合成时间序列。

甘小说简评:

生成性对抗网络的架构示意图(图片由作者提供)

GANs 架构由两个子模式组成,称为 生成器(G)鉴别器(D) ,它们相互竞争,目标是通过训练过程达到纳什均衡。生成器学习将潜在空间(例如,Noise ~ N(0,1) )映射到给定数据样本分布的数据空间,并且鉴别器评估生成器完成的映射。生成器的主要作用是生成模拟训练数据集的合成数据,达到鉴别器不能区分合成数据和真实数据的程度。

发生器的输入是一个随机噪声向量x’(通常是均匀或正态分布)。噪声向量通过生成器映射到一个新的数据空间,得到一个伪样本G(x’),它是一个多维向量。鉴别器是一个二元分类器,它接受合成的G(x’)和训练( x )数据集,并学习将它们分类为假的和真的。当鉴别器不能确定数据是来自真实数据集还是来自发生器时,达到 GAN 模型的最佳状态。

随着时间的推移,GANs 的几种变体被开发出来,以解决手头问题的特定需求,但是所有这些变体都采用分两个阶段进行的对抗性训练:

第一阶段:训练鉴频器,冻结发电机。这是通过将真实和虚假数据的样本传递给模型并评估鉴别器是否能够正确预测它们来实现的。在训练过程的第一阶段,网络将只进行正向传递,不进行误差的反向传播。

第二阶段:在此阶段,我们训练发电机,并冻结鉴别器。这可以通过优化发生器来实现,以创建逼真的样本来欺骗第一阶段中经过训练的鉴频器。

一旦训练完成,GANs 模型将被优化以生成足够真实的合成时间序列,从而模拟真实的时间序列数据。训练后,生成模型可用于按需创建新的可信样本。

什么是随机天气发生器?

作者图片

随机天气生成器是一种统计模型,旨在通过分析某个地区的天气统计特征,生成该地区无限长的天气数据合成时间序列。大多数随机天气生成器使用马尔可夫过程和不同天气变量的频率分布的组合。

在气候建模中,传统上使用连接函数对多元分布进行建模。copula 函数是具有标准一致边缘的多元分布。任何多元分布都可以写成它的边际分布和它的 copula 的组合。例如,在二元情况下,给定两个连续的随机变量【x】【y】,具有边际分布【F】【G】,以及联合分布【Q】,存在一个系词【C】使得

GANs 提供了一个完全不同的框架来模拟多元分布。结合使用生成性和鉴别性模型,以及对抗性训练,我们将能够将噪音转化为现实的天气数据。

数据:

在这项研究中,我们将使用位于加州湾区的五个气象站的月总降水量。为了训练 GAN 模型,我们将使用从 NOAA 的 USHCN 数据库获得的 1893 年至 2012 年的月降水量数据。降水量的单位是百分之一英寸。我们将重点关注 GANs 通过模拟月总降水量来获取五个气象站之间的空间相关性的能力。

****湾区气象站(图片由作者提供)

型号:

对于 GAN 的发生器和鉴别器组件,我们将采用三层顺序模型。潜在向量将包括从正态分布中采样的 20 个值。我们将在隐藏层中使用流行的 ReLU 激活函数,并使用平均绝对百分比误差(MAPE)损失和随机梯度下降的 Adam 版本来训练模型。为了防止模型过拟合,我们将采用剔除正则化技术。本研究中使用的 GANs 架构示意图如下所示

****甘建筑(图片作者提供)

我们的模型输出将有 10,000 个合成数据样本,其中 5 个输出特征对应于利弗莫尔、伯克利、纳帕、佩塔卢马和圣克鲁斯地区的月总降水量。该模型是使用 Python 中的 Keras 库实现的,下面提供了代码片段。

结果:

正如本文介绍部分所提到的,GANs 最大的优势之一是它能够按需生成数据。使用经过训练的 GANs 模型,为五个气象站中的每一个生成了 10,000 个新的合成数据点。下图和下表比较了用于训练模型的实际数据和 GANs 模型生成的合成数据的描述性统计数据。

不同气象站降水数据的箱线图(实际)

不同气象站降水数据的箱线图(合成)

实际(训练)和合成数据的描述性统计和相关性比较

对模型结果的快速回顾表明,GAN 模型能够相对较好地了解每个气象站的数据分布,同时保持站之间的交叉相关性。对于圣克鲁斯站,模型估计值略高于观测值。但一般来说,合成数据的样本最小值、下四分位数(25%)、中值(50%)、上四分位数(75%)和样本最大值与实际数据的相应统计数据匹配良好。通过优化潜在向量的大小、层数、代价函数、训练算法和激活函数,可以进一步提高 GAN 模型的性能。

基于 GANs 的数据增强;

对于大多数现实世界的应用程序来说,数据稀缺是需要解决的最大瓶颈之一。在保险和风险分析领域尤其如此,数据质量进一步加剧了数据稀缺的问题。GANs 提供了一个强大的预训练建模框架,可以人工合成新的标记数据,用于开发更好的模型和风险分析。这项研究只是触及了 GANs 在风险建模中的潜在应用的表面。敬请关注更多内容。

感谢阅读这篇文章!感谢所有反馈。如有任何问题,请随时联系我。

如果你喜欢这篇文章,这里还有一些你可能喜欢的文章:

** [## 使用深度学习的飓风路径预测

每年 6 月 1 日到 11 月 30 日之间的时间窗标志着北大西洋飓风季节。在此期间…

medium.com](https://medium.com/@kap923/hurricane-path-prediction-using-deep-learning-2f9fbb390f18) [## 通过数据科学解读气候变化

用 FB Prophet 预测未来 CO₂水平

towardsdatascience.com](/interpreting-climate-change-through-data-science-321de6161baf) [## 飓风佛罗伦萨——建立一个简单的风暴路径预测模型

飓风佛罗伦萨是 2018 年大西洋飓风季节的第一场主要飓风。从它在海角附近的起源…

towardsdatascience.com](/hurricane-florence-building-a-simple-storm-track-prediction-model-1e1c404eb045)**

股票基本面分析:SEC 季度数据汇总的 EDA

原文:https://towardsdatascience.com/stock-fundamental-analysis-eda-of-secs-quarterly-data-summary-455e62ff4817?source=collection_archive---------34-----------------------

大熊猫 2020 SEC 申报的探索性数据分析

马库斯·斯皮斯克在 Unsplash 上的照片

许多投资者认为基本面分析是他们战胜股市的秘密武器。您可以使用许多方法来执行它,但是它们有一个共同点。他们都需要关于公司财务报表的数据

幸运的是,所有在美国股票市场交易的股票都必须向证券交易委员会提交季度报告。每季度 SEC 都会准备一份舒适的 CSV 文件,帮助所有投资者寻找投资机会。让我们来探讨如何从这些中获得有价值的见解。csv 文件。

在本教程中,我们将使用 python 的 pandas 库来解析 CSV 文件,我们将学习如何:

我们将处理数据并:

  • 浏览秒转储中的文件
  • 查看这些文件的每一栏,并讨论与最相关的
  • 移除按关键列或多列分组的重复的数据
  • 使用交互式 Plotly 图表可视化数据以支持我们的探索
  • 还有更多

和往常一样,你可以按照 GitHub 上分享的笔记本里的代码。

[## vaclavdekanovsky/数据分析示例

github.com](https://github.com/vaclavdekanovsky/data-analysis-in-examples/blob/master/SEC Quarterly Data Dump/EDA_of_SEC_2020Q1_Filling_sub.ipynb)

SEC 季度数据

好像没什么问题。你只需从 SEC 数据集页面下载季度包,按降序排列财务报表中的数值,并挑选顶部的股票。现实并没有那么简单。让我们来看一看 2020 年第一季度所有 SEC 备案的 45.55MB 大 zip 文件。

每个季度的包包含 5 个文件。这里有一个 2020 Q1 的例子:

  • readme.htm—描述文件的结构
  • sub.txt —关于提交文件的主要信息,包括公司标识符和文件类型
  • num.txt —每份财务报表和其他文件的数字数据
  • tag.txt —标准分类标签
  • pre.txt —关于 num.txt 中的数据如何显示在在线演示文稿中的信息

SEC 季度数据转储中的解压缩文件

本文将只讨论 submission master,因为它包含的信息对于一篇文章来说已经足够了。后续报道将更详细地研究这些数据。我们开始吧。

2020Q1 提交文件

2020 年第一季度,这些公司已经提交了13560文件,sub.txt 收集了关于它们的 36 个专栏。

# load the .csv file into pandas
sub = pd.read_csv(os.path.join(folder,"sub.txt"), sep="\t", dtype={"cik":str})# explore number of rows and columns
sub.shape[Out]: (13560, 36)

我总是从一个简单的函数开始,该函数检查数据框的每一列,检查空值的百分比,以及有多少唯一值出现在列中。

浏览 sub.txt 文件,查看每列包含的数据

让我强调一下 SEC submission master 中的几个重要栏目。

pandas 中的快速文件概览示例

  • adsh — EDGAR 登录号唯一标识每份报告。该值在 sub.txt 中从不重复,例如 0001353283–20–000008 是 Splunk 的 10-K(年度备案)代码。
  • cik —中央索引键,识别每个 SEC 注册人的唯一键。例如,Splunk 的 0001353283。如您所见,adsh 的第一部分是 cik。
  • 名称 —提交季度财务数据的公司名称
  • 表格 —提交报告的类型

表格 s—提交给 SEC 的提交类型

根据分析,我们看到 2020 年第一季度提交的报告包含 23 种独特的财务报告。投资者的主要兴趣在于涵盖上市公司年度业绩的 10-K 报告。因为这份报告预计每年只提交一次,所以显示公司财务季度变化的报告也很重要。

  • 10-K美国公司年报
  • 10-Q季度报告和也许
  • 20-F外国公司的年度报告
  • 40-F外国公司的年度报告(加拿大)

让我们看看哪些表单在数据集中最常见。2020Q1 中表格类型的绘制将显示此图片:

使用 Plotly 的低级 API 生成条形和饼形支线剧情

各公司在 2020 年第 1 季度使用 Plotly 中的可视化功能报告了不同的提交类型

该数据集包含超过 7000 份 8-K 报告,通知重要事件,如协议、裁员、材料使用、股东权利修改、高级职位变更等(参见 SEC 的指导方针)。因为它们是最常见的,我们应该花些时间来探索它们。

8k 唱片公司

仅过滤8-K表单,我们看到数据集包含这种类型的7502记录。

[In]:
# let's filter adsh, unique report identifier of the `8-K`s
eight_k_filter = sub[sub["form"]=="8-K"][["name","adsh"]]
eight_k_filter.shape[Out]: (7502, 2)

如果我们将包含详细财务数据的num.txt合并,我们只能得到2894行。有些记录似乎没有细节。

[In]:
# load the num.txt file containing detailed data
num = pd.read_csv(os.path.join(folder,"num.txt"),sep="\t")# merge the file headers with the detailed data 
eight_k_nums = num.merge(eight_k_filter)
eight_k_nums.shape[Out]: (2894, 10)

除此之外,这些记录仅涵盖20份独特的报告(每份报告由adsh号标识)。

[In]: len(eight_k_nums["adsh"].unique())
[Out]: 20

这是因为num.txt只包含财务细节,而大多数8-K用文字描述事件。只有像0001262976–20–000015这样的罕见事件,这种特殊情况会声明额外的财务报表作为8-K报告的一部分。

num.txt 中的每一行正好包含财务报表中的一行

8-K以纯文本描述事件,这不是转储的一部分。只有在包括财务报表的情况下才会出现详细信息,这种情况很少见

8-K 没有财务明细,其他表格有吗?

我们很少在num.txt中看到任何与8-K表单相关的数据。让我们用图表显示所有的表格类型,看看其他归档是否有所不同。我们将把num.txt左连接到sub.txt,并使用indicator参数来查看哪个adsh键出现在两者中。

只有 8-K 和 8-K/A 与财务详细信息无关

当我们连接这两个文件时,我们可以看到只有8-K8-K/A缺少财务细节,这很好,因为现在我们将研究年度10-K和季度10-Q报表

10K 和 10 Q

在 8-K 文件中,只有 20 份包含 SEC 季度数据转储中的额外信息,这并没有带来多少好处。让我们将注意力转移到更有趣的提交类型——年度报告和季度报告,然后我们将简要地看一下其他的形式。

SEC 在 2020 年 4 月初发布了数据集,因此我们很有可能在记录中看到一些日期为 2019-12-31 的年度报告。如果我们只过滤10-K10-Q,我们会发现 2020Q1 转储中的大部分数据都是年度报告。

# filter only 10-K and 10-Q forms
tens = sub[sub["form"].isin(["10-Q","10-K"])]# count how many forms of each type are in the dataset
tens_counts = tens["form"].value_counts().reset_index().rename(columns={"index":"form type", "form": "count"})# using Plotly.Express create a bar chart
fig = px.bar(tens_counts,
            x="form type",
            y="count",
            barmode='group', 
            text="count", 
            title="Number of Annual and Quarterly forms in 2020Q1"
           )
fig.show()

Q1 的 SEC 数据转储主要包含年度报告

但是所有的公司都在一年的最后一天报告年度报表吗?

财政年度

数据集包含列fyfp,它们表示财务报表所代表的财政年度和季度。我们绘制了最典型的图表。(有关代码,请参见完整的笔记本“财政年度”部分)

2019 年的年度报表是最典型的,但我们看到一些 Q1、Q2 甚至 2020 年第三季度的报表

它揭示了一个有趣的事实,即 2020 年第一季度的数据包含 2020 财年的第二季度和第三季度。我们怎么可能在第一季度就已经知道夏季和秋季的财务结果呢?

让我们来看一下雷克斯诺德公司的财务报表。

本报告中 2020 财年之前(含)的财年是指相应日历年的 4 月 1 日至 3 月 31 日。例如,我们的 2020 财年,即 2020 财年,是指 2019 年 4 月 1 日至 2020 年 3 月 31 日这段时间。— Rexnord 公司

财政年度不必与日历年度完全相同。有些公司在 1 月份结束了 2020 财年,大部分数据都进入了 2019 年。意味着一个公司的财政收入和其他公司没有可比性。

2020 财年将从 2 月 19 日持续到 2020 年 1 月

2019 年营收如何确定?

为了使价格与基本面特征一致,我们必须确定收入何时获得,现金何时流入。我们用什么变量来找出财务数据的真实时间框架?它是数据集中另一个名为period的变量。再来看剧情。

period 变量表示表单财务周期的结束日期。

我使用了 Plotly 的高级 API,所谓的 Plotly.express 。它在数据集方面非常强大,然而,它却在不同类型的支线剧情中挣扎,比如本例中的条形图旭日 char t。

fig=**px.bar**(tens_period_stats_1, # preproces statistics in a DataFrame
           **x="period"**, # on x-axis display the period
           **y="records"**, # on y-axis count of the records
           **color="form"**, # split the bar chart by form (10-K, 10-Q)
           # created groupped bar-chart (not stacked)
          ** barmode="group"**, 
           **text="records"**, # label the bars with counts
           # show only period from Sept-2019 to March-2020
           # you can zoom-out the chart by double click
           **range_x=['2019-09-30','2020-03-31']** 

          )# plotly also struggles a bit with date-time variables,
# to make sure I see end of the months a specify that I really want ticks at these values
fig.update_xaxes(
    ticktext=tens_period_stats_1["period"].astype('str'),
    tickvals=tens_period_stats_1["period"].astype('str')
)fig.show()

如果您想要显示类别的详细信息,旭日图是饼图的有用替代物。

fig=**px.sunburst**(tens_period_stats_1,
                path=["label","form"],
                values="records")
fig.show()

我们可以看到,大部分报表都落入了 2019 年底 2020 年初的预期期。还有一些来自 2019 年 9 月、10 月和 11 月的申请。为什么它们不属于 2019 年第四季度的前一次转储?

注意:周期似乎在一个月的最后一天结束,但这是由 SEC 引入的舍入引起的。有些公司,如 John Deere 使用 52/53 周财年,其会计年度于 2019 年 11 月 3 日结束(参见 SEC 文件)。然而,大多数公司都会在月底前提交报表。

处理这些报表需要多长时间?平均处理时间。

SEC 规定季度报表的最后期限为 40-45 天,年度报表的最后期限为 60-90 天(参见 SEC 指南)。小公司 60 天,大公司 3 个月。这意味着在 1 月初发布 2019 年第四季度数据时,一些公司还没有上传 10 月、11 月甚至 9 月的数据。这就是为什么它们会出现在 2020 年的第一批垃圾中。

让我们看看是否每个人都设法满足这些期限。我们将accepted(SEC 接受数据时)的值与财政期结束时的period进行比较。

# we subtract `period` from `accepted` and turn into days
tens_latest_period["delivery_time"] = (tens_latest_period["accepted"] - tens_latest_period["period"]).dt.days

我们关注基本的统计参数:

[In]: df["delivery_time"].agg(["mean","median","min","max"])
[Out]: 
mean        78.115119
median      58.000000
min         11.000000
max       2929.000000

最快的会计师在 11 天内提交报表,但平均值和中间值都接近 60 天。使用 Plotly 创建直方图的能力,我们可以检查通常的交付时间。

**px.histogram**(df, 
             x="delivery_time", 
             color="form", 
             # maximum is 2929 days, but most of the values appear in the first fifth of the chart
             range_x=[0,200])

我们看到季度报告的交付时间大多长达 50 天,而年度报表的交付时间则长达 90 天

你注意到 90 天后提交的表格数量突然下降了吗?它承认,大多数公司都能在截止日期前提交,只有少数公司提交晚了。还可以有一些修正,我们将在下一节中探讨。

典型的年度报告超过 50 页。见亚马逊的 10k

大家都只报一个 10-K 还是 10-Q?

我们希望每家公司每个季度只报告一份报告,但是一个勤奋的分析师会仔细检查。我们根据公司的唯一cik号分组,并标出有多少公司提交了一份申请,以及是否有一些公司提交了更多的申请。

# Is 10-K/Q reported once by each company or more times? 
tens = sub[sub["form"].isin(["10-Q","10-K"])]# using `.value_counts().value_counts()` combo will tell us
# how many companies have 1, 2 or more records
tens_counts_by_company = tens["cik"].value_counts().value_counts().sort_index().to_frame()

然后我们可以直接从熊猫创建一个情节,如果你设置了

pd.options.plotting.backend = "plotly"

你可以使用不同的“后端”选项直接从熊猫绘图。查看 Matplotlib 如何仅显示输入的 xticks,同时 Plotly 填充 x 轴上缺失的值

我们预计所有的cik都只提交了一份报告,对于大多数公司来说,这是事实。然而,有一些张贴了更多的记录。

[In]: tens["cik"].value_counts()[Out]: 
1191334    33
1165639    14
1624985     8
1481504     4
...
1517681     1

公司为什么要这么做?这些错误是对以前提交的错误还是更正?他们是否将信息分成多个文件?我们不会知道,除非我们看看多次提交的例子。

我们过滤重复的行:

# we filter the "cik"'s which appear more than once
companies_reporting_more_tens = tens["cik"].value_counts()[tens["cik"].value_counts()>1]# we look on few columns with relevant data
columns_to_see = ["adsh","cik","name","period","fy","fp","filed", "form"]
tens[tens["cik"].isin(companies_reporting_more_tens.index)].sort_values(by=["cik","period"])[columns_to_see]

上面的代码显示了 321 行,按cikperiod排序,简单看一下就会告诉我们,实际上,大多数公司都提交了一些历史更正。拥有cik=1191334的公司似乎报告了包含 24 份季度报告和 9 份年度报告的全部历史,但大多数只发送了一两份额外的文件。

# preprocess the data
df = tens[["form","cik"]].groupby(["cik","form"]).size().to_frame("submitted 10-K/Q")\
.reset_index().groupby(["form","submitted 10-K/Q"]).size().to_frame("company count").reset_index()# Create a bar chart with two series, one for 10-K and one for 10-Q
fig = px.bar(df[df["submitted 10-K/Q"]>1], 
            x="submitted 10-K/Q", 
            y="company count",
            barmode="group", 
            color="form", 
            title="Number of companies having more than 1 submission in 2020Q1")# update the tickers to each each one starting from 1 with step of 1
fig.update_layout(
    xaxis_type='category'
)
fig.show()

设置 xaxis_type='category '将强制 Plotly 以发送的方式显示值,并且不使用从 1 到 len(df)的线性值。不幸的是,一个范围接一个范围,所以所有的 10-K 在左边,剩下的 10-Q 在右边。

现场检查没有发现任何公司会在同一时期发送两种填充物。我们能证明他们真的不存在吗?

[In]: tens.groupby(["cik","period"]).size().max()
[Out]: 2

对分组cik&period组合的检查发现,有一些公司将同一时期的数据上传给 SEC 两次。

让我们通过使用groupby作为过滤器来观察它们:

[In]: tens.groupby(["cik","period"]).size()[tens.groupby(["cik","period"]).size()>1][Out]:
cik      period    
1191334  2013-09-30    2
1635748  2019-06-30    2

详细的观察表明,它们在filedaccepted或两者上有所不同。

删除重复项

重复的线是每个数据集的祸根。它们导致许多问题,因为它们扭曲了度量标准,污染了机器学习模型,并且随着每个连接而成倍增加。一旦我们发现它们,我们应该立即决定如何去除它们。

在我们的情况下,我们将只接受后来填写的表格(更高的filed),如果所有记录都相同,我们将采用较新的accepted。熊猫的.cumcount()功能将帮助我们完成任务。这相当于 SQL 的ROW_COUNT(),我们将只选取每条记录的第一次出现。详细步骤如下:

  • 按决定性字段filedaccepted对数据进行排序
  • 按分区列分组— cikperiod
  • 使用.cumcount()对行 0,1,2 进行排序...
  • 仅过滤具有该值的行==0
# for all the `10-K` and `10-Q` we reduce the number of rows from 5212 to 5210
tens = tens.loc[tens.sort_values(by=["filed","accepted"],ascending=False).groupby(["cik","period"]).cumcount()==0]

Github 上查看完整的代码和详细的分解。

类似的算法将帮助我们仅获得 2020 年第一季度提供的最新提交:

tens_latest_period = tens.loc[tens.sort_values(by="period", ascending=False).groupby("cik").cumcount()==0]

外国公司

10-KQ对所有在股票市场交易的美国公司都是强制性的。但 SEC 收集从美国市场受益的外国企业的信息。他们必须按照20-F40-F表格提交财务报表。它们有什么不同?

让我们使用列countrybacityba来保存注册人的业务地址信息。我们把这些信息转换成地址。

[## Python 的地理编码-将地址列表转换为地图

如何使用地理定位 API 接收绘制客户、工厂、车队地图所需的数据…

towardsdatascience.com](/pythons-geocoding-convert-a-list-of-addresses-into-a-map-f522ef513fd6)

有了这些地方的纬度和经度,我们就可以在世界地图上显示出来。Plotly 的.scatter_geo()是我们需要的图表类型:

# set up the chart from the df dataFrame
fig = px.scatter_geo(twenties, 
                     # longitude is taken from the df["lon"] columns and latitude from df["lat"]
                     lon="lon", 
                     lat="lat", 
                     # choose the map chart's projection
                     projection="natural earth",
                     # columns which is in bold in the pop up
                     hover_name = "name",
                     # format of the popup not to display these columns' data
                     hover_data = {"name":False,
                                   "lon": False,
                                   "lat": False,
                                   "countryba": True
                                     },
                     color="form",
                     size_max=20
                     )
# fit the map to surround the points
fig.update_geos(fitbounds="locations", showcountries = True)fig.show()

40-F 专用于在加拿大注册的公司,而 20-F 则用于其他外国公司

自己试试

你想自己试试吗?没有比这更简单的了。SEC 最近公布了 2020Q2 数据。下载它们,解压缩并运行笔记本中的脚本,看看表单的结构在第二季度是否发生了变化。

[## vaclavdekanovsky/数据分析示例

github.com](https://github.com/vaclavdekanovsky/data-analysis-in-examples/blob/master/SEC Quarterly Data Dump/EDA_of_SEC_2020Q1_Filling_sub.ipynb)

结论

在本文中,我们回顾了 SEC 季度数据转储中提供的提交类型。我们已经看到,最常见的8-K在转储中没有附加信息。因此,我们重点关注年度和季度报表,并探索这些报表在提交后的 180 天内出现在数据集中。大多数公司在一个季度报告一份报表,但我们已经看到一些历史文件和一些副本。

通过删除重复项,我们为分析的下一步——探索财务状况——准备了数据集。但是对于本文来说,这些信息已经足够了,我们将在下次讨论。

如果您喜欢这篇介绍,请随意查看我的其他文章:

[## 阅读熊猫 CSV 时处理多余的空格

为什么我们关心空白?内置熊猫功能,自定义处理。创建 1M 测试数据和…

towardsdatascience.com](/dealing-with-extra-white-spaces-while-reading-csv-in-pandas-67b0c2b71e6a) [## 在一个文件夹中解压缩、更新和再压缩 XML

使用 python 自动化办公程序

towardsdatascience.com](/unzip-update-and-zip-again-xmls-in-a-folder-7d57f9710ddb)

该股票指标可能是预测 COVID 突破的最佳方式

原文:https://towardsdatascience.com/stock-indicators-may-be-the-best-way-to-predict-covid-breakouts-9b6939d9fc0c?source=collection_archive---------54-----------------------

MACD 等交易指标帮助交易员预测股票的技术方向。这些数学技术对于预测新冠肺炎病毒的爆发同样有用吗?

美国 MACD 指标新冠肺炎新病例

随着 2020 年继续带来一个又一个全球性挑战,我们经常发现自己似乎与这些威胁无关,因为它们给人一种逐渐消失的错觉。不幸的是,我们面临的挑战没有确定的结束日期或完美的解决方案。与我们面临的其他问题不同,新冠肺炎不会简单地消失,一旦它对经济和生计“太长”或“太具破坏性”。换句话说,我们无法通过与病毒的交易或让步来立即解决这个问题。

由于这种动态,我们所能做的最好的事情是尝试执行缓解方法,如社会距离和戴口罩,直到病例的指数轨迹足够低,直到固体疫苗上市为止。这听起来直截了当,但正如我们在美国各地看到的那样,当病例数开始减少时,我们会产生一种错觉,以为我们没事了,只是在我们回到正常生活后不久,病例就会大量增加。那么,我们如何预测什么时候我们是安全的,什么时候我们又处于危险之中,而不是简单地用我们的后见之明来解释我们当前的处境呢?

世界各地的数据科学家正在研究这个问题,以预测下一次爆发。方法范围从简单的统计,图形网络,接触追踪,有时甚至涉及经典的方法扔在一个“神经网络”的问题。这些方法中有许多是为人群和病毒病例量身定制的,可以快速实施。与此同时,数据科学的一个领域(可能是最古老的)还没有被开发到可以提供帮助的水平。这当然是量化的股票交易或技术交易。近 100 年来,预测股票爆发的方法一直在不断改进,主要是因为用例是即时的,而金钱是一个相当普遍的动机。技术交易指标有一点比其他统计模型做得更好——它们使用当前的环境。这有助于提供更多的确定性,并允许人根据算法做出决定,而不是仅仅从屏幕上读取预测的数字。在众多指标中,有一个指标的工作本质上是指示股票的潜在突破,所以为什么不试一试,就像我们试图预测爆发一样。介绍 MACD。

MACD

移动平均收敛发散或 MACD 是技术交易中使用的二阶到三阶衍生指标,有助于了解短期动量变化和方向。

指数移动平均线

MACD(EMA short-EMAlong)的工作原理是跟踪长期均线的短期指数移动平均线。通过这样做,我们能够看到短期趋势何时开始收敛或偏离长期趋势。如果我们开始看到短期移动平均线背离,我们可以推断一个潜在的突破正在进行中。另一方面,当这两个平均值接近时,我们开始看到盘整和表现不佳。总的来说,MACD 是动量的量度。

为了做出更精细的决策,还可以绘制一条信号线。信号线跟踪 MACD 的动量,所以另一个导数水平下降。这让我们可以看到 MACD 何时高于或低于均线。简而言之,当 MACD 穿过向上移动的信号时,我们认为这是一个“买入”信号,当它穿过向下移动时,我们认为这是一个“卖出”信号。

TSLA 600 万的价格(上)MACD(下)—由 E*Trade Pro 精英会员提供

为了将此付诸实践,我们可以看看特斯拉股票最近突破(或爆发)的 MACD 是什么样子的。这里的红线是信号(MACD 的 9 日均线),白线是 MACD(12 日均线——26 日均线)。图表上的直方图是 MACD 和信号之间的差异的直观显示,我发现它对跟踪最有用。在大多数情况下,MACD 和信号是平坦的,几乎没有直方图的作用。在图表右侧附近,我们看到标记线,MACD 穿过信号,随后直方图快速增加。这是在大约 1 个月左右的时间里从大约 800 美元突破到 1700 美元的时候。事后很容易看出这是如何发生的,但重要的是要注意,当线交叉或接近交叉时,有非常微妙的运动。如果你仅仅根据 MACD 忠实地接受买入信号,你会在一两个月内赚到超过 100%的钱!我们可以看到,目前,MACD 已经脱离了巨大动量的信号。即使涨势放缓,我们也要记住,直到白线向下穿过红线,我们才应该认为涨势结束了。*免责声明:我不是在给股票建议。

通过理解 MACD 是如何在没有明显动作的情况下发出突破信号的,我意识到我们和新冠肺炎有着相同的目标。案例数据类似于股票价格(显然我们的希望是相反的)。考虑到这一点,我们也许能够在疾病爆发前发现潜在的疾病,并更加努力地阻止直方图失控。

MACD 代表新冠肺炎

正如所讨论的,通过将相同的 EMA 方程及其导数应用于 COVID 病例,我们可以更好地预测和应对在典型病例图中不可见的潜在爆发。为了解决这个问题,我从 https://covidtracking.com/data/download 下载了美国、我的家乡密歇根州和佛罗里达州的 COVID 病例数据。从这里开始,我在 Excel 中建立模型,并计算每个导数值。请注意,从住院到病例,任何情况都可以这样做,但为了简化这些示例,将使用病例。

Excel 电子表格—由智力建设者 AI Research 提供

正如你所看到的,第一组 MACD 值只能开始 26 天的数据,而信号只能开始 35 天的数据。这显然会影响数据的长度,因为每个数据集只有大约 170 天的价值。为了对结果有个大概的了解,并与上面的图表相似,让我们来看看美国 MACD 的图表。

美国 MACD COVID 案例(1 月 26 日—7 月 12 日)—由 MindBuilder AI Research 提供

在接下来的两个例子中,我将更深入地介绍与 MACD 相比的案例数,如果您愿意,可以将此图表与美国的新案例进行交叉引用。我们在这里看到的是 2 月中旬的初始峰值。直到大约 3 月底,病例继续增长势头,直到最终稳定下来,并最终得到适度控制,此时势头减弱。只是提醒一下,此图表并不显示病例数,而是显示趋势,因此 y 轴值为零实质上意味着每天都有相同数量的病例增加,而低于 0 则意味着新病例在减少。这里的负面部分是关于各州何时开始重新开放的。不幸的是,在数据的第 112 天,我们看到 MACD 穿过了信号,这可能是人们开始感到舒适的时候。随着这一势头的增长,我们已经看到美国继续增加比以往更多的病例。如果这个信号被当作一个缓和的触发器,我们可能不会处于现在的状态。为了更细致地观察,让我们看看基于状态的数据,以及相对于病例数据,疫情是如何被缓解或忽略的。

佛罗里达州 MACD 的 COVID 病例(3 月 1 日-7 月 12 日)——由智力建设者 AI 研究公司提供

佛罗里达案例(3 月 1 日至 7 月 12 日)

众所周知,美国许多州都在努力应对新新冠肺炎病例的激增。其中一个州是佛罗里达。在今年的大部分时间里,佛罗里达州的 COVID 病例低于平均水平。不幸的是,这给了他们一种错觉,认为他们是清白的,这反过来又让他们可以推迟采取措施来缓解病毒。很明显,他们并不清楚,但在上图中爆发之前,这一点并不明显。让我们仔细看看,了解佛罗里达州可以看到 MACD。

佛罗里达案例到第 77 天

想象我们生活在第 79 天。正如我们在上面看到的,直到第 79 天,病例几乎没有变化。这将导致大多数人认为病毒受到控制,无论规则和缓解措施如何变化,都不会有太大变化。MACD 在这一点上发现了一些微妙的信号,并讲述了一个不同的故事。

第 67 天 MACD 十字路口

让我们回顾一下第 67 天和第 79 天之间的病例数据。肉眼看起来,每天有 500-700 例的稳定增长,没有变化可担心,但是小的稳定增长显示在 MACD 图表上,变化不仅仅是细微的。在完整的图表中,我们看到这变成了病例的爆炸,昨天 7 月 12 日增加了 15,000 例。这表明,在原始数据之下,一定有更好的指标,可以预示和阻止如此可怕的疫情。在第 67-69 天的那一刻,没人能预测到我们看到的增长,但 1970 年的一个交易指标做到了。这些隐藏在众目睽睽之下的简单数字本可以拯救生命,并有望在未来拯救生命。

结束语

COVID cases 的密歇根 MACD(3 月 1 日-7 月 12 日)——由智力建设者 AI 研究公司提供

这是我的家乡密歇根州的图表。我们从一开始就受到了沉重的打击,但是正如我们从数据中看到的,我们的努力粉碎了势头,使短期均线大部分时间低于信号。从这个数据来源来看,早期的 COVID 没有一个时刻显示出 MACD 的爆炸性势头(这应该是在 2 月中旬)。不幸的是,有趣的夏季在第 79 天左右创造了一个适度倾斜的十字。幸运的是,案件数量还没有爆炸性增长。这一势头刚刚变得积极,似乎已经得到遏制。但是,图表显示的正是我们在佛罗里达看到的情况,这有点令人不安。积极的一面是,我们仍然有时间采取行动,创造我们都在等待的“卖出”信号(红色下面的白色十字)。如果我的状态戴着面具,负责任地社交,并着眼于没有 COVID 的生活的长期利益,而不是短期的快乐,我们可以创造“出售”信号,并很快发现我们的生活超越了 COVID。

有了 MACD 这样强大的指标,这不再是一场猜谜游戏。我们可以在病例出现之前看到势头的变化,这意味着我们可以采取行动拯救最脆弱人群的生命。这可能是我们对付病毒形式的敌人的唯一手段之一。我希望这种方法至少能为对抗 COVID 做出一点小小的贡献,并能帮助人们认识到,遵循数据永远是最佳选择。

编者按: 走向数据科学 是一份以数据科学和机器学习研究为主的中型刊物。我们不是健康专家或流行病学家,本文的观点不应被解释为专业建议。想了解更多关于疫情冠状病毒的信息,可以点击 这里

LinkedInTwitter上与我连线继续对话。

看看我目前在 https://www.mindbuilderai.com 做什么

基于卷积神经网络的股票买卖预测

原文:https://towardsdatascience.com/stock-market-action-prediction-with-convnet-8689238feae3?source=collection_archive---------2-----------------------

灵感来自题为“深度卷积神经网络的算法金融交易:时间序列到图像转换”的研究论文

这个项目大致基于一篇名为“ 深度卷积神经网络的算法金融交易:时间序列到图像转换方法 ”的研究论文。我说“不严格”是因为尽管我从论文中借用了核心思想,但我做的(或必须做的)一些事情与我们稍后将看到的不同。我上面分享的链接是论文的预印本。付费/主文可能会有更多的细节。这篇文章是我的上一篇关于股票价格预测的文章的一位读者建议的,它立即引起了我的注意。这里是 Githubrepo和主培训笔记本上 Kaggle 的链接。

有一件事我想让读者知道——我不是在这里宣称我有一个现成的交易模型(尽管我正在为我个人的使用进一步探索这个方法)。将传统的表格或时间序列数据转换为图像,并在此基础上训练分类模型的想法,似乎太令人兴奋了,以至于无法抗拒尝试并与社区共享。像我的 上一篇 这是一篇记述我与这个项目的经历。

1.研究论文怎么说?

在这一节中,我将解释论文中提出的观点。我将在下一节讨论代码和实现。

这个想法很简单:在你的交易数据中,每天用 15 个不同的周期长度(解释如下)计算 15 个技术指标。然后将 225 (15*15)的新特征转换成 15×15 的图像。根据文中提供的算法,将数据标记为买入/卖出/持有。然后像任何其他图像分类问题一样训练一个卷积神经网络。

如果你不知道什么是技术指标,我建议你查看上面的链接。我会用简单移动平均线(SMA) 来解释技术指标和时间周期的概念,因为它更简单。这应该足够让你理解这个想法了。

数字列表的移动平均值类似于算术平均值,但我们不是计算所有数字的平均值,而是计算前“n”个数字的平均值(n 是指窗口大小或时间段),然后将窗口移动(或滑动)1 个索引,从而排除第一个元素并包括 n+1 个元素,然后计算它们的平均值。这个过程还在继续。这里有一个例子来说明这一点:

excel 表中的 SMA 示例

这是一个窗口大小为 6 的 SMA 示例。前 6 个元素的形状记忆合金以橙色显示。现在把上面的第一列当作你选择的股票的收盘价。现在计算 sma_6 右侧连接的 14 个其他窗口尺寸(7 到 20)的收盘价 SMA。现在,数据集的每一行都有 15 个新要素。对其他 14 个技术指标重复这一过程,删除空行。

使用的一些指标是 SMA 的延伸。例如,WMA(加权移动平均线)是前“n”天的平均值,最近几天的权重较大。类似地,HMA(赫尔移动平均线)是 WMA 的延伸,有以下步骤:

图片来源:【Fidelity.com

现在你有 225 个新功能。如果你把这些数字重组为一个 15x15 的数组,你就有一个图像了!(虽然,在这一点上,它是一个单一的渠道。稍后将详细介绍)。不过,有一件事要记住。在构建这些图像时,我们应该保持相关技术指标在空间上接近。直觉是,当训练人脸识别时,如果一张照片的一只眼睛在鼻子下面,你不会把它标为人脸。相关像素应该在附近。为了简洁起见,我不公布计算所有指标的代码。您可以在 utils.py 文件中找到它们。

标注:现在剩下的就是标注这个数据集。为此,作者使用了以下算法:

用于将数据集标记为买入/卖出/持有的算法

乍一看,这似乎令人生畏,但它说的就是:在收盘价上使用 11 天的窗口。如果中间数是窗口内的最大值,则将中间日标记为“卖出”,或者,如果中间数是最小值,则将中间日标记为“买入”,否则标记为“持有”。像前面解释的那样滑动窗户,然后重复。这个想法是在任何 11 天的窗口期内,在波谷买入,在波峰卖出。这个算法的能力是一个不同的问题,我将在最后讨论这个问题。

训练:作者使用了滚动窗口训练,类似于我们上面看到的滑动窗口概念。如果您有 2000 年到 2019 年的股票历史数据,并且您决定对 5 年的数据进行训练,对 1 年的数据进行测试,那么,从数据集中分割 2000-2004 年的数据用于训练,2005 年的数据用于测试。根据这些数据训练和测试您的模型。接下来选择 2001–2005 作为训练数据,2006 作为测试数据。使用相同的模型对此数据进行重新训练。重复直到你到达终点。

计算性能评估:作者在论文中提供了两种类型的模型评估,计算和财务评估。计算评估包括混淆矩阵、F1 分数、类精度等。财务评估是通过将模型预测应用于真实世界交易并测量所获得的利润来完成的。我将只讨论计算评估。财务评估可以通过真实世界的交易或对持有的数据进行回溯测试来完成,我将在以后的文章中讨论这一点。

2.履行

正如本文开头提到的,我没有严格遵循研究论文,因为它没有产生预期的结果。当它们出现时,我会提到它们的不同之处。但是随着我所做的改变,结果与论文持平,在某些情况下甚至更好。

数据处理相关代码可以在 data_generator.py 中找到

数据来源:我通常从 Alpha Vantage 获取股票数据,该公司免费提供历史股票数据。我在之前的项目中也用过它。以下是下载数据的方法。

url = "[https://www.alphavantage.co/query?function=TIME_SERIES_DAILY_ADJUSTED&outputsize=full&apikey=api_key&datatype=csv&symbol=company_code](https://www.alphavantage.co/query?function=TIME_SERIES_DAILY_ADJUSTED&outputsize=full&apikey=api_key&datatype=csv&symbol=company_code)"
urllib.request.urlretrieve(url, path_to_save)

数据是这样的:

特色工程:第一个偏离论文的是我用的技术指标。我找不到论文中提到的一些指标的库/实现,比如 PSI。有些指标就是不清楚;例如, PPO 是用周期 12 和 26 的 EMA 计算出来的。如何才能计算出不同时期的 PPO?我尝试使用论文中提到的大多数指标,我发现这些指标的开源实现可以避免任何编程错误。我已经实现了一些指标,如 WMA,HMA 等,虽然他们很慢,需要优化。因为我只需运行一次并保存数据,所以这对我来说不成问题。不过,你可以选择不同的指标。他们还用调整比率调整了价格(开盘价、最高价、最低价等)。但我没有遵循这一条,因为我找不到任何关于如何调整的参考资料。构建这些特性的所有函数都在 utils.py 文件中。

标注数据:对于这篇博客,我使用了作者们用过的原始标注算法。下面是它的一个直接实现:

要素构造和标注后的数据集如下所示:

归一化:我用的是 Sklearn 的 MinMaxScaler 对[0,1]范围内的数据进行归一化,虽然论文用的是[-1,1]范围(二次偏差)。这只是个人喜好。

特征选择:在计算了这些指标,根据它们的类型(动量、振荡器等)在图像中对它们进行分组,并训练了许多 CNN 架构之后,我意识到模型只是学习不够。也许功能不够好。因此,我决定采用许多其他指标,而不严格遵循用不同时期计算它们的规则。然后我使用特征选择技术选择了 225 个高质量的特征。事实上,我使用了两种特征选择方法 f_classif 和 mutual_info_classif,并从它们的结果中选择了共同的特征。原论文中没有提到特征选择,所以第三个偏差。

最后,我在排序索引列表时发现了 f_classif 和 mutual_info_classif 的交集。这是为了确保相关特征在图像中非常接近,因为我已经附加了相似类型的指示器。特征选择显著提高了模型的性能。

将数据重塑为图像:到目前为止,我们有一个包含 225 个特征的表格数据。我们需要把它转换成这样的图像:

这是图像的样子:

训练图像

处理类别不平衡:这类问题难以解决的另一个原因是数据严重不平衡。“持有”操作的实例数量将总是比“买入/卖出”多得多的。事实上,论文中提出的标记算法产生了相当多的买/卖实例。任何其他现实世界的策略都会产生更少的实例。更复杂的是,“暂停”事件的分类并不简单(在最后会有更多介绍)。

对于模特来说,这真的很难学到任何有意义的东西。这篇论文只提到“重采样”是解决这个问题的一种方法。我尝试过过采样,合成数据生成(SMOTE,ADASYN),但没有一个给出任何满意的结果。最后,我满足于“样本权重”,其中你告诉模型更多地关注一些样本(第四个偏差)。这在处理阶级不平衡时很方便。以下是计算样品重量的方法:

然后将这个样本权重数组传递给 Keras 的“拟合”函数。您还可以查看“class_weights”参数。

培训:所有与培训相关的代码都可以在 stock_keras.ipynb 中找到。论文中提到的模型架构缺少一些要点。例如,他们没有提到他们使用的步幅。但是在 stride=1 和 padding=same 的情况下,我发现这个模型太大了,尤其是对 5 年的数据进行训练。无论我使用多么小的网络,我在滑动窗口训练中都没有任何运气。所以我用交叉验证的全训练数据训练(第五偏差)。但是我已经在项目中包含了滑动/滚动窗口训练的代码(在“train.py”文件中)。所以,我用了一个非常相似的模型,有一些小的不同,比如辍学等等。这是我用来训练的模型(我没有尝试过大范围的超参数调优):

Keras 模型训练是通过 EarlyStopping 和 ReduceLROnPlateau 回调完成的,如下所示:

正如你在上面看到的,我用 F1 分数作为衡量标准。对于测试数据评估,我还使用了混淆矩阵、Sklearn 的加权 F1 分数和 Kappa(这是我最近才知道的,必须深入挖掘)。

在沃尔玛的数据上,上述模型给出了以下结果:

每次运行时,这个结果都会有些变化,这可能是由于 Keras 权重初始化造成的。这实际上是一个众所周知的行为,这里有一个很长的讨论线索。简而言之,你必须为 numpy 和 tensorflow 设置随机种子。我只为 numpy 设置了随机种子。所以我不确定它是否能解决这个问题。我会在这里更新,一旦我尝试了。但大多数时候,对于我尝试过的大多数其他 CNN 架构,0 类和 1 类(买入/卖出)的精度低于 2 类(0/1 类为 70)。

作者得到了以下结果:

道琼斯 30 指数的结果在文件中提出

如果你注意到,“持有”类的分数明显比“买入/卖出”类的分数差,无论是在我们的结果中还是在论文中。我认为这个结果很有希望,因为模型可以识别大多数的买/卖实例。以下是作者对此的看法:

“然而,也产生了许多虚假的入境和出境点。这主要是由于“买入”和“卖出”点出现的频率比“持有”点少得多,神经网络不容易捕捉“很少”的进入点和退出点而不危及主导“持有”值的一般分布。换句话说,为了能够捕捉到大多数“买入”和“卖出”点(回忆),该模型通过为不存在的进入点和退出点(精度)生成错误警报来进行权衡。此外,持有点不像“买入”和“卖出”(山丘和山谷)那样清晰。神经网络很可能会将一些“持有”点与“买入”点和“卖出”点混淆,特别是当它们靠近滑动窗口上的山顶或谷底时。

3.进一步的改进

  • 在更好的网络架构和超参数调整方面,肯定有很大的空间。
  • 在其他数据集上使用具有相同架构的 CNN 并没有给出令人印象深刻的买卖精确度。但通过摆弄超参数,我们肯定可以将其提高到与沃尔玛相似的数字。
  • 虽然这些结果看起来足够好,但不能保证它会给你带来真实世界交易的利润,因为它会受到你选择标记数据的策略的限制。例如,我对上述交易策略进行了回溯测试(使用原始标签,而不是模型预测!)但是我没赚多少。但那取决于数据的标注。如果有人使用更好的策略来标记训练数据,它可能会表现得更好。
  • 探索其他技术指标可能会进一步改善结果。

4.结论

我带着怀疑的态度开始了这个项目。我不确定这些图像是否有足够的信息/模式供 ConvNet 查找。但由于结果似乎比随机预测好得多,这种方法似乎很有前途。我特别喜欢他们将时间序列问题转化为图像分类的方式。

UPDATE- 12/7/2020: 重大更新-标签创建出现 bug,将标签分配给窗口最后一天,而不是中间项。我也用新的结果更新了这篇文章。在“stock_keras.ipynb”中更新了新模型

GitHub 上也有代码修复。请注意,由于我已经转移到 PyTorch,我不再有一个工作 Tensorflow 环境,我在云上训练这个模型,并且必须复制粘贴修复。所以,我无法完全测试最终代码(训练部分)。

插入了由于我的 GitHub 账户的改变而丢失的代码。

UPDATE- 23/2/2020: 我刚刚在我的模型创建函数“create_model_cnn”中发现了一个 bug,在这里我使用下面的检查来添加 MaxPool 层:

*if params["conv2d_layers"]['conv2d_mp_1'] == 1
replace this with
if params["conv2d_layers"]['conv2d_mp_1'] >= 0*

对“conv2d_mp_2”也进行同样的操作。模型或程序本身没有任何问题,只是我一直在探索没有任何最大池的超参数搜索空间:-(。需要探索模型是否可以在 MaxPool 层中表现得更好。

更新- 09/02/2020 :增加了对“特性工程”章节中一些更复杂的技术指标的解释。

使用主成分分析进行股票市场分析

原文:https://towardsdatascience.com/stock-market-analytics-with-pca-d1c2318e3f0e?source=collection_archive---------6-----------------------

从主成分分析到资本资产定价

主成分分析(PCA)是一种强大的数据分析工具,用于机器学习的许多领域。然而,尽管它的多功能性和有效性,它在金融中的应用并没有被广泛讨论。

今天,我将谈论 PCA 如何用于股票市场,它如何与资本资产定价模型(CAPM)相关,以及我们如何使用 PCA 来分析 COVID19 的影响。

(你可以在这里找到完整的代码和其他资源

1.PCA 快速回顾

第一个主成分解释了数据中的大部分差异。

简而言之,主成分分析(PCA)将数据分解成许多称为主成分的向量,这些向量实质上“总结”了给定的数据。更具体地说,这些摘要是输入特征的线性组合,试图尽可能多地解释数据中的差异。按照惯例,这些主成分按照它们能够解释的方差大小排序,第一个主成分解释了大部分数据。

2.资本资产定价模型快速回顾

股票的收益可以分解为:(1)无风险资产的收益,(2)市场因素的收益,以及(3)股票的特殊收益。总的来说,市场因素是所有股票回报的主要驱动力。

资本资产定价模型(CAPM)是一个著名的资产(如股票)收益定价框架,与现代投资组合理论有许多有趣的联系,我将在以后的文章中讨论。

在深入 CAPM 的细节之前,理解无风险资产和市场因素的概念是很重要的。无风险资产本质上是一种能给你带来几乎无风险回报的资产(如政府债券)。相反,市场因素监测整个股票市场的整体状况,通常通过 S&P500 等指数来衡量。一般来说,整个市场比政府债券更不稳定/风险更大,但它也为投资者提供了更多的回报。

记住这些定义,让我们看看 CAPM 的证券市场线(SML)的概念。在实践中,SML 将一只股票的收益分解为三个主要因素:

  1. r_f :无风险回报
  2. *【beta _ I (r _ m-r _ f):市场因子回报
  3. :特质回归**

证券市场线方程 —作者图片

这个等式背后的直觉是:

(1)一只股票的回报至少应该等于无风险资产的回报(否则为什么要冒额外的风险呢?)

(2)资产的收益也用市场因素来解释,市场因素用术语 (r_m-r_f) (衡量市场相对于无风险资产的超额收益)和【β_ I】(衡量资产受市场因素影响的程度)。

(3)股票的回报也受到特质因素的影响,特质因素是股票特有的因素(例如,股票的收益发布只影响该只股票,而不影响整体市场)。

从经验上来说,市场因素是股市回报的主要驱动力,因为它往往可以解释任何给定股票在任何给定日期的大部分回报。

3。PCA 和 CAPM 之间的联系

W 当将 PCA 应用于每日股票收益时,第一个主成分近似于市场因子。

让我们考虑 S&P500 指数中的 500 只股票,并计算它们的日回报率,如下图所示。

**rs = prices.apply(np.log).diff(1) 
rs.plot(title='Daily Returns of the Stocks in the S&P500')**

S&P500 中股票的每日收益——图片由作者提供

**crs = rs.cumsum().apply(np.exp)
crs.plot(title='Cumulative Returns of the Stocks in the S&P500')**

S&P500 中股票的累计收益—图片由作者提供

上图显示了自 2020 年初以来,S&P500 500 只股票的每日回报率和累计回报率。原始数据的数量可能看起来非常庞大,因此让我们通过 PCA 计算日收益率的第一个主成分来处理它们。下图显示了第一个主成分的值,它实际上是一个维数为 500 的向量,包含 500 只股票中每只股票的值。

**from sklearn.decomposition import PCApca = PCA(1).fit(rs.fillna(0))
pc1 = pd.Series(index=rs.columns, data=pca.components_[0])pc1.plot(xticks=[], title='First Principal Component of the S&P500')**

S 的第一个主成分& P500 返回—作者图片

回想一下:( 1)第一个主成分代表解释大部分方差的输入数据的线性组合,以及(2)股票回报的主要驱动因素是整体市场因素。这意味着,如果我们通过将现金按比例分配到第一主成分(即输入数据的线性组合)来制定股票投资组合,我们可以近似复制 S&P500 的回报(即股票回报的主要驱动因素)。

**weights = abs(pc1)/sum(abs(pc1)) # l1norm = 1
myrs = (weights*rs).sum(1)rs_df = pd.concat([myrs, market_rs], 1)
rs_df.columns = ["PCA Portfolio", "S&P500"]crs_df = rs_df.cumsum().apply(np.exp)
crs_df.plot(subplots=True);**

用基于五氯苯甲醚的投资组合复制 S&P500—作者图片

如上图所示,我们的 PCA 投资组合可以作为市场因素的代理,市场因素是股票回报的主要驱动因素(因此解释了大部分差异!).请注意,虽然它们是相似的,但 PCA 组合并不完全复制 S&P500,因为 S&P500 是 500 只股票的市值加权平均值,而 PCA 组合中的权重受解释的方差的影响。

4.使用 PCA 分析 COVID19 的影响

使用主成分分析,我们可以将受 COVID19 疫情影响最大/最小的企业聚集在一起,而无需事先了解它们的基本面。

你可能知道,由于疫情飓风的影响,2020 年对股票市场来说是疯狂的一年。使用主成分分析,我们可以分析这个疫情如何影响个股。

例如,让我们看看第一个主成分,并选择具有最大和最小负 PCA 权重的股票,如下所示。

**fig, ax = plt.subplots(2,1)pc1.nsmallest(10).plot.bar(ax=ax[0], color='green', grid=True, title='Stocks with Most Negative PCA Weights')pc1.nlargest(10).plot.bar(ax=ax[1], color='blue', grid=True, title='Stocks with Least Negative PCA Weights')**

使用 PCA 权重分析股票—作者图片

请注意上图中最负面的股票是旅游和能源板块。这是有道理的,因为 COVID19 严重影响了旅游业务,以及为这些业务提供燃料的能源公司。另一方面,受影响最小的公司属于消费品行业,这也是有道理的,因为该行业受益于检疫措施带来的消费品销售增长。

因此,通过应用 PCA,我们能够将受 COVID19 疫情影响的最佳和最差企业聚集在一起,而无需事先了解它们的基本面!

此外,我们可以制定一个获胜的投资组合,即根据 PCA 权重排名前 10 位的公司。如下图所示,由此产生的投资组合的表现将明显好于市场,因为它投资于实际受益于疫情的公司。

请注意,该投资组合带有前瞻性偏差,其中投资组合权重是使用市场低迷时期不可用的未来数据计算的。因此,以这种方式使用的 PCA 是一种回顾性的分析工具。关于前瞻偏差以及如何避免它们的更多信息,请查看这篇文章

**myrs = rs[pc1.nlargest(10).index].mean(1)
mycrs = myrs.cumsum().apply(np.exp)
market_crs = market_rs.cumsum().apply(np.exp)mycrs.plot(title='PCA Portfolio vs. S&P500')
market_crs.plot()plt.legend(['PCA Selection', 'S&P500'])**

用 PCA 跑赢市场——作者图片

我希望你喜欢这篇文章!如果你想看更多这样的内容,请关注我。

此外,查看我的网站的完整代码和其他资源。

股票市场和比特币价格关系——Python 分析

原文:https://towardsdatascience.com/stock-market-and-bitcoin-price-relationship-python-analysis-f39f992201c7?source=collection_archive---------19-----------------------

股票市场和比特币(BTC)价格之间有关系吗?

通过对 Python 和 Pandas 的分析,我们将能够在本文中回答这个问题。首先我们将检索,使用一个免费的 API,过去几年的比特币和股票价格。然后,我们将计算股市和比特币价格之间的相关性。最后,我们将通过 相关性矩阵图 来结束绘制相关性的分析。

照片由 Rick 在 Unsplash 上轻拍

比特币在经济中的作用

自从比特币的出现之后,我就一直想知道比特币在我们的经济中有什么作用。以下是三个潜在角色:

  • 比特币是否有类似黄金的作用?黄金被认为是安全的投资。也就是说,当经济步入衰退时,黄金价格往往会上涨,因为投资者会从股票转向黄金。这有助于投资者减少股市崩盘给他们的投资组合带来的潜在损失。如果比特币一直在投资界扮演安全天堂的角色,我们应该会看到股票和比特币价格之间的负相关关系。
  • 另一个可能的作用是比特币跟随金融市场的趋势。也就是说,如果股票价格正在上涨,这种实证主义会传染吗,因此,在比特币价格中也是可见的吗?
  • 我们分析的第三个潜在结果可能是,比特币价格与股市完全没有关系。

让我们用 Python 来了解一下吧!

用 Python 检索股票市场价格和比特币价格

为了获得数据来执行我们的分析,我将使用financialmodelingprepAPI 来检索比特币价格。他们还提供免费的股票数据,但为了向您展示两种不同的获取数据的方式,我将使用 Pandas DataReader 来检索股票数据。

作为我们市场数据的代理,我们将使用 S & P 500 指数标准普尔 500 指数是一个衡量在美国上市的 500 家最大公司股票表现的指数。我们将使用 Pandas DataReader 下载 SP500 价格和美联储经济数据(FRED) 作为来源。

如果你以前从未使用过Pandas**DataReaderPandas ,你将需要安装这些软件包。你可以通过使用 pip 命令来完成。

pip install pandas_datareader #Pandas data reader may not work with the latest Pandas version, therefore, I recommend you to install Pandas version 0.24: pip install pandas==0.24.2

太好了,现在我们可以用 Python 检索数据了。首先,我们将提取过去十年的 S&P500 股票价格。注意,通过使用 web,我们可以很容易地获得我们称之为 SP500 的熊猫系列中的数据。DataReader 并指定系列名称(即 sp500 )和供应商(即 fred )

pd.core.common.is_list_like = pd.api.types.is_list_likeimport pandas_datareader.data as web
import datetimestart = datetime.datetime(2010, 1, 1)
end = datetime.datetime(2020, 2, 10)SP500 = web.DataReader(['sp500'], 'fred', start, end)
print(SP500)

上面的代码行将返回下面的标准普尔 500 熊猫系列,其中包含 S&P 过去 10 年的价格:

标准普尔 500 价格

现在让我们检索比特币价格。为此,我们将使用financialmodelingprep API。我们将向 API 端点发出一个 http get 请求,该请求将返回一个包含历史 BTC 价格的字典:

import requests#BTCUSD contains a dictionary
BTCUSD = requests.get('[https://financialmodelingprep.com/api/v3/historical-price-full/crypto/BTCUSD'](https://financialmodelingprep.com/api/v3/historical-price-full/crypto/BTCUSD'))BTCUSD = BTCUSD.json()
BTCUSD = BTCUSD['historical']

我们解析包含在关键字名称历史中的字典。如果你不熟悉如何解析 API 响应,我推荐你阅读下面的文章

print(BTCUSD)[{'date': '2020-02-15',
  'open': 10315.651367,
  'high': 10341.555664,
  'low': 10226.138672,
  'close': 10244.959961,
  'adjClose': 10244.959961,
  'volume': 42347495424.0,
  'unadjustedVolume': 42347495424.0,
  'change': 70.69141,
  'changePercent': 0.685,
  'vwap': 10270.88477,
  'label': 'February 15, 20',
  'changeOverTime': 0.00685},
 {'date': '2020-02-14',
  'open': 10211....
    ....
    ...]}

现在,通过查看 BTCUSD 变量的内容,我们可以看到 BTCUSD 是一个字典列表,列表中的每个元素都是包含比特币价格的不同日期。BTC 价格存储在关闭键下。

例如,我们看到在 2 月 15 日,比特币的价格是 10244 美元。

我们需要将字典列表转换成熊猫数据框架。我们可以使用 pd 轻松做到这一点。DataFrame.from_dict() :

BTC = pd.DataFrame.from_dict(BTCUSD)
BTC.set_index('date',inplace=True)#Keep only the close column
BTC = BTC[['close']]#Rename the column name to BTC
BTC.columns = ['BTC']
BTC

BTC 价格

最后,我们在两只熊猫数据框中给出了 BTC 和标准普尔 500 的价格。现在,我们只需要将它们合并在一起。幸运的是,对于 Python 和熊猫来说,这很容易做到。

我们可以使用 pd.merge 来连接索引上的两个数据帧,因为索引包含了日期。因此,我们想在比赛日加入 S & P500 和 BTC 价格。

我们可以通过参数 right_indexleft_index 等于 True 来让 Pandas 知道我们想要使用该索引进行合并。更多细节见 Pandas 合并文档

SP500BTC = BTC.merge(SP500, how='inner',right_index = True, left_index=True)#Drop NA since we have nan values for weekends. S&P500 only trades business days
SP500BTC.dropna(inplace=True)print(SP500BTC)

BTC 和标准普尔 500 的价格

比特币与标准普尔 500 价格的关系

太好了,我们已经为分析准备好数据了。现在,我们可以继续寻找股票和比特币价格之间的关系。

为此,我们可以使用 Pandasdata frame . corr()来查找 Pandas DataFrame 列的相关性:

correlation = SP500BTC.corr()
print(correlation)###Result:BTC     sp500
BTC    1.000000  0.834106
sp500  0.834106  1.000000

如何解读 BTC 和标准普尔 500 房价的相关性?

相关矩阵的值范围从-1 到 1。更接近+1 意味着两个变量紧密地在一起,并且向同一个方向移动。值 0 表示变量之间没有关系。而负相关表示变量朝不同方向移动。越接近-1,反比关系越强。

通过研究我们的结果,我们发现比特币价格和标准普尔 500 指数之间存在 0.83 的强正相关性。这意味着当股票市场的价格上涨时,我们可以预计比特币也会跟随趋势上涨。

我们也可以通过使用 matplotlibstatsmodels 来可视化这种相关性:

from statsmodels import api as sm
import matplotlib.pyplot as pltsm.graphics.plot_corr(correlation,xnames=list(correlation.columns))
plt.show()

BTC 和 S&P500 相关矩阵

图表中的红色意味着这种关系是牢固和积极的。我们还可以使用Lin regressivescipy.stats 来检查这种关系在统计上是否显著:

#statistically significant?from scipy.stats import linregress
linregress(SP500BTC['sp500'],SP500BTC['BTC'])#H0: BTC and Stock prices are not related#Results:
LinregressResult(slope=8.956910705798713, intercept=-18068.59091142212, rvalue=0.8341059841835341, pvalue=0.0, stderr=0.1673358700767462)

由于我们的 p 值低于 0.05,我们可以拒绝 H0,因此,我们可以从统计上说,比特币和股票价格正在一起移动。

包扎

使用 Python 和 Pandas,我们分析了股票市场和比特币价格之间的关系。根据我们的分析结果,我们可以说 BTC 和标准普尔 500 价格同向移动。

我们很想知道这种关系在衰退的商业周期中是否也成立。为了进行这样的分析,我们可能需要等待一段时间,因为在过去几年中,我们一直生活在一个扩张的经济中。

请参见下面的完整脚本:

import pandas as pd
pd.core.common.is_list_like = pd.api.types.is_list_likeimport pandas_datareader.data as web
import datetimestart = datetime.datetime(2010, 1, 1)
end = datetime.datetime(2020, 2, 10)
SP500 = web.DataReader(['sp500'], 'fred', start, end)import requests
BTCUSD = requests.get('[https://financialmodelingprep.com/api/v3/historical-price-full/crypto/BTCUSD'](https://financialmodelingprep.com/api/v3/historical-price-full/crypto/BTCUSD'))
BTCUSD = BTCUSD.json()
BTCUSD = BTCUSD['historical']BTC = pd.DataFrame.from_dict(BTCUSD)
BTC.set_index('date',inplace=True)
BTC = BTC[['close']]
BTC.columns = ['BTC']SP500BTC = BTC.merge(SP500,how='inner',right_index = True, left_index=True)
SP500BTC.dropna(inplace=True)correlation = SP500BTC.corr()
print(correlation)from statsmodels import api as sm
import matplotlib.pyplot as plt
sm.graphics.plot_corr(correlation,xnames=list(correlation.columns))
plt.show()#statistically significant?
from scipy.stats import linregress
linregress(SP500BTC['sp500'],SP500BTC['BTC'])

原载于 2020 年 2 月 15 日 https://codingandfun.com

股市灯实时跟踪器

原文:https://towardsdatascience.com/stock-market-lamp-real-time-tracker-b2d0562a71c3?source=collection_archive---------37-----------------------

如何使用 Python 实时跟踪自己的投资组合

不用说,在这个疫情,股票市场一直不稳定。由于我们大多数人都被困在家里,我决定建造一个很酷的彩灯来实时反映我的股票市场投资组合。这样,当股票市场开盘时,我的灯会打开,它的颜色会反映我的开仓头寸,并在一天内更新。这是一个很酷的小工具,我还没有看到购买,所以为什么不建立自己的。我不喜欢日内交易,因为很多原因,我坚信大多数人不应该日内交易。因此,灯与其说是焦虑的制造者,不如说是一个有趣的配件。

材料清单

这里是你需要建立你的股市灯实时追踪器。如果你已经拥有一个彩色灯泡,你可以检查是否有一个库或 API 来通过 http 发送命令。在这种情况下,我们使用一个 Yeelight,它有一个 Python 库。

黄色灯泡

灯泡球

基本上,你会有一个 Wi-fi 智能灯和它的颜色变化从你的 Python 代码。地球仪是一个外壳,使它看起来很漂亮。

Python 代码灯泡控件

创建新的 python 项目。安装我们将使用的两个主要库:

pip install yeelight investpy

安装 yeelight 手机 app,配置灯泡。在应用程序中,打开局域网控制。在灯泡->设置(右上角图标)->设备信息中获取灯泡的 IP 地址。检查灯泡是否工作。

from yeelight import Bulb, BulbException
BULB_IP = **'192.168.X.XXX'** bulb = Bulb(BULB_IP)
bulb.get_properties(requested_properties=[**'power'**, ])

Python 代码股票市场

接下来,您可以创建一个函数来确定股票的 PnL

def daily_pnl(stock):
    stock_data = investpy.get_stock_historical_data(stock, **'united states'**, from_date=(date.today() +
        timedelta(days=-1)).strftime(**"%d/%m/%Y"**), to_date=date.today().strftime(**"%d/%m/%Y"**))
    stock_data.index = stock_data.index + timedelta(days=1)
    ytd = stock_data.iloc[0].Close
    tdy = stock_data.iloc[1].Close
    return ((tdy-ytd)/ytd)*100

简单地通过一只股票,如“AAPL”应该返回前一天的利润或损失。

最后,你所要做的就是将 PnL 范围转换成 RGB 颜色。

def refresh_bulb_color(bulb):
    pnl_to_color = {-1.0: **'#ff1100'**,  *# <1%+ loss* -0.5: **'#ff6a00'**,
                    0.0: **'#ffffff'**,  *# neutral* 0.5: **'#8fb2ff'**,
                    1.0: **'#0004ff'**,}  *# >+0.5% gain* pnl = daily_pnl(**'AAPL'**)
    print(**"{:.2f}%"**.format(pnl))
    pnl_idx = np.searchsorted(list(pnl_to_color.keys()), pnl, **'left'**).clip(0,4)
    color = list(pnl_to_color.values())[pnl_idx]
    rgb = tuple(int(color.lstrip(**'#'**)[i:i+2], 16) for i in (0, 2, 4))

    try:
        bulb.set_rgb(rgb[0], rgb[1], rgb[2])
    except BulbException:
        logging.error(**'bulb disconnected'**)
        return False

    return True

创建无限循环并设置刷新间隔。你可以调整 PnL 函数来反映你自己的投资组合,而不是单一的股票。

就是这样!你有自己的实时彩灯跟踪器。

股票市场的结果目前是伯努利分布

原文:https://towardsdatascience.com/stock-market-outcomes-are-currently-bernoulli-distributed-c2fbde004745?source=collection_archive---------40-----------------------

西蒙Unsplash 上的照片

这对股票风险意味着什么

来自《走向数据科学》编辑的提示: 虽然我们允许独立作者根据我们的 规则和指导方针 发表文章,但我们并不认可每个作者的贡献。你不应该在没有寻求专业建议的情况下依赖一个作者的作品。详见我们的 读者术语

我们目前正站在十字路口。刺激还是不刺激?有疫苗还是没有疫苗?COVID 和住院治疗的增长趋势还是快速平台期?

这些问题目前无法回答——每个人都有自己的看法,但没有人知道答案。

这种对未来的巨大不确定性是 VIX(衡量标准普尔 500 回报的预期远期波动性,也就是年化标准差)在股市徘徊在历史高点附近的情况下仍然顽固走高的原因。我以前写过这种现象:

[## VIX 怎么了?

了解 VIX 以及它想告诉我们什么

medium.com](https://medium.com/alpha-beta-blog/whats-up-with-the-vix-88b0a724d9fb)

什么是 VIX,我们为什么要关注它?

金融和数据科学有很多重叠之处。我会在之前的链接中详细介绍,但是让我们快速回顾一下 VIX 是什么。

VIX 是标准普尔 500 的隐含波动率。换句话说,是市场预期的标准普尔 500 指数(未来 30 天)收益的年化标准差。它是通过标准普尔 500 指数上一篮子期权的价格计算出来的(隐含波动率是期权价格的一个关键驱动因素,因此给定价格,我们可以取消隐含波动率)。

尽管它声称是前瞻性的,但从历史上看,VIX 看起来很像标准普尔 500 在过去 30 天的中的实际波动——所以它不是很有前瞻性:

VIX 与过去 30 天实现的波动性(来源:Sharadar,图形由作者创建)

但这并不意味着它完全没有信号。包括我自己在内的许多投资者抱怨说,在潜在的灾难性经济背景下,市场最近表现得自满。

尽管原始股价并没有反映出太多的担忧,但隐含波动率却反映了。看下面这个散点图。它绘制了标准普尔 500 指数相对于其历史高点(x 轴)和 VIX (y 轴)的交易位置。它们之间有一个明显的负关系——这意味着当标准普尔 500 指数接近其历史高点或创下新高时,VIX 往往较低(当出现大幅下跌时,VIX 往往较高)。

注:VIX 水平比如说 50 可以解释为未来 30 天的预期年化波动率为 50%。这意味着预期的 30 天波动率为 50%/sqrt(12) = 14.4%。**

标准普尔 500 从之前的峰值下降对 VIX(来源:沙拉达尔,图形由作者创建)

蓝色圆点是 2020 年 8 月 1 日之前的所有交易日(从 2010 年 1 月 1 日到 2020 年 7 月 31 日),橙色圆点是 2020 年 8 月 1 日及以后的所有交易日。注意对于给定的水位降深(在 x 轴上),橙色点位于或超出蓝色点的顶部范围。

这意味着市场的行为有些反常——在股票市场水平的控制下,VIX 高于历史水平。

作为参考,今年 2 月,在所有的疯狂之前,SPY(一个受欢迎的标准普尔 500 ETF)的交易价格在 335 左右。与此同时,VIX 指数为 13.7(年化隐含波动率为 13.7%)。在我写这篇文章的时候,间谍的价值比二月份的时候高了 343,但是 VIX 的价值是 29——是以前的两倍多!换句话说,尽管股票价格已经完全恢复,但标准普尔 500 在未来一个月的波动性预计将增加一倍。

主要的实际影响是投资组合保险(VIX 看涨期权和标准普尔 500 看跌期权)今天比今年年初贵得多。这使得对冲股票风险变得更加困难。

为什么会出现这种情况?

新闻会说些老一套——选举不确定性、经济焦虑、软银收购大量科技股看涨期权,等等。

没错,这些都会对边际利润产生影响。但我觉得答案更简单。通常,当我们展望未来时,市场回报预计大致呈正态分布(如果你想了解细节,请参见下面的链接博客)。

* [## 股票收益是正态分布吗?

从概率分布中得出的预期与真实世界的股票回报匹配吗?

towardsdatascience.com](/are-stock-returns-normally-distributed-e0388d71267e)

如果你把所有的日收益率绘制在柱状图上,它应该看起来或多或少像一条钟形曲线,事实确实如此:

实际回报分布与理论回报分布(来源:Sharadar,图片由作者创作)

目前,市场收益不是正态分布的。下面,我绘制了标准普尔 500 过去两个月的每日收益分布图(橙色)和 COVID 市场崩盘前两个月的收益分布图(蓝色)。注意橙色分布看起来是双峰的。

实际回报分布与理论回报分布(来源:Sharadar,图片由作者创作)

最近,市场行为可以被描述为——当市场参与者降低他们获得更多政府刺激的可能性时,市场下跌。当他们提高政府刺激的可能性时,市场就会上涨。

但最终,答案要么是肯定的,要么是否定的。要么是经济得到足够的刺激,在柯维德退出的同时启动它,要么是没有。换句话说,我们要么得到一个快乐的结果,要么得到一个悲伤的结果,没有中间的

那样的双峰结果可以用 伯努利分布 来建模。伯努利分布随机变量的一个例子是掷硬币——要么你得到概率为 p 的正面,要么得到概率为 1-p 的反面。

这就像现在的股票市场——要么事情变好(刺激、疫苗、经济复苏),要么事情变坏(刺激不够、疫苗不起作用、经济灾难)。

伯努利分布随机变量的标准差为:

**Standard deviation of Bernoulli random variable
  = p*(1 - p)**Where p is the probability of success.

让我们想出一些数字,并计算一个标准差。假设以下情况:

  • 事情有 75%的可能会好起来。
  • 如果情况好转,市场将上涨 20%。
  • 如果事情变得糟糕,市场将崩溃-50%。

我们可以计算股票市场的预期标准差如下:

stock market standard deviation**= (0.2-(-0.5)) * (0.75*(1-0.75))**0.5 = 30.3%
which implies of VIX of 30.3**** denotes exponent

这非常接近目前观测到的 VIX 水平 29.3。如果您想仔细检查上述计算,可以运行以下 Python 代码。它产生相同的答案。

import numpy as npresult = []
for i in range(100000):
    if np.random.random() > 0.75:
        result.append(0.2)
    else:
        result.append(-0.5)

np.std(result)

伯努利分布回报的风险更大

29.3 挺高的。作为参考,在过去十年中,标准普尔 500 的平均实现 30 天波动率为 16.5%。

我之前认为隐含波动率太高,因此期权溢价很高。我不再这么想了。抛硬币的结果很可怕,因为风险很大。你可能会对我在上面的计算中使用的输入数据提出异议,但很明显,如果健康和经济状况不能很快好转,情况将会变得更糟。美联储和 QE 能做的就这么多了。

为什么我说伯努利分布收益风险更大?想象两个游戏:

  1. 游戏 1: 你掷 100 枚硬币。对于每枚硬币,如果是正面,你就赢 1500 美元,如果是反面,你就输 1000 美元。第一场的结果将是正态分布的。**
  2. 游戏二:你只抛一枚硬币。如果是正面,你赢 15 万美元,如果是反面,你输 10 万美元。第二场比赛的结果将是伯努利分布。

这两款游戏的预期价值都是 25000 美元。但他们显然不平等。第二场比赛风险更大——要么你很富有,要么你损失了一大笔钱。我们可以用下面的代码模拟这两个游戏:

*# 100K simulations of  Game 1 - Flip 100 coins
all_results = []
for j in range(100000):
    result = 0
    for i in range(100):
        if np.random.random() > 0.5:
            result += 1500
        else:
            result += -1000
    all_results.append(result)

print('Game 1:', np.mean(all_results), np.std(all_results))# 100K simulations of  Game 2 - Flip 1 coin
result = []
for i in range(100000):
    if np.random.random() > 0.5:
        result.append(150000)
    else:
        result.append(-100000)

print('Game 2:', np.mean(result), np.std(result))*

从我的代码输出中,我可以看到第一场游戏(我们掷 100 枚硬币)的标准差是 12,500 美元。相比其 25,000 美元的预期价值,这已经相当不错了。

另一方面,游戏 2 的标准差为 125,000 美元!与预期值相比,这是一个巨大的数字。

我们可以用两个游戏模拟结果的直方图来形象化这一点。尽管预期收益相同,游戏 2 显然有更大的下跌风险。在第一场比赛中赔钱的可能性很小(即使这样,你也只输了一点点)。在第二场比赛中,你有 50%的概率会丢失大量的零钱。

游戏 1 和游戏 2 的结果直方图(图形由作者创建)

虽然这个例子是程式化的,但它在精神上类似于当前的市场形势。在面临抛硬币时,股市参与者目前面临着前所未有的不确定性。虽然它可能没有被计入股市估值,但它被计入了 VIX,这与投资保险的价格相对应。大家小心!

更多真实故事

* [## iBuyers 为房地产市场带来便利和流动性

但是这些东西值得花几千块钱买吗?

medium.com](https://medium.com/alpha-beta-blog/ibuyers-bring-convenience-and-liquidity-to-the-real-estate-market-fb1c99f9fcd6) [## 了解线性回归

数据科学的主力

towardsdatascience.com](/understanding-linear-regression-94a6ab9595de)*

用 Python 进行股票新闻情绪分析!

原文:https://towardsdatascience.com/stock-news-sentiment-analysis-with-python-193d4b4378d4?source=collection_archive---------6-----------------------

对财经新闻进行秒级情感分析!

跟上金融和特定股票的新闻对你的交易策略非常有益,因为它通常会决定价格的变化。因此,我创建了这个算法,可以轻松快速地解析 FinViz 股票筛选程序,并计算任何输入股票的新闻标题的情绪。

图片由 StockSnap 来自 Pixabay

FinViz 无疑是网络上最强大的股票筛选工具之一。它可以免费获取大量信息,包括交互式图表、70 多个基本比率、大型银行交易数据以及几乎任何股票的最新新闻标题。如果你以前从未使用过 FinViz,我在下面附上了苹果公司的数据截图,以及我们将在本文中收集的数据。

AAPL 的基本比率和互动图表。

FinViz 为 AAPL 提供内幕交易信息和最新新闻标题。

第二个屏幕截图中的蓝色信息是更新的新闻标题,这正是我们将要抓取和执行情感分析的内容。既然我们已经检查了我们将使用的数据,让我们进入代码!

导入和参数

要开始,首先导入以下模块,并根据您的喜好设置参数。变量 n 表示将为‘ticker’列表中的每个 ticker 显示的文章数量。代码的其余部分将不必手动更新,这些是您每次运行代码时必须更改的唯一参数。

从 FinViz 获取新闻数据

接下来,我们将使用模块 BeautifulSoup 和 requests 从 FinViz 网站获取新闻数据。该代码解析新闻 HTML 表的 URL,并遍历滚动条列表,收集每个滚动条最近的标题。对于每一只输入的股票,都会打印出“n”个最近的头条,以便于查看数据。

反复阅读新闻

为了执行情感分析,数据必须采用正确的格式,因此这段代码遍历收集到的新闻,并将其分类为一个列表,包括报价器、日期、时间和实际标题。

执行情感分析

使用功能强大的 nltk 模块,可以分析每个标题的极性分值,分值范围为-1 到 1,其中-1 表示高度负面,1 表示高度正面。

查看结果数据

最后,数据已经准备好以一种吸引人的方式进行操作和查看。对于输入列表中的每个跑马灯,将创建一个新的数据帧,包括其标题和各自的分数。最后,将创建一个最终的数据帧,其中包括每个报价器在所有最近解析的新闻中的平均情绪值。

解析算法的所有代码

上面的 GitHub 要点包含了这篇文章的所有代码。我希望这个算法将来对你有用。非常感谢您的阅读!

免责声明:本文材料纯属教育性质,不应作为专业投资建议。自行决定投资。

如果你喜欢这篇文章,可以看看下面我写的其他一些 Python for Finance 文章!

[## 使用 Python 在几分钟内解析数千份股票推荐!

了解如何在不到 3 分钟的时间内解析顶级分析师的数千条建议!

towardsdatascience.com](/parse-thousands-of-stock-recommendations-in-minutes-with-python-6e3e562f156d) [## 用 Python 制作股票筛选程序!

学习如何用 Python 制作一个基于 Mark Minervini 的趋势模板的强大的股票筛选工具。

towardsdatascience.com](/making-a-stock-screener-with-python-4f591b198261) [## 在 3 分钟内创建一个财务 Web 应用程序!

了解如何使用 Python 中的 Streamlit 创建技术分析应用程序!

towardsdatascience.com](/creating-a-finance-web-app-in-3-minutes-8273d56a39f8)

使用最先进的转换器和时间嵌入进行股票预测

原文:https://towardsdatascience.com/stock-predictions-with-state-of-the-art-transformer-and-time-embeddings-3a4485237de6?source=collection_archive---------0-----------------------

给交易机器人输入最新的股票预测

照片由晨酿Unsplash 拍摄

在我之前的文章中,我分享了我第一次预测股票价格的研究结果,这些结果随后将被用作深度学习交易机器人的输入。在将我的数据集升级到数以千计的股票报价机,相当于几乎1tb 的股票价格历史和新闻文章的同时,我开始意识到我最初使用由LSTM(LONG-SshortTermM记忆模型和 CNN ( C 组成的神经网络的方法因此,为了克服这些限制,我必须实现一个专用于股票时间序列转换器

近年来,变压器因其出色的性能而广受欢迎。将自我关注机制、并行化位置编码结合在一起,在处理需要语义特征提取和大型数据集的任务时,通常比经典的 LSTM 和 CNN 模型更具优势1

由于我无法找到一个简单的转换器实现,它是为具有多种特征的时间序列定制的,例如,我们股票数据的(开盘、盘高、盘低、收盘、成交量)特征,所以我必须自己实现它。在这篇文章中,我将分享我对股票数据的转换架构,以及什么是时间嵌入,以及为什么必须将它们与时间序列结合使用。

数据

出于本文的解释目的,我们将使用 IBM 股票价格历史作为 1tb 股票数据集的简化版本。尽管如此,您可以轻松地将本文中的代码应用到更大的数据集。IBM 数据集从 1962 年 1 月 2 日开始,到 2020 年 5 月 24 日结束,总共包含 14699 个交易日。此外,每个交易日,我们都有 IBM 股票的开盘价高开低开收盘价以及交易量

IBM 的每日收盘价和成交量

数据准备

价格和交易量特征被转换成每日股票收益和每日交易量变化,应用最小-最大标准化,并且时间序列被分成训练、验证和测试集。将股票价格和交易量转换为每日变化率增加了数据集的稳定性。因此,模型从我们的数据集中获得的知识对未来预测具有更高的有效性。这里概述了转换后的数据是什么样子。

IBM 的每日收盘价回报和成交量变化

最后,训练集、验证集和测试集被分成长度为 128 天的单独序列。对于每个序列日,有 4 个价格特征(开盘价、盘高、盘低、收盘价)和交易量特征,每天有 5 个特征。在单个训练步骤中,我们的 Transformer 模型将接收 32 个序列 (batch_size = 32) ,它们是 128 天长的 (seq_len=128) ,并且每天有 5 个特征作为输入。

模型输入矩阵的大小

时间嵌入

作为 Transformer 实现的第一步,我们必须考虑如何将隐藏在股票价格中的时间概念编码到我们的模型中。

在处理时间序列数据时,时间是一个基本特征。然而,当使用转换器处理时间序列/顺序数据时,序列通过转换器架构一次转发,这使得提取时间/顺序依赖性变得困难。因此,与自然语言数据结合使用的转换器倾向于利用位置编码为模型提供词序的概念。详细地说,位置编码是单词的值及其在句子中的位置的表示,允许转换器获得关于句子结构和单词相关性的知识。一个位置编码的例子可以在BERT【2】模型的引擎盖下找到,该模型已经为许多语言任务实现了最先进的性能。****

类似地,一个转换器在处理我们的股票价格时需要一个时间概念。如果没有时间嵌入,我们的转换器将不会收到任何关于股票价格时间顺序的信息。因此,2020 年的股票价格对未来价格预测的影响与 1990 年的价格相同。当然,这将是可笑的。****

时间 2 向量

为了克服转换器的时间差异,我们将实现论文 Time2Vec:学习时间的向量表示【2】中描述的方法。论文作者提出了“一种与模型无关的时间向量表示,称为time 2 vec** 你可以把向量表示想象成普通的嵌入层可以添加到神经网络架构中,以提高模型的性能。**

将这篇论文归结为它的要点,有两个主要观点需要考虑。首先,作者发现有意义的时间表示必须包括周期性和非周期性模式。周期性模式的一个例子是随不同季节而变化的天气。相反,非周期性模式的一个例子是一种疾病,随着患者年龄的增长,这种疾病发生的概率很高。

****其次,时间表示应具有对时间缩放的不变性,意味着时间表示不受不同时间增量(如天、小时或秒)和长时间范围的影响。

结合周期和非周期模式的思想以及对时间缩放的不变性,我们由下面的数学定义给出。别担心,这比看起来容易,我会详细解释的。😉

时间向量的数学表示— Time2Vec:学习时间的向量表示[3]

时间向量/表示法***t2v***由两部分组成,其中***ωᵢτ + φᵢ***表示时间向量的非周期性/线性特征,***F(ωᵢτ + φᵢ)***表示时间向量的周期性特征。

用一种更简单的方式重写***t2v(τ) = ωᵢτ + φᵢ***,新版本***y = mᵢx + bᵢ*** 应该看起来很熟悉,因为它是你从高中就知道的线性函数的普通版本。***ωᵢτ + φᵢ***中的***ω***是定义我们的时间序列***τ***的斜率的矩阵,***φ*** 简单来说就是定义我们的时间序列***τ*** 与 y 轴的交点的矩阵。因此,***ωᵢτ + φᵢ***无非是一个线性函数。

非周期时间特征的 2D 表示

第二分量***F(ωᵢτ + φᵢ)***代表时间向量的周期性特征。就像之前我们又有了线性项***ωᵢτ + φᵢ***,然而,这次线性函数被包装在一个额外的函数***F()***中。作者试验了不同的函数来最好地描述周期关系(sigmoid、tanh、ReLU、mod、triangle 等。).最终,一个正弦函数取得了最好和最稳定的性能(余弦函数取得了类似的结果)。当组合线性函数***ωᵢτ + φᵢ***和正弦函数时,2D 表示如下。***φ*** 沿 x 轴移动正弦函数,***ω*** 决定正弦函数的波长。****

周期性时间特征的 2D 表示

让我们看一下 LSTM 网络的精度与时间向量(Time2vec)的不同非线性函数的组合是如何变化的。我们可以清楚地看到, ReLU 函数执行最差最差,相比之下,正弦函数优于所有其他非线性函数。ReLU 函数具有如此不令人满意的结果的原因是,ReLU 函数对于时间缩放不是不变的。函数对时间缩放的不变量越高,性能越好。

非线性函数的性能比较— Time2Vec:学习时间的向量表示[3]

时间 2 矢量性能改进

在我们开始实现时间嵌入之前,让我们看看普通 LSTM 网络(蓝色)和 LSTM+Time2Vec 网络(红色)的性能差异。正如您所看到的,建议的时间向量不会导致多个数据集的性能下降,并且几乎总是会提高模型的性能。有了这些认识,我们就可以继续实现了。

有和没有时间向量的 LSTM 网络的性能比较— Time2Vec:学习时间的向量表示[3]

Time2Vector Keras 实施

好了,我们已经讨论了时间向量的周期和非周期分量在理论上是如何工作的,现在我们将在代码中实现它们。为了使时间向量易于集成到任何种类的神经网络架构中,我们将向量定义为 Keras 层。我们定制的 Time2Vector 层有两个子函数def build():def call():。在def build():中我们初始化了 4 个矩阵,2 个为***ω*** 和 2 个为***φ*** 因为我们需要一个***ω******φ***的矩阵来兼顾非周期性(线性)和周期性(正弦)的特性。

seq_len = 128def build(input_shape):
   weights_linear = add_weight(shape=(seq_len), trainable=True)
   bias_linear = add_weight(shape=(seq_len), trainable=True) weights_periodic = add_weight(shape=(seq_len), trainable=True)
   bias_periodic = add_weight(shape=(seq_len), trainable=True)

启动 4 个矩阵后,我们定义一旦调用该层将执行的计算步骤,因此有了def call():函数。

将由 Time2Vector 层接收的输入具有以下形状(batch_size, seq_len, 5) → (32, 128, 5)batch_size定义了我们希望一次将多少股票价格序列输入模型/层。seq_len参数决定单个股票价格序列的长度。最后,数字5来源于这样一个事实,即我们有 IBM 每日股票记录的 5 个特征(开盘价、最高价、最低价、收盘价、成交量)。

第一个计算步骤排除了成交量,取开盘价、最高价、最低价和收盘价的平均值,得到形状(batch_size, seq_len)

x = tf.math.reduce_mean(x[:,:,:4], axis=-1)

接下来,我们计算非周期(线性)时间特征,并再次将维度扩展 1。(batch_size, seq_len, 1)

time_linear = weights_linear * x + bias_lineartime_linear = tf.expand_dims(time_linear, axis=-1)

对周期性时间特征重复相同的过程,也产生相同的矩阵形状。(batch_size, seq_len, 1)

time_periodic = tf.math.sin(tf.multiply(x, weights_periodic) + bias_periodic)time_periodic = tf.expand_dims(time_periodic, axis=-1)

结束时间矢量计算所需的最后一步是连接线性和周期性时间要素。(batch_size, seq_len, 2)

time_vector = tf.concat([time_linear, time_periodic], axis=-1)

时间 2 矢量层

将所有步骤组合成一个层函数,代码如下所示。

变压器

现在我们知道了提供时间的概念以及如何实现时间向量是很重要的,下一步将是转换器。转换器是一种神经网络架构,它使用自我关注机制,允许模型关注时间序列的相关部分,以提高预测质量。自关注机构由单头关注多头关注层组成。自我关注机制能够立即将所有时序步骤相互连接,导致长期依赖理解的创建。最后,所有这些过程都在 Transformer 架构中被并行化,从而加速了学习过程。

结合 IBM 数据和时间特性——为转换器提供信息

在实现了时间嵌入之后,我们将结合 IBM 的价格和数量特性使用时间向量作为转换器的输入。 Time2Vector 层接收IBMpricevolume 特征作为输入,并计算非周期性周期性** 时间特征。在随后的建模步骤中,计算出的时间特征与价格和数量特征连接在一起,形成一个形状为(32, 128, 7)的矩阵。**

计算时间特性并与 IBM 价格和交易量连接

单头注意力

****IBM 时间序列加上我们刚刚计算的时间特征形成第一单头注意层的初始输入。单头关注层总共取 3 个输入(查询,键,值)。对我们来说,每个查询、键和值输入都代表了 IBM 的价格、数量和时间特性。每个查询、键和值输入都通过单独的密集层接受单独的线性转换。为密集层提供 96 个输出单元是个人的架构选择。

单头注意力-查询、键和值输入的线性转换

在初始的线性变换之后,我们将计算注意力得分/权重。注意力权重决定了在预测未来股价时,对单个时间序列步骤的关注程度。注意力权重通过取线性变换的查询和键输入的点积来计算,而变换的键输入已经被转置以使得点积乘法可行。然后点积除以先前密集层(96)的尺寸大小,以避免爆炸梯度。然后,被划分的点积通过 softmax 函数产生一组权重,其总和为 1** 。作为最后一步,计算出的确定每个时间步焦点的 softmax 矩阵与转换后的 v 矩阵相乘,得出单头注意机制。**

单头注意力—在对查询、键和值输入进行线性转换后计算注意力权重

由于插图对于最初的学习来说是很好的,但缺乏实现方面,我为你们准备了一个干净的单注意力 Keras 层函数🙂。

多头注意力

为了进一步完善自我注意机制,论文作者提出了实施多头注意【4】。多头注意力层的功能是 c ***n*** 单头注意力层注意力权重进行处理,然后对密集层应用非线性变换。下图显示了 3 个单头层的连接。

拥有***n***单头层的输出允许将多个独立的单头层转换编码到模型中。因此,该模型能够同时关注多个时间序列步骤。增加注意力头的数量会积极地影响模型捕捉远距离依赖性的能力。1

多头注意力层

同上,多头注意力层的干净实现。

变压器编码器层

单头和多头注意机制(自我注意)现在被聚合到一个 transformer 编码器层中。每个编码器层包含一个自关注子层和一个前馈子层。前馈子层由两个致密层组成,其间有 ReLU 激活。

另一方面,如果 Conv 层的核大小和步距为 1,则密集层可以用 1 维卷积层代替。具有所述配置的密集层和卷积层的数学是相同的。

每个子层之后是一个丢失层,丢失后,通过将初始查询输入添加到两个子层输出来形成剩余连接。结束每个子层,在剩余连接附加之后放置一个标准化层,以稳定和加速训练过程。

现在我们有了一个现成的 Transformer 层,它可以很容易地堆叠起来以提高模型的性能。由于我们不需要任何变压器解码器层,我们实现的变压器架构与 BERT [2]架构非常相似。尽管不同之处在于时间嵌入,我们的转换器可以处理三维时间序列,而不是简单的二维序列。

变压器编码器层

如果您想深入研究代码,我们开始吧。

具有时间嵌入和转换器层的模型架构

总之,我们首先初始化时间嵌入层以及 3 个变换器编码器层。初始化之后,我们将一个回归头堆叠到最后一个 transformer 层上,训练过程开始。

结果

训练过程总共有 35 个时期。在训练之后,我们可以看到,我们的转换模型只是预测了一条位于每日股价变化之间的平坦线。当仅使用 IBM 股票历史时,即使是变压器模型也仅仅能够预测股票发展的线性趋势。得出的结论是,股票的历史价格和交易量数据只包含足够的线性趋势预测的解释价值。然而,当将数据集升级到数千个股票报价机(1tb 数据集)时,结果看起来完全不同🙂。

****

验证和测试数据集+预测

将移动平均应用于股票数据—特征工程

如上所示,即使是最先进的模型架构也无法从历史股价和交易量中提取非线性股票预测。但是,当对数据应用简单的移动平均平滑效果时(窗口大小=10),模型能够提供明显更好的预测(绿线)。该模型也能够预测涨跌,而不是预测 IBM 股票的线性趋势。然而,当仔细观察时,您仍然可以看到该模型在具有极端日变化率的日子中具有较大的预测增量,因此我们可以得出结论,我们仍然存在异常值问题。

应用移动平均效果的缺点是新的数据集不再反映我们的原始数据。因此,具有移动平均线效应的预测不能用作我们的交易机器人的输入。

****

移动平均特征-验证和测试数据集+预测

然而,由于移动平均效果的平滑化,可以在不应用移动平均的情况下实现性能的提高。我的最新研究表明,当将数据集扩展到大量股票时,可以获得相同的表现。

本文给出的所有代码都是可以端到端运行的笔记本的一部分。笔记本可以在 GitHub 上找到。

来自《走向数据科学》编辑的提示: 虽然我们允许独立作者根据我们的 规则和指导方针 发表文章,但我们并不认可每个作者的贡献。你不应该在没有寻求专业建议的情况下依赖一个作者的作品。详见我们的 读者术语

谢谢你,

一月

编辑于 2022 年 6 月 1 日:

在过去,我收到了一些反馈和请求,希望我的金融资产预测模型能够变得可用且易于使用。这将有助于人们回答以下问题:

有哪些好的资产可以投资?我应该把什么放入我的金融投资组合?

我给你介绍一下pink lionwww . pink lion . XYZ

** [## 粉色狮子

我们把你从乏味和令人沮丧的工作中解脱出来。没有更多的清洁数据和模型试验和…

www.pinklion.xyz](https://www.pinklion.xyz/)

PinkLion 是一款基于我的代码库之上的产品,它使成千上万只股票、基金/ETF 和加密货币的日常资产数据可用。此外,通过提供对基础预测模型的访问,它允许资产分析和投资组合的动态优化。

目前,注册人数仍然有限,因为单个计算需要大量的服务器资源。

请随意尝试并提供反馈。(目前还处于大致状态) www.pinklion.xyz**

放弃

本文中的任何内容都不构成任何特定证券、证券组合、交易或投资策略适合任何特定人士的建议。期货、股票和期权交易包含巨大的损失风险,并不适合每个投资者。期货、股票和期权的估值可能会波动,因此,客户的损失可能会超过他们的原始投资。

参考

1为什么要自我关注?神经机器翻译架构的目标评估https://arxiv.org/abs/1808.08946

**[2]伯特:语言理解深度双向转换器的预训练【https://arxiv.org/abs/1810.04805 **

**[3] Time2Vec:学习时间的向量表示法【https://arxiv.org/abs/1907.05321 **

[4]你所需要的只是关注https://arxiv.org/abs/1706.03762

基于深度学习的股票价格预测

原文:https://towardsdatascience.com/stock-price-prediction-based-on-deep-learning-3842ef697da0?source=collection_archive---------2-----------------------

照片由杰米街Unsplash

机器学习如何用于投资?

众所周知,如果人们能够破解咒语成功预测股票价格,股票市场就是一个可以发财的地方。尽管在大多数情况下不可能准确预测股票价格。所以,问题来了,如果人类可以估计并考虑所有因素来预测股票的走势或未来价值,为什么机器不能?或者,换句话说,我们如何让机器预测一只股票的价值?长期以来,全世界的科学家、分析师和研究人员一直在试图设计一种方法来回答这些问题。

在这篇文章中,我将尝试展示一种所谓的算法交易方法。这是一个完全基于研究目的的方法。请不要基于这种算法进行投资。那么,我们开始吧。

整个想法

股票价格可能取决于当前世界和股票市场中的几个因素。我们将尝试考虑两个主要因素的组合:

  1. 其他公司股价的影响和相关性,即其他公司股价的涨跌如何影响特定目标公司的股价
  2. 目标公司过去的业绩和记录

我看过几个博客,大多关注其中一个因素,主要是第二个因素。我认为,如果我们能设法将这两个因素都考虑进去,我们就能使我们的预测器更加可靠。

因此,我尝试使用三种深度学习模型的组合来实现这一点。首先,基于神经网络的回归模型考虑了其他公司对目标公司的影响。其次,一个递归神经网络模型来研究目标公司的过去行为并相应地给出结果。为此,我使用了 LSTM 层。最后,一个人工神经网络,接受他们的预测,并帮助达成一个坚定和稳健的结论。

资料组

在本文中,我们将使用标准普尔 500 公司数据库,尽管我只使用了 200 家公司的详细信息。我用网络清理从维基百科页面收集了 S&P 名单。我用这个作为一个来源,因为它是实时更新的。我在一些博客里看到过这个方法,所以我也用过。这似乎是一个可靠的来源。

import bs4 as bs
import pickle
import requestsdef save_tickers():
 resp=requests.get('[https://en.wikipedia.org/wiki/List_of_S%26P_500_companies'](https://en.wikipedia.org/wiki/List_of_S%26P_500_companies'))
 soup=bs.BeautifulSoup(resp.text)
 table=soup.find('table',{'class':'wikitable sortable'})
 tickers=[]
 for row in table.findAll('tr')[1:]:
  ticker=row.findAll('td')[0].text[:-1]
  tickers.append(ticker)with open("tickers.pickle",'wb') as f:
  pickle.dump(tickers, f)return tickerssave_tickers()

这个代码将帮助你放弃 500 强公司的股票。

然后我用熊猫网络数据阅读器从雅虎收集了他们的详细信息。

import bs4 as bs
import pickle
import requests
import datetime as dt
import os
import pandas as pd
import pandas_datareader.data as webdef fetch_data():
 with open("tickers.pickle",'rb') as f:
   tickers=pickle.load(f)if not os.path.exists('stock_details'):
  os.makedirs('stock_details')
 count=200start= dt.datetime(2010,1,1)
 end=dt.datetime(2020,6,22)
 count=0
 for ticker in tickers:
  if count==200:
   break
  count+=1
  print(ticker)

  try:
    df=web.DataReader(ticker, 'yahoo', start, end)
    df.to_csv('stock_details/{}.csv'.format(ticker))
  except:
    print("Error")
    continuefetch_data()

这段代码将有助于使用 web 阅读器从 Yahoo 收集数据。我保留了 200 个,因为我只想使用 200 个公司详细信息。在这 200 家公司中,我们将有一个目标公司和 199 家公司,这将有助于达成对我们的目标公司的预测。

该代码将生成一个“stock_details”文件夹,其中包含从 2010 年 1 月 1 日到 2020 年 6 月 22 日的 200 份公司详细信息。

文件

每个细节文件都将被保存在它的股票代码中。我选择了亚马逊作为我的目标股票。因此,我将尝试预测亚马逊的股票价格。它的股票代码是 AMZN。

那么,让我们来看看细节文件的结构。

结构

这是结构。它将“日期”作为索引特征。“高”表示一天中的最高值。“低”表示最低。“开盘”是开盘价,“收盘”是当天的收盘价格。现在,有时公司会规定接近值。因此,最终值是“调整收盘”值,如果股票价格不受管制,它与“收盘”值相同。“交易量”是指该日该公司的股票交易量。

我们将把每只股票的这种“可调接近”价值视为每只股票对我们目标股票的贡献特征。因此,我们将把每只股票的 Adj Close 重命名为相应的股票代码,并将其包含在我们的特性集中。

import os
import pandas as pd
import pickledef compile():
 with open("tickers.pickle",'rb') as f:
   tickers=pickle.load(f)main_df=pd.DataFrame()for count,ticker in enumerate(tickers):
  if 'AMZN' in ticker:
   continue
  if not os.path.exists('stock_details/{}.csv'.format(ticker)):
   continue
  df=pd.read_csv('stock_details/{}.csv'.format(ticker))
  df.set_index('Date',inplace=True)df.rename(columns={'Adj Close': ticker}, inplace=True)
  df.drop(['Open','High','Low',"Close",'Volume'],axis=1,inplace=True)if main_df.empty:
   main_df=df
  else:
   main_df=main_df.join(df,how='outer')print(main_df.head())
 main_df.to_csv('Dataset_temp.csv')compile()

这个代码片段将帮助我们选择除了我们的目标股票 AMZN 之外的每只股票的调整后收盘列,将该列重命名为 ticker,并将其合并到我们的功能集中。

特征文件的结构

它会产生一个这样的特性集。日期是索引,与日期相对应的是每个收报机的“Adj Close”值。现在,我们将看到最初有几个空列。这是因为这些公司在 2010 年还没有开始参与股市。这将给我们一个包含 199 个公司值和日期的 200 列的特性集。

现在,让我们关注我们的目标股票 AMZN 股票。如果我们开始可视化目标股票的每个给定列值,我们将获得这些值。

分别调整近、低和高可视化

现在,让我们用蜡烛线符号来想象我们的股票。我用的是熊猫 0.24.2 版本。可能存在一个问题,因为在当前版本中,此模块已被折旧。

import datetime as dt
import matplotlib.pyplot as plt
from matplotlib import style
from mpl_finance import candlestick_ohlc
import matplotlib.dates as mdates
import pandas as pd
df=pd.read_csv('stock_details/AMZN.csv',index_col=0,parse_dates=True)
df_ohlc= df['Adj Close'].resample('10D').ohlc()
df_volume=df['Volume'].resample('10D').sum()
df_ohlc.reset_index(inplace=True)
df_ohlc['Date']=df_ohlc['Date'].map(mdates.date2num)ax1=plt.subplot2grid((6,1), (0,0), rowspan=5, colspan=1)
ax2=plt.subplot2grid((6,1), (5,0), rowspan=1, colspan=1 , sharex=ax1)
ax1.xaxis_date()candlestick_ohlc(ax1,df_ohlc.values, width=2, colorup='g')
ax2.fill_between(df_volume.index.map(mdates.date2num),df_volume.values,0)plt.show()

这段代码将为我们提供烛台符号。

亚马逊股票的蜡烛棒符号

现在,让我们设计一些特征来帮助我们预测我们的目标。

我们将计算 50 移动平均线。这个特性被很多交易者用来做预测。

df['Moving_av']= df['Adj Close'].rolling(window=50,min_periods=0).mean()

这个片段将帮助我们生成移动平均线。实际上,它是第 I 个指数的“Adj Close”值的 i-50 到 I 值的平均值。

移动平均图

现在,我们将尝试获得另外两个特征,即我们股票的成交量增长率和调整后收盘价增长率

i=1
rate_increase_in_vol=[0]
rate_increase_in_adj_close=[0]while i<len(df):
    rate_increase_in_vol.append(df.iloc[i]['Volume']-df.iloc[i-1]['Volume'])
    rate_increase_in_adj_close.append(df.iloc[i]['Adj Close']-df.iloc[i-1]['Adj Close'])
    i+=1

df['Increase_in_vol']=rate_increase_in_vol
df['Increase_in_adj_close']=rate_increase_in_adj_close

这个片段将帮助我们获得这些特性。

调整后收盘增长率和成交量增长率

现在,我们的目标股票的特征文件已经准备好了。

目标库存的特征文件结构

现在,我们将这两个特性文件合并成主特性集。

Index(['High', 'Low', 'Open', 'Close', 'Volume', 'Adj Close', 'Moving_av',
       'Increase_in_vol', 'Increase_in_adj_close', 'MMM',
       ...
       'FITB', 'FE', 'FRC', 'FISV', 'FLT', 'FLIR', 'FLS', 'FMC', 'F', 'Date'],
      dtype='object', length=207)

这些是我们主要特性集的列。

它有 207 列,其中 200 列来自其他公司列表,7 列来自我们的目标股票特性集,锚定在日期列上。所以,我们有 207 列。

回归

在这一部分,我们将研究其他股票对我们的目标股票的影响。我们将尝试预测亚马逊股票的最高价、最低价、开盘价和收盘价。

首先,让我们分析我们的数据。

回归相关图。

在这里,我们可以看到我们已经发现了一些相关性。

回归直方图。

因此,从我们的图来看,很明显,我们的数据集中会有一些相关性。因此,接下来,我们从训练数据集中删除开盘、收盘、盘高和盘低值,并将它们用作目标标签或值集。我们还删除了数量和日期,因为它们没有相关性。

from sklearn.model_selection import train_test_split
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.3)

我们把我们的组分成训练组和测试组。

from tensorflow.keras.callbacks import ModelCheckpoint
from tensorflow.keras.models import Sequential
from tensorflow.keras.layers import Dense, Activation, Flatten
from sklearn.model_selection import train_test_split
from sklearn.ensemble import RandomForestRegressor
from sklearn.metrics import mean_absolute_error 
from sklearn.metrics import accuracy_scoredef model():
    mod=Sequential()
    mod.add(Dense(32, kernel_initializer='normal',input_dim = 200, activation='relu'))
    mod.add(Dense(64, kernel_initializer='normal',activation='relu'))
    mod.add(Dense(128, kernel_initializer='normal',activation='relu'))
    mod.add(Dense(256, kernel_initializer='normal',activation='relu'))
    mod.add(Dense(4, kernel_initializer='normal',activation='linear'))

    mod.compile(loss='mean_absolute_error', optimizer='adam', metrics=['accuracy','mean_absolute_error'])
    mod.summary()

    return mod

这是我们将用于回归的模型。

回归的模型摘要

可以使用以下代码片段运行它:

from tensorflow.keras.wrappers.scikit_learn import KerasRegressor
regressor = KerasRegressor(build_fn=model, batch_size=16,epochs=2000)
import tensorflow as tf
callback=tf.keras.callbacks.ModelCheckpoint(filepath='Regressor_model.h5',
                                           monitor='mean_absolute_error',
                                           verbose=0,
                                           save_best_only=True,
                                           save_weights_only=False,
                                           mode='auto')
results=regressor.fit(X_train,y_train,callbacks=[callback])

为此,我使用了 Keras 回归器。保存了最佳权重并使用了 2000 个纪元。平均绝对误差是我们的损失函数。删除列后,我们的输入为 200。我们将为每个输入获得四个值,高、低、开、闭。

y_pred= regressor.predict(X_test)
import numpy as np
y_pred_mod=[]
y_test_mod=[]for i in range(0,4):
    j=0
    y_pred_temp=[]
    y_test_temp=[]

    while(j<len(y_test)):
        y_pred_temp.append(y_pred[j][i])
        y_test_temp.append(y_test[j][i])
        j+=1

    y_pred_mod.append(np.array(y_pred_temp))
    y_test_mod.append(np.array(y_test_temp))

这给了我们测试集的预测值。这个代码片段有助于以解析的格式获取它们。

分别为高、低、开、闭的回归结果。

现在,我们可以看到我们的模型表现得相当好,考虑到大多数点位于回归线上,很少有异常值。

这里我们完成了回归部分。接下来,我们将移动到 RNN 部分。

递归神经网络

我们将使用 RNN 来分析我们的目标股票。所以我们将只使用目标库存特征文件。现在,这里我们将使用 LSTM 层的工作 RNN 原则,但工作在一个门控的方法。

图片由 Colah

LSTM 有助于 RNN 长时间保持记忆,解决渐变消失和爆炸问题。这里就不详细说了。详情你可以在这里找到。

这是我们 LSTM 的数据集。

现在,我们需要预测高,低,开放,关闭。因此,现在,我们将删除“日期”,因为它没有相关性。

High         Low        Open       Close    Volume   Adj Close  \
0  137.279999  134.520004  137.089996  134.520004   4523000  134.520004   
1  136.610001  133.139999  136.250000  133.899994   7599900  133.899994   
2  135.479996  131.809998  133.429993  134.690002   8851900  134.690002   
3  134.729996  131.649994  134.600006  132.250000   7178800  132.250000   
4  132.320007  128.800003  132.009995  130.000000  11030200  130.000000       Moving_av  Increase_in_vol  Increase_in_adj_close  
0  134.520004              0.0               0.000000  
1  134.209999        3076900.0              -0.620010  
2  134.370000        1252000.0               0.790009  
3  133.840000       -1673100.0              -2.440002

现在,我们的输入将是这个数据帧的值。因此,我们的输入将有 9 列,相应地,我们的输出将有 4 列,高,低,开放,关闭我们的目标股票。

我们需要为 LSTM 模型创建训练和测试集。

为此,我们将把长度为 2636 条记录的数据分成两部分。我们将使用 0–2200 条记录作为训练集,2200–2636 条记录作为测试集。我们从我们的训练集中选择包含 4 个目标列的目标集。

df_train=df_main[:2200]
df_target=df_train[['High','Low','Open','Close']]

现在,我们缩放数据以使我们的模型易于收敛,因为我们的数据集中有大量不同的值。

sc = MinMaxScaler(feature_range = (0, 1))
target_set=df_target.values
train_set=df_train.values
training_set_scaled = sc.fit_transform(train_set)
target_set_scaled = sc.fit_transform(target_set)

这样,我们就获得了 LSTM 模型的定标数据。

LSTM 模型接受系列数据并产生输出。我们的 LSTM 是多对多的 RNN 模式。所以,我们需要为此产生一系列数据。为此,我们从第 50 个索引开始,并移动到训练集的长度。我们在列表中添加了 0–49,即 50 个值。我们已经为我们所有的功能创建了这样的列表。

因此,我们的输入有(n x 50 x 9)维数据用于我们的训练集。我们有 9 个特性,每个特性都是 50 天的特性值列表。n 是从给定数据集获得的此类序列的数量。现在,我们的目标集是第 51 天目标列的值。

我们通过使用,

X_train = []
y_train = []
for i in range(50,len(train_set)):
    X_train.append(training_set_scaled[i-50:i,:])
    y_train.append(target_set_scaled[i,:])

X_train, y_train = np.array(X_train), np.array(y_train)

现在,让我们观察火车和目标组的形状。

print(X_train.shape)(2150, 50, 9)print(y_train.shape)(2150, 4)

让我们设计我们的模型。

from sklearn.metrics import accuracy_score
from tensorflow.keras.layers import BatchNormalization
import datetime as dt
from sklearn import model_selection
from sklearn.metrics import confusion_matrix
from sklearn.preprocessing import StandardScaler
from sklearn.model_selection import train_test_split
import numpy as np
import pandas as pd
from sklearn.preprocessing import MinMaxScaler
from tensorflow.keras.models import Sequential
from tensorflow.keras.layers import Dense
from tensorflow.keras.layers import LSTM
from tensorflow.keras.layers import Dropoutdef model():
    mod=Sequential()
    mod.add(LSTM(units = 64, return_sequences = True, input_shape = (X_train.shape[1], 9)))
    mod.add(Dropout(0.2))
    mod.add(BatchNormalization())
    mod.add(LSTM(units = 64, return_sequences = True))
    mod.add(Dropout(0.1))
    mod.add(BatchNormalization())

    mod.add((LSTM(units = 64)))
    mod.add(Dropout(0.1))
    mod.add(BatchNormalization())
    mod.add((Dense(units = 16, activation='tanh')))
    mod.add(BatchNormalization())
    mod.add((Dense(units = 4, activation='tanh')))
    mod.compile(loss='mean_squared_error', optimizer='adam', metrics=['accuracy','mean_squared_error'])
    mod.summary()

    return mod

这是我们的 LSTM 模型。我在这里用过 Keras 层。损失函数是均方误差。我们已经使用了亚当优化。

LSTM 模型形状

为了训练我们的模型,我们将使用这个片段。

import tensorflow as tf
callback=tf.keras.callbacks.ModelCheckpoint(filepath='./RNN_model.h5',
                                           monitor='mean_squared_error',
                                           verbose=0,
                                           save_best_only=True,
                                           save_weights_only=False,
                                           mode='auto',
                                           save_freq='epoch')
RNN_model.fit(X_train, y_train, epochs = 2000, batch_size = 32,callbacks=[callback])

我们的模型现在已经训练好了。

让我们专注于测试部分。

我们的测试值有 2200 到 2636 条记录。因此,我们通过选择股票的开盘价、收盘价、最高价、最低价这四列来获得目标值。

df_test=df_main[2200:]
df_target_test=df_test[['High','Low','Open','Close']]
target_set_test=df_target_test.values
test_set=df_test.values

为了进行测试,我们还需要转换我们的测试特征数据集,并为该数据集形成一系列 50 个特征值,就像我们在训练集的情况下所做的那样。

predicted_stock_price = RNN_model.predict(X_test)
predicted_stock_price = sc.inverse_transform(predicted_stock_price)
print(predicted_stock_price)

这个代码片段有助于获得我们想要的预测结果。

array([[1690.364 , 1610.5382, 1643.4277, 1643.8912],
       [1687.384 , 1607.5323, 1640.3225, 1640.7366],
       [1688.7346, 1608.965 , 1641.6777, 1642.0984],
       ...,
       [2567.6138, 2510.703 , 2522.8406, 2538.787 ],
       [2576.5056, 2519.5195, 2531.803 , 2547.9304],
       [2578.5886, 2521.65  , 2533.9177, 2550.0896]], dtype=float32)

结果就是这样获得的。

现在,如果我们用目标列的实际值相应地绘制它们,我们将获得下面的图。

LSTM 取得了成果

如果我们观察,有 4 行,这是因为我们有 4 列作为目标。我们可以看到模型在大部分地方获得了曲线模式。

现在,如果我们分别绘制它们,我们将获得如下 4 幅图。

RNN 的高、低、开和关

因此,我们使用 LSTM,基于股票的过去价值来结束对单个目标股票的研究。现在,我们转到封面或结论部分。

覆盖人工神经网络

现在,这是结论部分。我们使用两个排他性模型研究了可能影响公司股票的两个不同领域,得出了两个不同的结果。现在,我们将尝试合并两个结果。我们将通过合并获得的结果并在整个过程中训练我们的人工神经网络来做到这一点。

对于上面讨论的两个模型,我们有 4 个目标列。对于最后的结论,我们将尝试只预测两列,我们的目标股票的高点和低点。

因此,为此,我们使用这两种模型来预测我们的完整数据集。回归模型产生 2636 个预测值。

代码片段和结果如下:

saved_model_regressor=tf.keras.models.load_model('Regressor_model.h5')
Regressor_prediction=saved_model_regressor(X)
import numpy as np
y_pred_mod=[]for i in range(0,4):
    j=0
    y_pred_temp=[]

    while(j<len(Regressor_prediction)):
        y_pred_temp.append(Regressor_prediction[j][i])

        j+=1

    y_pred_mod.append(np.array(y_pred_temp))
Y_pred=pd.DataFrame(list(zip(y_pred_mod[0],y_pred_mod[1],y_pred_mod[2],y_pred_mod[3])),columns=['High_regress','Low_regress','Open_regress','Close_regress'])

这是片段。它创建一个长度为 2636 的数据帧,包含四个预测值列。

Y_pred.head()

我们将其保存为 CSV 格式以备将来使用。

现在,类似地,我们为 LSTM 网络做这个。我们为前 50 个值获取一个值,因为前 50 个值是我们的第一个测试集。因此,除法是 0–49 获得第一个值,1–50 获得第二个值,依此类推。我们从 RNN 总共获得了 2586 个值。

片段:

saved_model_RNN=tf.keras.models.load_model('RNN_model.h5')
RNN_prediction=saved_model_RNN.predict(X_test)
import numpy as np
y_pred_mod=[]for i in range(0,4):
    j=0
    y_pred_temp=[]

    while(j<len(RNN_prediction)):
        y_pred_temp.append(RNN_prediction[j][i])

        j+=1

    y_pred_mod.append(np.array(y_pred_temp))
Y_pred=pd.DataFrame(list(zip(y_pred_mod[0],y_pred_mod[1],y_pred_mod[2],y_pred_mod[3])),columns=['High_RNN','Low_RNN','Open_RNN','Close_RNN'])

该代码片段使用目标值的 RNN 预测生成一个数据帧。

我们对两个模型的预测都准备好了。我们需要从回归预测中删除 0–50 指数,因为这些值没有 RNN 预测。我们现在准备合并结果。

因此,在合并结果之后,我们获得了具有 8 列的 2586 个值的数据帧。

df**=**pd.concat([df1,df2],axis**=**1)df.head()

这是连接的结果。

整个事情将成为我们的人工神经网络模型的特征集。那么,我们的目标是什么?我们的目标集合将由原始数据集中亚马逊目标股票的原始高值和低值组成。

df1=pd.read_csv("dataset_target_2.csv")
target_high=[]
target_low=[]
i=50
while i<len(df1):
    target_high.append(df1.iloc[i]['High'])
    target_low.append(df1.iloc[i]['Low'])
    i+=1
df['Target_high']=target_high
df['Target_low']=target_lowdf.to_csv('feature.csv',index=False)

这个代码片段有助于合并我们特性集中的所有列。有 10 列。来自两个模型的 8 个特征列和目标股票的高低值作为目标值。

我们的新特性集如下所示。

这是我们的特征直方图。这里,我们也从图中得到了很好的相关性。现在让我们设计和训练我们的人工神经网络模型。

X_Df=df_main[['High_regress','Low_regress','Open_regress','Close_regress','High_RNN','Low_RNN','Open_RNN','Close_RNN']].values
y_Df=df_main[['Target_high','Target_low']].values
from sklearn.model_selection import train_test_split
X_train, X_test, y_train, y_test = train_test_split(X_Df, y_Df, test_size=0.3)

现在,让我们看看我们的模型设计。

from tensorflow.keras.callbacks import ModelCheckpoint
from tensorflow.keras.models import Sequential
from tensorflow.keras.layers import Dense, Activation, Flatten
from sklearn.model_selection import train_test_split
from sklearn.ensemble import RandomForestRegressor
from sklearn.metrics import mean_absolute_error 
from sklearn.metrics import accuracy_scoredef model():
    mod=Sequential()
    mod.add(Dense(32, kernel_initializer='normal',input_dim = 8, activation='relu'))
    mod.add(Dense(64, kernel_initializer='normal',activation='relu'))
    mod.add(Dense(128, kernel_initializer='normal',activation='relu'))
    mod.add(Dense(2, kernel_initializer='normal',activation='linear'))

    mod.compile(loss='mean_absolute_error', optimizer='adam', metrics=['accuracy','mean_absolute_error'])
    mod.summary()

    return mod

这是我们的人工神经网络模型。正如我们看到的,我们模型的输入维度是 8。这是因为我们输入了 8 个特征列,其中 4 列来自每个模型的输出。输出层有两个节点,分别用于目标股票的高低栏。

我使用损失函数作为平均绝对误差,优化器作为亚当的优化器。

我们可以使用下面的代码片段运行模型:

import tensorflow as tf
model_ANN=model()
callback=tf.keras.callbacks.ModelCheckpoint(filepath='ANN_model.h5',
                                           monitor='mean_absolute_error',
                                           verbose=0,
                                           save_best_only=True,
                                           save_weights_only=False,
                                           mode='auto')
results=model_ANN.fit(X_train,y_train, epochs = 2000, batch_size = 32,callbacks=[callback])

在我们训练模型之后,我们将使用预测的模型来预测我们的测试集并检查性能。

y_pred=model_ANN.predict(X_test)
import numpy as np
y_pred_mod=[]
y_test_mod=[]for i in range(0,2):
    j=0
    y_pred_temp=[]
    y_test_temp=[]

    while(j<len(y_test)):
        y_pred_temp.append(y_pred[j][i])
        y_test_temp.append(y_test[j][i])
        j+=1

    y_pred_mod.append(np.array(y_pred_temp))
    y_test_mod.append(np.array(y_test_temp))
df_res=pd.DataFrame(list(zip(y_pred_mod[0],y_pred_mod[1],y_test_mod[0],y_test_mod[1])),columns=['Pred_high','Pred_low','Actual_high','Actual_low'])

我们的预测器为每个特征记录预测两个值。因此,这个代码片段有助于获得两列的预测值和测试值,并将它们表示为 Dataframe。

现在,让我们绘图并检查。

import matplotlib.pyplot as pltax1=plt.subplot2grid((4,1), (0,0), rowspan=5, colspan=1)ax1.plot(df_res_2.index, df_res_2['Pred_high'], label="Pred_high")
ax1.plot(df_res_2.index, df_res_2['Actual_high'], label="Actual_high")plt.legend(loc="upper left")
plt.xticks(rotation=90)plt.show()

这个片段有助于查看预测的和实际的变化。

我们目标设定变化的高低。

如果我们想检查我们的模特表演。我们可以通过使用下面的代码片段来做到这一点:

fig, ax = plt.subplots()
ax.scatter(y_test_mod[0], y_pred_mod[0])
ax.plot([y_test_mod[0].min(),y_test_mod[0].max()], [y_test_mod[0].min(), y_test_mod[0].max()], 'k--', lw=4)
ax.set_xlabel('Measured')
ax.set_ylabel('Predicted')
plt.show()

这将获得:

我们模型的低柱和高柱。

这些线性图表明,我们的模型预测值和实际值之间存在线性关系。

因此,我们的复合模型在预测我们的目标亚马逊股票的高低列值方面做得相当好。因此,我们在这里结束了我们的整个目的。

结论

在本文中,我们看到了如何基于复合神经网络构建算法交易模型。希望这篇文章能有所帮助。

整个 Github 代码是:这里

请在这里找到关于这个主题的进一步任务:。

posted @ 2024-10-16 09:00  绝不原创的飞龙  阅读(209)  评论(0)    收藏  举报