学习用 Python 提取嵌套字典数据
辅导的
揭开 Python JSON、字典和列表的神秘面纱
JSON:字典和列表数据结构(类型),作者图片。
“生活就像洋葱,你只能一次剥开一层,有时还会流泪”――卡尔·桑德伯格
我想从嵌套的 JSON 结构中提取值也是如此。当处理由深度嵌套的数据结构混合组成的 JSON 对象时,即使是最熟练的程序员也会流泪。提取值的过程充其量只能说是混乱无序的。数据越多,越乱。
作者创建的课程
在本教程中,我将带您一步步地从任何 JSON 中提取您需要的值。给你一个警告:这个教程不是给 JSON、列表或字典的新手看的。如果你从未听说过列表索引或字典键值对,我建议你查阅一下网站或 YouTube 上的许多优秀教程。一旦你对这门课感觉更舒服了,再回来继续学习和成长。
家政
JSON 与列表和字典
首先,当谈到术语“JSON”、“list”和“dictionary”时,我们必须做一些重要的整理工作。JSON 或 JavaScript Object Notation 是一种更广泛的格式,用于包含字典和列表结构,如下图所示。
JSON:列表和字典结构,作者图片。
技术文档称 JSON 对象建立在两种结构上:一个键值对列表和一个有序的值列表。在 Python 编程中,键值对是字典对象,有序列表是列表对象。实际上,提取嵌套数据的起点是从字典或列表数据结构开始的。提取嵌套数据时,问题应该是:数据是嵌套在字典还是列表数据结构中?使用的数据结构组合是什么?使用的第一个数据结构是字典还是列表?
“长期以来,我的一条公理是,小事永远是最重要的。”——阿瑟·柯南·道尔爵士,
如果看起来我在术语上小题大做,那是因为我确实如此。当提取嵌套数据时,细节很重要。数据结构变化数据在 JSON 结构中嵌套得越深,知道这些区别就越重要**。最初的数据结构可能是一个列表,但在提取数据时会变成一个字典。从 JSON 对象中提取数据的关键是识别用于存储数据的混合数据结构。如果您努力识别 JSON 对象中的数据结构,很可能您会努力提取您想要的值。在大多数情况下,这会导致应用错误的**提取技术。****
下表简要回顾了用于从 JSON 结构中提取数据的技术。
数据类型和提取方法,按作者分类的图像
在开始我们的例子之前,最后一点需要注意。在 Python 编程中,术语“数据结构”在描述列表和字典时很少使用。常用的术语是“数据类型”。在本教程中,我会交替使用数据类型和数据结构这两个术语。我使用术语数据结构,因为它传达了数据结构是 JSON 对象的基本构建块的思想。在 Python 中,术语“数据类型”的使用同样重要,但是它与理解嵌套数据提取的关键意义不同。
真实世界数据
我们开始吧
最好的学习方法之一是通过混合使用列表和字典数据结构来处理真实数据。在本教程中,我们将使用来自 REST 国家 API 的真实数据。这个 API 返回大约 250 条记录,混合了字典、列表和其他数据类型。我们的目标是从字典键值对'code':'AFN'
中提取'AFN’
值,如下图所示。'AFN'
嵌套在两个列表结构和一个字典结构中。
其他国家 API 数据,按作者分类的图片
示例代码
单击此链接将允许您访问以下示例中的示例代码。该链接将带您进入我开发的关于学习提取嵌套 JSON 数据的课程。这门课程已经帮助数百名学生学会了提取嵌套数据。您不必购买课程来获取文件。文件名是 single_json.py 和 multiple_json.py。
提取单个项目
在本例中,我们将从使用列表和字典提取技术的组合来提取数据开始,如上表所示。在下面的 Python 代码中,我首先提供了用于导入数据的逻辑**、用于导出解决方案的解决方案以及用于导出解决方案的工作流。我建议遵循如下所示的所有步骤。Python 代码下面解释了工作流步骤。**
Python 代码:
工作流程步骤:
**Step 1: import requests**
:这一行为 Python 导入请求 HTTP 库。它是我们用来连接 Restful API 的库。如果您还没有安装它,您可以使用 pip 安装请求命令从命令提示符或虚拟环境安装它。**Step 2:** **url = 'https://restcountries.eu/rest/v2/all'**
这一行存储了 REST API 的网址。地址存储在url
变量中。**Step 3: response = requests.get(url)**
: 该方法用于连接 Restful APIhttps://restcountries.eu/rest/v2/all,提取数据。返回的数据存储在response
变量中。在技术术语中,这被称为响应对象。**Step 4: storage = response.json()**
返回结果的一个 JSON 对象(如果结果是用 JSON 格式写的,如果不是就抛出一个错误)。把.json()
想象成一种用来交换数据的存储格式。在这个实例中,我们将内容存储在**storage**
变量中。**Step 5: print(type(storage))**
: 返回用于存储数据的 Python 数据类型。在这种情况下,返回的数据类型将是一个列表(<class 'list'>
)。回头看看我之前提供的表格,可以使用 list index [0,…]提取数据。您应该始终使用type()
函数来确定数据类型。如果您知道数据类型,您就知道要使用的正确提取技术。**Step 6: print(len(storage))**
: 提供列表中的项目数。每个数字代表列表中某项的索引,该索引可用于提取值。**Step 7: print(storage[0])**
:0 代表列表中的第一项,用于从列表中提取该项。一旦项目被提取出来,一个新的数据类型就暴露出来了。步骤 8 中的type()
函数用于显示数据类型。**Step 8: print(type(storage[0]))**
: 新的数据类型将是<class 'dict’>
。字典意味着可以使用一个键提取数据。在我们的数据中,用于提取值的键是currencies
。在步骤 9 中使用currencies
键。取注**,数据类型从第 5 步的<class 'list'>
变为第 8 步的<class 'dict'>
。****Step 9: storage[0]['currencies']**
: 字典中的currencies
键用于输出[{code:'AFN,'name':'Afgahn afghani','symbol':''}]
。一旦项目被提取,一个新的数据类型现在被暴露。步骤 10 中的type()
函数用于显示数据类型。**Step 10: print(type(storage[0]['currencies']))**
: 新的数据类型将是<class 'list'
。列表数据类型意味着我们使用索引操作符[]
来提取下一组值。在这种情况下,索引值将为 0。所以我们在步骤 11 中使用它。注意,数据类型从步骤 8 中的<class 'dict'>
变为步骤 10 中的<class 'list'>
。**Step 11: print(storage[0]['currencies'][0])**
:指标[0]
用于输出{code:'AFN,'name':'Afgahn afghani','symbol':''}
。一旦项目被提取,一个新的数据类型现在被暴露。步骤 12 中的type()
函数用于显示数据类型。******Step 12: print(type(storage[0]['currencies'][0]))**
:新的数据类型为<class 'dict'>
。字典意味着数据可以用一个键提取。在我们的数据中,用于提取值的键是code
。在步骤 13 中使用code
键**Step 13: print(type(storage[0]['currencies'][0]['code']))**
:code
键用于输出AFN
,这是我们希望输出的值。
所以,让我们总结一下两个步骤**,重复这两个步骤直到我们得到我们想要提取的值。第一步是确定数据类型,而第二步是应用提取方法。如果数据类型是 list,那么使用带方括号的索引操作符。但是,如果数据类型是字典,请使用带花括号的字典键。**
提取多个项目
虽然从 JSON 结构中提取单个列表项是重要的第一步,但只提取单个值并不常见。在真实世界的数据中,JSON 对象中的值存储为集合。在下图中,currencies
和code
字典键和值在列表数据结构中有多个条目。我们在现实世界中的例子有 250 个这样的条目,所以我们在本节教程中的目标是提取这些和剩余的值。
其他国家 API 数据,按作者分类的图片
幸运的是,我们可以通过构建用于从 JSON 结构中提取单个值的工作流步骤来提取这些值。我就不再列举那些步骤了。由于列表和字典数据结构是可迭代的,我们可以使用一个for loop
结构来遍历我们的值。所以,让我们在第 14 步把它添加到我们的代码中。我们还需要使用range
和len
函数来枚举列表中的条目数。Python 代码下面解释了工作流步骤。
Python 代码:
工作流程步骤:
**Step 14:** for item in range(len(storage)):``storage
变量包含步骤 4 中返回的列表<class 'list'>
。len
功能用于统计列表中的项目数。range
函数根据列表中项目的数量生成一个数字序列。每当for loop
遍历storage
列表时,该数字被传递给item
变量。在第 48 行,步骤 14 中显示的**print(storage[item]['currencies'][0]['code'])**
来自步骤 13。我们将它封装在for loop
结构中,并将代码从storage[0]
修改为storage[item]
。storage[0]
引用列表中的单个项目。然而,storage[item]
在storage
列表中捕获多个项目。每次for loop
迭代时,storage[item]
递增以捕获下一组值。
结论
挖掘嵌套数据的过程有时会让人感到畏惧、迂回和恼怒。它不太适合介绍性的技术,比如彻底迭代dict.items(), dict.keys(), dict.values() or list indexes[]
。不可避免的是,JSON 结构的复杂性要求在多个字典和列表提取技术之间交替使用来提取数据。掌握它需要一个可重复的过程,但更重要的是实践。我已经包括了几个附加的练习题和解答(点击这里)。
当你不练习的时候,有人在进步——阿伦·艾弗森
祝你好运。
如何快速完成我的数据科学项目?
数据科学家不为人知的秘密
如今,机器学习模型开发甚至已经到了非数据科学家的手中。你只需要知道解决问题的正确方法。这不是一个大秘密,这只是一个意识到机器学习的高级发展和理解有助于更快更好开发的可用框架的问题。在本文中,我将首先描述数据科学家在过去许多年中遵循的传统方法,然后讨论数据科学家在当今遵循的现代方法。
传统方法
这些年来,当接受一个数据科学项目时,数据科学家会首先从探索数据集开始。他会清理数据,估算缺失值,查看列值的方差,搜索相关性,进行特征工程,等等。他将执行“n”个任务来创建一个数据集,用于训练他的机器学习算法或将其输入他设计的神经网络。这个清单是无止境的,耗时的,而且大部分是费力的。
在他为学习设置数据集之后,他的下一个任务将是尝试他根据自己的知识和经验选择的机器学习算法。在训练模型之后,他可能会发现他选择的算法只给出了 60%的准确度,这肯定是不可接受的。因此,他可能会回到数据预处理、特征工程、降维等方面来提高模型的准确性。他可能会摆弄超参数来检查性能改进。如果所有这些都不奏效,他将采用另一种算法。这个过程一直持续,直到他为他的数据集找到具有微调超参数的最佳执行算法。在这个阶段,他会称他的模型为准备部署。
现代方法
到目前为止,我所描述的过程,你很容易理解,是非常费力和耗时的。不仅如此,你还需要精通统计学、EDA(探索性数据分析)、机器学习算法、用于评估算法性能的指标等等。
如果有人能自动化这整个过程,那不是很好吗?听起来很难,但是是的,这种工具在行业中已经存在很长时间了。你需要学习如何在你的项目中使用它们。我们称之为 AutoML。我将向您快速介绍这类工具。作为参考,我将讨论基于广泛使用的 sklearn ML 库的工具。Auto-sklearn 就是这样一个工具,它采用了经典的 ML 方法,并自动模仿了 ANN 的方法。有几个其他的商业和免费使用的工具包可用。我将在最后提到几个,这样你可以选择一个适合你的目的。
经典 ML 方法
有了 auto-sklearn,你只需要知道你的任务——回归或者分类。首先,我将讨论分类的汽车模型开发。
分类任务
在 auto-sklearn 中,只需两行代码就可以在数据集上获得性能最佳的模型。对于分类任务,您可以使用如下代码:
model = AutoSklearnClassifier(time_left_for_this_task=4*60,
per_run_time_limit=30, n_jobs=-1)model.fit(X_train, y_train)```
AutoSklearnClassifier 变魔术了。它需要几个参数来控制执行时间。找到最合适的模型需要很长时间,有时甚至需要几个小时,因此这种时间控制是必不可少的。 fit 命令运行很长时间,最后,它会给出适合数据集的最佳模型。一旦这样做了,你就可以直接用它来推断:
predictions = model.predict(X_test)
如果好奇想知道幕后发生了什么,可以打印一些统计数据。
print(model.sprint_statistics())
我在 Kaggle 数据集上的一次测试产生了以下统计数据:
auto-sklearn results:
Dataset name: 1e3ad955125d649ab6cd828885a8d3fb
Metric: accuracy
Best validation score: 0.986602
Number of target algorithm runs: 24
Number of successful target algorithm runs: 15
Number of crashed target algorithm runs: 0
Number of target algorithms that exceeded the time limit: 9
Number of target algorithms that exceeded the memory limit: 0Accuracy: 0.993
你可以看到它尝试了 24 种算法——我没有耐心这样做。这个模型给了我 99%的准确率——你还能要求什么?如果我有进一步的好奇心想知道最后一个模型由什么组成,我可以要求它向我展示最终的模型配置:
model_auto.show_models()
这是我在测试运行中得到的输出。这只是部分输出,显示了在集合中使用的一个分类器( extra_trees )。
‘[(0.340000, SimpleClassificationPipeline({‘balancing:strategy’: ‘none’, ‘classifier:__choice__’: ‘extra_trees’, ‘data_preprocessing:categorical_transformer:categorical_encoding:__choice__’: ‘one_hot_encoding’, ‘data_preprocessing:categorical_transformer:category_coalescence:__choice__’: ‘no_coalescense’, ‘data_preprocessing:numerical_transformer:imputation:strategy’: ‘median’, ‘data_preprocessing:numerical_transformer:rescaling:__choice__’: ‘minmax’, ‘feature_preprocessor:__choice__’: ‘no_preprocessing’, ‘classifier:extra_trees:bootstrap’: ‘True’, ‘classifier:extra_trees:criterion’: ‘gini’, ‘classifier:extra_trees:max_depth’: ‘None’, ‘classifier:extra_trees:max_features’: 0.5033866291997137, ‘classifier:extra_trees:max_leaf_nodes’: ‘None’, ‘classifier:extra_trees:min_impurity_decrease’: 0.0, ‘classifier:extra_trees:min_samples_leaf’: 2, ‘classifier:extra_trees:min_samples_split’: 14, ‘classifier:extra_trees:min_weight_fraction_leaf’: 0.0},\ndataset_properties={\n ‘task’: 1,\n ‘sparse…’
大多数时候,我甚至都懒得看这些细节。只要模型在测试数据上给出了很好的准确性(在上面的例子中非常好),我就将它部署在生产服务器上。
只是为了与手动建模方式进行比较,我在同一个数据集上尝试了 SVC 分类器。这是比较结果:
作者图片
现在,告诉我为什么我要尝试手动方式?
甚至对于回归任务也采用类似的方法。
回归任务
对于回归,使用这三行代码:
model_auto_reg = AutoSklearnRegressor(time_left_for_this_task=4*60, per_run_time_limit=30, n_jobs=-1)model_auto_reg.fit(X_train_scaled,label_train)
print(model_auto_reg.sprint_statistics())
最后一行只是打印统计数据,这是我在 UCI 数据集上运行测试的结果。
auto-sklearn results:
Dataset name: 17f763731cd1a8b8a6021d5cd0369d8f
Metric: r2
Best validation score: 0.911255
Number of target algorithm runs: 19
Number of successful target algorithm runs: 6
Number of crashed target algorithm runs: 0
Number of target algorithms that exceeded the time limit: 11 Number of target algorithms that exceeded the memory limit: 2
再一次,你看,它尝试了 19 种算法——对一个人来说,这是很大的耐心。我甚至尝试了 sklearn 中的 LinearRegression 实现,将上面的模型与人工努力进行比较。这是我的两次测试运行的误差指标:
作者图片
出于进一步的好奇,您可以检查通过调用上面讨论的用于分类任务的 show_models 方法开发的模型。
作为对开发模型的进一步检查,我绘制了这两种方法的回归线,如下图所示:
作者图片
自动 sklearn 功能
在内部,auto-sklearn 不仅仅是对算法进行彻底的搜索。我们可以在他们网站上给出的架构图中很快观察到这一点。
图片来源:高效健壮的自动化机器学习
如您所见,除了算法选择,它还提供超参数调整。它集成了最高性能的算法。它使用元学习和贝叶斯优化来创建一个高效的管道。它还允许您检查模型细节。你可以控制整个过程。想象一下自己一个人做这些事情。
我发现唯一缺少的是,它没有给我一个基于所选模型的 ipynb 文件,以便我可以对我的数据管道、系综和超参数做进一步的调整。
现在,安汽车开发公司来了。
安/DNN 方法
随着人工神经网络/DNN 在解决使用经典 ML 无法解决的问题方面取得辉煌成功,数据科学家正在探索,或者更确切地说,使用它来完成他们的 ML 任务。一些数据科学家设计他们自己的人工神经网络架构和/或使用预先训练的模型来实现他们的业务目标。设计和使用人工神经网络架构需要除了统计学家以外的其他技能。我们要求你适应 ML 工程师的工作,并具备优化和数学知识。幸运的是,你有自动化的工具来完成这种任务。
像 auto-sklearn 一样, AutoKeras 有助于回归和分类任务的网络设计。不仅如此,它还处理结构化的图像和文本数据。
同样,使用这个库相当简单。对于结构化数据的分类,代码如下所示:
search = StructuredDataClassifier(max_trials=10,num_classes=3)
search.fit(x=X_train_s, y=y_train, verbose=0, epochs=5)
对于图像数据,它将类似于以下内容:
clf = ak.ImageClassifier(num_classes=10, overwrite=True, max_trials=1)
对于回归任务,由于需要回调,代码会更复杂一些。如下所示:
from tensorflow.keras.callbacks import ReduceLROnPlateau
lr_reduction = ReduceLROnPlateau(monitor=’mean_squared_error’, patience=1, verbose=1, factor=0.5, min_lr=0.000001)regressor = StructuredDataRegressor(max_trials=3,loss=’mean_absolute_error’)regressor.fit(x=X_train_scaled, y=label_train,
callbacks=[lr_reduction],verbose=0, epochs=200)
在库创建网络模型后,您可以评估其在测试数据上的性能、获取其评估分数、查找错误度量、使用它来预测未知数据,等等。我不会在这里讨论所有这些细节。相反,我将向您展示由该库创建的网络模型。您使用一个内置函数来导出模型。我在 UCI数据集上进行分类测试时,创建的模型如下:
作者图片
这是同样的网络图:
这不是很棒吗?作为一名数据科学家,你甚至不需要学习 ML 工程师的技能。虽然我使用了上面的两个工具来演示 AutoML 功能,但是市场上还有几个可用的工具,可能有更多的功能。
几个框架
仅举几个框架——你有 H2O.ai、TPOT、MLBox、PyCaret、DataRobot、DataBricks,还有最近宣布的 BlobCity AutoAI。这份清单并非详尽无遗。我只是把它限制在我评估过的几个范围内。其中一些提供付费服务,其他的免费使用,开源。一些支持 R。特别是,H2O 支持 R、Python、Java 和 Scala——所以你在编码方面有更广泛的选择。其中一些有很好的 GUI,所以不需要命令行编码。一些在云上运行。您可能希望为自己的目的选择一个合适的 AutoML 框架。
我在这里肯定会提到的一件事是,新诞生的汽车社区 AutoAI 为我生成了代码,这是迄今为止我所见过的汽车领域中没有人能做到的。它生成一个 ipynb 文件以及一个详细的文档。在其他库中,这就像使用黑盒模型一样。这个特性对我来说是一个很大的好处,因为我所有的客户都要求在接受交付之前提交源代码。
该公司还声称,他们在经典 ML 和 ANN 之间进行自动选择。这对所有数据科学家来说都是一个很大的帮助,因为他们总是面临在经典和人工神经网络之间选择的困境。他们还声称在回归和分类之间进行自动选择,其他工具也是这样做的,因此,这对我来说没什么大不了的。
我必须在这里说,到目前为止,我还没有完全核实他们的说法。这是一个开源项目,给了我一个验证这种说法的机会。都说了,我就不直接跳进去了。该项目是新推出的,正在开发中,很可能有很多错误,除非他们已经深入测试过。他们正在谈论的功能,如果他们坚持下去,这将是数据科学家和整个数据科学领域的一大福音。
结论性建议
我分享了我最近处理数据科学项目的方法。我使用自动化工具。我不想说是哪一个——有时不止一个。提到这些名字可能看起来像是一种认可,所以我在避免。也就是说,作为一名数据科学家,使用 AutoML 工具将会节省您大量的精力。有一点需要提醒的是——目前为止我测试过、使用过的所有工具都有一个或多个 bug——我在他们的 GitHubs 上看到了这些问题。我建议,如果你发现一个问题是可重复的,一定要提交给他们。这样的工具会让我们的生活变得更容易,但不会让我们(数据科学家)灭绝。
一些有用的链接
信用
Pooja Gramopadhye—文字编辑
乔治·萨维德拉—项目开发
https://medium.com/@profsarang/membership
机器是如何规划的?—介绍
思想和理论
图搜索算法和马尔可夫决策过程的简明介绍
规划未来的能力似乎是智力的关键特征之一。步行、骑自行车、做运动或开车等身体动作需要极大的协调性,而最佳的可能动作高度依赖于外部环境(如果你的路上有石头、障碍或对手,你必须适应并改变你的策略)。此外,我们每天做的大多数事情——通勤、购物、烹饪、学习、工作等等。—包括短期和长期规划。像国际象棋和围棋这样的战略游戏也是超前思维发挥重要作用的著名例子。
早在 20 世纪 50 年代,人们就已经提出用数学方法来描述规划的过程。现在这些方法的变体随处可见,从机器人运动规划到在谷歌地图上寻找最佳路线。在本文中,我们将研究一些关键的公式和规划算法,为以后关于规划和强化学习(RL)的文章奠定基础。
状态、行动和奖励(成本)
在导航设置中,想象一个典型的规划问题是什么样子是最容易的。想象你在一个迷宫里。你在某个位置(x,y ),你可以向四个方向移动——上、下、左、右——只要你不碰到墙。如果你达到目标,你成功地终止。
网格迷宫中的机器人(图片由作者提供)
我们用状态来描述我们所处的现状。如果你在 location (x,y),x 和 y 可以认为是在对你所处的状态进行编码,因为只要你知道 x 和 y,假设迷宫环境不发生变化,我们就能把自己放在正确的位置,重构当前的情境。通常,我们认为状态是一组足以概括我们可能遇到的特定情况的细节,并且可以用来区分一种独特的情况。
如果你想到一个更现实的机器人,你可以用一组数字概括它的配置——它的姿势(位置和角度)和它的许多关节的所有角度,这些可以被认为是状态。
一旦我们对状态的定义感到满意,我们就可以考虑在不同的状态之间移动,以达到我们想要的状态。对于上面的例子,这将到达宝箱的位置。我们可以通过采取动作在状态之间移动。在上述情况下,机器人可以采取的行动仅限于上下左右移动。但这并不限制我们思考更复杂的动作,比如迈出更大的步伐或跳过树篱,尽管我们现在不会考虑它们。
规划问题的最后一个要素是“成本”或“回报”的概念。在最短路径搜索或机器人学中,更典型的是考虑每一步的成本,并试图使路径上的总成本最小化。在游戏或环境中的计划背景下,你可以潜在地提高你的分数、能量水平、净值等。,更常见的是考虑奖励并试图最大化你能获得的总奖励。
作为搜索问题的规划
早期的规划工作集中在有限状态的问题上,每一个动作都导致状态间的确定性转换。换句话说,每当你采取一个行动时,你都可以确信你接下来会进入哪个状态。这和我们刚刚看到的网格迷宫问题一模一样。
因为我们想要评估到达目标的最短路径,所以我们将每次移动的成本指定为 1,并尝试在到达目标之前最小化总成本。现在,我们可以将网格迷宫问题转化为状态转换的最短路径问题,如下图左侧所示。可以将我们从初始状态带到目标状态的最短路径也将最小化总转换成本。
评估最短路径的图表(图片由作者提供)
在更一般的情况下,我们可以解决任何给定的连接网络的最短路径问题(例如,通过右边的路径连接的房子)。这种网络在数学上被称为“图”。节点(蓝色)代表状态,边(棕色)代表状态之间的转换。Dijkstra 和 A等图搜索算法可以找到图上最短路径问题的最优解。Dijkstra 的算法带有最少的假设,而如果你粗略地猜测(启发式的)扩展节点的优先级,A在搜索中会更有效。
鉴于本文篇幅有限,我将转到更一般的规划公式,即马尔可夫决策过程。然而,图搜索算法对于解决复杂的现实世界问题非常重要,例如机器人和最短路径搜索。如果你想了解更多关于 Dijkstra 的算法和 A*的知识,我推荐这篇有着惊人交互图形的文章。
https://www.redblobgames.com/pathfinding/a-star/introduction.html
如何描述一个更一般的规划问题
当有限数量的状态之间存在确定性转换时,图搜索算法非常有用。然而,如果在转换中有一些不确定性,或者如果有无限多的状态和转换可以进行呢?
让我们来看一个稍微复杂一点的规划例子——象棋。在这种情况下,国家和行动会是什么样子?
由于每个国家都应该捕捉当前局势的独特细节,一个合理的选择可能是对棋盘上每个棋子的位置进行编码({ ‘黑国王’:G8,‘黑王后’:D8,…,‘白国王’:G1,‘白王后’:D1……})。编码的确切方式并不太重要,只要它们与棋盘状态有一对一的映射,事实上,许多国际象棋游戏引擎已经提出了不同的棋盘状态编码方式。
象棋游戏的状态、动作和过渡(图片由作者提供,来自维基百科的棋子)
国际象棋中有更多可能的动作(从一种状态移动到另一种状态可以做的事情)。平均来说,每回合你可以走 30 步左右,因为你可以选择走哪一步,每一步都有一系列的走法。假设我们选择了主教。在这种情况下,我们可以采取的措施以绿色突出显示。一旦我们选择了一个动作,我们就进入了下一个棋盘状态,如右图所示。
有趣的是,因为国际象棋是一个双人游戏,我们不能仅仅通过选择我们的行动来完全确定下一个游戏状态。对手也开始行动了,所以虽然我们对下一个可能的状态有所了解,但是下一个可能的状态还存在一些不确定性。
和大多数游戏一样,国际象棋中也有更令人向往的游戏状态。最明显的是当你拿了对手的国王并且你赢了的时候。不太明显的是那些你还没有赢,但已经非常接近赢的。
最后,让我们想象一个更真实的问题,驾驶通过一些障碍课程。正如我们已经讨论过的,汽车的状态可以通过它的姿态(位置和角度)以及车轮速度、加速度、转向角、剩余燃油量等来总结。使汽车从一种状态进入另一种状态的动作可能是你加速、刹车、转向和加油的程度。
一般来说,驾驶或机器人技术的难点在于,与网格迷宫或象棋不同,状态和动作通常是连续的。如果你在开车,你不只是向左或向右打方向盘;你可以加速、刹车或平稳地转动方向盘,由此产生的汽车及其车轮的位置、速度、加速度和角度都取连续值。这使得在这种状态空间中进行规划成为一个很难解决的问题。
与国际象棋类似,驾驶是一个多智能体规划问题,这意味着你必须与街上同样驾驶、骑自行车或步行的其他人协调。由于我们还没有心灵感应,我们不得不在不完全了解他人可能会做出什么决定的情况下做出决定。还有一些我们并不完全了解的环境状态,比如下一个红绿灯什么时候改变,下一个十字路口是否堵车,或者如果我们在隧道里没有 GPS 信号,我们现在到底在哪里。
在现实世界中,有更多难以解决的规划问题。如果你在一次公路旅行中,你的目标是尽可能多地游览风景名胜,那该怎么办?在这种情况下,没有一个明显的目标可以达到。如果你想让你的人工智能学习股票投资的最佳策略,并不断将你的收益进行再投资,该怎么办?如果这个任务没有一个明确的结束,你会在什么时候评估人工智能的性能?
规划问题的范围
在我们可能有兴趣解决的规划问题中,我们已经看到了许多相似之处和不同之处。我们在一些例子中做了更多的假设,添加或删除假设会使问题看起来完全不同,不同的问题会产生不同的解决方案。
共性:
- 目的是找到一个好的策略,让我们能够决定在给定的情况下(在给定的状态下)采取什么行动
- 在不同的情况和状态之间存在某种映射
- 动作可以影响从一种状态到另一种状态的转换
- 在每一次转变过程中,都会有某种回报或代价
- 有一个处于某种状态的可取性(价值)的概念
根据问题不同的假设:
- 有时候,在你采取行动后,你最终会处于哪种状态是不确定的,要么是因为状态转换是嘈杂的/概率性的,要么是因为还有其他人也在做出决策。有专门为双人游戏开发的算法,比如 minimax 和 alpha-beta 剪枝。在更一般的情况下,我们可以将概率状态转移建模为马尔可夫决策过程(MDP ),这将在下面讨论。涉及其他代理的问题被称为多代理问题,并且可以基于代理是合作还是竞争以及它们是否被允许相互通信来进行额外的考虑。
- 有时候,你每一次转型能得到的回报也可以是概率性的。
- 在许多情况下,环境的状态转换和回报动态是未知的,直到你尝试一些事情,看看会发生什么,所以没有一些尝试和错误,很难提前计划事情。这是强化学习的主要假设,这种困境被称为“开发 vs 探索”。
- 有时,状态和/或行动可以是连续的,这意味着离散的规划算法,如 Dijkstra 和 A*将不再工作。在机器人学中,一种常见的方法是对状态空间进行离散化或采样,产生一个粗略的最短轨迹估计,然后应用控制理论找到一个合适的连续控制输入,使轨迹估计和机器人实际轨迹之间的误差最小。然而,随着深度学习的成功,使用神经网络对连续函数进行建模已经成为可能,开辟了在连续空间中直接规划的一系列可能性。
- 有时候,我们所处的状态是无法精确衡量的。在机器人学中,传感器输入范围有限,最常见的问题是定位,即知道机器人此刻的确切位置。卡尔曼滤波器是在给定一些噪声测量和观察的情况下用于估计状态的技术之一。 SLAM(同步定位和绘图)是一个完整的领域,致力于根据摄像机输入估计机器人的当前位置。更一般地说,真实的状态是未知的,因为我们无法直接观察状态(比如我们是否患有癌症,或者宇宙中每个粒子的确切位置和速度),所以我们必须根据有限的观察值来估计它们。强化学习中的一个相关领域叫做 POMDP(部分可观察马尔可夫决策过程)。
这就是引入一个考虑到这些不确定性的更一般的规划范例——马尔可夫决策过程的动机。
马尔可夫决策过程(MDP)
让我们想一个一般的规划问题。无论是机器人、象棋还是驾驶,总有一个决策实体通过采取行动来改变局面。我们称决策实体为代理,外部的一切为环境。通常,如果我们是下棋、在房间里走动或开车的人,我们人类就是代理人。当我们用算法解决这些问题时,计算机算法本身就成了代理。代理可以在环境中采取行动以达到新的状态。环境为代理提供关于当前状态的知识,以及代理发起的每个状态转换的回报。
状态 s s ∈ S (我们将可能状态的集合表示为 S ,每个状态表示为 s ),如前所述,是特定情况的唯一编码。当前状态可以直接测量或观察(如棋盘状态完全已知的国际象棋,或关节配置完全已知的机器人手臂),或者必须从环境提供的观察中推断(如驾驶,其中驾驶员必须推断汽车的当前位置和速度,或机器人不完全本地化)。
代理可以通过采取动作A∈A(s)来启动从一个状态到另一个状态的转换(可用的动作可以取决于您所处的状态,因此动作集可以是状态 s 的函数)。这将触发环境的变化,环境将向代理更新对新状态的观察,以及奖励 r 。奖励可以是正面的,比如你在国际象棋中走了一步棋,赢了对方,或者正确预测了股票的上涨,但也可以是负面的,比如输掉了比赛,耗尽了燃料,或者撞上了障碍物。奖励通常是当前状态 s 、代理 a 采取的动作以及新状态*s’*的函数,并被写成 R ( s 、 a 、s’)。
最后,我们还可以定义一个从当前状态 s 到新状态s’的转移概率,基于某个动作 a 为P(s’|s, a )。这是一个条件概率,因为我们想知道我们将最终处于哪个状态,假设我们处于状态 s 并且已经采取了动作 a 。
让我们用一个假设的场景来说明这一点,在这个场景中,我们想决定是骑着扫帚去上学好,还是通过心灵传输去上学好。(注意:我最初想找一个更日常的例子,但是很难找到既可信又容易检验的概率,所以让我们用一个假设的例子。)
假设运输系统的简单马尔可夫决策过程(图片由作者提供)
如图所示,你的起始状态 s 是“家”,有三种结果——学校、医院和被绑架。如果你传送,它会更快,所以去学校的回报会更高,但它也更有风险,所以你更有可能因严重受伤而住院。另一方面,乘扫帚旅行速度较慢,而且更加暴露,所以你有可能被外星人绑架。
让我们来决定我们是应该采取“扫帚旅行”还是“瞬间移动”的行动。我们可以计算出每个行动的期望回报(概率的平均回报)(σP(s’|s,a)R(s, a ,s’))
a= “扫帚”:0.8 * 1+0.1 *(10)+0.1 *(100)=-10.2
a= 《瞬移》:0.7 * 5+0.25 *(15)+0.05 *(100)=-5.25
因此,在这个简单的例子中,我们发现心灵运输给了我们最大的预期回报。
最大化总预期回报
虽然上面的例子只有一个带有即时奖励的单步转换,但在典型的计划问题中,如国际象棋,你需要提前计划,并根据你对未来奖励的估计采取战略性的行动,而不仅仅是即时奖励。更具体地说,我们应该最大化我们未来期望的回报总和。未来回报的总和被称为回报 G ,我们的目标是找到一个使其最大化的策略。
回报的定义
回到我们的网格迷宫示例,起点的回报将是来回移动的所有成本和达到目标的最终奖励的总和。假设机器人走了 6 步到达宝箱,每走一步获得-1 的奖励,但到达宝箱时获得 10 的奖励。在这种情况下,返回是(-1) * 6 + 10 = 4。
注意,在回报的定义中,有一个贴现因子γ。有些规划问题是没有明确的终点的,所以奖励一直无限累积下去。为了防止回报变得无穷大,我们通过乘以γ < 1 来贴现未来回报(类似于γ≈0.99)。
思想
我希望这有助于获得一些关于规划问题如何数学描述的直觉,以及如何用 MDP 规划的公式比图搜索更复杂,但这也允许我们对更一般的规划问题建模。
通常,状态、动作和奖励的概念是作为 MDP 公式的一部分引入的,用于强化学习。然而,在这篇文章中,我想更普遍地介绍状态、行动和奖励(成本)的概念,因为这些概念并不是 RL 或 MDPs 所独有的,也出现在机器人学、控制理论和概率论中,它们都有着悠久的历史和大量伟大的工作。一旦我们开始看到这些关系,我们就开始看到,例如,Dijkstra 算法中的累积成本和强化学习中的值在某些假设下是相同的,只是以不同的方式表述。
在以后的文章中,我们将更深入地研究强化学习,研究不同的方法来得出一个好的策略,并讨论它们背后的直觉。
相关文章
参考
- 理查德·萨顿和安德鲁·巴尔托。强化学习:导论,第二版 (2018),麻省理工学院出版社
- 史蒂文·拉瓦勒。规划算法 (2006),剑桥大学出版社
当社交距离成为规则时,人们如何移动?
实践教程
揭示就地安置要求对早期进入新冠肺炎疫情的德国和瑞典居民流动行为的影响
许多国家强制执行就地安置要求,以遏制新冠肺炎在本国领土上的传播。这些非药物干预(NPI)已经以政策研究人员急于破解的方式影响了人们的流动习惯。其目的不仅是为了更好地应对新的疫情疫情,也是为了及时发现那些尚未度过最糟糕时期的国家的经验教训。Bryant & Elofsson(2020 年)声称,不同国家的人们会以不同的方式改变他们的流动模式,以应对类似的 NPI,受此启发,我决定通过以下问题进行探索性分析来加入这场辩论:
随着时间的推移,德国和瑞典的公民如何减少个人流动性以应对各自政府颁布的就地安置要求?
德国和瑞典的比较预示着有趣的发现。两国在疫情早期采取了看似相反的策略来控制病毒。瑞典一再禁止这一消息,称其“轻锁”战略非常信任其居民的自愿自我监督。另一方面,德国很早就采取了严厉的政府干预措施,并被誉为榜样反应。
设置
我转向可公开访问的 OxCOVID19 数据库(Mahdi 等人,2020 年)来查询这两个国家的流动性和政策数据。OxCOVID19 数据库是一个大型的多模型存储库,收集了大量国家的流行病学、政府应对措施、流动性和社会人口数据。所有可用的数据都是作为 OxCOVID19 项目的一部分进行整理的,该项目旨在增进我们对疫情的了解,并促进基于统计分析的缓解策略的发展。我将 2020 年 2 月下旬至 11 月下旬的数据考虑在内,以探索两国疫情早期阶段的政策执行动态以及公共流动性的变化。
我的分析利用了 OxCOVID19 数据库中的两个表。就地安置政策颁布数据来源于政府反应 表整理关于颁布的遏制政策的国家级顺序数据。在任何给定时间点执行政策的严格程度跨越三个层面。值为 0 表示给定的策略当前不活动,而值为 1 表示策略符合性是推荐的。最后,值 2 意味着必须遵守。我从移动性表中检索谷歌移动性趋势数据,捕捉不同位置类别(例如工作场所、公交车站、公园)相对于前疫情基线值的每日移动性偏差百分比。我将流动性数据汇总到国家一级,以便进行跨国比较,并匹配可用政策数据的粒度,以便进行后续关联。我进一步将移动性数据重新采样到周箱中,以消除周末、银行假日和分析未明确控制的其他环境因素(如天气)的影响。
描述性分析
用一些描述性的统计数据来开始它从来都不是一个坏主意。表 1 记录了两个国家在时间跨度范围内的就地安置严格程度的百分比分布。有几件事很突出。
表 1 。德国和瑞典就地安置严格水平的覆盖范围。
德国在 66%的时间里暂停了就地安置令,而瑞典在 86%的时间里发布了就地安置建议。然而,瑞典从未将该建议转化为要求,而德国在 20%的时间里实施了最严格的政策水平,几乎跨越了政策发布时间框架的三分之二。
接下来,我绘制了随着时间的推移,德国和瑞典公民按地区分类的流动性变化百分比。我进一步用竖条覆盖每个时间序列图,竖条的宽度和颜色对应于两国政府实施就地安置政策的持续时间和严格程度。
**图一。**个人流动性的变化与颁布的就地安置要求之间的关系
相对于瑞典,德国将更大的流动自由时期限制在更短、更紧缩的政策实施时期内,自 3 月中旬政策出台以来,瑞典仅仅建议就地避难就成为了新常态。这种视觉叙事与学术界和媒体强调存在两种截然不同的病毒遏制路线图的声音不谋而合。瑞典采取了一种独特的政策组合,温和的命令与公众呼吁自我监管相结合,而不限制个人自由,因为社会不喜欢明确的政府遥控。相比之下,德国主张早期、严格的干预,然后通过较软的措施在感染曲线周围安全地跳舞(Jung et al .,p.363,2020)。
无论严格程度如何,只要有就地安置要求,这两个国家的地点类别的流动性百分比都比疫情前参考值显著下降。每个图旁边的汇总统计数据突出显示,当就地安置政策是积极的而不是取消时,平均流动性变化显著下降。用相对值表示,只要实施就地安置政策,这两个国家在不同地点类别的流动性都会出现两位数和三位数的下降。
显著性检定
好的,我们可以说,到目前为止,德国和瑞典的流动模式在时间范围上有所不同。但是,我们能确信隐现的差异不仅仅是由于偶然吗?为了解决这个问题,我继续计算 95%的置信区间。这是为了评估德国和瑞典居民之间个人流动性的平均变化是否有显著差异。用外行的话来说,95%的置信区间告诉我们,我们有 95%的信心,两国之间平均流动性的真正差异位于区间下限和上限之间的某个位置,我将为 4 个位置类别中的每一个计算区间。现在假设给定置信区间的界限不包括 0。在这种情况下,我们可以确信,与瑞典居民相比,德国居民流动性的相对下降实际上更高(即,如果两个区间边界都是负的)或更低(即,如果两个区间边界都是正的)。表 2 报告了范围内 4 个位置类别的置信区间。
表 2 。高于零的严格性水平的迁移率类别的平均差异。
德国引入了家庭避难所的建议和要求,在所有类别中,德国的平均相对流动性下降幅度都比瑞典大。“高客流量”地点类别零售&娱乐 (-29.1%)和中转站 (-11.3%)的差异尤为明显。相反,在类别工作场所 (-3.1%)和杂货店&药房 (-5.7%)中,差异不那么明显。这些差异是有意义的,因为无论就地安置政策颁布时多么激烈,去办公室、购买食物和获得药品仍然是基本权利,特别是在疫情开始时,远程工作等替代方案尚未成熟。最重要的是,我发现,除了类别工作场所之外,我的 95%置信区间将统计显著性归因于所有位置类别的已识别差异。在所有条件相同的情况下,图 1 中的时间序列图显示,在 5 月初政策暂停后,德国公民以惊人的速度重新发现了他们对个人流动性的喜悦。这些上升趋势甚至超过了他们的瑞典同龄人的流动性水平,他们在夏末仍然受到在家避难的建议。我建议您修改图 1,比较德国和瑞典的交通时间序列如何针对类别中转站(子情节 1 & 5)和工作场所(子情节 2 & 6)演变,以见证这些动态变化。
为了弄清这些观察结果,我计算了另一组 95%的置信区间,以评估当德国暂停就地安置政策而瑞典没有暂停时,是否存在确定的流动性差异。
表 3 。按流动类别的平均差异,比较德国的政策暂停(即当严格级别= 0 时)和瑞典的政策条例(即当严格级别> 0 时)。
令人震惊的结果:德国居民在 4 个地点类别中的 3 个地点的流动性确实下降得更少。与瑞典同行相比,工作场所类别、、中转站类别和杂货店类别&药店类别的流动性变化比疫情前基线值少 9.9%至 2.7%。
这一切意味着什么?
我的分析结果证实,个人流动性的降低与两国的政策部署相一致,但随着时间的推移,关于时机和严格性的不同部署战略可能会引发不同的反应。Murphy 等人(2020 年)关于公民遵守遏制政策的动机的研究声称,一旦法规取消,合规就不会持续。基于这一论点,对政府诱导的健康干预的规范性承诺可能是德国和瑞典公民个人流动性暂时下降背后的主要动机。从这个意义上说,随着限制解除后规范压力的消失,德国公民可能会回归到更为机会主义的行为模式。相反,正在进行的就地安置建议继续缓和瑞典居民的流动模式。
与此同时,瑞典公民的流动模式表现出高度可变性的实例表明,动态远不像乍看上去那样黑白分明。例如,让我们考虑瑞典居民对于位置类别零售&娱乐(例如,图 1 中的子情节 7)的移动性的变化。在没有任何政策转变的情况下,流动性水平有时甚至超过了疫情之前的水平。为了解释这一发现,让我们回顾一下,就地安置要求一直是瑞典的一项建议。因此,人们的流动行为可能会受到同时发生的更严格的政策变化的影响,而我的研究没有考虑到这一点。这种情况代表了统计学家通常所说的“遗漏变量偏差”。当一个模型或分析遗漏了一个或多个相关变量,可能会混淆所包含变量之间的真实关联时,就会发生这种情况。在我们的案例中,就地安置需求和个人流动性变化之间的关系。
局限性
每项研究都有其局限性。是时候告诉你我的故事了。您可能还记得,我曾有意参与数据聚合和重采样。聚合意味着在粒度方面均衡移动性和策略数据,而重采样意味着消除分析无法控制的星期效应或特殊事件的影响。归根结底,在数据预处理方面,没有免费的午餐。从这个意义上来说,重采样和聚集度量是一把双刃剑,它可以提高清晰度和抑制噪声,但代价是模糊微妙的信号,这些信号只有在较低的粒度级别才会变得明显。最后,一些限制与我使用的数据有关。在研究谷歌(2021 年)新冠肺炎社区移动性报告中的了解数据部分时,我了解到移动性数据来自拥有谷歌账户并允许访问其位置历史的智能手机用户。在排除没有谷歌账户的智能手机用户,有谷歌账户但位置共享设置不同的智能手机用户,以及没有智能手机的人(是的,他们仍然存在!),样本代表性有风险。类似地,谷歌声明,如果地方不够繁忙,无法防止重复识别,数据就会被保留。这个善意的隐私门槛违背了可靠地捕捉脚步的实际目的。最后,谷歌以 1 月 3 日至 2 月 6 日之间的固定五周时间为基准来衡量移动性变化。使用两个冬季月份作为参考框架来评估今年剩余时间内的流动性变化会引起严重的数据有效性问题。
结论
本文以提问开始:*随着时间的推移,德国和瑞典的公民如何减少个人流动性以应对各自政府颁布的就地安置要求?*通过分析德国和瑞典 8 个月的流动性和政府政策数据,我发现强制执行就地安置要求的严格程度似乎影响了人们的流动性行为。德国采取了更为保守的就地安置政策,在执行时个人流动性急剧下降,随后在放松时流动性水平出现更大幅度的反弹。最终,研究结果暗示了个人流动性变化和政策制定之间的复杂关系,而我的分析才刚刚开始揭示这种关系。在强调游戏中的局限性时,我渴望批判性地反思我的分析结果,并在更普遍的意义上,善意地提醒人们,看似令人信服的发现必须始终有所保留。最重要的是,我希望这篇文章能激发这类进一步的探索,以提高政府在面对像新冠肺炎这样的威胁性传染病爆发时的决策能力。
参考
布赖恩特,p .和埃洛夫松,A. (2020 年)。评估流动模式对 11 个欧洲国家新冠肺炎感染率的影响。 medRxiv 。
Jung,f .,Krieger,v .,Hufert,F. T .,,Küpper,J. H. (2020 年)。我们应该如何应对新型冠状病毒冠状病毒的爆发:德国的观点。临床血液流变学与微循环, 74 (4),363–372。
马赫迪、布拉什奇克、德洛特科、萨尔维、陈、T. S. T .、哈维和扎雷布斯基(2020)。OxCOVID19 数据库:更好理解新冠肺炎全球影响的多模态数据库。medRxiv。
ReLU 神经网络如何逼近任意连续函数?
从根本上说,机器学习模型是函数逼近器。例如,在试图从一个人的教育程度来预测其工资时,我们试图通过查看函数中的样本点来逼近单个输入函数。更复杂的任务,如图像分类是多维函数近似[1]。
神经网络在机器学习中无处不在,因为它们可以逼近各种各样的函数——所有连续的分段线性函数(CPWLs),只要给定足够的隐藏单元。通用逼近定理保证了良好逼近函数的存在,这篇文章将讨论只有一个隐藏层和许多隐藏单元的神经网络如何使用 ReLU (校正的线性单元)非线性来逼近一元函数。这个想法延伸到多元输入空间。
作为函数逼近的学习
我们可以把学习过程理解为:
从数据中学习(作者绘制)
在这篇文章中,我们的目的是演示箭头 2,并给出一个箭头 1 的简短例子。神经网络异常强大的另一个原因是,它们可以通过反向传播(箭头 5)进行良好的训练[3]
神经网络的功能形式
考虑具有一个隐藏层的全连接神经网络。
神经网络的简单表示(由作者绘制)
不失一般性,输出层的最终功能是具有一个隐藏层的神经网络的功能形式。(x 向量是输入,权重用 w 表示)。这里的激活函数用 f 表示。
定义 ReLU 的使用
假设激活函数 f(x)是 R(x)—ReLU(整流线性单位)函数。ReLU 是分段线性函数,对于 x 的所有负值为 0,否则等于 x。
ReLU 函数(Desmos)
通过将函数 R(x)乘以“a”,将函数移位“b”,并将域移位“c”,来修改函数 R(x),(“a”和“b”是可学习的参数)给出了一个函数,该函数成为我们近似的构建块。
修改 ReLU (Desmos)
在一个神经网络中,有几个激活(ReLUs)聚集在一起逼近一个函数。ReLU 函数可以通过减法以下列方式折叠。
聚集 ReLUs (Desmos)
详细示例
为了更具体,让我们以一个只有一个隐藏层的神经网络为例。考虑图像中定义的连续分段线性函数。
分段线性函数(Desmos)的示例
因为这是一个三段函数,我们需要隐藏层中的 6 个神经元来表示这个函数(每段 2 个神经元)。下图说明了代表上述分段线性函数的神经网络的外观(及其权重和偏差)。
ReLu 函数精确表示分段线性函数(Desmos)
这可以推广到任何连续的分段线性函数,可以用神经网络来表示。现在让我们看看神经网络是如何逼近连续函数的。
接近
对于任意连续函数 g(x),我们可以证明它可以由它的无穷小部分的斜率之和来近似。由于 ReLU 可以用来表示任意直线,它可以构成这些斜率,最终逼近函数 g(x)。
注意,神经网络仅在受限域中在逼近函数方面做得很好,因为对于无限域,可能存在这样的情况,其中给定数量的神经元总是可以改进逼近,因此,不会获得成本函数的最小值。然而,在一个受限的领域中,神经元总是能够找到最小成本并很好地逼近函数。
下图显示了 x 在一个小区域内的近似值。这是为了演示 ReLU 函数如何聚合。由于函数的参数是可学习的,神经网络调整这些参数(以权重和偏差的形式)并逼近一个函数。
x 的近似值
这篇文章试图简化和展示神经网络是如何表现一个功能的。我意识到解释不是微不足道的,并决定写这篇文章,以 ReLU 为例。在这篇论文中可以找到一个更加严谨和详尽的解释。
希望这能有意义的帮助到某个人!
笔记
[1]这里,输入是图片的每个像素中的像素颜色,输出是图片在输出类别之一中的概率(例如猫/狗)
[2]深度神经网络甚至是更好的近似器,因为它们需要更少的单元来近似相同的函数,并且概括得更好更快(链接
[3]理解反向传播(环节
访问者如何使用你的网站?
Hotjar 制作的信息图
什么是 Hotjar,它是如何工作的?
介绍
你刚刚推出了一个新网站。或者您在 web 应用程序中添加了新功能。你急切地期待反馈、询问、申请等。
然而,什么也没有发生。
你不会收到电子邮件,没有人注册使用你的产品,你会问自己为什么。毕竟,你肯定有人访问过你的网站。
嗯,结果是联系表坏了,这就是为什么你没有收到任何电子邮件。或者,一些访问者无法查看您网站的其他部分,因为在移动设备上使用导航很混乱。这些是你在创建网站或改变功能时可能面临的一些潜在问题。
这篇文章旨在介绍 Hotjar,以及如何通过一个真实的用例来理解网站访问者的行为。
热罐
Hotjar 是一项行为分析和用户反馈服务,帮助您了解网站用户的行为,并通过以下工具获得他们的反馈:
- 热图 :通过直观地表现用户的点击、点击和滚动行为,了解用户想要什么、关心什么、在你的网站上做什么
- 记录 :通过查看访问者的点击、轻拍和鼠标移动,您可以即时识别可用性问题以及他们遇到的问题
- 反馈调查:针对网络和手机网站上的特定访问者提出问题
- 调查 :使用简易编辑器构建您自己的响应调查。
Hotjar 补充了您从 Google Analytics 等传统网络分析工具中获得的数据和见解。这是一项行业领先且易于使用的服务,结合了用户行为分析和网站反馈工具,帮助您了解您的网站上实际发生了什么,您的用户关心什么,以及他们想说什么。
所以,如果你是营销人员、产品经理或用户界面设计师,Hotjar:
- 给你清晰和直观的数据点关于在你的网站上发生了什么
- 帮助你了解一些背景知识,比如为什么人们会有这样的行为
- 上面的是否快速而不需要陡峭的学习曲线
如何使用 HOTJAR
- 创建 Hotjar 帐户。要开始,您可以选择免费版本,它每天记录 500 个会话,持续 14 天。
- 包括你从 Hotjar 网站上获得的脚本。Hotjar 建议将脚本放在 HTML 页面的
<head>
部分,但是您也可以将脚本放在<body>
部分。 - 请检查 Hotjar 仪表板以验证安装。如果验证无效,请尝试禁用广告拦截器。
用例
像其他几位数据科学家一样,我着手建立了一个新冠肺炎数据报告门户。你可能会翻白眼,但它有一个真正的用例。在我所在的英国威尔士,对数据不感兴趣的人并不清楚新冠肺炎的数据报告。所以,我继续做了一个,几个月后,这个门户已经有了 509,000 的浏览量!😱
门户网站新冠肺炎·西姆鲁(威尔斯的新冠肺炎门户网站)
门户网站最受欢迎的功能之一是每日地图。这个页面提供了威尔士每个特定地区的每日病例数字——我认为它为人们提供了一点安慰,让他们看到疫情在他们家门口的实际情况,而不仅仅是整个国家的情况。
每日地图报告威尔士特定地区的新冠肺炎病例
我绝不是一个用户界面设计师。所以为了构建门户,我使用了小英莱利的免费自举门户设计。你绝对应该去看看她——她的设计棒极了!
我深入研究了她的文件,修改了设计以适应用例。然后,我开始在 Twitter 上报告案例,并将用户引向门户网站。我的 Google Analytics 报告说,我的大多数用户都是在移动设备上访问门户的,对此我想都没想。由于门户是使用 Bootstrap 构建的,因此可扩展到移动和平板电脑屏幕。
在 Twitter 上,我分享了一张地图附带的表格截图,我经常被问到它在门户网站的什么位置。
这让我想知道——用户看不到表格吗?
答案是,没有…
下图显示了两周后 Hotjar 在地图页面的移动视图上制作的热图。地图本身(出于安全考虑,地图所在的 iframe 无法通过 Hotjar 查看),显然是吸引力的一个特征。深红色热图区域表明了这一点。导航和地图视图选择也经常使用。但是如果我们注意桌子,几乎没有热量。因此,这表明移动用户没有意识到,如果他们在设备上向下滚动,表就位于地图下面。因此,为了改善这个可用性缺陷,用户需要某种可操作的指示,让他们知道要查看表格,他们必须滚动地图。
结论
正如你所看到的,将 Hotjar 嵌入到你的网站是很容易的。Hotjar 物有所值,它的免费层提供了有价值的信息!它帮助你建立更好的网站,让你的用户更有效地使用,降低跳出率。
虽然它有助于跟踪错误并帮助识别和修复网站中的漏洞,但 Hotjar 等工具可以帮助您解决 UX 问题并更好地了解您的受众。我们可以通过了解用户如何与我们的网站互动来消除这种猜测,而不是将我们的时间和资源集中在我们认为可行的事情上。
如何将主成分分析应用于逻辑回归以消除多重共线性?
PCA 在消除多重共线性中的作用
Gabriella Clare Marino 在 Unsplash 上拍摄的照片
当要素(输入变量)与数据集中的一个或多个其他要素高度相关时,会出现多重共线性 。它会影响回归和分类模型的性能。PCA(主成分分析)利用多重共线性,将高度相关的变量组合成一组不相关的变量。因此,PCA 可以有效地消除特征之间的多重共线性。
在本帖中,我们将在名为乳腺癌数据的分类数据集上构建一个逻辑回归模型。初始模型可以被认为是基础模型。然后,我们将对乳腺癌数据应用主成分分析,并再次建立逻辑回归模型。之后,我们将比较基本模型和这个模型之间的性能。最后,我们将建立一个机器学习管道,将应用逻辑回归和 PCA 的多个步骤结合起来。读完这篇文章后,你将能够将 PCA 应用于逻辑回归模型。
我们开始吧!
探索乳腺癌数据集
该数据集是 Scikit-learn 中的内置数据集之一。根据 Scikit-learn 文档,它有 569 个样本的 30 个特征。目标变量有两个类别,称为 0(没有乳腺癌)和 1(有乳腺癌)。由于目标变量只有 2 个类,因此数据集用于二进制分类。数据集中没有缺失值。所有的值都是数字。所以,不需要清洗!
加载数据集
等到加载 Python 代码!
乳腺癌数据集的一部分(图片由作者提供)
创建热图
热图可以用漂亮的彩色图来显示连续变量的相关系数。
等到加载 Python 代码!
(图片由作者提供)
正如您在热点图中看到的,数据集中的一些要素彼此高度相关。因此,存在多重共线性。
构建逻辑回归模型(基础模型)
以下代码块基于乳腺癌数据构建逻辑回归模型。
等到加载 Python 代码!
基本模型的输出(图片由作者提供)
基础模型非常好。一点也不合身。它在新的未知数据上表现良好。让我们看看是否可以通过应用主成分分析来提高模型的性能。
对乳腺癌数据应用主成分分析
PCA 概述
PCA 是一种线性降维技术(算法),它将一组相关变量§转换成较小的 k (k
主成分 ,同时尽可能多地保留原始数据集中的变化。在机器学习(ML)的背景下,PCA 是一种用于降维的无监督机器学习算法。如果变量不是在相似的尺度上测量的,我们需要在对我们的数据应用 PCA 之前进行特征缩放。这是因为 PCA 方向对数据的规模高度敏感。PCA 中最重要的部分是为给定的数据集选择最佳数量的组件。
为我们的数据选择最佳数量的电脑
首先,我们应用 PCA,保持所有组件等于原始维数(即 30 ),并观察 PCA 如何很好地捕捉我们的数据的方差。
等到加载 Python 代码!
(图片由作者提供)
第一个分量单独捕获数据中约 44%的可变性,第二个分量捕获数据中约 19%的可变性,依此类推。前 6 个分量一起捕获了数据中约 88.76%的可变性。我们有兴趣保留前 6 个组件。
使用 6 种成分再次运行 PCA
现在,我们得到了包含 6 个组件的转换数据集。为此,我们需要通过设置 n_components=6 再次运行 PCA。
等到加载 Python 代码!
转换数据集的一部分(作者提供的图像)
现在,我们可以使用这个转换后的数据集代替原始的乳腺癌数据集来建立逻辑回归模型。这是两个数据集之间的区别。
- 原始数据集有 30 个要素,而转换后的数据集有 6 个组件。
- 转换后的数据集仅捕获原始数据集中约 88.76%的可变性。
- 两个数据集对应的值完全不同。
- 原始数据集中的一些变量与一个或多个其他变量高度相关(多重共线性)。转换后的数据集中没有变量与一个或多个其他变量相关。
创建转换数据集的热图
fig = plt.figure(figsize=(10, 8))
sns.heatmap(X_pca.corr(),
annot=True)
(图片由作者提供)
我们看不到组件之间的任何关联。这是因为 PCA 已经将原始数据集中的一组相关变量转换为一组 不相关 变量。
对转换后的数据建立逻辑回归模型
下面的代码块在转换后的数据集(通过应用 PCA 获得的数据集)上构建逻辑回归模型。
等到加载 Python 代码!
(图片由作者提供)
您可以将这个输出与我们基本模型的先前输出进行比较。测试精度提高了 3%。假阳性和假阴性也减少了。然而,转换的数据集(通过应用 PCA 获得的数据集)仅捕获原始数据集中约 88.76%的可变性。所以, 这款车型的性能提升背后的原因是什么? 显而易见的答案是PCA 有效地消除了多重共线性!
构建机器学习管道
机器学习管道通过将应用逻辑回归的多个步骤与 PCA 相结合,简化了整个过程。以下是步骤:
(图片由作者提供)
等到加载 Python 代码!
log _ reg _ model流水线通过顺序应用变压器列表和最终预测器来简化训练过程。在我们的渠道中:
- StandardScaler() 是一个变压器。
- PCA() 是变压器。
- LogisticRegression() 是预测者。
现在,我们可以通过一个**训练所有的估计器。**称之为合体()。
log_reg_model.fit(X,y)
现在,我们已经完成了引言中承诺的工作。
摘要
PCA 对于消除多重共线性是有用的。它充当数据预处理步骤。PCA 还有很多其他的用例。这只是降维技术之一。你可以通过阅读我写的下面这篇文章找到更多关于那些事情的信息:
</11-dimensionality-reduction-techniques-you-should-know-in-2021-dcb9500d388b>
我的读者可以通过下面的链接注册成为会员,以获得我写的每个故事的全部信息,我将收到你的一部分会员费。
报名链接:https://rukshanpramoditha.medium.com/membership
非常感谢你一直以来的支持!下一个故事再见。祝大家学习愉快!
特别感谢 Unsplash 上的加布里埃拉·克莱尔·马里诺,她为我提供了这篇文章的封面图片。本帖提供的文字内容、代码示例、其他图片和内容链接,版权归作者所有。
鲁克山普拉莫迪塔 2021–06–15
如何用 Python 实现 AdaBoost?
助推技术
机器学习中的助推算法——第二部分
我们继续机器学习系列文章中提升算法的第 1 部分。看过第一部吗?它向您简要介绍了 boosting 以及一些关键技术术语的定义,这些术语对于理解今天的内容非常重要。
今天,我们将学习最流行的增强算法之一:AdaBoost(自适应增强)。更多的重点将放在算法的实现部分,在以下主题。
- sci kit-AdaBoost 的学习类
- 在葡萄酒数据上训练和评估 AdaBoost 分类模型
- 将 AdaBoost 模型与决策树残肢进行比较
- AdaBoost 中的重要超参数
- 测量超参数的效果 n_estimators
- 测量超参数的效果学习 _ 速率
- 使用网格搜索找到最佳超参数值
所有代码示例都将作为 GitHub gists 包含在内,以便您可以轻松地使用它们!在本文的最后,您将能够在具有最佳超参数值的给定数据集上实现 AdaBoost 算法。
我们开始吧!
sci kit-AdaBoost 的学习类
AdaBoost 的 Python 实现由两个 Scikit-learn 类完成:AdaBoostClassifier()用于分类(二进制和多类),以及AdaBoostRegressor()用于回归。导入惯例是:
from sklearn.ensemble import AdaBoostClassifierfrom sklearn.ensemble import AdaBoostRegressor
创建决策树树桩模型
通过用 max_depth=1 提前停止树的生长,我们将在葡萄酒数据上构建一个决策树桩。这是为了比较决策树桩和 AdaBoost 模型。我们也使用这个树桩模型作为 AdaBoost 的基础学习器。
下面的 Python 代码在 Wine 数据上创建了一个决策树,并评估了它的性能。
基于葡萄酒数据的决策树树桩模型
(图片由作者提供)
模型的性能很差。这并不奇怪,因为我们通过设置 max_depth=1 来严格调节树的生长。
创建 AdaBoost 分类模型
现在,我们将在葡萄酒数据上构建一个 AdaBoost 分类模型。
基于葡萄酒数据的 AdaBoost 分类模型
(图片由作者提供)
哦那个分数!与决策树残肢相比,AdaBoost 模型表现得非常好。
AdaBoost 中的重要超参数
以下是 AdaBoostClassifier() 和 AdaBoostRegressor() 中最重要的超参数。
- base_estimator: 这是 AdaBoost 算法中使用的基本学习器。默认的也是最常见的学习者是我们前面讨论过的决策树 stump(max _ depth = 1 的决策树)。
- n_estimators: 顺序训练的估计器(模型)的最大数量。默认值为 50。我们将很快测量这个超参数的影响。
- learning_rate: 确定在增强过程中应用于每个估计器的权重。默认值为 1。较小的值(如 0.05、0.1)会强制算法训练较慢,但具有高性能分数。我们将很快测量这个超参数的影响。
测量效果 n_estimators
我们将通过将超参数 n_estimators 的值从 2 变化到 100 来手动测量其效果,并绘制 AdaBoost 模型给出的测试分数。
n _ 估计量的影响
(图片由作者提供)
在大约 30 次估计之后,我们之前获得的准确度分数恒定在 0.972。您可以使用 30 以上的任何整数。但是请记住,如果您增加该值,该算法将需要很长时间进行训练。因此,在这种情况下,最好使用默认值 50。
衡量效果学习 _ 速率
我们将通过从 0.1 到 1 改变超参数 learning_rate 的值来手动测量其效果,并绘制 AdaBoost 模型给出的测试分数。
学习率的影响
(图片由作者提供)
最高精度为 0.4、0.5、0.7 和 0.8。我们在上面的模型中使用了 0.5。
两种测量都是手动完成的。有一种更简单的方法来找到 n_estimators 和 learning_rate 的最优值。
使用网格搜索找到最佳超参数值
这里,我们通过使用 网格搜索 ,同时自动调整(找到最佳值)两个超参数*。相比之下,在前面的步骤中,我们一次调优一个超参数。*
执行网格搜索
(图片由作者提供)
我们可以使用这些值来获得 AdaBoost 模型的最高精度。给出相同精度的一些其他可能的组合是:
- 学习率=0.5,n 个估计值=50
- 学习率=0.8,n 个估计值=50
- 学习率=0.8,n 个估计值=100
- 学习率=0.4,n 个估计值=50
摘要
用 Python 构建 AdaBoost 模型非常简单。你所要做的就是确定你想要解决的问题类型(回归/分类)并选择 Scikit-learn 中提供的合适的 AdaBoost 类。然而,超参数调整过程是一个真正的挑战。你需要做一些可视化,为超参数调整做并行计算。实际上,您将创建数千个模型。幸运的是,我们可以使用本文中讨论的高级方法来自动化调优过程。
模型的输出很大程度上受随机数据分割的影响。根据在 random_state 中指定的整数,您可能会得到不同的准确度分数。总是建议指定一个整数,以便在不同的执行中获得静态结果。
与决策树和随机森林等其他基于树的方法相比,AdaBoost 等 boosting 算法的性能非常好。这是因为考虑到前几轮初始树产生的误差,升压中的树被顺序训练。
在第三部中,我们将讨论梯度增强,另一种流行的增强算法。下一个故事再见。祝大家学习愉快!
我的读者可以通过下面的链接注册成为会员,以获得我写的每个故事的全部信息,我将收到你的一部分会员费。
*https://rukshanpramoditha.medium.com/membership
非常感谢你一直以来的支持!
特别感谢 Unsplash 上的约翰·普莱斯,为我提供了这篇文章的精美封面图片。
鲁克山普拉莫迪塔
2021–10–22*
如何连接 SQL 表?
WHERE 或 ON 子句?
照片由 Alina Grubnyak 在 Unsplash 上拍摄
马上,我不使用也永远不会使用WHERE
子句来连接表。
如果你正在使用WHERE
子句,这篇文章试图说服你也这样做。相反,使用ON
子句来实现表连接。
您使用WHERE
子句执行表连接吗?请不要让我检查或帮助你找到你的查询中令人沮丧的障碍。
你在问我为什么吗?
我告诉过你,我不喜欢用于连接表的WHERE
子句。我只用它来过滤数据。当用于实现表连接时,它以一种糟糕的方式(畏缩)让我恼火。我的思维变得超速,特别是在用于实现两个表之外的多个连接时。
类似下面的 SQL 查询伤害了我的眼睛,更糟糕的是我的大脑。使用WHERE
子句来实现表连接,会使表连接的顺序变得不清晰,也没有任何视觉提示。
使用 WHERE 子句连接多个表的 SQL 查询示例。这个 SQL 使用相同的 WHERE 子句进行过滤。
参见上面使用WHERE
子句连接 6 个表的 SQL 查询。更糟糕的是,它还使用 3 个带有相同的WHERE
子句的AND
逻辑操作符来执行数据过滤。
使用ON
子句实现相同结果的重写看起来像这样。奖励是非常明显的。
首先,我们使用了WHERE
子句的查询尾部的混乱被很好地整理了。现在很明显WHERE
子句在做什么——一件事——只有行过滤。
第二,简单地说,您可以识别和理解连接表的顺序,以创建保存查询结果的概念上的巨型表。
重写看起来也很有凝聚力。
表连接不使用 WHERE But ON 子句的更多理由
1.数据过滤
WHERE
子句很优秀,更适合数据过滤,而不是连接表。
2.认知超载
在实现数据过滤和表连接时使用WHERE
子句会造成认知超载。WHERE
子句在同时用于实现表连接和数据过滤时会影响可读性和查询理解。
3.有限的
WHERE
子句限制了你在不同的表上可以实现的连接。WHERE
子句只实现了INNER JOIN
,这是您可以使用ON
子句执行的 5 种连接类型之一。
4.缺失记录
因为使用WHERE
子句执行表连接在技术上与INNER JOIN
的行为相同,所以连接的表中的记录必须满足WHERE
子句中表达的条件,才能成为连接的表的结果的一部分。忽略这些基础知识可能会导致查询结果中遗漏重要的记录。在银行和汇款应用程序这样的金融应用程序中,这种疏忽可能是代价高昂的。
使用 ON 子句实现比内部连接更多的功能
正如我前面指出的,使用WHERE
子句产生的结果与同时使用ON
子句和INNER JOIN
子句产生的结果相同。
除了使用ON
子句实现INNER JOIN
之外,您还可以实现其他形式的 SQL 表连接。这些其他类型的表连接的好处是有足够的参数将WHERE
子句严格留给数据过滤。这样做也为您的查询带来了一致性,并减少了其他开发人员的 SQL 审查和维护难题,因为他们不必费力区分用于表连接和数据过滤的条件。
在本文的其余部分,除了内部连接之外,我将通过示例数据展示其他三种形式的 SQL 连接。
如果您想亲自操作,那么首先创建表并用示例数据作为种子。
创建表格,person
和contact
创建表“person”的 SQL 查询
创建表“联系人”的 SQL 查询
下载样本数据 person.csv 和 contact.csv 并分别植入表person
和contact
。
使用下面的查询解压缩并最终用示例数据播种这些表。记得用你下载的解压副本的路径替换/path/to/person.csv
和/path/to/contact.csv
。
如果您做的一切都是正确的,那么表上的 select 语句应该产生下面的输出
餐桌人员
SELECT * FROM person;
person.csv
表格联系人
SELECT * FROM contact;
contact.csv
除了内部连接之外的其他连接类型
除了INNER JOIN
,还有 4 种其他类型的连接,分别是FULL OUTER JOIN
、LEFT OUTER JOIN
、RIGHT OUTER JOIN
和CROSS JOIN
。
在本文中,我们将讨论LEFT OUTER JOIN , RIGHT OUTER JOIN
和FULL OUTER JOIN
左外部连接
如果两个表都满足用ON
子句指定的条件,左外连接通过列出左表中的指定列并将它们连接到右表中的列来组合两个表。
当条件与左表中的列不匹配时,为右表中的列设置一个NULL
值。
考虑下面的例子,一个person
表位于表contact
的左外部连接中。
工作台person
为左工作台contact
为右工作台。
您会注意到左边表格person
中的name
、gender
、age
列被连接到右边表格contact
中的phone_number
列。同样明显的是,没有匹配person_id
的最后 4 行将phone_number
设置为空。
SELECT person.name,
person.gender,
person.age,
person.phone_number
FROM person
LEFT OUTER JOIN contact
ON person.id = contact.person_id
输出:
表 person 和 contact 之间左外部连接的输出
右外部联接
右外连接通过列出右表中的指定列并在两个表都满足用ON
子句指定的条件时将它们连接到左表中的列来组合两个表。
当条件与左表中的列不匹配时,为左表中的列设置一个NULL
值。
考虑下面的例子,右外部连接中的一个person
表与表contact
。工作台person
是左工作台contact
是右工作台。
您会注意到右表中所有行的phone_number
都被列出,并连接到左表中匹配记录的name
、gender
、age
。
因为person
表和contact
表之间的关联是关系型的,确切地说是一个One2many
关系,所以如果没有一个根实体 person 来拥有它,就不会有联系人记录。因此,我们的RIGHT OUTER JOIN
结果仅限于有联系记录的人员。
如果来自person
表的name
、gender
、age
列表都满足ON
条款规定的条件,则它们被连接到来自contact
表的phone_number
。
SELECT person.name,
contact.mobile_number,
contact.home_address
FROM person
RIGHT OUTER JOIN contact
ON person.id = contact.person_id
输出:
表 person 和 contact 之间右外连接的输出
完全外部连接
完全外部联接通过列出两个表中的列来组合这两个表。当条件不满足时,为左表或右表的列设置一个NULL
值。
考虑下面的例子,一个person
表和contact
通过一个更完整的外部连接组合在一起,条件是person
上的id
列与contact
表上的person_id
列匹配。每个表中不满足该条件的行仍然显示在结果中,它们的列设置为NULL
SELECT person.name,
person.gender,
person.age,
person.phone_number
FROM person
FULL OUTER JOIN contact
ON person.id = contact.person_id
输出:
表 person 和 contact 之间完全外部连接的输出
结束语
希望我成功说服您放弃使用WHERE
子句来连接表。如果什么都没有,你已经注意到使用ON
子句给你的查询带来了多大的清晰度。还记得使用ON
子句时可以执行的其他类型的连接。
希望这篇文章对你有所帮助。
知识是给世界的,所以我们分享。
祝你一切顺利。下次见。
怎么知道自己的数据够不够好?
当然,可能会有一些例外,但我们中的大多数人处理数据是为了让人们能够做出好的决策。为了达到一个共同的目标,我们走了数百万条不同的道路:更好地了解这个世界,一次一点点。罗摩·罗摩克里希南的“从预测到行动”系列将带领我们到达目的地的序列分解成有时很棘手的部分;最近一期文章聚焦于为我们要解决的问题组装正确数据集的关键步骤。(既然你在这里,你也不妨重温一下第一部。)
定义要查看的正确数据,然后创建一个流程来从中得出可操作的见解是作为产品分析师的 Kate Gallo 的工作核心。与一些更常见的以数据为中心的工作描述相比,这是一个鲜为人知的角色,Kate 耐心地向我们介绍了它的来龙去脉。对她来说,产品分析师是作为用户的拥护者与多个合作伙伴一起工作的人:他的角色是“确保用户喜欢并从产品中获得价值”,并通过对精心选择的指标进行深思熟虑的分析来做到这一点。
Rama 和 Kate 的文章从商业决策的角度探讨了数据有效性的话题,但挑战在于知道我们是否在看正确的数据——我们有足够的数据吗?靠谱吗?它准确地代表了世界吗?—更深更广。正如艾丹·佩平在他的第一篇 TDS 文章中所写的,使观察到的现象可测量的过程需要多种形式的简化——“未能解释数据化的这种简化本质是许多算法伤害和失败的根本原因。”对于 Aidan 来说,如果我们想避免这些危险中最糟糕的情况,仔细的设计和注意我们在这个过程中做出的选择都是必要的。
观察、收集、展示和利用数据的方式有很多——如果你想在本周探索其他一些方向,我们将一如既往地为你提供帮助!):
- 发现结构方程建模的威力 。Laura Castro-Schilo 分享了对 SEM 的有用而全面的介绍,并解释了为什么这种方法成为如此多的行为和社会科学家的最爱。
- 恶补最新深度学习研究 。罗伯特·兰格备受期待的八月版学术论文推荐来了!这本书充满了对从视觉变形器到深度学习优化器基准等主题的热情阅读。
- 了解人工智能 中的转换范式。最近围绕人工智能的对话往往可以归结为一个简单的人类合作与人类对抗的二元对立。在最新的 TDS 播客中,Jeremie Harris 和嘉宾 Divya Siddarth 探讨了人工智能的其他想法和应用,并探讨了政府在该技术的下一个篇章中可能发挥积极作用的方式。
我们希望你喜欢本周的阅读——感谢你花时间和我们在一起,感谢你的支持让这一切成为可能。
直到下一个变量,
TDS 编辑
我们策划主题的最新内容:
入门
- 通过 Sheel Choksi 扩展您的数据团队时需要寻找什么
- 数据可视化中颜色的力量作者玛丽·勒菲弗尔
- 数据科学家 GitHub 桌面作者德鲁·西沃德
实践教程
- 2021 年建立营销组合模式的完整指南作者特伦斯·申
- 4 个预提交插件,由 Khuyen Tran 在 Python 中自动进行代码审查和格式化
- 用熊猫很快生成假数据作者胡安·路易斯·鲁伊斯-塔格勒
深潜
思想和理论
你怎么知道你的分析是“对的?”
验证数据分析的策略
如果你和数据打交道,我敢打赌有人告诉过你“这个数据看起来不对劲…”
当我还是一名全新的数据分析师时,这句话让我(非常)焦虑。我并不总是对我的工作有信心,总是假设如果分析的最终用户说它是关闭的,那么我肯定犯了一个错误。我一直在想,我只需要更加小心谨慎。
由 Avel Chuklanov 在 Unsplash 上拍摄的照片
虽然我仍然总是仔细检查我的公式和数据处理工作流程,但我现在意识到,在向利益相关者展示报告之前,尽最大努力验证最终结果对于增强信心和赢得信任至关重要。
这似乎是显而易见的,但是当您的输出是一百万条记录时,您如何验证这个结果呢?如果你不确定,请继续阅读。
用源系统验证输入数据
你知道这句谚语:垃圾进来,垃圾出去。因此,将您的原始数据与原始来源进行比较至关重要。在我目前的角色中,这通常意味着根据原始 ERP 系统检查来自我们数据湖的查询结果中的记录计数、数据类型和最新加载日期。这是一个相对快速和简单的检查,但是如果您在查询或数据湖中发现错误,它可以节省您大量的时间——这样您可以首先修复错误,然后继续前进,知道您正在检查有意义的分析。
我在项目的这一步遇到的一些问题包括:意识到我的查询有一个我不再需要的记录限制,看到源系统中包含的数据湖中缺少列,注意到数据库已经几个月没有加载新数据了,以及认识到数据类型的差异。
凯文·Ku 在 Unsplash 上拍摄的照片
检查数据汇总统计和分布
我发现检查汇总统计数据(如最小值和最大值、平均值等)很有帮助。)在我分析的多个点上。开始时,我将检查这些统计数据以发现异常值,并确保所有值都是正确的数据类型。此外,绘制变量的分布图有助于快速了解数据的情况,这将帮助您快速识别任何重大问题。
当您在分析项目结束时检查汇总统计数据时,您可能希望查看任何新变量的统计数据是否对您开始时的数据和您对最终结果的期望有意义。例如,如果您创建了一个类似“调查完成百分比”的指标,并且您看到值超过 100%,那么您知道您需要检查您的公式和/或格式。
运用批判性思维
Robina Weermeijer 在 Unsplash 上的照片
好的,非常明显——你必须批判性地思考你的结果。
尽管如此,我有时还是会收到来自其他人的数据,这些数据的值显然没有逻辑意义。我得到的制造数据表明,如果这是真的,我们公司应该倒闭。批判性地思考您的结果包括真正理解您的数据及其用例。
如果您不太了解您正在处理的变量,或者期望值应该是什么,那么您应该与业务方面的人员合作,以更好地了解对数据/指标的期望。
与主题专家合作
如果你是一名数据分析师或数据科学家,你不可能知道你得到的所有不同数据的一切。因此,向公司里的专家或经常处理这些数据的人询问大量问题,对于确保你的分析是正确的至关重要。
有时候,数据专家并不是项目的请求者。找到他们可能需要一些网络或消息。但是一旦你找到一个人,他可以解释某些维度意味着什么,或者为什么某些指标对业务理解很重要,他们的知识可以节省你无数个小时的努力。
我还发现,记录这些商业知识可以帮助提升你的分析团队的技能,并更快地分发信息。无论您是做项目符号笔记、制作流程图、创建关系数据库图表,还是做其他事情,您都可以真正帮助对您正在处理的数据感兴趣的其他同事。(而且可以减少对自己分析的提问!)
与类似分析相比
这项任务在不同的项目中可能会有很大的不同,但是总的来说,您希望对您的最终结果进行某种健全性检查,尤其是如果您以前从未处理过这些数据。
以下是我比较项目结果的一些例子:
- 将分组总计与来自源系统数据的汇总结果进行比较
- 确保我的数字在预期的数量级内(例如,销售额是百万还是十亿)
- 让一位同事复制分析结果(如果很短)并比较结果
- 查找现有仪表板以检查我的数据。他们不会完全一样,但他们可以提供大致的答案
结论
我希望对我的分析始终充满信心,因为它经常被用来制定商业战略决策。这就是为什么我在整个数据分析过程中,通过多种渠道来验证我的工作。
希望本文列举的策略能帮助你自信地说“是的,我的分析是对的。”祝您未来的数据项目好运!
朱利安·洛萨诺在 Unsplash 上的照片
要阅读更多关于数据分析的信息性(有时是机智的)文章,请看我的中型简介:
https://megandibble.medium.com/
作为一名数据科学家,你如何衡量成功?
我们每周精选的必读编辑精选和原创特写
本周我们感受到了节日的气氛——当我们激动地挥手说“你好!”时,数据科学最近达到了一个重要的里程碑在我们的第 600,000 个灵媒追随者中。
有很多方法可以衡量一个出版物的成功,但是如果你的读者没有出现,这些方法都没有用。所以,对阅读《变量》的每一个人:感谢你的出现,让我们的社区保持支持和欢迎,并帮助我们传播消息。如果你想以更直接的方式支持我们和我们的贡献者,考虑成为一个中等会员。它不仅可以让你无限制地访问 TDS 上的每一篇文章(以及 Medium 上的所有付费文章),还可以帮助我们和我们的作者继续发布一流的数据科学文章。
如果你想知道我们是如何庆祝的:我们是一个分布式的编辑团队,涉及了如此多的香槟酒瓶表情符号。(可能也有一些真的!谁知道呢?)然而,没有什么比发表真正优秀的帖子更能给我们带来快乐了,我们当然也这么做了。
不像数字出版物,读者不断用他们的眼睛和时间投票,许多软件公司需要细致入微的工具来衡量成功。 Chris Dowsett 分享了 Spaceship 团队为实现全自动 NPS(净推介值)程序而开发的流程——如果你想收集有意义的用户反馈,但没有谷歌规模的预算(或数据团队),请阅读该流程。
在许多行业背景下,定义成功是一个迭代过程,其中一个关键要素是避免最常见和最有害的错误。对于像李颖这样为 IBM 公司总部人力资源团队管理数据科学的人来说,拥有一个健壮的框架是至关重要的;在她的最新帖子中,她详细介绍了她推荐的分析管理七阶段生命周期,从制定正确的问题到淘汰过时的解决方案。 Fabrizio Fantini ,就他而言,专注于建立正确的护栏,以保持团队专注于正确的目标;阅读他的帖子了解如何避免数据科学项目设计中的四个常见陷阱。从不同的角度处理一个类似的问题, Aparna Dhinakaran 解释了 ML 可观测性,以及当团队将他们的模型从绘图板付诸实践时,它为什么对团队很重要:这是“在部署模型后盲目行动的团队和能够快速迭代和改进他们的模型的团队之间的关键区别。”
有时候,获得对手头问题更细致入微的理解本身就是成功的一种衡量标准——尤其是在机器学习这样一个年轻且不断变化的领域。Julia Nikulski 深入研究了人工智能文本生成中出了名的复杂的毒性话题,如果你跟随她,你也会更清楚地了解那些使简单修复变得不可能的因素和利益相关者。同样, Blake VanBerlo 和安大略省伦敦市人工智能应用实验室的团队正致力于解决他们城市的长期无家可归问题;他们建立的预测模型仍处于早期阶段。尽管如此,他们迄今为止所学到的东西已经很有价值了,并将为政策制定者在支持他们社区中的边缘人群的工作中提供选择。
最后,在过去的一周里,我们自己的团队也有机会反思过程、成功和迭代——这不仅仅是因为我们与不少于 600,000 名订阅者分享了我们的帖子。(我们已经提到过了吗?我们可能有。)在我们最新的作者 Spotlight Q & A 中,特约作者 Eugene Yan 向我们介绍了他从心理学专业到亚马逊应用科学家的道路,并且提供了作为数据科学家和公共作家对目标设定、学习和挑战自我的见解。在 TDS 播客上,主持人 Jeremie Harris 欢迎Brian Christian,The Alignment Problem的作者,来讨论我们——数据科学家、机器学习工程师,以及,嗯,整个人类——今天面临的最大挑战可能是什么:确保我们建立的人工智能系统不会,嗯,摧毁我们。
再次感谢您成为我们社区的一员——本周,以及每周。如果本周你也在庆祝一项成就或里程碑,请让我们知道。我们的生活中永远不会有足够多的香槟酒瓶表情符号。
直到下一个变量,
TDS 编辑
我们策划主题的最新内容:
入门指南
- 可解释还是准确?为什么不两者都要? by Parul Pandey
- 用数据科学做决策作者约什·泰勒
- 第一份数据科学家工作的面试:期待什么以及如何准备作者 Emma Ding 和 Hide Kato
实践教程
深潜
思想和理论
- 数据科学家的研究心态:潘武的“第一原理”思维
- 内部量化感知培训由 Vaibhav Nandwani
- 艾是来应聘你的工作的吗?由瑞亚茅台
你如何保持机器学习研究和最佳实践的领先地位?
TDS 聊天
我希望听到您和社区的意见。我们想问你:
- 你如何保持在机器学习文献和最佳实践的顶端?
- 您是否被每天和每次会议上发布的大量论文所淹没?如果是,你如何选择专注于哪些论文?
欢迎在评论中分享你的方法和观点。这对社区非常有益!
我们聊聊吧:)
如何在 CatBoost 中直接使用分类特征?
助推技术
机器学习中的助推算法——第六部分
妮可·詹皮耶罗在 Unsplash 上的照片
这是我们在 “机器学习中的 boosting 算法” 文章系列中涉及的第四个(最后一个)Boosting 算法。到目前为止,我们已经详细讨论了 AdaBoost 、梯度增强、 XGBoost 和 LightGBM 算法及其 Python 实现。
CatBoost(分类增强)是 XGBoost 的替代方案。它具有以下特点:
- 可以直接处理分类特征,无需编码
- 具有更简单的超参数调谐过程
- 运行速度比 XGBoost 快
在本教程中,我们将讨论如何在 CatBoost 中直接使用分类特征。我们还将它与 LightGBM 进行比较,后者也可以处理分类特征,但需要一些额外的工作!
我们开始吧!
安装 CatBoost
CatBoost 的安装超级简单。在 Anaconda 提示符或 Google Colab 编辑器中运行以下命令之一。
pip install catboost
#OR
conda install catboost
这两个命令都可以安装既支持 CPU 又支持 GPU 的 catboost 包。
在 CatBoost 中直接使用分类特征
与其他 boosting 算法相比,CatBoost 的一个独特特性是我们可以通过 CatBoost 直接使用分类特征(如果数据集中有分类特征的话)(无需编码)。为了验证这一点,我们将使用具有一些分类特征的“钻石”数据集构建一个 CatBoost 回归模型。
钻石数据集
现在,我们来看看“钻石”数据集的一些重要细节。
import pandas as pddf = pd.read_csv('diamonds.csv')
df.head()
(图片由作者提供)
让我们在数据集中找出一些关于特征(变量)的信息。
df.info()
(图片由作者提供)
如你所见,变量切割、颜色和净度是分类变量。它们都有对象数据类型。这些分类变量没有数值。通常,我们需要将它们编码成数值,因为大多数算法在训练过程中只接受带有数值的数据。
但是,CatBoost 的情况并非如此。我们可以在 CatBoost 中直接使用分类特征,而无需对它们进行编码。为此,我们需要通过使用 Pool() 类将我们的数据转换为 CatBoost 的特殊 Pool 数据类型。我们还需要在 cat_features 参数中指定分类特征的名称。
如果我们的数据只有数字特征,我们也可以使用 CatBoost,而无需将数据转换为 Pool 数据类型。如果我们的数据具有分类特征,我们必须在使用 CatBoost 之前将数据转换为 Pool 数据类型。
基于钻石数据的 CatBoost 模型的设计过程非常简单。我们可以选择价格变量作为目标列(y),其余变量作为特征矩阵(X)。我们还从数据集中删除了表、 x 、 y 和 z 变量,因为它们对数据没有太大价值。然后,我们可以将 X 和 y 定义如下:
X = df.drop(columns=['price', 'table', 'x', 'y', 'z'])
y = df['price']
因为价格是一个连续值变量,这里我们需要建立一个回归模型(实际上是一个 CatBoost 回归模型!).为了构建模型,我们使用了CatBoostRegressor()类及其相关的超参数值。对于分类任务,有一个单独的类叫做CatBoostClassifier()。
基于钻石数据构建 CatBoost 回归模型
这是代码。
等到加载代码!
(图片由作者提供)
这个值吗?这是预测误差(残差)的标准差。值越低,模型越好。让我们仔细看看价格变量。
y.describe()
(图片由作者提供)
范围(最大-最小)是 18497。标准差是 3989。因此,我们得到的 RMSE 值对于我们的模型来说是非常好的。另外,请注意,我们是在没有进行任何超参数调整的情况下获得这个值的!
具有分类特征的 LightGBM
在第 5 部分中,我们已经讨论了 LightGBM 也可以不经过编码直接用于分类特征。但是,LightGBM 没有任何内部机制来处理分类特征。
让我们看看如果使用带有分类特性的 LightGBM 会发生什么。
等到加载代码!
(图片由作者提供)
您将得到一个值错误,提示您应该将分类值编码为数值。
但是,等等!LightGBM 有一个简单的方法。我们不需要对我们的分类值进行编码。相反,我们只需要在训练算法之前对 X 做一个数据类型转换(对象数据类型→ 类别数据类型)。
转换前:
X.info()
(图片由作者提供)
转换过程:
for col in X.select_dtypes(include=['object']):
X[col] = X[col].astype('category')
转换后:
X.info()
(图片由作者提供)
现在,所有分类变量都有类别数据类型。因此,我们可以无任何误差地重建模型。
等到加载代码!
(图片由作者提供)
这个 RMSE 值比之前从 CatBoost 得到的值稍微好一点!
结论
CatBoost 是 XGBoost 的一个很好的替代品。如果您有一个包含分类变量的大型数据集,这应该是您的选择。当我们考虑性能和执行时间时,CatBoost 可以优于 XGBoost。但是,LightGBM 比 CatBoost 好多了!
今天的帖子到此结束。在第 7 部分的中,我们将讨论 XGBoost 与 CatBoost 以及 LightGBM 与 CatBoost 的一些性能比较。除此之外,我们还将讨论一些指导原则,帮助您为您的任务选择正确的提升算法。
下一个故事再见。祝大家学习愉快!
我的读者可以通过下面的链接注册成为会员,以获得我写的每个故事的全部信息,我将收到你的一部分会员费。
**https://rukshanpramoditha.medium.com/membership
非常感谢你一直以来的支持!
特别要感谢 Unsplash 网站上的 Nicole Giampietro,她为我的这篇文章提供了一张漂亮的封面图片。
鲁克山普拉莫迪塔
2021–10–31**
如何用 NumPy,SciPy 和 SymPy 解线性方程组?
让我们用唯一解、无解或无穷多解来求解线性系统
安托万·道特里在 Unsplash 上拍摄的照片
在线性代数中,线性方程组被定义为具有相同变量集的两个或多个线性方程的集合。同时考虑系统中的所有方程。线性方程组用于不同的领域,如制造、营销、商业、运输等。
当方程和变量的数量增加时,线性方程组的求解过程会变得更加复杂。解必须满足系统中的每个方程。在 Python 中,NumPy(NumericalPython)、SciPy(ScientificPython)和SymPy(SymbolicPython)库可以用来解线性方程组。这些库使用向量化的概念,通过避免许多 for 循环,允许它们有效地进行矩阵计算。
不是所有的线性系统都有唯一的解。其中有些无解或无穷多解。
(图片由作者提供)
我们将用 NumPy、SciPy 和 SymPy 实现来涵盖这 3 种类型的线性系统。可以用几种不同的方式来实现。我们还将在必要时讨论这些不同的方式。在本文结束时,您将能够求解一个线性系统(如果存在唯一的解),并使用强大的 NumPy、SciPy 和 SymPy 库识别无解或无限多解的线性系统。
先决条件
强烈建议学习 NumPy 的基础知识(数组创建、一维数组和二维数组的识别等)。如果你不熟悉他们,不要担心。要获取基础知识,可以看下面这篇我写的文章。
我们开始吧!
线性系统的一个例子
请看下图,它包含了一个线性方程组。
线性方程组(图片由作者提供)
该系统中有 3 个线性方程。每个方程都有一组相同的变量,称为 x 、 y 和 z 。求解这个线性系统意味着找到满足所有方程的 x 、 y 和 z 的值(如果存在)。
线性系统的矩阵表示
上述线性方程组可以表示为一个称为 增广矩阵 的特殊矩阵,它为通过矩阵计算求解线性方程组开辟了道路。
扩充矩阵(图片由作者提供)
这个扩充矩阵有两个部分:
- 系数矩阵— 这是一个矩形数组,仅包含变量的系数。在我们的示例中,这是上图中垂直线左侧的一个 3 x 3 的正方形矩阵。第一列包含每个方程的系数 x ,第二列包含系数 y 等等。行数等于线性系统中方程的数量。列的数量等于线性系统中不同变量的数量。在 NumPy 中,这可以表示为一个二维数组。这经常被赋给一个用大写字母命名的变量(比如 A 或者 B )。
import numpy as npA = np.array([[2, -3, 1],
[1, -1, 2],
[3, 1, -1]])
- 增大— 这是上图中垂直线右侧的列向量。它包含线性方程的常数。在我们的例子中,这是一个 3 x 1 的列向量。在 NumPy 中,这可以表示为一维数组。这通常被赋给一个用小写字母命名的变量(比如 b )。
import numpy as npb = np.array([-1, -3, 9])
用唯一解求解线性系统
让我们用 NumPy 解下面的线性系统。
(图片由作者提供)
为了马上解决这个问题,我们使用 NumPy linalg 子包中的 solve() 函数。
import numpy as npA = np.array([[2, -3, 1],
[1, -1, 2],
[3, 1, -1]])b = np.array([-1, -3, 9])np.linalg.solve(A, b)
输出是:
(图片由作者提供)
哇!上述线性系统有一个独特的解决方案:
- x = 2
- y = 1
- z = -2
**注意:**类似的实现可以用 SciPy 来完成:
from scipy import linalglinalg.solve(A, b)
这在内部是如何工作的?
直接实现并没有给出这在内部如何工作的清晰概念。让我们推导矩阵方程。
矩阵方程
(图片由作者提供)
让我们用矩阵方程得到同样的解:
np.dot(np.linalg.inv(A), b)
(图片由作者提供)
为了有一个解,应该存在 A 的倒数,并且 A 的行列式应该非零:
np.linalg.det(A)
(图片由作者提供)
求解无解的线性系统
当线性方程组无解时,这样的系统称为不相容系统。让我们看看当我们试图用 NumPy 解下面的线性系统时会发生什么:
(图片由作者提供)
import numpy as npA = np.array([[1, -1, 4],
[3, 0, 1],
[-1, 1, -4]])b = np.array([-5, 0, 20])np.linalg.solve(A, b)
输出是:
错误消息(图片由作者提供)
错误消息说我们的系数矩阵(A)是奇异的。用代数术语来说,就是行列式为零的不可逆矩阵。让我们检查一下:
np.linalg.det(A)
输出是:
(图片由作者提供)
行列式为零。因此,我们的系数矩阵(A)是奇异的。正因为如此,上述线性方程组无解!
**注意:**如果您用 SciPy 实现它,将会返回一个类似的错误消息。
求解具有无穷多解的线性系统
当一个线性方程组有无穷多个解时,这样的系统被称为相关系统。让我们看看当我们试图用 NumPy 解下面的线性系统时会发生什么:
(图片由作者提供)
import numpy as npA = np.array([[-1, 1, 2],
[1, 2, 1],
[-2, -1, 1]])b = np.array([0, 6, -6])np.linalg.solve(A, b)
输出是:
错误消息(图片由作者提供)
这与前一个案例相同。
**注意:**如果您用 SciPy 实现它,将会返回一个类似的错误消息。
现在,有一个问题。**如何区分无解线性系统和有无穷多解线性系统?**有方法。
我们试图将系数矩阵简化为行梯队形式,其对角线上为 1,其他地方为 0(单位矩阵)。如果我们成功了,这个系统有一个独特的解决方案。如果我们无法将系数矩阵放入单位矩阵,要么无解,要么无穷多解。在这种情况下,我们可以通过查看简化矩阵的最后一行来区分无解线性系统和有无穷多个解的线性系统。
得到简化的行梯队形式
我们可以使用 SymPy Python 包来获得简化的行梯队形式。首先,我们创建增广矩阵,然后使用 rref() 方法。让我们用一个具有独特解决方案的线性系统来尝试一下:
(图片由作者提供)
from sympy import *augmented_A = Matrix([[2, -3, 1, -1],
[1, -1, 2, -3],
[3, 1, -1, 9]])augmented_A.rref()[0]
(图片由作者提供)
我们成功了!我们得到了简化的行列形式。第 4 列是解决方案列。解是 x=2 , y=1 , z=-2 ,这与之前使用 np.linalg.solve() 得到的解一致。
让我们用一个无解的线性系统来试试:
(图片由作者提供)
from sympy import *augmented_A = Matrix([[1, -1, 4, -5],
[3, 0, 1, 0],
[-1, 1, -4, 20]])augmented_A.rref()[0]
(图片由作者提供)
这一次,我们没有成功。我们没有缩小的排梯队形式。这个表格的第三行(等式)是 0=1,这是不可能的!因此,线性系统无解。线性系统是不一致的。
最后,我们用一个有无穷多解的线性系统来尝试:
(图片由作者提供)
from sympy import *augmented_A = Matrix([[-1, 1, 2, 0],
[1, 2, 1, 6],
[-2, -1, 1, -6]])augmented_A.rref()[0]
(图片由作者提供)
这一次,我们也没有成功。我们没有缩小的排梯队形式。此表格的第三行(等式)是 0=0,这总是正确的!这意味着变量 z 可以取任何实数,并且 x 和 y 可以是:
- z =任何数字
- x-z = 2 (x = 2+z)
- y+z = 2 (y = 2-z)
将任意一个实数代入 z ,可以得到无穷多个解!线性系统是依赖的。
我们已经完成了任务。现在,您能够求解一个线性系统(如果存在唯一的解),并使用强大的 NumPy、SciPy 和 SymPy 库区分无解的线性系统和有无限多个解的线性系统。
一般的实现是:
先试试 np.linalg.solve() 。如果你得到了一个独特的解决方案,你就完成了任务。如果你得到一个错误信息(“奇异矩阵”),线性系统要么无解,要么有无穷多个解。然后,如上所述,尝试使用 SymPy Python 包获得简化的行梯队形式。通过查看简化表格的最后一行,你就可以决定事情了!
另外,请注意以下几点。
- 上面讨论的方法只能应用于线性系统。换句话说,系统中的所有方程都应该是线性的。
- 如果一个线性系统的方程比变量少,那么这个系统一定是依赖的或不一致的。它永远不会有唯一的解决方案。
- 方程比变量多的线性系统可能无解、唯一解或无穷多解。
我的读者可以通过下面的链接注册成为会员,以获得我写的每个故事的全部信息,我将收到你的一部分会员费。
报名链接:https://rukshanpramoditha.medium.com/membership
非常感谢你一直以来的支持!下一个故事再见。祝大家学习愉快!
特别感谢 Unsplash 网站上的 Antoine Dautry ,他为我提供了这篇文章的封面图片。本帖提供的文字内容、代码示例、其他图片和内容链接,版权归作者所有。
鲁克山普拉莫迪塔 2021–06–12
一个公司如何找到最好的市场来投放广告?
使用 Plotly 和 Tableau 识别最佳广告市场。
一家虚构的电子学习公司,目前总部设在美国,要求我进行一项调查,以确定推广其产品的最佳市场。他们也想知道学习者愿意为哪种内容付费。
这家公司提供不同的编程课程,包括 web 开发、移动开发、数据科学和游戏开发。Web 开发和移动开发占据了所提供课程的最大份额,学习者需要支付 59 美元的月费才能访问课程内容和资源。
在这篇文章中,我将带你了解我为公司寻找最佳市场的步骤;利用情节和画面。
收集数据
我有两种选择来找到合适的数据——对不同的市场进行调查,或者使用可靠来源的可用数据。考虑到我进行调查的时间和资源限制,我选择使用 freeCodeCamp 2017 新编码器调查。
freeCodeCamp 是一个完全免费的电子学习网站,提供各种网络开发课程。我选择了他们的数据,因为他们经营着一家流行的媒体出版物,目前拥有 60 多万名粉丝。更重要的是,2017 年的调查吸引了兴趣不同的新程序员。
你可以在这里下载数据集。
初始数据探索
我使用以下代码来研究数据集:
import pandas as pd
survey_data = pd.read_csv(‘2017-fCC-New-Coders-Survey-Data.csv’, low_memory = 0)#low_memory prevents dtype warning
survey_data.shape
以下是熊猫数据框的截图:
熊猫数据框中数据集的前 5 行(截屏来自 Yeside Okelana 写的 Jupyter 笔记本
数据集有 18,175 行和 136 列。列名也是不言自明的;这使得分析变得简单明了。
因为我要分析 Tableau 中的数据集,所以我将 Pandas 数据框从我的 Jupyter 笔记本导出到。包含以下代码的 csv 文件:
df.to_csv(r'Path where I wanted to store the exported CSV file\New File Name')
新编码者的利益分配
回想一下,尽管该公司提供的大多数课程都是关于移动和 web 开发的,但他们也提供数据科学和游戏开发等领域的课程。
但是首先,我们需要知道这个数据集有多大的代表性——web 和移动开发也是新程序员的兴趣所在吗?
为了回答这个问题,我为数据集中的JobRoleInterest
列创建了一个频率表,并做了以下观察:
- 相当多的新程序员只对 web 开发感兴趣(全栈、前端或后端开发)。
- 有些人对移动开发感兴趣。
- 少数人对移动和网络开发以外的主题感兴趣。
编码员的兴趣截图(图片来自 Yeside Okelana 的 Jupyter 笔记本
可以查看 Jupyter 笔记本查看频率表。
同时,频率表还显示,相当多的人有多重工作兴趣。因此,找出只对一个主题感兴趣的程序员和对多个主题感兴趣的程序员的比例是很有用的。
为此,我:
- 分割
JobRoleInterest
列,找出每个参与者选择的选项(我先去掉空值),然后 - 使用选项为变量生成频率表。
下面是我为完成这一任务而编写的 Python 脚本:
为编码人员创建频率表的 Python 脚本(由 Yeside Okelana 编写)
然后,我用 Tableau 制作了这个条形图来形象化这个比例。
按兴趣数量划分的编码者百分比(在表格中创建的条形图,由 Yeside Okelana 提取)
显然,大约 32%的程序员对他们想从事的特定编程领域很有把握。
但是,公司是否应该考虑扩展他们的课程设置;事实上,68%的程序员有不止一个兴趣,这将有助于他们决定引入哪种内容。
但是由于我们的重点是 web 和移动开发,让我们看看有多少程序员对这两个主题中的至少一个感兴趣。
我用 Plotly 创建了一个饼图,来直观地展示 web 和移动开发兴趣与其他兴趣的比较
程序员对 Web 或移动开发与其他主题的兴趣(饼状图由耶塞德·奥克拉纳使用 Plotly for Python 制作)
图表显示,大多数(约 86%)编码人员对 web 或移动开发感兴趣。这表明新编码员的兴趣分布与公司的课程分布相匹配。
下一步是确定花费广告预算的最佳市场。
为此,我发现:
- 这些新编码员的位置,
- 编码员数量最多的地点,以及
- 这些地方的新程序员愿意花多少钱来学习。
新编码员的位置和密度
在这个数据集中,我们有两列国家级数据的特权:
CountryCitizen
哪一项描述了编码者的原产国和CountryLive
描述编码者居住的国家。
然而,为了这个分析的目的,我与CountryLive
专栏一起工作,因为营销团队对在人们目前居住的地方投放广告感兴趣。
此外,由于数据提供了国家层面的信息,我将每个国家视为一个市场。
在这个分析中,我通过市场中编码者的数量来定义感兴趣的市场。本质上,一个市场的潜在客户数量越多越好。
我们来看看市场规模…
总体市场规模(图表由 Yeside Okelana 的 Tableau dashboard 生成)
从这个图表中可以看出,45.7%的程序员生活在美国。这是一个相对较大的数据比例。由于 freeCodeCamp 的总部设在美国,预计很大一部分受访者将来自美国。
我们还看到,像印度(7.7%)、英国(4.6%)和加拿大(3.8%)这样的国家构成了前四大潜在市场。
虽然带着这些信息在美国市场进行营销活动很有诱惑力,但为了盈利,了解这些市场的程序员愿意在学习上花费多少也很重要。
收入潜力
我和MoneyForLearning
栏目一起工作,了解该公司在这些市场的收入潜力。本栏描述了参与者愿意为学习花费的金额。
回想一下,订阅费是每月 59 美元。
同时,我将剩下的分析限制在 4 个市场——美国、印度、英国和加拿大,原因如下:
- 这些市场有最高的绝对频率。
- 因为课程是用英语编写的,所以这些国家的官方语言也是英语是有帮助的。因此,广告有更高的机会接触到正确的受众。
接下来,我创建了一个名为money_per_month
的新列,它描述了一个学习者每个月在学习上花了多少钱。我通过将MoneyForLearning
列除以MonthsProgramming
列来创建这个列。然后,我将每个市场的价值可视化在一个条形图中,如下所示:
前 4 大市场每月的平均收入(在表格中创建了图表)
从柱状图中,我们可以看到,平均来说,美国的学习者愿意支付最高的月费。
然而,如果我们考虑一些社会经济因素,如人均国内生产总值,那么人们可能会问为什么印度的学生愿意比英国甚至加拿大的学生支付更多的钱。
可能是加拿大和英国的数据代表性不足,或者是印度数据中存在异常值,使得平均值过高,或者是英国数据中存在异常值,使得平均值过低。也有可能数据是正确的。
让我们进一步调查,以得出结论。
处理极端异常值
我利用money_per_month
列来可视化可能的异常值。
下面的方框图显示了 4 个市场的money_per_month
值。
前四大市场每月的资金分布情况(图表由 Yeside Okelana 在 Tableau 中创建)
乍一看,我们无法从这个箱线图中确定印度、加拿大和英国是否存在极端异常值。但是美国有明显的极端异常值——2 个人表示他们每月支付超过 50,000 美元,这很奇怪,但并非不可能。
然而,出于分析的目的,我排除了大于$20,000 的值。
排除大于 20,000 的money_per_month
值后,平均值发生变化。看看新的价值观:
Yeside Okelana 制作的条形图截图
下面是一个显示剩余值分布的箱线图:
图片来自方框图由叶塞德·奥克拉娜在 Tableau 中创作
看方框图,很明显还是有几个极端的异常值。印度的值大于 2500 美元,美国的值大于 6000 美元,加拿大的值大于 5000 美元。
我进一步分析了这些值,并根据某些标准剔除了一些异常值。
例如,我观察到,印度有 6 名受访者表示,他们花了 2500 多美元学习,但没有人参加训练营。
我认为,受访者输入如此高价格的一个可能原因是他们误解了“除了大学学费,到目前为止,您在学习编程上花了多少钱(以美元计)?“所以,他们一定输入了他们的学费。我消除了这样的争吵。
你可以在 Jupyter 笔记本中获得我使用的淘汰标准的全部细节。
这是一个条形图,显示了每月花费的重新计算的平均值。
前四大市场每月平均收入(截图摘自 Yeside Okelana 制作的 Tableau 图表
…以及每个市场中money_per_month
分布的最终箱线图。
前 4 个市场的每月货币值分布(方框图由 Yeside Okelana 在 Tableau 中创建)
我们现在已经非常接近确定最佳广告市场了。
选择最佳市场
很明显,在这 4 个市场中,美国是我们绝对应该做广告的一个市场,因为大多数新程序员目前都住在那里,他们愿意花高价学习(平均 143 美元)。
加拿大似乎是第二个要考虑的市场,因为学习者愿意支付比在印度和英国更高的价格。
然而,有几个原因可以解释为什么将印度视为第二好的市场会更好。他们在这里:
- 对于印度的潜在客户来说,每月 59 美元的订阅费似乎并不贵,因为他们平均可以支付 66 美元。
- 印度的潜在客户几乎是加拿大的两倍。
前四大市场中每个市场的规模(由耶塞德·奥克拉纳用画面创建)
不清楚我们应该在印度和加拿大这两个市场中选择哪一个。因此,我们有三个选择。
选项 1
把广告预算全部花在美国市场上。
选项 2
利用市场规模的比例,在美国和印度或美国和加拿大之间划分广告预算,如下所示:
- 美国为 86%,印度为 14%。
- 美国为 92%,加拿大为 8%。
选项 3
利用市场规模的比率,在美国、印度和加拿大之间划分广告预算如下:
- 美国为 80%,印度为 13%,加拿大为 7%
然而,这些选项最好由营销团队仔细检查,然后他们将利用他们的领域知识在印度和加拿大进行新的调查。有了新的调查,我就可以对新数据进行进一步分析,做出更明智的决策。
同时,根据现有数据,没有考虑英国市场,因为平均money_per_month
低于订阅费。
结论
这个项目的目标是找到做广告的最佳市场。根据我对 freeCodeCamp 2017 年新程序员调查的分析,很明显美国是一个很好的广告市场。但是在印度和加拿大之间做决定并不容易。
然而,我认为,营销团队将处于最佳位置,要么使用此分析的结果来确定要考虑的其他市场,要么创建一个新的调查,以便做出更明智的决策。
DQN 如何逼近贝尔曼方程?
建立直觉
这是那些可能比自己发现更难解释的事情之一。在深度 Q 学习中,贝尔曼方程由 DQN 近似的方式在直觉上并不明显。这篇文章是关于我对正在发生的事情的探索。一个简单的 DQL 模型,其代码可在这里获得,有助于可视化 DQN 学习,并揭示了算法如何迭代和向固定点前进。如果感兴趣,下载模型并调整参数,以探索它们的效果和相互依赖性。
为什么这种洞察力是有用的?因为它导致在配置与经验重放相关的超参数(如缓冲区大小、采样批量大小、目标更新频率)时做出更明智的决策。它也有助于解释意外结果或不稳定性的一些原因,特别是在训练有限数量的数据时。
本文假设读者熟悉深度 Q-Learning,并且具有经验重放和双(策略和目标)DQN 实例的典型实现的工作知识。有太多关于强化学习、Q 学习和深度 Q 学习的参考文献。DeepLizard 的这一系列四教程、 Tambet Matiisen 的文章“揭秘深度 RL ”以及 Jonathan Hui 的 RL - DQN 深度 Q-Network 就是这样三个参考资料,它们为本文奠定了基础,并提供了引入该主题的补充方式。
DQN 被训练来近似的贝尔曼方程的形式是:
采取行动 a 后状态 s 的 Q 值是括号中表达式的期望值,由此从(s,a)到新状态 s '和奖励 r 的映射从经验重放历史 h 中导出。括号中的表达式是该步骤的奖励与新状态 s '的贴现最大 Q 值的总和,其中 a '是最大化行动。贴现因子为 γ。
双 DQN 的实现,使用两个相同的神经网络实例:策略 DQN 和目标 DQN。政策——DQN 是用于制定每一步决策的地方,也是所有培训发生的地方。目标 DQN 只是策略 DQN 的快照的被动副本,每步都会被替换。这是通过简单地复制其权重来完成的。设 l 为跟踪这些 τ 步循环的序号。在周期 l 期间的目标 DQN 近似于在周期 l-1 期间学习的策略 DQN 函数。当然,这假设 DQN 的架构是正确的,并且能够学习接近目标 Q 值,我们认为这是给定的,这超出了本文的范围。
为了直观显示目标和政策 Q 值随时间的变化,并展示它们如何捕捉任意大量的未来贴现回报,我们将进行两种简化:
- 我们将我们的环境限制为只有一个动作,使动作选择具有确定性。这消除了在比较不同轨迹的累积未来回报时的任何模糊性,并确保我们是在比较苹果与苹果。
- 我们用五个随机特征(可以是任何数字)构建状态,取值从 0 到 1,奖励总是设置为这五个值的平均值,即每一步的期望值相同。因此,累积奖励单调增加并接近一个固定点,即平均奖励乘以γ的幂的和的渐近极限:
我们使用这个数学表达式来生成未来奖励的每个深度级别的理论贝尔曼方程结果,并将这些值与每个步骤中相应的目标和政策 DQN 生成的值进行比较。
考虑到这两种简化,我们可以将贝尔曼方程简化为:
其中 t 表示沿着确定性轨迹的步骤序列。上面的函数是尾递归的,和原来的贝尔曼方程一样,可以简化为一次迭代。此外,如我们所见,第二项形成一个收敛于一个不动点的级数。为了说明这是如何工作的,让我们用循环序列 l 来解开递归标记级数的每一级:
未来奖励的进展
第一个公式简单地计算 Q 作为步骤 t 的奖励。第二个和每个后续公式通过增加一个未来折扣奖励的步骤使计算更加精确。显然, l 的每一次增加都对应于贝尔曼方程右侧的一个额外嵌套项:
用贝尔曼方程研究未来报酬的级数
这个 Q 函数阶梯对应于由目标 DQN 在由 l 表示的周期序列中捕获的快照阶梯。最初,目标 Q 函数是第一个方程,其中 l =0 。每个新周期 l 开始于将目标与策略 DQN 同步,随后训练策略 DQN 以接近贴现未来奖励的附加水平( l+1 )。在每个周期中,DQN 接近由贝尔曼方程定义的固定点。
这看起来像是可以通过迭代实现的递归函数的教科书示例。不同之处在于,该循环不是简单地聚集数据,而是“递归地改进”非线性函数,即策略 DQN,其模拟收敛序列,即贝尔曼方程。在每次迭代期间,DQN 被训练到极限的更好的近似值,即固定点。因为我们使用迭代而不是递归,我们的过程要求我们在训练期间覆盖策略 DQN 的相同实例。目标 DQN 就像一个“变量”,它保存了在生成目标时使用的最后一次迭代的策略 DQN 的副本。每一次迭代都需要 k 步,但是如果我们选择设置 k=1,那么我们的双 DQN 实现将会崩溃(或者变得类似于)为单个 DQN 实现。
让我们来看看所有这些与 DQN 架构和相关超参数相关的一些含义。但是首先,我们总结一下我们使用的符号:
k 是目标更新事件之间的步数
m 是一集的步数(假设没有终端状态)
m/k 是一集的目标更新事件数
l 是截至时间 t 的目标权重更新总数
b 是来自重放缓冲区的每批重放样本的经验数
DQN 的训练不能捕获比 l 更多的未来折扣奖励水平:【DQN】不能将比执行的目标权重更新的次数更长的未来折扣奖励范围纳入其贝尔曼方程的近似中。即使 k 比成功训练策略 DQN 所需的时间长得多,也是如此,因为用于训练的目标被限制为比前一周期的目标多一个级别。即使每个周期的训练都很完美,目标也会被训练到 l 的水平。
γ的高值需要更大数量的目标权重更新: 考虑选择*= 0.95需要l**= 45次迭代来覆盖在折扣 Q 值中贡献 10%或更多的所有项。这是因为γ⁴⁵=0.10。对于γ**= 0.8只需要大约l**=10 次迭代自γ⁰= 0.11。这说明了为什么设置γ**= 1或非常接近它会有问题。通常,我们希望接近渐近极限的 10%以上,因此我们必须确保允许足够的目标更新来充分训练 DQN。为了包括所有贡献超过 1%的未来奖励,这两种情况所需的迭代次数分别为 90 和 21。最小迭代次数由表达式**log(d)/log(γ)*给出,其中 d 是最小可接受折扣,而 γ 是折扣因子:
log(0.01)/log(0.95)= 90
log(0.01)/log(0.80)= 21
*用于将策略 DQN 训练到每个新目标的示例数量是 bk: 可能需要调整一批中的经验数量,以便在一个训练周期中使用足够的经验。当然,训练可以持续不止一集。
第 1 次迭代期间的训练对于所有级别 i ≤ l 连续进行: 学习通常比上面的讨论所表明的更流畅且更少条块化。例如,一个目标迭代的训练可能在分配的 k 步骤中只部分完成。对于单个 DQN 的情况或者如果 k = 1,这显然是这种情况。训练优化所有未来奖励等级,最高(但不超过) l 。
设置 k=1 模拟单个 DQN 的情况:使用单个 DQN 作为政策和目标,只要它收敛,将可能近似于贝尔曼方程。这个场景相当于有两个实例,并且在每一步都更新权重,即k*= 1*,从而策略 DQN 的训练量只受批量 b 的控制。**
****避免重放缓冲区中的陈旧体验:较长的重放缓冲区可以容纳更多种类的体验和更大的批量样本。根据应用,这可能是所希望的。然而,如果缓冲区跨越多个情节,特别是如果相同的数据集范围被重复用于训练,这可能导致不稳定。原因是,从混合了新的和陈旧的经验的缓冲区中取样可能会导致不同的轨迹和不同的奖励,从而导致不一致或倒退的学习行为。这更有可能发生在有噪声的数据中。比方说,在训练的早期阶段,一个特定的状态倾向于动作 1,而在训练的后期,同样的状态倾向于动作 2。如果两个体验都存在于重放缓冲区中,选择较早的一个将会适得其反。避免这种情况的一种方法是让重放缓冲区安全地变大,但不要大到有采样陈旧体验的风险。
DQN 有效性,低 l 和/或嘈杂的数据可以被混杂: DQN 架构的不足之处,或嘈杂的环境可以造成跳动的损失。不仅绘制损失图,而且分别绘制目标 Q 值和预测 Q 值也有助于分析。如果平台以与目标重量更新相对应的间隔出现,则有理由怀疑训练没有充分渗透到足够的未来折扣水平,或者更新必须更频繁,或者可能需要更大批量或更长时间的训练。如果这发生在训练过程中,请考虑在以前没有训练过的数据中形成新机制的可能性。
对于较小规模的训练数据,考虑到γ,k,l,b,m: 之间错综复杂的依赖关系, γ 的值越高,说明足够的目标更新 l 对于确保未来奖励折扣的足够深度越重要。请记住,正是目标更新频率扩展了未来折扣奖励的范围,因此如果您需要 γ 非常接近 1,您可以考虑单个 DQN(如果它收敛),或者具有较小k 的双 dqn 增加批量 b 可以补偿较短的迭代。为了提高稳定性,尽量允许足够多的例子b***k在每个目标迭代内进行训练。每个周期培训所需的示例数量也取决于数据的性质和 DQN 体系结构。
**一个具有单一动作环境的普通工作 DQL 有助于说明这些要点。你可以在 this GitHub repo 获取代码。该状态包含五个取值在 0.0 和 1.0 之间的随机特征。回报总是这五个特征的平均值。下图显示了以三种不同方式产生的随机批次经验样本的平均 Q 值:(1)政策 DQN,(2)目标 DQN,以及(3)根据前面所示的每个 k 步骤的 Bellman 方程的扩展计算出的理论值。该情节长 12000 步,目标更新每 1000 步发生一次,并且批量样本大小为 250 次经历。该图清楚地显示了从 Q=0.5 开始,每 1000 步增加一个折扣项,这些值如何在理论级数后达到平稳状态。我们用贴现因子 γ = 0.8。奖励的期望值总是 0.5,作为(0,1)中 5 个随机值的平均值。
k=1000,b=250,m=12000
大批量和长(1000 步)目标更新间隔导致低方差并允许快速收敛。数列收敛到的渐近极限是r**/(1-γ*)= 2.5forγ*= 0.8r= 0.5。****
通过将目标更新频率加倍到 2000 步,如下图所示,适合该集的六个周期不会从上一次运行的前六个周期扩展未来的奖励深度,并且它们最终与目标更新频率为 1000 时处于相同的水平。正是级别的数量将贝尔曼方程的精确度限制在未来奖励折扣的 6 个级别。实际上,每一级似乎都可以通过少量的步骤被充分训练到新的水平。当然,在更复杂的环境中,可能需要更多的示例来实现充分的培训。
k=2000,b=250,m=12000
接下来,我们将更新目标频率设置为 1,并将批处理设置为 1000。下图显示了理论线如何以接近垂直的方式达到渐近值,而目标值和政策值需要接近 1500 步才能达到该水平。这演示了如何同时训练多个深度级别,最多可达权重更新事件的数量。
k=1,b=1000,m=12000
我们重复相同的运行,但使用较小的批量:250。请注意,方差增加,训练变得更加紧张,
k=1,b=250,m=12000
你可以尝试批量大小、目标更新间隔、未来奖励折扣因子的不同组合,甚至尝试 1、2 或 3 个隐藏层的不同 dqn。“readme”文件概述了代码以及如何通过配置文件更改超参数。
一个 AI 是如何想象宇宙的?
利用生成性对抗网络生成新的世界、星系和恒星
由 Unsplash 上 Greg Rakozy 拍摄的照片
外面有什么?在这个浩瀚、无限、不可思议的宇宙中……有史以来,恒星、行星、星云、天体都在碰撞、绕行、诞生、消亡。
人类总是着迷地仰望天空,想象着梦幻般的世界和遥不可及的星系,这促使人类利用科学来更好地了解宇宙。
多亏了现代望远镜,我们现在可以仰望星空,发现许多关于宇宙和我们自己的真实面貌。
杰里米·珀金斯在 Unsplash 上拍摄的照片
太空也一直是全世界艺术家的灵感来源,他们甚至创造了一个专门用于天文学的特殊流派,即“太空艺术”,来展示宇宙的奇迹。几个世纪以来,产生了无数的艺术作品,从 1301 年乔托的《东方三博士的崇拜》中天空中的彗星,到展示遥远、迷人和想象中的星系的现代艺术作品。
杰里米·珀金斯在 Unsplash 上拍摄的照片
因此,几个世纪以来,我们已经看到了科学家是如何发现宇宙的,艺术家是如何想象和抽象宇宙的,但人工智能会怎么想呢?它会如何想象宇宙?
我们现在能够回答这些问题,这要归功于生成性对抗网络(GANs),这是一种能够查看一系列图像并生成新的可信图像的神经网络!
gan 由两个截然不同的网络组成,一个是生成器,一个是鉴别器,这两个网络是相互对照的。生成器查看输入数据,试图生成新的可信图像,以欺骗鉴别器。另一方面,鉴别器试图理解给定的图像是生成的还是原始的。当生成器在生成图像方面变得足够好以至于骗过鉴别器时,除了输入数据中存在的例子之外,它还可以用于创建其他可信的例子。
作者图片
然后,我创建了一个小型数据集,其中包含 600 个真实空间场景的例子,包括行星、星云、星系和恒星,以及虚构的空间主题绘画和艺术品。这些图像将成为我们的 GAN 的输入,并将作为它理解空间是什么的知识库。
有了这些数据,我首先训练了一个能够生成 128x128 像素图像的小型 GAN,然后是一个轻量级的 StyleGAN,这是目前最强大的 GAN 之一。
让我们来看看由小甘生成的一些最精彩的图像!
图片由作者
在这个奇妙的网络生成的宇宙中,行星、太阳和星系可以清晰地分辨出来,它们明亮的颜色照亮了黑暗的空间,这是通过一个相当小的网络和一些样本图像获得的。
但是网络是如何实现这些结果的呢?这一切都始于简单的噪声,图像以一种几乎随机的方式生成,生成器网络逐渐学会进化以欺骗鉴别器网络。
让我们来看看随着时代的推移,甘是如何生成图像的:
图片由作者
这些是小 GAN 获得的结果,现在让我们看看轻量级版本的 StyleGAN 能够生成什么!
图片由作者
惊人的和非常现实的图像!以下动画展示了 GAN 实现这一奇妙结果的过程:
图片由作者
但是我们想要更多。为什么要满足于产生单一的天体呢?我们想要创造一个完整的宇宙!
好吧,也许让一个 GAN 自己生成宇宙的一部分有点过分了。然而,我们可以从哈勃望远镜中获得灵感,该望远镜能够通过将对宇宙各个部分的观察结合在一起而组合出一幅广阔的宇宙图。我们不能做些类似的事情吗?
幸运的是,我们不需要建造一个巨大的望远镜来获得我们的观测结果,因为七年前在 Kaggle 上开始了一场比赛,以训练一个可以区分不同类型星系的分类器。一个巨大的数据集被建立起来并公之于众,该数据集包含了由望远镜捕捉到的成千上万的各种大小、形状和颜色的星系的真实图像。
有了这么多数据,不尝试利用我们的星系来产生新的星系将是一种浪费,你不这样认为吗?我已经完成了,这些是模型生成的图像:
图片由作者
太棒了。有了这些结果,我们可以将这些图像组合在一起,生成一个广阔的宇宙视图!为了做到这一点,我们的 GAN 生成的图像将与其他正方形和中性图像相结合,以在空间的各种随机区域中给出空白空间的感觉。
一些中性瓷砖的例子。图片由作者提供。
所有这些图像将被随机混合,调整大小,旋转,最后组合成一个大图像!
各位,这就是,甘宇宙!
图片由作者
我们已经到达了旅程的终点。我们让自己陶醉在这些奇幻的世界里,在无尽的宇宙中迷失了自己的心智。当然,那里有无限的星系和行星,迷人而遥远,还有更多我们可以想象和绘制,今天甚至可以自动生成,但有一点是肯定的,我们所有人都应该清楚:
在无限的宇宙中,只有一个地球。
美国宇航局在 Unsplash 拍摄的照片
这种意识加上我们近年来目睹的可怕的灾难性现象,应该促使我们思考保护我们星球的健康是多么重要。政府间气候变化专门委员会(IPCC)的科学家最近敲响了警钟,称人类为红色代码。人类活动导致气温急剧上升,降雨模式发生变化,海平面上升,全球野火数量显著增加。
法比安·琼斯在 Unsplash 上的照片
在日常生活中养成良好的习惯当然是抵消这种现象的好方法,但最大的影响当然可以由政府通过立即有效的监管来实现。否则,简单地说其他人应该带头并不是一种建设性的态度,因为这篇文章的许多读者都对机器学习的世界感兴趣,我收集了一些可能的起点,以产生具体的影响。
看星星,但保护你的地球。
执行类似实验的代码现在可以在 Github 上获得!
参考资料和见解
[1]《大卫·柯考米尼》。"机器学习专家应不应该响应气候变化号召行动起来?
[2]“约瑟夫·罗卡”,“理解生成性敌对网络(GANs) ”
[3]“罗汉·贾格塔普”,“生成性对抗网络(GANs)综合指南”
[4] “Ian J. Goodfellow 等人”,“生成性对抗网络”
[5]“d .哈维等人”,“银河动物园——银河挑战”
[6]“luciduals”,“ StyleGAN2 Pytorch 实现
[7]“luciduals”,“轻量级 StyleGAN Pytorch 实现”
[8]“美国国家航空航天局”,“哈勃天文学家汇集广观不断演化的宇宙
【9】《维基百科》,什么是太空艺术或天文艺术?
[10]“IPCC”,“气候变化广泛、迅速、加剧
ASR 系统如何处理从未见过的单词?
语言的教训:Dialpad 的数据科学研究团队正在进行的系列中的第一篇
首先,如果你是自动语音识别(ASR)的新手,一定要看看我同事的 ASR 101 帖子。这些信息会派上用场,因为今天,我们将更进一步,看看如何训练 ASR 系统。具体来说,就是学习从未见过的新单词。
传统的 ASR(自动语音识别)系统有三个主要组件:
- 声学模型,
- 语言模型,以及
- 发音词典。
发音词典包含单词及其相关发音(在某些情况下是多个发音)。在这种类型的系统中,任何不在本词典中的单词都不会被输出到抄本中。
即使字典里有成千上万的单词,我们也需要一种方法来不断更新它,以确保我们为客户提供最准确的抄本。(我们的词汇和俚语总是在进化!)
因此,如果我们的转录系统在音频中遇到一个单词是字典中的而不是,它将使用字典中的单词以及听起来与所说的相似的单词来猜测所说的内容。
例如,我们的公司名称可能会出现为“拨号键盘”,而当 COVID 第一次出现时,它被转录为“觊觎”。
我们训练模型的方法之一是将音频发送给一组转录员,他们转录音频,这为我们提供了音频中所说内容的高度准确的表示。我们可以将从这个团队获得的数据与我们自己的词典进行比较,以识别当前不在词典中的单词。
平均来说,每 1000 个单词中大约有 6 个是我们的字典中没有的,我们称之为“词汇之外”的单词,或 OOV。
OOV 里有什么?(有 6 种类型)
你可能想知道,在一本已经包含成千上万个词条的字典中,还会缺少哪些词呢?我们对其中的一小部分进行了分析。它们主要分为六个不同的类别:
1.人名——46%
绝大多数 oov 都是人名。由于各种原因,人名给 ASR 系统带来了相当大的挑战。
许多名和姓有多种拼法和发音。还有大量不同的名字,特别是当我们努力包括来自许多不同起源的名字,而不仅仅是西方国家常见的那些。
例如,这里列出了“基拉”这个名字所有可接受的拼法:凯拉、凯拉、凯拉、基拉、基拉、凯拉、凯尔哈、基利亚、凯拉、基拉和希亚拉。
2.真实 OOVs — 24%
大约四分之一的单词是我们确定为“真实”的未登录词。这些英语单词还没有进入我们的系统,可能是因为它们很少使用,或者是最近才被纳入我们的日常用语。
你可能遇到的一些“罕见用法”的例子包括“亚热带”和“嵌入”,而一个最近在使用中爆炸的词的好例子可能是“煤气灯”
3.首字母缩写— 20%
我们审查的单词中,大约有 20%是首字母缩写词,它类似于首字母缩写词,但发音是组成它们的字母,而不是单词。
例如,NASA 是首字母缩写,CRM 是首字母缩写 ASAP 可以两者都是!任何一个最近开始新工作的人都会告诉你,公司喜欢用很多首字母缩写!
我们希望确保我们能够识别它们,以正确地设置它们的格式,并能够将它们与说话者实际拼写单词的时间区分开来。
我们需要 EOD 把这个交给首席执行官。
对
我的电子邮件地址在 Dialpad dot com 拼写为 J-O-N-E-S。
4.公司名称— 8%
我们看到的公司名称通常分为两类:
- 那些发音像一个或几个常用词的词——想想 LinkedIn = linked in 和 Zoom = zoom,还有
- 那些没有的,比如 Deliveroo 和 Pinterest。
无论发音如何,我们都需要能够识别这些名称,以便正确地转录和格式化它们。我们遇到的一个公司名称的例子是 Spiceworks。
在不知道有一家公司叫这个名字的情况下,我们的文字记录会简单地将其转录为“spice works”
5.语言创新——2%
最后一类英语未登录词,诚然,也是我个人最喜欢的,是我们说话者的语言创新,也就是所谓的“实际上并不存在,但有人说过的单词”
人类非常擅长塑造词语来传达意思,而不会扰乱听者的理解!我最近遇到的一个很好的例子是“informationable”这个词,这个词没有出现在韦氏词典,但仍然能够传达“提供信息的能力”的定义
在这一类别中,我们经常看到的另一个例子是通用商标现象,或者当专有商标开始被用作产品或服务整体的描述符时。
当人们把一个品牌名称修改成一个动词时,比如“我在 Craigslisted 上卖了我的旧手机”,它最常以 OOV 的形式出现
6.非英语单词— 1%
一小部分单词是非英语单词。在大多数情况下,我们的字典中不包括其他语言,除了那些说英语的人常用的语言。
这方面的一个例子是来自短语“途中”的单词“en”,它源于法语,但在英语会话中常用。
到目前为止,这一直是我们的政策,但在阅读了一篇关于这种方法相关问题的引人注目的文章之后,我们将寻求在我们的产品中更公平地支持来自不同语言和文化的外来词。
我们还能如何识别 OOVs?
语言很棒,也很复杂。上面描述的方法甚至还不足以识别对话中经常使用的所有行话、缩写和名字。
我们正在处理数百万分钟的对话,而只有极小一部分被发送出去进行转录。
为了尝试和减轻这种情况,我们为客户提供了通过他们的公司词典直接向我们提交这些单词的选项,这样我们可以快速将它们添加到我们的发音词典中,并在提交后两周内开始在我们的文字记录中识别它们。
这是迄今为止最有效的方法来帮助提高这些单词在你的成绩单上的准确性。完整过程如下所示:
图像由拨号盘提供
添加提交内容不仅有助于提高您自己的文字记录的准确性,也有助于使用相同术语的其他客户!我们还有一种更主要的方式来识别 oov,那就是通过一个叫做网络搜集的过程。
本质上,我们从客户的网站上提取数据,并对文本进行分析,以将产品名称或行话等重要术语与“the”等常用词区分开来。
这是一个非常成功的方法,因为它提供了一个团队使用的术语的更全面的视图。虽然使用公司的字典很好,但做条目的人可能会使用与不同团队或不同部门的人不同的词。
将字典与网络搜集的数据配对,可以让我们有一个更完整的可能出现在用户记录中的术语列表!
欢迎来到有史以来最大的语言课堂
我们一直在寻找新的关键短语来源,以包含在我们的模型中,并寻找其他方法来提供更准确的副本。
我们为客户的数据开发最准确的副本的旅程得到了客户的大力帮助,他们花时间在他们的公司字典中提供了周到的条目。
人工智能是如何创造价值的?
从更哲学的角度看待这项技术的影响
照片由来自 Pexels 的 Tara Winstead 拍摄。
过去的十年充满了喧嚣和热闹——没有新闻。然而,现在各个行业(至少从人工智能顾问的角度来看)对新的人工智能技术和方法的普遍兴趣和吸收有了明显的转变,从深奥到奇异,再到害怕过时。
行业和客户比以往任何时候都更愿意使用相对较新的(甚至未经证实的)数据处理和见解提取方法来参与原型和放大工作。但正如大多数顾问发现的那样,机器学习的简单应用并不能带来成功的解决方案。需要解决一个潜在的问题,一些可测量的结果和回报至少比实现成本高一个数量级。
那么价值通常是如何创造的,人工智能又是如何为价值创造做出贡献的呢?而且有没有一种模式可以解释为什么 AI 这么有价值?
理解现代经济中的价值创造
“价值”有许多定义,但为了我们的目的,我们将把它定义为*“对某物的重要性、价值或有用性的现代经济衡量”*(来自牛津语言)。由此可见,一个经济体系中的价值创造思想,直接关系到创造财富、降低运营成本,或者加速和减轻个人的工作负担的能力。
(现在,衡量人工智能的社会影响是一个完全独立的话题,我甚至不想在这里提出来。此外,我完全意识到我将屠宰经济学 101 概念,但我概括了这篇文章的要点和主要信息。)
超越(旧)工业的三部门模式
经济价值创造的一个流行模型是三部门模型,其中 20 世纪的经济价值观被分为三个主要领域:
- 第一产业集中于资源的开采和控制,如铁、木材和采矿;
- 第二产业侧重于制造、转型,直至交付消费品;
- 第三产业通常被称为服务部门,包括政府、咨询和知识工作者的所有事务。
这一特殊模式广泛关注价值创造的提取基础,包括对环境和对人的价值创造。还有一种资源有限的想法:只能有这么多技术工人,或者这么多树可以砍伐。这种经济模式的参与者主要被视为劳动者:伐木工、冶炼工、餐馆服务员。你通过 1)去上班,2)做好工作来获得报酬。
然而,这一模型未能捕捉到在这些部门中的每一个都有效所需的潜在知识。仅仅在森林附近给某人一把电锯并不意味着我可以每天安全可靠地获得一定数量的木材。
超越三个部门:知识经济
照片由 Pexels 的 Janko Ferlic 拍摄
也被称为第四次革命和信息时代,知识经济模型允许所有信息事项(如市场洞察、算法和流程)被表示为有价值的信息,工人现在成为思想家。
来自维基百科:
知识经济的特点是在微观经济和宏观经济环境中拥有高度熟练的劳动力;机构和行业创造需要专业技能的工作岗位,以满足全球市场的需求。知识被视为附加 输入劳动力 和 资本 。原则上,一个人的主要个人资本是知识以及创造经济价值的能力。
那么如果知识是有价值的,那么那个应用的自动化应用不也是有价值的吗?事实上,这就是自动化作为一个整体,特别是软件的用武之地。我可以将我的知识编码成一系列可重复的步骤,这些步骤将产生预期的结果,甚至是结果。
(关于这个编码过程的有趣事实是:软件开发人员,作为一个阶层的人,经历了巨大的https://www.zdnet.com/article/developer-burnout-isnt-going-away-employers-need-to-act-now/。我也经常听到我的团队使用让水手脸红的语言。)****
回到未来——与 ML 一起
从这些不同的模型中退一步,我们正在寻找关于人工智能的高层次问题的答案,以及在给定适当数据的情况下,人工智能在大多数情况下变得有价值的一般能力。
如果我们将三个部门模型抽象为活动类型,我们会注意到数字相关价值创造要素的三个可重复方面。这对技术领域的许多价值创造链是一个有益的启发。将这三个部门抽象为价值创造的一般要素,我们得到:
- 提取和收集,涉及通过从其原始环境中分离、隔离或复制特定单位而进行的积累。
- 转换,涉及到对这个单元应用一个或多个改变(比如处理或消化),这样它在不同的状态下可能更有用,通常是对它类的所有其他单元,有时是对这些单元的多个类。
- 信息,即与前两类相关的知识或诀窍(如在哪里提取、如何转化)。
数据及其价值创造元素的简单表示。
例如,在采矿业中,知道在哪里挖掘与知道如何操作将矿石从地下开采出来的机器同等重要。
(事实上,可以用一个案例来说明现代咨询是如何简单地利用信息差异的——你知道如何做一些我不知道的事情,而我需要这些知识,因此在我目前的情况下,你的知识是有价值的。)
知识经济中的价值:数据转换光谱
数据移动、改变和通知的方式是在知识经济内外创造经济价值的前提。我们终于看到了 21 世纪初大数据推动的结果,现在有办法让它变得可行。
如果我们采用所有形式的数据(无论是原始的、未收集的状态,还是经过润色的公司报告),并将它们放入按细化级别组织的桶中,我们可以创建五种主要状态:连接性、可见性、聚合、见解生成和决策支持。
数据转换类别。类别是什么真的不重要,更重要的是有一个独特的桶的概念。
这个数据转换谱是一个简单的模型,可以在高度互联的世界中用作技术创新的灵感。它涵盖了数据作为主要资源的价值创造的许多潜在方面。
公司将付费获得连接的、可见的、聚合的、可理解的和/或自动化的东西。
简而言之,当数据在整个范围内移动时,价值就产生了。
那么,为什么人工智能具有如此大的变革性呢?
机器学习是第一个可以应用于数据转换范围内价值创造链的每个方面的技术范式。由于其深度和广度,数据科学和机器学习工程的结合允许洞察的产生、工作的加速和对链上每个组件的调查支持。
人工智能如此有价值的原因是,它在数据转换的每个支柱内部和之间提供了价值创造的元素。
数据转换领域。
这就是为什么人工智能可以创造如此多的价值:它适用于几乎任何给定的数据相关背景,提供某种价值(通过操纵数据或在其背景下生成结果),并允许越来越多的自动化和来自数据的洞察力。
摘要
- 价值是通过一个能产生金钱、降低成本、减轻资源和劳动力负担的系统来创造的。
- 从历史上看,价值是由体力劳动创造的;现在,在知识经济中,信息和可再生的软件意味着降低分担负担的成本。
- 通过技术创造价值的基本要素是收集和提取资源,将这些资源转化为新元素,以及如何实现前两者的知识。
- 从数据中提取见解(有价值且可操作的信息)的能力贯穿于整个转型过程。
- 人工智能在这个光谱的每个支柱上创造价值。
咨询愉快!
马特。
如果您对本文或我们的 AI 咨询框架有其他问题,欢迎通过LinkedIn或通过email联系。