机器学习和深度学习模型的训练后分析和量化
虚拟助理项目
一个极其重要但有时被忽视的概念
建立和探索机器学习以及深度学习模型是我喜欢做的事情。我选择一个项目并开始着手做。有些只是业余爱好者级别的项目,有些是具有真实用例和优势的项目。我有一个中等的 GPU 和一个中等的处理能力的系统。所以我所关注的只是训练和确保模型在我的电脑上工作和运行。然而,这并不是故事的结尾,有时我最终会错过一个极其重要的概念——模型的训练后分析。
这种培训后分析是什么,为什么如此重要?
训练后分析有时也称为事后分析,在模型优化中起着重要作用。构建和训练的业务模型需要优化,以便在低端设备和嵌入式系统(如 raspberry pi)上有效工作。构建和评估模型的主要组件之一是检查模型的预测能力和性能质量。一个更重要的概念是理解你的机器学习或深度学习模型的局限性。克服这些限制是成功模式的关键。
在本文中,我们将讨论如何针对特定用例有效地量化我们的模型。我们将主要关注深度学习模型的局限性、改进和量化的讨论。首先,我们将讨论使用 TensorFlow 的模型的训练后量化到底是什么。我们将学习如何在各种优化技术的帮助下,使我们的模型在所有平台上更加动态和有效,以达到更广泛的目标受众。然后,我们将了解可用于改进各种模型的限制和技术。我们对这个项目的主要参考将是 TensorFlow 博客的训练后量化和虚拟助理项目系列,这是我做的。你可以在下面提供的链接中查看这两个,尽管不是强制性的。
训练后量化是一种转换技术,可以减少模型大小,同时还可以改善 CPU 和硬件…
www.tensorflow.org](https://www.tensorflow.org/lite/performance/post_training_quantization) [## 虚拟助手项目——走向数据科学
阅读《走向数据科学》中关于虚拟助手项目的文章。分享概念、想法和…
towardsdatascience.com](https://towardsdatascience.com/tagged/virtual-assistant-project)
**注意:**虽然不是必要条件,但我强烈建议观众查看我以前在智能面部锁定系统、下一个单词预测和虚拟助手系列中创新的使用一维卷积层的聊天机器人项目上的项目,因为这将有助于以更直观的方式掌握一些概念。
训练后量化:
在您的系统上有效运行的模型可能无法在低端设备上有效运行相同的程序/模型。这可能是由于目标设备的硬件限制。在这里,训练后量化可以帮助改进目标设备的算法和模型的优化。训练后量化是一种转换技术,可以减少模型大小,同时还可以改善 CPU 和硬件加速器的延迟,而模型精度几乎不会下降。当您使用 TensorFlow Lite 转换器将其转换为 TensorFlow Lite 格式时,您可以量化已训练的浮点 TensorFlow 模型。TensorFlow Lite 转换器在 Raspberry Pi 等设备上非常有用,可用于优化对象检测模型、人脸识别模型等。对象检测项目可以使用 TensorFlow Lite 进行优化,对 android 或 ios 设备也有很大的影响。你可以在这里查看这个很酷的项目。
下面是帮助您为模型选择最佳训练后量化和优化方法的框图:
来源:图片来自 tensorflow
简而言之,各种训练后量化方法如下:
动态范围量化
这种最简单的训练后量化形式。它只将权重从浮点静态量化为整数,精度为 8 位。
全整数量化
通过确保所有模型数学都是整数量化的,您可以进一步改善延迟,减少峰值内存使用,并与纯整数硬件设备或加速器兼容。
浮点量化
您可以通过将权重量化为 float 16(16 位浮点数的 IEEE 标准)来减小浮点模型的大小。
基本上,在这 3 种训练后优化方法中,我们确保我们的模型设计尽可能高效和优化。我们必须确保,一旦完成了必要的优化更改,该模型将保持高效的性能,同时在精度和损失等参数方面保持或多或少相同的有效性。
其他直观的例子来理解模型的局限性以及可以做出的重大改变和改进—
1。人脸识别模型:
所以,你成功地建立了一个面部识别模型,使用了像迁移学习这样的深度学习技术,类似于这里的。整个模型在训练数据上表现得非常好。在对训练和验证数据进行测试时,产生的结果仍然非常好。该模型在大多数情况下都能按预期运行。然而,该模型存在一些局限性。让我们来理解和看待人脸识别模型的这些局限性。让我们也看看在以下方面可以作出的改进。
局限性:
- 人脸识别模型不能在低质量的相机上表现得很好。摄像机质量必须至少一般,才能正确捕捉实时人脸并授予访问权限。
- 周围的照明不能太暗。它至少需要适度的亮度。否则,该模型将在实时分析过程中出现检测和识别人脸的问题。
- 我们使用 Haar cascode _ frontal face _ default . XML 来检测人脸。这对于在某些角度识别面部可能是有问题的,并且面部的检测可能不能如期望的那样工作。
改进:
- 可以使用一次性学习和训练方法来减少每个面部的训练时间。由于当前模型只识别一张脸,如果我们想添加更多的脸,我们需要重新训练整个模型。因此,需要考虑一次性学习等方法来提高模型的质量和性能。
- 可以找到 haarcascade _ frontal face _ default . XML 的替代方案来提高在任何特定角度检测面部的准确性。另一种方法是为正面和侧面创建一个定制的 XML 文件。
- 为了使其在嵌入式设备上运行,可以对内存约束进行更改,如转换为 tf.float(32 ),也可以通过考虑使用 tflite 对模型进行更改。
2.下一个单词预测:
下一个字预测模型能够在模型上实现体面的损失。下一个单词模型是一种预测搜索类型的方法,可用于 google 搜索。这些也可以用来检测用户的某些模式,并可以用于电子邮件和短信的下一个单词预测任务。该模型尽管还不错,但仍有缺陷,并且存在改进下一个单词预测模型中存在的缺陷的方法。让我们看看所有的限制和可以改进整个模型的变化。
局限性:
- 下一个单词预测仅限于几个单词,并且不能非常准确地对较长的句子进行预测。在这个行业工作时,这不是最好的情况,因为可能会有更长的刑期。
- 由于使用了 LSTM 层,与其他模型相比,该模型需要更长的时间来训练和执行。在 ram 和 GPU 能力较低的小型嵌入式系统中,这种较长的训练可能是一种限制。然而,一旦在更好的系统上训练,部署就不是一个大问题了。
改进:
- 对于自然语言处理,甚至存在零拍和一拍的学习方法。可以使用相同的方法来更好地训练模型,以提高整体性能,并避免重复的训练过程,这在一些现实生活的应用程序和场景中可能是一个真正的大障碍。因此,一次性学习是在其他培训能力较低的嵌入式系统中部署和工作的一个很好的选择。
- 像 GPT-3 模型这样的高级训练算法对这些预测任务非常有效。
- 可以使用更多预处理方法,也可以测试更多替代方法,以获得更好的精度、更低的损耗,并实现整体高性能。
3.聊天机器人模型:
聊天机器人模型是一个基于文本分类的创新聊天机器人,可以实现整体良好的准确性和减少损失。聊天机器人模型能够在我们使用的整个数据集上表现得非常好。然而,即使是我们的聊天机器人也有一定的局限性和问题。我们将在下一节中介绍它们。但是基于 conv-1D 架构的整体预测系统和聊天机器人在 witty.txt 数据集上表现良好,可以用于类似的数据集。该模型对最常重复的问题的唯一值进行分类。
局限性:
- conv-1D 聊天机器人模型的主要限制之一是,它是一种基于分类的聊天机器人,而不是一种生成式建模方法。这种分类方法可能会导致重大挫折,因为在某些语言中可能会有问题,比如当用户不太精通英语时的语义问题。这可能会产生误导,聊天机器人可能不会产生预期的结果。
- 由于它不是一个完全完美的模型,所以有时会容易出错。它可以预测用户不满意的结果,这可能是工业应用的一个问题。
改进:
- 可以使用更多的预处理和自然语言处理的方法来达到更高的精度和减少模型训练的损失。这也可以改善模型的整体预测。
- 像 GPT-3 模型这样的高级训练算法甚至对对话型聊天机器人也非常有效,这是训练高质量聊天机器人的一个很好的替代方法。
- 可以使用其他方法,如基于分类的迁移学习、注意的序列到序列模型,或者甚至用于训练的某些一次性学习方法。
威廉·艾文在 Unsplash 上的照片
结论:
体验机器学习和深度学习模型的乐趣总是很酷,也是它们最棒的部分。在探索这些模型时,如果您确实希望将它们转换成现实生活中的用例,使其能够惠及大量的人,那么模型的训练后分析和训练后量化对于提高效率、质量和紧凑性以将项目部署到更广泛的受众变得极其重要。训练后量化还使我们能够在量化模型上获得几乎相同的精度,类似于在原始模型中获得的精度。这简化并使我们的生活变得容易多了!
谢谢大家坚持到最后。祝你在机器学习和深度学习模型的探索和量化过程中度过愉快的时光。请随意查看我之前提到的所有项目,我希望你们都喜欢这篇文章,并祝你们有美好的一天!
今年,PostEra 正在使用机器学习制造一种新冠肺炎药物
将谷歌翻译启发的机器学习应用于化学
声明:我是 Cortex 的维护者,这是一个开源的机器学习工程平台,用在下面提到的一些项目中。
最近,一家名为 PostEra 的初创公司宣布,他们打算“在年内”开发一种新冠肺炎疗法,作为开源 moonshot 的一部分。
自然,这一宣布引起了一些兴奋。虽然 PostEra 肯定不是第一家做出雄心勃勃声明的生物技术/机器学习初创公司,但这次有一些特别令人兴奋的事情。
虽然我们可能已经习惯于宣布公司 X 将做不可能的事 Y 因为“机器学习”——其细节从未得到解释——PostEra 的宣布是不同的,因为它:
- 分离出药物开发中的一个特殊瓶颈。
- 把阻断器设计成一个工程挑战。
- 提出了一种新颖的机器学习解决方案来应对这一挑战。
看他们的发布公告,感觉不像是 AI 福音或者炒作。感觉就像*工程,*机器学习只是堆栈的另一部分。
因此,PostEra 在一年内制造新冠肺炎治疗的目标,虽然可能是雄心勃勃的,但在某种程度上感觉是严肃的,这是许多登月者所没有的。PostEra 没有等待机器学习的突破,他们没有押注于投机性技术。他们正在推广一个流行产品——Google Translate——所使用的成熟方法,以解决一个新领域的类似问题。
为了更好地解释我的意思,让我们深入了解一下 PostEra 是如何工作的。
将化学合成理解为翻译
PostEra 在药物开发中解决的问题是分散的:
对于任何给定的化合物,都有许多不同的制造方法,并且没有严格的、确定性的模型来确定哪种方法是最好的。
为了给出更多的上下文,你可以简单地在白板上画出一个分子:
氧原子到这里,在那里插入几个键,瞧——分子。然而,在现实生活中,我们不能如此精确地剪切和粘贴原子。
为了创造一种新的分子,化学家采用更简单的分子,通过化学反应转化它们,这被称为“移动”然后,新分子通过额外的移动进行转化,直到最终产生目标分子。形成一个分子的一系列运动被称为“路线”
化学家主要通过有知识的试错法来预测移动的结果和路线的可行性。这很贵,因为化学。
PostEra 所做的是建立一个平台,使用机器学习来即时预测,给定一个拟议的分子,最可行的合成路线:
来源: PostEra
为了理解该平台如何工作,将化学合成问题分解成更抽象的术语是有帮助的:
- 你需要将一组对象 A 转换成一个单独的对象 b。
- 您可以通过一组预定义的功能(化学/物理反应)组合对象来转换它们。
- 你需要创建一个模型来对许多理论上似乎合理的函数链的可行性进行评分。
如果你把这个问题的化学背景去掉,它就变成了工程师们熟悉的东西——一个翻译问题。
假设你的任务是设计谷歌翻译。您可以像这样确定问题的范围:
- 您需要将一组对象 A 转换成一个单独的对象 B,即一个等价的英语短语,在本例中,这个对象是法语单词“乐惠·德·诺克斯·德·可可,”。
- 您可以通过以多种不同方式应用翻译功能来转换对象。乐惠·德·诺伊克斯·德·可可可能是“椰子油”或“可可坚果油”
- 你必须给各种翻译打分,没有明显的基于规则的系统。“椰子油”是对的,但“椰子的坚果油”不是不对。
来源:谷歌翻译
从根本上说,这是同样的问题,Google Translate 中使用的相同的序列到序列方法应该适用于 PostEra。
经过适当的训练,PostEra 的模型应该能够生成分子之间可能的“翻译”树,为树中的每条路线分配可行性分数,然后在树中搜索最可行的翻译——这正是所发生的事情。
然后,可以将这一系列模型部署为单个 API,可从 PostEra 前端查询,以创建药物化学即服务平台。
波斯特拉正在努力实现登月,而不是创造奇迹
需要强调的是,PostEra 的 moonshot 唯一雄心勃勃的是它的时间线。
基本技术已经被证实。机器翻译作为一个领域已经建立了很长时间,PostEra 的创始团队甚至在公司成立之前就发布了第一个在预测化学反应结果方面胜过人类化学家的模型。
这也是为什么 ML 月球探测器如此令人兴奋的部分原因。底层产品不是推测性的——它是功能性软件,它是机器学习工程如何以真实、有形的方式改变技术的又一个例子。
注来自《走向数据科学》的编辑: 虽然我们允许独立作者根据我们的 规则和指导方针 发表文章,但我们不认可每个作者的贡献。你不应该在没有寻求专业建议的情况下依赖一个作者的作品。详见我们的 读者术语 。
PostgreSQL 13 特性精华
数据工程
PostgreSQL 最新版本中的索引优化、增量排序、并行清空和更多最新特性
J 就在几周前,我写了关于 MySQL 8.0 在 Google Cloud 上正式发布,在所有主要云平台上完成它的旅程。MySQL 8.0 已经问世一段时间了。开源数据库社区急切地等待 PostgreSQL 的主发布版本 13。PostgreSQL 是仅次于 MySQL 的第二大流行的开源数据库,由于其固有的可扩展特性,它在所有地区和行业都被越来越多的人采用。随着 AWS 红移走上 PostgreSQL 路线,PostGIS 中的世界级地理空间支持和令人惊叹的核心功能集,PostgreSQL 几乎不是一个可以忽略的数据库。
一周前,9 月 24 日,PostgreSQL 13 发布了。这个新版本有很多特性,但我们只介绍了 PostgreSQL 官方版本中列出的一些主要特性。
平行分度真空
清空是一个缓慢而乏味的过程,但与其他数据库不同,PostgreSQL 使用它来回收磁盘上任何未使用的空间。当 vacuum 在任何给定的表上运行时,在该表上创建的索引也会被清空。PostgreSQL 13 引入了一个特性,可以并行清空一个表上的多个索引。
可以使用名为**max_parallel_maintenance_workers**
的数据库变量设置并行化的程度。这应该设置为表拥有的索引数。
这一点,再加上许多其他索引改进,使得这个版本的 PostgreSQL 13 更有吸引力。也许优步终究会考虑搬回 PostgreSQL,开个玩笑!
注:请注意,autovacuum 尚不支持此功能。这里列出了对 autovacuum 的一些其他改进。
为查询优化器和规划器提供更好的统计数据
我们所知道的关于优化器的一件事是,如果他们有更新和更好的关于表、索引、分区等的统计数据,他们会优化、计划和重写更好的查询。几年前,随着 PostgreSQL 10 的发布,它引入了用户定义的自定义统计数据的概念,名为扩展统计数据。使用扩展的统计数据,用户可以创建自己的统计数据来定义高级关系和依赖关系,以捕获行为统计数据并将其提供给优化器。
在 PostgreSQL 13 中,我们看到了更多的改进。以前,规划器只能使用一组定制的统计数据来规划和优化查询。用户可以通过OR
、IN
或ANY
子句使用多个统计数据。
增量排序
在这个主要版本之前,如果您在一个表中有一个针对(column_1, column_2)
的索引,它将自己具体化为一个 B 树,并且您发出一个使用(column_1, column_2, column_3)
排序的查询,PostgreSQL 不会使用现有的索引,该索引已经对 where 子句中的前两列的数据进行了排序。
在这个新版本中,这个问题已经得到了解决。现在,PostgreSQL 不会对已经为列column_1
和column_2
排序的数据重新排序。在亚历山大·库兹曼科夫的演讲中了解更多。
使用重复数据删除的 b 树成本优化
考虑一个您想要索引的表列,但是它有许多重复的值。在该列上创建索引时,所有值都绘制在索引的 B 树结构上。很多重复出现在你的索引中。这导致索引很大,并且索引的处理时间也很长。
主键或唯一索引 显然不会发生这种情况——请参考Andrew Kozin对这篇帖子的评论,了解为什么这句话不成立。
非唯一列上的索引对于聚合查询非常重要。为了从这些查询和数据库中获得更好的性能,PostgreSQL 13 引入了一个新的重复值删除过程。PostgreSQL 现在只保存对列值的引用,而不是存储所有重复的值。
重复数据删除过程显然节省了大量空间,因为这是一个常见问题。节省空间的同时,也节省了在更大的索引上花费的额外处理时间。在这里了解更多关于 B 树实现的信息
本节涵盖了可能对高级用户有用的 B 树索引实现细节。看…
www.postgresql.org](https://www.postgresql.org/docs/13/btree-implementation.html#BTREE-DEDUPLICATION)
聚合的性能优化
PostgreSQL 10 引入的另一个特性是散列聚合。Postgres 在聚合时有两个选项——散列或组。如果哈希表可以放在内存中,则使用哈希聚合。在 PostgreSQL 13 之前,如果哈希表不适合内存,PostgreSQL 只会选择组聚合。但是现在,在这个版本中,如果哈希表不适合内存,它将溢出到磁盘。
对于那些已经在使用 PostgreSQL 的人来说,如果你打算迁移到 PostgreSQL 13 ,这里有一篇关于 Percona 博客的好文章。
PostgreSQL —出自马嘴
在 Unsplash 上由伊尼基·德尔·奥尔莫拍摄的照片
阅读材料汇编 PostgreSQL 专家的书籍和博客
这篇文章的灵感来自于我一年多前写的这篇关于 MySQL 的广泛的文章。在所有四个主要的关系数据库上工作过之后,我阅读了大量的官方文档、博客、白皮书和书籍。这个书籍和博客的集合是我在 PostgreSQL 上读到的所有内容的精华**。它可能不像 MySQL 那样广泛和准确,因为我没有广泛地使用 PostgreSQL。但是,不管怎样,这就是了。**
要读的书
只有一本书是我广泛使用过的关于 PostgreSQL 的内容,所以我建议这样做。我的大部分知识来自博客和我在 PostgreSQL 领域关注的人——PostgreSQL:Up Running,第三版,作者 Regina Obe 和 Leo Hsu 。可能会有更多值得阅读的 Postgres 原创作者和开发者的书。
要关注的博客
戴夫的 Postgres 博客
作为 EnterpriseDB 的核心团队成员之一,Dave 对 Postgres 内部发生的事情有着深刻的见解。尽管他的博客自去年 7 月以来一直处于休眠状态,但如果你想深入了解 Postgres,还是有一些博客帖子可供使用。当 VoltDB 在 2010 年第一次出现时,Postgres 和 VoltDB 的比较见此。顺便说一下,戴夫被称为“T21”。
宰泽的博客
长期 Postgres 用户,Zaiste 博客作为一个技术用户,而不是来自内部团队的人。他的一系列名为《大忙人入门》的帖子非常棒。在这一点上,他确实有一本为忙碌的人准备的 Postgres 初级读本——只是为了让你开始使用 Postgres。没什么高级的。他是 Nukomeet 、 RuPy Conf 和 PolyConf 的创始人。
安德鲁·邓斯坦的 PostgreSQL 博客
作为 PostgreSQL 的核心提交者,Andrew 发表了关于 PostgreSQL 的特性、问题和性能技巧的文章。这个博客已经不活跃很多年了,但是它仍然有非常有用的信息,这些信息来自真正了解内部的人。
Bruce Momijan 的 PostgreSQL 博客
他是 EnterpriseDB(商业 PostgreSQL)的副总裁,从 2008 年开始写作。如果你想专攻 PostgreSQL,他的文章简短扼要,非常有用。他每周发布几次帖子,主题涉及从理解预写日志的内部到复制再到 SQL 查询的方方面面。
乔希·伯克思的数据库汤
他从事数据库工作已经超过 20 年了。他不怎么发表关于 PostgreSQL 的文章,但无论何时他发表,通常都是关于一些新特性或性能优化技巧。
米歇尔·帕奎尔的博客
作为一名 PostgreSQL 提交者,他已经为许多不同的项目做出了贡献。他在会议上发言,并不时在博客上发表关于数据库的文章。我很喜欢 PostgreSQL 12 中的新特性,可以选择是否实现 CTE。cte 广泛用于数据工程和分析领域。这无疑会对查询性能产生重大影响。
斯蒂芬·费科特的博客
这个博客主要是关于管理——备份、恢复、复制,特别是许多不同的 Postgres 扩展,如pg _ back sleeve。
Hubert Lubaczewski 的博客
除了 Postgres 内部的大量知识、新特性和最佳实践,这个博客还有最好的在线查询计划可视化工具。你可以去这里了解一下。
克雷格·克斯廷斯的每周时事通讯
对于 Postgres 爱好者来说,这是一个阅读 Postgres 的好地方。这份时事通讯经过精心策划,涵盖了数据库的所有方面——软件开发、数据库管理、分析、扩展等等。查看最新一期的新闻简报。
德米特里·方丹的博客
这篇博客来自《PostgreSQL 的艺术》一书的作者。我还没有抽出时间来读这本书,但打算很快读。Dmitri Fontaine 是 PostgreSQL 的长期撰稿人。
罗伯特·哈斯的博客
最后但同样重要的是,来自 EnterpriseDB 首席架构师、长期 Postgres 贡献者的关于 Postgres 的最全面的博客之一。数据库一点也不简单。它们是复杂的软件,需要指导和调整,这样你就可以充分利用它们。这个博客对任何想深入研究 Postgres 的人来说都是很好的文献。我已经断断续续关注这个博客很多年了。
我希望你发现这个信息有价值。虽然 PostgreSQL 文档非常简洁,但是光靠文档并不能教会你一切。这些博客中的大部分填补了精通 PostgreSQL 实际需要的东西和文档中提供的东西之间的空白。
PostgreSQL:秩函数介绍。
如果您尝试过分析一些应用程序数据库,您可能会看到如下内容。
卢克·切瑟在 Unsplash 上拍摄的照片
每个用户都可以在应用程序中发布多个帖子,我想一个超级简化版的 twitter 数据库应该是这样的。
数据分析的问题来了。
我们如何才能发现每个用户第一次发帖的时间和内容?这种问题很常见,当你分析应用程序数据时,你想知道每个用户的第一个活动。通过实现这一点,我们应该得到如下表格。
您可以看到,现在我们提取了三个帖子,它们是用户从上一个表中首先创建的第一个帖子。该提取可以作为获得如下服务洞察的基础
- 用户创建第一个帖子需要多长时间?
- 用户倾向于在第一篇帖子中使用什么样的词?
增强用户采取主动是激活服务的关键,所以你应该知道如何做到这一点。
编写 SQL
我们可以将所需的程序总结如下。
- 按
user_id
分组数据样本。 - 按每组中的
id
降序排序。 - 从每组中提取 id 最小的样本。
要仅使用 PostgreSQL 实现这一点,有一些可能的方法,但今天我们将使用其中实现的一个窗口函数, RANK 函数。使用这个,我们可以简单容易地完成这个分析。该函数将用于分组和排序方法的列作为参数,并给出每个组的排名。它的语法是这样的。
RANK() OVER (
[PARTITION BY partition_expression, ... ]
ORDER BY sort_expression [ASC | DESC], ...
)
如你所见,我们将“如何分组”交给PARTITION BY
,将“如何排序”交给ORDER BY
。似乎很简单,对吗?让我们把这个排序函数应用到我们的问题中。
select
*,
rank() over (partition by user_id order by id)
from
posts
PARTITION BY
使用user_id
将数据分组到每个用户中,ORDER BY
id
对每个用户组中的帖子进行排序。通过执行这个 SQL,我们可以获得下表。
您可以看到每个用户组的排名数字,为了从转换后的表格中只提取第一篇文章,我们可以利用where
来约束rank = 1
。
select
*
from
(
select
*,
rank() over (partition by user_id order by id)
from
posts
) as tmp
where
rank = 1
这个 SQL 最终给出了我们想要的东西。
我希望您现在可以看到,使用 PostgreSQL 的 RANK 函数提取数据库中每个用户的第一篇文章是多么容易。基于这些提取的信息,你可以运行大量的分析来更好地理解你的用户。
医疗人工智能的上市后责任
metamorworks/Shutterstock.com
第二部分——在医疗人工智能商业化方面,行业应该做些什么
在本系列文章的第一部分中,我描述了 FDA 和行业之间关于 FDA 对医疗人工智能的适当监督程度的紧张关系。我解释说,目前看来 FDA 可能会要求国会给予更多的上市后权力,以便能够以更深入的方式监督医疗人工智能的商业化,尽管事实上 FDA 已经拥有相当大的权力。
在第二部分,我提出了另一种选择。我建议行业采用最佳实践来确保病人得到最好的护理,可以说是自我调节。在第三部分,我将把 FDA 的监督限制在它现有的法定权限内。
在商业化阶段,行业应在四个方面积极采取措施,以确保其基于人工智能的医疗设备的安全性和有效性。
A.追求增强的上市后警惕性
将自适应特别是自主的人工智能算法部署到市场上需要部署它们的公司大大提高上市后的警惕性。根据定义,自适应算法在使用时进行调整。作为质量保证和风险缓解的问题,也作为持续改进产品的方法的研究问题,公司应该密切监控其算法在市场上的性能。
应该怎么做?
在回答这个问题之前,重要的是要理解为什么监控很重要。识别可能出错的事情告诉我们什么样的监控是必要的。
这里我大量借用了奥姆·德什穆克的一篇优秀的文章“部署你的机器学习模型?以下是你需要知道的后期制作监控”2019 年 10 月 7 日。
下面是几个不同的场景,它们会显著改变已训练算法的性能。
在域中但看不见数据。我们开始意识到每个人是多么的不同。个性化医疗基于我们对人类基因组的深入了解,以及种族、民族、性别等因素如何对诊断和治疗决策产生重大影响。这使得训练集具有来自算法最终将使用的所有群体的数据变得尤其重要。例如,很有可能一个训练有素的算法可能不包括美洲土著人口,当该算法用于这些人口时,其性能可能会下降。从某种意义上说,在这种情况下的训练会对美国土著人有偏见。
输入数据不断变化的性质。自适应算法必然需要新数据。并且很容易预测新数据可能不总是以与算法最初被训练的数据相同的方式被创建。如果自适应 AI 分析放射图像,如果产生图像的技术发生变化,这些变化可能会导致自适应算法以不同方式解释数据。很容易想象技术引发的变化,以及数据生产中的社会变化。医疗专业人员甚至患者自己或其护理人员收集数据的方式可能会改变,从而影响算法解释数据的方式。那些花大量时间清理数据的人明白,从字符串转换为整数这样的小事会对算法的运行产生深远的影响。
**数据解释的变化。**现有数据的含义会随着时间而变化。即使数据点本身不会改变,但它们的意义会因社会或环境因素而改变。在医疗环境中,可以想象电子健康记录中的单词的含义会随着医生和其他健康护理人员的实践的改变而逐渐改变。随着时间的推移,医生可能会使用相同的词语,但有了新的含义。这不同于上述数据发生变化的问题。
**部署在意想不到的环境中的机器学习系统。**这在医疗技术领域非常常见,因为医生和其他医疗保健专业人员会尝试现有技术的不同用途。你可以想象,原本打算用于追踪流感症状的软件,在某些医生的手中,可能会被用于追踪 COVID 19 症状。随着医疗专业人员决定探索其他领域的实用性,这意味着算法功能所基于的数据可能会发生变化,从而对产品的整体性能产生影响。
**缺失数据。**对于使用各种数据的算法,某些数据流可能会被切断或中断。
**模型漂移。**如果不关注原因,模型可能会因为各种原因而表现不佳。
**恶意的行为。**一旦人工智能设备处于“野生状态”,恶意行为者可能会故意引入数据集,故意扭曲设备的行为,这可能比传统的“黑客攻击”更难检测到(例如,“闯入”系统并改变参数)。
关键是我们需要明白,当一个算法在现实世界中使用时,会发生影响性能的事情。不难想象。
那么公司在上市后监管方面到底应该怎么做呢?也许我们都同意的一件事是,一种尺寸不适合所有人。然而,这些软件开发人员可以遵循一些通用原则,以确保他们能够充分地监控他们的产品。
概括地说,我们可以把监控分为两种不同的类型:主动的和被动的。先说主动。
1.主动模型监控
Deshmukh 先生建议我们根据一组关键指标持续跟踪机器学习模型的性能,并生成特定的基于事件的警报。虽然德什穆克先生笼统地谈到了这个问题,但我想重点谈谈医学背景。
这项技术的目标是“识别哪些输入样本明显偏离了训练数据中的模式,然后让人类专家仔细检查这些样本。”问题是,感兴趣的模式在很大程度上取决于数据的领域、问题的性质以及所使用的机器学习模型。
假设我们有一个算法,它正在观察医院里一个病人的 10 种不同的生命体征,着眼于识别这些生命体征何时达到表明病人正在变得败血症的程度。实现这种监控的一种方法是统计地查看这些生命体征如何正常流动,并设置统计分布或其他参数,如果超过这些参数,将向算法开发者发出警报。请注意,这些警报不同于用于确定特定患者何时需要医疗护理的警报。这些是基于统计数据的警报,表明算法正在分析的数据类型发生了一些变化。这样的警告将会给为开发人员工作的人一个机会去调查是否有需要更新或纠正的地方。
除了检查统计异常之外,我们可能会进行其他形式的实时数据检查,例如,确保模型仍然接收到它需要的所有不同的数据。这对于分类变量和数值变量都是正确的。该公司可以检查数据,以确定在活动模型中是否存在任何特征依赖性。
该公司还可以在客户的配合下进行模型预测和性能测试。在这种情况下,公司将需要从最终用户那里获得有关预测事件是否会发生的数据。如果软件开发人员可以协商访问这些数据,公司就可以不断地评估其模型的性能。这在医学上通常是困难的,因为后果可能是几个月甚至几年之后。然而,在某些情况下,预期事件很可能在短时间内发生(或不发生),因此可以持续评估性能。如果公司无法获得访问权限,那么简单地跟踪预测的总体分布以查看该分布是否会随时间而变化是很重要的。
2.反应式模型监控
反应式模型监控非常类似于医疗设备制造商已经在做的事情。根据法律要求,这些制造商拥有收集和分析用户向公司报告的问题的系统。然而,在人工智能环境中,反应式模型监控可以在更系统的基础上进行。
客户可能会报告不准确的结果。这些中的一定数量是可以预料的。很可能,在模型的训练和验证之后,该公司了解到该模型在一定的统计精度水平上表现得不够完美。因此,公司知道有时模型会产生不正确的预测。
虽然这些客户投诉在意料之中,但它们也创造了持续改进的机会。通过收集和分析这些报告,公司可以寻找系统的根本原因,以及在未来提高准确性的方法。
话虽如此,这也是很有可能的,公司需要注意这样一个事实,即他们不应该通过过度适应来追求业绩。很容易想象,一家公司可能会通过善意的行动,认为它正在根据对某一组不准确预测的反馈进行改进,但无意中它损害了算法的未来整体性能,降低了它在以前表现良好的领域的准确性。
毫无疑问,公司可以从失败中学到很多东西,持续分析失败的趋势以及失败的总体水平是一项富有成效的工作。挖掘根源非常重要,而且说起来容易做起来难。
如果需要对算法进行实质性的修改,该公司需要让 FDA 重新参与讨论,因为没有 FDA 的事先审查和批准,对通过某个阈值的产品的修改是不允许的。这可以包括,例如,算法的重要再训练。
B.与用户共享信息
许多术语都涉及到人工智能可理解性的一般主题。人们谈论“透明度”、“黑盒”、“可解释性”、“可解释性”等等,而我自己的感觉是,这些词并没有被一致地使用。事实上,在我职业生涯的过去几年里,我在如何使用这些词上并不一致。所以我现在想用我自己的语言说得更清楚些。
关于 FDA 法律,我认为有两个密切相关的概念也是可以清楚区分的。我选择下面的词来描述这两种不同的想法有点武断,因为坦率地说,没有准确的英语标签可用。我将把这些区别建立在 FDA 法律中的重要原则上。
1.结构
a.透明度
FDA 的法律关注的是在用户决定产品是否适合特定用途时提供给他们的信息。FDA 高度重视这一决定,因为正确使用 FDA 监管的产品是其安全性和有效性的关键决定因素。事实上,FDA 最常提起的执法行动之一是对标签外促销的索赔,这是一项法律指控,即销售者提供的信息鼓励产品的使用范围超过 FDA 授权的范围。
需要明确的是,医疗保健专业人员可以随心所欲地使用产品。FDA 的主要关注点是确保医疗保健专业人员从制造商处获得真实的、无误导性的信息。然而,在 FDA 的世界观中,这也意味着将制造商提供的信息限制在 FDA 合法授权的范围内。
我将把人工智能开发者分享公司与这一使用决策相关的信息的义务称为“透明度”。我在这里使用“透明”这个词,因为在这个上下文中,透明意味着分享你所知道的。我稍后会解释,这与开发新信息以解决知识缺口的义务形成对比。透明度在很大程度上是被动的,不需要难以收集的信息。字面意思是不要把信息留给自己。
与任何医疗设备一样,对于基于人工智能的医疗产品,产品的安全性和有效性信息是潜在用户在决定产品是否适合给定的计划用途时需要了解的重要信息。但与其他医疗设备不同的是,随着算法根据新数据进行调整以及性能的发展,这些信息将不断变化。因此,与传统医疗设备相比,人工智能开发人员需要保持这些公共信息最新。
b.可解释性
除了使用前的适宜性决定,FDA 法律中还有一个相对较新的重点,即医疗保健专业人员是否能够理解软件生成的关于特定患者使用后的建议的基础。这一新的关注点来自 2016 年的一项法律,即《21 世纪治愈法案》。该法案的第 3060 条明确指出,任何授权医疗专业人员独立审查诊断或治疗建议的基础的软件,只要该专业人员不必主要依赖软件建议来做出关于单个患者的临床诊断或治疗决定,则不受监管。在这个世界上,FDA 的规定可能意味着几年的延迟和几十万美元的额外费用,这一条款创造了相当大的激励,以确保用户可以审查建议的基础,而不是依赖它。
我将通过确保用户能够充分理解特定建议的基础来称之为避免 FDA 监管的机会:“可解释性”正如我所使用的术语,可解释性不同于透明性,因为透明性是被动的,专注于使用前的适用性决策(实际上是共享已经存在的信息),可解释性在人工智能的情况下通常要求在算法产生结果后主动创建新的信息。我小心翼翼地措辞以关注结果,认识到可解释性的基础显然必须在软件使用之前就建立起来。
法令并不局限于利用人工智能的软件,对于专家系统来说,可解释性更容易实现,例如,仅仅应用临床指南形式的标准知识来提出建议。非人工智能中的可解释性通常意味着简单地构建软件,以便用户可以轻松地回到知识的原始来源,理解推荐的基础。不幸的是,在人工智能的世界里,解释是极其困难的。
换句话说,可解释性是事实之后的信息,我应该考虑评估我是否相信算法得到了正确的答案。如果算法说我 Brad 很可能有 COVID 19,我该相信吗?
患者和临床医生可能会有关于人工智能生成的建议的基础的具体问题,包括以下内容:
- 算法是如何得出这个结论的?
- 在我的特殊情况下,算法考虑了哪些信息?
- 该算法最依赖什么症状和生理测量作为其结论的基础?
- 为什么算法在得出关于我的结论时如此重视这些症状?
- 我有没有不符合诊断的症状,因为某些原因被忽略了?
- 算法以最终推荐的形式考虑并拒绝了哪些可能性?
重要的是要明白透明性和可解释性是表亲。良好的透明度为更有效的可解释性奠定了基础。但是,虽然它们是相关的,但它们显然是不同的。它们服务于不同的目的,具有不同的监管后果,并且以截然不同的方式产生。
当然,特别是在过去的五年里,在医学人工智能的可解释性方面有大量的研究。该研究面临的核心挑战是,人工智能算法不会像人类一样思考。人类寻找因果关系,而算法寻找关联。在这种意义上,仅仅叙述算法发现 X 和 y 之间的关联是不够的。人类需要更深入的解释,理想地解决因果关系或至少上述问题。
重要的是,法令不要求算法是可解释的。我注意到文献中围绕这一点有些混乱。一些评论家抱怨说,作为其监管过程的一部分,FDA 坚持可解释性。他们不是。相反,如上所述,实现可解释性的一个动机是人工智能开发者希望避免 FDA 的监管以及所有随之而来的成本和延迟。然而,如果一个软件开发者想制造一个不可解释的黑盒,它可能会。该公司只需通过 FDA 的流程,提供足够的证据来证明该算法的安全性和有效性,在这种算法中,用户将无法理解推荐的基础。因此,即使是受管制的产品,也有动机在标签或其他地方向用户提供至少一些解释,作为降低风险的工具,减少所需的安全性和有效性的证据。应该注意的是,尽管 FDA 可能不会坚持向最终用户解释,但作为一个科学机构,FDA 在没有对因果关系有所了解的情况下,将很难授权人工智能的上市。
2.选择最佳政策方案时需要平衡的因素
正如在本系列的第一部分中所解释的,找出什么对病人是最好的需要平衡许多因素,这些因素在某些情况下是相互冲突的。我们希望确保用户——通常是医疗保健专业人员(越来越多的患者)——能够在使用人工智能算法之前了解它的优势、劣势和适当使用,以便他们能够在正确的情况下将它用于正确的患者。为了确保知情同意,我们还需要确保患者了解算法的性质,如果有必要依赖黑盒算法,他们也了解风险。与此同时,在一个相互冲突的优先事项中,在我们共享的信息的透明度和可解释性方面,我们需要尊重那些其数据被算法训练的人的隐私利益。
还有其他领域会出现冲突。例如,我们需要平衡这种上市后警惕所带来的负担与创新和获得潜在救命人工智能技术的需求。这意味着不要求更多的监控和更多的纠正措施,但也意味着不要求开发商与公众分享更多不必要的信息,商业秘密信息可能会损害他们将产品商业化的竞争能力。医疗保健是一个行业,它遵循的经济规则与其他行业相同。这意味着如果我们强迫人工智能开发者分享他们的商业秘密,他们可能无法在竞争中生存,因此不愿意投资未来的发展。最后,所有的发展都需要以生产一种具有成本效益的产品的方式进行,这样我们的集体经济资源就能提供这种产品。
3.提议:活标签
基于这些竞争因素,我建议我们追求一个“活标签”的概念我所使用的“活标签”这个术语,意味着标签会不断地更新信息,包括透明度和可解释性。通常,对于医疗器械,标签是 FDA 在上市前审查中同意的一组固定的词语。随着时间的推移,有一定的灵活性来改变它们,但不是很多。有了这个活标签的概念,将会有一个与 FDA 的预许可协议,即开发者将更新标签以反映 ABC 区间上最新的 X、Y 和 Z,而不需要新的监管提交。
基于人工智能的医疗设备需要投入更多精力来持续更新标签信息。总的来说,对于一个不断进化的自适应算法,在透明性下跟踪的指标需要不断更新。虽然可解释性可能是静态的,因为软件必须在每次使用时被编程来解释它自己,但是如果可解释性包括动态元素,那么这些动态元素需要保持最新。
在我在第一部分引用的 FDA 报告中,你看到 FDA 提出了本质上相同的东西,即开发者不断共享更新的信息。所以这个概念对我来说并不新鲜,也不独特。然而,我确实有一个与 FDA 不同的实施方案。我们的观点似乎有两点不同。首先,FDA 似乎打算与该机构持续分享至少部分信息。第二,FDA 考虑的可能是更深入、更广泛的信息共享,而不是关键统计数据的汇总。
我建议软件开发人员以概要形式共享信息,而不(1)违反患者保密原则,(2)共享会损害其商业秘密地位的信息,或(3)需要过度昂贵的信息收集和处理。根据人工智能的类型和软件产品的预期用途,确切的方法会有很大的不同。这里有一些公司可以考虑的一般原则。
a.透明度
市场上基于人工智能的医疗解决方案的开发者应该让现有和潜在的客户了解当前的性能。这意味着共享作为上述监控结果而跟踪的关键指标的适当摘要。这不仅仅是当公司认为发生了有趣的事情时的偶尔更新。这意味着,在适当的时间间隔内,通过某种机制(如公司网站)或更直接地通过产品本身更新关键信息是理所当然的。
这是除了与理解人工智能模型的适当使用相关的信息之外,这些信息可能不会改变,但仍然需要共享。不变的信息包括历史上算法是如何被训练的,这包括关于数据是如何被获取和使用的细节。这是关键,因为基于人工智能的产品的每个用户都需要判断原始训练集中是否存在潜在的任何偏差,这会影响给定的使用。例如,如果我清楚地认识到算法不是针对青少年训练的,我知道如果我想对青少年使用该产品,就会有一些无法量化的风险,即结果将是不准确的。
用户可能还想知道数据是如何清理的?模型训练的特征或维度是什么?数据增加了吗?虽然这些数据显然更具技术性,但一个有见识的用户很可能会对该算法对其特定用途的适用性得出结论。
同样重要的是,公司在质量上要透明,以监控和管理产品上市后的质量。用户会对公司如何允许算法适应、适应有什么限制以及公司正在进行什么质量检查和测试非常感兴趣。随着产品的发展,这些都提供了与使用产品相关的风险的洞察力。
例如,如果我知道该产品被标记为供成人使用,但我看到该公司在程序上没有将新数据仅限于成人,我知道随着时间的推移会有一些风险,即其他用户会添加青少年数据,这将改变产品的性能。再比如,允许算法多长时间适应一次?在像 COVID 19 这样的新传染病发作时,了解数据集受 COVID 患者影响的速度有多快,有助于我理解算法的性能在疫情期间可能会如何变化,或者至少变化有多快。
正如为《福布斯》杂志撰稿的评论员 Ron Schmelzer 所建议的那样,包含模型版本化可能也很重要。他建议“那些生产模型的人也应该清楚和一致地说明模型将如何版本化,模型版本化的频率,以及如果新模型开始表现不佳时使用旧模型版本的能力。”
为了支持正确使用算法的决策,FDA 已经规定了标签中要包含的大量信息,我在此不再赘述。但它包括开发者的预期用途以及在 FDA 批准前用于验证该技术的临床试验结果。
b.可解释性
用于实现可解释性或 XAI 的确切机制因数据科学领域而异。例如,使用图像分析可能相对容易实现可解释性,软件可以被编程来突出显示感兴趣的区域,即使它不能精确地阐明为什么该区域是感兴趣的。
相比之下,对于利用电子健康记录数据的数据科学模型,XAI 方法可能有点困难,包括以下策略:
- 特征交互和重要性,包括对特征重要性和成对特征交互强度的分析。
- 注意机制,包括在序列中找到与预测任务最相关信息的一组位置的能力。
- 数据降维,正如你可能猜到的,它集中在最重要的特性上。
- 知识提炼和规则提取,将知识从复杂而精确的模型转移到更小、更简单、更快但仍然精确的模型。
- 本质上可解释的模型,它依赖于保留不太复杂的机器学习方法的可解释性,同时通过增强和优化技术来提高它们的性能。【2】
指出关键的有统计学意义的特征类似于一个放射科医生指着图像上的一个地方说,“我以前见过那个,它是恶性的。”我们在医学上“知道”的很多东西只是联想,而没有对因果关系的更深入理解。创新的数据科学家也在开发全新的方法,如视觉模型,以更准确地解释数据科学的结果。
总而言之,为了帮助用户解释人工智能的输出,开发人员可以:
解释能解释的。不要把问题扩大化。如果该软件实际上是专家系统和机器学习的混合,如果某个特定的建议是基于专家系统的,例如简单地查找患者 EHR 中的药物过敏,遵循简单的计算模型或推荐一种治疗方法,因为它更便宜,那么该建议应该会揭示原因。
对于真正依赖于人工智能的软件输出,尽可能精确地陈述支持特定建议的特定关联。如前所述,根据新的研究,在某些情况下,可以确定哪些特性对推荐的影响最大。
传达特定建议的可信度。不确定性对于沟通以做出最佳决策和法律上的知情同意总是很重要的。
C.向 FDA 报告符合法律可报告性测试的问题
销售 FDA 监管医疗器械的公司必须建立质量体系。该质量体系包括要求这些公司有投诉处理程序。用户投诉可能导致问题的识别。如果这些投诉导致确定了根据所谓的医疗器械医疗器械报告(MDR)法规(21 CFR Part 803)触发报告义务的情况,公司需要向 FDA 报告这些情况。
这种报告义务之所以存在,是因为在某种严重程度上,如果 FDA 认为需要比公司本身计划的更重大的补救措施,并监控同一法规或产品代码中规定的其他产品中类似问题的普遍性,则需要向 FDA 报告。美国食品和药物管理局在人工智能应用于医疗保健之前制定了 MDR 法规,因此可能需要更新指南,以明确在人工智能情况下何时触发报告义务。然而,正如我将在第三部分详细讨论的,FDA 不应该扩大 MDR 义务。
MDR 报告阈值反映了信号和噪声之间的谨慎平衡。软件开发人员有责任从噪音中提取信号,并向机构报告足够严重的信号。这有助于确保该机构接收足够的信息,但不要接收太多的信息,否则会使该机构的系统负担过重,坦率地说,会导致 FDA 错过信号。
如上所述,也有向 FDA 报告的商品化产品的重大变更,但没有上升到需要 FDA 上市前审查的水平。公司显然也应该做这些报告。
D.允许 FDA 检查公司的数据和记录
除了报告之外,质量体系还要求制造商记录设备的每一项变更,并记录投诉调查和其他经验数据。事实上,几乎所有 FDA 感兴趣的信息都可以在质量体系的记录中找到。
《联邦食品、药品和化妆品法案》第 704 条授权 FDA 在合理的时间、合理的限度内,以合理的方式对生产医疗器械的组织进行检查。这些现场访问的范围允许机构检查质量系统信息以及物理制造和质量系统,以确保符合性。因此,FDA 可以对包含相关信息的质量体系记录进行物理检查。根据法律,医疗人工智能开发者需要允许这些现场 FDA 检查。然而,正如我将在第三部分中解释的那样,FDA 不应该试图扩大法令允许的范围。
在第三部分,我将为允许 FDA 更多地参与人工智能商业化的监督所造成的损害陈述理由。FDA 当然是一个重要的监管机构,但作为一个天生保守的监管机构,FDA 并不打算参与人工智能商业化所需的日常决策。
[1] 我要指出的是,虽然我首先是作为一名律师来处理这个问题,其次才是作为一名数据科学家,但数据科学家能够独立地看到并理解这种差异。参见 Hlozinger 等人的《医学中人工智能的可因性和可解释性》第 4 页,教科书题为《有线数据挖掘知识发现 2019》
【2】Payrovnaziri,at L,Review,使用真实世界电子健康记录数据的可解释人工智能模型:系统范围审查,美国医学信息学协会杂志,2020 年
【3】Lamy 等,可解释的乳腺癌人工智能:一种可视化的基于案例的推理方法,人工智能在医学中,2019。
医疗人工智能的上市后责任
production Perig/shutterstock . com
第三部分——FDA 不应扩大对商业化人工智能的监管
这不仅是不必要的;这对创新和重要的、可能挽救生命的技术的可获得性肯定是有害的。明确地说,我并不是建议我们简单地相信公司会做正确的事情,定义为每个公司自己认为是正确的事情。相反,我建议将第二部分中列出的原则嵌入到 FDA 将颁布的良好机器学习实践法规中。如果公司对上市后警惕性的要求明确,绝大多数开发医疗人工智能的公司都会遵循这些要求。
我所质疑的是,除了澄清医疗人工智能公司在从事上市后警戒时应该遵守的监管要求,我们还增加了这些公司的报告义务。我反对的是报道的增加。国会和 FDA 都不应该修改法律,以(1)要求公司在上市后与 FDA 分享更多信息,(2)允许 FDA 监督产品生命周期商业化阶段的日常决策,或(3)赋予 FDA 进行虚拟检查的能力。
在这第三部分,我将概述这三个反对扩大 FDA 对商业化医疗人工智能的报告义务的主要论点。
A.林业发展局不应增加公司的报告义务
1.信息量将是巨大的
在未来几年,在医疗保健领域部署人工智能的公司将大量收集上市后数据。我们不会试图在这里预测到底有多少,但希望每个人都同意这将是一个巨大的数字。
如果 FDA 要求公司开始向该机构移交哪怕一小部分数据(包括性能数据和在主动监控下收集的其他数据),也会让该机构不堪重负。我们理解 FDA 目前受到人力资源的限制,特别是那些有人工智能软件背景的人。坦白地说,该机构没有配备人力或信息系统来阅读和解释上市后持续传递给它的数据。
即使 FDA 努力与医疗器械利益相关者合作建立国家卫生技术评估系统(NEST ),这也是事实。NEST 将永远没有必要的资源来确保为 NEST 将收集的所有真实证据提供适当的上下文。
如上所述,MDR 背后的整个理念是要求公司在向 FDA 报告时区分信号和噪音。该法规包括针对故障和严重伤害的特定相关性测试,公司将使用这些测试来评估信息是否需要报告给 FDA。事实上,FDA 过去曾表示,多报是违反 MDR 法规的,因为该机构担心多报会用噪音掩盖信号。因此,历史上传递给 FDA 的信息量已经过仔细的滴定,以确保它集中于相关信号,并排除干扰噪声。采用人工智能来改变这种精心制定的长期方法是没有依据的。
换句话说,我确实认为公司将不得不投入相当多的资源来监控他们的算法在上市后的表现,如上所述。但是,这并不意味着我们也应该考虑增加对 FDA 的报告,特别是因为该机构不太可能具备处理额外信息的能力。
2.原始信息对 FDA 没有什么价值
除了反对通过降低被认为重要的门槛来增加软件开发商必须提交的 MDR 报告的数量,开发商不应该被要求与 FDA 分享更多的原始信息流。我所使用的术语“原始信息”是指软件开发人员直接收集的信息,没有经过任何分析或语境化。
现有 MDR 法规的另一个目的是确保原始信息不会简单地转储到 FDA。来自市场的原始信息本身几乎没有任何信息。从市场上收集的所有信息都需要进一步的调查和重要背景的分析,以理解信息的临床和技术意义。公司自己也经常这样做。当他们发现一个潜在的信号时,他们会深入了解这个信号的含义。
在这方面,人工智能与其他任何医疗设备没有什么不同。它将产生大量的信息,比传统的医疗设备产生的信息要多得多。除非放在适当的上下文中,否则这些信息实际上是没有意义的。现有的质量体系条例(21 CFR Part 820)规定公司有责任对投诉和其他质量信号进行调查。然后是 MDR 法规,要求公司向 FDA 报告任何潜在的严重信号,以便该机构可以参与最终决策。
任何让公司与 FDA 分享原始信息的方法都可能只会增加该机构的负担,而不会有任何结果。如果没有适当的背景,即使假设 FDA 能够建立必要的信息技术和人力资源来分析信息,也会导致混乱。
现有的 MDR 义务,建立在质量体系义务之上,就潜在问题向 FDA 提供有意义的上下文报告。没有理由背离这种方法。
B.FDA 不应该介入人工智能新产品商业化的日常决策
大多数人都听说过这样一个笑话:“我来自华盛顿,我是来帮助你的。”坦率地说,政府监管的介入几乎从来不会对被“帮助”的公司有所帮助。
1.食品和药物管理局可能会不必要地干预公司的运作
与 FDA 过度分享有一个明显的缺点,那就是过多的噪音会让该机构感到困惑。如果 FDA 有人力和计算机资源来读取数据,并且如果 FDA 能够理解原始数据,缺乏上下文可能会导致 FDA 反复询问报告公司问题,并可能在实际上不应该采取行动时要求采取行动。对数据的部分或不完全理解会产生潜在的风险,即该机构将采取不明智的行动,从而给公司带来巨大的负担。
2.FDA 会无意中伤害人工智能初创公司
一家小公司根本无法在美国食品和药物管理局每天向其提出大量问题的情况下运营。该机构的这种微观管理水平将对行动造成毁灭性打击。最终结果将是公司无法将足够的资源投入到包括质量保证在内的运营中。那么,病人将会因为公司的分心而遭受损失。
此外,FDA 要求公司提供的数据量会迫使公司花费额外的资源来满足 FDA 的要求。虽然大公司可以更容易地吸收这些额外的员工,但小公司,尤其是初创公司,却不能。长期来看,这将使初创公司更难创新重要的新的 FDA 监管的人工智能。
3.与 FDA 分享太多信息会产生公开披露的风险
正如已经解释过的,我同意,如果公司分享更多关于部署的自适应或自主人工智能的信息,这将符合每个人的最佳利益。但是正如我也说过的,FDA 和我可能在谈论完全不同的领域,哪些信息应该共享。
公司应该分享产品性能的适当总结。在一家公司的网站上分享几个段落,也许是总结产品当前性能的表格或图表,将有助于所有用户了解应该在多大程度上依赖(或不依赖)该产品。对所有人来说,理解算法输出的不确定性程度以及其他统计度量是很重要的。
然而,无论如何,公司都不应该与公众或 FDA 共享原始数据,甚至是带注释的数据,这样我们就可以期望接收者进行他们自己的分析。这将违背几乎所有其他领域的现有商业惯例。
人工智能开发者在竞争激烈的市场中运作。事实上,人工智能领域竞争激烈,因为它不需要大量资本进入,至少在早期阶段不需要。此外,专利保护不足以完全保护这些公司免受竞争威胁。
正如已经观察到的,如果我们希望人们在这些企业上冒险投入时间和金钱,他们必须能够保护这些投资。要求公司广泛而自由地分享原始数据供所有人分析只会导致公司在其他地方投资,而不是追求这些技术。这样的数据会让竞争对手对算法的机制有太多的了解。此外,如前所述,病人最终会失败。
美国法律体系一直要求公司诚实披露信息,并披露他们需要披露的任何信息。现有的产品责任法以及广告法中的真实性要求(1)肯定的披露和(2)披露的真实性。几十年来,美国的制度是建立在这样一个前提之上的,即我们将依赖公司的直率和诚实,但我们不会要求它们分享为其业务创造价值的机密商业信息和商业秘密。
即使只是向 FDA(一个像所有联邦机构一样受《信息自由法》约束的机构)披露信息,也会产生这样的风险,即如此共享的信息会进入公共领域。FDA 必须对其认为应该发布的产品做出判断,而这些判断决不是绝对可靠的。这里有两个独立的风险。
第一,FDA 只是犯了个错误,发布了不该发布的信息。这种情况并不经常发生,但重要的是要明白,上市后收集的可能以电子方式传输的数据可能会意外地被放在公开发布的数据集中。判断应该发布什么信息通常需要仔细的人工审查。目前,该系统对上市前申请中提交的数据工作得相当好,但上市后收集的数据则完全不同,而且更加复杂。FDA 获得的数据越多,他们在管理上就越难决定哪些是可以公开发布的,哪些是不可以公开发布的,从而更容易出错。
第二,也是更大的风险,是食品和药物管理局会简单地以不同于制造商的方式解释法律,并发布制造商不同意受 FOIA 发布条款约束的信息。有整本书都在讨论 FOIA 的范围,但是在一个高层次上,FDA 必须决定什么是不公开发布的,因为它是商业秘密或者机密的商业信息。这些定义不是很精确,关于人工智能的信息实际上是否属于这些受保护的类别,法律学者之间有很大的不同观点。例如,被清理或操纵的训练和验证数据集是机密商业信息还是商业秘密?关于算法考虑哪些特征的知识呢?或者算法的源代码、其规格和调整参数,以及将预测转化为行动的任何辅助计算机程序的编程细节?这些决定涉及许多法律判断。
一旦数据掌握在 FDA 手中,尽管公司可以通过行政程序为自己辩护,但最终信息的发布掌握在 FDA 手中,并受到司法监督。只有当一家公司事先得到通知并有机会反对时,这种情况才会发生。简而言之,增加公司所需的数据共享会不可接受地增加数据落入那些想要伤害公司的人手中的风险。
此外,这不仅仅是竞争威胁。外面有坏人。看看网络安全攻击就知道了。更进一步,还有人故意在社交媒体上散布误传,伤害他人。除了经济原因,他们还有各种各样的原因。然而,即使在经济领域,也不仅仅是竞争对手。人们会在负面新闻的帮助下进行投资押注(例如,卖空股票的人)。
复杂的原始信息,同样在没有重要背景帮助的情况下,可能会被误解并被用来伤害公司和影响市场。要求发布难以理解和复杂解释的未经语境化的原始数据不会带来公众的信任,反而会导致错误信息和混乱。
正如我在上面所说的,但是我要再说一遍,我确实同意公司对统计上重要的信息进行适当的总结将有助于利益相关者正确地使用技术。利益相关者必须理解技术的局限性,而这些局限性将随着时间的推移而演变。因此,更新这些总结将是重要的一步。
然而,期望公司分享原始的甚至是有背景的原始信息供公众分析是一个坏主意。竞争影响将过于消极,其他错误信息的风险也将过于巨大,因此这不是一个明智的做法。
C.FDA 不应回避现场物理检查
FDA 不应通过强制要求公司以电子方式向该机构发送记录来绕过现场实物检查要求,因为这样做会有效地扩大报告义务,这与刚才陈述的论点相反。
为了将这一切结合在一起,我建议坚持 MDR 系统的现有框架,即公司在自己的上市后审查中保持警惕,寻找可能出现的信号,并将有问题的信号报告给 FDA。此外,如前所述,公司将收集广泛的信息,并在持续的基础上生成内部报告,以监控其产品的性能,这些信息作为质量系统的一部分,将在现场检查期间供 FDA 审查。
这并不是说我建议对 FDA 隐瞒这些信息。但是,我建议,除了明确要求报告的信息之外,这些信息只有在现场实际检查后才能提供给 FDA。正是实际检查访问的要求使 FDA 免于不必要的微观管理。如果 FDA 真的必须去该公司查看记录,FDA 只有在有足够的理由感兴趣时才会这样做。这个小小的措施,要求 FDA 进行现场视察,在确保 FDA 监督的实际水平方面产生了巨大的影响。
近年来,食品和药物管理局一直试图绕过明确的法定限制,他们进行实地考察。不难理解为什么。只需拿起电话,打电话给制造商,告诉他们将信息发送给代理商,就可以节省资金。尴尬的是,制造商非常关心 FDA 的权力,并希望让 FDA 满意。这种强制手段非常有效。它导致公司在不需要的时候以电子方式提交信息。
然而,这种情况必须停止。除非在非常特殊的情况下,如疫情,否则不应该允许食品和药物管理局进行实际的现场检查。虽然 FDA 很想这样做,但我认为 FDA 应该避免这样做。正如我在上面所说的,要求 FDA 在要求查看公司记录之前采取个人访问的肯定步骤是有明确逻辑的。这是对过度监管的一个微妙但非常重要的限制。
实际上,FDA 的行为违反了规定公司报告义务的 MDR 法规。应要求公司自行严格监控,向 FDA 报告符合法定 MDR 标准的可疑问题,然后在现场访问时向 FDA 提供所有数据。然而,这应该是它的极限了。
结论
一切从病人开始,也从病人结束。我的父亲在我之前是一名食品和药品律师,他总是告诉我,如果我面对一个含糊不清的法规,从有利于病人的角度去解释它,我就不会出错。政策制定也是如此。弄清楚什么对病人最好。
监管对病人有好处,但要适度。过度监管是很有可能的。对于像人工智能这样的新兴技术,我们需要特别敏感地正确对待这一点。由于监管太少,严厉的过度监管肯定会给患者带来不好的结果。不必要的阻碍新技术通过减少可及性伤害了患者。
谈到监管已经上市的产品,我们在医疗设备方面有几十年的经验,可以应用于新技术。虽然人工智能有一些使其不同于传统医疗设备的基本要素,例如它们在市场上随着时间的推移而变化,但这并不一定意味着需要一种新的范式。
如果人工智能开发者履行他们的责任,进行必要的上市后警戒,现有的上市后范式将会相当好地工作。并非所有的上市后产品监管决策都值得 FDA 首先参与。我们应该合理地相信公司会做正确的事情,而不是假设他们会做错误的事情。
与此同时,我做这行已经 35 年了,我没有幻想过行业中的每个人都是可敬的。可惜世界上总有坏人。
在这种情况下,平衡一切,法律中需要的改进是我理解的 FDA 已经在追求的,这是一套良好的机器学习实践。这些 GMLPs 需要尽可能明确,而不是规定具体的,关于上市后公司管理产品生命周期阶段的义务。这不是附加报告。这只是 GMLP 应该实施的标准,要求公司按照上述思路积极主动地保持足够的警惕,而不仅仅是被动地做出反应。有了这一点,监管专业人士可以帮助确保公司尽一切努力负责任地管理使用可适应人工智能的内在风险。
法律关于上市后警戒的明确性,而不是 FDA 的额外监督,将平衡患者安全与新产品开发中的创新需求。
詹姆斯·奥莱利,联邦信息公开,2020 年第一版。
医疗人工智能的上市后责任
HeartBeat/Shutterstock.com
第一部分——FDA 加强监管的计划
房间里有一头大象。我们需要讨论的紧张气氛。FDA 正试图说服医疗保健领域的人工智能开发商,让该机构对上市产品拥有比目前更广泛的权力和权限,以换取更快的上市前审查时间。我对工业界的建议?不要这样做。不要同意会给 FDA 扩大上市后权力的监管变化。就不值得了。
需要说明的是,我给出这个建议并不仅仅是因为 FDA 未能量化任何上市前优势,无论是提交给该机构所需证据的减少还是更快的审查。相反,这是我的建议,仅仅是因为给予 FDA 扩大上市后授权的成本太高了。虽然我同意在将能够适应新数据的医疗人工智能商业化时,扩大警惕性确实是必要的,但我敦促医疗人工智能行业积极主动地接受自己的上市后监测和持续改进的责任,而不是增加 FDA 的监督。
这是一个很大的话题,所以我把它分成三个不同的部分,分别发表。这篇文章的第一部分,我提供了 FDA 计划要求国会给予更多法律权力来监管医疗人工智能市场的背景。此外,作为背景,我将描述食品和药物管理局现有的权力,我将提出我们应该评估扩大监管监督是否对病人最好的标准。第二部分将重点关注医疗 AI 开发者现在应该做什么,以承担营销医疗 AI 的责任。换句话说,我将谈论我希望行业采纳的最佳实践。然后,第三,在我的最后一篇文章中,我将说明为什么国会不应该给予 FDA 对医疗人工智能商业化的扩大监督。
A.FDA 现有的上市后角色
就背景而言,理解 FDA 已经在监督医疗器械的商业化方面发挥了重要作用是很重要的,但这是一个受法律约束的角色。以下是 FDA 对市场上医疗产品的一些更重要、更相关的法律权威的高度概括:
如果一家公司想以实质性的方式改变一个上市的医疗器械,该公司通常需要在做出改变之前获得 FDA 的许可或批准。产品或标签的微小变化也有例外。此外,除非有重大更新,否则也可以提交中间报告,包括 II 类器械的“文件信函”以及 III 类器械随后可在年度报告中汇总和报告的报告。
制造商需要跟踪他们收到的投诉,以及他们根据质量体系进行的调查,以评估这些投诉的重要性。制造商保留所有这些记录,FDA 有权进行现场检查,允许他们访问包括这些记录在内的所有质量信息。
制造商有持续的义务向 FDA 报告其产品售后引进的问题。这些问题要么是产品以物质方式伤害了某人,要么是产品出现了故障,即使没有伤害任何人,如果故障再次发生,产品也有可能伤害到某人。FDA 可以惩罚没有报告这些事件的公司。
FDA 有权下令召回,尽管更典型的情况是 FDA 仅仅哄骗制造商开始召回。
如果通过法律程序,FDA 可以要求特定的制造商对其产品进行上市后监督。
FDA 可以启动任何数量的法律程序,如扣押行动,以追查它有理由相信正在生产不符合法律规定的产品的制造商。FDA 也可以提起惩罚性的法律诉讼,如在不良行为发生后处以巨额民事和刑事罚款。
FDA 还有其他几项法律权力,如禁止它认为不安全的某些产品,以及在没有法院的情况下行政性地扣留它担心的产品。
但是,在该机构看来,当涉及到人工智能的商业化时,这对 FDA 来说是不够的。
B.房间里的大象
每次 FDA 提出其监管人工智能的新愿景的话题,除了讨论上市前审查流程和质量系统要求的变化,FDA 还在讨论结束时提出其扩大上市后权限的愿望。我分享两个例子。
1.软件预认证计划
FDA 似乎在 TSA 针对美国航空旅客的预检计划之后模拟了其拟议的预认证计划,这表明它将为愿意接受严格预认证的制造商提供更快的市场路径,以确保他们有可能生产安全有效的医疗软件的强大质量文化。这是一个大话题,坦率地说,FDA 的提议有很多优点和缺点。该计划仍在开发中,并处于试点阶段。
但具体到本文的目的,FDA 已经明确表示,它希望扩大与该拟议计划相关的上市后授权。在 2019 年 1 月发布的该计划的最后一次公开迭代中,【1】FDA 观察到:
我们相信,优秀的组织不仅在开发[作为医疗设备的软件]产品时关注质量,而且在产品推出后,他们还会基于从其产品的真实使用中获得的经验教训而成长和发展。虽然具体的[真实世界绩效,或 RWP]数据元素和分析方法可能因组织和产品类别而异,但优秀的组织始终从不同来源收集和分析上市后数据,为其运营和决策提供信息,从质量控制到新细分市场的产品开发。
在这一点上我们意见一致。但在观察到该计划中的所有公司都应该收集此类数据后,FDA 表示这些公司应该:
允许 FDA 访问与组织卓越性和产品级安全性和有效性相关的数据元素分析。
至少在该计划的试点阶段,FDA 希望持续收到收集的上市后信息。
在 FDA 的交互式审查和双方同意提议的[真实世界性能分析,或 RWPA]计划足以监控[作为医疗设备的软件,或 SaMD]产品的安全性和有效性后,试点参与者将通过组织定义的流程和方法收集和分析 RWP 数据元素,并按照约定与 FDA 共享选定的 RWPA。
然后,FDA 通过解释为什么该机构希望访问公司的上市后数据来证明他们增加的共享上市后数据的要求是合理的:
预认证组织在上市后数据收集方面的稳健报告和增加的透明度也可能使 FDA 能够探索优化预认证组织现有上市后义务的机会,包括报告和检查要求。…选定的 RWPA 跟踪现实世界健康分析、用户体验分析和产品性能分析可以定期提交给 FDA 定期访问 RWPA 将增加 FDA 对收集的数据类型和由预先认证的组织监测的任何潜在信号的熟悉程度。该机构认为,当产品需要修改或更新时,这种增加的熟悉度将促进 FDA 和预认证组织之间的合作。旨在快速解决任何上市后安全或安保问题的合作参与,反过来可能会减少合规行动的需求,并简化对任何所需产品修改的审查。虽然进入 RWPA 将允许 FDA 与单个制造商合作,以保持产品质量并确保患者安全,但它还可能使 FDA 能够识别所有产品类别中潜在的或新出现的问题,并在产品质量受到影响之前通知制造商。
请注意,美国食品和药物管理局正非常努力地向工业界推销这个想法。我可以继续引用这份文件,但你明白了。FDA 很想看看上市后的数据。再加上他们要看周期,我们也不知道周期是什么意思。然而,从上下文中似乎可以清楚地看出,它必须相当频繁,否则那些所谓的好处就不会实现。
2.2019 年人工智能概念文件
虽然预认证计划将适用于所有用作医疗设备的软件,但 FDA 在其 2019 年 4 月的 AI/ML 概念文件中对人工智能的描述更加具体。【2】首先,这里有两个定义,对于理解这种 AI/ML 监管方法的基本结构很重要。
SaMD 预规范(SPS):SaMD 制造商对“性能”或“输入”的预期修改,或与基于 AI/ML 的 SaMD 的“预期用途”相关的更改。
算法变更协议(ACP):制造商为实现和适当控制 SPS 中描述的预期变更类型的风险而采用的特定方法。
使用该框架,该机构然后陈述其对上市后报告的期望。
通过这个框架,制造商将被期望致力于基于 AI/ML 的 SaMD 的透明性和真实世界性能监控的原则。FDA 还希望制造商定期向 FDA 报告作为批准的 SPS 和 ACP 的一部分而实施的更新,以及这些 SaMD 的性能指标。这一承诺可以通过各种机制来实现。
透明度可能包括对 FDA、器械公司和制造商合作者以及公众(如临床医生、患者和普通用户)的更新。…[M]制造商可能会考虑如何实现透明的独特机制——他们可能希望建立沟通程序,描述如何向用户通知更新(例如,信函、电子邮件、软件通知)以及可以提供哪些信息(例如,如何恰当地描述当前版本和以前版本之间的性能变化)。
真实世界的性能监测也可以通过各种建议的机制来实现,这些机制目前正在 FDA 使用或处于试点阶段,例如……通过 Pre-Cert 程序进行真实世界的性能分析。报告类型和频率可根据设备的风险、修改的数量和类型以及算法的成熟度进行调整(即,如果算法处于成熟阶段,季度性能变化极小,则季度报告不太可能有用)。
该机构似乎对自己的角色有着比许多外部人士所理解的更远大的愿景。底线是 FDA 想成为你的商业伙伴。他们想在产品的整个营销过程中监督你,对下一步应该发生什么做出自己的独立判断。
C.了解 FDA 的行为
在本文的第三部分,我将提出反对扩大 FDA 上市后监管的理由,我想弄清楚为什么我认为这是一个如此糟糕的主意。我在第三部分中的许多论点都将基于组织行为,这是心理学的一个分支,它认为我们所有人在某种程度上都会对我们工作的组织结构、目的和文化做出反应。
学者们早就建议政府机构使用“理性-法律权威”领导框架来组织工作。【4】大约 80 年前,马克斯·韦伯列举了许多政府组织的原则,包括:正式的组织等级制度,按规则管理,按职能专业组织,根据技能和技术资格选拔人才,以及有目的的非个人化环境(例如,对组织的所有成员应用相同的规则和结构)。作为一个拥有约 15,000 名员工的联邦机构,根据 FDA 的宗旨和组织结构,我们可以预测整个组织的某些行为风格。
为了理解 FDA 的文化,我们需要理解并真诚地同情 FDA 必须运作的环境。FDA 因为避免了问题而得到政治和公众的称赞,但更典型的是因为医疗产品造成的伤害而受到政治和公众的批评。机构领导人通常被传唤到国会作证,就国会声称 FDA 在审查中遗漏的问题作证。
不仅如此,FDA 还面临着一个巨大的挑战,那就是招募有才华的科学家为一个薪水跟不上工业发展的联邦机构工作。尽管这导致了巨大的人员流动,但更根本的是,这意味着该机构必须采取不同于悬空薪酬的招聘策略。FDA 的招聘策略非常简单:以任务为导向。来 FDA,有所作为。这吸引了许多人,但尤其吸引了那些想有所作为的人。FDA 的人通过阻止有害产品进入市场来改变现状。该机构的整个方向是围绕其监管任务。
部门主管等中低层员工拥有巨大的权力,可以根据自己的个人判断做出决策,而这些判断往往相当保守。FDA 的决定应该是科学驱动的,但科学往往不是决定性的,需要判断。虽然通情达理的人可能会不同意,但当高级官员试图否决低级官员时,低级别的 FDA 雇员有时会认为 FDA 经理的行为是出于错误的原因,例如,遵循可能来自白宫的广泛政策声明。FDA 的雇员向国会议员抱怨说,他们认为 FDA 的管理遵循政治冲动,而不是科学,因此,FDA 的领导不愿意否决他们的雇员。这给了那些一线员工巨大的权力去做出他们认为正确的决定。
因此,对于一家试图在医学领域创新人工智能的公司来说,FDA 作为一个机构可能是最糟糕的商业伙伴。虽然我下面解释的更多,但是我要明确的是,这是因为组织行为学和心理学;这与食品药品管理局的个人无关。事实上,FDA 的许多人都是我在全世界最喜欢的人。他们是典型的聪明、勤奋和充满激情的奉献者。大多数人都非常擅长自己的工作。此外,每天都有大量的 FDA 决定是有充分的事实、科学和法律依据的。但不是全部。
FDA 有工作要做,作为一个联邦执法机构,包括实际携带枪支的特工。【6】重要的是要记住,就此而言,FDA 不是 NIH 或 CDC。药监局抓罪犯。他们通过威胁、正式的机构强制行动和司法强制,使任性的、有时是不诚实的行业成员回到正轨。代表各地消费者,我很高兴。
然而,有时 FDA 会使用其他不太正式的强制手段,如负面媒体,也许是当他们觉得自己的法律理由不充分,或者他们只是不想花费资源。这实际上是 FDA 的常用策略。以 1991 年为例,当时 FDA 专员大卫·凯斯勒(David Kessler)命令联邦代理人没收超过 12,000 加仑的 Citrus Hill 橙汁,指控这些果汁被错误地标注为“新鲜”。“今天的行动将发出一个明确的信息,即 FDA 不会容忍这样的违法行为,”FDA 专员大卫·凯斯勒在佛罗里达州棕榈滩花园的一次会议上说。他们试图公开羞辱公司以达到他们的目的。在橙汁事件中,宝洁公司(T2)坚信其使用“新鲜”一词是合法的。鉴于他们的责任,食品和药物管理局采取强硬手段。我当然不同意该机构使用的一些策略。
这些都没有让 FDA 成为一个好的商业伙伴。他们首先是一个监管执法机构,这是理所应当的。
D.判断最佳政策方法的标准
在这一系列文章中,我提出了一种政策方法来管理人工智能在医疗保健领域的风险,同时这种产品已经上市。在考虑最佳政策方针时,我们需要把重点放在病人身上。无论是从行业、政府还是医疗保健提供商的角度来看,共同点是我们都是为了服务患者而存在的。我们必须把病人放在第一位。
在某些方面,说起来容易理解起来难。把患者利益放在第一位真的没那么简单。做对病人最好的事涉及到许多因素的平衡,其中一些因素经常是互相对立的。下面我将列出一些较大的因素,但我不会详细讨论每一个。关键是,即使患者是等式的中心,在这里找出最佳方法也不是基于一个简单的因素。
患者安全性和有效性。弄清楚如何实现对患者的安全性和有效性需要检查科学证据,但可接受的风险收益的实际水平最终仍是主观的。根据希波克拉底誓言,医生首先被要求不伤害任何人。但重要的是要理解安全性——通常被认为是预防伤害——通常包含有效性措施,从某种意义上说,使用一种不起作用的产品可能意味着患者没有使用其他有效的产品。因此,在设计人工智能时,与所有医疗设备一样,重要的是产品不仅要有适当的安全水平,还要有有效性的证据。对于随着时间的推移而适应的产品,这也意味着使用上市后的警惕性来确保产品继续有效,并且我们将继续在适当的患者中使用该产品,同时考虑到软件的培训。
授权患者决策。这是一个重要的哲学需要。在医学上,我们有知情同意的概念,强调“知情”这个词。患者必须对风险和益处有足够的了解,才能在知情的情况下决定是否需要某种医疗服务。坦率地说,这个问题也有经济含义,因为我们想确保患者和他们的护理人员做出适当的购买决定,以便好的产品在市场上占优势,坏的产品靠边站。这里还有一个消费者信心和信任的因素,如果购买者相信产品是高质量和有效的,市场的规模将会增加,这将会扩大市场准入以及产品研发。
**患者隐私。**就医疗人工智能而言,人们强烈要求透明——软件开发人员共享信息。当开发人员考虑共享这些信息时,他们必须确保这样做不会无意中危及已经接受治疗的患者的隐私。
可用性/访问和结果。显而易见,只有医疗专业人员和患者能够使用人工智能这样的技术,才能挽救生命。为了进入市场,显然产品必须首先被发明出来。创新依赖于足够的投资回报,这需要保护知识产权。所有这些听起来显而易见,但它在政策制定中往往被低估。开源技术和透明到不保护商业秘密的程度并不总是能给软件开发带来足够的激励。
**性价比。**同理,如果买不起,技术也没用。技术必须在更大的医疗经济学范围内考虑。此外,产品必须是可持续的,这可能取决于费用是由第三方支付还是由患者支付。同样,这似乎是显而易见的,但监管政策的成本后果往往被低估。
**法律责任。**医疗技术的联邦法规旨在让开发商和销售链中的其他人对他们销售给市场的技术负责。因此,该系统需要包括适当的政府监督和企业责任。
挑战在于找到所有这些因素的正确平衡,为患者优化人工智能的发展。这些因素并不都朝着同一个方向。它们需要在它们之间进行权衡。
结论
在这一系列文章中,我试图将这些因素考虑在内,在必要时平衡它们,在第二部分中提出最佳实践,以及在第三部分中解释 FDA 应该发挥的有限作用。
【1】https://www.fda.gov/media/119722/download
【2】https://www . FDA . gov/files/medical % 20 devices/published/US-FDA-人工智能-机器学习-讨论-论文. pdf
【3】史蒂文·麦克沙恩、玛丽·冯·格里诺,《组织行为学》,2018 年第 8 版。
【4】韦伯,马克斯,《社会经济组织论》。由 A.M .汉德森和塔尔科特·帕森斯翻译。伦敦:科利尔·麦克米伦出版社,1947 年。
https://www . medpagetoday . com/Washington-watch/FDA general/30954
【6】https://www . Reuters . com/investigates/special-report/USA-FDA-cases/
【7】https://www . UPI . com/Archives/1991/04/24/FDA-seizes-orange-juice-in-labeling-battle/9056672465600/
使用掩模 RCNN 训练定制对象检测模型
照片由 Marc-Olivier Jodoin 在 Unsplash 上拍摄
从安装和培训到在 webapp 中部署定制的经过培训的对象检测模型的完整指南。
背景
根据维基百科,“坑洞是路面上的凹陷,通常是沥青路面,交通已经清除了路面的碎片”。据报道,截至 2015 年,加拿大阿尔伯塔省的埃德蒙顿“自称为坑洞之都”,每年花费 480 万美元用于 45 万个坑洞。在印度,每年大约有 1100 人死于由坑洞引起的事故。当当局不了解情况时,普通公民没有办法向有关当局传达或报告糟糕的道路。
因此,几个组织一直在尝试开发工具(如 web 应用程序),市民可以向有关当局报告坑洼。已经举办了几次黑客马拉松,把这个项目作为目标之一。鉴于这一问题日益受到关注,在这个项目中,解决这一问题的目标是开发一个简单的界面,使用最先进的物体检测技术来实时检测坑洞,并使用谷歌地图报告它们。这篇文章将带你完成建立你自己的坑洞探测系统的步骤。根据 Newzoo 的 2019 年全球移动市场报告,该项目的部署介质将是印度 5 亿多人使用的智能手机。
使用的工具:
- Python 3.6 以上版本
- Tensorflow 对象检测 API
- 像素注释工具
- Anaconda 包管理器
- 瓶
该项目的工作流程如下:
- 环境设置
- 数据集收集
- 模特培训
- 用烧瓶展开
- 结果
Anaconda 环境设置
开始时,我们将建立一个新的 Anaconda 环境,并安装这个项目所需的所有必要的包。Anaconda 是和“pip”一起流行的 python 包管理器。如果您在此项目之前没有安装,请使用下面的链接进行安装。
这是一个相当简单的安装过程,应该不会花很长时间。如果你有使用命令行的经验,你可以安装 Miniconda ,但是如果你愿意,贵由可以安装带有所有附加软件包的 Anaconda Navigator (这将需要更长的安装时间)。
之后,从开始菜单中打开“Anaconda Prompt ”,并按照安装说明的其余部分进行操作:
- 创造康达环境。
(base) C:\Users>conda create --name pothole python=3.6
2.激活环境并升级 pip。
(base) C:\Users>activate pothole
(pothole) C:\Users>python -m pip install --upgrade pip
3.通过发出以下命令安装其他必需的软件包:
(pothole) C:\Users>conda install -c anaconda protobuf
(pothole) C:\Users>pip install pillow
(pothole) C:\Users>pip install lxml
(pothole) C:\Users>pip install Cython
(pothole) C:\Users>pip install contextlib2
(pothole) C:\Users>pip install jupyter
(pothole) C:\Users>pip install matplotlib
(pothole) C:\Users>pip install opencv-python
(pothole) C:\Users>pip install labelme
(pothole) C:\Users>pip install tensorflow-gpu==1.15.2
4.从 Github 克隆或下载 tensorflow 对象检测 api 存储库。出于这个项目的目的,我们使用 tensorflow 版本 1.15.2。注意始终确保安装的 tensorflow 版本和 tensorflow 对象检测 api 存储库版本相同。运行下面的命令或者手动下载这个库。
(pothole) C:\Users>git clone https://github.com/tensorflow/models.git
将这些文件夹放在名为“模型”的文件夹中。您可以将这个“模型”文件夹放在您选择的目录中。
5.配置 PYTHONPATH 环境变量并安装 COCO api:
(pothole) C:\Users>set PYTHONPATH=C:\models;C:\models\research;C:\models\research\slim
(pothole) C:\Users>pip install git+https://github.com/philferriere/cocoapi.git#subdirectory=PythonAPI
6.编译 Protobufs 并运行 setup.py
在 Anaconda 提示符下,将目录更改为\models\research 目录
(pothole) C:\Users>cd C:\models\research
运行以下代码行:
protoc --python_out=. .\object_detection\protos\anchor_generator.proto .\object_detection\protos\argmax_matcher.proto .\object_detection\protos\bipartite_matcher.proto .\object_detection\protos\box_coder.proto .\object_detection\protos\box_predictor.proto .\object_detection\protos\eval.proto .\object_detection\protos\faster_rcnn.proto .\object_detection\protos\faster_rcnn_box_coder.proto .\object_detection\protos\grid_anchor_generator.proto .\object_detection\protos\hyperparams.proto .\object_detection\protos\image_resizer.proto .\object_detection\protos\input_reader.proto .\object_detection\protos\losses.proto .\object_detection\protos\matcher.proto .\object_detection\protos\mean_stddev_box_coder.proto .\object_detection\protos\model.proto .\object_detection\protos\optimizer.proto .\object_detection\protos\pipeline.proto .\object_detection\protos\post_processing.proto .\object_detection\protos\preprocessor.proto .\object_detection\protos\region_similarity_calculator.proto .\object_detection\protos\square_box_coder.proto .\object_detection\protos\ssd.proto .\object_detection\protos\ssd_anchor_generator.proto .\object_detection\protos\string_int_label_map.proto .\object_detection\protos\train.proto .\object_detection\protos\keypoint_box_coder.proto .\object_detection\protos\multiscale_anchor_generator.proto .\object_detection\protos\graph_rewriter.proto .\object_detection\protos\calibration.proto .\object_detection\protos\flexible_grid_anchor_generator.proto
如果出现找不到 protobuf 文件的错误,请在以下时间后运行:
protoc object_detection/protos/*.proto --python_out=.
最后,我们需要运行以下命令:
(pothole) C:\models\research> python setup.py build
(pothole) C:\models\research> python setup.py install
8.您可以通过运行名为“object_detection _ tutorial . ipynb”的 object _ detection 文件夹中的 IPython 笔记本来测试一切是否正常。
(pothole) C:\models\research>cd object_detection
(pothole) C:\models\research\object_detection>jupyter notebook object_detection_tutorial.ipynb
您可以使用我的存储库来获得本文的支持材料。
[## SamdenLepcha/带面罩的坑洞探测-R-CNN
这个存储库包含来自文章“用掩模 RCNN 检测坑洞”的项目。你可以找到关于…的文章
github.com](https://github.com/SamdenLepcha/Pothole-Detection-With-Mask-R-CNN)
数据集收集
与往常一样,在任何数据科学或人工智能项目的开始,在问题陈述被确定之后,我们继续收集数据,或者在这种情况下,收集用于训练的图像。
为了训练一个健壮的模型,我们需要使用大量的图片,但是也要有变化。这意味着坑洞必须以不同的角度或形状出现,这样我们的模型就不会倾向于一种变化,或者说过度拟合,也不会推广到其他图像。
你可以使用你自己拍摄的图片,或者像我一样从网上下载。对于这个项目,我们的想法是检测坑洼,这样我们就不会根据严重程度将它们分割出来,但这也为未来的范围留下了一些东西。以下数据源用于构建此项目:
按作者分类的数据集中的图像
我们需要调整图像的大小,以便可以使用这些调整后的图像(如本项目中的 800 x 600)来训练模型(除非你有无限的 GPU 计算能力)。使用命令提示符或 anaconda 提示符或任何其他 IDE 来运行这个脚本。例如,在 Anaconda 提示符下:
(pothole) C:\Users> python DatasetCreation.py
数据标记
现在我们已经收集了数据集,我们需要标记图像,以便模型了解什么是坑洞。为了给图像贴标签,我们需要一个贴标签软件。
为了这个项目的目的,我使用了 labelme,因为它使用起来相当简单。在您的 anaconda 环境中输入“labelme ”,软件应该会像下面这样打开。
(pothole) C:\Users>labelme
从你的目录中打开你的图像,点击创建多边形,开始给你的图像加标签。Labelme 将您的标签保存为与图像名称同名的 json 文件。将 json 放在与图像相同的目录中。Labelme(右)和像素注释工具(左)的示例如下所示。对于这个项目,我已经标记了 400 张图片。
像素注释工具(左)和 Labelme(右)的图像(作者提供的图像)
模特培训
- 创建 TFRecords:
在标记了我们的整个数据集之后,我们现在必须生成 TFRecords,作为我们的模型训练的输入。但在此之前,我们需要将 json labelme 标签转换成 COCO 格式。我采用了 Gilber Tanner 在他的教程中提供的脚本来执行此操作。你也可以在我的标有“ labelme2coco.py ”的 Github 存储库中找到它。下载并把它放到你的训练/测试图像所在的目录中。现在运行以下命令:
(pothole) C:\Users\models\research\object_detection\images>python labelme2coco.py train --output train.json
(pothole) C:\Users\models\research\object_detection\images>python labelme2coco.py test --output test.json
既然训练/测试数据是 COCO 格式的,我们现在可以使用同样由 Gilber Tanner 创建的 create_coco_tf_record.py 来创建 TFRecords。这个脚本也需要从 object_detection 文件夹中放置并运行。
python create_coco_tf_record.py --logtostderr --train_image_dir=images/train --test_image_dir=images/test --train_annotations_file=images/train.json --test_annotations_file=images/test.json --include_masks=True --output_dir=./
您应该在 object_detection 文件夹中找到 train.record 和 test.record。
2.正在创建标签映射
标签映射将类名链接到 ID 号。使用类似 Sublime Text 的文本编辑器创建一个“labelmap.pbtxt”并将其存储在 object_detection/training 文件夹中。在文件夹内写下以下内容:
item {
id: 1
name: 'Pothole'
}
您可以根据您想要检测的类别来定义您想要的数量,但对于这个项目的目的,我们只对检测坑洞感兴趣。
这个 id 应该与您的 train.json 和 test.json 文件中提到的 id 相匹配。请注意它是如何大了一个数字的,即这里是 id: 0,但我们在 labelmap 文件中提到了 id:1。
"categories": [
{
"supercategory": "Pothole",
"id": 0,
"name": "Pothole"
},
],
3.正在创建培训配置文件:
现在我们需要创建一个培训配置文件。从张量流模型动物园有各种各样的张量流模型可用于 Mask RCNN,但为了这个项目的目的,我们将使用Mask _ RCNN _ inception _ v2 _ coco,因为它的速度。下载该文件并将其放在 object_detection 文件夹中。您可以在 samples/config 文件夹中找到 mask _ rcnn _ inception _ v2 _ coco . config 文件。复制此文件夹并将其放入 object_detection/training 文件夹。现在,我们必须对这个配置文件进行以下更改:
- 第 10 行:将 num_classes 更改为您希望分类器检测的不同对象的数量。(在本项目中为 1)
- 第 126 行:将微调检查点更改为:
fine_tune_checkpoint: "<path>/models/research/object_detection/mask_rcnn_inception_v2_coco_2018_01_28/model.ckpt"
- 第 142 行:将 input_path 改为 train.records 文件的路径:
input_path: "<path>/models/research/object_detection/train.record"
- 第 158 行:将 input_path 改为 test.records 文件的路径:
input_path: "<path>/models/research/object_detection/test.record"
- 第 144 行和第 160 行:将 label_map_path 更改为标签映射的路径:
label_map_path: "<path>/models/research/object_detection/training/labelmap.pbtxt"
- 第 150 行:将 num_example 更改为测试文件夹中图像的数量。
4.训练模型:
运行以下命令,从 object_detection 文件夹开始模型的定型:
python legacy/train.py --train_dir=training --pipeline_config_path=training/mask_rcnn_inception_v2_coco.config
在每个间隔之后,模型将检查点保存在 training 文件夹中。让它训练到损失低于 0.05 是个好主意。花费的时间将取决于你的 GPU 有多强大。
您可以通过打开另一个 Anaconda 提示符窗口,将目录更改为 object_detection 文件夹,并键入以下命令来查看模型的进度:
(pothole) C:\models\research\object_detection>tensorboard --logdir=training
这将在您的本地计算机上创建一个网页,您可以通过 web 浏览器查看该网页。TensorBoard 页面提供了显示训练进度的信息和图表。
Tensorboard 示例(图片由作者提供)
在命令提示窗口中,可以通过按 Ctrl+C 来停止训练。我建议在它在你的文件夹中创建检查点后停止,这通常是每 5-10 分钟做一次,取决于你的计算能力。步骤数最高的检查点将用于生成冻结推理图。
5.导出推理图
在 object_detection 文件夹中创建一个名为“inference_graph”的文件夹。现在我们可以创建冻结的推理图(。pb 文件)放在这个文件夹中。要解决这个问题,请发出以下命令:
python export_inference_graph.py --input_type=image_tensor --pipeline_config_path=training/mask_rcnn_inception_v2_coco.config --trained_checkpoint_prefix=training/model.ckpt-2194 --output_directory=inference_graph
这个冻结的推理图是对象检测分类器。
6.测试新训练的分类器
为了测试新训练的分类器,您可以对我的 Github Repo 中已经存在的 object_detection.ipynb 文件进行修改。
更改 labelmap,inference_graph,.配置文件和 test_images 目录。您应该得到以下输出:
测试图像的输出(作者提供的图像)
使用烧瓶展开
Flask 是一个用 Python 编写的微型 web 框架,由阿明·罗纳彻开发。我们将使用 Flask 来部署我们定制的经过训练的对象检测模型。你可以在他们的官方文档上找到初学者教程。
我们将在 Flask 应用程序中使用 object_detection.ipynb 文件中的代码。代码名为“ app.py ”,也在我的 Github 库中。在我们的 app.py 文件的开始,我们导入我们的库,并在对象检测 api 所在的位置附加我们的 Python 路径。根据您放置该文件的位置进行更改。
Flask 应用程序的简单架构可以用下图来描述。
Flask Webapp 架构(图片由作者提供)
我们将图像作为定制训练的掩模 RCNN 模型的输入,该模型基于准确度分数来决定是否给出坐标。您可以通过运行以下命令来运行“app.py”。
python app.py
flask 应用程序在命令提示符下的输出(图片由作者提供)
运行上面的命令后,我们应该得到下面的输出。将它复制到您的浏览器中,以便 web 应用程序呈现 HTML 页面。这件事我做得很糟糕。你们可以通过修改 HTML 和 CSS 文件来为这个项目创建更好的界面或 UI。您可以在下面的结果部分找到所有的输出图像。
结果
这个部分只包含项目的各种输出图像。
- 这是将来自 Anaconda 提示符的 URL 复制到您选择的浏览器后的第一页。
Webapp 主页(图片由作者提供)
- )这是选择并上传您选择的图片后的页面。
加载后的 Webapp(图片由作者提供)
- 这是点击提交按钮后的页面。请注意,只有当分数高于 50%时,下方的按钮才会出现。
模型预测后的输出(图片由作者提供)
点击下方的按钮后,输出结果状态,得到当前位置。为了不暴露我的位置,我已经把地图缩小了不少,但是你可以非常精确地放大坐标。您可以尝试建立一个架构,其中您在线维护一个位置数据库,以便页面可以显示这些坐标,但对于这个项目的目的,我们只是显示图像上传的当前位置。所以图像必须在同一个地方拍摄和上传。
最终谷歌地图功能的输出(图片由作者提供)
感谢您阅读到本文结尾。这就是本教程的内容。我希望您喜欢这篇文章,并希望它对您的数据科学之旅有所帮助。你可以在我网站的博客部分找到更多这样的文章。
在这次以“人工智能/机器学习”为主题的黑客马拉松中,我们为他们的……
www.samdenlepcha.com](https://www.samdenlepcha.com/#blogs)
参考
- 3 年内超过 9300 人死亡,25000 人因路面坑洼受伤— 今日印度
- S & Booysen,M.J. (Thinus) & Kroon,RS(2015).用于坑洞检测的图像数据集。10.13140/RG.2.1.3646.1520
- 如何在 Windows 10 上使用 TensorFlow (GPU)训练一个针对多个物体的物体检测分类器— Github
- 使用 Tensorflow 对象检测 API 的自定义遮罩 RCNN—介质
- 使用 Tensorflow 对象检测 API 训练 Mask R-CNN 模型— Gilbert Tanner
- HTML 地理定位 API — w3schools
功耗分析变得简单
如此简单,你可以用手来做。
你已经重新设计了你网站的登陆页面,现在你需要对它进行 A/B 测试。您应该运行测试多长时间?本文将演示如何使用样本大小计算(“功效分析”)来回答这个问题。
统计学可能是一门令人望而生畏的学科,但也不尽然。这些指南的目的是让人们更容易使用统计工具。确保您熟悉抽样分布的概念(如果您需要复习,请参见此处的)和比例度量标准误差的计算(请参见此处的)。尽情享受吧!
1.计划 A/B 测试
您想要 A/B 测试您的登录页面的重新设计。目前的登录页面平均每天有 200 名访客,点击率为 5%。您认为重新设计将带来至少 7%的点击率。一旦我们平均分配流量,当前的登录页面(控制)每天应该看到 100 个访问者,重新设计(测试)每天也应该看到 100 个访问者:
测试和控制的预计流量和性能
为了验证测试确实优于控制,您应该运行测试多少天?
2.如果我们运行测试,比如说,7 天呢?
假设我们计划只运行我们的 A/B 测试 7 天,此时我们每组将收集 700 个访问者。让我们计算零假设(总体 CTR 无差异)和替代假设(总体 CTR 有真实差异)的抽样分布。
第一步:计算汇集样本比例§。
第二步:用 p 计算标准误差( se )。
第三步:计算抽样分布。
- H0(零假设) : 均值= 0,标准差= 0.013 的正态分布。
- HA(替代假设) : 一个均值= 0.02,标准差= 0.013 的正态分布。
让我们绘制这些分布图:
H0 和 HA 在 7 天数据收集后的抽样分布
在显著性水平(𝛂)为 0.05 时,临界值为 0.0249。这意味着:
1.如果样本 CTRs 的绝对差值>为 0.0249,我们将总是拒绝零假设(H0)。
- 如果 H0 是真的,那么拒绝它的决定将是不正确的(类型 1 错误)。这种情况的发生率为 100 次实验中有 5 次(𝛂).
- 如果哈确实是真的,那么拒绝 H0 的决定将是正确的。这将发生在 35/100 的实验中(1-𝛃).这种速率也被称为 功率 的一种测试。
2.如果样本 CTRs 的绝对差≤ 0.0249,我们总是 无法拒绝 零假设(H0)。
- 如果 H0 确实是真的,那么不拒绝它的决定将是正确的。这种情况的发生率为 95/100(1-𝛂).
- 如果 HA 为真,那么不拒绝 H0 的决定将是不正确的(类型 2 错误)。这种情况的发生率为 100 次实验中有 65 次(𝛃).
总结一下:
A/B 测试所有潜在结果的描述
我们决定仅运行 7 天的 A/B 测试,这将导致我们在 100 个实验中的 65 个实验中无法检测到测试组的升高。这个错误率太高了!通常,我们希望将该值降至 20%,相当于 80%的幂。我们可以通过增加样本量来实现这一点。
重述:通过运行 7 天的 A/B 测试,因此,每组收集 700 个访问者的样本量,我们实验的功效只有 35%。为了达到 80%的功效,我们需要增加样本量,这意味着让 A/B 测试运行更长时间。
3.手动计算 80%功率所需的样本大小
要获得 80%功率的测试,我们需要多大的样本量?
让我们将零假设下的采样分布转换为一个 标准正态分布 以使计算更简单:
- 显著性为 0.05 的临界值约为 1.96,可从查找表中获得。
- 如果我们现在考虑给定替代假设的采样分布,那么我们希望-1.96 和 1.96 之间的曲线下面积等于 20%(对于 80%的功率)。因此,临界值必须距离平均值约 0.84(也可从查找表中获得)。
- 所以总的标准化的均值之间的差值一定是 1.96 + 0.84 = 2.8。
这可能更容易用图形来理解:
我们还知道,真实的均值之间的差值为 0.02,因此,标准化的差值等于 0.02 / se。所以我们可以构造一个等式并求解 n:
所以我们需要收集每组 2211 个观察值。按照每组每天 100 名访问者的速度,我们需要运行测试至少 23 天,以获得 80%功率的实验。在这种样本规模下,如果重新设计的页面确实提供了至少 7%的点击率,那么我们在 100 次实验中有 80 次可以检测到这种提升。
概述:参考标准正态分布,我们能够确定平均值之间的标准化差值在 80%功率下应为 2.8 左右。然后,我们可以用标准误差来表示,然后求出 n。我们计算出 n = 2,211 次观察。
4.R 中的统计分析
至此,您应该对样本大小计算(功效分析)的总体框架感到相当满意了。现在,让我们看看如何将上述所有步骤简化为几行代码。在 R 我们会写:
它产生:
[1] "absolute difference (Test — Control)"
0.02[1] "pooled sample proportion"
0.06[1] "standardized distance for requested power"
2.80158521811297[1] "solve for n"
2213.38408508644
电源分析——你从未听说过的最酷的东西。
从头做起
将权力投入到您的物流决策中。
无论我说什么,T2
“基本概率”
可能立即跳入你脑海的是统计学中的贝叶斯数学(可能是宗教的)。贝叶斯定理或条件概率定理都是很好的例子,说明为什么这是一个很好的假设。尽管条件概率与贝叶斯统计有很强的关系,但是,有很多独特而有趣的方法来进行推理。当你在一台计算机和程序机器学习算法(数据科学超级力量)后面时,尤其如此。)我主观地认为,统计学和统计学家这两个派别(很可能是宗教派别)实际上合作得非常好,或者可以互换。今天我将向你展示如何在 Julia 中使用简单的数学来操作逻辑概率。
逻辑回归功效分析的迷人之处在于,执行它的数学是相对基础的,不需要任何递归成本训练或任何类似的东西(甚至不需要 sigmoid 或 relu。)这不仅方便,而且性能很好,易于编程和操作。此外,您可以将这种分析重新应用到机器学习算法中,并将其用于您的优势。
说明
逻辑回归功效分析通常用于确定样本量。统计学家中一个常见的误解是,你的样本量是静态的;也就是说,对于每一种情况,没有一个特定的样本量。幸运的是,使用一个逻辑的决策模型将允许你为几乎任何场合计算一个精确的样本大小。作为一个额外的好处,功耗分析还可以做很多其他的事情。
该功能
为了执行功耗分析,我们需要一些输入变量。不要太担心这些简短的解释,因为如果您处于未知领域,它可能在函数的示例使用中更有意义。
首先,我们需要 p1 和 p2。这两个值中的 p 是一个概率,所以本质上,我们有
概率 1 和概率 2。
记住:这些不是 P 值,而是百分比。
我们还需要阿尔法。一个阿尔法水平是一个类型 I 错误的概率,所以当它为真时,你拒绝零假设。这是在 对比 到贝塔水平中,正好相反,会让你接受你的零假设。确保不要在这个问题上选边站,你不能选择是接受还是拒绝你的空值。有时候我喜欢用迷因来阐述观点,不久前我发现了这个:
(不是质量最好的)
我们的最后一个值是 rsq,rsq 是预测变量(y)和模型中所有其他变量(X('s))之间的多重相关的平方。我们需要在这个函数中获取的第一个值是 l1 和 l2:
pd = p2 - p1
l1 = p1/(1-p1)
l2 = p2/(1-p2)
如果 X 是一个未知变量,其概率分布为 f(x ),其特征为未知参数θ,随机样本 X1 的大小为 n,X2………X2 XnX1………Xn 然后统计ϕ=h(X1,X2,)是θ\左(\θ\右)的点估计量。我们也可以说ϕϕ是θ的参数空间。所以本质上,当我们声明 l1 和 l2 时,我们所做的是,用我们的两个概率来设置θ的参数空间。现在我们计算θ,就像用较高概率(p2)的参数(l2)除以较低概率(p1)的参数(l1)一样简单。
θ = l2 / l1
现在我们需要λ,我们可以通过简单地记录θ来得到。这可以在 julia 中用 log()方法完成(正如您可能已经想到的。)我们也可以继续做λ。
λ = log(θ)
λ2 = λ^2
接下来,我们需要一个正态分布,我们还想获得正态分布的分位数,在 Julia 中,我们将使用 Julia 基本统计库中的分位数函数:
za = quantile(Normal(),1-alpha)
这里我使用的是软件包“Distributions.jl”,这当然是一个很棒的软件包,可以在 Julia Pkg 注册表中找到,但是计算您自己的正态分布是相对简单的。如果你熟悉标准定标器,它就是**一样的东西。**您只需从 X 的迭代中减去样本均值,然后除以标准偏差。
f(x)=[I =(I-μ)/σfor I in x**)**
您可能已经注意到我使用了一个语法循环,这是有意为之的,因为 quantile()方法的语法不会采用单个规范化值,因为它依赖于分布和 1-alpha 来计算 za。
using Lathe.stats: mean, std
# Function
function normald(array)
**σ** = std(array)
μ = mean(array)
v = [i = (i-μ) / **σ** for i in array]
return(v)
end# Syntactual expression
normald(x) = [i = (i-mean(x)) / o for i in x]
现在我不确定 Julia 是否真的使用了 syntactual 表达式,但是发行版中的 Normalize()方法很有可能也适用于这个特定的实例。
朱利安提示:分位数是通过点
((k-1)/(n-1), v[k])
之间的线性插值计算出来的,对于k = 1:n
其中n = length(v)
。
接下来,我们将打印出双尾检验的值。这一步当然是可选的,但对于这一特殊功能来说,这无疑是一个很有价值的步骤:
println("One-tailed test: alpha = ",alpha,", p1 = ",p1,", p2 = ",p2,", rsq = ",rsq,", odds ratio = ",or)
如果你还在继续,这就是我们现在的情况:
接下来,我们需要计算小写 delta。幸运的是,对于这个特定的操作,我们已经有了可用的值。它看起来是这样的:
δ = (1 + (1 + λ2)*exp(5 * λ2/4))/(1 + exp(-1*λ2/4))
我们将为样本大小和功效值创建两个空数组。
pwr = zeros(Float64,8)
nn = zeros(Int64,8)
然后,最重要的是,我们添加一个循环来迭代我们的幂和样本大小,并给出一个返回:
i = 1
for power = 0.6:.05:.95
zb = quantile(Normal(),power)N = ((za + zb*exp(-1 * λ2/4))^2 * (1 + 2*p1*δ))/(p1*λ2)
N /= (1 - rsq)
pwr[i] = power
nn[i] = ceil(Int64,N)
i += 1
end
return(pwr,nn)
最终结果看起来有点像这样:
例子
假设,让我们说我们正计划为我们的一个空缺职位招聘人员。在我们的带回家的面试中,我们给每个人都做了一个测试,他们必须通过这个测试才能被录用——但是那些分数较高的人更有可能被考虑。我们预计,只有大约 25%的人会在测试中取得高于样本平均值的分数。然后我们还会考虑多 15%的分数会比平均值高出一个标准差,或者
μ < p1 = .25 + .15 = p2 < **σ**
有了这个表达式,我们可以假设值 p2 将是那些测试的 15%+= P1,所以在我们的例子中,我们得到 0.40。现在如果我们把它代入公式:
现在我们可以用 zip 函数并行打印我们的幂和样本大小(或者成对连接它们,由您决定。)
for (i,w) in zip(pwr,nn)
println("Power: ", i, " n: ", w)
end
功率的技术定义是,它是检测到一个“真实”效应存在时的概率。在大多数情况下,功耗分析涉及许多简化假设,以使问题易于处理,并使用不同的变量多次运行功耗分析,以涵盖所有的意外情况。
描绘我们的力量
当然,为了完成这一切,我们必须将这些数据可视化。为此,我将使用我的包 Hone.jl。
using Hone
看起来我的系统上有 0.0.1 版本的 Hone.jl,但没关系,我可以忍受它…我们在这里可以观察到的是,随着功率的增加,nn 也会增加。我们可以利用这些数据做的另一件有趣的事情是回到那个迭代循环,记录更多的功率。
结论
坦白地说,我认为很多读者知道这种方法是可能的。话虽如此,我希望能从这篇文章中吸取一些东西。我在制作它的过程中获得了很多乐趣,我肯定会在 Julia、R 和——你猜对了,Python 中添加更多“从头开始”的机器学习模型(也许我会变得疯狂,做一些 Scala 或 C,谁知道呢。)
Power BI 101 —简而言之的数据整形
在 Power BI 101 系列的第 2 部分中,了解什么是数据整形,以及为什么学习这个概念可以将您的 Power BI 数据模型提升到新的高度
马库斯·斯皮斯克在 Unsplash 上拍摄的照片
在这一系列 Power BI 101 文章中,我将尝试涵盖并解释与 Power BI 相关的不同基础概念,例如数据整形、数据剖析和数据建模。
理解这些概念对于创建最佳商业智能解决方案至关重要。一旦您掌握了这些基本概念,您将能够构建可扩展且灵活的电力 BI 报告解决方案,为其现有环境增加真正的商业价值。
在 Power BI 101 系列的上一篇文章中,我解释了什么是数据概要分析,为什么您应该关注它,以及当您应用适当的技术来检查和增强您的数据质量时,您可以如何受益。
照片由 Ash Edmonds 在 Unsplash 上拍摄
塑造它,塑造它,宝贝!
一旦您熟悉了您的数据,并意识到您计划在您的商业智能解决方案中使用的数据中可能存在的陷阱,您就应该执行数据整形阶段(我有意使用术语“商业智能”而不是“Power BI”,因为这是一个应该在 Power BI 解决方案之外使用的通用概念)。
简而言之,数据整形是数据整合的过程,在成为数据模型的一部分之前。关键要记住的是两个字:之前!因此,我们应该在数据进入报告本身之前进行数据整形。
数据整形可以在不同的地方进行,也可以在数据准备过程中的不同时间点进行,这取决于您应用数据整形技术的位置。
我应该在哪里执行数据整形?
首先,让我们看看可以在哪里进行数据整形:
- 源数据库 —这是最明显的选择,在大多数情况下也是最理想的场景。它基于传统的数据仓库原理,即 E 提取- T 转换- L 加载(ETL)数据。
在这个场景中,您定义想要提取的数据(并不需要数据库中的所有数据,并且通常导入所有数据并不是一个好主意)。然后,您决定是否需要在此过程中转换数据,以更好地满足您的报告需求,例如,您是否需要执行货币转换,或者您是否需要符合城市名称(纽约,NY,NYC)。
此外,您应该为列和属性指定用户友好的名称,并在将数据加载到数据模型之前决定是否需要聚合数据。
- Power Query—Power BI 内置的工具,可以对数据进行的各种变换。根据微软的官方文档,您可以应用 300 多种不同的转换,而且这个数字还在不断增加!
对于某些数据源(例如 Excel 文件),没有在源端转换数据的选项。因此,对于这种数据源和许多其他“非数据库”数据源,Power Query 是显而易见的选择。
帕特里克·亨德利在 Unsplash 上的照片
在 Power Query 中执行不同的数据整形步骤时,最重要的考虑是 如果查询折叠 !我将在另一篇文章中讨论查询折叠,但是此时,了解什么是查询折叠是很重要的。
用最简单的话来说,查询折叠就是 Power Query 将您的请求“翻译”成数据源“理解”的单个语句的过程,从而使您的请求更高效地执行。
理解查询折叠的概念对于数据成形过程极其重要。如果您正在使用关系数据库的数据源,那么您应该考虑在源端执行所有的数据整形,并在一个单独的步骤中将您的数据加载到 Power BI 中(如果可能的话,从一个单独的数据库对象,如 database view),而不是在加载了 数据之后应用额外的转换 ,因为这会破坏查询折叠并使您的数据加载/数据刷新效率低下!
根据经验,您应该将所有的数据整形和转换尽可能地推向数据源!
- 数据模型 —最后一个,也肯定是最不想要的选项,是在数据模型本身上执行数据整形。这是您想要避免的情况,并且通常是不充分和糟糕的计划的后果。这意味着,例如,您可以使用 DAX 创建计算列,但是您应该知道这不是一个最佳的解决方案——计算列是后台表格引擎的额外开销,因为它们不能被最佳压缩。
强大的查询=强大的数据整形
现在,我们已经绘制了一幅大图,并对数据整形进行了总体概述,如果您阅读了这篇文章,我假设您对 Power BI 的数据整形特别感兴趣。因此,我想更深入地解释 Power BI 数据整形。
照片由 Aditya Joshi 在 Unsplash 上拍摄
正如我们之前所了解的,Power BI 为您提供了执行数据整形任务的强大工具。进入 Power BI Desktop 后,您可以单击“主页”选项卡下的“转换数据”来打开 Power Query 编辑器:
有一大堆可用的转换来使您的数据达到最佳状态,例如重命名列和表、更改数据类型、删除列、过滤行、替换值、将首行提升为标题、旋转/取消旋转列等。我们将把重点放在几个你可能会经常使用的地方。
在上图中,在左侧,您可以看到数据模型中所有表/查询/函数的列表,而在右侧,您可以看到应用于特定表/查询的所有转换步骤。转换步骤是按照您应用它们的顺序记录的,记住这一点很重要,因为您应该致力于在一个单独的步骤中应用类似的转换,而不是经常在转换之间切换。
例如,如果要从列中筛选数据,应该在一个步骤中应用所有筛选条件:
在上图中,我过滤了 DimCustomer 表,只保留了姓 Adams、性别为男性的客户。您可以看到,Power Query 在一个语句中应用了这两个过滤条件,因此在左边创建了一个转换步骤。
现在,假设我想从我的数据模型中删除一个列后缀,然后我想过滤掉所有年收入> 50.000 的男性 Adams 客户。
正如您所注意到的,我们现在有了一个额外的步骤来过滤 YearlyIncome 列。这是一种不好的做法,你应该避免。尽可能在一个步骤中应用所有类似的操作,因为这将提高数据加载/数据刷新过程的效率。
这里可以看到的另一个不好的实践是转换步骤的命名。如果你在 Power BI 中独立工作,并且你有不到 10 个转换步骤,看起来可能没那么糟糕。但是想象一下当您看到 30 多个转换步骤时的场景,这些步骤的名称有:删除的列 1、筛选的行 1、更改的类型 1、筛选的行 2、删除的列 2 等等。您需要打开每一个步骤来确定应用了哪些转换!
因此,不要偷懒,以人类可读的方式重命名每个步骤:
你必须承认现在看起来方便多了!
常用转换
正如我已经提到的,Power Query 为您提供了 300 多种方式来塑造您的数据。当然,你不可能把它们都用上。像任何其他工具一样,有一些特性您比其他的使用得更频繁。
因此,对于 Power Query,如果右键单击表中的特定列,可以看到“最常用”转换的列表:
这些选项将在 80–90%的情况下完成工作,但是如果您需要执行一些高级转换,或者甚至手写 M 代码来实现您的目标,这里有一个好消息:您也可以在 Power Query 中这样做!
“转换”选项卡提供了一系列全新的高级功能,包括数据内容操作(替换值、格式化值等)。),以及数据结构增强(旋转/取消旋转列、拆分列、转置表等)。):
让我们不要忘记 Add Column 选项卡,它为您提供了应用一整套不同技术的可能性,以便用新的列来增强您的数据模型,从而为您现有的数据模型带来额外的业务价值。
了解特定的 Power 查询转换在现实中如何执行的最好方法是——使用它们!测试、尝试并查看哪些技术和转换以最有效的方式满足了您的业务需求。
结论
为了能够创建最佳的数据解决方案,数据整形是需要理解的关键概念之一。理解这个概念并将其应用到实际项目中,坚持我们在本文中研究的一些最佳实践,将增强您的数据模型,并帮助它们变得更加健壮、可伸缩和可重用。
在数据分析和数据建模阶段的协同作用下,适当的数据整形为您的商业智能解决方案提供了实质性的质量,并作为其中的一部分增强了 BI 报告。
感谢阅读!
成为会员,阅读 Medium 上的每一个故事!
订阅这里获取更多有见地的数据文章!
Power BI:向图表添加类别“其他”
资料来源:Pexels.com
问题是
微软一直在以更快的速度改进 Power BI。每当我遇到缺点时,我的第一个想法是等待,并假设它会很快被新的更新解决。然而,等待仪表板的客户并不总是分享我的乐观和耐心,因此,我经常需要有创造力。
我前阵子遇到的一个问题是有一个分类太多的饼状图;当你有一个饼状图,比如说 20 个不同的百分比(显然总和为 100%)时,这个图表可能会变得难以阅读。当然,您可以使用 Power BI 的 top-N 特性,但是这将不可避免地排除剩余的数据。这意味着 100%将只包含可见的分区,这可能会造成混乱。
对此的解决方案是将某个百分比设置为阈值,并将低于该阈值的所有部分一起分组到名为“其他”的分区中。
将截止值设置为 10%之前和之后
更好的方法是添加一个可以动态改变阈值的切片器。在尝试了一些度量和查询之后,我想到了下面的解决方案。
结果呢
让我向您介绍一下我的方法,这样您就可以自己尝试了…
蓝图
数据
在动手之前,了解您的数据非常重要。对于这个例子,我使用了洛杉矶湖人队 2015-2016 赛季的统计数据,这是科比·布莱恩特的告别赛季。在本例中,我们将只使用两列图表;球员的名字和他们在整个赛季中的得分。
我们将使用的数据
既然你理解了数据,我们可以开始工作了。
添加类别“其他”
如果您想绘制一个功率 BI 值,应该有一行或一个度量值。假设在您的数据中没有名为“ Other ”的没有值的行,您有两个选择;创建新行或使用度量。度量看起来是最佳选择,但是这意味着您必须将它与您已经拥有的行结合起来。因此,添加新行对我来说似乎是最好的选择。
在 Power BI 中,您不能简单地向已经加载的表中添加新行,而是可以创建自己的表并追加新行。通过一些简单的步骤,你可以添加一个名为“其他玩家”的新玩家。因为他的分数会随着他所代表的玩家数量而变化,我们会给这个玩家零分,至少现在是这样。
- 手动创建一个具有相同列标题的新表格(‘输入数据’)
- 仅创建一行。该表应该如下所示:
为额外的“其他玩家”行创建表格。
3.将该表追加到包含分数的主表中。(编辑查询/转换数据—主页—合并—追加查询)
好了,数据准备好了。但是在我们开始衡量之前,我们需要做更多的准备。
创建动态阈值
注意:如果对动态百分比不感兴趣,可以跳过这一步。如果您想使用一个固定的阈值(例如 10%),您可以跳到下一节“编写度量”。如果您希望用户动态更改百分比,您必须遵循另一个步骤:
准备工作非常简单。您只需手动创建另一个表,如下所示:
为百分比切片器值创建一个表。
对于这个例子,我创建了 0 到 15%之间的值,但是您当然可以使用您喜欢的任何范围和步长。
注意:确保该表没有以任何方式连接到数据集中的其他表。设置好表格后,您可以向报告中添加一个切片器,从中可以选择所需的分界点。
写度量
准备工作到此为止。是时候写解决方案的核心了;衡量标准。
为了让我的代码更具可读性和可调整性,我倾向于使用很多变量。让我们从定义一些关键值开始:我们在切片器中选择的截止百分比和我们将要计算的玩家的名字。
Points_calculation =VAR percentage = MAX(Threshold[Percentage]) -- can also be fixed
VAR current_player = MAX(‘Season total’[Name])
注意:如果您不想要前面提到的动态百分比,您可以将百分比变量设置为 0 到 1 之间的固定值。
现在我们来计算一下球队的总得分。
VAR total_points = CALCULATE(
SUM(‘Season total’[PTS]),
ALL(‘Season total’)
)
根据上面的信息,我们可以计算出一个临界值。假设这个团队总共得了 2000 分,你将百分比设置为 10%,截止数将是 200。任何低于 200 分的玩家都应该被归类到分区“其他玩家”中。
VAR cutoff_number = total_points * percentage
使用这个截止点,我们现在可以计算阈值之上和之下的点的总和。
VAR sum_above_cutoff = SUMX(
FILTER(
ALL(‘Season total’),
‘Season total’[PTS] > cutoff_number),
(‘Season total’[PTS])
)VAR remainder = total_points-sum_above_cutoff
在代码的最后一部分,对于每个玩家,如果他通过了阈值,我们将返回他的点数,如果他没有通过阈值,我们将什么也不返回( BLANK() )。对于类别“其他玩家”我们将返回那些没有达到截止的玩家的总和(VAR 余数)。
VAR filter_points = IF(
MAX(‘Season total’[PTS]) < cutoff_number,
BLANK(),
MAX(‘Season total’[PTS])
)VAR result = IF(
current_player = “Other players”,
remainder,
filter_points)RETURN result
这就是你需要的所有代码。现在剩下的就是绘制结果了。但是首先,让我用一段代码总结一下整个措施:
Points_calculation =VAR percentage = MAX(Threshold[Percentage])
VAR current_player = MAX(‘Season total’[Name])VAR total_points = CALCULATE(
SUM(‘Season total’[PTS]),
ALL(‘Season total’)
)VAR cutoff_number = total_points * percentageVAR sum_above_cutoff = SUMX(
FILTER(
ALL(‘Season total’),
‘Season total’[PTS] > cutoff_number),
(‘Season total’[PTS])
)VAR remainder = total_points-sum_above_cutoffVAR filter_points = IF(
MAX(‘Season total’[PTS]) < cutoff_number,
BLANK(),
MAX(‘Season total’[PTS])
)VAR result = IF(
current_player = “Other players”,
remainder,
filter_points)RETURN result
剧情
绘制结果非常简单,您所要做的就是绘制一个饼图(或您选择的任何其他可视化工具),并像这样设置字段:
-Legend:’ Season total '[Name]
-Values:Points _ calculation
结果应该是这样的:
决赛成绩
结论
正如您所看到的,在您的可视化中创建一个动态的“ other ”分区是相当简单的。然而,我在这里写的手册实际上是我之前创建的包含类别选择、指示器和行聚合的更复杂版本的改编版本。
我非常有信心,微软将很快创造出一个解决方案,不需要一个 hacky 解决方案,以及他们目前可能有的其他缺点。但是只要我们发现了没有被解决的需求,除了保持创造力和自己写更多的代码之外,我们别无选择。
请随意查看我创建的一些其他工具或教程,以改进您的 Power BI 仪表盘或其他数据应用程序。
关于我:我叫布鲁诺,是总部位于荷兰的人工智能技术纵向扩展公司 Dashmote 的数据科学家。我们的目标是借助基于人工智能的解决方案,弥合图像和数据之间的鸿沟。
查看我在 上的其他作品 https://www.zhongtron.me 。
Power BI:计算度量与计算列
鲁珀特·布里顿在 Unsplash 上的照片
选择正确的
微软的 Power BI 在过去 3 年中有了很大的改进。起初,它在数据可视化领域是一个弱小的竞争对手,但每月的更新使它逐渐成为 Tableau、TIBCO 的 Spotfire 和 Qlik 的有力竞争者。然而,即使有了重大改进,一些令人困惑的特性仍然存在…我收到的关于 Power BI 的最常见问题之一涉及计算度量和计算列。
我们都在数据模型和可视化中利用计算。所以,这两个特征是前面和中间。正确理解后,它们将丰富您的数据模型以及您通过报告和仪表板分享的见解。
这两个功能听起来很相似,如果不是相同的话,并且都可以从 Power BI 中功能区的相同位置访问。它们经常被互换使用,随后的混乱也随之而来,因为它们不能互换。他们之间的差异是微妙的,但意义重大。
计算列
计算列是对每一行进行评估的表的扩展。计算列位于 Power BI 的 xVelocity 内存存储中,就像从数据源导入的所有其他数据一样。除了一个例外,计算列实际上与非计算列相同。它们的值是使用 DAX 公式和其他列中的值计算的。
由于计算列与表处于同一级别,因此只有在第一次定义它们时以及在数据集刷新期间才会对它们进行计算。计算列的一个示例是通过从产品价格中减去产品成本得出产品的单位利润。
单位利润=产品[价格] —产品[成本]
将对 Products 表中的每一行执行此计算。计算出的值将存储在新的单位利润字段中。
如何:
- 在字段窗格中选择产品表。
2.从建模选项卡的计算部分中,选择新列。
3.在公式栏中,输入上面的公式。
也可以通过右键单击字段窗格中的表名并从上下文菜单中选择新列来创建计算列。您还可以从 Power BI 查询编辑器中创建计算列。
计算度量
计算度量值与任何其他表列的处理方式不同。与计算列不同,度量是随着上下文的每次变化而动态计算的。如果将日期筛选器从 2019 年更改为 2020 年,将会重新计算所有度量值。虽然这对于实时查看基于上下文的计算很好,但它对计算机的处理器要求很高。
度量值也可以用作聚合。每个计算度量值都必须包含一个聚合函数,如 AVG 或求和。如果没有聚合函数,度量的公式将显示错误。
如何:
- 在字段窗格中选择产品表。
2.从建模选项卡的计算部分中,选择新度量。
3.在公式栏中,输入上面的公式。
何时使用计算列和度量
选择一个而不是另一个并没有硬性规定。在某些情况下,您可以使用计算列或度量值。然而,有些情况下只有一个选项有效。请记住,如果您可以使用其中任何一种,当您的用户与您的报表交互时,计算列将消耗较少的资源。每次用户更改筛选器时,度量都会重新计算,这会导致您的报表响应缓慢。
使用计算度量值时的另一个注意事项是计算列无法在公式中引用它们。由于度量被认为是动态的,并且在 xVelocity 表之外,因此计算列不应在其定义中使用它们。这经常会打乱新来者的努力。他们首先为高度上下文驱动的报告创建一个度量。随着对新报表功能需求的增加,需要更多的计算列。随着您意识到您的度量在一个独立的世界中,并且在计算列公式栏中毫无用处,挫败感袭来。
一种仅通过计算度量解决的场景是,需要在上下文变化时随时改变计算。如果我希望销售人员在所选地区的销售百分比发生变化,需要根据每个地区的总销售额重新计算。每当用户选择切片器中的另一个区域时,就会发生这种情况。
相反,有时您只能使用计算列。度量值不能用作切片器中的筛选器,也不能用作页和报表级别的筛选器。在这些情况下,如果使用计算作为筛选器的来源,则必须使用计算列。
我希望对 Power BI 中计算列和计算度量之间的差异的概述是有帮助的。即使有这种解释,适应它们并理解何时在适当的空间使用它们也需要时间。希望对你来说,这会发生得快一点。但是不要放弃。最后,你会对它们的能力和实用性感到满意。
罗德蓖麻 帮助公司获得正确的分析!他与国际组织和小型企业合作,以改善他们的数据分析工作、数据科学、技术战略和技术领导力。除了咨询,Rod 还喜欢公开演讲、教学和写作。你可以在rodcastor.com和applied ai . us了解更多关于罗德和他的作品。
功率 BI 柱 vs 测量。我应该在什么时候使用哪一个?
…在我刚开始的时候,本可以使用这些说明。
罗伯特·阿纳奇在 Unsplash 上的照片
为什么有计算列,为什么有度量?我应该使用哪一个?哪个更快?我什么时候使用它?
这些都是好问题。我刚开始的时候也问过自己同样的问题。随着我更多地使用 Power BI,我意识到它们非常不同,工作方式也不同。越早知道这些区别越好。
怎么会?首先,它们在 Power BI 中的加载方式不同,对视觉效果的影响也不同,而且一个处理行上下文,另一个处理过滤上下文。
但是在我们深入研究之前,让我们先来看看它们到底是什么,我们还将浏览一个例子:)
计算列
计算列是在数据视图中逐行计算的列。它们占用计算空间并增加文件大小**。对于被认为属于**“缓慢变化”类别的数据,应完成计算栏。
工资等级就是一个很好的例子。一个人的工资每月不会有太大的变化,一个工资等级可以意味着与整个公司相比,他们是处于低端、中间还是更高的工资范围。
不过,根据个人的工资等级来看他们的表现可能很重要。此类别不能在度量中,因为您不能基于度量筛选报表。这将是一个用作计算列的好例子。然后,您可以根据这些括号过滤您 PBI 报告。
另一个很好的例子是工作地点——根据不同的地点,了解每个地点的表现非常重要。您可能需要将多个城市合并到区域中并筛选报表,因此您需要一个计算列来完成这项工作。
这里有两个主要问题要问自己是否应该使用计算列。
- 我需要该列的结果来过滤我的报告吗?
2。这是一个“变化缓慢”的字段吗?例如,年龄、工资级别或工作地点?
如果您回答“是”,您可能应该构建一个计算列。
措施
基于用户与报告的交互在现场计算测量值**。测量结果不会在刷新期间加载,而是在现场计算。使用 CPU,不增加文件大小。**
这方面的一个很好的例子是销售的产品,销售的产品应该是一个衡量标准,因为它将被工资等级和公司位置“切割”。
另一个例子是员工的社交媒体活动分数(一个基于他们登录公司网络论坛的次数和回答顾客问题的数量的分数。等等)。您可能希望根据年龄类别和地区了解员工在社交媒体上的活跃程度,然后与他们的表现进行比较。你可以为此建立一个衡量标准。
如果您想构建一个度量标准,需要问自己两个主要问题。
- 我需要用户选择的数据结果快速变化吗?
2。这些数据会以某种方式被聚合、分割吗?
如果你的答案是肯定的,你应该建立一个衡量标准。
让我们看一个简单的例子。
这里我有一个简单的模型,这个数据库按日期跟踪销售额,有多个销售人员 id 以多对一的关系连接到 staff 维度表。商店和日期表也是如此。
在这里,我想筛选按员工工资销售的产品。我应该用一个衡量标准吗?
嗯,那会相当困难。薪资栏有多种薪资。从 UX 的角度来看,最终用户很难仅仅为了过滤报告而选择多个薪金。(例如,他们必须选择 55001、55020、56000,以获得 55000–56000 的范围)。最好创建一个薪资等级列来过滤报告。我需要建立一个计算列。
我还想按城市进行筛选,看看员工的表现如何。由于有多个城市,最好将它们合并到区域中。我还需要为此建立一个计算列。
您可以通过 Power BI 中的宁滨函数构建这些列,或者选择在 Power Query 中构建一个条件列。最佳实践实际上是在 Power Query 中这样做,但是有时您可能想要快速完成,您也可以在 Power BI 中这样做作为测试。如果这是最终要保留的东西,你应该在 Power Query 上做。
那么这个模型中的度量是什么呢?
你想报道什么?想想这个问题——你打算汇总什么?在这里,我需要根据地区、工资等级等来比较销售的产品。我需要为此建立一个衡量标准。
如果你需要更多关于开始使用 power query 的信息,这里有一篇关于它的文章。
作者图片
以绿色突出显示的是计算列,以紫色突出显示的是用于构建度量的列。
在这个模型中,我现在可以根据工资级别、地区进行筛选,并比较产品销售和活动得分的衡量标准。
如果你仍然停滞不前,什么都没有意义,坐下来问自己这个问题。
您想报告什么内容,使用什么过滤器?
如果你能回答这个基本问题,你就会对什么应该是度量值,什么是计算列有一个大致的概念。
见下文—
作者图片
也许我过于一般化了,但是我已经用这个问题来帮助我思考各种各样的 Power BI 报告,我希望它也能帮助你。
请记住,关键是要有一个好的模型,一个有意义的模型,然后才能决定度量值和计算列。
拥有一个好的模型可以让你在未来免除很多头疼的事情!我一直在那里挑灯夜战,但模型仍然不工作。不要走那条路。
希望这有助于保持安全!😃
Power BI 连接到 Azure 数据块
在 Unsplash 上由 Carlos Muza 拍摄的照片
派生 Spark URL 并创建一个用户令牌,PowerBI 使用该令牌在 Azure Databricks 中进行身份验证
作为一种数据分析工具,微软的 PowerBI 最近变得越来越受欢迎。此外,对于一个公司来说,拥有一整桶包含 Azure 的微软产品是普遍存在的。
Azure Databricks 是 Azure 平台中最受欢迎的服务之一。它利用 Apache Spark 在分布式环境中处理数据,这可以显著提高性能。Azure Databricks 还支持 Delta Lake,这是一个分布式环境中的开源存储层。它的使用与大多数传统数据库管理系统非常相似,因为它支持 ACID 事务。
本文将展示如何使用内置连接器从 PowerBI 连接到 Azure Databricks 表(Delta Lake)。棘手的部分是“Spark URL ”,这将在后面强调。
样本数据表准备
由于本教程的目的只是介绍将 PowerBI 连接到 Azure Databricks 的步骤,因此将创建一个示例数据表用于测试目的。首先,让我们创建一个包含几列的表。一个日期列可以用作“过滤器”,另一个列用整数作为每个日期的值。
我们先在 Azure Databricks 中创建一个笔记本,我愿意称之为“PowerBI_Test”。
为测试目的创建一个数据库。
%sql
CREATE DATABASE TEST_DB;
然后,导入必要的库,创建一个 Python 函数来生成包含上述列的 Pandas 数据帧。
from datetime import datetime, timedelta
import numpy as np
import pandas as pd# Create date df in pandas
def create_date_table(start='2020-01-01', end='2020-03-01'):
df = pd.DataFrame({"date": pd.date_range(start, end)})
df['day'] = df['date'].dt.weekday_name
df['date'] = df['date'].dt.date
df['value'] = np.random.randint(100, size=df.shape[0])
return df
现在,我们可以从熊猫数据帧中生成 Spark 数据帧,并将其保存到 Delta Lake 中。
date_pdf = create_date_table()
sample_table = spark.createDataFrame(date_pdf)
sample_table.write.format('delta').mode("overwrite").saveAsTable('TEST_DB.sample_table')
以下是表格的预览:
Azure 数据块 URL 和用户令牌
苏珊·霍尔特·辛普森在 Unsplash 上拍摄的照片
要从 PowerBI 连接到 Azure Databricks,我们需要两个重要的“密钥”,即 URL 和用户令牌。
如何获取 spark 网址?
- 从左侧导航中,转到“Cluster”选项卡。
- 从群集列表中,单击选择要使用的群集。这将把页面导航到集群编辑页面。
- 在群集编辑页面中,单击“高级选项”以展开该部分。
- 选择“JDBC/ODBC”选项卡。这里会有很多信息,但我们只需要关注“JDBC 网址”。
5.将整个 URL 复制到某个文本编辑器中。这个 URL 不能直接使用,我们需要从中“派生”出正确的 URL。
以下是我从“JDBC 网址”文本字段中复制的网址:
jdbc:spark://australiasoutheast.azuredatabricks.net:443/default;transportMode=http;ssl=1;httpPath=sql/protocolv1/o/***************/****-******-*******;AuthMech=3;UID=token;PWD=<personal-access-token>
方括号中显示了我们从该 URL 中需要的组件:
jdbc:spark[://australiasoutheast.azuredatabricks.net:443/]default;transportMode=http;ssl=1;httpPath=[sql/protocolv1/o/***************/****-******-*******];AuthMech=3;UID=token;PWD=<personal-access-token>
我们还需要在前面加一个协议,就是HTTPS
。因此,最终的 URL 将如下所示:
[https://australiasoutheast.azuredatabricks.net:443/sql/protocolv1/o/***************/****-******-*******](https://australiasoutheast.azuredatabricks.net:443/sql/protocolv1/o/***************/****-******-*******)
如何获取用户令牌?
我们需要创建一个用户令牌来进行身份验证。
首先,在右上角找到用户图标。单击图标,然后在下拉菜单中选择“用户设置”。
在“用户设置”页面中,单击“生成新令牌”按钮。在弹出窗口中,输入注释字段,该字段将用于提醒您该令牌的用途。
“生命周期”将决定多少天后令牌将被自动吊销。请注意,如果未指定令牌寿命,令牌将无限期存在。
点击“生成”按钮后,将生成一个令牌。
*** 重要提示* **一旦点击“完成”按钮,您将无法取回令牌。因此,请确保您现在复制令牌并将其保存到一个安全的地方。
PowerBI 连接到 Azure 数据块
现在,我们可以从 PowerBI 中的 Databricks 获取数据。
在 PowerBI 中,点击“获取数据”>搜索“Spark”>在列表中选择“Spark”>点击“连接”按钮。
在弹出窗口中,将 URL [https://australiasoutheast.azuredatabricks.net:443/sql/protocolv1/o/***************/****-******-*******](https://australiasoutheast.azuredatabricks.net:443/sql/protocolv1/o/***************/****-******-*******)
填入“服务器”文本字段。
然后,选择“HTTP”作为协议。对于“数据连接模式”,我们选择“DirectQuery”。这是因为当我们在实践中需要 Azure Databricks 时,我们很可能会处理大型数据集,所以在这种情况下,将所有数据导入 PowerBI 并不是一个好主意。
点击“OK”按钮后,我们将能够看到当前 Azure Databricks 集群中的所有表。如果集群中有很多表,我们可以在导航器中搜索这些表。然后,单击“Load”按钮将该表添加为数据源。当然,在实践中可以一次导入多个表。
现在,我们可以从三角洲湖创建可视化。
摘要
照片由 Aaron Burden 在 Unsplash
本文展示了如何从 Microsoft PowerBI 连接到 Azure Databricks。最关键的步骤是从 Azure Databricks 获取 Spark URL 和用户令牌。
希望这篇文章可以帮助数据科学家/工程师直接从 Azure Databricks 创建可视化。
作为一个媒体会员,你的会员费的一部分会给你阅读的作家,你可以完全接触到每一个故事…
medium.com](https://medium.com/@qiuyujx/membership)
如果你觉得我的文章有帮助,请考虑加入 Medium 会员来支持我和成千上万的其他作者!(点击上面的链接)
为凡人嵌入的能量 BI
https://pix abay . com/photos/table-spanner-embedded-漆面-2584957/
好人
Power BI 已经成为市场上最强大、最常用的数据可视化和分析工具之一。它有许多令人惊讶的功能,但我最喜欢的一个很酷的功能是嵌入功能。简而言之,Power BI Embedded 允许将任何发布的报告作为独立 web 应用程序的一部分呈现。我现在对 SharePoint 部件有些怀念😂。这意味着用户没有被限制或要求拥有 Power BI 许可证。这个用例对于开发由 Power BI 支持的 web 应用的 ISV 非常有用。
坏的和丑的
如果我没记错的话,Power BI Embedded 已于 2018 年左右推出。它最初被绑定到一个叫做工作空间集合的东西上,现在这个东西已经退役了。自最初发布以来,API 发生了一些变化,而且像 Power BI Premium 这样的新服务已经发布,以服务于更多的企业场景。我已经使用旧的 workspace 集合完成了 Power BI Embedded,并希望尝试最新的 API,看看它是如何工作的。作为一个务实的人,我的动机是在 web 应用程序中嵌入优化问题解决方案的可视化。优化是使用 Google 或-Tools 完成的,我发现了很多很酷的视觉效果来展示这个解决方案,这比渲染 HTML 表格之类的东西更有吸引力。
但正如我们所知,生活并不总是彩虹和飞翔的独角兽。微软的文档总体来说相当不错,但是对于 Power BI Embedded 来说,有些地方有点模糊。因此,我想准备一个简单的说明手册,介绍如何使用 Power BI Embedded,其中一个常见案例有时被称为“应用拥有数据”。这个概念很简单,应用程序拥有对报表和底层数据的完全访问权限,并且报表呈现在其中一个应用程序页面中。用户不需要使用 Power BI 进行身份验证。他们可以无缝地查看报告并与之交互。
所以如果你喜欢 Power BI,那就来看看怎么嵌入吧!
因为不是每个人都有有效的 Power BI 许可证,所以最好从免费的 Office 365 E3 试用订阅开始,并在该租户内注册一个月的 Power BI Pro 试用许可证。Office 365 和 Power BI Pro 都不需要信用卡信息。Office 365 租户附带了一个捆绑的 Azure Active Directory,这是这个过程中需要的。
本教程将使用以下工具:
- 超级商务智能桌面
- 。网芯 3.1 SDK
- Visual Studio 代码
- NodeJs
1.准备要嵌入的报告
我们可以选择任何 Power BI 报告在这里使用,但我想使用一个带有直接查询数据源的报告。原因是直接查询对于嵌入场景可能非常有用,因为我们不需要担心数据刷新等问题。所以我首先创建了一个 Azure SQL 数据库,并用 AdeventureWorksLT 数据库初始化。我有一个 Azure 订阅,而不是之前提到的 Office 365 试用版,所以不要搞混了。使用导入模式的报告也可以很好地工作。因此,如果您无法访问 Azure SQL 数据库,请在 Power BI desktop 中创建任何报告,并跳过几个段落,直到创建工作区并发布报告的步骤。
一旦创建了数据库,我们必须配置防火墙规则(底层 SQL server 的)以允许来自其他 Azure 服务和我的本地机器的访问。
之后,我们可以创建一个新的 Power BI 报告(当然使用 Power BI desktop ),以可视化与我们的示例数据相关的任何内容,例如每个客户的销售额。正如我提到的,该报告设计有一个直接查询数据源,允许实时反映数据库状态。
要使用的报告没有什么特别的,对我来说,它类似于一个简单的SELECT SUM(Amount) FROM Sales GROUP BY Customer
语句。
该报告必须发布,以便 Power BI Embedded 以后可以访问。但是要发布,我们得先有一个工作空间。使用 Office 365 租户的管理员帐户登录 Power BI,并创建如下所示的工作区来存放报告。
然后将报告从 Power BI desktop 发布到上述工作区。对于具有直接查询模式的报告,将要求您重新输入报告中数据集的凭据,但除此之外,报告在浏览器中应该工作正常。
2.创建嵌入服务主体
在我们的例子中,为了使嵌入尽可能无缝,我们将使用服务主体。可以把它想象成一个服务帐户,它被授予了对某个资源的足够的权限,这样应用程序就可以使用分配给这个服务主体的凭证对这个资源调用 API。
要创建服务主体,请打开与我们的 Office 365 租户链接的 Azure AD。只需打开portal.azure.com并使用相同的管理员凭证登录。从侧边菜单或搜索框中,找到 Azure Active Directory 并单击名为应用注册的链接。在此页面中点击新注册。只需提供一个名称,然后单击创建。
创建之后,我们需要记下应用程序和租户 id,因为我们以后会用到它们。有些两个标识符有时被称为客户端 Id 和租户 Id。
我提到过服务主体拥有某种凭证。在当前应用程序的同一个页面中,单击证书&机密,创建一个客户端机密并复制值,因为在此之后将无法访问该值。不过,对客户端机密的描述是任意的。
在 Azure AD 中要做的最后一步是创建一个组,并将新创建的服务主体添加为组成员。我们稍后会看到为什么需要这样做,但现在,在 Azure AD 主页中单击 Groups 链接,创建一个名为 Power BI Embedding Users 的新组(属于安全类型),并在创建页面中将之前创建的服务主体作为该组的成员。
3.配置 Power BI 以使用服务原则
现在我们已经完成了 Azure AD 并创建了一个服务主体,我们需要切换到我们的 Power BI 网站(https://app.powerbi.com)来授予对之前创建的工作区上的服务主体的访问权限。但是要允许 Power BI 使用服务原则,必须首先对其进行配置。从 Power BI cog 按钮中,选择管理门户。
单击租户设置菜单项,然后确保启用开关在应用程序中嵌入内容并选择指定安全组并添加我们之前创建的安全组。
对做同样的事情,允许服务主体使用 Power BI API。
接下来,在 Power BI 中打开工作区页面,选择工作区访问。
然后搜索服务主体并将其添加为一个管理员。
4.将报表嵌入到 web 应用程序中
唷,为嵌入做准备要做很多家务,但是我们就快到了。剩余任务的一般模式如下:
- 使用后端 web API 开发 web 应用程序
- 后端 web API 负责使用存储在后端的服务原则信息/凭证来生成嵌入令牌
- 前端将使用嵌入令牌来呈现报告
听起来很容易,我们开始吧。
首先,用 dotnet 核心后端 web API 创建(实际上是搭建)一个 react web 应用程序。
dotnet new react -o EmbedWeb
cd .\EmbedWeb\
cd .\ClientApp\
npm install
npm install caniuse-lite@latest --save
caniuse-lite
行是必需的,因为在编写时当前模板有一个过时的依赖关系,它阻止了应用程序的运行,因此需要升级这个 npm 依赖关系。
现在使用 Visual Studio 代码打开EmbedWeb
文件夹,使用Ctrl + ``打开一个终端窗口。在终端窗口中,执行
dotnet watch run`。
让我们点击 HTTPS 的网址,看看这个应用程序是否还活着。
很好,现在一切都好。在第二个终端窗口中,添加几个后端 nuget 包,负责与 Azure AD & Power BI REST API 交互。这将在第一个终端窗口中触发另一个构建,几秒钟后,如果您想确保没有任何损坏,网站应该会有响应。
dotnet add package Microsoft.Identity.Client
dotnet add package Microsoft.PowerBI.Api
在EmbedWeb
文件夹的根目录下,添加一个名为Embedder.cs
的新文件,并将以下内容复制到其中。
您需要更新客户端 Id、客户端密码和租户 Id 的值。这些值可以在 Azure AD 中创建的服务主体的主页中找到。用您自己的值保存文件,并确保它在dotnet watch
的终端窗口中构建良好。
以下是该文件的简要说明:
GetAppOnlyAccessToken
负责生成一个访问令牌来调用 Power BI REST API。此方法使用新的 Microsoft 身份验证库。NET(MSAL.NET)在 nuget 包Microsoft.Identity.Client
中发现。GetPowerBiClient
使用这个访问令牌来实例化一个类,该类抽象了针对 Power BI API 的 REST 调用,这样我们就可以简单地调用方法并获得类型化的响应等等。这就是 nuget 包Micorsoft.PowerBI.Api
中发现的 Power BI SDK 的全部要点。GetEmbedInfo
方法使用 Power BI SDK 客户端对象获取报表元数据并生成嵌入令牌。生成 embed token 的调用配置为顺便获取一个允许编辑的 token。关于 RBAC 和安全有很多要说的,但是现在,让我们假设如果我们想的话,我们可以有只查看模式或编辑模式的令牌。
这个Embedder
类是一个助手类,可以从 web API 控制器调用,因此创建嵌入令牌是在后端完成的。此外,将服务主体细节直接硬编码到其中也很简单。
旁注: 本文末尾的参考资料部分有几个 YouTube 视频,由 Ted Pattison 制作,解释了许多其他有用的关于 Power BI 嵌入认证模式的细节。
我们已经完成了 helper 类,所以是时候拥有一个 web API 控制器了。添加一个名为EmbeddingController.cs
的新文件,但这一次它必须进入 controllers 文件夹,并在其中粘贴以下代码片段。
您必须提供您的工作区和报告的 id。如果你想知道如何得到这些东西,有一个简单的窍门。只需打开 Power BI 上发布的报告,查看浏览器地址栏中的网址即可。
https://app.powerbi.com/groups/<**GUID1**>/reports/<**GUID2**>/ReportSection
GUID1 是工作区 ID,GUID2 是报告 Id。现在保存文件并确保构建成功。为了确保我们的后端部分正常工作,打开一个新的 PowerShell 窗口并curlweb API 端点,它应该是https://localhost:5001/embedding。
后端部分已经完成,所以下一步也是最终目标是在我们的 web 应用程序中有一个 HTML 页面来呈现与 Power BI 服务相同的报告。
同样,Power BI SDK nuget 包也有一个面向 JavaScript 世界的 npm 包。这个 npm 包可以用来做很多事情,但是我们将只讨论嵌入部分。
在终端窗口而不是构建/监视窗口中,添加 Power BI npm 包。
cd .\ClientApp\
npm install --save powerbi-client
现在用以下内容替换ClientApp\src\Components\Home.js
react 文件的内容。
上面的代码片段只做了两件事:
- 调用 web API 端点来获取嵌入令牌
- 使用 Power BI JavaScript 库,通过获得的嵌入令牌来嵌入报告。
此外,将下面的 CSS 片段添加到custom.css
文件中,为呈现的报告添加一些真实属性。
.full-width
{
width: 100%;
height: 800px;
}
现在转到浏览器并刷新页面。
很好,嵌入是可行的,因为我们在前端和后端都支持编辑,我们甚至可以编辑报告并保存更改。
最后要测试的是直接查询模式。这不是与嵌入相关的核心问题,但也是可以尝试的。因此,让我们随机化每个客户订单的总到期金额(这是一个包含 sub total 列的计算列)。
UPDATE [SalesLT].[SalesOrderHeader]SET SubTotal = ABS(CHECKSUM(NewId())) % 120000
现在刷新页面,您将得到一个完全不同的模式来反映数据库的当前状态。直接查询非常酷,尤其是源数据几乎是预先聚合的或者很容易提取的。
包裹
我希望您现在了解 Power BI 嵌入工作流中涉及的核心活动部件。还有其他需要考虑的事项,下面的参考资料部分有一些提示。需要强调的另一点是,生产环境需要 Power BI 专用容量。
引用一点文档:
将嵌入令牌与 Pro 许可证一起使用旨在进行开发测试,因此 Power BI 主帐户或服务主体可以生成的嵌入令牌数量是有限的。专用容量需要嵌入生产环境中。对于使用专用容量可以生成多少嵌入令牌,没有限制。
简而言之,拥有专用容量的最简单方法是创建 Azure Power BI 嵌入式资源。它按小时计费,可以暂停/重启以节省成本。
然后将它与包含要嵌入的报告的工作区链接起来。
快乐嵌入😀
资源
了解如何使用 Power BI APIs for embedded 将报告、仪表板或图块集成或嵌入到应用程序中…
docs.microsoft.com](https://docs.microsoft.com/en-us/power-bi/developer/embedded/embed-sample-for-customers) [## 具有 Power BI 的服务主体- Power BI
服务主体是一种身份验证方法,可用于让 Azure AD 应用程序访问 Power BI 服务…
docs.microsoft.com](https://docs.microsoft.com/en-us/power-bi/developer/embedded/embed-service-principal)
Power BI 考试— DA100
一些传球的技巧
我今天早上做了 DA100 测试,通过了。我有大约 2 年的 Power BI 经验,但我仍然需要学习很多东西。
我写这篇文章是为了帮助你准备考试。
由于保密协议,我不打算在这里列出任何问题,但我可以说考试包括了考试大纲上列出的所有内容。我甚至不认为有什么遗漏。微软的大纲非常准确,我没有学习大纲上没有的东西。
有一些课程可以帮助你准备考试,但是说实话,微软的模块和学习路线已经非常简洁了。我做的所有测试都在大纲上。即使不是答案之一,也是出现的选项之一。
为考试做准备
运用概念——你需要运用你所学的知识。如果你在学习记忆不同连接的定义,或者课文内容。替换函数对你没有任何帮助。你当然需要知道它是什么,但更重要的是如何应用它。
举个例子,
你可能知道如何在可视范围内到达 TOPN,但在计算范围内呢?你可能知道什么是分解树,你如何在商业环境中使用它?
交叉过滤,什么时候用?
当然还有连接的类型,多对一,一对多,以及连接的类型。这里可以看。
你知道使用 M 函数的基本知识吗?你也可以在这里阅读。在考试大纲中的“利用 Power Query 中的高级编辑器编辑 M 代码”一节下。
问题风格 —转到学习见解并在那里做一些测验。我可以说那里的问题真的帮助了我。
当你不明白的时候,我知道这种感觉。我一遍又一遍地查找角色级安全性和直接与导入查询。直到我在 C urbal 上看到几个视频,它们才帮助了我。有时候,看个视频更好。另外,微软指导文章也有帮助。
做 模块**——**微软在他们的网站上提供模块,其中包括如何通过考试的学习途径。我做了模块。嗯——我已经尽我所能了。如果我已经知道如何做某些事情,我会跳过它。然而,如果有新的东西,我会花时间去学习和做。我不经常使用书签,我花时间在实验室里制作它,也在日常工作中使用它。
使用 学习路径——它写得很好,很简洁,对考试有帮助。考试中学习路径的“知识检查”部分有什么问题吗?遗憾的是没有,看起来大多数问题都是基于应用你所学的概念。
测试你的系统— 学习的时候,别忘了做这件事!测试您系统的链接应该来自您注册的考试公司,并且应该在您注册考试后出现在您的电子邮件中。尽早进行系统测试,这样你就不会因为在。
考试前
提前喝你的咖啡——如果你正在远程写作,考试期间你不能喝咖啡或任何东西。为什么?我不知道。水?我不知道,但可能也不会。
整理你的工作空间——你需要整理一下。你不能有任何笔记本、铅笔或钢笔。你不能写下任何东西,你必须在头脑中建模。除了你的笔记本电脑和两张身份证,我什么都没有。您将被要求拍摄您的工作站和身份证的照片。如果考官(他们称之为监考人)同意,他们将开始考试。不要让书、文件和孩子跑来跑去,让他们的生活变得艰难。
摘下你的耳机——我想戴上我的降噪耳机去考试。不允许。
作者图片
考试期间
调查 —你必须先完成一项调查。它会询问您对 Power BI 的总体体验。我只是实话实说,我有 2 年左右的经验,我和一个比我级别高的团队一起工作。没有必要假装比你实际上有更多的经验。不知道这个调查对考试有没有影响。
仔细阅读— 不要急着写下任何答案。仔细想想。有时候大声朗读会有帮助。加入多对一关系的 A 和 B 与加入一对多关系的 A 和 B 之间有一个巨大的**差异。仔细阅读。有时候考试就是要求选择中的两个答案。仔细阅读。**
技术问题——我至少遇到过两次…你能相信吗?它发生了,我不知何故断开,只是重新加载,并让考官知道。你不会失去你所有的工作,所以不要担心。
你被录下来了 —你被摄像头拍下来了,会被录下来了,所以不要做什么尴尬的事。
制定策略——也许这是常识,但在最紧要的时候你可能会忘记。如果不知道答案,不如慢慢看,缩小选择范围。当我慢慢读的时候至少有 2 个问题,当它对我有意义的时候再读一遍。有时候,这只是一个微小的措辞,会帮助你排除一个选择。
例如,您可能有 4 个选择,其中两个是关于表函数,另外两个是列表函数。如果你能首先找出哪个函数符合这个问题,你就已经排除了 50%的选择。
复习 —如果有几个问题你有一定把握,但需要再思考一下,可以设置为“复习”,之后再复习。你不可能回答所有的问题,但是大多数问题。
考试结束后
结果立竿见影——一旦你提交了考试,你就会看到你是否通过了考试。说实话,太突然了,我都不知道自己已经过了!
事实上,我不得不发信息给考官,看看我是否还需要做其他事情,他们回复说“再见”。我想就这样吧。
证书 —你会在你的学习仪表板上看到你的证书,这个考试两年内有效。
作者图片
祝你好运!
电源 BI 功能—(列表。包含,列表。包含任何,列表。包含所有)
…数据之旅的有用工具。
马蒂亚斯·海尔在 Unsplash 上拍摄的照片
本文将向您介绍包含列表的函数。这是一个很好的功能,可以用在电源查询中。每一个都有细微的差别,但是我希望这篇文章能帮助你开始。
幂查询中的列表用{}括号写。它们可以是{1,2,3},甚至是{1,“a”,123}。如果你喜欢实验,可以去 Power Query >创建空白查询>高级编辑器>替换源信息为> Source = {1," hello ",123}。
记住这一点很重要——Power query 中的列可以包装在{[Column A]}中以返回一个列表,这样就可以使用列表函数。您也可以参考表[A 列]返回一个列表。
但是两者有所不同——在下面的数据集中使用{ [ID] }创建一个新列会为每个“单元格”返回一个值。使用#“Previous Step”[ID]返回嵌套在"单元格"中的整个列表。
作者图片
在深入研究之前,先看看如何在本文中构建一个 Power BI 数据模型。Power BI 中的模型与 Access 和 SQL 数据库略有不同。
如果你想知道如何应用 Power BI — 中的函数,这里有一篇好文章。
现在回到这个话题,为什么这些列表函数会有帮助呢?当您想要在数据集中的各个列中放置一个列表来检查条件时,这很有帮助。
当然,您可能可以在 Power Query 上使用条件列功能区,但是列出您希望检查的所有特定项目会非常繁琐。
您还可以对支持表进行各种连接,但之后的清理工作也会很繁琐。你可以写 if 语句,但是如果你的列表很大呢?
让我们一起来看看这些函数。
列表。包含任何
列表。ContainsAny —下面是函数的分解。
找出列表{1,2,3,4,5}包含 3 还是 4。
作者图片
List.ContainsAny({1, 2, 3, 4, 5}, {3, 4})
返回 TRUE —因为{1,2,3,4,5}的列表中有任何 3 或 4
List.ContainsAny({"A", "B", "C", "D", "E"}, {"F", "G"})
返回 FALSE—“F”或“G”不在{“A”、“B”、“C”、“D”、“E”}列表中
列表。包含
列表。包含——这里是功能的细分。
作者图片
查找列表{1,2,3,4,5}是否包含 3。这里的函数将是
List.Contains({1, 2, 3, 4, 5}, 3)
返回 TRUE
然而,你可能需要小心你所观察的物品。您要查看的项目没有{}。与最后一个值进行比较的是期望的是一个值而不是一个列表,所以下面返回 false。
List.Contains({1, 2, 3, 4, 5}, {3})
返回 FALSE。
列表。包含所有
现在不是单个值— 列表。如果 ContainsAll 能够将列表中的所有项目与您想要比较的列表进行匹配,它将返回 True。
List.ContainsAll({1, 2, 3, 4, 5}, {4, 5})
返回 TRUE-4 和 5 都在列表中。
因为这个函数需要一个匹配的列表,并且在 Power Query 中是逐行布局的,所以您需要首先嵌套这个列表,这样才能工作。(下面有更多相关信息)
让我们看一个例子。
我在 power query 中有一个表,我将使用 add columns 特性添加额外的列来使用我们的 contain 函数。
作者图片
让我们添加使用列表的第一列。包含使用“添加列”按钮。
结果会是这一栏。
让我们创建我们的第一列。我想检查 Store_Number 1 是否在列中的任何位置。
这里,该列表示在商店编号列中有一个商店编号 1。
作者图片
我还想检查是否有商店编号 1,并且任何评论都包含“太棒了”这个词。
作者图片
最后一列,我想检查我的所有评审标准— {“很好”、“很好”、“嗯”} —是否都出现在该列中。
作者图片
这张特别的单子。ContainsAll 与其他的有些不同。
如果您像其他人一样使用定制列,那么由于 Power Query 中的行上下文,它将不起作用。
直觉上,如果你试着做—
List.ContainsAll({[Reviews]},{“Great”,”Good”,”Meh”})
实际上将返回 FALSE,即使您在此列出的项目都在列中。
这里的问题是行——如果您只是引用列,Power Query 会获取列的“单元格”,并对照列表{“Great”、“Good”、“Meh”}进行检查,然后返回 FALSE。这个特定的“单元格”不包含列表中的所有项目,所以它返回 FALSE。
当我们使用列表时。包含任何,列表。包含,它们返回正确的值,因为即使它对每个值进行检查,它仍然会得到我们想要的。这里的区别在于,我们希望在与列表进行比较之前,将整个列嵌套在一个“单元格”中。
这就是我们需要写作的原因。
List.ContainsAll( #PreviousStep[Reviews],{“Great”, ”Good”, “Meh”} )
这里,它将整个列作为一个列表引用——以对照另一个列表进行检查。
结果将返回 TRUE
另外,这两个函数也非常有用。AnyTrue 和列表。AllTrue 。
它们和其他的非常相似,你可以添加其他条件,而不仅仅是检查成员资格。
作者图片
这些函数的伟大之处在于,您可以用 and、or 运算符将它们串在一起,并在数据上创建检查,而不必恢复到连接和多个嵌套语句。
TL:DR ?这是所有这些问题的总结—
列表。包含 —记住要排除搜索项目的{}。
列表。ContainsAll —记住对搜索列表使用上一步的[列名]。
列表。包含任何 —最容易使用。我总是不得不用这个特别的。
列表。任何事实,列表。AllTrue —您可以向它们添加条件。整个条件语句需要用{}包装
作者图片
在 Power Query 中尝试这些功能会很有趣!注意安全!