如何对你的 Azure 数据科学项目进行审计跟踪
1.介绍
假设一个机器学习模型正在生产中运行,重要的决策都是基于它的预测。或者假设一个模型有奇怪的结果,需要进行故障排除。因此,模型的审计跟踪是必不可少的,至少可以追溯到以下内容:
- 模型预测的记录
- 模型的版本和度量
- 模型中使用的数据和算法
- 创建模型的个人/团队
在这篇博客中,定义了一个 Azure 数据科学项目,然后讨论了如何创建审计跟踪。如果你对这个项目具体是如何实施的感兴趣,可以参考我之前的博客。请注意,这篇博客是独立的,没有必要先阅读前面的博客。
2.Azure 数据科学项目的设置
Azure 提供了很多进行数据分析和数据科学的可能性。在这个项目中,流行的 Azure 服务的功能被组合起来,以创建一个预测端点。项目的设置可以描述如下:
2. Setup of Azure data science project using popular Azure services
Azure 服务及其在本项目中的使用可以描述如下:
- Azure Storage gen 2 用于存储数据。数据是不可变的,并且新数据被添加到具有时间戳的单独文件夹中,使得当它被添加时是清楚的。
- Azure Databricks 用于模型的交互开发和特征工程。Azure ML 服务使用 Databricks Spark 集群作为计算来训练模型。请注意,创建了 sparkml 模型,但也可能创建了 scikit-learn 模型。
- Git 用于笔记本的源代码控制,并作为资源库链接到 Azure Devops。在这个项目中,使用了 Azure DevOps 中的 git,但也可以使用 GitHub。
- Azure 机器学习(ML)服务用于跟踪模型及其指标。Azure ML Service SDK 用于创建模型的 docker 映像并将其部署到 Azure Container 容器和 Azure Kubernetes 服务。有关使用 Azure ML 服务的部署可能性的概述,请参见此处的。
- Azure DevOps 用于设置构建/发布管道。在构建阶段,使用 git、Databricks Spark Clusters 和 Azure ML Service SDK 创建 docker 映像。在发布阶段,docker 映像被部署为 Azure 容器实例用于测试,然后部署到 Azure Kubernetes 服务用于生产。
- Azure 容器实例(ACI) 用作测试端点,而 Azure Kubernetes 服务(AKS) 用于生产。AKS 具有可扩展性、安全性和容错性。将 AKS 与 Azure ML Service SDK 一起使用,许多功能都是现成的,例如记录和评估模型数据和监控失败率、请求率
本项目的设置可视为“同类最佳”方法,具有以下优点/缺点:
- 这种设置的优点是团队可以使用他们最喜欢和最有经验的工具。例如,使用已经用于其他 IT 项目的 Azure DevOps。或者使用已经用于公司内部其他大数据项目的 Azure Databricks。
- 缺点是保留审计线索和故障排除会变得更加复杂。这将在下一章讨论。
3.审查跟踪
假设一个审计员想知道为什么使用 ML 模型做出某个决定(例如,为什么这个抵押被拒绝?).然后需要使用审计线索追溯模型决策的基础。在本章的剩余部分,将对本博客第一部分中介绍的主题进行审计跟踪,如下所示:
- 3a。记录模型请求和预测
- 3b。模型、图像和 HTTP 端点的版本
- 3c。模型的度量和统计
- 3d。模型中使用的数据和源代码
- 3e。创建模型的个人/团队
3a。记录模型请求和预测
在数据科学项目中,该模型使用 Azure ML 服务 SDK 部署在 AKS 产品中。使用 Azure ML service SDK 和记录和评估模型数据特性,可以记录所有的模型请求和预测。这记录在 Azure 存储帐户中,该帐户附加到/modeldata/文件夹中的 Azure ML 服务工作区,另请参见下文:
3a1. Storage account where logging is stored
在 data.csv 中,可以找到请求的时间戳、输入数据和预测,请参见下面的示例
3a2. Logging of input request and logging
3b。模型、docker 映像和 HTTP 端点的版本
为了链接模型、图像和 HTTP 端点,请转到 Azure portal 中的 Azure ML 服务工作区,然后转到“部署”选项卡。这里可以看到 AKS 中使用的 HTTP 端点的 IP 地址和 docker 镜像版本。
3b1. HTTP endpoint, AKS and image
随后,可以在模型选项卡中找到模型版本。
3b2. Model used in docker image
请注意,可以在标签中找到的运行 id。这可以用于在下一部分中检索模型度量。
3c。模型的度量和日志记录
使用前一部分中的 run_id,您可以查找模型的度量和统计数据。转到 Experiments 并使用过滤器中的 run_id 来查找模型的指标。
3c1. Retrieve model metrics
对于该模型,记录 roc、prc 和假/阴性阳性/阴性。此外,您还可以使用 matplotlib 创建图像。
3c2. Display metics of models
3d。模型中使用的数据和源代码
在这一部分中,将确定用于训练模型的数据和来源。所有源代码和数据都存储在 Azure DevOps 项目的存储库中,因此第 3b 部分中确定的模型需要链接到存储库。
首先,查找使用 Azure ML 服务 API 将图像部署为容器的发布管道。在这个项目中,创建了一个夜间构建/发布管道,因此可以查看最后一个成功的发布,如下所示
3d1. Last succesfull build/release in Azure DevOps
在发布的日志中,可以找到发布步骤的日志。在部署步骤的日志中,可以找到对应于步骤 3b 中的 IP 和版本的 HTTP IP 地址和映像版本,见下文。
3d2. Logging of release
随后,通过点击工件框来下载发布的所有输入。在这个下载中,可以找到所有源代码,见下文。
3d3. Download build artifact
在这个项目中,数据不是版本控制的一部分,也没有存储在工件中。相反,数据存储在 Azure Storage gen 2 上,并且是不可变的。新数据被添加到带有时间戳的新文件夹中。随后,在构建管道中,记录哪些文件夹用于训练模型,从而可以清楚地知道使用了什么数据。
3e。创建模型的个人/团队
在上一节中,确定了用于创建模型的源代码和数据。在这一部分,追溯了是哪个人/团队更改了代码,以及这是在什么时候发生的。在步骤 3c 中下载的构建工件中,也可以找到提交 id,在本例中是 e670024。当您单击这个发布时,代码与之前的提交有所不同。此外,还可以找到变更的人员和日期,见下文。
3e1. Code compare with previous commit
通过单击 Parent 1 链接,您可以追溯到上一次提交,直到发现可疑的更改。或者,您也可以直接转到“提交”选项卡,查看最近提交的概述,并从那里开始,见下文。
3e2. Commit overview
最后,请注意,可以将您的 Azure Git 存储库与 Azure Databricks 连接起来,Azure Databricks 在本项目中用作交互式开发环境,请参见下面的截图以及使用此处的解释
3e3. Azure Databricks integration with Azure DevOps
4.结论
在这篇博客中,描述了一个数据科学项目的设置,其中结合了流行的 Azure 服务的功能。然后讨论了如何在这个项目中保留审计线索,以便可以追溯预测所基于的内容。当模型预测令人费解时,拥有一个良好的审计线索也有助于排除故障。这有助于将你的项目投入生产,参见下面的架构。
4. Setup of Azure Data Science project
如何调优决策树?
决策树的超参数如何影响您的模型,您如何选择要优化的超参数?
超参数调谐
超参数调优是在超参数空间中搜索一组可以优化模型架构的值。
这与调整模型参数不同,在模型参数调整中,您会搜索最能最小化成本函数的特征空间。
超参数调整也很棘手,因为没有直接的方法来计算超参数值的变化将如何减少模型的损失,所以我们通常求助于实验。首先,我们为所有超参数指定一个可能值的范围。现在,这是大多数人陷入困境的地方,我要尝试什么值,为了回答这个问题,你首先需要理解这些超参数的含义,以及改变超参数将如何影响你的模型架构,从而尝试理解你的模型性能可能如何改变。
定义值的范围后,下一步是使用超参数调整方法,有一堆,最常见和最昂贵的是网格搜索,其他如随机搜索和贝叶斯优化将提供“更智能”,更便宜的调整。这些方法并不是本文的重点,但是如果您想了解更多,请查看参考资料部分[1]。
决策图表
决策树是最流行和最广泛使用的机器学习算法之一,因为它对噪声的鲁棒性、对丢失信息的容忍度、对不相关的冗余预测属性值的处理、低计算成本、可解释性、快速运行时间和鲁棒预测器。我知道,这太多了😂。但是学生问我的一个常见问题是如何调整决策树。对于最大深度,我应该尝试的值的范围应该是什么,在叶节点上需要的样本的最小数量应该是什么?这些都是很好的问题,没有直接的答案,但我们可以做的是了解改变一个会如何影响你的模型。比如增加最大深度到底意味着什么,改变最小样本叶子对你的模型有什么影响。因此,在本文中,我试图向您介绍这些参数,以及它们如何影响您的模型架构,以及它对您的模型的一般意义。
让我们看看 Scikit-learn 的决策树实现,让我解释一下这些超参数是什么,以及它们如何影响您的模型。顺便说一下,我假设你对决策树有一个基本的了解。
由于决策树主要是一个分类模型,我们将研究决策树分类器。
决策树分类器
条件:字符串,可选(default=“gini”):
衡量分割质量的函数。支持的标准是基尼杂质的“基尼”和信息增益的“熵”。
如果你想知道决策树节点是如何分裂的,那是通过使用杂质。杂质是节点上标记同质性的量度。有许多方法来实现杂质测量,其中两个 scikit-learn 已经实现的是信息增益和基尼杂质或基尼指数。
信息增益使用熵度量作为杂质度量,并且分割节点,使得它给出最大量的信息增益。而 Gini 杂质测量目标属性值的概率分布之间的差异,并分割节点以使其给出最少量的杂质。
根据论文“基尼指数和信息增益标准之间的理论比较”[3],基尼指数和信息增益一致/不一致的频率仅占所有情况的 2%,因此对于所有意图和目的,您几乎都可以使用两者之一,但唯一的区别是熵的计算可能稍慢,因为它需要您计算对数函数:
许多研究人员指出,在大多数情况下,分裂标准的选择不会对树的性能产生太大影响。正如“没有免费的午餐”定理所表明的那样,每个标准在某些情况下是优越的,而在另一些情况下是低劣的。
拆分器:字符串,可选(默认= “最佳”)
用于在每个节点选择拆分的策略。支持的策略是选择最佳分割的“最佳”和选择最佳随机分割的“随机”。
根据 scikit-learn 的“最佳”和“随机”实现[4],“最佳”分离器和“随机”分离器都使用基于 Fisher-Yates 的算法来计算特征阵列的排列。您实际上不需要担心算法,唯一的区别是,在“最佳”拆分器中,它在拆分之前使用标准评估所有拆分,而“随机”拆分器使用随机统一函数,将最小特征值、最大特征值和随机状态作为输入。我们将在下面研究这些是什么,但现在,让我们看看拆分器将如何影响模型。
假设您有数百个要素,那么“最佳”拆分器将是理想的,因为它将根据杂质测量计算要拆分的最佳要素,并使用它来拆分节点,而如果您选择“随机”,则您很有可能最终得到的要素实际上不会提供那么多信息,这将导致树更深、更不精确。
另一方面,“随机”拆分器有一些优点,特别是,由于它随机选择一组要素并进行拆分,因此它没有计算最佳拆分的计算开销。其次,它也不太容易过度拟合,因为在每次分割之前,您基本上不会计算最佳分割,额外的随机性将在这里帮助您,所以如果您的模型过度拟合,那么您可以将分割程序更改为“随机”并重新训练。
因此,对于一个没有任何过度拟合的具有很少特征的树,为了安全起见,我会选择“最好的”拆分器,这样你就可以得到最好的模型架构。
max_depth: int 或 None,可选(默认=None)
树的最大深度。如果没有,则扩展节点,直到所有叶子都是纯的,或者直到所有叶子包含少于 min_samples_split 样本。
决策树可以达到的理论最大深度比训练样本的数量少 1,但是没有算法会让你达到这一点,原因很明显,一个很大的原因是过度拟合。请注意,这是训练样本的数量,而不是特征的数量,因为数据可以在同一特征上拆分多次。
让我们先来谈谈缺省的 None 情况,如果你不指定树的深度,scikit-learn 将扩展节点直到所有叶子都是纯的,这意味着如果你为 min_samples_leaf 选择 default,叶子将只有标签,其中缺省值是 1。请注意,这些超参数中的大多数都是相互关联的,我们将很快讨论 min_samples_leaf。另一方面,如果您指定一个 min_samples_split(我们接下来将会看到),那么节点将会展开,直到所有叶子包含的样本数都少于最小样本数。Scikit-learn 将根据哪个给你的树提供最大深度来选择一个。这里有许多移动的部分,min_samples_split 和 min_samples_leaf,所以让我们单独取 max_depth,看看当您更改它时,您的模型会发生什么,这样在我们完成 min_samples_split 和 min_samples_leaf 后,我们可以更好地直观了解所有这些是如何组合在一起的。
一般来说,你允许你的树增长得越深,你的模型将变得越复杂,因为你将有更多的分裂,它捕获更多的关于数据的信息,这是决策树过度拟合的根本原因之一,因为你的模型将完全适合训练数据,并且将不能在测试集上很好地概括。因此,如果您的模型过度拟合,减少 max_depth 的数量是防止过度拟合的一种方法。
深度太低也不好,因为模型会过拟合,所以如何找到最佳值,请进行实验因为过拟合和过拟合对数据集来说都是非常主观的,没有一个值适合所有解决方案。所以我通常做的是,让模型首先决定 max_depth,然后通过比较我的训练和测试分数,我寻找过度拟合或欠拟合,并根据我减少或增加 max_depth 的程度。
min_samples_split: int,float,optional(默认值=2)
分割内部节点所需的最小样本数:
- 如果 int,那么考虑 min_samples_split 作为最小数。
- 如果是 float,那么 min_samples_split 是一个分数,ceil(min _ samples _ split * n _ samples)是每次拆分的最小样本数。
min_samples_split 和 min_samples_leaf,如果你读了它们的定义,听起来好像是一个隐含着另一个,但是你需要注意的是,leaf 是一个外部节点,min_samples_split 指的是一个内部节点,根据定义,内部节点可以进一步拆分,而根据定义,leaf 节点是一个没有任何子节点的节点。
假设您指定了一个 min_samples_split,并且产生的拆分导致一个具有 1 个样本的叶,并且您将 min_samples_leaf 指定为 2,那么您的 min_samples_split 将不被允许。换句话说,无论 min_samples_split 值是多少,min_samples_leaf 始终是有保证的。
根据该论文,关于决策树的超参数调整的实证研究[5]对于在 scikit-learn 中实现的 CART 算法,理想的 min_samples_split 值往往在 1 到 40 之间。min_samples_split 用于控制过拟合。较高的值会阻止模型学习可能高度特定于为树选择的特定样本的关系。过高的值也会导致欠拟合,因此根据欠拟合或过拟合的程度,您可以调整 min_samples_split 的值。
【min _ samples _ leaf:int,float,optional(默认值=1)
叶节点上所需的最小样本数。任何深度的分裂点只有在左和右分支的每一个中留下至少 min_samples_leaf 训练样本时才会被考虑。这可能具有平滑模型的效果,尤其是在回归中。
- 如果 int,那么考虑 min_samples_leaf 为最小数。
- 如果是 float,那么 min_samples_leaf 是一个分数,ceil(min _ samples _ leaf * n _ samples)是每个节点的最小样本数。
类似于 min_samples_split,min_samples_leaf 也用于通过定义每个叶具有多个元素来控制过拟合。从而通过为每个样本专门创建一堆小分支来确保树不会过度适应训练数据集。实际上,这实际上只是告诉树,每片叶子的杂质不一定是 0,我们将在 min _ infinity _ decrease 中进一步研究杂质。
论文《决策树超参数调优的实证研究》[5]也指出,对于 CART 算法,理想的 min_samples_leaf 值往往在 1 到 20 之间。本文还指出,根据其相对重要性分析,min_samples_split 和 min_samples_leaf 对最终树的性能影响最大[5]。
根据 scikit-learn,我们可以使用 min_samples_split 或 min_samples_leaf,通过控制将考虑哪些拆分来确保多个样本为树中的每个决策提供信息。他们还说,一个非常小的数字通常意味着树会过度适应,而一个大的数字会阻止树学习数据,这应该是有意义的。我认为一个例外是当你有一个不平衡的阶级问题时,因为少数阶级占多数的地区会很小,所以你应该用一个较低的值。
min _ weight _ fraction _ leaf:float,可选(默认值=0。)
要求位于叶节点的权重总和(所有输入样本)的最小加权分数。当未提供 sample_weight 时,样本具有相等的权重。
min_weight_fraction_leaf 是要求位于叶节点的输入样本的分数,其中权重由 sample_weight 确定,这是处理类不平衡的一种方法。类别平衡可以通过从每个类别中采样相等数量的样本来完成,或者优选地通过将每个类别的样本权重之和归一化为相同的值来完成。另请注意,min_weight_fraction_leaf 将比不知道样本权重的标准(如 min_samples_leaf)更少偏向主导类。
如果样本是加权的,那么使用基于权重的预修剪标准(例如 min_weight_fraction_leaf)来优化树结构将会更容易,这确保了叶节点包含样本权重总和的至少一部分。
max_features: int、float、string 或 None,可选(默认=None)
寻找最佳分割时要考虑的特征数量:
- 如果 int,那么在每次分割时考虑 max_features 特性。
- 如果是 float,那么 max_features 是一个分数,在每次分割时考虑 int(max_features * n_features)个特征。
- 如果“自动”,那么 max_features=sqrt(n_features)。
- 如果“sqrt”,那么 max_features=sqrt(n_features)。
- 如果“log2”,那么 max_features=log2(n_features)。
- 如果没有,那么 max_features=n_features。
注意:直到找到节点样本的至少一个有效分区,对分割的搜索才会停止,即使它需要有效地检查多于 max_features 的特征。
每次出现分裂时,您的算法都会查看大量特征,并使用基尼不纯度或熵选取具有最佳度量的特征,然后根据该特征创建两个分支。每次查看所有特征的计算量很大,因此您可以使用各种 max_features 选项来检查其中的一些特征。max_features 的另一个用途是限制过度拟合,通过选择数量减少的特征,我们可以增加树的稳定性,并减少方差和过度拟合。
至于在选项中选择哪一个,这将取决于您拥有的功能的数量、您想要减少的计算强度或您拥有的过度拟合的数量,因此如果您有很高的计算成本或您有很多过度拟合,您可以尝试使用“log2 ”,根据产生的结果,您可以使用 sqrt 稍微提高它,或者使用自定义浮点值进一步降低它。
【random _ state:int,RandomState 实例或无,可选(默认=无)
如果 int,random_state 是随机数生成器使用的种子;如果是 RandomState 实例,random_state 是随机数生成器;如果没有,随机数生成器就是 np.random 使用的 RandomState 实例。
哈哈臭名昭著的 random_state,大部分新手都这么问我,为什么是 1,为什么是 0,为什么是 42?42 因为那是生命的意义,咄。
random_state 并不是一个真正需要优化的超参数,您应该这样做吗😋。让我从何时以及为什么应该设置 random_state 开始。最直接的答案是,这样你就可以得到一致的结果,这在一定程度上是因为记住 splitter,它会给你的结果带来一些随机性,所以如果你重新运行决策树,你的结果会有所不同,但不应该太不同。
这就引出了我的下一个观点,我看到新学生在玩 random_state 值,他们的精度会发生变化,这是因为决策树算法是基于贪婪算法[6]的,它使用随机选择的特征(拆分器)重复多次,这种随机选择受到伪随机数发生器[7]的影响,伪随机数发生器[7]将 random_state 值作为种子值, 因此,通过改变 random_state,您可能会随机选取好的特征,但您需要认识到的是,random_state 不是一个超参数,随着 random_state 改变您的模型的准确性仅意味着您的模型有问题。 这是一个很好的暗示,在你的数据中有许多局部最小值,决策树没有很好地处理它,所以我宁愿让你设置一个 random_state 并调整你的其他参数,这样你就不会陷入局部最小值,而不是玩弄 random_state。
min _ infinity _ decrease:float,可选(默认=0。)
如果该分裂导致杂质减少大于或等于该值,则该节点将被分裂。
加权杂质减少公式如下:
N_t / N * (impurity - N_t_R / N_t * right_impurity
- N_t_L / N_t * left_impurity)
其中 N 是样本总数,N_t 是当前节点的样本数,N_t_L 是左子节点的样本数,N_t_R 是右子节点的样本数。
N,N_t,N_t_R,N_t_L 都是指加权和,如果传递 sample_weight。
最小杂质减少帮助我们根据杂质来控制树的生长深度。但是,这种杂质是什么,它如何影响我们的决策树?记得在标准部分,我们快速看了基尼指数和熵,它们是杂质的一种度量。杂质测量定义了多个类别的分离程度。通常,当属性值的数据被平均分割时,杂质测量值应该最大,当所有数据属于同一类时,杂质测量值应该为零。更详细的解释将需要我们进一步进入信息论,这不是本文的范围,所以我将尝试解释改变杂质值如何影响您的模型,以及如何知道何时改变这些值。
最好的方法是绘制决策树,并研究基尼指数。如果您对正在处理的数据集有领域知识,那么解释决策树应该相当容易,因为叶节点的基尼指数为 0,因为它是纯的,这意味着所有样本都属于一个类。然后,您可以查看导致基尼系数为 0 的分割,并查看是否有必要对您的类进行这样的分类,或者您是否可以减少深度,从而得到一个更概化的树,如果是这样,您可以增加 min _ infinity _ decrease 以防止进一步分割,因为现在,如果杂质没有减少您指定的数量,节点将不会进一步分割。请注意,这将影响你的整个树,所以,你必须用这些数字做实验,但上面的解释应该给你一个起点。
class_weight:字典,字典列表,“平衡”或无,默认=无
与{class_label: weight}形式的类相关联的权重。如果没有给定,所有类的权重都应该是 1。对于多输出问题,可以按照与 y 的列相同的顺序提供字典列表。
class_weight 用于为每个输出类提供权重或偏差。但这实际上意味着什么,看当算法计算熵或基尼不纯度以在节点处进行分裂时,产生的子节点由 class_weight 加权,根据您指定的类比例给出子样本权重。
当数据集不平衡时,这非常有用。通常,您可以从类的分布作为类权重开始,然后根据决策树的倾向,您可以尝试增加或减少其他类的权重,以便算法相对于其他类惩罚一个类的样本。最简单的方法是指定“平衡的”,然后从那里开始自定义权重。
请注意,这不像欠采样或过采样技术,一个类中的样本数量实际上不会改变,而是分配给它的权重会改变,您可以在打印决策树和每个节点中的值时看到这一点,它将变为
weight * (the number of samples from a class in the node) / (size of class)
预排序:bool,可选(默认=False)
是否对数据进行预排序,以加快拟合中最佳分割的查找速度。对于大型数据集上决策树的默认设置,将此设置为 true 可能会减慢训练过程。当使用较小的数据集或受限的深度时,这可以加速训练。
这个参数相当简单,如果您有一个小数据集,或者如果您将限制树的深度,并且在运行第一次迭代后,您有一个不平衡的树,其中大多数数据点仅位于叶节点的一小部分上,使用预排序将有助于您。
预排序的工作方式是,在学习之前首先对所有变量进行排序,在每个节点评估时使用排序向量,在选择最佳分割后,您将分割数据点和排序索引,以便将数据子集和排序索引子集发送到子节点。因此,你可以在递归中应用这一思想。但是,请注意,如果数据实例的数量大于输入要素的数量,则这种方法有效。
摘要
决策树的复杂性对其准确性有着至关重要的影响,并且它由所使用的停止标准和所采用的修剪方法来明确控制。通常,树的复杂性是通过以下度量之一来衡量的:节点总数、叶子总数、树深度和使用的属性数量[8]。max_depth、min_samples_split 和 min_samples_leaf 都是停止标准,而 min_weight_fraction_leaf 和 min _ infinity _ decrease 是修剪方法。
尽管所有这些几乎都实现了停止或修剪方法,但它在应用于模型的级别上有所不同。如果你有一个硬停止标准,你的模型可能会拟合不足,所以如果你把它改为一个宽松的停止标准,那么你的模型可能会过度拟合,这就是为什么我们有修剪方法。我们应该有一个宽松的停止标准,然后使用修剪来删除导致过度拟合的分支。但是请注意,修剪是准确性和可推广性之间的折衷,因此您的训练分数可能会降低,但是训练分数和测试分数之间的差异也会降低。
我希望您对这些参数有更好的了解,并且在优化超参数时,它们可能会如何相互作用。但是如果有不清楚的地方,请在评论中告诉我,我会很乐意进一步解释。
参考
[1] 机器学习模型的超参数调优。
[3] Laura Elena Raileanu 和 Kilian Stoffel,“基尼指数和信息增益标准之间的理论比较”《数学和人工智能年鉴》41:77–93,2004 年。
[5]拉斐尔·戈梅斯·曼托瓦尼、托马什·霍瓦特、里卡多·切里、西尔维奥·巴尔邦·茹尼奥尔、华金·范舍伦、安德烈·卡洛斯·庞丝·德莱昂·费雷拉·德卡瓦略,“决策树超参数调整的实证研究”
arXiv:1812.02207
[6] 贪婪算法
【7】伪随机数发生器
[8] Lior Rokach,Oded Maimon,“第 9 章:决策树”
如何调整 tSNE 的超参数
生命科学的数理统计和机器学习
三个简单的规则,使美丽的 tSNE 图
这是生命科学的数理统计和机器学习专栏的第二篇文章。在第一篇中我们讨论了在生命科学中我们是否以及在哪里有适合机器/深度学习的大数据,并强调了单细胞是最有前景的大数据资源之一。t-分布式随机邻居嵌入(tSNE) 是一种机器学习非线性降维技术,对于单细胞数据分析来说是绝对核心的。然而,为 tSNE 选择超参数可能会让初学者感到困惑。
在这篇文章中,我将分享我对选择超参数的最佳值的建议,如困惑度、要保留的主成分数和运行 tSNE 的迭代次数。
如何有效地使用 tSNE
在教授单细胞 RNA 测序(scRNAseq)课程时,我不断收到关于tSNE 对超参数如困惑度的敏感性的问题。这些问题通常是由这篇精彩的文章激发的,这篇文章讲述了解读剧情的挑战。
A popular tutorial on developing intuition behind tSNE
尽管我非常尊重帖子的主要信息,但我认为 scRNAseq 社区不应该过于担心 困惑和其他 tSNE 超参数,因为:a)帖子中的许多例子来自抽象的数学拓扑,并不真正类似于 scRNAseq 数据,b)帖子专注于在现实世界 scRNAseq 分析中很少使用的极端 tSNE 超参数。
如果你做 scRNAseq 分析,你不会避免流行的 Rtsne 函数和 R 包,它是基于 Barnes-Hut C++实现的原始 tsne 算法。Rtsne 函数有三个主要的超参数:
- initial_dims(默认值为 50)假设 pca=TRUE
- 困惑(默认 30)
- max_iter(默认值为 1000)
在这里,我们将浏览这些超参数并解释它们的含义。显然,它们的默认值可能不适用于任意数据。在这里,我将解释如果您不确定从哪里开始,如何为您的特定数据集选择最佳 tSNE 超参数。
如何选择最佳的电脑数量?
scRNAseq 是高维数据(~20 000 维/基因),而 tSNE 难以处理高维数据。因此,通常您希望使用 PCA 等线性或 Autoencoder 等非线性方法(参见此处的)将初始维数减少到 30 - 50 个潜在变量( initial_dims ),并将其用作输入 tSNE 的新数据集。这里为了简单起见,我们将使用 PCA 进行预降维,因为 PCA 在分离信号和噪声方面非常出色。让我们使用来自癌症相关成纤维细胞(CAFs) 的 scRNAseq 数据,绘制由主成分(PCs)解释的方差百分比:
看起来很眼熟,不是吗?然而,我们应该保留多少个主成分(PC)来输入到 tSNE 中,即 initial_dims 应该取什么值:20、30、50 或者更多?这里我们有一个难题:1)如果我们选择太多的电脑,我们将包括“噪音”电脑从图的尾部,但是 2)如果我们选择太少的电脑,我们可能会失去信号从数据。为了做出这个决定,我们记得随机化是数据科学家的朋友,并将比较由 PCs 解释的观察方差和置换方差。为此,我们对表达式矩阵的元素进行混洗,执行 PCA,并检查置换矩阵的上图是什么样的:
第一个图中的红色曲线是 PCs 解释的置换方差的平均值,这可以被视为**“噪声区”。换句话说,观察方差(绿色曲线)与置换方差(红色曲线)的交点决定了我们的数据中有多少信息量**。此外,由于我们有一个置换方差的向量,因此可以计算每个 PC 的观察方差与置换方差的差异的 p 值。对于 caf 的情况,我们的结论是,应该为 tSNE 保留 30 个 PCs,其余的应该忽略,因为它们的值属于“噪声区”。
如何选择最佳困惑度?
困惑也许是 tSNE 最令人困惑的超参数。tSNE 的作者 Laurens van der Maaten ,在FAQ:5 到 50 之间的困惑范围的典型值。一个显而易见的问题立即浮现在我的脑海:“对于多少个数据点?如果我有 10 000 个单元格,我还应该使用介于 5 和 50 之间的困惑度吗?”。在 FAQ 的下一句中,Laurens van der Maaten 补充道:
粗略地说,可以说更大/更密集的数据集需要更大的困惑
这听起来很合理,但是为了捕获局部和全局数据结构,应该用什么函数形式来表示困惑与单元数量?为了回答这个问题,一年前我收集了当时公开可用的 43 个 scRNAseq 数据集,其中许多是从这里下载的。 Valentine Svensson 有另一个更全面和更新的 500 个 scRNAseq 数据集的列表。对于 43 个数据集的每一个,我做了几个 tSNE 图,复杂度从 3 到 N/3 不等(Rtsne 函数中默认的最大复杂度),N 是细胞的数量。对于 CAFs 数据集,看起来是这样的:
接下来,我仔细查看了这些图,以选择一系列对我来说聚类看起来最透明的困惑,并绘制了这个困惑范围的平均值与每个数据集的单元格数量的关系。正常(上图)和对数标度(下图)的曲线如下:
对对数标度的依赖性看起来是线性的,拟合线性模型 I 得到log(Perp)=-0.179+0.51 * log(N)。请注意 log(N)前面的系数 1/2 ,这暗示着困惑随着 Perp ~ N^(1/2) 而增长。后来我意识到这个幂律非常类似于在 K -最近邻(KNN)算法中选择最佳 K 的经验法则。事实上,在 KNN 机器学习中,人们普遍认为最优的k~n^(1/2。由于困惑背后的直觉是每个数据点能“感知”到多少个邻居,这就印证了上面得到的幂律。
现在让我们试着分析推导这个幂律。由于 tSNE 是基于最小化 Kullback-Leibler (KL)散度,所以也许可以从 KL 的最小值中找到最佳困惑?然而,如果我们将 KL 绘制为在其他参数固定的情况下的困惑度的函数,则它单调下降。
因此,就困惑度而言,KL 没有最小值,KL 总是更喜欢更高的困惑度,尽管我们知道太大的困惑度会导致一大堆没有任何聚类的点。因此,我们需要建立另一个分数 函数,它包括 KL 和一个额外的贡献,因为太大的困惑而惩罚 KL。假设 KL 表现为 1/困惑,一个总是有最小值的简单函数将是分数~ 1/困惑+困惑。然而,困惑通常是一个很大的数字,因此得分函数将由第二项支配。使两个贡献处于相同数量级的一个简单技巧是将第二项归一化单元数 n,最后,为了找到分数的最小值,我们计算其关于困惑度的导数,并使其等于零。解这个方程导致困惑~ N^(1/2).
Simple scaling derivation of the power law Perplexity ~ N^(1/2)
尽管得出幂律的经验方法,《困惑~ N^(1/2 》,不能被认为是适当的研究,但它有助于发展关于困惑的概念及其与细胞数量的关系的直觉。另一方面,关于 tSNE 的许多事情都是基于纯粹的直觉和经验法则,因为与 UMAP 相比,tSNE 没有坚实的数学背景。因此,如果你不确定对你的特定数据集使用什么样的困惑,试试 N^(1/2 ),你就不会太离谱了。
如何选择最优迭代次数?
当谈到 tSNE 收敛所需的迭代次数时,最简单的建议可以是迭代次数越多越好。然而,实际上这对于大数据集是不可行的,因为可能需要等待几天才能达到例如 10 000 次迭代。相比之下,如果使用的迭代次数太少,聚类可能不可见,通常会在 tSNE 图的中心发现大量数据点。这种情况下该怎么办?如果你仔细观察文献中可用的 tSNE 图,你会注意到数据点之间的最大距离约为 100。这个简单的经验法则表明算法达到了收敛,进一步增加迭代次数只会略微改变图形。对于 CAFs 数据集,我们可以观察到规模如何在训练开始时仅跨越几个单位,并在大量迭代(如 max_iter = 1000)时增长到约 60 个单位,这也导致更明显的聚类。
Changes in tSNE plot when increasing the number of iterations
摘要
在这篇文章中,我们了解到,尽管 tSNE 可能对其超参数很敏感,但有一些简单的规则可以为 scRNAseq 数据获得好看的 tSNE 图。通过表达式矩阵的随机化可以找到输入 tSNE 的最佳 PC 数量。根据简单的幂定律困惑~ N^(1/2) 可以从单元的数量计算出最佳困惑。最后,最佳迭代次数应该提供 ~100 个单位的数据点之间的最大距离。
在下面的评论中,让我知道生命科学中的哪些分析对你来说特别神秘,我会在这个专栏中尝试解决它们。在媒体关注我,在 Twitter @ NikolayOskolkov】关注我,在 Linkedin 关注我。我打算写下一篇关于做集群而不指定集群数量的帖子,敬请关注。
如何将黑暗的湖泊变成黄金
在过去的几年里,许多公司已经“人工智能清洗”了他们的品牌,以加入人工智能的潮流。人工智能驱动、人工智能内部、人工智能驱动这些术语似乎已经被默认添加到每一个软件和服务产品中。问题是,这些公司是通过人工智能战略赚钱(做“认知”),还是像大数据收集和存储投资那样赔钱。
在这篇博客中,我将总结我从上周在圣克拉拉举行的 AI &北美大数据博览会 2019 活动中获得的信息。我将介绍人工智能创造的潜在价值,以及为 ML 模型的创建减少著名的 80%数据准备的机会。显然,这是当前全行业的话题。
乍一看,人工智能&大数据博览会北美 2019 是一个相当不寻常的设置,人工智能/大数据、区块链、5G 和安全共同位于一个大型博览会中,有一个展厅和平行的会议轨道。自然,我对人工智能/大数据感兴趣,希望了解趋势在哪里,行业在哪里,以及围绕这一学科正在进行的一些研究。有趣的是,在查看议程后,我很快发现了许多跨学科的内容;5G 分析、Calibra 采用因素、用于安全测试自动化的人工智能等等。
我花了两天时间吸收、开会、讨论和整合。以下是最让我产生共鸣的。
有一个共识,数据战略的圣杯涉及促进业务的战略、战术和运营问题的生成,这些问题到分析的翻译是通过文本、或语音、或任何对首先提出问题的人来说更容易接近的东西来提供的。听起来很简单,对吧?没那么快。
迷失在翻译中:
- Gartner 预测“到 2020 年,50%的组织将缺乏足够的人工智能和数据读写技能来实现商业价值。”以及“人工智能实施增加 270%”、“250,000-预计到 2024 年美国将出现 DS 短缺”、“90 天以上才能完成任务”和“全球 DSs 供应紧缩”。
看起来数字不匹配。我们打算利用人工智能,但没有足够的人力资源来这样做。当供应减少时,价格就会上涨,这使得数据科学(DS)的工资飙升。由于高成本、短缺和无法有效利用他们的 DS 人员,许多项目在翻译中失败或丢失。
2)为什么无法利用这一资源?我们都知道,业务人员对盈利能力、可持续性、品牌、客户、合作伙伴关系和合规性感兴趣,而 DS 团队则关注 NLP、CV、OCR 和 NN。在这两者之间,有确保可伸缩性、安全性、可靠性、性能和容量的 RnD 团队。因此,在业务人员和 DS 人员之间有一条沟通的护城河。他们只是说不同的语言。
3)结果,由于 a)缺乏信任和对业务逻辑的理解,以及 b)训练数据中的固有偏见,以及 c)要求过程更加清晰的立法(在某种意义上是一个黑箱),新的人工智能解决方案和应用被创建和放弃。
数据谱系
要实现数据驱动,我们不仅要提出正确的业务问题,还必须构建坚实的数据基础,使我们能够使用数据回答这些问题。
可能的解决方案是驻留在单个技术堆栈上的数据沿袭。挑战:如何让每个人都可以访问数据谱系?DBA 需要看到与 VP 不同的东西。这里的度量标准是沿袭调查的速度,以及基于沿袭所提供的信任的决策速度。俗话说,真理没有单一的来源,只有单一版本的真理。换句话说,让每个人都可以使用数据谱系将克服“确认偏差”,并用支持它的数据来辅助论证。
数据引力的第 22 条军规:
数据量呈指数级增长。例如,一辆自动驾驶汽车每天产生 4TB 的数据,相当于 3000 个人产生的数据。将数据移动到 BI/Analytics 中会产生成本限制。另一方面,由于数据重力,拥有相同的存储和分析提供商将使客户陷入困境(Google/Looker)。这导致了过多的工具和解决方案,这些工具和解决方案经常不能相互集成,使得寻找答案或理解其来源变得更加困难。
一些供应商倾向于在边缘(GPU、FPGAs、ASICs)执行特征提取,并集中运行逻辑计算。
最终,除了吞吐量等物理限制之外,每个人都应该计算维护的 OPEX、资本支出和总拥有成本。这是一个权衡的游戏。
会话/自然语言处理
高达 23%的企业用户是数据盲。除非消费问题得到解决,否则拥有数据收集、存储、沿袭和分析不会帮助他们做出决策。关于自然语言查询和对话式人工智能作为人工智能应用程序的接口,可以桥接数据(il)读写问题,有过多次讨论。
一位来自优步的研究人员(他以前从事过 Alexa 开发)提出了在开发这些界面时需要解决的几个重点领域:
自然语言理解很难实现,因为它不能用数学来表示
开放式问题会导致不确定的答案,即实际观点
领域系统对话系统仍处于研究阶段
由于对话流程的实施和答案的构建,一次处理多个句子是一个挑战
测试人工智能
根据 Forrester 的调查,在过去几年中,软件测试自动化在所有记录的测试中占 46%。我们可以用人工智能来改善这一点吗?
显然,37%的受访公司使用 ML 进行测试,主要用于预测性维护(不完全是测试,更像是操作)和增强人工测试人员的视觉测试。只有 26%的人声称测试过自主 AI 应用。在未来,预计会有 API 测试生成自动化、测试生命周期优化,以及最终的体验测试。
在没有 XAI(人工智能的可解释性/可解释性)的情况下,完全自主地将人类从循环中带走,人工智能应用的风险会增加。这使得企业公司更难甚至不可能扩展人工智能,特别是在医疗、金融和保险等高度监管的领域。
例如,固有的偏见可能会对有关人类生命的决定构成巨大威胁,就像美国 12 个法院使用的指南针推荐系统一样。
那么应该如何测试 AI 呢?我们可以使用 F1 得分指标来衡量准确性,Fair ML,AI fairness toolkit 和 openscale 都可以是一个好的开始。
XAI
谈到可解释性,Zynga 在一个标准化的管道中自动提取特征,适用于所有游戏,支持牵引力、采用率和终身客户价值的优化。将人为因素排除在流程之外可以成倍提高效率。如果你想知道工程特征的自动化是否减少了 XAI,答案肯定是肯定的。因此,这些游戏将能够进化和改进,变得更加令人上瘾,而我们却不知道是如何做到的。社交网络上有一集《黑镜》突然看起来不那么牵强了。
新的商业模式:
认知术语出现了很多——试图找出如何利用人工智能来增加收入或降低成本。
例如,众所周知的消费电子和家用电器公司 LG 推出了 LG ThinQ,这是一个“融合先进人工智能技术的产品和服务品牌”。这里的新奇之处在于“零 UX 或原理”。LG 不打算为其 ThinQ 产品开发任何界面,而是与 Alexa、谷歌助手和 Yandex 等其他本地助手集成,以与消费者沟通。LG 开源的 Auptimizer 是一款用于优化人工智能模型的工具,可以在内部或与 AWS 一起使用,并且是模型不可知的。这是进入汽车即服务市场的一步。
这出乎意料,尤其是当 DS 自助服务平台有了有趣的发展时。他们不仅加强了 ML-ops 解决方案(数据流等),还开创了专业服务实践业务,这仅支持以下主张,即通用工具在没有业务目标与 DS 问题之间的正确映射时,或者在使用混乱/稀疏/不适当的数据时经常失败。
埃森哲在 5G 分析方面提供了一个意想不到的角度(至少对我来说是意想不到的)。据称,价值将位于连接提供商之外,或下游,在分析应用程序、安全等方面…这将是 5G 电子竞技/游戏的实时分析,这将推动 5G 的采用,包括脑机接口。
将黑暗的湖水变成金色
说到商业模式,现有的大多数都包含了经济价值曲线收益递减的范式。意味着用同样的收益投入更多。想想软件产品。越来越多的资金被投入到没有额外相关收入的研发中,只是为了跟上竞争的步伐。
答案是数据。
如何确定数据的价值?
评估资产的框架是基于你为之付出的和因使用而被剥夺的。数据不一样。你用得越多,它就越有价值,而且零使用成本。
Schmarzo 经济数字资产估值定理是这样的:
“在以知识为基础的行业中,学习经济比规模经济更有力量。改进分析模型的预测效果会对以前使用这些分析模型的用例产生影响。”数据是一种永不枯竭、永不磨损的资产,可以以接近零的边际成本在无限的用例中使用。这就是为什么特斯拉是一种不断升值的资产,因为它收集数据,学习和改进。
总而言之,转化为技术定义的业务问题的自动化(如果你愿意,也可以说是自助式 BI 的发展)得到了单一数据基础的加强,这将优化人工智能的支出,而新的商业模式,例如 5G 分析将推动货币化。
你想改变游戏吗?换框架。将您的数据变成黄金。
如何把物理变成优化问题
思想和理论
如果你知道机器学习的基础,你就已经知道如何在没有意识到的情况下解决大量的物理问题。
这篇文章主要是关于一个叫做拉格朗日力学的工具,它可以让你解决物理问题,比如最优化问题。
在机器学习中,你最小化预测和标签之间的损失,以找到最佳预测器
在拉格朗日力学中,你可以最小化一个系统的总作用力来寻找它的运动
代表权问题
拉格朗日力学比传统的牛顿力学有一个巨大的优势,因为它的表示不变,这意味着你可以自由选择最简单的表示来工作。
作为一个例子,我们将讨论最简单的一种机器人,一个二维钟摆——你的每个肢体都是一个钟摆,而你的身体是由一堆钟摆组成的。
Image by Mark Saroufim
在这种情况下,我们感兴趣的是描述弦末端的质心运动,所以在每一时刻 t,我们需要找到 3 个变量
- p →质量的位置
- v →质量速度
- 质量的加速度
v 是 p 随时间的变化率
a 是 v 随时间的变化率
所以我们只需要预测一个变量 p。
p 是物体从开始时间 s 到结束时间的位置序列
但是我们如何准确地表示质心的位置呢?显而易见的首选是使用笛卡尔坐标 x,y。
Image by Mark Saroufim
但是现在我们面临一个两难的问题——我们应该把坐标放在球本身的中心,还是放在墙上,或者其他什么地方?有没有什么原则性的方法来决定哪个坐标更好?
我们可以用钟摆的另一种表示法:
Image by Mark Saroufim
我们可以完全描述钟摆所有可能的位置
- θ →天花板和绳子之间的角度
- l →绳子的长度
综合起来,你就得到极坐标。
极坐标和笛卡尔坐标是同构的(数学上是相同的),但是极坐标在这种情况下更有优势。
在系统的演化过程中,l 从未如此有效地改变,我们可以只用一个变量θ,而不是两个变量 x 和 y,来描述整个系统的运动。
配置空间
θ表示更好的一个主要原因是,如果我们试图从 t 时刻开始预测球在 t + 1 时刻的位置,只有 3 个可能的解
在笛卡尔坐标中,解在 x,y 平面的某处,但是从时间 t 到 t + 1 有无限多可能的方向。
Image by Mark Saroufim
但是在极地环境中,解决方案只能有两个方向。
Image by Mark Saroufim
圆圈是摆问题所有可实现解决方案的集合中的配置空间,粒子通过该空间的特定路径描述了其实际运动,称为配置路径。
以这种方式研究系统的“形状”是被称为拓扑学的更大领域的一部分。拓扑学在研究物理系统的运动时非常有用,所以这里先介绍一下。
让我们来看一个更复杂的系统,一个双摆——想象第一个球是你的肘部,你可以看到它是如何代表更有趣的东西,也就是你的手臂。
Image by Mark Saroufim
你可以从两个角度来描述这个系统
如果固定第一个角度,那么第二个角度的配置空间又是一个圆,因此两个角度的新空间看起来像。
Image by Mark Saroufim
由于在较大的圆上面有无限多的小圆,我们最终得到的形状就是拓扑学中著名的圆环。
Image by Mark Saroufim
这个三维物体上的每一点都代表了双摆位置的一个可能的解决方案。我们本质上把这个系统的解描述为一个空间。
然后,一个示例摆的实际运动由该环面上的路径来描述。
Image by Mark Saroufim
如果你用牛顿力学工作,需要改变你的表示,看看什么是最好的,你需要重新推导你所有的公式,当你进入双摆领域时,涉及到一些棘手的三角学。
另一方面,拉格朗日 L 与表象无关,这意味着。
现在让我们定义什么是拉格朗日函数,看看它是如何工作的。
拉格朗日算符
现在我们知道,我们可以用路径来描述一个系统的运动,但是一个系统在它的构型空间中,实际上会走哪条路径呢?
大自然是懒惰的
所有物理过程都选择最小化总动作的路径。
一个著名的例子是折射,光在这里弯曲,因为它这样做更快。
Image by Mark Saroufim
系统 L 的拉格朗日量可以理解为它的“活泼性”。它的正式定义是
其中 T 是动能,V 是势能。
动能 T 总是不变的
势能取决于被描述的系统的类型,但是对我们来说,我们主要看重力势能
在哪里
m →物体的质量
g →重力常数
h →离地高度
更著名的能量守恒定律是势能和动能之和,它在剔除糟糕的物理理论方面非常可靠。
能量守恒定律告诉我们的是,没有新的能量可以创造,也没有能量可以损失。相反,我们有一个权衡,如果 T 增加,V 减少,如果 T 减少,V 增加。
Image by Mark Saroufim
系统产生的总作用记为 S,可以通过将构型空间中每个位置的所有拉格朗日量相加来计算。
欧拉-拉格朗日方程
那么现在我们可以推导出任何系统的拉格朗日 L,那么我们如何得到最小的 S 和产生它的路径呢?
从拉格朗日方程到解决方案的转换是通过欧拉-拉格朗日方程完成的,该方程将找到最小作用的路径。
欧拉-拉格朗日方程是
这个公式看起来比实际更复杂,通过几个例子可以更好地理解。
落球
我举的两个例子都深受这个系列的启发
假设我们有一个质量为 m 的球落到地上
Image by Mark Saroufim
动能 T 只是 y 的函数,因为没有侧向运动
势能 V 是
所以拉格朗日量是
欧拉-拉格朗日方程只是 y 的函数,所以我们可以简化它
插入 L
这简化为
所以我们最终从零开始推导牛顿定律🤯
移动小车摆锤
最后一个例子是向你们展示拉格朗日力学是如何工作的,但这不是拉格朗日力学发光的例子。
当系统复杂,有许多变量,用牛顿力学很难建模时,拉格朗日力学就大放异彩。
所以我们要想象一下,我们有一辆质量为 M 的移动小车,有一个质量为 M 的摆,一想到我需要在这里建模的不同力的数量,我就头疼。
Image by Mark Saroufim
谢天谢地,拉格朗日使得求解这个系统容易得多,因为我们可以独立地对每个对象求和。
我们可以用 2 个变量来模拟球和车的位置,每个变量总共有 4 个变量,或者我们可以使用一个技巧来改变坐标系,使我们的生活更容易。
我们做了以下两个替换
有了这个变量的变化,我们就可以导出拉格朗日 l。
记住,自然不在乎我们如何表现它
动能很容易。小车只能在 x 方向移动,而摆锤可以在 x 和 y 方向移动。
势能
所以总拉格朗日量是
一旦有了 L,你就可以应用欧拉-拉格朗日方程,来看看这个系统是如何运行的。
对比一下牛顿力学的方法
- 在每一个物体和每一个其他物体之间创建一个力图,以创建一组方程——可能是指数级的
- 将这些方程代入常微分方程求解器,因为物理学中的大多数导数都没有封闭形式的解——祈祷吧
牛顿力学和拉格朗日力学的区别就是命令式和声明式编程的区别。像拉格朗日力学这样有效的声明性范例总是更受欢迎,因为 SQL 比 UNIX 脚本更受欢迎。
建模约束
拉格朗日力学的最后一个优点是,我想简单地讲一下,给系统添加约束是很容易的。
约束是这样的函数
f 可以是对最大速度的约束,也可以是对关节可以弯曲多远的约束,或者是对两个对象的碰撞应该有多柔和的约束。
您可以有任意多的约束
你所需要做的,不是把 L 代入欧拉-拉格朗日方程,而是代入,λ是权重,代表每个约束的重要性。这个技巧被称为“拉格朗日乘子”,广泛用于凸优化。
密码
尽管拉格朗日力学是一个强大的想法,让你大大简化实现物理引擎,据我所知,它还不是一个主流想法。如果你知道任何使用它的物理引擎,请让我知道,我会在以后的博客文章中描述它在真实的物理引擎中是如何工作的。
我第一次看到拉格朗日力学的完整实现是在那本神奇的书——经典力学的结构与解释。这里的实现是用 LISP 实现的,LISP 是一种很好的学习语言,但以我的经验来看,这是一种很难在大型项目中使用的语言。
因此,我建议看一看 https://github.com/MasonProtter/Symbolics.jl项目,它提供了一个受 SICM 实现启发很大的 Julia 实现。
自述文件特别谈到了谐振子,这只是一个附加在弹簧上的重物的花哨术语。
Image by Mark Saroufim
https://github.com/MasonProtter/Symbolics.jl
后续步骤
哈密顿力学
拉格朗日力学让我们很容易计算出一个系统将要走的路径,但是它并没有给我们太多的洞察力,去了解构型空间中的点的速度。所以只有拉格朗日力学,我们不能真正描绘一个系统是如何完全进化的。
哈密顿力学是解决物理问题的第三种方法,它不是在组态空间中工作,而是在相空间中工作。
这本身是一个很大的话题,对描述动力系统非常有用,在非线性动力学和混沌中被详细使用
我正计划再写一篇关于这个话题的博文,所以我会放一些图片,激发你想了解更多的想法。
phase space of simple pendulum — CC BY-SA 4.0 Krishnavedala https://en.wikipedia.org/wiki/Phase_portrait#/media/File:Pendulum_phase_portrait.svg
如果你喜欢这篇文章,我强烈推荐你看看这本由里基·罗瑟写的关于域名着色的可观察笔记本
可微物理学
一个新兴的研究领域是可微物理学。伟大论文的一个例子是这里的。
任何种类的物理预测都涉及到编写和求解许多微分方程,所以这个想法是你用一种可微分的语言编写一个物理引擎,比如 Pytorch 或 Flux.jl,然后在线性时间内计算导数。
这种方法的主要好处是,你只需要描述你的系统需要如何发展(前向传递),并且你可以免费得到衍生产品(后向传递)。
就个人而言,我发现这是当今机器学习中最令人兴奋的研究领域。
我将在以后的博客中更多地谈论自动微分,所以这个想法很快就会变得清晰。
深入研究数学和物理
许多在物理学中有重大应用的数学技术正在走向机器学习和机器人技术。因此,我推荐一些参考资料来开始学习这种超越线性代数和基本微积分的新数学。我推荐这个列表中的很多书→ 我喜爱的技术书籍。
特别是,在未来的博客文章中,我想更多地谈论配置空间的拓扑结构,并将向您展示如何应用这些想法来简单地描述三维机器人的运动。
如何理解一家使用人工智能的公司
这篇文章是关于使用人工智能为高管团队产生洞察力的。
合规性不是一个性感的话题,所以这里有一个噩梦般的场景:你是一家财富 500 强公司的首席财务官,许多内部报告定期送到你的办公桌上。假设你的年度内部审计在一月份进行,一份重要的报告在二月份放在你的办公桌上。如果你的办公室在下一次年度审计之前没有处理好报告中的关键信息,那么你的工作可能会有危险。这里的困难在于,声誉风险、数据泄露、隐私侵犯甚至规划错误等非财务风险都可能导致未来的损失。这些风险很难被发现,因为它们是以文本而不是数字的形式到达你的办公桌的。通常情况下,长篇报告太多,关键的见解被忽略了。除非危机降临,否则它们不会出现在账本上,不管是罚款、诉讼还是失去客户账户。
在董事会上,很难解释为什么你把报告放在办公桌上(或收件箱里),却从未提出这个问题。在小公司里,这只是一个问题。没有足够的报告来激励一个基于人工智能的解决方案。只有当你面对潮水般的报告时,高管们才突然无法有效地处理大量和各种各样的风险。这些报告通常在文档管理系统(DMS)中整理了几十年,但没有到达一些分析工具来生成见解,也没有得到人类的评估。
此外,详细阅读每一份报告仍然会错过大局。您无法定期查看业务部门的非财务绩效,这导致最佳情况下只能看到人为生成的年度快照,或者根本看不到任何图片,而不是在注重细节的层面上对公司情况的实时视图,无论您在飞行中编造了什么关键字。
一年多来,我们的团队一直在开发和完善一个名为 AuditMap.ai 的审计人工智能,我在过去的文章中描述了这个工具的动机(这里和这里)。当我写这篇文章时,当你搜索内部审计人工智能时,我们关于 AuditMap.ai 的文章仍然在谷歌上排名第一。
我今天想做的这篇文章是向你展示结果,而不是关注人工智能是如何工作的。
主要想法是让人工智能在所有内部审计报告的大集合中找到关键语句,并在仪表板、列表中向高管展示底层信息,并作为行动项目。这种可配置的解决方案评估个人陈述、并将信息提炼为可操作的见解。
Example of the tool in action, showing risk and controls per year using the PEFA framework and an off-the-shelf audit universe.
请记住,内部审计的工作是发现不好的东西,并提供可行的见解。让我们一起来看看人工智能引擎在处理了一些大规模公开可用的文档数据集后,在各个业务领域识别出的一些关键风险陈述。
以下陈述摘自内部报告数据集,并被标记为业务运营各个领域的风险:
管理:
- 当前的指南不要求信息系统部项目管理系统制定正式的项目风险评估。
- 没有基于风险的计划的组织不知道这是预期的。
- 限制。无法具体确定专门用于治理职能的资源。
- 鉴于分支机构没有一致考虑风险来源,也没有进行可靠的控制评估,报告的完整性可能仅限于形式上的工作。
财务:
- 我们在监测中观察到的弱点使[实体]面临这样的风险,即它提供资金的项目可能不符合商定的条件,而且[实体]不会及早意识到不符合情况,从而减轻潜在的环境或社会影响。
- 因此,存在一种风险,即行使病人差旅支出启动权限的员工可能没有被正式授予这些权限。
- 分析工作仅限于这些国家是现有证据中的一个严重缺陷。
- 此外,我们注意到支持各种风险评估的文件水平不一致。
隐私:
- 对于保密和匿名之间的区别似乎没有明确的理解。
- 调查结果。由于缺乏关于隐私的国家指令,导致了不同地区指令的发展,这些指令并不一定满足所有关于保护个人信息的要求。
- 受访的分支机构联系人指出,他们没有适当的政策或流程来识别分支机构内需要进行隐私影响评估的所有活动。
- 同样,该策略本身不符合财政委员会隐私政策中规定的实践管理要求。
数据:
- 不完善的分离流程会导致对信息的不当访问,从而损害信息的机密性和完整性。
- 然而,需要进行改进,以确保所有要求的文件都保存在中央储存库中,并在合同审批过程中有审计跟踪,以展示最佳价值、竞争性、公平性和透明度。
- 然而,当评估小组要求提供进一步的细节以围绕绩效展开讨论时,所提供的数据(在[小组]总部进行广泛的收集和分析之后)与最初观察到的数据不同。
- 此外,没有定期测试系统数据备份的准确性和完整性,使该部面临没有其系统数据最后一份已知完好副本的完整记录的风险。
正如我们从上述报表中看到的,有许多非财务报告报表是危险信号,表明潜在的未来监管或财务损失需要立即采取纠正和预防措施。显然,AI 可以读取和标记关键陈述,并且它可以在风险管理框架和程序分离的上下文中(例如, PEFA 和 COSO )以及在公司的上下文中(例如,特定的审计领域)这样做。然而,我们如何为管理层提取关键的洞察力呢?我们如何从已确定的问题中退一步,总结全局?
让我和你们分享 3 种方法:仪表板、上下文窗口和风险控制矩阵。这些视图获得了客户端拉取和特性请求。
1)仪表板
AuditMap 充满了仪表板,用于从数据中提取高级别见解。我将在这里展示 4 个仪表板,让您了解如何获得洞察力,并了解贵公司的整体情况。
要查看的第一个视图是 ETL 作业摘要。简单地说,这个视图告诉你数据库中有多少东西,以及有多少东西被 AI 标记为相关的。在我们最新的版本中,我们跟踪风险、控制、发现、建议和观察。
This dashboard component shows how many sentences, entities (e.g., “Kitchen Sink”), risk statements, and control statements are in the database for a given project.
另一个要考虑的仪表板是审计宇宙树。请将此视为组织内审计员可以审计的所有空间的列表。每个公司的做法都有所不同,因为这个树适合公司结构和他们直接业务伙伴的某些部分。
audit universe 树让您了解公司每个部分的报告中有多少数据,以及 AI 在这些内部报告中标记了多少信息。
A dashboard for exploring coverage gaps, areas where data is missing, and trends in mentions of various entities.
接下来,我们有一个高级仪表板(见上图),用于识别主题中的覆盖差距和趋势。左上方的块让高管们发现在他们的审计宇宙树中哪里有覆盖缺口以及有多长时间了。从 2016 年开始,回溯到过去,AuditMap 发现了一个点,在这个点上,没有一个文件被绑定到审核宇宙树的这个分支。
在真实的应用程序中,这可能意味着两种情况之一。要么:
(1)每个人都知道在这个业务分支上执行的工作是以 4 年周期完成的, 或
(2)这里的工作被搁置了年,最终在 2016 年被砍掉。这种潜在的 3 年信息封锁在项目规划阶段使用 AuditMap 进行标记。
在同样出现的令人恐惧的空白中,上图的右上部分详细描述了审计领域中没有相关文档工作的领域。右上角标记了 3 个区域,其中未找到报告。除了最近添加到审计领域的内容之外,不言而喻,当这个框列出业务线时,需要提出问题。当发现报告但没有发现风险或控制时,可以部署相同类型的小部件来显示。这种情况下,该职能部门每年都会收到报告,但这些报告只是钉在白纸上的笑脸,因此不会暴露风险或控制措施以供管理层审查。
这个特定仪表板的底部组件标记为“实体趋势”,它跟踪热门提及在一段时间内的移动。这个小部件告诉您随着时间的推移,哪些内容在报告中被提到得最多,这有助于在规划过程中产生一些高层次的想法,从而在面向细节的下钻中深入了解特定的风险。
向下钻取发生在浏览页面中,这些页面的仪表板向您显示特定上下文(如控制活动)中特定计划(如分销和物流>计划)的非常狭窄的视图。
This dashboard is used to understand the high-level situation over time for the detail-oriented drill-down into specific Enterprise Risk Management (ERM) aspects within a specific business unit.
在上面的仪表板中,您可以看到一个高度定制的企业职能部门内的风险和控制视图。该工具可以为企业的任何部分、任何 ERM 方面做到这一点,还可以使用小部件中的“搜索风险”和“搜索控制”框任意过滤。因此,你可以一次深入到多个维度,形成一个关于组织中正在发生什么的论文。
2)上下文窗口
对于从文档中提取的每一条语句,AuditMap 使您(用户)能够:
- 在两个层次上感受标记数据的上下文:段落(通过下图中围绕着粗体句子的上下文文本)和文件级(使用工具的内置文档摘要器)。
- 最重要的是,团队 AuditMap 整合了我们的引擎透明理念,让人们看到甚至纠正人工智能的预测,以纠正错误或简单地推翻人工智能的意见。
- 有趣的是,找到任何感兴趣的东西并不意味着乐趣就此停止。这些标记的语句可以保存到可导出的列表中,然后生成风险控制矩阵。
3)风险控制矩阵
谈到风险控制矩阵(RCM)设计,审计经理比最高管理层更熟悉。
RCM 是在审计程序中确认适当覆盖范围的一个关键工具,因此探索可以直接进入审计计划。从另一个角度来看,通过快速建立陈述之间的关系,您可以使用它来建立一个关于公司某个职能或风险领域正在发生什么的案例。
风险控制矩阵本质上是给定审计范围内所有控制措施的列表,以及这些控制措施在公司运营中降低风险的直观关系。这是另一个视图,你可以用它来建立一个关于公司的某个职能或风险领域正在发生什么的案例。风险和控制语句可以从 explore 选项卡的视图中提取,并以如下所示的漂亮的矩阵格式设置。
An example risk-control matrix in AuditMap.ai
该矩阵非常紧凑,因为典型的 RCM 实际上可以变得非常大。这些通常在 excel 中编译,我们确实想到了这一点,并构建了一个 excel 导出工具。
带回家的信息:用人工智能理解企业
人工智能可以用来以真正自动化和复杂的方式理解公司的内部报告。可以在较高的级别查看数据,并对数据进行切片和切块,以获得不同时间和特定上下文中的数据视图。用人工智能处理数据让你知道数据中的差距在哪里,问题(风险)或努力(控制)在哪里呈上升趋势。
**想要试玩吗?**这里有一些关于如何联系我们团队讨论试点项目的信息。
发现你的审计图:
马修·勒梅matt @ audit map . ai
T:+1–819–923–6288
我们也很高兴地宣布 AuditMap.ai 正式从 Lemay.ai 中分离出来成为自己的公司,我们计划在 2019 年筹集资金以提高我们的销售额。这是一个非常激动人心的时刻!
如果你喜欢这篇文章,那么看看我过去最常读的一些文章,比如“如何给人工智能项目定价”和“如何聘请人工智能顾问”
下次见!
——丹尼尔
LEMAY . AI
1(855)LEMAY-AI
丹尼尔@lemay.ai
如何理解 Numpy 文档
当我们开始学习数据科学、机器学习、深度学习或任何将使用 Python 作为编程语言的激动人心的领域时,很可能我们所有人都会使用 numpy 。在这篇文章中,我将根据我使用 numpy 的经验,编写 numpy 基础知识以及如何正确阅读文档。在阅读我的帖子之前,如果你知道编程语言和 python 的基础知识是很好的。我将使用 python 3.6 作为例子。
什么是 Numpy
你可能想知道为什么所有的机器学习教程都将使用 numpy ,为什么其他库不用?在我们进入 numpy 之前,请先让我说一下什么是 Python。
Python 是一种编程语言,我们可以神奇地导入用 C++编写的库。C++是一种非常快速的语言,代码将被直接编译成机器代码,因此 C++中的库可以比纯 python 编写的库执行得更快。
Numpy 很快!它是由互联网上许多伟大的程序员维护的。
Numpy 是一个用 C++编写的开源库,它是用 Python 实现科学计算的基础包。安装非常简单,如下所示:
pip install numpy
它包含许多工具和算法,用于大多数机器学习任务,例如
- 强大的 N 维数组对象
- 复杂的(广播)功能
- 有用的线性代数、傅立叶变换和随机数功能
numpy 中的常用技术术语
形状
np.random.rand(d0,d1,…,dn)-给定形状中的随机值。
np.full(shape,fill_value,dtype=None,order=‘C’) —返回给定形状和类型的新数组,用 fill_value 填充。
每当描述中提到“形状”,它就意味着数组的大小,或者维度的大小。如果 numpy 数组的“shape”是[4,3,2],这意味着它是一个 3d 数组,因为形状本身有 3 个值 4,3 和 2。让我们看看下面的图片。
An array with shape of [4, 3, 2]. 4 2d array with [3,2]. For each 2d array, it has 3 rows and 2 columns.
对于形状为 4d 的数组,可以认为该数组包含了**多个 3d 数组。**然后你就可以想象使用 3d 数组的数据如上图。
数量
当你在描述中看到“标量”时,它只是一个单一的值。比如 x = 1,y = 3.0。所有这些都被认为是“标量”。
数据类型
dtype 是数据类型,其中常见的数据类型有图像的 uint8 (无符号 8 位整数,0–255),标量的 int32 (有符号 32 位整数,-对 1),标量的 float32 (有符号 32 位浮点)。大多数操作将使用 float32,因为机器学习数据中有很多小数。
可以读作**{有符号/无符号} _ { int/float } _ {位数,8,16,32,…}** 。
数组 _like
array_like 通常表示 numpy 数组或 list ,可以解释为 array。在库中,它将有助于转换为 numpy 数组。
恩达雷
输入必须是 numpy 数组,不能是列表,
强大的 N 维数组对象
在机器学习中,我们将永远与**【数据】**打交道。通俗地说,数据就是一个 excel 文件,存储着关于某个事物的信息。(例如公司的销售记录)
Illustration of a simple sales record
上面的例子是一个非常简单的销售记录,它有日期、项目名称和价格。
当我们想要将这个文件加载到 python 中时,我们很可能会使用 numpy 或 pandas (另一个基于 numpy 的库)来加载文件。加载后会变成数组形状为(3,3)的 numpy 数组,意思是 3 行数据,3 列信息。
为了更好地理解什么是 numpy 数组,或 N-d 数组,我们可以想象 1-d 数组是一个向量或一个项目列表,2-d 数组是一个矩阵,3-d 数组可以是矩阵列表。你可以参考上面的图片进行说明。
Numpy 会自动将数据转换成 N-d 数组,这样我们就可以执行更多像加法一样简单和像矩阵乘法一样复杂的运算。
复杂的(广播)功能
这可能解释起来有点复杂,当你在 numpy 中变得有经验时,你会理解什么是正确的广播。
广播更像是自动数组分配。在 Java 中,我们有 ArrayList,它会自动扩展数组的大小。广播更像是神奇地执行数组扩展来执行一些算术运算,比如加法。
Example on what is broadcasting
在上面的例子中,我们有一个形状为(2,3)的二维数组 x 和形状为(3)的一维数组 y 。x 是一个有 2 行的数组,每行有 3 列。第一行是[0,1,2],第二行是[3,4,5]。
执行一个简单的加法运算,就是通过语法将 x 和 y 相加: z = x + y ,将结果存储到 z. 然而,你可能会想,它们两个具有不同的数组大小,为什么它可以像 x + y 一样简单地实现。这就是“广播”的工作方式。可以理解为对于 x 的每一行,返回 x[i] + y. 那么输出 z 会自动生成,形状为 x (2,3) ,存储 x + y 的结果。
如何阅读 numpy 文档
好了,终于说到正题了!每当你在 numpy 函数的使用上遇到问题,你不知道如何使用它,你可以用“np.dot”这样的关键字进行谷歌搜索。
how to search numpy function
通常第一个会是你想要的,进入页面会像下面这样
numpy.dot documentation page
当我第一次阅读文档时,我发现它很难,因为我不知道从哪里看,文本似乎复杂而混乱。但是熟悉 numpy 之后,我只搜索我想知道的东西,也就是输入输出。
numpy.dot documentation page highlight
首先,这是你想要的功能吗?例如,您想要对两个二维数组(也称为矩阵)执行点积,其中 C = AB。现在你看文档的第一行,它描述的是你想要的吗?嗯,“两个数组的点积”似乎是正确的。
numpy.dot documentation page more description
对于初学者来说,这似乎是一篇很长的文章。有时我会跳过这一部分,因为我觉得它对我没有帮助😂。在你熟悉 numpy 之后,我建议你阅读一下描述,也许会帮助你进一步理解它是如何工作的。但是,我会一直关注参数和样本输入和输出。
numpy.dot documentation parameter
每当我们看到 array_like ,就意味着函数输入是一个 numpy 数组,从点积的意思来看,你应该知道输入是一维或者二维数组(虽然也可以接受 N-d (N > 2)。几乎大多数 numpy 操作都有 out 作为参数,这是为了内存引用,可能是为了内存高效的程序,但是,我建议我们总是这样调用函数: out = np.dot(a,b) 而不是 np.dot(a,b,out) 。它与一些编程语言概念有关,我总是使用第一种方式,即 out = np.dot(a,b) 。
大多数 numpy 操作都返回一个 numpy 数组。只有一些操作会返回其他内容,比如元组或索引。
numpy.dot documentation output
我总是看例子来找出如何使用这个函数,但是有时你可能会弄不清看哪个。
在这种情况下,您应该尝试运行该示例,或者将任何值放入该示例中,以测试该函数是否能输出您期望的结果。
TLDR;
- 阅读描述的前几行,它与你想要的匹配。
- 您可能会在文档页面中找到很多信息,只搜索参数。
- 看例子。
- 不断地试错。
让我知道你在阅读 numpy 文档时遇到了什么问题,这样我就可以继续撰写阅读 numpy 文档的好教程(或者任何常见的库文档,例如 pytorch)。
如何使用聚类技术生成合成数据
我们展示了如何使用高斯混合模型(GMM),一个强大的聚类算法,合成数据生成。
聚类和 k-均值
对于利用数据科学的商业或科学企业来说,聚类是机器学习管道的重要组成部分。顾名思义,它有助于识别数据块中密切相关(通过某种距离度量)的数据点的集合,否则很难理解。
k-means 算法在未标记的多维数据集中搜索预定数量的聚类。它使用最佳聚类的简单概念来实现这一点:
- *“聚类中心”*是属于该聚类的所有点的算术平均值。
- 每个点离自己的聚类中心比离其他聚类中心更近。
它通过从随机分配聚类中心开始,然后分阶段迭代来完成聚类,其中,在每个阶段,它为每个聚类中心分配特定的点,然后根据这些点的算术平均值来重新计算聚类中心的位置。这里有一个很好的视频演示了这个过程。
k 均值和高斯混合模型(GMM)的局限性
k-means 算法的一个关键优势是其简单性,这使得它成为快速处理大规模数据的流行选择。但是这种简单性也导致了一些关键的实际挑战。
特别是,k-means 的非概率特性及其采用简单的径向距离度量来分配集群成员资格,导致许多现实情况下性能不佳。
例如,想象以下数据点。在这里,它们由它们的标签来着色,但是在无监督的机器学习设置中,我们不会有类别标签。
如果我们运行一个简单的 k-means,我们很可能会得到下面的最终聚类排列,
两个中间的聚类看起来有重叠,即我们可能对重叠区域中点的聚类分配没有完全的信心。不幸的是, k-means 模型没有对聚类分配的概率或不确定性的内在度量。
k-means 从设计上来说是非概率的。
此外,对于 k-means,当数据分布的形状是圆形时,它工作得最好。这是因为 k-means 没有考虑长方形或椭圆形簇的内置方法。因此,举例来说,如果我们获取相同的数据,并通过向一个方向拉伸来转换它,则聚类分配会变得次优。
k-means 不够灵活,无法解释这种“拉长的数据,并试图**将数据强行拟合到四个圆形聚类中,**这些聚类并不代表数据点的真实形状。
k-means 在“非圆形”数据(即长方形或椭圆形聚类)上表现不佳
G 澳大利亚 M ixture M 模型(GMMs),可以看作是 k-means 背后思想的延伸。GMM 试图将给定数据建模为多个多维高斯概率分布的混合物。
它基于 期望最大化(E-M)算法 工作,并从本质上处理生成数据的概率性质。
在最简单的情况下,GMM 可以像 k-means 一样用于寻找聚类。然而,它对于非圆形数据斑点执行得完美无缺,因为它可以用参数(std。dev 和 mean)适合于拟合数据的特定形状。
在本文中可以找到对这些模型的全面总结,
在机器学习领域,我们可以区分两个主要领域:监督学习和非监督学习。主要的…
towardsdatascience.com](/gaussian-mixture-models-explained-6986aaf5a95)
作为生成模型的 GMM
GMM 最流行的分类是聚类算法。然而,从根本上说,它是一种用于 密度估计 的算法,属于 生成模型 家族。
这意味着,当 GMM 适合某些数据时,生成的模型不仅仅是一组固定聚类的描述,而是描述数据真实分布的生成概率模型。
GMM 是一种生成式建模技术,可以生成接近拟合数据分布的合成数据。
这里有一个关于生成模型的很好的介绍,
[## 生成模型与判别模型
我想以一个故事开始这篇文章。
medium.com](https://medium.com/@mlengineer/generative-and-discriminative-models-af5637a66a3)
使用 GMM 的合成数据生成
假设我们有一些数据点的月牙形聚类排列。这是一个流行的玩具例子,经常用来展示 k 均值的局限性。一种称为谱聚类的特殊聚类方法最适合这种类型的数据。
有多少个自然集群?
显然是两个。如果我们选择两个集群运行 GMM,我们将得到类似这样的结果。
印象不深,是吗?对于这种特殊形式的数据,它显示了与 k-means 相同的限制。
但是假设我们对聚类不感兴趣,但是基于给定的数据样本生成更多的合成数据。
为此,我们需要大量的高斯星团。看看当我们选择 4、8 和 16 个集群运行相同的 GMM 算法时会发生什么。
这些聚类似乎紧密地跟随数据的形状。GMM 的伟大之处在于我们有一种sample
方法。这意味着它已经学会了数据的分布,而不仅仅是对数据进行聚类,并且可以从分布中生成任意数量的样本。
GMM 的标准算法实现有一个生成数据的
sampling
方法。k-means 没有这样的方法。
看看当我在这些模型(4、8 和 16 集群模型)上调用predict
方法时会发生什么。
它能够生成新的数据,紧密跟随它所聚类的原始数据的形状!
很明显,4 簇模型不太擅长模拟原始数据,但是 16 簇模型非常接近原始数据,不是吗?
当然,这种能力并不局限于任何特定的形状或二维空间,而是通常扩展到多变量情况。下面是一个 4 簇数据集的例子。
警告和含义
就像任何生成技术一样,这容易受到过度拟合和泛化能力差的影响。您可以无限制地增加高斯分量的数量,但这将开始适应噪声,而不是代表真实的分布。
一般来说,必须对高斯分量、初始化、容差和迭代次数的选择进行仔细的实验。
增加高斯分量的数量,直到开始获得足够接近的原始数据集表示,但不再增加。遵守奥卡姆剃刀的原则,并尝试在足以满足您的应用的最小复杂度处停止。
这种技术的一个潜在应用是直接用于商业分析和市场细分案例。通常,市场调查产生的数据点数量有限。如果您的内部聚类算法或其他数据处理技术需要更多的数据点,该怎么办?这是一种接近模拟真实数据集分布并为进一步处理生成相似聚类的潜在方法。
业务分析可以使用这种合成数据生成技术从有限的真实数据样本中创建人工聚类。
关于这个的练习 Jupyter 笔记本可以在这里找到。
如果您有任何问题或想法要分享,请通过tirthajyoti【AT】Gmail . com联系作者。此外,您可以查看作者的 GitHub 资源库,了解 Python、R 和机器学习资源中其他有趣的代码片段。如果你像我一样对机器学习/数据科学充满热情,请随时在 LinkedIn 上添加我或在 Twitter 上关注我。
[## Tirthajyoti Sarkar - Sr .首席工程师-半导体、人工智能、机器学习- ON…
通过写作使数据科学/ML 概念易于理解:https://medium.com/@tirthajyoti 开源和有趣…
www.linkedin.com](https://www.linkedin.com/in/tirthajyoti-sarkar-2127aa7/)
如何将气流式 Dag 用于高效的数据科学工作流
Airflow 和 Luigi 对于数据工程来说很棒,但是对于数据科学来说并没有优化。 d6tflow 为数据科学带来了气流式的 Dag。
数据科学工作流是 Dag
数据科学工作流通常如下所示。
此工作流类似于数据工程工作流。它包括将参数化的任务链接在一起,这些任务在彼此之间传递多个输入和输出。参见为什么你的机器学习代码可能不好的 4 个原因为什么在函数之间传递数据或硬编码文件/数据库名称而没有明确定义任务依赖关系不是编写数据科学代码的好方法。
# bad data science code
def process_data(data, do_preprocess):
data = do_stuff(data, do_preprocess)
data.to_pickle('data.pkl')data = pd.read_csv('data.csv')
process_data(data, True)
df_train = pd.read_pickle(df_train)
model = sklearn.svm.SVC()
model.fit(df_train.iloc[:,:-1], df_train['y'])
R&D 与生产数据工作流
使用气流和 luigi 比编写用于管理数据工作流的功能代码前进了一大步。虽然数据工程和数据科学工作流相似,但它们的注意事项是相同的。这两个库都是为数据工程师在生产环境中使用而设计的,其重点是:
- 确保一切按时顺利进行
- 时间安排和协调
- 从故障中恢复
- 数据质量
相比之下,研发工作流程的重点是:
- 产生洞察力
- 原型速度
- 评估不同模型和参数的预测能力
- 可视化输出
因此,研发工作流程:
- 不太明确
- 涉及反复试验
- 当模型、参数和数据发生变化时,需要频繁重置任务和输出
- 接受数据工程师的输出
R&D 环境中的气流/luigi 问题
由于这两个库都针对数据工程生产环境进行了优化,因此数据科学研发环境的 UX 并不是很大:
- 用于读/写数据的湿代码
- 手动跟踪保存数据的文件名或数据库表名
- 当模型、参数和数据改变时,不方便重新设置任务
- 不方便跟踪不同参数设置的模型结果
在复杂的数据工作流中手动跟踪文件名…不可扩展。
# example of manually caching dataframes and keep track of files
cfg_fpath_cc_base = cfg_fpath_base + 'vendor/'
cfg_fpath_cc_raw = cfg_fpath_cc_base + 'df_cc_raw.pkl'
cfg_fpath_cc_raw_recent2 = cfg_fpath_cc_base + 'df_cc_raw_recent2.pkl'
cfg_fpath_cc_yoy = cfg_fpath_cc_base + 'df_cc_yoy.pkl'
cfg_fpath_cc_yoy_bbg = cfg_fpath_cc_base + 'df_cc_yoy_bbg.pkl'
cfg_fpath_cc_yoy_fds = cfg_fpath_cc_base + 'df_cc_yoy_fds.pkl'
cfg_fpath_cc_var_fds = cfg_fpath_cc_base + 'df_cc_var_fds.pkl'
cfg_fpath_cc_yoy_recent2 = cfg_fpath_cc_base + 'df_cc_yoy_recent2.pkl'
cfg_fpath_cc_actual = cfg_fpath_cc_base + 'df_cc_sales_actual.pkl'
cfg_fpath_cc_monthly = cfg_fpath_cc_base + 'df_cc_monthly.pkl'
cfg_fpath_cc_yoy_cs2 = 'data/processed/df_cc_yoy_cs2.pq' # consistent shopper data for new methodology from 2018
d6tflow 与 airflow/luigi 有何不同
d6tflow 针对数据科学研究和开发工作流进行了优化。以下是在数据科学中使用 d6tflow 的好处。
好处:任务有输入和输出数据
不再需要手动加载和保存数据,而是外包给图书馆。这可以更好地伸缩,并减少维护,因为输入/输出数据的位置可以改变,而不必重写代码。这也使得数据工程师更容易将数据交给数据科学家。
class TaskProcess(d6tflow.tasks.TaskPqPandas): # define output format def requires(self):
return TaskGetData() # define dependency def run(self):
data = self.input().load() # load input data
data = do_stuff(data) # process data
self.save(data) # save output data
好处:轻松使任务无效
实现了常见的失效场景。当您在试错过程中更改代码和数据时,这将提高原型开发速度。
# force execution including downstream tasks
d6tflow.run(TaskTrain(), force=TaskGetData())# reset single task
TaskGetData().invalidate()# reset all downstream tasks
d6tflow.invalidate_downstream(TaskGetData(), TaskTrain())# reset all upstream tasks
d6tflow.invalidate_upstream(TaskTrain())
优点:使用不同的参数轻松训练模型
更改参数后,您可以智能地重新运行工作流。参数从目标任务传递到相关的下游任务。因此,您不再需要手动跟踪要更新的任务,从而提高了原型开发速度并减少了错误。
d6tflow.preview(TaskTrain(do_preprocess=False))'''
└─--[TaskTrain-{'do_preprocess': 'False'} (PENDING)]
└─--[TaskPreprocess-{'do_preprocess': 'False'} (PENDING)]
└─--[TaskGetData-{} (COMPLETE)] => this doesn't change and doesn't need to rerun
'''
好处:轻松比较模型
用不同参数训练的不同模型可以容易地加载和比较。
df_train1 = TaskPreprocess().output().load()
model1 = TaskTrain().output().load()
print(sklearn.metrics.accuracy_score(df_train1['y'],model1.predict(df_train1.iloc[:,:-1])))df_train2 = TaskPreprocess(do_preprocess=False).output().load()
model2 = TaskTrain(do_preprocess=False).output().load()
print(sklearn.metrics.accuracy_score(df_train2['y'],model2.predict(df_train2.iloc[:,:-1])))
加速数据工程师向数据科学家的移交
要快速共享工作流输出文件,可以使用 d6tpipe 。参见共享工作流和输出。
import d6tflow.piped6tflow.pipe.init(api, 'pipe-name') # save flow output
pipe = d6tflow.pipes.get_pipe()
pipe.pull()class Task2(d6tflow.tasks.TaskPqPandas): def requires(self):
return Task1() # define dependency def run(self):
data = self.input().load() # load data from data engineer
或者,您可以使用 d6tflow premium 将输出保存在数据库中。
d6tflow2.db.init('postgresql+psycopg2://usr:pwd@localhost/db', 'schema_name')class Task1(d6tflow2.tasks.TaskSQLPandas): def run(self):
df = pd.DataFrame()
self.save(df)
最后,数据科学家可以继承数据工程师编写的任务来快速加载源数据。
import tasks_factors # import tasks written by data engineer
import utilsclass Task1(tasks_factors.Task1):
external = True # rely on data engineer to run def run(self):
data = self.input().load() # load data from data engineer
d6tflow 快速入门
这是一个完整的例子,展示了如何使用 d6tflow 进行 ML 工作流https://github.com/d6t/d6tflow#example-output
可扩展 ML 项目的模板
在https://github.com/d6t/d6tflow-template有一个用于真实项目的 d6t 流代码模板
- 多任务输入和输出
- 参数继承
- 模块化任务,运行和
如何使用气流而不头疼
Photo by Sebastian Herrmann on Unsplash
按计划处理和移动数据的数据管道和/或批处理作业为所有美国数据人员所熟知。事实上的标准工具来编排所有的是阿帕奇气流。它是一个以编程方式创作、调度和监控工作流的平台。工作流是表示为直接非循环图(DAG)的一系列任务。例如,将提取、转换、加载(ETL)作业视为一个工作流/DAG,其中 E、T 和 L 步骤是其任务。您可以使用 Python 在代码中配置工作流。这允许您在 Git 这样的源代码控制系统中对工作流进行版本控制,这非常方便。
总而言之,气流是一个很棒的工具,我喜欢它。但是,我最初用错了方法,可能其他人也是这样。这种误用会导致令人头疼的问题,尤其是在工作流部署方面。为什么?简而言之,我们将它用于在同一个气流实例上协调工作流和运行任务的 。在这篇文章中,我将告诉你为什么这是一个问题。当然,我还将向您展示如何轻松地解决这个问题。我希望这能减少你未来的阿司匹林摄入量,就像我一样:)
气流流向不好的方向
我以一个关于我自己和气流的小故事开始这篇文章。
创建工作流时,您需要实现和组合各种任务。在 Airflow 中,您使用运算符来实现任务。Airflow 提供了一组开箱即用的操作符,比如 BashOperator 和 PythonOperator 等等。显然,我在工作中大量使用了 PythonOperator,因为我是一名数据科学家和 Python 爱好者。这开始很好,但是过了一会儿,我想
“嗯,我如何将我的工作流部署到我们的生产实例中?我的包和其他依赖项是如何安装在那里的?”
一种方法是为每个工作流添加一个 requirements.txt 文件,该文件在部署时安装在所有 Airflow workers 上。我们试过了,但是我的任务和同事的任务需要不同的熊猫版本。由于这个包依赖问题,工作流不能在同一个 Python 实例上运行。不仅如此,我使用了需要 Python 3.7 的 Dataclasses 包,但是在生产实例上,我们只安装了 Python 3.6。这可不好。
所以我继续谷歌了一下,找到了另一个由 Airflow 提出的解决方案,名为 Packaged-DAGs。上面写着:“将所有 Dag 和外部依赖项打包成一个 zip 文件,然后部署它。”您可以点击此链接了解更多详情。对我来说,这听起来不是一个很好的解决方案。它也没有解决 Python 版本问题。
作为操作符提供的另一种可能性是将您的任务包装在一个 PythonVirtualEnvOperator 中。我不得不说,我没有试过,因为它仍然没有解决 Python 版本的问题。但是,我想如果你每次执行一个任务都要创建一个虚拟环境的话,可能会很慢。除此之外,文档中还提到了其他一些注意事项。
Damm,三次尝试仍然没有令人满意的解决方案来部署用 Python 编写的任务。
最后,我问自己如何使用 Python 之外的语言编写任务?那一步会不会变成语言不可知?甚至有人能执行一个不知道具体气流的任务吗?我如何在气流中部署和集成这样的任务?我是否必须编译它,并在每个 worker 上安装带有所有依赖项的结果,以便最终通过 BashOperator 调用它?这听起来像是一次痛苦的部署和开发经历。此外,这可能再次导致依赖性冲突。总之,这听起来不太令人满意。
但是我要用气流!
那么,我们能修好它吗?
Taken from https://knowyourmeme.com/photos/292809-obama-hope-posters
良好的气流方式
每当我听到“依赖冲突”、“版本问题”或“我想成为语言不可知者”之类的话,我马上会想到容器和 Docker 。幸运的是,Airflow 提供了一个开箱即用的docker operator(还有一个用于 Kubernetes )。这允许我们从气流中调用隔离的 docker 容器作为任务。
好快啊:)
但是现在,更详细一点。在下文中,我将向您展示从开发基于 Docker 的任务和 Dag 到部署它们的端到端过程。对于每一步,我都突出了各自解决的问题。
任务开发和部署
- 用你想要的任何语言和语言版本来开发和测试你的任务。这允许你在与气流细节和其他任务隔离的情况下测试和开发任务。它降低了新开发人员的门槛,因为他们可以选择自己最熟悉的语言。
- 将工件和所有依赖项打包到 Docker 映像中。这解决了依赖和版本冲突的问题。它大大有助于减轻你的头痛。
- 使用 DockerOperator 从容器中公开一个入口点来调用和参数化任务。这使你能够从气流中使用你的图像。
- 构建您的图像,标记它,并将其推送到一个中心 Docker 注册表。理想情况下,这是自动化的,并且是您的 CI/CD 渠道的一部分。气流将图像从注册表中拉到执行任务的机器上。这有助于部署任务。又是一个减少头痛的步骤。此外,它允许您拥有同一任务的多个版本。最后,拥有一个中央注册中心使您能够在整个组织中共享和重用任务。
DAG 开发和部署
- 使用 DockerOperator 作为唯一的操作符来构建 DAG。使用它来调用 Docker 注册表中的各种任务。对我来说,这使我的 DAG 定义变得小巧、清晰、易读。除了 DockerOperator 之外,我也不必学习任何特定的气流操作符。
- 将您的 DAG 放入版本控制系统。这样,部署您的 DAG 只是一个简单的推拉动作。同样,这应该是自动化的,并成为您的 CI/CD 渠道的一部分。
我希望这听起来合理,你会得到它提供的许多好处。你所要做的就是学习 Docker 如果你还不知道并且你已经准备好了。
现在,我们知道该做什么了。下一段,我们通过一个例子来看看是怎么做的是怎么做的。
例子
让我们快速浏览一个示例 DAG,其中我只使用了 DockerOperator。使用这个 DAG,我模拟了一个 ETL 作业。请注意,DAG 定义文件并没有显示它只是一个模拟的 ETL 作业。它可能是一个超级复杂的或者只是一个虚拟的。实际的复杂性从 DAG 定义中去除,并转移到各自的任务实现中。生成的 DAG 定义文件简洁易读。你可以在我的 Github 库中找到所有代码。您不仅可以在这里找到 DAG 定义,还可以了解如何使用 Docker 构建和运行相应的 Airflow 实例。您还可以找到模拟的 ETL 任务实现以及 Dockerfile 文件。但是现在,让我们具体点。
代码
首先,让我们导入必要的模块,并为 DAG 定义默认参数。
**from** datetime **import** datetime, timedelta
**from** airflow **import** DAG
**from** airflow.operators.docker_operator **import** DockerOperator
d_args = {
"start_date": datetime(2019, 11, 14),
"owner": "shawe",
"depends_on_past": False,
"retries": 1,
"retry_delay": timedelta(minutes=5),
}
这里没有什么特别的,但是您可以看到我只导入了 DAG,这是必需的,还有 DockerOperator。在这个阶段,我们不需要气流以外的东西。
在我们构建 DAG 之前,关于 DockerOperator 和您将看到的内容,还有一些话要说。我的所有任务都使用同一个 Docker 映像,名为 etl-dummy ,标记为 latest 。该映像提供了一个名为 etl 的 CLI。该 CLI 有 3 个子 CLI,分别是提取、转换和加载。子 CLI 有不同的参数。例如,要运行转换任务,您需要调用
etl --out-dir /some/path transform --upper
要从 DockerOperator 中调用 Docker 图像,只需将图像名称指定为 name:tag,并指定要调用的命令。请注意,我的图像存储在本地 Docker 注册表中。这样,我的 etl dag 定义看起来像
si = "@hourly"
**with** DAG("etl", default_args=d_args, schedule_interval=si) **as** dag:
**def** etl_operator(task_id: str, sub_cli_cmd: str):
out_dir = "/usr/local/share"
**cmd = f"'etl --out-dir {out_dir} {**sub_cli_cmd**}'"**
**return** DockerOperator(
command=cmd,
task_id=task_id,
image=f"**etl-dummy:latest**",
volumes=[f"/usr/local/share:{out_dir}"],
)
extract = etl_operator("e-step", **"extract --url http://etl.de"**)
transform = etl_operator("t-step", **"transform --lower"**)
load = etl_operator("l-step", **"load --db 9000://fake-db"**)
**# Combine the tasks to a DAG**
extract >> transform >> load
我只是添加了一个小的助手函数来创建 DockerOperators。对我来说,这看起来又好又干净。
最后的笔记和提示
如果您在一个可远程访问的 Docker 注册表中托管您的图像,您必须以registry-name/image-name:image-tag的形式传递图像名称。此外,您必须提供一个 docker_conn_id 来使气流能够访问注册表。这个 docker_conn_id 引用了一个由 Airflow 管理的秘密。
您可以添加的另一个功能是将图像名称和标签作为变量存储在 Airflow 中。如果你想更新你的 DAG,你所要做的就是用一个新的标签将另一个图像推送到你的注册表中,并改变 Airflow 中变量的值。
最后,我想重复一遍,你可以在我的 Github 资源库中找到包括 Docker 上的 Airflow 和示例 Docker 镜像在内的所有代码。
包裹
我希望这篇文章对你有用,如果你过去有过头痛,我希望它们将来会消失。感谢您关注这篇文章。一如既往,如有任何问题、意见或建议,请随时联系我。
如何在日常分析工作中使用因果推理——第 1 部分,共 2 部分
商业世界中的分析师和数据科学家充斥着大量的观察数据。这是在业务运营过程中产生的数据。这与的实验数据形成对比,在实验数据中,受试者被随机分配到不同的治疗组,结果被记录和分析(想想随机临床试验或 AB 测试)。
实验数据可能很昂贵,或者在某些情况下,不可能/不道德地收集(例如,将人们分为吸烟组和非吸烟组)。另一方面,观察数据非常便宜,因为它们是商业运作的副产品。
鉴于大量廉价的观测数据,“询问”这些数据是日常分析工作的主要内容也就不足为奇了。最常见的询问技巧之一是在重要的指标上比较各组“主题”——客户、员工、产品等等。
使用“50 美元以上订单免运费”优惠券的购物者比没有使用优惠券的购物者多花了 14%。
商店前面的产品比商店后面的产品多被购买 12%
从多个渠道购买的客户比从单一渠道购买的客户每年多花费 30%。
西部地区的销售代表比东部地区的销售代表的人均预订量高出 9%。
Source: http://bit.ly/2VtX2FV
比较非常有用,可以让我们深入了解系统(即业务、组织、客户群)实际上是如何工作的。
而这些见解反过来又建议我们可以做些什么——干预*——来改善我们关心的结果。*
从多个渠道购买的客户比从单一渠道购买的客户每年多花费 30%。
30%已经很多了!如果我们能吸引单一渠道的购物者下次从不同的渠道购买(也许是给他们一张只适用于那个新渠道的优惠券),也许他们第二年会多花 30%的钱?
商店前面的产品比商店后面的产品多被购买 12%。
哇!所以如果我们把销量弱的产品从店铺后面移到前面,也许他们的销量会增加 12%?
如果计算原始比较的数据是实验性的*(例如,如果一个随机的产品子集被分配到商店的前面,我们将它们的性能与后面的进行比较),这些干预可能会产生预期的效果。*
但是如果我们的数据是观察性的*——零售商出于商业原因选择了一些产品放在商店的前面;给定一组渠道,一些客户自己选择使用单个渠道,其他人使用多个渠道—您必须小心。*
为什么?
因为从观测数据计算出来的比较可能不真实。它们可能并不能反映你的业务是如何运作的,按照它们行事可能会给你带来麻烦。**
在因果推理领域中研究了如何从观察数据中回答‘干预性’问题的一般问题。有一些有用的文章(示例、示例)、书籍(因果推理、为什么的书)和课程(示例)教授关键概念,如因果关系与相关性、混杂、选择偏差、因果图、反向因果关系等。
虽然这种知识有趣且有价值,但还是有很多的。套用查理·芒格“承担大部分运费”——我们可以在周一早上例行应用来测试一个暗示性的比较是否真实,这里面有什么基本的想法吗?
是的。当一个比较误导你的时候, 混淆 往往就是这个原因(我们很快就会看到这样的例子)。
混杂 发生在什么时候
- 受试者根据非随机因素和自行选择分组或被分配分组
- 这些因素影响着被比较的对象。
这些因素被称为混杂因素。把混杂因素想象成 共因 共因既有受试者如何在群体中结束又有群体在利益衡量标准中的表现。
我们来看几个例子。
- 对比:经常冥想的人比不冥想的人患心脏病的几率低 X%。锻炼和饮食可能造成的混淆:锻炼和遵循更健康饮食的人= >更可能在冥想组和更不容易患心脏病(来源:改编自http://bit.ly/2TQjzus)
- 对比:单身人士比已婚人士在脸书上活跃的可能性高 X%。因年龄而产生的可能混杂因素:更年轻的人= >更有可能属于单一群体而更有可能活跃在脸书上(来源:改编自分类数据分析,第 2.1.8 章,第 43 页)。
- 对比:一家医院想要更换超声波设备,进行了一项测试,发现新设备比旧设备多花了 X%的时间。因专业水平而可能产生的混淆:新技术人员= >更有可能尝试新装置和可能需要更长时间在任何装置上做超声波检查(来源:改编自http://bit.ly/2V0yfsZ)。
学习混杂因素就像学习一个新单词。一旦你意识到他们的存在,你会发现他们无处不在。
对于混杂因素,我们能做些什么?
我们需要为他们控制。有大量关于如何做到这一点的文献(文章、文章、文章),许多领域的研究人员——例如生物统计学和流行病学——已经这样做了几十年。当你在报纸上读到一篇文章“X 与 Y 的高风险有关,在控制了年龄、性别、身体质量指数、血压和身体活动水平后”,混杂因素正在得到控制。
控制混杂因素的一种简单且广泛使用的方法是分层。
- 我们根据混杂值将受试者分组,并计算每个组的比较。
- 根据定义,在每个时段内,混杂因素的值不会改变。 因此,该时段内结果指标的任何变化都不能归因于混杂因素的变化。 这就是为什么分层行得通的本质。
- 然后,我们通过计算每个桶的数字的加权平均值来计算新的总体比较。我们在这里使用的权重是关键,我们将在下面详细检查它们。
- 如果最初的比较和新的比较彼此非常不同,那么混淆就起作用了,我们不应该相信最初的比较。
让我们把这些想法汇总成一个清单,当你看到一个提示性的比较时使用。
1。首先,确认基础数据实际上是观察性的,也就是说,受试者是自我选择还是以某种非随机的方式结束分组?如果数据是实验性的,就不需要这个清单:-)
2。想到潜在的 混杂因素 那影响 既 (a)哪个主体最终在哪个群体(b)利益衡量标准?如果受试者自己选择分组,思考是什么因素导致他们有意识或无意识地选择一组而不是另一组。**
3。如果你发现的任何一个混杂因素都有数据,就按照上面的描述进行分层分析。
让我们将清单应用到几个例子中。
几个月前,您在您的电子商务网站的一个部分介绍了产品推荐,并想知道它是否“有效”。你可以做的一个最简单的比较就是比较点击了一个推荐的访问者和没有点击的访问者的花费。
这是你发现的。
点击产品推荐的网站访客比没有点击的访客多花了 18%的钱。
这种比较应该相信吗?
如果你这样做了,你可以决定在网站的所有部分显示推荐,以增加购物者点击推荐的机会。对于这样做的购物者,他们可能会平均多花 18%的钱?
让我们应用清单。
- 观测数据?**是的。虽然 A/B 测试在电子商务中无处不在,并且由于其使用了随机化,是可靠比较的来源,但像上面这样的比较不太可能来自随机测试,因为你不能强迫访问者点击产品推荐。参观者必须自选。
- 潜在的混杂因素。显而易见的是来访者的既往病史。如果他们是一个忠实的客户,他们可能会经常访问网站,更多地浏览网站,点击产品推荐,在购买时花费更多等等。因此,忠诚度可以影响他们点击推荐的倾向和他们的花费。
- 分层分析。
步骤 1:定义混杂变量桶。如果我们认为忠诚度是一个混淆因素,也许我们可以做的最简单的事情就是定义两个桶,新访客和回访访客,作为访客忠诚度的近似衡量标准。
****第二步:计算每个混杂因素的数量。我们分别计算新访客和回头客的人均消费数字。这将扩展原始表…
…到这
等一下!点击产品推荐对任何一种访问者类型都没有影响——0.70 美元保持为 0.70 美元,1.30 美元保持为 1.30 美元——然而,总体影响是 18%!这怎么可能?****
为了深入了解这是如何发生的,让我们从桶级别数字开始,自下而上计算总数——1.18 美元和 1.00 美元。
我们将首先计算样本中新访客和回头客的总体百分比:
然后,我们计算每种访问者类型点击推荐的百分比:
虽然 83%的回头客会点击产品推荐,但只有 55%的新访客会这样做。
有了这两个表,我们可以计算点击者和非点击者组中新的和返回的的百分比(即在每一列中)。例如,新访问者的点击者百分比= 27% * 55% / (27% * 55% + 73% * 83%) = 20%,返回的点击者百分比为 100% — 20% = 80%。完整的表格是:
现在,总体数字只是新的和返回的支出数字的平均值,加上上面计算的数字…
$0.70 * 20% + $1.30 * 80% = $1.18
$0.70 * 50% + $1.30 * 50% = $1.00
从图像上看,
…导致
我们现在可以看到它的危害有多严重。
每组(即列)中新老员工的比例因组而异。**
如果组合不完全相同,可能会出现奇怪的事情——例如,的总人数可能会减少,而 的每一个 阶层人数都会增加! ( 辛普森悖论)。
为什么两列中的混合物不一样?
因为回头客比新访客更有可能点击推荐。
需要注意的是,这种现象与你的数据样本中新访客和回头客的组合无关。关键因素是点击推荐的新访客的百分比与点击推荐的回头客的百分比。
如果这两个百分比相同,混合将是相同的。如果这两个百分比不同,混合将是不同的。
(顺便说一句,这就是随机分配如何防止混淆。如果我们以某种方式随机将访问者分配到“点击”和“未点击”组,点击推荐的新访问者的百分比将与点击推荐的回访访问者的百分比相同。因此,“点击”组和“未点击”组中的新信息和返回信息的混合应该是相同的,防止了我们上面看到的失真)
第三步:计算调整后的总比较数。
我们通过在两列中使用相同的权重来“取消发现”。哪些砝码?新客户和回头客的百分比。
正如我们之前看到的,新访客和回头客的总体比例分别为 27%和 73% …
…我们将它们作为权重来计算调整后的比较。
你现在可以看到,每种游客类型的 0%的消费差异也反映在调整后的总人数中。差异已经消失。
混杂因素扭曲了这些权重,因此每一列的权重都不同。通过对每根柱子使用相同的重量,我们消除了损害。
概括一下:使用数据中混杂组的受试者组合作为两组的权重,计算组级数字的加权平均值,以得出调整后的总体数字。
第四步:比较比较:-)
由于原始比较和调整后的比较大相径庭,因此原始比较不可信。
(旁白:评估产品推荐效果的一个更好的方法是将网站访问者随机分配到 A 组和 B 组,A 组的推荐在而 B 组的在关闭,并测量这两组在特定时间段内的每次点击收入、转换率等)。**
警告:这种“控制混杂因素”的方法远非万无一失。
- 可能还有其他你没有想到的混淆因素。关于如何识别一整套混杂因素(例如后门标准),有一个高度发展的理论,我鼓励你去阅读。我的希望是,这里提倡的尝试非正式地(基于你对业务的了解)识别混杂因素的方法足以让你开始。
- 你可能想到了其他混杂因素,但是你没有关于它们的数据,所以你无法控制它们。
- 你发现的混杂因素并不是真正的混杂因素。
- 你的控制方法不够好,例如,在上面的例子中,我们将游客分为两个桶,但也许这些桶太大了,以至于混淆在每个桶的内继续(在文献中称为剩余混淆)。**
- 另一方面,如果您创建了太多的存储桶,这些存储桶中的一些可能有太少的主题,这将导致度量的不可靠的估计。
- …
尽管有这些警告,当你看到一个有趣的比较,并想付诸行动时,还是值得使用这个清单。
这可能不会让你成为工作中的摇滚明星,但至少在某些时候会让你避免得出错误的结论。
在第 2 部分中,我们看了更多的例子,并解决了混杂因素太多导致分层变得混乱的情况。
(如果您觉得这篇文章有帮助,您可能会发现这些感兴趣的内容)
如何使用卷积神经网络进行时间序列分类
一个温和的介绍,最先进的模型概述,和一个动手的例子。
Photo by Christin Hume on Unsplash.
介绍
大量数据以时间序列的形式存储:股票指数、气候测量、医学测试等。时间序列分类有着广泛的应用:从股票市场异常的识别到心脑疾病的自动检测。
时间序列分类有多种方法。大多数方法包括两个主要阶段:在第一阶段,你要么使用某种算法来测量你想要分类的时间序列之间的差异(动态时间弯曲是一种众所周知的方法),要么使用你可以使用的任何工具(简单的统计学,先进的数学方法等)。)将您的时间序列表示为特征向量。在第二阶段,你使用某种算法对你的数据进行分类。它可以是从 k-最近邻和 SVM 到深度神经网络模型的任何东西。但是有一点将这些方法统一起来:它们都需要某种特征工程作为分类执行前的一个单独阶段。
幸运的是,有些模型不仅将特征工程整合到一个框架中,还消除了任何手动操作的需要:它们能够自动提取特征并创建时间序列的信息表示。这些模型是递归和卷积神经网络(CNN)。
研究表明,与其他方法相比,使用 CNN 进行时间序列分类有几个重要的优势。它们是高度抗噪声的模型,并且它们能够提取与时间无关的非常有用的深层特征。在本文中,我们将详细研究一维卷积如何对时间序列进行运算。然后,我将概述一个由圣路易斯华盛顿大学的研究人员提出的更复杂的模型。最后,我们将查看一个简化的多尺度 CNN 代码示例。
时间序列的一维卷积
想象一个长度为 n 宽度为 k 的时间序列。长度是时间步长的数量,宽度是多元时间序列中变量的数量。例如,对于脑电图,它是通道的数量(人头部的节点),对于天气时间序列,它可以是温度、压力、湿度等变量。
卷积核始终具有与时间序列相同的宽度,而它们的长度可以变化。通过这种方式,内核从一个时间序列的起点向终点沿一个方向移动,执行卷积。它不会像通常的 2-D 卷积应用于图像时那样向左或向右移动。
1-D Convolution for Time Series. Source: [2] (modified).
核的元素乘以它们在给定点覆盖的时间序列的相应元素。然后将乘法的结果加在一起,并将非线性激活函数应用于该值。结果值成为新的“过滤”单变量时间序列的元素,然后内核沿着时间序列向前移动以产生下一个值。新的“过滤”时间序列的数量与卷积核的数量相同。根据核的长度,初始时间序列的不同方面、属性、“特征”在每个新的过滤序列中被捕获。
下一步是对每个过滤的时间序列向量应用全局最大池:从每个向量中取最大值。从这些值形成一个新的向量,并且这个最大值的向量是最终的特征向量,其可以被用作常规全连接层的输入。整个过程如上图所示。
让我们把它带到另一个水平
记住这个简单的例子,让我们检查用于时间序列分类的多尺度卷积神经网络的模型[1]。
该模型的多重可伸缩性在于其架构:在第一卷积层中,卷积在 3 个并行的独立分支上执行。每个分支从数据中提取不同性质的特征,以不同的时间和频率尺度进行操作。
这个网络的框架由 3 个连续的阶段组成:变换、局部卷积和全卷积。
Multi-Scale Convolutional Neural Network Architecture [1].
转换
在这一阶段,不同的变换应用于 3 个独立分支上的原始时间序列。第一个分支转换是身份映射,这意味着原始时间序列保持不变。
第二个分支转换是用不同窗口大小的移动平均值平滑原始时间序列。通过这种方式,创建了几个具有不同平滑度的新时间序列。这背后的想法是,每个新的时间序列都整合了来自原始数据的不同频率的信息。
最后,第三个分支变换是用不同的下采样系数对原始时间序列进行下采样。系数越小,新的时间序列就越详细,因此,它会在更小的时间范围内整合有关时间序列特征的信息。系数较大的下采样会产生不太详细的新时间序列,这些序列捕捉并强调原始数据在较大时间尺度上表现出来的特征。
局部卷积
在这个阶段,我们前面讨论的具有不同滤波器大小的 1-D 卷积被应用于时间序列。每个卷积层之后是最大池层。在前面更简单的例子中,使用了全局最大池。这里,最大池不是全局的,但池内核的大小仍然非常大,比您在处理图像数据时习惯的大小要大得多。更具体地说,池内核大小由公式 n/p 确定,其中 n 是时间序列的长度,而 p 是池因子,通常在值 {2,3,5} 之间选择。这个阶段称为局部卷积,因为每个分支都是独立处理的。
全卷积
在这一级,来自所有 3 个分支的局部卷积级的所有输出被连接。然后再增加几个卷积层和最大池层。在所有的变换和卷积之后,您只剩下一个具有深度、复杂特征的平面向量,这些特征在广泛的频率和时间尺度域中捕获关于原始时间序列的信息。然后,该向量被用作最后一层上具有 Softmax 函数的完全连接层的输入。
Keras 示例
from keras.layers import Conv1D, Dense, Dropout, Input, Concatenate, GlobalMaxPooling1D
from keras.models import Model#this base model is one branch of the main model
#it takes a time series as an input, performs 1-D convolution, and returns it as an output ready for concatenationdef get_base_model(input_len, fsize):
#the input is a time series of length n and width 19
input_seq = Input(shape=(input_len, 19))
#choose the number of convolution filters
nb_filters = 10
#1-D convolution and global max-pooling
convolved = Conv1D(nb_filters, fsize, padding="same", activation="tanh")(input_seq)
processed = GlobalMaxPooling1D()(convolved)
#dense layer with dropout regularization
compressed = Dense(50, activation="tanh")(processed)
compressed = Dropout(0.3)(compressed)
model = Model(inputs=input_seq, outputs=compressed)
return model#this is the main model
#it takes the original time series and its down-sampled versions as an input, and returns the result of classification as an outputdef main_model(inputs_lens = [512, 1024, 3480], fsizes = [8,16,24]):
#the inputs to the branches are the original time series, and its down-sampled versions
input_smallseq = Input(shape=(inputs_lens[0], 19))
input_medseq = Input(shape=(inputs_lens[1] , 19))
input_origseq = Input(shape=(inputs_lens[2], 19))#the more down-sampled the time series, the shorter the corresponding filter
base_net_small = get_base_model(inputs_lens[0], fsizes[0])
base_net_med = get_base_model(inputs_lens[1], fsizes[1])
base_net_original = get_base_model(inputs_lens[2], fsizes[2])embedding_small = base_net_small(input_smallseq)
embedding_med = base_net_med(input_medseq)
embedding_original = base_net_original(input_origseq)#concatenate all the outputs
merged = Concatenate()([embedding_small, embedding_med, embedding_original])
out = Dense(1, activation='sigmoid')(merged)model = Model(inputs=[input_smallseq, input_medseq, input_origseq], outputs=out)
return model
该模型是多尺度卷积神经网络的更简单版本。
它将原始时间序列及其 2 个下采样版本(中等长度和小长度)作为输入。模型的第一个分支处理长度为 3480、宽度为 19 的原始时间序列。相应的卷积滤波器长度是 24。第二个分支处理时间序列的中等长度(1024 时间步长)下采样版本,这里使用的滤波器长度为 16。第三个分支处理时间序列的最短版本(512 个时间步长),滤波器长度为 8。这样,每个分支提取不同时间尺度的特征。
在卷积和全局最大池层之后,添加了丢弃正则化,并且所有输出被连接。最后一个全连通层返回分类结果。
结论
在这篇文章中,我试图解释深度卷积神经网络如何用于时间序列分类。值得一提的是,提出的方法并不是唯一存在的方法。有多种方法可以将时间序列以图像的形式呈现出来(例如,使用它们的光谱图),可以对其应用常规的二维卷积。
非常感谢您阅读这篇文章。我希望它对你有帮助,我真的很感谢你的反馈。
参考文献:
[1]崔,陈,陈.多尺度卷积神经网络用于时间序列分类(2016),。
[2] Y. Kim,卷积神经网络用于句子分类(2014),https://arxiv.org/abs/1408.5882。
如何利用数据科学产生社会影响
Photo by Arjunsyah on Unsplash
透明度腐败协作信任
数据科学是一个真正的跨学科领域。
数学家、统计学家、计算机科学家、社会科学家、数据库管理员、数据工程师、图形设计师、用户界面专家、记者、说书人、研究人员和企业管理人员都参与了这个过程。
随着机器学习和人工智能的不断发展,哲学家和伦理学家也有望被纳入这一过程。
数据科学强大。如果使用正确,它将授予对以下内容的访问权限:
- 客观理解世界的能力。
- T4 利用这种理解来创造进步的能力。
故事是这样的:
Figure 1
利用数据以多种形式出现。网飞利用数据科学向顾客推荐电影和电视节目。脸书利用数据科学来制作有针对性的广告。谷歌使用数据科学来优化搜索结果。亚马逊使用数据科学与 Alexa 进行对话。微软利用数据科学创造虚拟现实。
但是等等,还有更多。
Kaggle 正在使用数据科学来预测贫困水平,以确定哪里最需要社会福利援助。Code for Africa 正在使用数据科学来创建一个工具,帮助肯尼亚公民出现在投票箱前了解情况并准备投票。DataKind 正在使用数据科学来创造更多简化的摆脱无家可归的途径。
这两组数据科学用户之间存在明显的差异。前者利用数据获得收入。后者利用数据进行社会影响。
我们如何继续利用数据科学产生社会影响?
关键:公开数据。
什么是开放数据?
由开放知识基础定义:
“开放数据是指任何人都可以自由使用、重用和重新分发的数据。”
很明显,数据科学首先依赖于数据收集。没有数据就没有数据清理*,数据分析,或数据*利用率。来自 Kaggle,Code for Africa 和 DataKind 的社会影响项目非常棒,但是如果没有数据,这些项目是不可能实现的。
如果 IDB 没有给他们家庭收入数据,Kaggle 不可能开始预测贫困。如果独立选举&边界委员会没有发布他们在选民登记中心的位置数据,“非洲代码”不可能创造出任何工具。
这正是为什么开放数据是通过数据科学创造社会影响的关键。可用的数据越多,利用它的机会就越多。
我承认,当谈到开放数据时,有一点二分法。这是透明度和安全性之间的一种不稳定的平衡。
我已经分享了我对数据隐私需求的想法。在达到不可逆转的地步之前,解决开放数据的潜在滥用是很重要的。剑桥分析公司(Cambridge analytic a)、 Strava 和 Equifax 丑闻清楚地概述了为什么公开数据可能是糟糕的。
这就是为什么它必须被正确地做。
如何正确做开放数据
对脸书来说,突然向公众开放他们的数据库并不是一个好主意。对谷歌来说,分享他们所有的私人用户信息也是一个同样糟糕的主意。需要明确的是,开放数据并不意味着适用于所有平台。
公开数据的最佳用途是在政府和人民之间。
故事是这样的:
Figure 2
开放数据开启对话
布宜诺斯艾利斯利用他们的开放数据平台告知公众政府正在做什么。他们用数据可视化制作了有趣的报告,向他们的公民展示重要信息。他们甚至创造了一个互动工具来帮助公众了解政府如何为季度预算分配资金。
“预算反映了国家如何利用从全体公民那里获得的资源。重要的是要传达这些资金是如何用于刺激参与、优化控制和提高公众讨论水平的。”-布宜诺斯艾利斯城
开放数据打击犯罪
在哥伦比亚的卡利,开放数据平台已经允许像 DataPico 这样的公司创建工具,告知公众他们城市的犯罪分布情况。
当我住在卡利时,我甚至使用开放数据平台告诉公众在他们的城市哪里最有可能发生凶杀案。
This visual was created using data provided by Cali’s open data platform
预测性警务是数据如何用于打击犯罪的一个很好的例子。虽然在政府采用这一系统之前,预测性警务还有一些重要问题需要解决,但哥伦比亚波哥大的国立大学已经在制定一项为期三年的计划,以利用数据更有效地管理城市。目标是减少犯罪。
开放数据对抗暴力
当数据公开时,就更容易与大量受众分享严酷的现实。Vox 是通过数据可视化向公众提供信息的平台的一个很好的例子。在这个故事中,Vox 使用来自美国实体的数据来提高人们对枪支暴力的认识。
请记住,数据科学提供了一种“客观理解世界的能力”。新闻媒体倾向于主观地向公众展示数据分析。公开数据的美妙之处在于原始数据是客观的。开放数据为公众提供了获取信息的途径,这使得每个人都可以得出自己的结论。
这个工具是一个很好的例子,展示了暴力是如何在卡利市被客观地可视化的。数据可视化提高了公众意识。
开放数据对抗腐败
当政府被迫公开数据时,隐藏腐败变得更加困难。这方面的一些例子:
- 布宜诺斯艾利斯政府向公众提供他们的预算分配,要求他们负责准确使用预算。
- 被要求在执勤时佩戴人体照相机的美国警察被要求在法庭上保持诚实。
- 在墨西哥,使用公开数据来识别腐败合同让政府有责任停止将贿赂作为商业交易。
图 2 概述了这一过程。当公众意识到这一点时,政府和公众之间的对话就开始了。对话导致合作。合作使政府能够与其公民一起创造进步。
进步在人民和政府之间建立信任。
对于有腐败历史的国家来说,信任非常重要。一个国家的腐败感知指数(CPI)是一个每年收集的指数,用于衡量腐败公民对其政府的看法。CPI 与人均 GDP 直接相关。
当公民相信他们的政府不那么腐败时,GDP 就会上升。仅仅一个单位的 CPI 增长就被证明可以使人均 GDP 年均增长 1.7%。对腐败的看法在发展中国家有很大影响。
TLDR:在政府和公民之间建立信任非常重要。开放数据有助于做到这一点。
是什么在挡路?
开放数据的主要障碍是它只有在每个人都参与的情况下才能发挥作用。我将在本文中进一步讨论这个问题。
我们建设未来
像 DataKind、Code for Africa 或 Kaggle 这样的组织面临的严峻现实是,大多数社会影响项目都依赖于志愿者工作。不幸的是,很难将有所作为的项目货币化。
好消息是变革的工具就在我们的指尖。开放式数据平台正在增长。许多编码课程可以在免费在线获得。社会影响似乎触手可及。如果你有一台电脑和互联网,你就和其他人一样有资格开始做一些项目来改变你的社区。
数据是我们的历史。数据科学是我们的未来。我们要做的就是建造它。
*结语 *
这篇文章的灵感来自我和我哥哥在哥伦比亚卡利共同举办的主题为“如何编码和实现社会影响”的编码研讨会
The workshop filled up in just a few days!
在研讨会上,我们讨论了开放数据平台如何帮助经济增长、打击腐败和犯罪、建立信任社区以及在政府和公民之间架起桥梁。
为了在 Cali 推广开放数据平台,我们创建并发布了 Datos Profundos。
欢迎来到 Datos Profundos!这是一个为英语和西班牙语使用者开放的资源仓库,他们对…
github.com](https://github.com/jesmith14/DatosProfundos)
Datos Profundos 是一个开源存储库,为具有任何编码能力的个人提供讲座和教程,以理解数据科学。这些教程使用 Cali 的开放数据平台来推动创建社会影响视觉效果和工具,就像在布宜诺斯艾利斯和肯尼亚那样。
讲西班牙语和英语的人都可以访问该平台。
感谢阅读!感觉有动力?我和我哥哥正在哥伦比亚发起一项运动,旨在提供无障碍编码教育,同时利用技术产生积极的社会影响。如果你有兴趣参与,请联系我们!
[## 杰西·史密斯-数据科学实习生- datapico | LinkedIn
数据伦理技术社会影响透明度真实性*教育我喜欢学习和与人交流。我…
www.linkedin.com](https://www.linkedin.com/in/jessiejsmith/)
如何在机器学习项目中使用数据版本控制(dvc)
当在一个多产的机器学习项目中工作时,你可能会处理一些数据和几个模型。为了跟踪哪些模型是用哪些数据训练的,您应该使用一个系统来对数据进行版本化,类似于对代码进行版本化和跟踪。解决这个问题的一种方法是 dvc(数据版本控制,https://dvc.org/),它以类似于 Git 的方式处理数据版本控制。
为了说明 dvc 在机器学习环境中的使用,我们假设默认情况下我们的数据分为训练、测试和验证文件夹,数据量随着时间的推移通过主动学习周期或通过手动添加新数据而增加。下面的结构就是一个例子,为了简化起见,这里省略了标签:
├── train
│ ├── image1.jpg
│ ├── image2.jpg
│ └── image3.jpg
├── val
│ └── image4.jpg
└──test
└── image5.jpg
通常,最低版本系统应该具有以下两种功能:
- 用新版本标记一组新数据,例如 vx.y.z
- 返回旧数据版本或在不同数据版本之间切换非常容易
在其他功能中,dvc 能够完成这些任务。为此,它与 Git 紧密合作。首先,您需要安装 dvc,这可以使用 pip 来完成
pip install dvc
要开始版本化过程,您必须在数据的基本文件夹中创建一个 git 存储库,然后通过
git init
dvc init
通过 init 命令,dvc 现在已经创建了一个包含其缓存的. dvc 文件夹,以便保存不同数据版本和存储元信息的配置文件之间的差异。
在这种情况下,你想知道 git 如何适应这个概念:在这种情况下,git 的任务不是对数据本身进行版本化,而是对 dvc 文件进行版本化,DVC 文件保存了版本的元信息,如对应于特定版本的文件的位置,或者数据的哪个文件属于当前数据版本的信息。
为了让 git 忽略数据本身,dvc 还会自动写入。gitignore 文件。提交 dvc 的配置文件和。gitignore 文件我们需要做一个初始提交
git commit -m “Initial commit”
每个数据版本都与其自己的相关联。dvc 文件,同样与一个提交或一个 Git 头相关联。dvc 文件定义并跟踪给定版本的数据,由此 dvc 文件本身被 Git 跟踪。对我来说,将新数据版本与 Git 头相关联的一个好方法是为新数据版本创建一个新分支。为此,在定义我们的第一个版本之前,我们用版本的名称创建一个新的分支,并签出到这个分支:
git checkout -b v0.0.1
现在,我们可以通过告诉 dvc 应该跟踪哪些数据来定义我们的第一个版本,在我们的例子中是 train、val 和 test 文件夹。这可以通过 dvc add 命令来完成:
dvc add train test val
之后,我们现在看到新的。每个文件夹的 dvc 文件,如基本文件夹中的 train.dvc。文件夹本身已被添加到。gitignore,这样 git 就不会跟踪数据本身,在我们的例子中,这是 dvc 的任务。为了追踪新的。我们用 Git 创建了标准的 Git 提交过程
git add .
git commit -m "Data versioning files added to Git"
现在,我们已经创建了数据的第一个版本,将哪些数据属于我们的。dvc 文件并参考了。dvc 自己被当前提交。请注意,您还可以将 git 连接到远程 git 来保存和版本化。远程 dvc 文件。在这种情况下,数据保留在当前文件夹中,而不是远程存储(这也可以使用 dvc 推拉进行更改)。
我们现在已经将数据的一种状态与一个版本相关联,但是当然,您不需要为一个 fix 数据集进行数据版本化。因此,我们现在假设两个新图像(image6.jpg 和 image7.jpg)被添加到 train 和 test 文件夹中,因此结构现在看起来像这样:
├── train
│ ├── image1.jpg
│ ├── image2.jpg
│ ├── image3.jpg
│ └── image6.jpg
├── val
│ └── image5.jpg
└── test
├── image4.jpg
└── image7.jpg
为了创建新的数据版本,我们重复前面的步骤。因此,我们创建一个对应于新数据版本的新分支
git checkout -b v0.0.2
正如我们已经知道的,一个新的数据版本总是与它们自己相关联的。存储版本元信息的 dvc 文件。为了更新。dvc 文件我们需要告诉 dvc,它应该再次跟踪 train 和 test 文件夹,因为这些文件夹中有新数据:
dvc add train test
train.dvc 和 test.dvc 文件已更改,dvc 现在可以跟踪哪些文件属于当前版本。为了追踪新的。git 分支中的 dvc 文件,我们必须提交:
git add .
git commit -m "Data versioning files added to Git"
现在爽的部分来了。当检查您的 git 分支时,您会看到两个不同的分支(主分支除外),其中每个分支对应一个数据版本:
master
v0.0.1
* v0.0.2
现在,您可以返回到旧的数据版本,并直接更新您的数据目录,以便重新创建旧的数据版本。为了回到之前的版本,我们需要做两件事。首先,我们需要签出到数据版本的相应标题,在本例中是 branch v0.0.1:
git checkout v0.0.1
在这个脑袋里。与 v0.0.2 相比,dvc 文件有所不同,但我们当前的数据目录看起来仍然相同,目录中的数据仍然对应于 v0.0.2。这是因为 dvc 尚未将数据目录与其对齐。dvc 文件。将您的数据目录与正确的数据版本对齐,这同样在。dvc 文件,需要执行 dvc checkout 命令:
dvc checkout
该命令使用其缓存恢复旧的数据版本(在本例中为 v0.0.1)。现在,当您查看您的数据存储库时,您会再次看到以下结构:
├── train
│ ├── image1.jpg
│ ├── image2.jpg
│ └── image3.jpg
├── val
│ └── image4.jpg
└──test
└── image5.jpg
文件 image6.jpg 和 image7.jpg 被从数据目录中删除并存储到 dvc 的缓存中。现在,您可以像往常一样使用三个文件夹来处理旧数据版本。
此过程还适用于包含比当前持久存储在数据文件夹中的数据多得多的数据版本,因为 dvc 在其缓存中存储不同版本之间任意大小的差异,因此可以通过其 checkout 命令重新创建数据目录的较旧或较新状态。当然,结账也可以是另一个方向。您可以将 git 签出到 branch v0.0.2 并执行 dvc 签出,以便将数据目录设置为 v0.0.2 版本的状态。
除了 init、add 和 checkout 命令之外,dvc 还有更多功能,以便使机器学习/大数据工作流程更加简单。例如,可以在多台机器之间共享数据版本吗?使用像亚马逊的 S3 存储桶这样的远程存储桶,并使用 dvc 推拉与存储桶进行交互(有关详细信息,请参见。https://dvc.org/。
我希望这篇文章可以帮助更好地组织机器学习项目中的数据,并保持更好的概览。
更多关于机器学习、数据科学和统计学的博文,请查看
如何使用深度学习,即使是小数据
以及为什么它如此重要
你已经听说了这个消息——深度学习是自切片面包以来最热门的东西。它承诺以极小的代价解决大量数据中最复杂的问题。唯一的问题是,你既不是在谷歌也不是在脸书工作,数据很少。那你打算怎么办?你还能利用深度学习的力量吗?还是你运气不好?让我们来看看你如何能够利用深度学习,即使数据有限,以及为什么我认为这可能是未来研究中最令人兴奋的领域之一。
从简单开始
在我们讨论利用深度学习处理有限数据的方法之前,请从神经网络后退一步,建立一个简单的基线。通常不需要很长时间就可以试验一些传统的模型,比如随机森林。这将帮助你衡量深度学习的任何潜在提升,并为你的问题提供深度学习与其他方法之间的权衡的大量见解。
获取更多数据
这听起来可能很荒谬,但是你真的考虑过你是否能收集更多的数据吗?我惊讶地发现,我经常向公司提出这样的建议,他们看着我,好像我疯了一样。**是的——投入时间和金钱来收集更多的数据是可以的。**事实上,这通常是你的最佳选择。例如,也许你正在尝试对稀有鸟类进行分类,但数据非常有限。几乎可以肯定的是,只要标注更多的数据,解决这个问题会更容易。不确定需要收集多少数据?尝试绘制学习曲线,添加额外的数据并观察模型性能的变化。
微调
Photo by Drew Patrick Miller on Unsplash
好吧。让我们假设您现在有一个简单的基线模型,并且收集更多的数据要么是不可能的,要么太昂贵。在这一点上,最可靠的方法是利用预先训练好的模型,然后针对您的问题对它们进行微调。
微调的基本思想是获取一个非常大的数据集,希望它与您的领域有些相似,训练一个神经网络,然后用较小的数据集微调这个预训练的网络。你可以在这篇文章中了解更多。
对于图像分类问题,要去的数据集是 ImageNet 。该数据集包含跨越许多对象类别的数百万幅图像,因此可用于许多类型的图像问题。它甚至包括动物,因此可能有助于珍稀鸟类的分类。
要开始微调一些代码,请查看 Pytorch 的伟大的教程。
数据扩充
如果您无法获得更多数据,并且在大型数据集上的微调没有任何成功,那么数据扩充通常是您的下一个最佳选择。它也可以与微调结合使用。
数据扩充背后的想法很简单:以提供新数据的方式改变输入,同时不改变标签值。
例如,如果你有一张猫的图片,旋转图像,它仍然是一张猫的图片。因此,这将是很好的数据扩充。另一方面,如果你有一张道路的照片,并希望预测合适的转向角度(自动驾驶汽车),旋转图像会改变合适的转向角度。这是不行的,除非你也适当地调整转向角度。
数据扩充是最常见的图像分类问题,你可以在这里找到技术。
你可以经常想到创造性的方法来增加其他领域的数据,如 NLP(参见这里的一些例子),人们也在尝试用 GANs 来生成新数据。如果对 GAN 方法感兴趣,我会看看 DADA :深度对抗数据增强。
余弦损失
最近的一篇论文,在没有使用余弦损失进行预训练的情况下对小数据集进行深度学习,发现当将损失函数从分类交叉熵损失切换到分类问题的余弦损失时,小数据集的准确性提高了 30%。余弦损失简单来说就是 1 — 余弦相似度。
在上面的图表中,您可以看到性能如何根据每个类的样本数量而变化,以及微调如何对一些小数据集(CUB)非常有价值,而对其他数据集(CIFAR-100)没有价值。
深入
在 NIPs 的一篇论文中,现代神经网络对小数据集进行归纳,他们将深度神经网络视为整体。具体来说,“不是每一层都呈现出不断增加的特征层次,而是最终层提供了一个整体机制。”
我对此的看法是,对于小数据,确保你建立了深厚的人际网络,以利用这种整体效应。
自动编码器
已经有一些成功使用堆叠式自动编码器用更优的起始权重来预训练网络。这可以让你避免局部优化和其他不好的初始化陷阱。不过,安德烈·卡帕西建议不要对无人监督的预训过于兴奋。
如果你需要温习自动编码器,你可以查看斯坦福深度学习教程。基本想法是建立一个预测输入的神经网络。
先验知识
Photo by Glen Noble on Unsplash
最后,但同样重要的是,尝试并找到整合特定领域知识的方法来指导学习过程。例如,在通过概率程序归纳的人类级概念学习中,作者构建了一个模型,该模型通过利用过程中的先验知识从零件构建概念。这导致了人类水平的性能,并超过了当时的深度学习方法。
您还可以使用领域知识来限制网络的输入,以减少维数或将网络架构调整得更小。
我把这作为最后一个选项,因为整合先前的知识可能具有挑战性,并且通常是最耗时的选项。
再次制造小爽
希望这篇文章给了你一些关于如何利用深度学习技术的想法,即使数据有限。我个人发现,这个问题目前没有得到应有的讨论,但它有着非常令人兴奋的影响。
有大量的问题只有非常有限的数据,而获取更多的数据是非常昂贵或不可能的。比如检测罕见病或者教育成果。找到将我们的一些最佳技术(如深度学习)应用于这些问题的方法是非常令人兴奋的!甚至吴恩达也同意:
这个故事也可以在这里找到。
如何使用不同的数据模型和数据库的可视化表示
数据库和 SQL 初级课程
当您进入数据库和数据科学领域时,您必须掌握的第一件事是数据库中实体之间的关系。这很重要,因为您使用的数据必须对其进一步的实现绝对有效。
Photo by JESHOOTS.COM on Unsplash
让我们马上看看如何最好地概述数据并准备它。
举个例子,我将使用一个基于 1954-2014 年 FIFA 世界杯的数据库。
在这个数据库中,我们有多个实体,它们代表了数据库中最重要的部分,并且应该是相互连接的。这是这种关系的可视化表示:
当连接实体时,您还必须添加符号,以便更容易识别实体之间的关系。对于这个数据库,我准备用修改陈的符号。Chen 的实体关系建模符号使用矩形表示实体集,菱形表示适合一级对象的关系:它们可以有自己的属性和关系。如果实体集参与关系集,它们用一条线连接起来。
这看起来是这样的:
1:1 — [1]到[1]
1:C — [1]到[0 或 1]
1:M — [1]到[至少 1]
1:MC — [1]到[任意多]
C:C — [0 或 1]到[0 或 1]见陈
C:M — [0 或 1]到[至少 1]见 1
C (“choice”/"can ")到模型 0 或 1,而 1 恰好表示 1,M 至少表示 1
对关系建模有多种表示方式,这意味着实体之间的符号可以不同。
例如,您可以使用(min,max)符号,对于同一个数据库,该符号如下所示:
这是一个 SQL 脚本,它将表创建为上面的实体:
下图显示了用关系表(红色)连接实体(绿色)的过程:
这就是数据的可视化表示。就不同的符号和关系而言,还有很多方法可以做到这一点。
激励的遗言
当开始使用数据库时,尽量精确处理数据和数据中实体之间的关系。掌握数据科学的每一步都有其特殊之处,正确开始非常重要!坚持学习编程!
感谢阅读!
如何设计最快的汽车
从有限数量的乐高积木中研究实验设计(DOE)
ZEUS — The Mighty Truck
项目目标和目的
这个“实验设计”项目的目的是最大限度地增加乐高赛车在走下预先建造的坡道后可以行驶的距离。这辆赛车是由数量有限的乐高积木组装而成的。通过建造这款赛车,我们对距离进行了细致的比较,以找到最佳型号。
描述你的实验装置
首先,当实验进行时,所有的观察都是在同一天进行的。如前所述,这个模型有两个不同的复制,四个因素(将在下一节介绍)。这个斜坡与墙壁的夹角为 24 度,斜坡的尺寸为 28 英寸(长)x 12.5 英寸(高)。为了测试的目的,汽车从这个稳定的斜坡的顶部被释放,并在房间内行驶一段距离。每一个测试的变化,关于模型,举行了不同的因素组合,以发现最好的赛车。
选择的因素
Factors
为项目选择的第一个因素是 【离地间隙(A) ,它描述了模型底部离地面的高度,单位为厘米。为了了解离地间隙是否重要,选择了 2 厘米作为“-1”因子等级,另一方面,2.2 厘米低于因子等级“1”。在这个项目中选择的第二个因素是模型的***【B】,这与汽车前后轴基的宽度有关。为了了解这一因素是否重要,因子级别“-1”选择了 4.8 厘米,因子级别“1”选择了 6.4 厘米。为该项目挑选的第三个因素是 【前轮尺寸© ,它描述了可以安装到模型上的不同车轮组。同样,小车轮尺寸将由因子等级“-1”表示,大车轮尺寸将由因子等级“1”表示。第四个也是最后一个因素是模型的(D)***,这是模型背面的迷你翼形机构。要查看结果是否有实际变化,因子级别“-1”将用于复制没有扰流板的车型,而“1”将用于复制有扰流板的车型。
响应变量测量
用卷尺测量离坡道末端的距离。在本项目中,响应变量(y)是从匝道终点测量的水平距离。对于每一次观察,都要测量离斜坡底部中心的距离。就赛车而言,测量是从模型的左后轮进行的,以便在所有观察中获得更好的准确性。通过这个实验设置,收集了包含所有 32 个观察值的完整数据表。
实验设计和方法
该实验的设计包括不断测试具有相同基础模型的乐高赛车,同时还实施四个因素和两个复制。为了减少该模型中的变化,我们选择了前面提到的在测试期间进行快速调整的因素。这使得在存在不同因素组合的情况下,可以通过观察模型的比较来做出比较决策。为了避免任何噪音,该实验再次运行两次,以避免和阻止这些罕见情况下的任何噪音参数。在这个项目的方法中,遵循了两个约束条件,以确保汽车的性能不会受到任何外部因素的影响。第一个限制是给定的乐高积木是 DOE 项目中唯一使用的积木。第二个约束包括确保所有测试的模型都有乐高套装中提供的挡风玻璃和方向盘。
数据分析和模型充分性检查
下图中的 “残差与拟合” 表明所有残差围绕 0 的中线随机分离。这种模式支持回归的假设,即关系是线性的,并表明残差具有恒定的方差,同时也指出没有异常值。通过图表中各种各样的点可以进一步看出这一点。图中没有任何危险信号或趋势表明数据中存在问题。现在, “残差对顺序” 图也显示了所有残差随机围绕 0 的中间线,其结果与前面提到的图非常相似。因此,这两个图表明残差是独立的,并且彼此不相关。看 【正态概率图】 时,点呈正态分布,有很强的线性关系,表示正态。 【直方图】 图也讲述了一个类似的故事,因为残差的频率显示了一组非常正态分布的数据。
结果
观察
Normal Plot and Pareto Chart
Normal Plot and Pareto Chart
如上图所示,通过来自数据集的四个组合可以看出重要因素。第一个重要因素是轴距。第二个重要因素是赛车底座到地板的离地间隙。第三个重要因素是汽车前部的车轮尺寸。最后也是最有趣的因素是离地间隙、轴距和扰流板的组合。首先,这一点包括 D,它本身并不是一个重要因素。另一方面,这种特殊的因素组合产生了数据差异,与前面提到的其他重要因素不相上下。
Main Effects Plot
Main Effects Plot
此处的“主效应”图显示,与 d 相比,因素 A、B、C 的影响更大。原因是线更陡,这表明存在强烈的主效应。其中最陡的大约是轴距,因为这个因素有非常重要和积极的影响。虽然可能有轻微的主效应,但关于扰流器,该线更接近于水平,这将表明这实际上不太重要。
Interaction Plot
Interaction Plot
上面的“距离相互作用图”显示了数据中可能存在的各种相互作用。这里每一个接近平行的图,比如左上角的 AB,都没有数据中存在的相互作用。另一方面,AD 有一个相互作用,即“离地间隙扰流器”,因为两条线相互交叉,因此表明存在一种关系。此外,由于这种情况,这两个因素 AD 相互影响。
Cube Plot
Cube Plot
上面显示的“立方体图”显示了与实验测试结果和数据集相关的拟合平均值。这些值中的最大值是左立方体右上角的 46.3828。这表明 A*B 关系产生了一个大值,如图所示。此外,与另一个立方体相比,左边的立方体具有更高的拟合平均值。
因子回归
Analysis of Variance
下面的 ANOVA 表表明,所有 4 个因素(A、B、C 和 ABD)分别是显著的。这可以通过 P 值 0.017、0.000、0.002 和 0.026 看出。由于这些值都小于 0.05,所以它们在统计上是显著的,并显示出它们在数据中的差异。此外,它们还具有较高的 F 值,这表明在大多数情况下具有统计学意义。
Analysis of Variance
Model Summary
80.09%的高 R2 值表明拟合值非常接近实际观察值。
Model Summary
Coded Coefficients
下面的编码系数表显示所有 VIF 值均为 1,这表明这些因子没有多重共线性。
Coded Coefficients
结论
总之,在 DOE 项目中发现的最重要的因素是离地间隙和轴距。这些部件对乐高赛车的距离和速度都有很大的影响。在财务分析中选择的最好的汽车是“AB”型,它有更宽的轴距,更高的离地间隙,小前轮,没有扰流板。与其他型号相比,这辆车达到了最大的平均行驶距离。就推荐而言,轴距大、离地间隙高、前轮小、没有扰流板的车型是最佳的赛车。现在,就 DOE 项目期间经历的其他事情而言,建议任何型号都采用更宽的轴距。总的来说,找到的性价比高的模型显示了最佳距离,并将成为“比赛日”比赛的竞争者。
关于我
非常感谢您阅读我的文章!大家好,我是雪莉,目前在亚利桑那州立大学攻读商业分析硕士学位。特别感谢我的队友 Divya,Raghu 和 Andrew 的贡献。如果您有任何问题,请随时联系我!
Email me at ***kchen122@asu.edu***and feel free to connect me on [**LinkedIn**](https://www.linkedin.com/in/kuanyinchen-shirley/)!
如何使用改变游戏规则的人工智能来提高决策质量(案例研究 1)
source: rarehistoricalphotos.com
注:本文由 诺贝特·多勒 合著。
免责声明:精选照片显示的是加利福尼亚州斯德哥尔摩的旧电话塔。1890.它连接了大约 5500 条电话线。如果你完全接受它的复杂性,那你就看错了文章。然而,如果它让你想起你自己的事业,并且你相信总有更好的方法——这篇文章就是为你准备的。
在本系列的介绍中,我们讨论了游戏人工智能对于商业应用的潜力。企业通过其决策的质量创造价值。通常,这些决策非常复杂。有数以百万计的选择、冲突的驱动因素、不确定性、隐藏的偏见等等。这些复杂性加在一起,使得人类很难做出好的决策。与人类不同,游戏人工智能是为处理这种复杂性而设计的。它擅长支持复杂的决策。
为了说明游戏人工智能如何帮助增强决策能力,我们发布了一系列案例研究。这些例子展示了游戏 AI 在现实世界行业应用中的优势。
本文讨论了我们想要涉及的第一个案例:*维护计划。*我们将关注能源行业,但这是一个跨许多行业的高风险问题。
Photo by Nicholas Doherty on Unsplash
我们将逐步介绍我们的方法:
- 将业务问题转化为游戏
- 开发正确的游戏人工智能代理来控制游戏
- 分析人工智能的制胜策略——从而解决业务问题
但是,在我们进入游戏、人工智能和获胜策略之前,让我们后退一步,从基础开始。什么是维修规划,更重要的是:为什么是这么复杂的问题?
“行业局外人可能会对(……)运营商经常忽视或忽略详细的活动规划感到惊讶,这要么是因为更紧迫的中断修复问题优先考虑,要么是因为在一个专注于激动人心的发现和新产品的行业中,它似乎不那么有趣。”(贝恩&公司
维护规划—它是什么,为什么复杂?
想象一家能源公司的离岸资产。它有十个无人平台需要维护。资产面临着维护范围的巨大工作量,大约有 9,000 个活动需要执行。
这些活动在硬性指标方面有很大不同,例如:
- 所需工人(员工)总数
- 工人的技能(如焊工、架子工和技术员)
- 执行工程的材料要求
- 工作地点
- 工程持续时间
此外,活动在软指标方面有所不同,例如
- 相对重要性
- 相对紧迫性
最后,更糟糕的是,执行能力受到约束。只有一艘工作船将维护人员运送到平台上。那艘船的载客量是固定的,限制了每天和每个地点可用的工人数量。
资产面临的问题是:计划活动的“最佳”策略是什么?
Photo by Hans-Peter Gauster on Unsplash
这个问题在很多方面都很复杂。
首先是规模的问题。有 9000 件作品,可能的计划选项的数量绝对是巨大的。
第二,有约束。工作船在任何给定的行程中只能承载这么多的工人。每个船员都有特殊的技能,需要相应的计划。活动可能是相互依赖的,有些活动取决于其他活动的时间安排。一些活动可以并行执行,而另一些则不能。
第三,更软的指标通常由意见驱动。意见往往没有量化,有偏差。优先级是由“谁喊得最响”驱动的。不同的利益相关者有不同的看法。而这些意见都在争夺同样的资源。
最后,条件一直在变。检测结果、生产混乱或泄漏经常会改变产品组合。因此,除了非常大、受约束和意见驱动之外,工作范围也一直在变化。
因此,公平地说,资产正面临着驱动因素、约束、意见和数学的复杂局面。找到规划工作的“最佳”策略一点也不简单。
source: gratisography on pexels
处理这一挑战的现有流程基于手工作业。计划是通过优秀、经验和直觉的结合而产生的。结果是维护人员的效率远远低于预期。计划不稳定,维护积压逐年增加。这种积压影响了资产的安全和生产性能。
想象一个星期五晚上下班后在任何一个石油城镇,从阿伯丁到卡尔加里或珀斯。钻井工人和维修工程师讲述了本周的小胜利——其中不少包括吹嘘需要长时间加班才能解决意外问题的英勇努力,或支付溢价将零件和人员紧急送往急需的地方——所有这些都是石油和天然气行业闻名的“能行”精神的一部分。
虽然这些都是好故事,但这绝不是经营企业的方式。“(贝恩&公司)
换言之,提高规划效率是一个需要解决的关键问题。而目前的流程并不能解决这个问题。
幸运的是,还有一个选择:制作一个游戏。
游戏人工智能——步骤 1:将问题转化为游戏
我们的第一步是把手头的业务问题变成一个游戏。为了让游戏人工智能有效,这种翻译的准确性是至关重要的。在实践中,这一步需要对问题有深入的业务理解。
像现实生活中的游戏一样,所有的商业游戏都有相同的关键元素来定义它们。有一个目标,球员,动作和规则,以及一个得分系统。让我们来看看维护游戏中的这些元素。
Photo by Robert Collins on Unsplash
比赛目标
游戏的目标是以可能的最佳方式及时分配资源给任务。资源是工作船和船上的维修人员。任务是从(不断变化的)工作范围组合中提取的活动。
选手,招式&规则
维护计划是一个单人游戏,人工智能代理与自己竞争。代理人做出的移动代表规划决策。它们是:
- 船会去哪些地方,按什么顺序?
- 船将在每个地点停留多长时间?
- 船上有什么船员?每次访问期间,剧组会完成哪些活动?
The AI Agent assigns work to workers, workers to a boat, and a boat to a specific location at a specific time.
这些决策需要遵守各种规则,例如
- 这艘工作船最多只能运送 50 名工人。
- 工作船需要每两周返回岸边更换一次船员。
- 工作船每天只能支持一个平台
- 夏季平台的工作时间为上午 8 点到下午 6 点,冬季为上午 9 点到下午 5 点。
评分系统
有了规则,我们就有了一个可以在计划游戏中合法行动的玩家。将动作串在一起对应一个维护计划。掌握这个游戏意味着学习如何做出获胜的招式。一系列获胜的棋步产生一个优化的计划。
为了确定如何获胜,我们需要引入一个评分系统。计分系统反映了玩家每一步棋的价值。也就是说,每一个计划好的维护活动——一次游戏移动——都会为玩家赢得点数。点数反映了在给定时间执行维护活动的价值。
Photo by Crissy Jarvis on Unsplash
当然,对于这个估值会有意见分歧。也就是说,不同的意见会产生不同的评分系统。例如,假设生产经理优先考虑最高生产平台上的工作。我们可以通过在这些平台上工作赚取额外积分的选项来适应这一点。或者,让我们说维护经理优先减少积压。我们可以通过奖励积压工作来解决这个问题。每一套观点对应一套分数,和一个要玩的游戏。每一个被掌握的游戏都对应着一个为驱动它的观点而优化的计划。
在此阶段,维护游戏的所有主要组件都已就绪。接下来,让我们解释我们如何开发人工智能来掌握它。
第二步:开发正确的人工智能代理来控制游戏
游戏人工智能作为一个研究课题最近有了巨大的发展。有大量关于前沿求解器架构的论文。也有相当多的开源代码被 DeepMind、 OpenAI 和其他人共享。这很棒,但这并不意味着为一个新游戏开发一个 AI 代理——像维护游戏——是微不足道的。用最好的算法来匹配一个游戏会变得非常棘手。开发通常是迭代的,游戏和求解器是并行调整的。
Photo by Lenin Estrada on Unsplash
一般来说,我们结合使用
- 深度强化学习(DRL),
- 树搜索,有时是随机的,
- 运筹学方法,以及
- 进化算法
这个列表并不详尽,但让我们对我们所研究的体系结构的广度有所了解。在开发我们的人工智能时,有几件事对我们很重要:
- 表现——做决策有多好?
- 速度 —它学习的速度有多快?
- 可扩展性 —它能处理多少选项?
- 易用性 —需要调多少音才能让它学会?
- 鲁棒性 —它有多敏感?
- 配合游戏 —够简单吗?我们不想拿出一把大锤来砸坚果。
在维护游戏中,我们观察到以下情况:
- 树搜索有潜力,但我们的选择空间太大,不能单独使用它们。
- 或者方法在小范围内非常有效,但在我们感兴趣的范围内就失效了。
- 深度强化学习是灵活的,但需要仔细调整以刺激学习。
- 进化算法不太适合这种排序游戏。
Non-exhaustive list of thoughts on solver architectures for a maintenance game
像普通游戏一样,商业游戏在设置和复杂程度上有很大的差异。因此,游戏人工智能代理往往也非常不同。一刀切的求解器架构方法是行不通的。
因此,我们使用许多架构的元素来构建我们的 AI 代理。就像 AlphaZero 结合强化学习和树搜索来掌握围棋一样。
对于这个案例研究,我们也开发了一种混合方法。在*顶层,我们使用了树搜索和深度强化学习。这些方法擅长于做大规模的决策(例如,我把船送到哪里,多长时间?).在的底层,*我们建立了一个运筹学引擎。它擅长于专门的排序(例如,我在任何给定的地点和持续时间执行什么工作?).这种组合架构速度快、灵活且高性能。通过结合其构建模块的优势,我们的解决方案优于单引擎解算器。
第三步:分析人工智能的制胜策略——并解决业务问题
质量决策需要对所有可行的备选方案进行全面的概述。以及对这些选择之间的权衡的理解。通过我们的游戏设置,很容易将不同的意见转化为可供选择的计划。
Photo by StartupStockPhotos on Pixabay
例如,有人可能会说在某些平台上每天 24 小时工作是可能的。(这是一个观点)这将极大地提高生产力。然后我们可以更新游戏规则*,*让 AI 机器人掌握这个新游戏,并审查由此产生的优化计划。
另一个例子:维护经理可能对他的积压工作感觉强烈。他可能会争辩说(另一个观点)减少积压是最重要的。我们可以在评分系统中反映这一点,让 AI 智能体再次进行比赛并掌握比赛。这就产生了另一个可供选择的优化方案。
游戏人工智能方法的美妙之处在于,任何数量的观点都可以使用相同的基础和衡量标准进行比较。对于每一组规则,人工智能代理都会产生一个优化的计划。比较优化的计划就是比较苹果和苹果。
那么,我们如何比较这些备选方案呢?
首先,我们与业务利益相关者一起定义关键指标。这些反映了对他们很重要的指标,并推动决策制定。有时这些是现有的指标,有时我们定义新的指标。
在本案例研究中,我们使用了以下指标:
- 安全关键范围完成的百分比
- 年底积压工作的规模(工作范围的数量)
- 产量面临风险
- 已执行的工作范围总数
其次,我们定义需要评估的场景的。这些代表要玩的优化游戏的集合——根据需要,可以多达数千个。
场景和它们的度量标准充分洞察了意见和结果计划之间的权衡。这使得最终决策者能够做出明智的质量决策。
在本案例研究中,我们发现与现有的规划理念相比,可以规划多达 30% 的工作。正常的业务改进计划很少会带来两位数的改进。此外,在能源行业,两位数代表巨大的货币价值。
30%的改进对 T2 来说是一个巨大的进步,可以扭转积压订单逐年增加的趋势。但是,30%是一个惊喜吗?不,当你想到团队用来玩如此复杂游戏的过时工具集时,就不会了。我们的改进至少部分是由当前的低标准推动的。但是这个标准是真实的——它是规划者每天都要面对的。他们不应该这么做。
更换过时的工具集,并重新设计流程
在我们的简介中,我们建议把你复杂的商业问题带到绘图板上。我们力劝您用 21 世纪的工具取代陈旧的 Excel 规划表。挑战自我,重新设计和改进工作流程和方式。并围绕最新技术重新设计它们。
我们希望这个案例研究是变革的动力。大多数复杂的商业决策都是基于有缺陷或不完整的分析。如果你看着自己的企业,不知道如何改进,那么我们希望这篇文章能激发你的灵感。
Photo by Ben White on Unsplash
我们很想听听你的看法。请随时联系 info@whitespaceenergy.eu 或在 LinkedIn 上发表评论。