强化学习中的演员评论介绍
直观的方法理解强化学习中最重要的方法之一。
Photo by Fatih Kılıç on Unsplash
更新:学习和练习强化学习的最好方式是去 http://rl-lab.com
概观
在深入探讨演员评论家的细节之前,让我们提醒自己一下政策梯度。
基于策略的强化学习意味着什么?简单地说,想象一个机器人发现自己处于某种状况,但这种状况似乎与它以前经历过的事情相似。
因此,基于策略的方法说:既然我过去在这种特定情况下采取了行动 (a) ,那么让我们这次也尝试同样的行动。
PS。不要把相似的情况和相同的状态混为一谈,在相似的情况下,机器人或智能体处于一些新的状态,类似于它以前经历过的,而不一定是完全相同的状态。
Left: The robot faces a barrier, but he has seen something like that before and it knows what to do in this situation. Middle: The robot took the same action it took in such situation. Right: The robot is wondering hindsight if there were more efficient way to overcome the barrier.
在上面的图像中,一个机器人面对着一个壁垒,但它似乎以前见过这种情况,所以像以前一样,它用火箭跳过它。
然而,这一次可能不是完美的行动!
可能发生的情况是,有一个简单的触发器来打开门,从而节省宝贵的能量,这些能量可能在以后被使用。
基于这个概念,机器人必须做一些回顾性的回顾,以检查那个动作(使用他的火箭)有多有用。
现在我们需要把它转化成一个数学方程。
目标
请记住,我们的目标是始终获得最高的回报。
为了能够做到这一点,我们必须定义一个收集这些奖励的函数,并对其进行优化,以最大化这些奖励。
另一个同样重要的点是,我们将使用神经网络来完成这项工作。
所以我们要做的是找到神经网络的一组权重𝜽,帮助我们最大化目标函数。
**重要!**注意以下陷阱:如果你熟悉深度学习和神经网络,你更习惯于寻找使误差最小的权重。在这种情况下,我们不这样做,相反,我们希望最大化一个目标函数。意识不到这一点会让你陷入困惑。
从基于政策的梯度中,我们找到了一个目标函数,并按如下方式计算其梯度(有关该等式如何形成的详细信息,请查看政策梯度逐步):
J(𝜽)是依赖于𝜽的目标函数
m 是执行的情节(这里称为轨迹)的数量
𝛑是由𝜽参数化的政策,这意味着当𝜽变化时,政策将受到影响。请记住,策略给出了当代理处于特定状态时采取特定操作的概率。
𝞽ⁱ是执行的第 I 集或轨迹。
R(𝞽ⁱ)是轨迹𝞽ⁱ.的回报(总报酬)
T 是轨迹𝞽ⁱ.的步数
这个方程告诉我们的是,J(𝜽的梯度是所有 m 个轨迹的平均值,其中每个轨迹是组成它的步骤的总和。在每一步,我们计算保单𝛑对数的导数,并将其乘以回报 R(𝞽ⁱ).
换句话说,我们正试图找出𝜽.之后政策的变化返回 R(𝞽ⁱ的使用)是为了放大(或减小)这些变化。这意味着如果 R(𝞽ⁱ)很高,它将提高结果,并使神经网络确信𝜽在正确的方向上前进。
然而,返回 R(𝞽ⁱ).有一个问题
退货问题
假设我们在一个轨迹中,早期的回报是负的,而接近轨迹末端的回报是正的,这样总 R = 0!
在这种情况下,∇J(𝜽)将为 0,并且神经网络将不会从这种情况中学习𝜽的任何新值。
为了解决这个问题,我们在每一步都使用了折扣奖励,从当前状态开始,直到轨迹结束。
这将给我们一个新版本的∇J(𝜽):
现在神经网络将能够从轨迹中学习。还有更大的改进空间,但我们需要做更多的数学计算。
数学来了
如果我们深入思考呢?
Rt(从步骤 t 开始返回)还不错,但是我们不确定 Rt 的值是多少,好到可以考虑?!
以文章开头的机器人为例,使用火箭跳跃是一个好的解决方案吗?我们怎么知道?有多好?
同样,如果你拿 100 米短跑运动员 10 秒的成绩举例,他做得好还是不好?如果它是好的,那么它有多好?
赋予这个数字意义的一种方法是将其与一个参考值进行比较,或者我们称之为基线。
基线可以有几种形式,其中一种是预期绩效,或者说是平均绩效。如果短跑运动员得了 10 分,但平均分是 12 分,那么他做得很好,相反,如果平均分是 8 分,那么他做得很差。
让我们将基线表示为 b 𝑡,目标函数的梯度变为:
现在让我们想一想,R𝑡是在步骤 t 采取行动 的回报,另一方面 b 𝑡代表所有行动结果的平均值。
这看起来很奇怪地类似于 Q(s,a)是在状态采取的行动的值,以及 V(s)是状态的值,或者是在状态采取的所有行动(引起的)的平均值。****
该等式可以改写为
如果我们仔细观察上面的等式,我们会看到𝛑(a|s)是执行动作的(记住𝛑是动作的概率是在状态时获得的),而 Q(s,a)-V(s)告诉我们它有多有价值。****
换句话说,𝛑(a|s 是演员,Q(s,a)-V(s)是评论家。
批评家的计算可以有不同的味道:
- 演员兼评论家
- 优势演员兼评论家
- TD 演员兼评论家
- 演员兼评论家
- 天生的演员兼评论家
相关文章
使用 Python3 介绍 AWS Lambda、Layers 和 boto3
面向数据科学家的无服务器方法
Photo by Daniel Eledut on Unsplash
Amazon Lambda 可能是当今最著名的无服务器服务,提供低成本,几乎不需要云基础设施治理。它提供了一个相对简单明了的平台,用于在不同的语言上实现功能,比如 Python、Node.js、Java、C#等等。
亚马逊 Lambda 可以通过 AWS 控制台或者 AWS 命令行界面进行测试。Lambda 的一个主要问题是,一旦函数和触发器变得更复杂,设置起来就变得很棘手。本文的目标是向您展示一个易于理解的教程,让您用外部库配置第一个 Amazon Lambda 函数,并做一些比打印“Hello world!”更有用的事情。
我们将使用 Python3、boto3 和 Lambda 层中加载的其他一些库来帮助我们实现我们的目标,将 CSV 文件加载为 Pandas 数据帧,进行一些数据辩论,并将报告文件中的指标和图表保存在 S3 存储桶中。虽然使用 AWS 控制台来配置您的服务不是在云上工作的最佳实践方法,但我们将展示使用控制台的每个步骤,因为这对初学者来说更便于理解 Amazon Lambda 的基本结构。我相信在阅读完这篇教程之后,你会对将部分本地数据分析管道迁移到 Amazon Lambda 有一个很好的想法。
设置我们的环境
在我们开始使用 Amazon Lambda 之前,我们应该首先设置我们的工作环境。我们首先使用 conda (也可以使用 pipenv )(2)为项目(1)和环境 Python 3.7 创建一个文件夹。接下来,我们创建两个文件夹,一个保存 Lambda 函数的 python 脚本,另一个构建 Lambda 层(3)。我们将在本文后面更好地解释 Lambda 层的组成。最后,我们可以创建文件夹结构来构建 Lambda 层,这样它就可以被 Amazon Lambda (4)识别。我们创建的文件夹结构将帮助您更好地理解 Amazon Lambda 背后的概念,并组织您的函数和库。
# 1) Create project folder
**mkdir medium-lambda-tutorial**# Change directory
**cd medium-lambda-tutorial/**# 2) Create environment using conda **conda create --name lambda-tutorial python=3.7
conda activate lambda-tutorial**# 3) Create one folder for the layers and another for the
# lambda_function itself
**mkdir lambda_function lambda_layers**# 4) Create the folder structure to build your lambda layer
**mkdir -p lambda_layers/python/lib/python3.7/site-packages
tree** .
├── lambda_function
└── lambda_layers
└── python
└── lib
└── python3.7
└── site-packages
亚马逊 Lambda 基本结构
在尝试实现我的第一个 Lambda 函数时,我遇到的一个主要问题是试图理解 AWS 调用脚本和加载库所使用的文件结构。如果您按照默认选项“从头开始创作”(图 1)来创建 Lambda 函数,那么您最终会得到一个文件夹,其中包含您的函数名称和名为 lambda_function.py 的 Python 脚本。
Figure 1. Creating a Lambda function using Author from scratch mode.
lambda_function.py 文件结构非常简单,代码如下:
import jsondef lambda_handler(event, context):
# TODO implement
return {
'statusCode': 200,
'body': json.dumps('Hello from Lambda!')
}
这 8 行代码是理解 Amazon Lambda 的关键,所以我们将逐行解释它。
import json
:你可以导入 Python 模块在你的函数上使用,AWS 为你提供了一个已经在 Amazon Lambda 上构建的可用 Python 库的列表,比如json
等等。当你需要不可用的库时,问题就出现了(我们稍后将使用 Lambda 层来解决这个问题)。def lambda_handler(event, context):
这是主函数当你运行服务时,你的 Amazon Lambda 会调用这个函数。它有两个参数event
和context
。第一个用于传递可以在函数本身上使用的数据(稍后将详细介绍),第二个用于提供运行时和元数据信息。- 这里就是奇迹发生的地方!您可以使用
lambda_handler
函数的主体来实现任何您想要的 Python 代码。 return
函数的这一部分将返回一个默认字典,其中statusCode
等于 200,而body
则返回一个“Hello from Lambda”。您可以在以后将这个返回更改为任何适合您需要的 Python 对象。
在运行我们的第一个测试之前,有必要解释一下与 Amazon Lambda 相关的一个关键话题: 触发器 。触发器基本上是调用 Lambda 函数的方式。有很多方法可以使用事件来设置触发器,比如将文件添加到 S3 桶,更改 DynamoDB 表上的值,或者通过 Amazon API Gateway 使用 HTTP 请求。你可以很好地集成你的 Lambda 函数,以供各种各样的 AWS 服务调用,这可能是 Lambda 提供的优势之一。我们可以这样做来与你的 Python 代码集成的一个方法是使用 boto3 来调用你的 Lambda 函数,这是我们将在本教程后面使用的方法。
正如您所看到的,AWS 提供的模板结构非常简单,您可以通过配置一个测试事件并运行它来测试它(图 2)。
Figure 2. Running your first Amazon Lambda test.
由于我们没有对 Lambda 函数的代码做任何修改,测试运行了这个过程,我们收到了一个绿色的警告,描述了成功的事件(图 3)。
Figure 3. A successful call of our Lambda Function.
图 3 展示了 Lambda 调用结果的布局。在上面部分,您可以看到返回语句中包含的字典。下面是摘要部分,我们可以看到一些与 Lambda 函数相关的重要指标,如请求 ID、函数持续时间、计费持续时间以及配置和使用的内存量。我们不会深入讨论 Amazon Lambda 定价,但重要的是要知道它的收费依据是:
- 功能运行的持续时间(四舍五入到最接近的 100 毫秒)
- 使用的内存/CPU 数量
- 请求的数量(调用函数的次数)
- 进出 Lambda 的数据传输量
总的来说,测试和使用它真的很便宜,所以在小工作负载下使用 Amazon Lambda 时,您可能不会有计费问题。
与定价和性能相关的另一个重要细节是 CPU 和内存的可用性。您选择运行您的函数的内存量,并且“ Lambda 与配置的内存量成比例地线性分配 CPU 能力”。
在图 3 的底部,您可以看到日志输出会话,在这里您可以检查 Lambda 函数打印的所有执行行。在 Amazon Lambda 上实现的一个很棒的特性是它与 Amazon CloudWatch 集成在一起,在那里你可以找到你的 Lambda 函数生成的所有日志。关于监控执行和日志的更多细节,请参考 Casey Dunham great Lambda 文章。
我们已经介绍了 Amazon Lambda 的基本功能,因此在接下来的几节课中,我们将增加任务的复杂性,向您展示一个真实世界的使用,提供一些关于如何在日常基础上运行无服务器服务的见解。
增加层次,拓展可能性
使用 Python 的一个好处是可以获得大量的库,帮助您实现快速解决方案,而不必从头开始编写所有的类和函数。如前所述,Amazon Lambda 提供了一个 Python 库列表,您可以将其导入到您的函数中。当您不得不使用不可用的库时,问题就出现了。一种方法是将这个库安装在你的lambda_function.py
文件所在的文件夹中,压缩这些文件,然后上传到你的 Amazon Lambda 控制台。在本地安装库并在每次创建新的 Lambda 函数时上传库,这个过程可能是一项费力且不方便的任务。为了让您的生活更轻松,亚马逊为我们提供了将我们的库作为 Lambda 层上传的可能性,它由一个文件结构组成,您可以在其中存储库,将其独立加载到 Amazon Lambda,并在需要时在您的代码中使用它们。一旦你创建了一个 Lambda 层,它可以被任何其他新的 Lambda 函数使用。
回到我们组织工作环境的第一个会话,我们将使用在lambda_layer
文件夹中创建的文件夹结构在本地安装一个 Python 库 Pandas。
# Our current folder structure
.
├── lambda_function
└── lambda_layers
└── python
└── lib
└── python3.7
└── site-packages# 1) Pip install Pandas and Matplotlib locally
**pip install pandas -t lambda_layers/python/lib/python3.7/site-packages/.**# 2) Zip the lambda_layers folder
**cd lambda_layers**
**zip -r pandas_lambda_layer.zip ***
通过使用带参数-t
的pip
,我们可以指定要在本地文件夹(1)上安装库的位置。接下来,我们只需要压缩包含库(2)的文件夹,我们就有了一个准备作为层部署的文件。保持我们在开始时创建的文件夹的结构(python/lib/python 3.7/site-packages/)是很重要的,这样 Amazon Layer 就可以识别您的压缩包中包含的库。点击 AWS Lambda 控制台左侧面板上的“层”选项,然后点击“创建层”按钮创建一个新层。然后我们可以指定名称、描述和兼容的运行时(在我们的例子中是 Python 3.7)。最后,我们上传我们的压缩文件夹并创建层(图 4)。
Figure 4. Creating a Lambda Layer.
这花了不到一分钟的时间,我们的 Amazon 层已经准备好用于我们的代码了。回到 Lambda 函数的控制台,我们可以通过点击图层图标,然后点击“添加图层”(图 5)来指定要使用的图层。
Figure 5. Adding a layer to a Lambda function.
接下来,我们选择我们刚刚创建的层及其各自的版本(图 6)。从图 6 中可以看出,AWS 提供了一个 Lambda 层,其中包含随时可以使用的 Scipy 和 Numpy,因此如果您只需要这两个库中的一个,就不需要创建新的层。
Figure 6. Selecting our new Pandas Layer.
选择我们的熊猫层后,我们需要做的就是把它导入你的 Lambda 代码,因为它是一个已安装的库。
最后,我们开始编码吧!
现在我们已经准备好了环境和熊猫层,我们可以开始编写代码了。如前所述,我们的目标是创建一个 Python3 本地脚本(1),它可以使用定义的参数(2)调用 Lambda 函数,在位于 S3 (3)上的 CSV 上使用 Pandas 执行简单的数据分析,并将结果保存回同一个桶(4)(图 7)。
要让 Amazon Lambda 访问我们的 S3 存储桶,我们只需在控制台上的会话 执行角色 中添加一个角色。尽管 AWS 为您提供了一些角色模板,但我的建议是在 IAM 控制台上创建一个新的角色,以准确地指定 Lambda 函数所需的权限(图 8 的左侧面板)。
Figure 8. Defining the role and basic settings for Lambda function.
我们还将可用内存量从 128MB 更改为 1024MB,并将超时时间从 3 秒更改为 5 分钟(图 8 中的右图),以避免内存不足和超时错误。亚马逊 Lambda 限制RAM 内存总量为 3GB,超时为 15 分钟。因此,如果您需要执行高度密集的任务,您可能会发现问题。一种解决方案是将多个 Lambdas 链接到其他 AWS 服务,以执行分析管道的步骤。我们的想法不是对 Amazon Lambda 进行详尽的介绍,所以如果你想了解更多,请查看这篇来自艾毅的文章。
在展示代码之前,描述我们将在小项目中使用的数据集是很重要的。我选择了来自 Kaggle 的 Fifa19 球员数据集,这是一个 CSV 文件,描述了游戏中出现的球员的所有技能(表 1)。它有 18.207 行和 88 列,你可以从每个球员那里得到国籍,俱乐部,薪水,技能水平和更多的信息。我们下载了 CSV 文件,并上传到我们的 S3 桶(重命名为 fifa19_kaggle.csv )。
Table 1. The fifa19_kaggle.csv 20 first rows.
所以现在我们可以专注于我们的代码了!
正如我们在上面的脚本中看到的,前 5 行只是导入库。除了熊猫,其他所有的库都可以使用,而不必使用层。
接下来,我们有一个名为write_dataframe_to_csv_on_s3
(第 8 到 22 行)的附属函数,用于将熊猫数据帧保存到一个特定的 S3 桶中。我们将使用它来保存在分析过程中创建的输出数据帧。
我们代码中的另一个函数是 main lambda_handler,
,当我们调用 Lambda 时,这个函数将被调用。我们可以看到,lambda_handler
上的前 5 个赋值(第 28 到 32 行)是传递给event
对象的变量。
从第 35 行到第 41 行,我们使用 boto3 下载 s 3 存储桶上的 CSV 文件,并将其作为熊猫数据帧加载。
接下来,在第 44 行,我们使用 Dataframe 上的 group by 方法来聚合GROUP
列,并获得COLUMN
变量的平均值。
最后,我们使用函数write_dataframe_to_csv_on_s3
在指定的 S3 桶上保存df_groupby
,并返回一个以 statusCode 和 body 为键的字典。
正如之前在 Amazon Lambda 基本结构会话中所描述的,事件参数是一个对象,它携带了可用于lambda_handler
函数的变量,我们可以在配置测试事件时定义这些变量(图 9)。
Figure 9. Defining the variables on the test event.
如果我们运行这个测试,使用与测试 JSON 的 5 个键相关的正确值,我们的 Lambda 函数应该处理来自 S3 的 CSV 文件,并将结果 CSV 写回到桶中。
尽管在测试事件中使用硬编码的变量可以展示我们的 Lambda 代码的概念,但这不是调用函数的实际方法。为了解决这个问题,我们将创建一个 Python 脚本(invoke_lambda.py
)来使用 boto3 调用我们的 Lambda 函数。
我们将只使用三个库: boto3 、 json 和 sys 。从第 5 行到第 10 行,当通过命令行运行脚本时,我们使用sys.argv
来访问参数。
**python3 invoke_lambda.py <bucket> <csv_file> <output_file> <groupby_column> <avg_column> <aws_credentials>**
我们提供给invoke_lambda.py
的最后一个参数(aws_credentials)是一个 JSON 文件,其中包含我们访问 aws 服务的凭证。您可以使用 awscli 配置您的凭证,或者使用 IAM 生成密钥。
在我们的主函数invoke_lambda
中,我们使用 boto3 客户端来定义对 Amazon Lambda 的访问(第 38 行)。下一个名为payload
的对象是一个字典,包含了我们想要在 Lambda 函数中使用的所有变量。这些是可以使用event.get('variable').
访问的 Lambda 变量
最后,我们简单地用目标 Lambda 函数名、调用类型和携带变量的有效负载来调用client.invoke()
(第 54 行)。调用类型有三种 : 请求响应(默认)、到同步调用函数。保持连接打开,直到函数返回响应或超时";事件,异步调用 Lambda 或者当您需要验证用户信息时 DryRun 。对于我们的主要目的,我们将使用默认的 RequestResponse 选项来调用我们的 Lambda,因为它等待 Lambda 流程返回响应。由于我们在 Lambda 函数上定义了一个 try/except 结构,如果流程运行时没有错误,它将返回一个状态代码 200,并显示消息“Success!”,否则它将返回状态代码 400 和消息“错误,错误的请求!”。
当使用正确的参数运行时,我们的本地脚本invoke_lambda.py
需要几秒钟才能返回响应。如果响应是肯定的,状态代码为 200,那么您可以检查您的 S3 存储桶来搜索由 Lambda 函数生成的报告文件(表 2)。当我们使用“俱乐部”和“总体”两列进行分组以获得平均值时,我们显示了平均玩家总体技能水平最高的 20 个俱乐部。
Table 2. The first 20 rows of the output CSV file generated using our Lambda function.
最终考虑
希望这个快速介绍(没那么快!)帮助你更好地理解这种无服务器服务的具体细节。它可以帮助您在数据科学项目中尝试不同的方法。有关使用 AWS 的无服务器架构的更多信息,请查看 Eduardo Romero 的这篇精彩文章。
如果你觉得你需要更深入地了解 AWS Lambda,我最近发表了一篇文章,描述了 Lambda 背后的基础设施和它的一些其他功能。
非常感谢你阅读我的文章!
更多资源
** [## 为什么需要 Python 环境以及如何使用 Conda-protostar . space 管理它们
我不应该只安装最新的 Python 版本吗?
medium.com](https://medium.com/@gergoszerovay/why-you-need-python-environments-and-how-to-manage-them-with-conda-protostar-space-cf823c510f5d) [## 使用 Python 的 AWS Lambda:完全入门指南
在这篇文章中,我们将了解什么是亚马逊网络服务(AWS) Lambda,以及为什么它可能是一个好主意,用于您的…
stackify.com](https://stackify.com/aws-lambda-with-python-a-complete-getting-started-guide/) [## 用 AWS S3 兰巴和 DynamoDB 构建无服务器数据管道
AWS Lambda plus Layers 是管理数据管道和实现无服务器管理的最佳解决方案之一
medium.com](https://medium.com/hackernoon/build-a-serverless-data-pipeline-with-aws-s3-lamba-and-dynamodb-5ecb8c3ed23e) [## 无服务器架构模式
构建在 AWS 无服务器堆栈之上的云架构模式。
medium.com](https://medium.com/@eduardoromero/serverless-architectural-patterns-261d8743020) [## 深入探究 AWS Lambda
了解 Lambda 的基本基础设施,如何运行可执行文件和解析 CloudWatch 日志
towardsdatascience.com](/diving-deeper-into-aws-lambda-a52b22866767)**
Scala Apache Spark 简介
本文是 3 月份 Scala-Lagos 会议的后续笔记,在该会议上,我们讨论了 Apache Spark、它的功能和用例,以及一个简单的例子,其中 Scala API 用于 Tweets 上的样本数据处理。它旨在很好地介绍 Apache Spark 的优势以及这些优势背后的理论。
Spark——一个包罗万象的数据处理平台
“如果有一个收获的话,那就是小赢也没什么。小胜是好事,他们会复合。如果你做得对,最终结果将是巨大的。”—安迪·约翰斯
Apache Spark 是一个高度开发的引擎,用于在数千个并行计算引擎上进行大规模数据处理。这允许最大化这些计算引擎的处理器能力。Spark 能够处理多种数据处理任务,包括复杂的数据分析、流分析、图形分析以及对大量数据进行可扩展的机器学习,这些数据的数量级为 TB、Zettabytes 等等。
Apache Spark 的成功得益于其开发背后的基本理念,即打破 MapReduce 的限制,MapReduce 是 Hadoop 的一个关键组件,迄今为止,其处理能力和分析能力比 MapReduce 好几个数量级,100 倍,并且具有内存处理能力的优势,因为它能够将其数据保存在计算引擎的内存(RAM)中,并对存储在内存中的数据进行数据处理,从而消除了从磁盘写入/读取数据的连续输入/输出(I/O)需求。
为了有效地做到这一点,Spark 依赖于使用一种称为弹性分布式数据集(RDD) 的专门数据模型,它可以有效地存储在内存中,并允许各种类型的操作。RDD 是不可变的,即存储在内存中的数据项的只读格式,并且有效地分布在机器集群中,人们可以将 RDD 视为原始数据格式(如 String、Int)的数据抽象,这使得 Spark 可以很好地工作。
除了 RDD,Spark 还利用直接无环图(DAG)来跟踪 rdd 上的计算,这种方法通过利用作业流来适当分配性能优化来优化数据处理,这还有一个额外的优势,即通过有效的回滚机制帮助 Spark 在作业或操作失败时管理错误。因此,在出现错误的情况下,Spark 不需要从头开始计算,它可以很容易地利用错误之前计算的 RDD,并通过固定操作传递它。这就是 Spark 被指定为容错处理引擎的原因。
Spark 还利用集群管理器在一个机器集群上正确地运行它的作业,集群管理器以一种主-工的方式帮助分配资源和调度作业。主设备为集群中的工人分配作业和必要的资源,并协调工人的活动,以便在工人不可用的情况下,将作业重新分配给另一个工人。
凭借使用 RDD 抽象、DAG 计算范式、资源分配和集群管理器调度的内存处理理念,Spark 已成为快速大数据处理领域不断进步的引擎。
星火数据处理能力。
使用基本 SQL 进行复杂分析的结构化 SQL
Apache Spark 一个众所周知的功能是,它允许数据科学家轻松地以类似 SQL 的格式对大量数据进行分析。利用 spark-core 内部和底层 RDD 上的抽象,spark 提供了所谓的 DataFrames,这是一种将关系处理与 Spark 的函数式编程 API 集成在一起的抽象。这是通过使用具有列名的模式向数据添加结构信息以向数据提供半结构或完整结构来实现的,并且通过这种方式,可以使用列名直接查询数据集,从而为数据处理打开了另一个级别。
从 Spark 1.6 版开始,结构化 SQL API 提供了数据集 API,它为 Spark-core 的低级 RDD 提供了类似 SQL 的高级功能。从字面上看,数据集 API 是一种抽象,它通过使用优化的 SQL 执行引擎为 spark RDD 提供了 SQL 感觉和执行优化,同时也不会失去 RDD 附带的功能操作。数据集 API 和数据帧 API 都构成了结构化 SQL API。
用于实时分析的火花流
Spark 还提供了一个扩展,通过以离散流的形式提供底层 RDD 的抽象,可以轻松地操作流数据。使用底层 RDD Spark 内核有两个主要优势;它允许 Spark 的其他核心功能在流数据上得到利用,并有利于可以在 rdd 上执行的数据核心操作。
离散化数据流是指实时小批量获得的 RDD 数据。
用于预测建模的 MLLib/ML 机器学习
Spark 还通过提供机器学习算法、数据特征化算法和流水线功能来提供机器学习功能,这些功能经过优化,可以在大量数据上进行扩展。Spark 机器学习库的目标概括如下:
让实用的机器学习变得可扩展和简单。
GraphX 图形处理引擎。
第四种数据处理能力是其固有的对图形数据进行分析的能力,例如在社交网络分析中。Spark 的 GraphX API 是 ETL 处理操作和图形算法的集合,针对数据的大规模实现进行了优化。
初始化火花
根据使用情况,有多种方法可以初始化 Spark 应用程序,应用程序可以利用 RDD、Spark 流、带有数据集或数据帧的结构化 SQL。因此,理解如何初始化这些不同的 Spark 实例非常重要。
- RDD 与星火语境:
spark-core 的操作是通过创建一个 spark context 来启动的,该 context 是通过许多配置来创建的,例如主位置、应用程序名称、执行器的内存大小等等。
这里有两种启动 spark 上下文的方法,以及如何使用创建的 spark 上下文创建 RDD。
2。带 Spark 会话的数据帧/数据集:
如上所述,Spark 的入口点可能是通过使用 Spark 上下文,然而,Spark 允许通过 Spark 会话与结构化 SQL API 直接交互。它还包括指定 Spark 应用程序的配置。
下面是启动 Spark 会话并使用该会话创建数据集和数据帧的方法。
3。带火花流的数据流:
Spark 的另一个入口点是在与实时数据交互时使用流上下文。流式上下文的实例可以从 Spark 配置或 Spark 上下文中创建。如下所示
对 RDD、数据集和数据帧的操作
已经很好地了解了 spark 的功能,展示一些可以应用于各种 Spark 抽象的操作是很重要的。
1。RDD
RDD 是 spark 的主要抽象,也是 Spark 核心的核心,它有两个基本操作。
转换 —转换操作应用于现有的 RDD,以创建新的和已更改的 rdd。这种操作例子包括 映射过滤 和 平面映射 等等。spark 中转换操作的完整列表可以在这里找到
一旦 spark 上下文用于创建 RDD,这些操作就可以应用于 RDD,如下面的代码示例所示。值得注意的是,这些操作是延迟计算的,因为它们在应用操作之前不会被直接计算。
动作 —动作操作触发 Spark 中的实际计算,它驱动计算向驱动程序返回值。动作操作的思想是将集群中的所有计算返回给驱动程序,以产生一个实际数据类型的单一结果,而不是 spark 的 RDD 抽象。启动动作操作时必须小心,因为驱动程序有足够的内存来管理这些数据是很重要的。动作操作的例子包括 【减少】收集取 等等。完整列表可在这里找到
2。数据集/数据帧
如前所述,数据集是结构化 SQL 的类似 RDD 的优化抽象,既允许 SQL 中的关系操作,也允许函数操作,如 映射 、 过滤 和许多其他类似的操作,这些操作在 RDD 中都是可能的。需要强调的是,并不是所有的 DataFrame 类似 SQL 的功能都完全适用于 Dataset,但是有许多基于列的函数仍然非常适用于 Dataset。此外,在特定于领域的对象中编码数据集还有一个额外的优势,即把数据集映射到一个类型 T 这有助于扩展 Spark Dataset 可能实现的功能,还增加了执行强大的λ操作的能力。
Spark DataFrame 可以进一步视为以命名列组织的数据集,并呈现为一个等效的关系表,您可以使用类似 SQL 的查询甚至 HQL。因此,在 Spark DataFrame 上,执行任何类似 SQL 的操作,例如 SELECT COLUMN-NAME 、 GROUPBY 和 COUNT 等等变得相对容易。关于 Spark DataFrame 的另一个有趣的事情是,这些操作可以使用任何可用的 spark APIs 以编程方式完成——Java、Scala、Python 或 R,以及将 DataFrame 转换为一个临时 SQL 表,在该表中可以执行纯 SQL 查询。
结论。
总结一下 Spark 的介绍,一个示例 scala 应用 tweets 上的字数统计是提供的,它是在 scala API 中开发的。该应用程序可以在您喜欢的 IDE 中运行,如 InteliJ 或笔记本电脑,如 Databricks 或 Apache Zeppelin。
在本文中,涵盖了一些要点:
- Spark 作为下一代数据处理引擎的描述
- 赋予 spark 能力的非延迟技术
- Spark 中存在的数据处理 API
- 关于如何使用数据处理 API 的知识
- 体验 spark 处理能力的一个简单例子。
本文原载 此处
人工神经网络导论——解释、公式和推导
Photo by Billy Huynh on Unsplash
神经网络处于机器学习的前沿。他们正在接受训练,以完成各种可以想象的任务。通过这篇文章,我们试图看看神经网络的公式,推导。我们也着眼于神经网络学习的实际方面。
来自生物学的动机
大脑是我们身体中支持学习的重要组成部分。它有大约 100 亿个相互连接的神经元。一个神经元从它的突触接收来自其他神经元的输入。输入发生总和,当总和超过特定阈值时,神经元通过轴突向另一个神经元发送电尖峰。
感知器
P erceptron 是机器学习中用于二元分类器监督学习的算法,即确定输入向量所属类别的函数。
可以写成:
走向神经网络
基本的人工神经网络是感知器的自然扩展。我们可以说,一个基本的神经网络是一个多层感知器,称为前馈神经网络。它将包含:
- 隐藏层
- 偏差单位
- 神经元(输入、输出和感知器)
- 突触权重
- 激活功能
前馈神经网络
任何神经网络的目标都是估计一个函数 f,该函数对给定的一组输入给出一组输出的估计。
上面提到的神经网络被称为前馈,因为没有输出反馈给输入(不同于递归神经网络)。
输入时间权重,添加偏差并激活
我们可以说:
where f is the activation function
我们可以进一步说:
where nH represents the number of perceptrons in the hidden layer & w0 are the bias units.
因此,输出神经元 z 可以导出为:
但是人工神经网络是怎么学习的呢?
对于每个神经网络,我们都有一个与其预测相关的成本函数。我们称这个成本函数为损失函数。该损失函数将根据输入和隐藏权重进行优化。现在,我们可以计算关于每个权重的成本函数偏导数,并更新最优成本函数的权重。
注意:在这种方法中,我们将单个输入样本多次(等于权重的数量)传递给神经网络,用于计算和优化单个输入的所有权重。这在计算上非常昂贵。
反向传播是来拯救我们的
Geoff Hinton 于 1986 年在其 论文 *中提出了反向传播。*当时它被高度低估,但后来逐渐成为前馈神经网络的主干。
本质上,反向传播只是链式法则的一个巧妙应用。
反向传播使我们能够在一次反向传递中计算每个重量的偏导数。我们可以说:
where J(w) represents the loss function, c = total number of output & t is the given output and z is the predicted output.
我们可以说:
where eta is the learning rate.
类似地,对于其他重量,
在我们获得由于后向传递中的误差函数(误差函数中每个权重的贡献)引起的权重变化之后,我们可以如下更新它们:
我们可以通过 随机梯度下降 或其变体反向传播来计算权重。
反向传播的实际问题
激活功能
激活函数的主要目的是将输入信号转换为神经网络中某一节点的输出信号。没有激活函数的神经网络只是一个线性回归模型。因此,为了学习复杂的非线性曲线,我们需要激活函数。
激活函数应遵循的属性:
- 非线性为了生成非线性输入映射,我们需要一个非线性激活函数。
- 饱和一个饱和的激活函数挤压输入,把输出放在一个有限的范围内;因此,没有一个重量会对最终输出产生显著影响。
- 连续和平滑对于基于梯度的优化,更平滑的函数通常显示出更好的结果。因为输入取连续范围,所以输出也应该取节点的连续范围。
- 可微正如我们在推导 f 的反向传播导数时所看到的,应该定义。
- 单调如果激活函数不是单调递增的,则神经元的权重可能会使其影响较小,反之亦然;这与我们想要的正好相反。
- 对于小值是线性的如果对于小值是非线性的,我们需要在神经网络的权重初始化时考虑约束,因为我们可能会面临消失梯度或爆炸梯度的问题。
消失和爆炸渐变
V
正如我们之前讨论的,饱和激活函数将输入压缩到一个小值,因此输入的显著变化将导致输出的小变化,因此导数更小。
ReLU 是一个没有消失梯度问题的激活函数。大多数深度学习模型都以此为激活函数。
但是如果你仍然坚持使用 tanh 或 sigmoid,你可以选择批量标准化。它只是把输入保持在导数不小的绿色区域。
E 在极端情况下,权重值可能会溢出,从而导致 NaN 权重。因此,这些 NaN 权重不能被进一步更新,导致学习过程停止。
有许多方法来处理爆炸式渐变,如渐变剪辑(如果范数超过特定阈值则剪辑渐变)和权重正则化(对大权重值的损失函数进行惩罚)。
损失函数
成本函数或损失函数本质上计算神经网络输出和目标变量之间的 差 。它们可以分为三种分类:
**回归损失函数:**当目标变量为连续回归损失函数时使用。最常用的是均方差。其他名称包括绝对误差和平滑绝对误差。
**分类损失函数:**当输出变量是一个类的概率时,我们使用分类损失函数。大多数分类损失函数倾向于最大限度地增加利润。著名的名字包括分类交叉熵,负对数似然,边缘分类器。
**嵌入损失函数:**当我们必须测量两个或多个输入之间的相似性时,我们使用嵌入损失函数。一些广泛使用的嵌入损失函数是 L1 铰链误差和余弦误差。
优化算法
优化算法负责更新神经网络的权重和偏差,以减少损失。它们可以主要分为两类:
**恒定学习率算法:**其中学习率 η 对于所有参数和权重都是固定的。最常见的例子是随机梯度下降。
**自适应学习率算法:**Adam 等自适应优化器具有每参数学习率方法,该方法提供了更直接的启发式方法,而不是手动处理超参数。
以上让你开始学习神经网络。保持文章简短,我将在后续文章中讨论 CNN 和 RNN。请关注此空间了解更多信息。
上一篇: 人工智能中的统计方法介绍
参考
- https://machine learning mastery . com/expanding-gradients-in-neural-networks/
- https://medium . com/data-science-group-iitr/loss-functions-and-optimization-algorithms-demystified-bb 92 daff 331 c
- https://towards data science . com/the-vanishing-gradient-problem-69 BF 08 b 15484
增强随机搜索简介。
让 MuJoCo 学习快速有趣的方法
Photo by jean wimmerlin on Unsplash
更新:学习和练习强化学习的最好方式是去 http://rl-lab.com
本文基于加州大学伯克利分校的 Horia Mania、Aurelia Guy 和 Benjamin Recht 于 2018 年 3 月发表的一篇论文。
作者声称,他们已经建立了一种算法,在 MuJoCo 运动基准上,该算法比最快的竞争对手无模型方法至少高效 15 倍。
他们将这种算法命名为增强随机搜索,简称 ARS。
问题是
正如在每个 RL 问题中一样,目标是找到一个策略来最大化代理在给定环境中遵循该策略时可能获得的期望回报。
方法
本文提出的解决方案是增强一种称为基本随机搜索的现有算法。
基本随机搜索
基本随机搜索的想法是挑选一个参数化的政策𝜋𝜃,通过对所有𝜹应用+𝛎𝜹和-𝛎𝜹(其中𝛎< 1 is a constant noise and 𝜹 is a random number generate from a normal distribution).
Then apply the actions based on 𝜋(𝜃+𝛎𝜹) and 𝜋(𝜃-𝛎𝜹) then collect the rewards r(𝜃+𝛎𝜹) and r(𝜃-𝛎𝜹) resulting from those actions.
Now that we have the rewards of the perturbed 𝜃, compute the average
δ= 1/n *σ[r(𝜃+𝛎𝜹)-r(𝜃-𝛎𝜹)]𝜹来冲击(或扰动)参数𝜃,并且我们使用δ和学习率来更新参数。𝜃ʲ⁺=𝜃ʲ+𝝰.δ
增强随机搜索(ARS)
ARS 是 BRS 的改进版本,它包含三个方面的增强功能,使其性能更高。
除以标准偏差𝞼ᵣ
随着迭代的进行,r(𝜃+𝛎𝜹和 r(𝜃-𝛎𝜹之间的差异可以显著变化,学习率𝝰固定,更新𝜃ʲ⁺=𝜃ʲ+𝝰.δ可能大幅振荡。例如,如果𝝰 = 0.01,δ= 10,那么𝝰.δ就是 0.1,但是如果δ变成 1000,𝝰.δ就变成 10。这种残酷的变化伤害了更新。请记住,我们的目标是让𝜃向回报最大化的价值观靠拢。
为了避免这种类型的差异,我们将𝝰.δ除以𝞼ᵣ(所收集奖励的标准差)。
使状态正常化
国家的正常化确保政策对国家的不同组成部分给予同等的重视。例如,假设一个状态分量取值范围为[90,100],而另一个状态分量取值范围为[1,1]。然后,第一个状态分量将支配计算,而第二个不会有任何影响。为了获得一个直觉,考虑一个简单的平均值,假设 C1 = 91,C2 = 1,平均值将是(C1 + C2) / 2 = 92 / 2 = 46。现在假设 C2 急剧下降到最小值,C2 = -1。平均值将是(91–1)/2 = 45。
注意,相对于 C2 的大幅下降,它几乎没有移动。
现在让我们使用规范化。对于 C1 = 91,NC1 =(91–90)/(100–90)= 0.1,
对于 C2 = 1,NC2 = (1 - (-1))/(1-(-1)) = 2/2 =1。
归一化平均值将为(0.1 + 1)/2 = 0.55。
现在如果 C2 下降到-1,NC2 = (-1-(-1))/2 = 0,归一化的平均值变成(0.1 + 0)/2 = 0.05。
如你所见,平均值受到了 C2 急剧变化的极大影响。
ARS 中使用的标准化技术包括从状态输入中减去状态的当前观察平均值,然后除以状态的标准偏差:
(state _ input-state _ observed _ average)/state _ STD
使用最佳表现方向
记住我们的目标是最大化收集到的奖励是很有用的。然而,我们在每次迭代中计算平均奖励,这意味着在每次迭代中,我们在𝜋(𝜃+𝛎𝜹和𝜋(𝜃-𝛎𝜹之后计算 2N 集,然后我们对所有 2N 集收集的奖励 r(𝜃+𝛎𝜹和 r(𝜃-𝛎𝜹进行平均。这就带来了一些隐患,因为如果一些奖励相对于其他奖励来说很小,它们就会压低平均值。
解决这个问题的一个方法是根据 max(r(𝜃+𝛎𝜹、r(𝜃-𝛎𝜹)).键将奖励按降序排列然后只使用排名前的 b 和的奖励(以及它们各自的摄𝜹)来计算平均奖励。
注意,当 b = N 时,算法将与没有此增强的算法相同。
例如,假设我们有以下扰动及其各自的回报,如下表所列。
我们按照键 max([r(𝜹i)、r(-𝜹i)])的降序对表进行排序,结果如下表所示:
我们假设 b = 3,那么我们在平均计算中考虑这些数字:
【𝜹9,r(𝜹9】,r(-𝜹9)],【𝜹5,r(𝜹5】,r(-𝜹5)],【𝜹1,r(𝜹1】,r(-1)]
ARS 算法
最后,ARS 算法变成:
简单来说,它会变成如下形式:
Let 𝛎 a positive constant < 1
Let 𝝰 be the learning rate
Let N the number of perturbations
Let 𝜃 a (p x n) matrix representing the parameters of the policy 𝜋
Let 𝜹i a (p x n) matrix representing the ith perturbation1\. While end condition not satisfied do:
2\. Generate N perturbations 𝜹 from a normal distribution
3\. Normalize 𝜋i+ = (𝜃+𝛎𝜹i)ᵀx and 𝜋i- = (𝜃-𝛎𝜹i)ᵀx for i = 1 to N
4\. Generate 2N episodes and their 2N rewards using 𝜋i+ and 𝜋i- and collect the rewards ri+ and ri-
5\. Sort all 𝜹 by max(ri+, ri-)
6\. Update 𝜃 = 𝜃 + (𝝰/(b*𝞼ᵣ)) Σ(ri+ - ri-)𝜹i (where i = 1 to b)
7\. End While
实施和演示
下面是标准的 ARS 实现,很容易在互联网上找到。
运行代码将产生不同的学习阶段。
在最初的几次迭代之后
在第 100 次迭代之后
在第 300 次迭代之后
AWS EC2 和数据科学中的命令行简介
这个帖子的灵感来自于一个从来没有听说过命令行的朋友。这并不令人惊讶,因为我大约两年前才开始。现在,我每天都用它。
数据科学中最重要的工具之一是命令行(同义短语包括终端、shell、控制台、命令提示符、Bash)。尤其是在使用亚马逊网络服务(AWS)和弹性计算云(EC2)时,熟悉命令行是一个必须做的事情。
你可能会问,“为什么我不能用我自己的电脑呢?”答案很简单——随着数据量的增加,仅靠 8 或 16 GB 的 RAM 处理数 TB 的数据变得不可能。使用 AWS 可以在处理大数据时实现可扩展性。你不再使用的一台本地计算机,而是可能使用云上的 40 台计算机,这一概念被称为*并行处理。*简而言之(一语双关),你是在付钱给亚马逊借他们的电脑。
命令行的目的是与计算机(本地或远程)及其文件系统进行交互。它提供了一个纯文本界面(是的,不再需要点击)来为你的操作系统运行提供命令。
一些使用案例:
- 读取、写入、编辑、查找、移动、复制、删除、下载文件
- Git/Github
- 基本数据探索/操作
- 登录到远程计算机,也称为 SSH-ing(安全外壳)
- 观看《星球大战》(打开终端,输入 telnet towel.blinkenlights.nl)
一些危险用例:
- 拒绝服务(DoS)攻击
- 黑客攻击和窃取人们的信息
Source: https://xkcd.com/196/
本教程旨在给出一个简短的介绍,首先是 AWS EC2 入门(我们将使用自由层规范),然后是在命令行上使用的重要语法。
AWS 入门
首先要做的是去https://aws.amazon.com/创建一个账户。然后,按照这个简短的 GIF。
Launching an AWS instance
喝杯咖啡,等一两分钟,让 AWS 实例启动。一旦准备好,它应该显示正在运行。
EC2 Management Console
注意右下角的公共 DNS (IPv4)。
打开您的终端,键入以下命令:
chmod 400 <<name_of_pem_file>>
ssh -i <name_of_pem_file> [ubuntu@<<](mailto:ubuntu@ec2-54-213-153-185.us-west-2.compute.amazonaws.com)Public DNS (IPv4)>>
例如,我会键入:
chmod 400 chris_medium.pem
ssh -i "chris_medium.pem" ubuntu@ec2-54-213-153-185.us-west-2.compute.amazonaws.com
Inside an AWS instance
Source: https://xkcd.com/908/
恭喜你!您现在已经准备好在 AWS 上开始云计算了。
命令行入门
现在您已经进入了 AWS 实例,您需要知道如何通过终端输入文本命令来提供指令。
让我们从古腾堡计划中抓取一些文本(《傲慢与偏见》,简·奥斯汀)开始:http://www.gutenberg.org/files/1342/1342-0.txt
wget: 从网站下载文件
wget [http://www.gutenberg.org/files/1342/1342-0.txt](http://www.gutenberg.org/files/1342/1342-0.txt)
ls: 列出当前工作目录下的文件
当输入 ls 时,您的终端应该显示一个名为1342-0.txt
的文件。
前缀为的文件。是隐藏的文件。参数-a
将显示它们。有些参数是必选的,而有些像-a
是可选的。
男人: 查看命令手册页
键入man ls
(或者 help 前面加两个连字符,由于某种原因 Medium 不断将两个连字符转换成长破折号)将为您提供每个参数的信息。多个参数可以通过连续输入来完成,例如,ls -ltr
将以一个长列表的格式显示你的文件,并按修改时间排序,最早的条目最先出现。
头: 打印前 10 行
尾: 打印最后 10 行
你在屏幕上看到的被称为标准输出。让我们将三个命令合并成一个。
猫: 打印文件的内容
|: 将一个命令的输出作为输入传递给另一个命令的管道运算符
**WC:**字数
首先,文本内容将被打印到标准输出。然后,标准输出将被传递给wc
命令,该命令将提供文件的行数、字数和字符数。
mv: 移动文件(可以用来重命名)
mkdir: 创建目录/文件夹
cp :复制一个文件
rm :删除一个文件
光盘: 更改目录
让我们将文本文件重命名为pride_and_prejudice
,创建一个名为books
的目录,将pride_and_prejudice
文件复制到books
。
mv 1342-0.txt pride_and_prejudice
mkdir books
cp pride_and_prejudice books/
grep: 基于模式的过滤器
> : 将标准输出写入一个文件(如果已有同名文件则覆盖)
***>>:***将标准输出追加到文件末尾
触摸: 创建空文件
回显: 打印消息到标准输出
- 让我们将包含单词“happy”的所有行存储到一个名为 happy.txt 的文件中。
- 接下来,让我们将包含单词“sad”的所有行存储到一个名为 sad.txt 的文件中
- 然后,创建一个名为 subset 的空文件,并将这两个文件组合在一起。
- 在子集的末尾添加一条消息,说明“完成!”
cat pride_and_prejudice | grep happy > happy.txt
cat pride_and_prejudice | grep -sw sad > sad.txt
touch subset
cat *.txt >> subset
echo "Finished" >> subset
在第二行中,使用了可选参数-sw
,这样 dis sad vantage 这样的词也不会被捕获。您可以使用星号*
对所有以扩展名.txt
结尾的文件执行操作。
假设您的任务是从古腾堡项目网站下载 100 个文件(书籍 1000–1099 ),并将文件名更改为书名。这似乎是一个非常单调的任务,但是使用命令行,只用几行就可以完成!
我们需要学习如何做循环。
Source: https://www.cyberciti.biz/faq/bash-for-loop/
for i in 1 2 3 4 5
do
echo "Hi Person $i"
done
输出将是:
Hi Person 1
Hi Person 2
Hi Person 3
Hi Person 4
Hi Person 5
一个稍微复杂一点的例子:
for i in $( ls )
do
echo file: $i
done
输出将是:
file: books
file: happy.txt
file: pride_and_prejudice
file: sad.txt
file: subset
$
使您能够在另一个命令中使用一个命令。
从古腾堡网站上看,这些文件将会是http://www.gutenberg.org/files/1/1-0.txt或http://www.gutenberg.org/files/1/1.txt(它们的文件名中是否有-0
并不一致。
考虑到这两种情况,我们可以使用||
命令,如果第一个命令失败,它将只触发第二个命令。
tr: 翻译一个字符(使用-d 会删除字符)
代码如下(一步一步的细节可以在下面看到):
mkdir gutenberg
cd gutenbergfor i in {1000..1099}
do
wget -O file "[http://www.gutenberg.org/files/$i/$i.txt](http://www.gutenberg.org/files/2/2.txt)" ||
wget -O file "[http://www.gutenberg.org/files/$i/$i-0.txt](http://www.gutenberg.org/files/2/2-0.txt)"
name=$(cat file | head -n 1 | tr -cd "[:alnum:][:space:]")
name="${name/$'\r'/}"
mkdir "$i"
mv file "$i/$name"
done
键入ls
应该会得到这样的结果:
要查看文件夹中的文件,您可以使用ls -R
:
创建一个名为 gutenberg 的文件夹,并将目录更改为该文件夹
mkdir gutenberg
cd gutenberg
开始 for 循环,其中 I 将是一个从 1000 到 1099(包括 1000 和 1099)的数字
for i in {1000..1099}
do
参数-O
会将文件重命名为名称file
。它将首先尝试下载<number>.txt
,如果失败,它将尝试<number>-0.txt
。
wget -O file "[http://www.gutenberg.org/files/$i/$i.txt](http://www.gutenberg.org/files/2/2.txt)" ||
wget -O file "[http://www.gutenberg.org/files/$i/$i-0.txt](http://www.gutenberg.org/files/2/2-0.txt)"
这将获取文本文件,检索第一行(标题所在的位置),只保留字母数字和空格,并将字符串存储为一个名为name
的变量。[:alnum:]
和[:space:]
分别是字母数字和空白的字符集。下一行将删除剩余的奇怪的、bash 特有的字符,例如将'The Project Gutenberg EBook of the Riverman by Stewart Edward White'$'\r'
转换为'The Project Gutenberg EBook of the Riverman by Stewart Edward White'
。这使用了*变量替换、*的概念,并使用了以下语法:${parameter//patern/string}
。在这一部分中,/string
组件是空的,所以它不用任何东西替换\r
。
name=$(cat file | head -n 1 | tr -cd "[:alnum:][:space:]")
name="${name/$'\r'/}"
最后一部分将通过创建一个具有适当编号的文件夹并将文件移动到其中来结束 for 循环。
mkdir "$i"
mv file "$i/$name"
done
结论
本教程中还有许多我没有涉及到的工具,它们也被广泛使用。其中包括:
- Git/Github
- 精力
- Bash 脚本
- Bash 配置文件
感谢您的阅读!这是我的第一篇博文——欢迎留下评论,提供任何建设性的反馈。你也可以建议我将来写的主题。我会试着每周发一次帖子。
回溯测试交易策略简介
Source: pixabay
学习如何使用zipline
建立和回溯测试交易策略
在这篇文章中,我想继续量化金融系列。在第一篇文章中,我描述了资产回报的程式化事实。现在,我将介绍回溯测试交易策略的概念,以及如何使用 Python 中现有的框架进行回溯测试。
什么是回溯测试?
先说交易策略。它可以被定义为一种在市场上购买和/或出售资产的方法(基于预先定义的规则)。这些规则可以基于例如技术分析或机器学习模型。
回溯测试基本上是根据历史数据评估交易策略的表现——如果我们在过去对一组资产使用了给定的策略,它的表现会有多好/多差。当然,不能保证过去的表现能代表未来的表现,但是我们仍然可以调查!
Python 中有一些可用的回测框架,在本文中,我决定使用zipline
。
为什么是zipline
?
zipline
环境提供的一些不错的特性包括:
- 易用性——有一个清晰的结构来说明如何构建回溯测试以及我们可以预期的结果,所以大部分时间可以花在开发最先进的交易策略上:)
- 现实—包括交易成本、滑点、订单延迟等。
- 基于流—单独处理每个事件,从而避免前瞻偏差
- 它附带了许多易于使用的统计方法,如移动平均、线性回归等。—无需从头开始编写代码
- 与 PyData 生态系统集成—
zipline
使用 Pandas 数据帧存储输入数据和性能指标 - 很容易将其他库,如
matplotlib
、scipy
、statsmodels
和sklearn
集成到构建和评估策略的工作流中 - 由 Quantopian 开发和更新,为
zipline
、历史数据甚至实时交易功能提供网络界面
我相信这些论点不言自明。开始编码吧!
使用conda
设置虚拟环境
安装zipline
最方便的方法是使用虚拟环境。在本文中,我使用conda
来实现这一点。我用 Python 3.5 创建了一个新环境(我在使用 3.6 或 3.7 时遇到了问题),然后安装了zipline
。也可以pip install
一下。
# create new virtual environment
conda create -n env_zipline python=3.5# activate it
conda activate env_zipline# install zipline
conda install -c Quantopian zipline
为了一切正常工作,你还应该安装jupyter
和本文中使用的其他软件包(见下面的watermark
)。
导入库
首先,我们需要使用%load_ext
魔法加载 IPython 扩展。
%load_ext watermark
%load_ext zipline
然后我们导入其余的库:
import numpy as np
import matplotlib.pyplot as plt
import pandas as pd
import zipline
from yahoofinancials import YahooFinancials
import warningsplt.style.use('seaborn')
plt.rcParams['figure.figsize'] = [16, 9]
plt.rcParams['figure.dpi'] = 200
warnings.simplefilter(action='ignore', category=FutureWarning)
下面您可以看到本文中使用的库列表,以及它们的版本。
导入自定义数据
zipline
准备好从 Quandl(维基数据库)下载的数据。您始终可以通过运行以下命令来检查已经接收的数据:
!zipline bundles
这种方法的问题是,在 2018 年年中,数据被中断,因此没有去年的数据。为了克服这一点,我展示了如何手动接收来自任何来源的数据。为此,我使用了yahoofinancials
库。为了加载到zipline
中,数据必须是 CSV 文件和预定义的格式——就像数据帧预览中的格式。
然后,我们需要将数据作为 CSV 文件保存在名为“daily”的文件夹中(或者您选择的另一个文件夹)。
df.to_csv('daily/aapl.csv', header=True, index=False)
在下一步中,我们需要修改位于 zipline 目录中的extension.py
文件。安装完zipline
后,它是空的,我们需要添加以下内容:
我们还可以为数据接收脚本定义并提供一个定制的日历——例如在处理欧洲股票时。有关如何操作的详细信息,请查看文档。
与数据下载函数相反,我们需要传递下载数据的确切日期范围。在本例中,我们从2017-01-03
开始,因为这是我们获得定价数据的第一天。
最后,我们运行以下命令:
!zipline ingest -b apple-prices-2017-2019
我们可以验证捆绑包是否被成功摄取:
!zipline bundles
下载基准数据有一个已知问题,所以——目前——我们坚持使用默认包中的历史数据。但是,您现在知道了如何使用自定 CSV 文件摄取数据。
有关如何使用csvdir
包加载自定义数据的详细信息,请参考这篇文章,其中我展示了如何导入欧洲股票数据并在此基础上运行基本策略。
买入并持有策略
我们从最基本的策略开始——买入并持有。这个想法是,我们购买某项资产,在整个投资期限内不做任何事情。这个简单的策略也可以被认为是更高级策略的基准——因为使用一个非常复杂的策略比购买和什么都不做产生更少的钱(例如由于交易成本)是没有意义的。
在这个例子中,我们考虑苹果的股票,并选择 2016 年至 2017 年作为回溯测试的持续时间。我们从 1050 美元的资本开始。我选择这个数字,因为我知道我们需要多少或多或少的初始购买,我喜欢让这个数字尽可能小,因为我们只购买 10 股,所以不需要几千的初始余额。我们假设默认的交易成本(每股 0.001 美元,没有最低交易成本)。
使用zipline
有两种方法——使用命令行或 Jupyter 笔记本。要使用后者,我们必须在笔记本的单元格中编写算法,并指出zipline
应该运行它。这是通过%%zipline
IPython magic 命令完成的。这个魔术与上面提到的 CLI 采用相同的参数。
还有一点很重要,算法运行所需的所有导入(如numpy
、sklearn
等)。)必须在算法单元中指定,即使它们以前被导入到其他地方。
恭喜,我们已经完成了第一次回溯测试。那么到底发生了什么?
每个zipline
算法包含(至少)两个我们必须定义的函数:
initialize(context)
handle_data(context, data)
在算法开始之前,调用initialize()
函数并传递一个context
变量。context
是一个全局变量,我们可以在其中存储从算法的一次迭代到下一次迭代需要访问的额外变量。
算法初始化后,每个事件调用一次handle_data()
函数。在每次调用时,它传递同一个context
变量和一个名为data
的事件帧。它包含当前的交易棒线,包括开盘价、最高价、最低价和收盘价(OHLC)以及交易量。
我们通过使用order(asset, number_of_units)
创建一个订单,在这里我们指定购买什么以及多少股票/单位。正数表示买入那么多股票,0 表示卖出我们所有的股票,负数表示卖空。另一种有用的订单类型是order_target
,根据需要订购尽可能多的股票,以达到投资组合中所需的数量。
在我们的买入并持有策略中,我们会检查是否已经下单。如果没有,我们订购一定数量的股票,然后在回溯测试的剩余时间里什么也不做。
我们来分析一下策略的表现。首先,我们需要从 pickle 文件加载性能数据帧。
# read the performance summary dataframe
buy_and_hold_results = pd.read_pickle('buy_and_hold.pkl')
现在我们可以绘制一些存储的指标:
从第一眼看,我们看到该投资组合在投资期限内产生了资金,并在很大程度上跟随苹果的价格(这是有意义的,因为它是投资组合中的唯一资产)。
为了查看事务,我们需要从 performance DataFrame 转换transactions
列。
pd.DataFrame.from_records([x[0] for x in buy_and_hold_results.transactions.values if x != []])
通过检查性能数据框架的列,我们可以看到所有可用的指标。
buy_and_hold_results.columns
其中一些值得注意的是:
- 期初/期末现金——检查给定日期的现金持有量
- 起始/终止值—检查资产;给定日期的值
- 订单—用于检查订单;当交易策略产生信号时,创建订单有不同的事件,当在下一个交易日实际执行时,创建订单有不同的事件
- pnl —每日损益
简单移动平均策略
我们考虑的第二个策略是基于简单移动平均线(SMA)。该战略的“机制”可以总结如下:
- 当价格向上穿过 20 日均线时,买入
x
股票 - 当价格向下穿过 20 日均线时,卖出股票
- 在任何时候,我们最多只能拥有
x
股 - 该策略中没有卖空(尽管它很容易实现)
回溯测试的其余组成部分,如考虑的资产、投资期限或启动资本,与买入并持有示例中的相同。
这个算法的代码稍微复杂一点,但是我们涵盖了代码的所有新方面。为了简单起见,我在上面的代码片段中标记了引用点(sma_strategy.py
),并将在下面用数字引用它们。
1.我演示如何手动设置佣金。在这种情况下,为了便于比较,我使用默认值。
2。“热身期”——这是一个用来确保算法有足够的天数来计算移动平均值的技巧。如果我们使用具有不同窗口长度的多个指标,我们应该总是取最长的一个用于预热。
3。我们通过使用data.history
访问历史(和当前)数据点。在本例中,我们访问过去 20 天。数据(在单个资产的情况下)存储为一个pandas.Series
,按时间索引。
4。SMA 是一个非常基本的指标,所以对于计算来说,我简单地取之前访问的数据的平均值。
5。我把交易策略的逻辑概括在一个if
声明中。为了访问当前和先前的数据点,我分别使用了price_history[-2]
和price_history[-1]
。为了查看是否有交叉,我将当前和以前的价格与均线进行比较,并确定我正在处理哪种情况(买入/卖出信号)。在没有信号的情况下,算法什么也不做。
6。当回溯测试完成时,您可以使用analyze(context, perf)
语句来执行额外的分析(如绘图)。perf
对象只是我们也存储在 pickle 文件中的性能数据帧。但是当在算法中使用时,我们应该称它为perf
,不需要加载它。
与买入并持有策略相比,你可能已经注意到投资组合价值持平的时期。这是因为当我们出售资产时(以及再次购买之前),我们只持有现金。
在我们的案例中,简单的均线策略胜过买入并持有策略。对于 SMA 策略,投资组合的期末价值(包括现金)为 1784.12 美元,而对于更简单的策略,期末价值为 1714.68 美元。
结论
在本文中,我展示了如何使用zipline
框架来执行交易策略的回溯测试。一旦你熟悉了这个库,就很容易测试出不同的策略。在以后的文章中,我将介绍如何使用基于技术分析的更先进的交易策略。
一如既往,我们欢迎任何建设性的反馈。你可以在推特上或者评论里联系我。您可以在我的 GitHub 上找到本文使用的代码。
喜欢这篇文章吗?成为一个媒介成员,通过无限制的阅读继续学习。如果你使用这个链接成为会员,你将支持我,不需要额外的费用。提前感谢,再见!
以下是本系列的后续文章:
我最近出版了一本关于使用 Python 解决金融领域实际任务的书。如果你有兴趣,我在贴了一篇文章介绍这本书的内容。你可以在亚马逊或者 Packt 的网站上买到这本书。
贝叶斯信念网络简介
什么是贝叶斯信念网络?
贝叶斯信念网络或贝叶斯网络或信念网络是一种概率图形模型(PGM),它通过有向无环图(DAG)来表示随机变量之间的条件依赖关系。
An Example Bayesian Belief Network Representation
今天,我将尝试解释信念网络的主要方面,尤其是可能与社会网络分析(SNA)相关的应用。此外,我将向您展示这种网络的一个示例实现。
我们用贝叶斯网络做什么?
贝叶斯网络在很多领域都有应用。例如,疾病诊断、优化的网络搜索、垃圾邮件过滤、基因调控网络等。这个列表还可以扩展。这些网络的主要目标是试图理解因果关系的结构。为了澄清这一点,让我们考虑一个疾病诊断问题。有了给定的症状及其导致的疾病,我们构建了我们的信念网络,当新患者到来时,我们可以通过提供每种疾病的概率来推断新患者可能患有哪种或哪些疾病。类似地,这些因果关系可以为其他问题构建,推理技术可以应用于有趣的结果。
快速概率复习
在继续之前,为了让我们回忆一下,让我给你条件属性的定义。条件概率是在给定其他随机变量的情况下,一个随机变量的概率。它显示为
如果这两个随机变量是相关的,
如果他们是独立的,那么
信念网络的数学定义
通过以下公式在信念网络中计算概率
正如您从公式中所理解的那样,为了能够计算联合分布,我们需要有由网络表示的条件概率。但是进一步说,如果我们有共同分布,那么我们可以开始问有趣的问题。例如,在第一个例子中,如果“季节”是“冬天”,“狗叫”是“真”,我们就要求“下雨”的概率。
信任网络的 Python 示例
所以,我认为这对于理论来说足够了,在继续之前,让我们看一些我目前最喜欢的编程语言 Python ❤️的真实例子,你可以在这里找到我写的 Jupyter 笔记本。
# create the nodes
season = BbnNode(Variable(0, 'season', ['winter', 'summer']), [0.5, 0.5])
atmos_pres = BbnNode(Variable(1, 'atmos_press', ['high', 'low']), [0.5, 0.5])
allergies = BbnNode(Variable(2, 'allergies', ['allergic', 'non_alergic']), [0.7, 0.3, 0.2, 0.8])
rain = BbnNode(Variable(3, 'rain', ['rainy', 'sunny']), [0.9, 0.1, 0.7, 0.3, 0.3, 0.7, 0.1, 0.9])
grass = BbnNode(Variable(4, 'grass', ['grass', 'no_grass']), [0.8, 0.2, 0.3, 0.7])
umbrellas = BbnNode(Variable(5, 'umbrellas', ['on', 'off']), [0.99, 0.01, 0.80, 0.20, 0.20, 0.80, 0.01, 0.99])
dog_bark = BbnNode(Variable(6, 'dog_bark', ['bark', 'not_bark']), [0.8, 0.2, 0.1, 0.9])
cat_mood = BbnNode(Variable(7, 'cat_mood', ['good', 'bad']), [0.05, 0.95, 0.95, 0.05])
cat_hide = BbnNode(Variable(8, 'cat_hide', ['hide', 'show']), [0.20, 0.80, 0.95, 0.05, 0.95, 0.05, 0.70, 0.30])bbn = Bbn() \
.add_node(season) \
.add_node(atmos_pres) \
.add_node(allergies) \
.add_node(rain) \
.add_node(grass) \
.add_node(umbrellas) \
.add_node(dog_bark) \
.add_node(cat_mood) \
.add_node(cat_hide) \
.add_edge(Edge(season, allergies, EdgeType.DIRECTED)) \
.add_edge(Edge(season, umbrellas, EdgeType.DIRECTED)) \
.add_edge(Edge(season, rain, EdgeType.DIRECTED)) \
.add_edge(Edge(atmos_pres, rain, EdgeType.DIRECTED)) \
.add_edge(Edge(rain, grass, EdgeType.DIRECTED)) \
.add_edge(Edge(rain, umbrellas, EdgeType.DIRECTED)) \
.add_edge(Edge(rain, dog_bark, EdgeType.DIRECTED)) \
.add_edge(Edge(rain, cat_mood, EdgeType.DIRECTED)) \
.add_edge(Edge(dog_bark, cat_hide, EdgeType.DIRECTED)) \
.add_edge(Edge(cat_mood, cat_hide, EdgeType.DIRECTED))
我们首先用条件概率描述了我们的节点。您应该注意到,为了简单起见,我跳过了一些可能的状态值。例如,季节变量取其他值“春天”和“秋天”。所以,想法是一样的。
不,让我们检查一下我们的网络是否构建正确。
with warnings.catch_warnings():
warnings.simplefilter('ignore')
graph = convert_for_drawing(bbn)
pos = nx.nx_agraph.graphviz_layout(graph, prog='neato')plt.figure(figsize=(20, 10))
plt.subplot(121)
labels = dict([(k, node.variable.name) for k, node in bbn.nodes.items()])
nx.draw(graph, pos=pos, with_labels=True, labels=labels)
plt.title('BBN DAG')
这段代码片段将生成下图
所以,你看这个网络和我一开始画的很像。现在,让我们在这个信念网络上做一些推论。
# convert the BBN to a join tree
join_tree = InferenceController.apply(bbn)# insert an observation evidence
ev = EvidenceBuilder() \
.with_node(join_tree.get_bbn_node_by_name('season')) \
.with_evidence('winter', 1.0) \
.build()join_tree.set_observation(ev)# print the marginal probabilities
for node in join_tree.get_bbn_nodes():
potential = join_tree.get_bbn_potential(node)
print(node)
print(potential)
print('--------------------->')
这段代码基本上以 1.0 的概率向网络证明了季节是冬天。根据这一证据,当我们进行推论时,我们得到以下结果。
0|season|winter,summer
0=winter|1.00000
0=summer|0.00000
--------------------->
2|allergies|allergic,non_alergic
2=allergic|0.70000
2=non_alergic|0.30000
--------------------->
3|rain|rainy,sunny
3=rainy|0.80000
3=sunny|0.20000
--------------------->
4|grass|grass,no_grass
4=grass|0.70000
4=no_grass|0.30000
--------------------->
1|atmos_press|high,low
1=high|0.50000
1=low|0.50000
--------------------->
5|umbrellas|on,off
5=on|0.95200
5=off|0.04800
--------------------->
6|dog_bark|bark,not_bark
6=bark|0.66000
6=not_bark|0.34000
--------------------->
7|cat_mood|good,bad
7=good|0.23000
7=bad|0.77000
--------------------->
8|cat_hide|hide,show
8=hide|0.87150
8=show|0.12850
--------------------->
当我们添加进一步的证据时,就像狗没有叫一样
# convert the BBN to a join tree
join_tree = InferenceController.apply(bbn)# insert an observation evidence
ev = EvidenceBuilder() \
.with_node(join_tree.get_bbn_node_by_name('season')) \
.with_evidence('winter', 1.0) \
.build()ev2 = EvidenceBuilder() \
.with_node(join_tree.get_bbn_node_by_name('dog_bark')) \
.with_evidence('not_bark', 1.0) \
.build()join_tree.set_observation(ev)
join_tree.set_observation(ev2)# print the marginal probabilities
for node in join_tree.get_bbn_nodes():
potential = join_tree.get_bbn_potential(node)
print(node)
print(potential)
print('--------------------->')
我们得到以下推论结果
0|season|winter,summer
0=winter|1.00000
0=summer|0.00000
--------------------->
2|allergies|allergic,non_alergic
2=allergic|0.70000
2=non_alergic|0.30000
--------------------->
3|rain|rainy,sunny
3=rainy|0.47059
3=sunny|0.52941
--------------------->
4|grass|grass,no_grass
4=grass|0.53529
4=no_grass|0.46471
--------------------->
1|atmos_press|high,low
1=high|0.39706
1=low|0.60294
--------------------->
5|umbrellas|on,off
5=on|0.88941
5=off|0.11059
--------------------->
6|dog_bark|bark,not_bark
6=bark|0.00000
6=not_bark|1.00000
--------------------->
7|cat_mood|good,bad
7=good|0.52647
7=bad|0.47353
--------------------->
8|cat_hide|hide,show
8=hide|0.83162
8=show|0.16838
--------------------->
你看出区别了吗?😆当我们加入与狗叫声有关的证据时,很多概率值都变了。这绝对是一个愚蠢的例子,但很好地获得了直觉。
SNA 中如何使用贝叶斯网络?
贝叶斯网络是理解变量之间因果关系结构的非常强大的工具。一旦你设计了你的模型,即使只有很小的数据集,它也能告诉你各种各样的事情。这一部分的问题是如何在 SNA 中获得贝叶斯网的好处。答案不是唯一的,但让我们从一个深刻的想法开始。在 SNA 中,我们试图理解社会网络的结构。此外,我们试图理解节点的重要性。但是我们不知道我们的重要性度量的结果是什么。这就是贝叶斯网络发生的地方。例如,如果你认为一个节点的重要性是由度中心性和链接中心性引起的,你可能有下面的网络。
这是一个非常幼稚的贝叶斯网络。除了确定节点的重要性,进一步的应用可能是搜索某些特定类型的节点。让我们考虑一个社交网络,其中有一些人是潜在的领导者,我想寻找他们。考虑下图
这个稍微复杂一点的网络将有助于我们确定与成为领导相关的节点的不确定性。
另一个应用程序将推断链接。新的链接可以从现有的链接中推断出来。例如,从社交网络中的群组成员关系,可以推断出可能的成员关系链接。我的意思是,我们可以通过考虑现有的链接来建立用户和组之间的新链接。参见下面的模型图
所以,这些是贝叶斯网络如何应用于 SNA 的一些基本例子。这个主题没有被很好地研究过,但是我认为进一步研究可能是非常有用的。
结论
贝叶斯网络的难点在于设计。特别是,当你想到 SNA 时,用贝叶斯网络从社会网络构建映射是艺术而不是科学😃但是一旦你完成了艺术工作,并且很好地设计了你的模型,这些方便的工具可以告诉你很多事情。众所周知,贝叶斯网络在很多领域都有应用。在大多数情况下,它工作得非常好。因此,我坚信我们也可以对社交网络做出非常深刻的推论。
关于 SNA 和贝叶斯网络的进一步研究,请继续关注🚀
参考
- 科尔勒、戴维&普法茨、乔纳森&法瑞、迈克尔&考克斯、扎克&卡托、杰弗里&坎波隆戈、约瑟夫。(2006).贝叶斯信念网络在社会网络分析中的应用。
- https://www.edureka.co/blog/bayesian-networks/
- 图纸绘制在草图 io 中
- 样本网络取自https://www . probabilistic world . com/Bayesian-belief-networks-part-1/
BigQuery ML 简介
几个月前,谷歌宣布了一个名为 BigQuery ML 的新功能,目前正在测试中。它由一组 SQL 语言的扩展组成,允许创建机器学习模型,评估其预测性能,并直接在 BigQuery 中对新数据进行预测。
Source: https://twitter.com/sfeir/status/1039135212633042945
BigQuery ML (BQML)的一个优点是,一个人只需要知道标准 SQL 就可以使用它(不需要使用 R 或 Python 来训练模型),这使得机器学习更容易使用。它甚至处理数据转换、训练/测试集分割等。此外,它减少了模型的训练时间,因为它直接在存储数据的地方工作(BigQuery ),因此,没有必要将数据导出到其他工具。
但并不是一切都是优势。首先,实现的模型目前是有限的(尽管我们将看到它提供了一些灵活性),由于适应 SQL 的事实,这种情况可能会一直存在。其次(在我看来,更重要的是),即使 BQML 使模型训练变得更容易,但一个不熟悉机器学习的人仍然可能难以解释他们创建的模型,评估其性能并试图改进它。
在这篇文章中,我将解释 BQML 的主要功能,以及如何使用它们来创建我们的模型,评估它并使用它进行预测。这一过程将包括以下步骤:
- 创建数据集(可选)
- 创建模型
- 型号信息(可选)
- 评估模型
- 预测
创建数据集(可选)
与 BigQuery (BQ)表一样,模型必须保存在一个数据集中,因此首先您必须决定要将模型保存在哪个数据集中:现有的数据集还是新的数据集。
如果您的情况是后者,创建一个新的数据集就像下面这样简单:
- 在 BQ 界面中,选择要创建数据集的项目,点击“创建数据集”按钮。
2.命名新数据集,并选择存储数据的位置和到期时间。你可以在这个链接中找到关于这些领域的更多信息。
创建模型
在监督机器学习中,使用响应变量已知的训练数据集来生成模型,该模型捕获数据的潜在模式,以便它可以预测看不见的数据的结果。
BQML 允许您直接在 BigQuery 中完成这个过程。目前,它支持三种类型的模型:
- 线性回归。它用于预测连续数值变量的结果,如收入。
- 二元逻辑回归。它用于预测具有两个可能类别的分类变量的结果,例如当您想要确定用户是否会购买或而不是时。
- 多项逻辑回归(或多类)。它用于预测具有两个以上类别的分类变量的结果。
要使用 BQML 创建(和训练)模型,必须使用以下语法:
#standardSQL
{CREATE MODEL | CREATE MODEL IF NOT EXISTS | CREATE OR REPLACE MODEL} `project.dataset.model_name`
OPTIONS(model_option_list)
AS query_statement
此查询将使用指定的选项(options)创建一个模型(CREATE MODEL ),并将查询的结果(AS)用作训练数据。我们必须指定:
1)模型的名称及其保存位置。创建模型创建并训练模型(将在指定的数据集中以名称“ model_name ”保存),只要没有已创建的同名模型。如果模型名称存在,带有 CREATE MODEL 的查询将返回错误。为了避免这种错误,我们可以使用两种替代方法:
- 如果不存在,则创建模型,这将仅在没有已创建的同名模型的情况下创建和定型模型。
- 创建或替换模型,即创建模型(如果不存在)或替换模型(如果存在)并训练模型。
- 型号 _ 选项 _ 列表。指定与模型和培训过程相关的一些选项的列表。格式如下:选项 1 =值 1,选项 2 =值 2,… 两个最重要的选项是:
- model_type(强制):指定我们要训练的模型的类型: linear_reg 用于线性回归,或者 logistic_reg 用于二元或多类 logistic 回归。
- input_label_cols:指定包含响应变量的训练数据的表的列名。如果列名为标签,则该字段是可选的;如果不是,必须指定为 [‘列名’] 。
尽管 BigQuery ML 具有用于模型训练的默认选项,但是它提供了一些灵活性来选择与避免过度拟合和模型参数优化相关的选项。例如,我们可以应用正则化 L1 或 L2,将数据分为训练集和验证集,或者设置梯度下降的最大迭代次数。您可以在这个链接中找到所有可用的选项。
- 查询 _ 语句。生成将用作定型数据的表的查询。BigQuery ML 的一个优点是负责模型训练的数据转换。特别是:
- 分类特征(BOOL、STRING、BYTES、DATE、DATETIME 或 TIME 类型)是一次性编码的(即转换为每个类的二进制变量)。由于被称为多重共线性的问题,如果您想要得出关于特征和响应变量之间关系的结论,则不建议这样做。
- 数值特征(NUMERIC、FLOAT64 或 INT64 类型)针对训练数据和未来预测进行了标准化。
- 在数值变量的情况下,空值由平均值替换;在分类特征的情况下,空值由对所有这些缺失数据进行分组的新类替换。
关于响应变量,必须考虑到:
- 线性回归中不能有无穷大或 NaN 值。
- 在二元逻辑回归中,它必须正好有两个可能的值。
- 在多类逻辑回归中,最多可以有 50 个不同的类别。
例如,让我们想象一下,我们希望根据与用户浏览活动相关的几个特征(页面浏览量、会话持续时间、用户类型、他使用的设备以及是否是付费流量)来预测一个 web 会话最终是否会购买。如果你想了解这个例子,我们将使用 BigQuery 提供的谷歌分析测试数据集。为了创建模型,我们将使用以下查询:
#standardSQL
CREATE MODEL `project.dataset.sample_model`
OPTIONS(model_type='logistic_reg',
input_label_cols=['isBuyer'])
AS
SELECT
IF(totals.transactions IS NULL, 0, 1) AS isBuyer,
IFNULL(totals.pageviews, 0) AS pageviews,
IFNULL(totals.timeOnSite, 0) AS timeOnSite,
IFNULL(totals.newVisits, 0) AS isNewVisit,
IF(device.deviceCategory = 'mobile', 1, 0) AS isMobile,
IF(device.deviceCategory = 'desktop', 1, 0) AS isDesktop,
IF(trafficSource.medium in ('affiliate', 'cpc', 'cpm'), 1, 0) AS isPaidTraffic
FROM
`bigquery-public-data.google_analytics_sample.ga_sessions_*`
WHERE
_TABLE_SUFFIX BETWEEN '20160801' AND '20170630'
由于我们的响应变量具有两个分类(1 =“有购买”或 0 =“没有购买”),我们必须在选项中指定模型的类型是逻辑回归(logistic_reg)。另外,请注意,响应变量名为“isBuyer”,因此我们也必须在选项中指定它。
型号信息(可选)
在线性模型中,每个解释变量都有一个相关的系数(或权重),用于确定该特征和响应变量之间的关系。其幅度越大,对响应变量的影响就越大。此外,正(负)号表示当该解释变量的值增加时(或者,在分类变量的情况下,类别存在),响应是否增加(减少)。
在 BigQuery ML 中,我们可以使用以下查询来获取已训练模型的权重:
#standardSQL
SELECT *
FROM ML.WEIGHTS(MODEL `project.dataset.model_name`)
如前所述,如果您没有在查询中“手动”将分类变量转换为二进制变量(例如,正如我们对 isMobile 和 isDesktop 所做的那样),每个可能的类别都将有一个权重,并且系数的可靠性将由于多重共线性而受到损害。
例如,我们在上一节中创建的模型具有以下系数:
也就是说,作为一个新用户的会话,使用移动设备或通过付费渠道访问网络降低了访问以购买结束的概率。而使用桌面或者在网站上花更多的时间增加转化的概率。
评估模型
一旦我们有了训练好的模型,我们需要评估它的预测性能。这总是必须在不同于训练集的测试集上进行,以避免过度拟合,当我们的模型记忆我们的训练数据的模式时,就会发生过度拟合,因此它在我们的训练集中非常精确,但它不能在新数据中做出良好的预测。
BQML 提供了几个函数来评估我们的模型:
- ML。培训信息。提供有关模型定型期间迭代的信息,包括每次迭代时定型集和验证集中的损失。预期结果是两组中的损失都减少(理想情况下,减少到 0,这意味着模型总是正确的)。
- ML.EVALUATE .提供最常用的指标来评估模型的预测性能。此函数可用于任何类型的模型(线性回归、二元逻辑回归、多类逻辑回归),但根据是回归还是分类任务,度量标准会有所不同。
- ML。困惑 _ 矩阵。返回给定数据集的混淆矩阵,这使我们能够知道分类模型中每个可能类别的正确预测和错误。它只能用于分类模型,即逻辑回归和多类逻辑回归。
- ML。ROC_CURVE。此函数允许我们构建 ROC 曲线,这是一种用于评估二元分类模型预测能力的可视化图形。在这种情况下,它只能用于二元逻辑回归模型。
在这篇文章中,我们将关注 ML。评估,但我们将给出其他函数的语法和示例,以防有人对使用它们感兴趣。
ML。评价
要评估先前创建的模型,必须使用以下语法:
#standardSQL
SELECT *
FROM ML.EVALUATE(MODEL `project.dataset.model_name`,
{TABLE table_name | (query_statement)}
[, STRUCT(XX AS threshold)])
我们必须指定:
- 模型。
- 我们要为其计算评估度量的表,评估度量可以是查询的结果。显然,这个测试集必须与定型集具有相同的列,包括响应变量(以便将模型预测与实际值进行比较)。如果未指定表或查询,它将使用验证集(如果在创建模型时指定)或定型集(如果未指定验证集)。
- 在逻辑回归的情况下,阈值。此值是可选的,它指定了我们的模型的预测值(介于 0 和 1 之间的值,可以解释为该观察值属于类 1 的概率)将用于类 0 或类 1。默认情况下,阈值为 0.5。
此查询的结果是一个单行,其中包含评估模型预测的最常用指标,这取决于所使用的模型类型。
特别是,BigQuery ML 为逻辑回归和多类逻辑回归模型提供的指标有:
- 精确
- 召回
- 准确(性)
- f1 _ 分数
- 日志 _ 损失
- roc_auc
在线性回归的情况下,它们是:
- 平均绝对误差
- 均方误差
- 均方对数误差
- 中位数绝对误差
- r2 _ 分数
- 解释的差异
例如,对于我们示例中的逻辑回归,我们必须使用:
#standardSQL
SELECT *
FROM ML.EVALUATE(MODEL `project.dataset.sample_model`,
(
SELECT
IF(totals.transactions IS NULL, 0, 1) AS isBuyer,
IFNULL(totals.pageviews, 0) AS pageviews,
IFNULL(totals.timeOnSite, 0) AS timeOnSite,
IFNULL(totals.newVisits, 0) AS isNewVisit,
IF(device.deviceCategory = 'mobile', 1, 0) AS isMobile,
IF(device.deviceCategory = 'desktop', 1, 0) AS isDesktop,
IF(trafficSource.medium in ('affiliate', 'cpc', 'cpm'), 1, 0) AS isPaidTraffic
FROM
`bigquery-public-data.google_analytics_sample.ga_sessions_*`
WHERE
_TABLE_SUFFIX BETWEEN '20170701' AND '20170801'
),
STRUCT(0.5 AS threshold)
)
请注意,用于生成数据的日期与用于创建模型的日期不同。前一个查询的结果是:
评估模型的其他函数
1.ML。培训 _ 信息
语法:
#standardSQL
SELECT *
FROM ML.TRAINING_INFO(MODEL `project.dataset.model_name`)
示例:
#standardSQL
SELECT *
FROM ML.TRAINING_INFO(MODEL `project.dataset.sample_model`)
2.ML。困惑 _ 矩阵
语法:
#standardSQL
ML.CONFUSION_MATRIX(MODEL `project.dataset.model_name`,
{TABLE table_name | (query_statement)}
[, STRUCT(XX AS threshold)])
示例:
#standardSQL
SELECT *
FROM ML.CONFUSION_MATRIX(MODEL `project.dataset.sample_model`,
(
SELECT
IF(totals.transactions IS NULL, 0, 1) AS isBuyer,
IFNULL(totals.pageviews, 0) AS pageviews,
IFNULL(totals.timeOnSite, 0) AS timeOnSite,
IFNULL(totals.newVisits, 0) AS isNewVisit,
IF(device.deviceCategory = 'mobile', 1, 0) AS isMobile,
IF(device.deviceCategory = 'desktop', 1, 0) AS isDesktop,
IF(trafficSource.medium in ('affiliate', 'cpc', 'cpm'), 1, 0) AS isPaidTraffic
FROM
`bigquery-public-data.google_analytics_sample.ga_sessions_*`
WHERE
_TABLE_SUFFIX BETWEEN '20170701' AND '20170801'
),
STRUCT(0.5 AS threshold)
)
3.ML。ROC _ 曲线
语法:
#standardSQL
ML.ROC_CURVE(MODEL `project.dataset.model_name`,
{TABLE table_name | (query_statement)},
[GENERATE_ARRAY(thresholds)])
示例:
#standardSQL
SELECT *
FROM ML.ROC_CURVE(MODEL `project.dataset.sample_model`,
(
SELECT
IF(totals.transactions IS NULL, 0, 1) AS isBuyer,
IFNULL(totals.pageviews, 0) AS pageviews,
IFNULL(totals.timeOnSite, 0) AS timeOnSite,
IFNULL(totals.newVisits, 0) AS isNewVisit,
IF(device.deviceCategory = 'mobile', 1, 0) AS isMobile,
IF(device.deviceCategory = 'desktop', 1, 0) AS isDesktop,
IF(trafficSource.medium in ('affiliate', 'cpc', 'cpm'), 1, 0) AS isPaidTraffic
FROM
`bigquery-public-data.google_analytics_sample.ga_sessions_*`
WHERE
_TABLE_SUFFIX BETWEEN '20170701' AND '20170801'
),
GENERATE_ARRAY(0.0, 1.0, 0.01)
)
预测
要使用通过 BigQuery ML 创建的模型进行预测,必须使用以下语法:
#standardSQL
ML.PREDICT(MODEL model_name,
{TABLE table_name | (query_statement)}
[, STRUCT(XX AS threshold)])
该查询将使用一个模型(model ),并对一个新的数据集(TABLE)进行预测。显然,该表必须具有与定型数据相同的列,尽管没有必要包含响应变量(因为我们不需要它来预测新数据)。在逻辑回归中,您可以选择指定一个阈值,该阈值定义将哪个估计概率视为最终预测的一个类别或另一个类别。
该查询的结果将包含与我们提供的数据集一样多的行,并且将包括输入表和模型预测。在逻辑回归模型(二元或多类)的情况下,除了预测模型的类之外,还提供了每个可能类的估计概率。
继续我们的例子:
#standardSQL
SELECT *
FROM ML.PREDICT(MODEL `project.dataset.sample_model`,
(
SELECT
IFNULL(totals.pageviews, 0) AS pageviews,
IFNULL(totals.timeOnSite, 0) AS timeOnSite,
IFNULL(totals.newVisits, 0) AS isNewVisit,
IF(device.deviceCategory = 'mobile', 1, 0) AS isMobile,
IF(device.deviceCategory = 'desktop', 1, 0) AS isDesktop,
IF(trafficSource.medium in ('affiliate', 'cpc', 'cpm'), 1, 0) AS isPaidTraffic
FROM
`bigquery-public-data.google_analytics_sample.ga_sessions_*`
WHERE
_TABLE_SUFFIX BETWEEN '20170701' AND '20170801'
)
)
请注意,包含响应(isBuyer)的列不是必需的。前一个查询的结果是:
第一列返回我们的模型为每个新观察预测的类。第二列和第三列给出了每个类别的估计概率(估计概率较大的类别是第一列中的类别)。其余的列是我们请求其预测的数据。
化学信息学导论
化学信息学的常见挑战、库和数据集
Photo by Alex Kondratiev on Unsplash
什么是化学信息学?
随着计算能力的增加,机器学习在不同的科学领域中得到了许多应用。其中之一是化学,科学家应用机器学习模型来预测各种分子的属性,如其溶解性和毒性[1]或将其用于药物发现。
化学信息学是一个应用机器学习等计算方法来解决化学中各种问题的科学领域[2]。它提出了非常具有挑战性的问题,例如将 3D 分子结构转换为 ML 模型的输入,解决数据稀缺的问题,或者试图更好地理解哪个分子的特征对于预测是重要的[3]。
在本文中,我将温和地向您介绍化学信息学目前面临的几个问题,并列出一些可用的库和数据集,以帮助您开始涉足这一激动人心且富有挑战性的领域!
如何表示分子结构
分子可以被视为一个三维量子力学对象,它由分子内位置明确的原子组成[4]。你可以在这里提取大量信息:与每个分子的相对距离、原子序数、电子概率云的形状以及许多其他信息。
Photo by Holger Link on Unsplash
然而,在将这些信息转换为机器学习模型的输入时,很难保留所有这些信息。幸运的是,有一些现有的分子表示正在试图解决这个问题。
笑容
微笑是分子的一种类似文本的表示,它代表简化的分子输入行条目。除了它听起来别扭的名字之外,它还是最流行的表示分子的方式之一。事实上,一些深度学习模型直接接受微笑作为输入[5]。
你也应该意识到微笑表示确实会产生信息损失,这对训练机器学习模型非常重要。在将分子转换成微笑【4】时,像原子键的长度和分子的 3D 坐标位置这样的特征会丢失。
SMILES algorithm. [Source]
扩展连接指纹(ECFP)
*首先:什么是分子指纹?*分子指纹只是用数字表示分子的另一种方式。指纹产生的位状图案表明分子中某些亚结构的存在或不存在。生成这些模式背后的想法有点复杂,如果你感兴趣,可以看看这里的。
ECFP 是分子指纹的一个特例,它为任何分子的原子分配唯一的编号。编号取决于许多因素,如绝对电荷、重原子连接数、非氢键数量或原子电荷。这里需要注意的关键是,这种算法可以通过各种方式进行优化,并且可以由流行的化学信息学库 RDKit 处理。
流行的深度学习架构
一旦我们得到了正确形状的输入,我们应该决定哪种机器学习模型将有效地处理分子结构。在这里,我将为您提供一些在化学信息学中运行良好的流行架构。
递归神经网络
RNNs 与分子的 SMILES 表示一起工作得很好。由于 SMILES 是基于文本的表示,RNNs 可以用于预测序列中的另一个分子。它允许生成新的 SMILES 序列,这可能有助于发现具有所需特性(例如,某些溶解性或毒性)的分子。本文展示了用 RNNs 生成新分子的结果。
图形卷积网络
将 RNNs 和 CNN 一般化以将图形作为输入是一个相当困难的问题,在处理分子时经常会出现这种情况。图形卷积网络(gcn)通过将分子图及其特征作为输入来解决这个问题。更具体地说,图形连同每个节点(原子)的特征被转换成矩阵形式,然后插入到神经网络模型中。关于 GCNs 的深入文章可以在这里找到。
Image Convolution and Graph Convolution. [Source]
*我们为什么要使用 gcn?*根据文献[7],如果将分子表示为 2D 图,则保留了更多的信息。它还需要相对低的计算成本并达到高精度,这有助于类似 CNN 的架构。
公开可用的分子数据集
如果没有足够的数据,如何训练机器学习模型?这曾经是化学中的一个问题,但现在化学家们通常会将数据免费提供给每个人。我将在这里列出一些最受欢迎的分子数据集,以便您可以将其用作参考:)
公共化学
世界上最大的免费化学信息收集。它包含近 1 亿种化合物和超过 2.36 亿种物质。数据集似乎维护得很好,包括文档和教程。有大量关于物理和化学性质的信息,以及每种化合物的各种结构表示。绝对值得一探究竟!链接是这里的。
化学蜘蛛
这是一个与 Pubchem 非常相似的数据库,但是化学成分更少。在写这篇文章的时候,它包含了来自 270 个数据源的 7700 万个化学结构。如果你打算做一些大的事情,它可以和 PubChem 一起使用。这里的链接是这里的。
ChEMBL
这是一个人工筛选的数据集,包含具有类似药物特性的生物活性分子。目前,它包含 2M 化合物和 110 万种分析。此外,他们使用数据挖掘来收集更多关于分子的数据(例如,从专利文件中)。这里的链接是。
荣誉奖
一些鲜为人知但有用的数据集包括 Tox21 (毒理学)溶解度挑战,以及其他许多可以在 Kaggle 上找到的数据集。
有用的工具和 Python 库
深度化学
这是一个非常受欢迎和维护良好的 Python 库,在 Github 上有超过 1.7k 的 start。它为药物发现、量子化学和其他生命科学中的深度学习提供了开源工具链。他们网站的链接是这里。
RDKit
它是用 C++和 Python 编写的通用机器学习和化学信息学软件的集合。一些功能包括读写分子、亚结构搜索、化学转化或分子相似性。就我个人而言,我在我的笔记本电脑(Ubuntu)上很难设置它,但在 Conda 安装上它工作得很完美。他们网站的链接是这里。
荣誉奖
请看一下这个与化学相关的所有可用 Python 库的精选列表。
最后几句话要说
喜欢这篇关于化学信息学的文章吗?
确保你在 Medium 和 Linkedin 上关注我,我在那里发布了很多关于这个领域的有趣文章!你也可以在 Github 上找到我。
参考
[1] Pirashvili,m .,Steinberg,l .,Belchi Guillamon,f .,Niranjan,m .,Frey,j .和 Brodzki,J. (2019)。通过拓扑数据分析加深了对水溶性建模的理解。
[2]网上来源。可用这里。
[3]网上来源。约翰·加斯泰格。*化学信息学中已解决和未解决的问题。*可用此处。
[4]丹尼尔·c·埃尔顿、佐伊斯·鲍库瓦拉斯、马克·d·富格和彼得·w·琼加(2019)。用于分子设计的深度学习——当前技术水平综述
[5]潘德五世,沃尔特斯 P,伊斯曼 P,拉姆松达 B. 生命科学的深度学习
[6]网上来源。(2019).*计算扩展连接指纹。*此处可用。
[7] Seongok Ryu 等人。(2018).利用注意力和门增强图卷积网络深度学习分子结构-性质关系
计算机视觉导论
超越所有媒体噪音和魅力的计算机视觉的基本解释。
“我不害怕电脑。我担心缺乏他们。” —艾萨克·阿西莫夫
在过去的十年中,计算机视觉一直是一个流行的重复出现的术语,尽管随着时间的推移,它的流行程度已经从一个闻所未闻的主题变成了热门新闻。作为近年来成为一个趋势性话题的结果,对计算机视觉需要什么的理解有些嘈杂。因此,本文的目的是分解术语计算机视觉并分析其组成部分,从而提供对什么是计算机视觉的基本理解。
为了扩展计算机视觉的主题,我们首先需要分析术语(“计算机”和“视觉”)的组成部分,并对它们进行定义。
计算机可以被定义为能够根据软件或硬件指导的指令集执行各种处理、计算和操作的电子机器。
因此,视觉,更具体地说,通过视觉的视觉感知可以被定义为通过可见光谱对环境中的物体进行照明来理解局部环境。
结合这两个术语的定义,初步的解释是,计算机视觉是机器如何试图理解它们看到的东西以实现目标。
我们可以通过陈述计算机视觉是机器或系统通过调用一个或多个作用于所提供的信息的算法来产生对视觉信息的理解的过程来扩展上述定义。理解然后被转化为决策、分类、模式观察等等。
然后在应用程序、硬件和软件中利用整理理解的翻译,翻译可以采取多种形式,如下所示:
- 对象检测:在数字图像甚至视频中识别感兴趣的对象(猫、狗、汽车)
- 光学字符识别:将书写或打字的文本图像翻译成机器编码格式
- 指纹识别:使用人类指纹的模式信息在指纹源和作为目标的指纹之间进行比较。
当向大众介绍计算机视觉时,我们需要包括已经采取的方法,以便使系统能够推理发展理解,并因此开发计算机视觉的有用应用。
计算机视觉系统可以应用两种主要的策略来从已经提供给它的信息中获得理解。它们分别是:自下而上和自上而下的方法。
自下而上的方法包括利用对积累的信息的理解来对一些任意的观察进行进一步的理解;最终,所有积累的理解会导致对观察对象整体的解决方案或总体理解。
在计算机视觉应用中使用自底向上方法的一个例子是自动车牌识别。这种类型的应用似乎是交通超速摄像机的合理组成部分。
自动车牌识别(ANPR)通过自下而上的方法将视觉信息(车牌)传递到我们的计算机视觉系统中。该系统通过识别盘子上数字的边缘来进行某种形式的理解。从边缘信息,我们继续向上一个层次,并开始通过连接边缘来识别线(这里我们可以看到理解从一个层次到另一个层次的转移)。之后,线条可以连接起来形成形状,最后,我们通过识别线条相交的区域和边缘来观察字符。
自上而下的方法应用背景知识从观察中获得理解。背景知识作为选择适合模型的参数的参考指南(类似于深度学习技术的方法)。这种方法可以简单地概括为这样的过程,通过该过程,图像被分解为子成分,并且获得对片段信息的理解,以呈现对图像整体的理解。
从这篇文章中,我们了解了计算机视觉的定义及其组成部分。还提到了计算机视觉技术的一些应用领域。除此之外,我们还探索了这些系统中的计算机视觉技术在试图从信息中获得理解时可以采用的方法。
从这里开始,您可以了解一些基本的低级图像处理技术,如边缘检测、降噪、图像锐化等。
张量流卷积神经网络简介
学习计算机视觉卷积神经网络的基础,并使用 TensorFlow 构建 CNN
Photo by Stephanie Cook on Unsplash
深度学习的最新进展使计算机视觉应用向前迈进了一大步:从用我们的脸解锁手机,到更安全的自动驾驶汽车。
卷积神经网络 (CNN)是计算机视觉应用背后的架构。在这篇文章中,你将学习细胞神经网络和计算机视觉的基础,如卷积运算,填充,步长卷积和池层。然后,我们将使用 TensorFlow 构建一个用于图像识别的 CNN。
对于机器学习、深度学习和人工智能的实践视频教程,请查看我的 YouTube 频道。
Spiderman recognizing Spiderman…
理解卷积
顾名思义,卷积运算是卷积神经网络的构建模块。
现在,在计算机视觉领域,图像可以表示为 RGB 值的矩阵。这个概念实际上是在之前的一篇文章中介绍的。
为了完成卷积运算,我们需要一个图像和一个过滤器。
因此,让我们将下面的 6x6 矩阵视为图像的一部分:
6x6 matrix. Source
并且过滤器将是下面的矩阵:
3x3 filter. Source
然后,卷积包括将过滤器叠加到图像矩阵上,将来自过滤器的值和来自图像矩阵的值的乘积相加,这将生成 4x4 卷积层。
这很难用语言表达,但这里有一个很好的动画来解释这个卷积:
Convolution operation
对上面的图像矩阵执行此操作,并使用上面定义的过滤器,您应该得到下面的结果矩阵:
4x4 output layer. Source
如何解读输出层?
考虑到每个值都表示颜色,或者像素有多暗(正值表示亮,负值表示暗),您可以将输出图层解释为:
Output layer interpretation. Source
因此,似乎这个特殊的过滤器负责检测图像中的垂直边缘!
如何选择合适的滤镜?
这是一个很自然的问题,因为你可能会意识到有无数种可能的滤镜可以应用于一幅图像。
事实证明,您的过滤器矩阵中的精确值可以是基于模型目标的可训练参数。因此,您可以选择适合特定应用的滤波器,也可以使用反向传播来确定能够产生最佳结果的滤波器的最佳值。
计算机视觉中的填充
之前,我们已经看到,3x3 滤波器与 6x6 图像卷积将产生 4x4 矩阵。这是因为在 6×6 的图像中,有 4×4 的可能位置适合滤波器。
因此,在每个卷积步骤之后,图像会缩小,这意味着只能执行有限次数的卷积,直到图像无法再缩小为止。此外,位于图像角落的像素仅被使用一次,这导致神经网络的信息丢失。
为了解决上述两个问题,使用了填充。填充包括在输入图像周围添加边框,如下所示:
Input image with padding of 1
如你所见,添加的边框通常用零填充。现在,图像的角像素将被多次使用来计算输出,有效地防止信息丢失。此外,它允许我们在输出中保持输入矩阵的形状。
考虑我们的 6x6 输入图像,如果我们添加 1 的填充,我们得到一个 8x8 的矩阵。应用 3×3 滤波器,这将产生 6×6 输出。
一个简单的等式可以帮助我们计算出输出的形状:
Where n is the input shape, p is the padding size, and f is the filter shape
重申一下,我们有:
- 6x6 输入
- 填充 1
- 3x3 过滤器
因此,输出形状将是:6+2(1)-3+1 = 6。因此,输出将是一个 6x6 的矩阵,就像输入图像一样!
填充并不总是必需的。但是,当使用填充时,通常是为了使输出与输入图像具有相同的大小。这产生了两种类型的卷积。
当没有应用填充时,这被称为“有效卷积”。否则称为“同卷积”。要确定保持输入图像尺寸所需的填充大小,只需将上面的公式等同于 n 。求解完 p 后,你应该得到:
您可能已经注意到,为了使填充为整数, f 应该是奇数。因此,在计算机视觉领域,使用奇数滤镜是一种惯例。
步进卷积
之前,我们已经看到了步长为 1 的卷积。这意味着过滤器水平和垂直移动了 1 个像素。
跨距卷积是指跨距大于 1 的卷积。在下面的动画中,步幅是 2:
Convolution with a stride of 2
现在,考虑步幅,计算输出矩阵形状的公式为:
Where s is the stride
按照惯例,如果上面的公式不能得出一个整数,那么我们就向下舍入到最接近的整数。
池层
合并图层是另一种减少图像解释大小以加快计算速度的方法,它使检测到的特征更加稳健。
用一个图像来解释池是最好的。下面是最大池的一个例子:
Max pooling with a 2x2 filter
如您所见,我们选择了步幅为 2 的 2x2 滤波器。这相当于将输入分成 4 个相同的正方形,然后我们取每个正方形的最大值,并将其用于输出。
也可以执行平均池化,但是它不如最大池化流行。
您可以将池化视为防止过度拟合的一种方式,因为我们正在从输入图像中移除一些特征。
为什么要使用卷积神经网络?
我们现在有一个强大的卷积神经网络的基础知识。但是,深度学习从业者为什么要用呢?
与全连接层不同,卷积层需要学习的参数要少得多。这是因为:
- 参数共享
- 联系的稀疏性
参数共享是指一个特征检测器,例如垂直边缘检测器,将在图像的许多部分有用。那么,连接的稀疏性是指只有少数特征与某个输出值相关。
考虑上面的最大池示例,输出的左上值仅取决于输入图像的左上 2x2 正方形。
因此,我们可以在更小的数据集上进行训练,并大大减少要学习的参数数量,使 CNN 成为计算机视觉任务的一个伟大工具。
用 TensorFlow 构建 CNN
理论讲够了,让我们为手势识别编写一个 CNN。我们重温一个以前的项目,看看 CNN 是否会表现得更好。
一如既往,完整的笔记本可在这里获得。
步骤 1:预处理图像
导入所需的库和资产后,我们加载数据并预处理图像:
步骤 2:创建占位符
然后,我们为特征和目标创建占位符:
步骤 3:初始化参数
然后,我们使用 Xavier 初始化来初始化参数:
步骤 4:定义正向传播
现在,我们定义正向传播步骤,这实际上是我们 CNN 的架构。我们将使用一个简单的三层网络,包括两个卷积层和一个全连接层:
第五步:计算成本
最后,我们定义一个函数来计算成本:
步骤 6:将所有功能组合成一个模型
现在,我们将上述所有功能合并到一个 CNN 网络中。我们将使用小批量梯度下降进行训练:
太好了!现在,我们可以运行我们的模型,看看它的表现如何:
_, _, parameters = model(X_train, Y_train, X_test, Y_test)
在我的例子中,我在只使用 CPU 的笔记本电脑上训练 CNN,我得到了一个相当糟糕的结果。如果你在有更好的 CPU 和 GPU 的台式机上训练 CNN,你肯定会得到比我更好的结果。
恭喜你!你现在对 CNN 和计算机视觉领域有了很好的了解。尽管还有更多的东西需要学习,但是更高级的技术使用这里介绍的概念作为构建模块。
在下一篇文章中,我将介绍 Keras 的剩余网络!
干杯!
参考: deeplearning.ai
Python 中的数据可视化简介
如何使用 Matplotlib,Pandas 和 Seaborn 制作图形
Figure 1: Photo by Lukas Blazek on Unsplash
数据可视化是一门学科,它试图通过将数据置于可视化的环境中来理解数据,从而揭示出可能无法检测到的模式、趋势和相关性。
Python 提供了多个优秀的图形库,这些图形库包含了许多不同的特性。无论你是想创建交互式的、实时的还是高度定制的情节,python 都为你提供了一个优秀的库。
下面是一些流行的绘图库:
- Matplotlib:低等级,提供了大量的自由
- 熊猫可视化: 易于使用的界面,基于 Matplotlib 构建
- Seaborn:高级界面,绝佳的默认样式
- gg plot:基于 R 的 ggplot2,采用图形的语法
- 剧情: 可以创建互动剧情
在本文中,我们将学习如何使用 Matplotlib、Pandas visualization 和 Seaborn 创建基本的绘图,以及如何使用每个库的一些特定功能。本文将关注语法,而不是解释图形,我将在另一篇博客文章中介绍。
在以后的文章中,我将介绍像 Plotly 这样的交互式绘图工具,它构建在 D3 上,也可以与 JavaScript 一起使用。
导入数据集
在本文中,我们将使用两个免费提供的数据集。 Iris 和葡萄酒评论数据集,我们都可以使用 pandas read_csv
方法加载。
Figure 2: Iris dataset head
Figure 3: Wine Review dataset head
Matplotlib
Matplotlib 是最流行的 python 绘图库。这是一个低级的库,有一个类似 Matlab 的接口,提供了很多自由,代价是必须写更多的代码。
要安装 Matplotlib,可以使用 pip 和 conda。
**pip install matplotlib
or
conda install matplotlib**
Matplotlib 特别适合创建基本的图表,如线形图、条形图、直方图等等。可以通过键入以下内容来导入它:
**import matplotlib.pyplot as plt**
散点图
要在 Matplotlib 中创建散点图,我们可以使用scatter
方法。我们还将使用plt.subplots
创建一个图形和一个轴,这样我们就可以给我们的绘图一个标题和标签。
Figure 4: Matplotlib Scatter plot
我们可以通过按类别给每个数据点着色来赋予图表更多的意义。这可以通过创建一个从类映射到颜色的字典来完成,然后使用 for 循环分散每个点并传递各自的颜色。
Figure 5: Scatter Plot colored by class
折线图
在 Matplotlib 中,我们可以通过调用plot
方法来创建折线图。我们还可以在一个图形中绘制多个列,方法是循环遍历我们需要的列,并将每个列绘制在同一轴上。
Figure 6: Line Chart
柱状图
在 Matplotlib 中,我们可以使用hist
方法创建一个直方图。如果我们向它传递分类数据,如葡萄酒评论数据集中的 points 列,它将自动计算每个类出现的频率。
Figure 7: Histogram
条形图
可以使用bar
方法创建条形图。条形图不会自动计算类别的频率,所以我们将使用 pandas value_counts
函数来完成这项工作。条形图对于没有太多不同类别(少于 30 个)的分类数据非常有用,因为否则它会变得非常混乱。
Figure 8: Bar-Chart
熊猫可视化
Pandas 是一个开源的高性能、易于使用的库,它提供了数据结构(如数据帧)和数据分析工具(如我们将在本文中使用的可视化工具)。
熊猫可视化使得从熊猫数据帧和系列中创建情节变得非常容易。它还拥有比 Matplotlib 更高级的 API,因此我们需要更少的代码来获得相同的结果。
Pandas 可以使用 pip 或 conda 安装。
**pip install pandas
or
conda install pandas**
散点图
为了在 Pandas 中创建散点图,我们可以调用<dataset>.plot.scatter()
并向它传递两个参数,x 列的名称和 y 列的名称。可选地,我们也可以传递给它一个标题。
Figure 9: Scatter Plot
正如您在图像中看到的,它会自动将 x 和 y 标签设置为列名。
折线图
为了创建熊猫的折线图,我们可以称之为<dataframe>.plot.line()
。在 Matplotlib 中,我们需要循环遍历我们想要绘制的每一列,而在 Pandas 中,我们不需要这样做,因为它会自动绘制所有可用的数字列(至少如果我们没有指定特定的列)。
Figure 10: Line Chart
如果我们有一个以上的功能,熊猫会自动为我们创建一个图例,如上图所示。
柱状图
在熊猫中,我们可以用plot.hist
方法创建一个直方图。没有任何必需的参数,但是我们可以有选择地传递一些参数,比如 bin 的大小。
Figure 11: Histogram
创建多个直方图也非常容易。
Figure 12: Multiple Histograms
subplots
参数指定我们想要为每个特征单独绘图,而layout
指定每行和每列的绘图数量。
条形图
为了绘制条形图,我们可以使用plot.bar()
方法,但是在调用这个方法之前,我们需要获取数据。为此,我们将首先使用value_count()
方法对事件进行计数,然后使用sort_index()
方法从最小到最大对事件进行排序。
Figure 13: Vertical Bar-Chart
使用plot.barh()
方法制作水平条形图也非常简单。
Figure 14: Horizontal Bar-Chart
我们也可以绘制其他数据,然后是出现的次数。
Figure 15: Countries with the most expensive wine(on average)
在上面的例子中,我们按国家对数据进行分组,然后取葡萄酒价格的平均值,对其排序,并绘制出平均葡萄酒价格最高的 5 个国家。
海生的
Seaborn 是一个基于 Matplotlib 的 Python 数据可视化库。它为创建吸引人的图形提供了一个高级接口。
Seaborn 有很多东西可以提供。在 Matplotlib 中,你可以用一行创建几十行的图形。它的标准设计非常棒,而且它还有一个很好的界面来处理熊猫数据框。
可以通过键入以下内容来导入它:
**import seaborn as sns**
散点图
我们可以使用.scatterplot
方法创建散点图,就像在 Pandas 中一样,我们需要传递 x 和 y 数据的列名,但现在我们也需要传递数据作为附加参数,因为我们没有像在 Pandas 中那样直接调用数据上的函数。
Figure 16: Scatterplot
我们还可以使用hue
参数按类突出显示要点,这比在 Matplotlib 中容易得多。
Figure 17: Scatterplot colored by class
折线图
可使用sns.lineplot
方法创建折线图。唯一需要的参数是数据,在我们的例子中是 Iris 数据集中的四个数字列。我们也可以使用sns.kdeplot
方法,如果你的数据集中有很多异常值,这种方法会使曲线的边缘变圆,因此更干净。
Figure 18: Line Chart
柱状图
为了在 Seaborn 中创建直方图,我们使用了sns.distplot
方法。我们需要将我们想要绘制的列传递给它,它会自己计算出现的次数。如果我们想在图中画出高斯核密度估计值,我们也可以传递给它箱的数量。
Figure 19: Histogram
Figure 20: Histogram with gaussian kernel density estimate
条形图
在 Seaborn 中,可以使用sns.countplot
方法创建一个条形图,并将数据传递给它。
Figure 21: Bar-Chart
其他图表
现在你已经对 Matplotlib、Pandas Visualization 和 Seaborn 语法有了一个基本的了解,我想向你展示一些对提取内部有用的其他图形类型。
对他们中的大多数人来说,Seaborn 是首选库,因为它的高级接口只需要几行代码就可以创建漂亮的图形。
箱线图
方框图是显示五个数字汇总的图形方法。我们可以使用 seaborns sns.boxplot
方法创建箱线图,并向它传递数据以及 x 和 y 列名。
Figure 22: Boxplot
箱线图,就像条形图一样,对于只有几个类别的数据来说是很好的,但是会很快变得混乱。
热图
热图是数据的图形表示,其中包含在矩阵中的单个值用颜色表示。热点图非常适合探索数据集中要素的相关性。
为了获得数据集中特征的相关性,我们可以调用<dataset>.corr()
,这是一个 Pandas dataframe 方法。这将给我们相关矩阵。
我们现在可以使用 Matplotlib 或 Seaborn 来创建热图。
Matplotlib:
Figure 23: Heatmap without annotations
要向热图添加注释,我们需要添加两个 for 循环:
Figure 24: Heatmap with annotations
Seaborn 使创建热图和添加注释变得更加容易:
Figure 25: Heatmap with annotations
刻面
分面是将数据变量分解成多个子情节并将这些子情节组合成一个图形的行为。
如果想快速浏览数据集,分面真的很有帮助。
要在 Seaborn 使用一种刻面,我们可以使用FacetGrid
。首先,我们需要定义FacetGrid
并向它传递我们的数据以及一行或一列,它们将用于拆分数据。然后我们需要在我们的FacetGrid
对象上调用map
函数,并定义我们想要使用的绘图类型,以及我们想要绘制的列。
Figure 26: Facet-plot
你可以做出比上面例子更大更复杂的图。你可以在这里找到几个例子。
配对图
最后,我将向您展示 Seaborns pairplot
和 Pandas scatter_matrix
,它们使您能够在数据集中绘制成对关系的网格。
Figure 27: Pairplot
Figure 28: Scatter matrix
正如你在上面的图片中所看到的,这些技术总是将两个特征彼此结合在一起。图表的对角线用直方图填充,其他图是散点图。
推荐阅读
如何使用 Python Reddit API 包装器从 Reddit 抓取数据(PRAW)
towardsdatascience.com](/scraping-reddit-data-1c0af3040768)****
结论
数据可视化是一门学科,它试图通过将数据置于可视化的环境中来理解数据,从而揭示出可能无法检测到的模式、趋势和相关性。
Python 提供了多个优秀的图形库,这些图形库包含了许多不同的特性。在本文中,我们研究了 Matplotlib、Pandas visualization 和 Seaborn。
如果你喜欢这篇文章,可以考虑订阅我的 Youtube 频道,在社交媒体上关注我。
本文涵盖的代码可以从 Github 资源库获得。
如果你有任何问题、建议或批评,可以通过推特或评论区联系我。
决策智能简介
人工智能时代领导力的新学科
好奇想知道在大草原上躲避狮子的心理与负责任的人工智能领导和设计数据仓库的挑战有什么共同点吗?欢迎来到决策智能!
决策智能是一门的新学科与选项选择的所有方面有关。它将最好的应用数据科学、社会科学和管理科学汇集到一个统一的领域,帮助人们使用数据改善他们的生活、业务和周围的世界。对于人工智能时代来说,这是一门至关重要的科学,涵盖了负责任地领导人工智能项目所需的技能,以及为大规模自动化设计目标、指标和安全网。
决策智能是在任何规模下将信息转化为更好行动的学科。
让我们浏览一下它的基本术语和概念。这些章节的设计有利于略读(也有跳读,也就是跳过无聊的部分……有时甚至完全跳过阅读)。
什么是决定?
数据很美,但重要的是决策。通过我们的决定——我们的行动——我们影响着周围的世界。
我们将单词*“decision”*定义为任何实体在选项之间的任何选择,因此对话的范围比 MBA 式的困境更广(比如是否在伦敦开设一家分公司)。
通过我们的决定——我们的行动——我们影响着周围的世界。
在这个术语中,在用户的照片上附加一个标签,如猫与非猫是由计算机系统执行的决定,而弄清楚是否启动该系统是由人类领袖深思熟虑后做出的决定(我希望!负责这个项目。
Decisions, decisions, decisions. Image: SOURCE
什么是决策者?
在我们的说法中,一个“ 决策者 ”不是那个突然出现否决项目团队阴谋的利益相关者或投资者,而是负责决策架构和上下文框架的人。换句话说,一个精心措辞的目标的创造者,而不是他们的破坏者。
什么是决策?
决策是一个不同学科使用不同的词,所以可以指:
- 当有其他选择时采取行动(在这个意义上,可以说是由计算机或蜥蜴做决策)。
- 履行(人类)决策者的职能,其中一部分是负责决策。尽管计算机系统可以执行决策,但它不能被称为决策者,因为它不对其输出承担责任——这一责任完全落在创造它的人类肩上。
计算与决策
并非所有的输出/建议都是决策。在决策分析术语中,只有当不可撤销的资源分配发生时才做出决策。只要你能免费改变你的想法,还没有做出任何决定。
决策智能分类法
学习决策智能的一种方法是按照传统路线将其分为定量方面(与应用 数据科学大部分重叠)和定性方面(主要由社会和管理科学的研究人员开发)。
定性方面:决策科学
构成定性方面的学科传统上被称为决策科学——我喜欢把整个事物都叫做决策科学(唉,我们不能总是得到我们想要的)。
Image: SOURCE
决策科学关心的问题有:
- 你应该如何建立决策标准和设计你的度量标准(全部)
- “您选择的指标是否与激励相容*?”*(经济学)
- “你应该以什么样的质量做出这个决定,你应该为完美的信息支付多少钱?”【决策分析】
- “情绪、启发和偏见如何影响决策?”(心理学)
- “像皮质醇水平这样的生物因素是如何影响决策的?”(神经经济学)
- “改变信息呈现方式如何影响选择行为?”(行为经济学)
- “在团队环境中做决策时,你如何优化你的结果?”(实验博弈论)
- “在设计决策环境时,您如何平衡众多约束和多阶段目标?”(设计)
- “谁将体验决策的后果,各种群体将如何看待这种体验?”(UX 研究)
- “决策客观道德吗?”【哲学】(T13)
这只是小试牛刀…还有更多!这也远远不是所涉及学科的完整列表。可以认为决策科学是以模糊的存储形式(人脑)来处理决策设置和信息处理,而不是以半永久性存储方式(纸质或电子形式)整齐地写下来的那种,我们称之为数据。
你大脑的问题
在上个世纪,赞美那些将大量数学知识投入到人类毫无察觉的努力中的人是一种时尚。采取定量的方法通常比轻率的混乱要好,但是有一种方法可以做得更好。
基于纯数学理性的策略相对幼稚,往往表现不佳。
基于纯数学理性而没有对决策和人类行为的定性理解的策略可能是相当幼稚的,并且相对于那些基于共同掌握定量和定性方面的策略来说,往往表现不佳。(请继续关注关于社会科学中理性历史的博客文章,以及心理学击败数学的行为博弈论的例子。)
人类不是优化者,我们是 满足者 ,这是对切角者的一个花哨说法。
人类不是优化者,我们是 满足者 ,这是一个对切角者的花哨称呼,他们满足于足够好而不是完美。(这也是一个足以打击我们人类傲慢的概念——这是对理性的、神圣的、完美的人的一记重拳——它值得获得诺贝尔奖。)
Aristotle thought that the brain was a glorified air conditioner for the heart. I guess the brain looks less impressive when it’s on the outside… Image: SOURCE
事实上,我们人类都使用认知启发法来节省时间和精力。这通常是件好事;在我们还没开始计算之前,想出完美的跑步路线来逃离大草原上的狮子会让我们被吃掉。满足感也降低了生活的卡路里成本,这是好事,因为我们的大脑是荒谬的耗电设备,尽管体重约为 3 磅,却吞噬了我们约五分之一的能量支出。(我打赌你总重量超过 15 磅,对吗?)
我们走的一些捷径会导致可预见的次优结果。
既然我们大多数人都不会整天躲避狮子,我们走的一些捷径会导致可预见的垃圾结果。我们的大脑并不完全适合现代环境。了解我们这个物种将信息转化为行动的方式,可以让你使用决策过程来保护自己免受自己大脑缺陷的影响(以及那些故意利用你本能的人的影响)。如果这个可怜的东西追赶达尔文的速度慢得惊人,它还可以帮助你构建工具,增强你的表现,并使你的环境适应你的大脑。
如果你认为人工智能把人类排除在外了,那就再想想吧!
顺便说一句,如果你认为人工智能将人类排除在等式之外,请三思!所有技术都是其创造者的反映,大规模运行的系统会放大人类的缺点,这就是为什么发展决策智能技能对于负责任的人工智能领导如此必要的一个原因。点击此处了解更多信息。
Image: SOURCE
也许你没有做决定
有时候,仔细思考你的决策标准会让你意识到世界上没有任何事实会改变你的想法——你已经选择了你的行动,现在你只是在寻找一种让它感觉更好的方式。这是一个有用的认识——它阻止你浪费更多的时间,帮助你在做你无论如何都要做的事情时转移你的情绪不适,让数据见鬼去吧。
“他用 统计 就像一个醉汉用灯柱……来支撑而不是照明。”——安德鲁·朗
除非你会对不同的未知事实采取不同的行动,否则这里没有决定…尽管有时决策分析的培训会帮助你更清楚地看到那些情况。
完全信息下的决策
现在想象一下,你已经非常小心地制定了一个决策,这个决策对事实非常敏感,你可以打响指来查看执行决策所需的事实信息。你需要数据科学做什么?没什么,就是这样。
当务之急应该是弄清楚我们会如何对事实做出反应。
没有什么比事实更好的了——你肯定知道的事情(是的,我知道这里有一个相对主义者的大兔子洞,让我们继续)——所以如果我们有事实,我们总是更喜欢根据事实做决定。这就是为什么当务之急应该是弄清楚我们想要如何处理事实。您希望将您的理想信息用于以下哪种用途?
Your author particularly enjoyed this wall in Jamaica. Image: SOURCE
你能用事实做什么?
- 你可以用事实做出一个重要的预先设定好的决定。如果它足够重要,你将需要大量依靠事物的定性方面来明智地制定你的决定。心理学家知道,如果你让自己遭到意外信息的袭击,它会以你不喜欢的方式操纵你,所以他们(和其他人)有很多话要说,如何提前选择你会接受的信息。
- 你可以利用事实做出一种特殊的预先框定的决策,称为影响(或因果)决策。如果你的决定是以采取行动导致某事发生为框架的,那么你需要因果关系的事实来做决定。在这种情况下,如果没有关于原因的事实(例如“因为抗生素”),关于效果的事实(例如“人们从这种疾病中康复”)对你是无用的。得到因果信息的方法是做一个受控的 实验 。另一方面,如果你正在做一个执行决定,作为对一个非因果事实的回应(例如,“如果我的储蓄账户里至少有 x ,我会给自己买双新鞋”),那么实验就没有必要了。
- 你可以用事实来支撑观点(“我预计外面是晴天”变成了“我知道外面是晴天”)。
- 你可以用事实来做出一个重要的基于生存的决定。基于存在的决策(“我刚刚发现隔壁有一个埃博拉病例,所以我马上离开这里……”)是这样的决策,以前未知的未知的存在动摇了你的方法的基础,以至于你事后意识到你的决策背景是草率制定的。
- 您可以使用事实来自动化大量决策。在传统编程中,人类指定一组指令,用于将事实输入转换成适当的动作,可能涉及类似查找表的东西。
- 您可以使用事实来揭示自动化解决方案。通过查看关于系统的事实,您可以基于它们编写代码。比起在没有任何信息的情况下绞尽脑汁想出解决方案的结构,这是一种更好的传统编程方法。例如,如果您不知道如何将摄氏温度转换为华氏温度,但是您可以使用数据集来查找与摄氏温度输入相匹配的华氏温度条目…但是如果您分析该查找表本身,您会发现将它们联系起来的公式。然后,您只需编写一个公式(“模型”)来为您完成您的脏工作,丢掉笨重的表格。
- 您可以使用事实来生成自动化问题的最佳解决方案,这是完全可以解决的。这是传统的优化。你会在运筹学领域找到很多例子,其中包括如何争论约束以获得理想结果,比如完成一系列任务的最佳顺序。
- 你可以用事实来启发你如何做未来的重要决定。这是分析的一部分,也属于部分信息部分。保持这种想法!
- 你可以用事实来评估你正在处理的事情。这有助于您了解可用于未来决策的输入类型,并设计如何更好地管理您的信息。如果你刚刚继承了一个充满潜在成分的又大又黑的(数据)仓库,你不会知道里面有什么,直到有人看了它。幸运的是,你的分析师有手电筒和旱冰鞋。
- 你可以草率地用事实做出没有框架的决定。当决策的风险足够低,以至于不值得花力气去仔细对待它们时,这种方法是有效的,例如,“我今天午餐应该吃什么?”试图在所有决策上始终保持严格会产生次优的长期/终生结果,并且属于无意义的完美主义。把你的努力留到足够重要的情况下,但是请不要忘记,即使使用低质量低努力的方法是有效的,最佳决策方法仍然是低质量的。当这是你的方法时,你不应该捶胸顿足或过于自信…如果你抄近路,你拿着的东西是脆弱的。有些情况下,脆弱可以完成工作,但这不会突然让你的结论变得坚定。不要靠在上面。如果你想要高质量的决策,你需要一个更严谨的方法。
通过决策科学的培训,你学会了减少做出基于事实的严格决策所需的努力,这意味着同样的工作量现在可以让你全面获得更高质量的决策。这是一项非常有价值的技能,但是需要大量的工作来磨练它。例如,行为经济学的学生养成了在信息之前设定决策标准的习惯。例如,我们这些从要求非常高的决策科学培训项目中受到打击的人不禁会问自己,在我们查询票价之前,我们最多会为一张票支付多少钱。
数据收集和数据工程
如果我们有事实,我们早就完事了。唉,我们生活在现实世界中,经常我们必须为我们的信息工作。数据工程是一门复杂的学科,致力于大规模可靠地获取信息。就像去杂货店买一品脱冰淇淋很容易一样,当所有可用的相关信息都在一个电子表格中时,数据工程也很容易。
Image: SOURCE
当你开始要求运送 200 万吨冰淇淋时,事情就变得棘手了……在那里冰淇淋是不允许融化的!如果你必须设计、建立和维护一个巨大的仓库,事情会变得更加棘手,你甚至不知道未来会要求你储存什么——也许是几吨鱼,也许是钚……祝你好运!
当你甚至不知道下周你将被要求储存什么时,建立一个仓库是很棘手的——也许是几吨鱼,也许是钚…祝你好运!
虽然数据工程是一个独立的姐妹学科,也是决策智能的主要合作者,但决策科学在建议设计和管理事实收集方面有着深厚的专业传统。
定量方面:数据科学
当你制定了你的决定,并且使用搜索引擎或分析师(为你扮演人肉搜索引擎的角色)查找了你需要的所有事实,剩下的就是执行你的决定。你完了!不需要花哨的数据科学。
如果在所有的跑腿工作和工程柔术之后,交付的事实并不是您理想的决策所需的事实呢?如果它们只是部分事实呢?也许你想要明天的事实,但你只有过去能通知你。(记不住未来的时候好烦。)也许你想知道你所有的潜在用户对你的产品的看法,但是你只能问一百个用户。然后你就在处理不确定性!你知道的并不是你希望知道的。进入数据科学!
自然,当你拥有的事实不是你需要的事实时,你应该期待你的方法会改变。也许它们是一个更大拼图中的一块拼图(就像来自更大的人口的样本一样)。也许它们是错误的谜题,但却是你最好的谜题(就像用过去预测未来一样)。当你被迫跨越数据时,数据科学变得有趣起来……但是一定要小心避免伊卡洛斯式的重击!
- 你可以利用部分事实,通过统计推断做出一个重要的预先设定的决定,用假设补充你已有的信息,看看你是否应该改变你的行动。这是 Frequentist(古典)统计。如果你正在做一个影响决策(框架为采取行动导致某事发生,例如“如果导致更多人访问你的网站,你只想将你的标志颜色改为橙色”),那么最好使用来自随机控制 实验 的数据。如果你正在做一个执行的决定(例如“如果至少 25%的用户认为橙色是他们最喜欢的颜色,你只想把你的标志颜色改成橙色”),一个调查或观察研究就足够了。
- 你可以利用部分事实合理地将观点更新为更有见识的(但仍然是不完善的和个人的)观点。这是贝叶斯统计。如果这些观点涉及因果关系,最好使用来自受控随机实验的数据。
- 你的部分事实可能包含关于存在的事实,这意味着你可以在事后利用它们做出基于存在的决定(见上文)。
- 您可以使用部分事实来自动化大量决策。这是传统的编程,使用类似查找表的东西,将你以前没有见过的东西转换成你拥有的最接近的东西,然后照常进行。(简而言之,这就是 k-NN 所做的……当果壳中有更多的东西时,它通常会工作得更好。)
- 您可以使用部分事实来激发自动化解决方案。通过查看系统的部分事实,您仍然可以基于您所看到的内容编写代码。这是分析。
- 你可以使用部分事实为一个不完美的可解自动化问题生成一个体面的解决方案,这样你就不必自己想出这个方案。这是机器学习和 AI 。
- 你可以用部分事实来启发你如何做未来的重要决定。这是分析。
- 你可以使用部分事实来理解你正在处理的事情(见上文),并通过高级分析来加速自动化解决方案的开发,例如通过激发新的方法来将信息融合在一起,以制作有用的模型输入(行话是*“特征工程”*)或在人工智能项目中尝试新的方法。
- 你可以草率地使用部分事实来做出无框架的决定,但是要注意质量甚至比你草率地使用事实时还要低,因为你实际知道的与你希望知道的差了一步。
对于所有这些用途,都有办法整合来自各种以前孤立的学科的智慧,以便更有效地制定决策。这就是什么是决策智能!它汇集了对决策的不同观点,使我们所有人更加强大,并给予他们新的声音,摆脱他们最初研究领域的传统限制。
To return to the kitchen analogy for AI, if research AI is building microwaves and applied AI is using microwaves, decision intelligence is using microwaves safely to meet your goals and using something else when you don’t need a microwave. The goal (objective) is always the starting point for decision intelligence. Image: SOURCE
如果你想了解更多,我这里关于 Medium.com 的大部分文章都是从决策智能的角度写的。我的启动人工智能项目的指南可能是最不微妙的,所以如果你还没有通过这篇文章中的链接选择你自己的冒险,我推荐你去那里潜水。
感谢阅读!人工智能课程怎么样?
如果你在这里玩得开心,并且你正在寻找一个为初学者和专家设计的有趣的应用人工智能课程,这里有一个我为你制作的娱乐课程:
Enjoy the entire course playlist here: bit.ly/machinefriend