数据科学用 Excel?
了解最古老的分析工具之一如何促进您的数据科学工作
Microsoft Excel 可能是最知名的数据处理工具。几乎每个人都知道这一点,我们对表格、枢轴、VBA 脚本和图表有自己的恨或爱。我们做每月的业务电子表格,计算假期成本,甚至在 Excel 中处理联系人列表。“Excel”这个词甚至成了“表格”或一组表格的同义词,比如:“嘿,我能给你发一个 Excel 吗?”连你奶奶都用过。毕竟,它从 1987 年就存在了,而且它的网格和表格看起来仍然非常相似。他们可能在设计上做对了什么?
但是等等。数据科学?在 Excel 中??难道数据科学不是关于网络浏览器中大肆宣传的 Jupyter 笔记本,云中的大数据和 Hadoop,GPU 上的深度学习和高级交互图和可视化,以及…?这听起来可能和你所知道的 Excel 相差甚远。嗯,等一下…
获得物理学硕士学位后,我花了十多年时间应用“数据科学”来解决问题。从汽车行业的自动驾驶汽车,到保险领域的风险管理和医疗技术领域的预测性维护,Excel 一直紧随其后。现在,我想与你分享我的经验。
是时候振作起来承认:
Excel 是数据科学的强大工具。
对此可能有很多支持(和反对)的理由。但在开始之前,让我们先澄清一下:我和微软没有任何职业关系,从来没有。
这些是我自己的想法和经验——我可能错了,所以请纠正我!
2D 数据最佳编辑
没有比这更好的二维数据编辑器了。大概这就是为什么 Excel 这么多年来都是同样的布局。这些表格易于编辑、格式化、着色和共享。Google Sheets 是对 Excel 数据编辑设计的明确肯定——但也适用于多个用户。允许多个用户同时编辑是我在 Excel 中怀念的东西(在 SharePoint 和 OneDrive 上丢失数据太多次之后)。分享链接的便利可能也是像 Jupyter 这样的数据科学笔记本背后的成功的一部分。
然而,在 Excel 中,只需按一下[F11]键,就可以使用公司的视觉标识将您的表格变成图表(假设有人花时间设置了主题)。除此之外,内置的表格,过滤器,切片器,分组,窗口分割,单元格公式和其他功能,以及任何替代的表格或数据库编辑器都保持不变。也就是说,只要您对每张工作表的最大行数为 1,048,576,列数为 16,384 没有问题!对于大数据来说,这并不令人印象深刻,但对于实际编辑和查看数据来说,这通常就足够了。
高级分析平台
在一部关于人工智能视角的电影中,DARPA 使用电子表格来说明神经网络如何工作。
DARPA using spreadsheets to explain neural nets
事实上,Excel 有深度学习方法,但也许这不是你首选的工具。但是 Excel 附带了一个分析工具库,可以被激活以释放更多高级功能。前几天,我听到一位微软代表被问到“高级分析和普通分析的区别是什么?”。她回答“使用机器学习的能力”。由于分析工具库通过回归和其他复杂数据分析进行机器学习,我假设微软将 Excel 视为其高级分析平台之一。
无论如何,工具库感觉有点老派,因为在 SAS 或 SPSS 中使用硬编码的函数。现代数据科学是关于开放图书馆和透明度的。也许你出于某种原因想要调整你的高斯混合模型或者了解它是如何被优化的?在 Excel 中做这些或者在Visual Basic for Applications(VBA)中改编一些开源代码可能会很麻烦(在 VBA 你怎么能对一个矢量切片呢?).
编写 Excel 脚本——像数据科学家
当然,您会喜欢使用您最喜欢的数据科学脚本语言(Python、R、Scala、Julia、Java、JavaScript 等等)和可信库。这很好:你可以在 Excel 中使用 Python。至少如果你用的是 Windows 系统的机器(这是我推荐的,因为 Mac 上的 Excel 仍然不是很稳定)。
现在越来越专业了:Python 在 Excel 中的应用
Example data in “Table1” in Excel
要在 Excel 中演示 Python,只需创建一个新的电子表格,并输入一些类似于此处截图的数据。选择所有数据并制作表格[Ctrl+T 或 insert table]。如果您使用的是英文版的 Excel,该表默认为“Table1”。下面的 Python 代码使用包 win32com 与 Excel 的对象模型(一个程序员对 Excel 的接口)进行实时交互。请注意,您得到了一个与正在运行的程序交互的活动连接,我们不仅仅是读写磁盘上的文件。
实时连接到正在运行的 Excel 和活动工作表
import win32com.client
import pandas as pdapp = win32com.client.Dispatch("Excel.Application")
ws = app.ActiveSheet
获取表格内容和标题,放入 Pandas 数据框 注意,我们可以使用 Ranges 以及 ListObjects 等。
x = ws.Range("Table1").Value
headers = ws.ListObjects("Table1").HeaderRowRange.Value[0]df = pd.DataFrame(list(x), columns=headers)>>> df
Product Month Income
0 A January 7358.001583
1 A February 2218.386731
2 B January 5201.179032
3 C January 1765.453011
4 C February 6261.555208
计算每种产品的收入中值,并写回 Excel 中
注意,Excel 在分配范围时总是期望 2D 形状:
income_med = df.groupby('Product').Income.median()ws.Range("A10:A12").Value = (('A',), ('B',), ('C',))
ws.Range("C10:C12").Value = tuple((_,) for _ in income_med)
让我们演示一下 Python 与 Excel live 的交互
为表格设置一个过滤器并选择某个范围:
ws.ListObjects("Table1").Range.AutoFilter(
Field=2,
Criteria1="=January")ws.Range("C10:C12").Select()
上面的例子可以很容易地扩展到几十万行,而不会有性能问题。Python 可以直接访问 Excel 内部的数组存储。与运行 VBA 相比,Python 和 Pandas 在更高的抽象层次上提供了更强的数据操作能力。你也可以很容易地从 SciPy 和其他一些资源中获得科学工具——但是要保持 Excel 作为查看数据的“前端”。
更多可能性
使用 Excel 还有几种进一步分析的可能性。内置的数据库引擎可以对表和动态数据集执行 SQL 查询, Power 查询编辑器可以从各种数据源(包括 Azure cloud 或 Hadoop)获取数据。如果你还没有,还有很多东西值得探索。
数据唾手可得还是数据沿袭?
与数据科学工作流程相比,Excel 可以直接呈现数据。你可以随心所欲,想存多少版本就存多少版本,操纵自如。数据传承,从起点追踪数据的能力,通过操作到目的地或结论,因此很难。另一方面,在数据科学笔记本中,整个操作过程被列为脚本,其他人可以重复和验证。自然,自动化或投入生产的步骤要比笔记本小得多。更不用说处理版本控制和跟踪变更了。
Ad for Excel for Windows 3.0 (released 1990)
对于数据新手来说,Excel 的简单性降低了入门门槛,允许快速开始数据操作。重复任务的功能和宏可以在这个过程中学习。笔记本中的数据科学轨道最初看起来更艰难,但当涉及到更大的操作和更复杂和自由的分析时,它将会给你带来回报。
太早,还是领先?
我认为微软早在 90 年代就推出了 Office 套件。Excel 是一个很好的例子,它将数据仓库、图形用户界面、分析工具和 VBA 脚本环境都放在了一起。开放对象模型使得构建扩展、插件和直接与电子表格的核心交互变得相当容易。Microsoft Access 是另一个类似的、但更面向数据库的解决方案,它将所有这些结合在一起。你可以把它作为一个文件来分享,这不是很棒吗?微软显然是这种数据分析自助服务套件的领导者。在某种程度上,我认为他们甚至太早了。或者是 Excel、Access 和类似工具带来了我们最近看到的数据科学革命?
那些辉煌的日子
可悲的是,Excel 在脚本语言方面远远落后(VBA 是建立在 60 年代发明的 BASIC 之上的),更不用说脚本的版本控制或安全性了。数据容量并不令人印象深刻(即使数据模型可以在内部承载超过 1 百万行)并且 Excel 可能永远达不到大数据水平(不管那是什么)。图形是另一个 Excel 远远落后于开源库的主题,比如 ggplot 和 matplotlib 。显然,微软把所有的精力都放在了数据可视化的 Power BI 上。自从 Excel 成为唯一工具的辉煌时代以来,已经发生了很多事情。
数据科学家:向过去学习
许多超级大国依然存在。我认为 Excel 是几乎所有小规模 2D 数据的最佳编辑器,它被大量使用,有点像共享电子表格的默认编辑器。脚本和分析有很多种可能性,甚至像我们在 Python 中看到的交互方式。也许这就是为什么如此多的组织遭受“Excel 地狱”?绕过顽固的业务系统并构建自己的 Excel 解决方案实在是太容易了。(我知道,我已经贡献了不少了;-))
Depicting the “Excel Hell” (3xcorp)
现代数据科学平台可以从 Excel 中学到很多东西。数据科学就是从数据中学习,从数据中学习意味着从过去中学习。Excel 有很多过往的经验可以分享。也许 Jupyter 笔记本可以找到一种更好的方式来包含数据集以供共享?在线数据科学工作台能否提供更好的界面,以可视化方式快速编辑和格式化数据?有很多种可能。我认为优势在于允许智能存储、编辑、可视化、分析和共享。
对我来说,数据科学一直是关于组合最适合完成工作的工具。通常 Excel 就是其中之一。我不断尝试迁移到 Linux 上的 LibreOffice(享受开放软件,摆脱微软),但仍然经常发现自己启动了一个虚拟的 Windows 机器来访问 Excel 的超级功能。要么是我已经沉迷其中,要么是 Excel 的设计中隐藏了一些伟大之处。无论如何,我认为一个没有 Excel 经验的数据科学家和一个从来没有用过锤子的木匠是不相上下的。我可能会在很长一段时间内继续通过电子邮件向人们发送电子邮件。它仍然是数据交换的最佳格式,允许接收者立即进行自己的分析——每个人都知道这一点。
让你超越自我的工具
总而言之,Excel 已经存在了几十年,毫无疑问,它是编辑和分析表格数据最流行的工具。许多人在日常生活中离不开它。数据唾手可得,而且正如我们所展示的,可以从 Python 脚本和机器学习包中直接访问,您还能期望什么呢?我建议真正探索和学习 Excel,作为一名数据科学家,你将获得令人印象深刻的超能力。
你的体验是什么?
预计支付 215 美元来填写你的 2018 年世界杯贴纸相册
Photo from Emilio Garcia at Unsplash
加的夫大学的保罗·哈珀教授最近计算出如果收集者不与任何人交换她的任何复制品,填写 2018 年帕尼尼世界杯贴纸专辑将花费 773 英镑(1100 美元)。根据教授的计算,如果 10 个朋友互相交换,费用可能会下降到 247 英镑(352 美元)。贴纸专辑的制造商帕尼尼发布了一份官方声明,称哈珀教授假设收藏者生活在泡沫中,不与陌生人交易,从而高估了真实成本。
我最近开始填写我的贴纸相册,我想自己计算一下我应该支付多少来完成它。我写了一个程序来模拟各种交换场景下的贴纸收集,我认为真正的成本接近 290 美元。下面我将向您介绍我是如何设置模拟的以及我的发现。
该设置
自 1970 年墨西哥世界杯以来,帕尼尼世界杯贴纸专辑每四年发行一次。收藏家们成包地购买贴纸,并交换他们重复的贴纸,以便完成相册。今年,该专辑由 682 张贴纸组成。每包售价 1 美元,有 5 张贴纸。
我的模拟做了以下假设:
- 每个标签都同样有可能出现在任何包装中。
- 收藏者只能在互利的交易中交换重复的贴纸*
- 每位收集者从随机抽取的 25 张贴纸开始。
在我的模拟中,有 10 个朋友试图完成这张专辑。在每一个时间点,这 10 个朋友会互相交易。好友间的交易完成后,每个人都有机会和 k 个完全陌生的人进行交易。我对 k {0,2,5,10}的以下值进行了模拟。如果玩家不能和他的朋友或陌生人交易,他就买一包贴纸。当所有 10 个朋友完成相册时,模拟终止。
总而言之,以下是我的模拟所采用的参数和我使用的数值:
- 交易的朋友数量= 10
- 相册中的贴纸数量= 682
- 每包中的贴纸数量= 5
- 每位玩家每轮可以交易的陌生人数量= {0,2,5,10}
- 陌生人在交易前购买的贴纸数量= 100
结果
对于所有的场景,我都进行了 100 次模拟,然后研究了这 10 个朋友花钱的分布情况。因此,每次分配都以 1000 点为基础。
场景 1:不与陌生人交易
在这种情况下,这 10 个朋友只能相互交易。对我来说,这就是哈珀教授计算出的 352 美元的成本。经过 100 次模拟,我发现平均成本是 326 美元,但有很多噪音。成本低至 199 美元,高至 1218 美元。我怀疑正在发生的事情是,一些不幸的朋友是唯一一个收集专辑的人,她需要求助于购买包,直到她完成。
场景二:与朋友交易后可以与 2 个陌生人交易
在这种情况下,结果噪音较小。收藏家们平均花费 215 美元,但也可能从 146 美元到 498 美元不等。
场景三:和朋友交易后可以和 5 个陌生人交易
这种情况下的平均成本是 181 美元。分布的范围正在接近平均值。
场景四:和朋友交易后可以和 10 个陌生人交易
在这种情况下,完成专辑的平均成本是 135 美元。
结论
与陌生人交易将有助于你以更低的成本更快地完成专辑,这是常识,但我的模拟通过量化成本预计会随着与你交易的陌生人数量的增加而减少,从而深入了解这种关系。我发现最令人信服的是,与只和同样的 9 个朋友交易相比,只和两个陌生人频繁交易可以减少 30%的成本。此外,随着陌生人数量的增加,与多一个陌生人频繁交易的额外好处也会减少。要点是,你只需要一点点打破你的泡沫,就能最大限度地降低成本。
最终,我认为哈珀教授和帕尼尼的观点都有道理。帕尼尼是对的,这张专辑的成本和你想要的一样高。如果你不想买很多包,你应该试着和尽可能多的陌生人交易。然而,哈珀是对的,他指出,随着帕尼尼增加专辑中贴纸的数量以及贴纸的价格,专辑的奖金会随着时间的推移而不断增加。考虑到帕尼尼故意提高专辑的价格,期望人们经常与 10 个以上的陌生人交易以保持价格低于 100 美元似乎有点不合理。
我希望这能让你对完成世界杯专辑的成本有一个更好的了解,但这一分析绝非详尽无遗。我邀请你看看我在这个模拟中使用的代码和修改你认为合适的假设。收集贴纸是一件非常有趣的事情,尤其是当你得到你渴望得到的贴纸时,所以我希望我没有阻止你开始收集。如果你在芝加哥,我很乐意和你交易!
附录:
*我还模拟了收藏家只进行一对一交易的场景。关键的要点是相同的,但分布的噪音更小。
“期望管理”或我如何学会不害怕商业演讲
我将写一些关于数据科学项目中的期望管理的内容。现在,这是我个性中学术方面发现的一点“商业用语”。然而,这在商业环境中很重要(可能在非商业环境中也是如此,比如非营利组织)。
值得分享一本呆伯特漫画。只是因为它总是与讨论“商业用语”相关。
版权所有:斯科特·亚当斯和呆伯特
所以下面是我学到的一些小技巧。我分享这些的原因是管理期望是数据科学过程中的一个困难部分。研究和开发类型的工作甚至软件工作都很难,它们很难管理,我们生活在一个期望相当膨胀的世界——许多评论(通常是似是而非和垃圾的)如“人工智能将窃取我们的工作”都于事无补。然而,这就是我们生活的世界。我在这方面并不完美,这是我仍在努力的一项技能,但我想写下我思考过的一些概念和框架。
首先关注简单的事情。即使是交付一个数据集或一些 KPI,在一个没有充分利用数据的环境中也是很重要的。这也有助于你搜索域名。一个好的策略是向人们发送更新——无论是电子邮件更新还是其他方式。我也喜欢把图表打印出来贴在墙上,这样人们就可以看到了。
其次,在你进行的过程中迭代地交付东西。你从一个 6 个月的研发项目中失去的政治资本通常是不值得的。例如,比较您从一些基于 SQL 的产品分析中获得的洞察(比如 6 个月内获得 20 个洞察)和从一个推荐引擎获得的洞察(可能需要超过一个季度才能看到 ROI)。
第三,也会产生负面结果。“我们发现这个功能不够强大”或者这里没有信号。Jonathan Nolis 在这个上写了一篇很棒的博文——这是我在一些雄心勃勃的项目上的经验,遗憾的是,这些项目就是行不通。实验包括接受积极的结果和消极的结果。
有时我们相信数据中的信号比实际的要多!这是可以的。
第四——与商业伙伴建立非常密切的工作关系,这样你就能站在他们的角度考虑问题,让他们成为旅程的一部分,这样即使是很小的决定也是共同的。这是我的朋友 Padraic 给我的,非常重要。向业务利益相关者展示 KPI(关键绩效指标)或分析—帮助他们理解流程,并真正帮助作为数据科学家的您了解什么是重要的以及每个领域的真正含义。
让我们分享一个具体的例子——在我做的一个项目中,结果是还款没有全部存储在同一个列中——所以需要一些时髦的 SQL 和业务流程理解来真正过滤所有的还款。如果你不这么做,很容易得到一个误导性的收入数字——比如收入加还款。我艰难地认识到,向商业利益相关者快速展示结果是非常重要的。
我有一些其他的想法,但这些是我目前的主要想法。对激动人心的研发项目说是非常容易的。然而,你的工作不是对此说“是”,而是为企业创造价值。专注于此,而不是$SHINY_TOOL
我要感谢与詹姆斯·斯坦尼尔、奥利·格拉斯、米克·库尼和罗布·霍顿的对话,这些对话形成了我对此的想法。
在生产中使用 R 和 Python 的经验
从 2016 年 5 月开始,重新分享我们伟大的经历,开始我的新媒体博客。
Python 和 R 是一些最好的数据科学开源工具。它们可以很容易地用于脚本和自定义分析,但作为在线软件的一部分自动运行它们需要更多的考虑。在 Smartly.io,我们已经广泛地使用了这两个工具。在这篇博文中,我将分享我们在生产中集成它们的一些经验。
作为背景,我们需要统计计算的第一个用例是预测预算分配。它自动在多个广告集之间重新分配预算,以优化营销活动中的每次行动总成本。它每天都会自动运行大量的活动。
为了将统计分析与我们在线平台的其余部分分开,我们创建了一个新的微服务。我们想把统计软件用在最合适的地方:做数学运算——并在其他地方做剩下的工作。基本上,服务获得它需要的所有输入数据并给出一个输出。在我们的例子中,输入数据包含所有必要的历史数据(印象、转化、花费、预算等。)并给出新的预算作为输出。下面是一个用 JSON 格式输入输出的简化例子。
Input: { "d": [ { "id": "a", "impressions": 100, "conversions": 5, "budget": 50, "spent": 50 }, { "id": "b", "impressions": 100, "conversions": 6, "budget": 50, "spent": 50 } ] }
Output: [ { "id": "a" "budget_prop": 46, }, { "id": "b" "budget_prop": 54, } ]
最初,我们通过使用 R 创建了微服务。有一些 R 包将自定义 R 库包装到 HTTP API 中,特别是至少有 DeployR 和 OpenCPU 。简而言之,这些服务允许您通过 HTTP 调用 R 函数。一年前,我们评估了备选方案,选择了 OpenCPU 作为我们的案例。我们自己没有尝试其他替代方案,所以我们的实际操作体验仅限于 OpenCPU。
在 Linux 上安装 OpenCPU 非常简单。要使用 OpenCPU,您必须创建一个自定义的 R 库。RStudio 有一个好的文档开始。在 R 中安装了库之后,它将连接到 OpenCPU 服务器,因此您可以通过 HTTP 调用开始调用 R 函数。
例如,在我们的例子中,我们有一个名为BudgetAllocation(d)
的 R 函数,它在数据帧d
中获取输入数据。该功能在我们的内部包smartlybuster
中提供。使用 OpenCPU,我们能够通过 http://localhost:8080/ocpu/library/smartlybuster/R/BudgetAllocation/json 调用 BudgetAllocation 函数,将上述 JSON 作为输入,并获得函数的输出作为响应。
我们在 OpenCPU 上使用 R 大约半年,没有出现任何问题。我们的 R 代码库开始增长,最终我们意识到 Python 更适合我们的目的,因为它是一种更合适的编程语言。最初,我们从 R 代码到 Python 进行了几乎一对一的转换,并在大约一周内完成。对我们的 R 库进行适当的单元测试对转换帮助很大。
对于 Python,我们最终使用了 Flask ,因为它为 Python 提供了类似于 OpenCPU 为 r 提供的 HTTP API。由于我们的 BudgetAllocation 是一个独立的微服务,我们可以很容易地将旧的 R 服务切换到新的 Python 服务。在产品化阶段,我们同时运行这两个程序,以评估结果是否匹配。
从 R 到 Python 的过渡相当简单。通过使用 pandas 库,我们得到了与 r 中相似的数据帧。最大的惊喜之一来自 pandas 如何处理数据帧中的子集和索引。在 pandas 中,获取行的子集会返回一个数据帧,其中的行以它们原来的行号命名。这可以通过一个 reset_index()调用来解决,该调用允许您使用 d.loc[i,’ budget’]类型的访问权限再次访问数据。
Python,pandas 和 Flask 在迁移后对我们来说都很好用。有些部分将受益于以适当的 Python 方式重写。总而言之,我们认为 R 和 Python 都是非常适合的工具,在开发中很容易运行。Python 是一种更适合开发的编程语言,而 R 有更好的统计库。
在未来,我们看到我们可能会同时使用两者。Python 将作为处理大多数情况的主要工具。r 可用于某些特定的统计部分。为了进行这种集成,我们可以继续使用 OpenCPU 从 Python 调用 R,或者切换到特定的集成库,如 rpy2 。
体验数据科学中的“科学”
我从事软件行业已经很长时间了。我扮演过各种角色,但大多数时候我是一名开发人员,或者更正式地说,我是一名“软件工程师”。
今天,我是一名数据科学家。虽然我的工作并没有完全不同,我仍然坐在电脑前写代码,但工作性质不同了。在我开始数据科学之旅后不久,我开始经历沮丧的时刻。这并不是说我不喜欢我的工作,只是偶尔我会因为我当时从事的项目而感到沮丧。大多数时候,那些时刻是我认为我知道我在做什么,而意识到我不知道的结果。今天我已经意识到,这些时刻只是工程和科学之间的差异。
工程有很多定义,在维基百科中总结为:
工程是应用数学,以及科学、经济、社会、实用知识为了发明、创新、设计、建造维护、研究,改进结构、机器
或者在我的简短版本中:
工程是为了解决问题而应用的技术”
是的,也许这个定义太宽泛了,但我想说的是,在工程中,在大多数情况下,我们有一个明确定义的问题需要使用明确定义的资源和约束来解决。像“让我们建造一座支持许多汽车的桥梁”、“让我们铺设一条支持许多人的电线”或“让我们建造一个允许许多用户共享照片的应用程序”这样的问题。
许多人会同意软件开发就像工程一样。我们有一个问题,我们需要解决它。有时,这些是非常困难和重要的问题,在这种情况下,开发人员(或工程师)必须利用他最好的知识、经验和创造力。这就是开发的乐趣所在。你努力工作,你发明东西,最后你解决了问题。开发(工程)很有趣,我喜欢它!
这个过程的一个非常好的特性是能够知道你确实解决了问题,并且能够判断(在大多数情况下)一种方法可能有效而另一种方法无效。这正是工程和科学之间的主要区别(在我看来也是游戏规则的改变者)。
维基百科对科学的定义是:
“以可测试的解释和关于宇宙的预测的形式建立和组织知识的系统企业。”
或者在我的删节版中:
“一种描述现实的方式”
也许这是一个太深奥的定义,但最终科学是一个创造世界/宇宙如何运作的想法(模型)的过程。科学的一个重要属性是它必须是“可测试的”或“可测量的”一旦你有了一个假设,你必须能够测试,测量和重现你的结果,以证明这个理论/想法/模型描述的空间足够好。
在数据科学中,我们正是这样做的。我们有一些问题(如在工程中),我们试图创建一个模型,以尽可能最好的方式描述这个问题(世界),这样我们就可以对我们的问题做出预测/结论。我们用这个模型进行实验,测量我们的结果,确保我们可以重现我们的结果,并最终创建一个产品(或报告)。实验的一个不好的地方是它们可能会失败。此外,与工程不同,我们不能 100%确定我们解决了问题,也很难知道什么方法行得通,什么行不通(这就是实验的目的)。
数据科学家的工作很大一部分是运行实验,实验可能会失败。你可能对你的问题有一个很好的想法,直觉告诉你这个想法一定会大大提高你的模型的性能,你努力开发这个想法,你测试了几天,最后你发现你的想法…嗯,没用。它不起作用是因为你错过了一些东西,因为这个世界并不像你想象的那样工作,因为你没有足够的或不好的(嘈杂的)数据或其他原因。这令人沮丧,或者至少对初级数据科学家(或任何科学家)来说是令人沮丧的,尤其是对软件开发人员(或工程师)来说。
过了一段时间,我开始意识到这是这份工作的乐趣所在。你可能会失败,但当你成功时,那是一种很棒的感觉。数据科学很有趣,我喜欢它!
有一件事比实验失败更令人沮丧。当你实验失败的时候,你知道你在哪里,你知道你尝试过(和没有尝试过)什么,你知道它没有成功(或曾经成功)。经过几次实验后,你会知道什么可能有效,什么可能无效。为了实现这一点,你必须能够知道什么有效,什么无效,这意味着你必须能够衡量你的结果(并且相信你的衡量!).如果你没有一个合适的测量或者你不能重现你的结果,你就完全被蒙在鼓里,这真的很令人沮丧。
如果我有一个给初级数据科学家的建议,那就是你必须为你的问题/实验创建一个值得信赖的测量,无论是通过获得高质量的数据,自己标记还是任何其他方法,你都必须这样做。
基于扩展聚类质心的多数欠采样技术(E-CCMUT)对 CCMUT 的实验改进
在我之前的文章《 基于扩展聚类质心的多数欠采样技术(E-CCMUT) 》中,我提出了一种新的欠采样算法——基于扩展聚类质心的多数欠采样技术(E-CCMUT)。在本文中,我将演示一个实验,在这个实验中,我将证明 E-CCMUT 比 CCMUT 具有更好的统计结果,并且与 E-CCMUT 的直觉相符。
实验:
从人口普查数据中预测一个人的收入水平是否大于 5 万美元 。这与我以前的文章“ 欠采样:不平衡数据的性能助推器 ”中使用的实验相同,其中 CCMUT 被用作欠采样算法,以便通过实验证明欠采样可以提高模型性能。这里,将使用 E-CCMUT 而不是 CCMUT,并将使用在“ 欠采样:不平衡数据的性能助推器 ”中导出的结果进行直接性能比较。
数据集:
数据预处理:
标签编码、特征选择和一键编码按顺序完成,如“ 欠采样:不平衡数据的性能助推器 ”
数据不平衡消除:
这是使用 E-CCMUT 完成的,其中多数类(标签 0)是 68%的欠采样。E-CCMUT 的 Python 实现如下所示:
import numpy as np
from math import sqrtdef **ECCMUT**(X,f):
cluster_centroid = np.sum(X,axis=0)/X.shape[0]
euclidean = [None]*X.shape[0]
for i in range(0,X.shape[0]):
euclidean[i] = sqrt(sum((cluster_centroid-X[i])**2))
# finding the most important instance with label 1
imp_instance = X[euclidean.index(min(euclidean))]
# removing the instances (under-sampling...)
for i in range(0,X.shape[0]):
euclidean[i] = sqrt(sum((imp_instance-X[i])**2))
indices=list(reversed(sorted(range(len(euclidean)), key=lambda
j: euclidean[j])))
X_f = np.delete(X, indices[:int(f/100*X.shape[0])], axis=0)
return X_f
这里,X 是多数样本矩阵,f 是欠采样的百分比,X_f 是 E-CCMUT 对 X 的欠采样形式,它由 ECCMUT()返回
洗牌和拆分:
产生的数据集以一致的方式进行混洗,并且 80–20 分割(80%训练集和 20%验证集)。
学习算法:
梯度推进分类器用作训练集上的学习算法,并使用网格搜索进行调整。
网格搜索后得到 100 个估计量和最大深度为 4 的最优超参数。基于平均分数的模型的网格搜索调整的总结如图 1 所示。
Fig 1. Grid-Search Summary on Mean-Score
结果:
使用度量、训练准确度、验证准确度、召回率、精确度、F1 分数、受试者操作者特征曲线下面积(图 2 所示的 AUROC)和混淆矩阵(图 3 所示)来分析模型性能。
Fig 2. ROC Curve showing the Area Under the Curve
Fig 3. Normalized Confusion Matrix
表 1 中列出了训练准确度、验证准确度、召回率、精确度和 F1 分数。
Table 1
该模型与使用相同方法但使用 CCMUT 开发的模型的比较:
在某些情况下,用于开发机器学习/深度学习模型的数据集通常是…
towardsdatascience.com](/under-sampling-a-performance-booster-on-imbalanced-data-a79ff1559fab)
根据上述文章,CCMUT 所取得的结果被考虑在内。模型性能比较基于以下指标:
- 拟合度量:|训练准确性-验证准确性|
- 验证准确性
- 精确
- 回忆
- f1-分数
- 奥罗克
对照表如表 2 所示:
Table 2
- 在这里,E-CCMUT 在召回率、精确度、F1-Score 和 AUROC 方面的性能没有比 CCMUT 有所提高或下降。
- 在拟合方面,E-CCMUT 比 CCMUT 有了显著的提高,拟合度从 2.1 下降到 1.29。拟合度量越多,验证和训练精度的可比性就越小,因此要么过拟合,要么欠拟合,拟合度量越小,模型就越接近"完美拟合"
- 与 CCMUT 相比,E-CCMUT 的验证准确性有非常轻微的下降(0.24%),这可以忽略不计。
此外,还进行了许多其他实验,并观察到 E-CCMUT 产生了比 CCMUT 更适合的模型,而验证准确性没有显著下降。
因此,E-CCMUT 是对 CCMUT 模型的拟合性能指标的改进,并且证实了在构建算法时所采用的直觉。
[实验模型]实现用于 CIFAR 10 分类的树形深度神经网络[带有 TF 的手动后撑]
Gif from here
所以今天,我想做一个实验模型,昨天晚上我想到了这个网络架构。一种类似树的形状的架构,但是如果你知道任何支持这种创新或网络架构的知名学术论文,请在下面评论,以便我可以提供适当的参考。
更新 Peter Baylies 向我提供了一篇论文,该论文的网络架构与本文中的相似,请点击此处查看该论文。
请注意,这是一个实验模型,因此性能不是我的目标。
再一次,像往常一样让我们比较。手动反向传播方法与传统自动微分模型的比较。如果你不知道自动微分,请点击这里。
网络架构(基本构建模块/完整架构)
黑色矩形 →输入图像
→绿色/红色矩形 →卷积层(内核大小 3)→批量归一化
→黄色矩形 →瓶颈卷积层(内核大小 1)→批量归一化
蓝色圆圈 →加法运算(残差连接)
所以上面的剩余块是我们完整网络的基本块。现在,如果你看到完整的架构,你就会明白为什么我称这个网络为树状网络。(最主要是因为网络的形状像一棵树。)
圆圈 →我们上面覆盖的每个卷积残差块
浅棕色矩形 →全连通网络
橙色矩形 →软 Max 层
所以如果我们把我们的模型旋转 90 度,它看起来就像一棵树!(嗯有点……)
另外,请注意紫色箭头,我们也将做一些不同的事情。
Layer3_a →仅将红框圈和蓝框圈的结果相加。
Layer3_b →仅将蓝色方框和黄色方框的结果相加。
Layer3_c →只将红框圈和黄框圈的结果相加。
紫色箭头不同于粉红色箭头,因为我们没有把所有的变量加起来。
结果(自动微分)
在 100 epoch 上,我们可以看到模型明显过拟合,这可能是由于多种原因造成的。但众所周知,在深度学习模型中,Adam optimzers 并没有那么好地概括。如果您不知道 Adam optimizer,请单击此处的。
结果(破碎的散瞳反向传播)
对于这种情况,手动反向传播是可怕的。这个模型甚至不能达到 40%的准确率。
请注意,我们在前馈操作期间执行了批量标准化,但是,我没有在整个过程中反向传播,因此出现了中断的扩张反向传播。
透明度
为了让这个实验更加透明,我把所有的命令日志从我的窗口提示符上传到我的 Github。查看自动微分产生的输出请点击她的 e,对于手动反向传播请点击此处。
交互代码
对于 Google Colab,您需要一个 Google 帐户来查看代码,而且您不能在 Google Colab 中运行只读脚本,因此请在您的操场上创建一个副本。最后,我永远不会请求允许访问你在 Google Drive 上的文件,仅供参考。编码快乐!
要访问自动区分代码,请点击此处。
要访问手动 ba ck 繁殖模型,请点击此处。
最后的话
我真的很喜欢做实验模型,它们可能不能保证性能,但它们激发了我的创造力。
如果发现任何错误,请发电子邮件到 jae.duk.seo@gmail.com 给我,如果你希望看到我所有写作的列表,请在这里查看我的网站。
同时,在我的 twitter 上关注我这里,访问我的网站,或者我的 Youtube 频道了解更多内容。如果你感兴趣的话,我还做了解耦神经网络的比较。
参考
- 文件?,W. (2018)。解压一个. tar.gz 文件需要什么命令?。Askubuntu.com。检索于 2018 年 3 月 30 日,来自https://askubuntu . com/questions/25347/what-command-do-I-need-to-unzip-extract-a-tar-gz-file
- CIFAR-10 和 CIFAR-100 数据集。(2018).Cs.toronto.edu。检索于 2018 年 3 月 30 日,来自https://www.cs.toronto.edu/~kriz/cifar.html
- j . brown lee(2017 年)。深度学习的 Adam 优化算法的温和介绍-机器学习掌握。机器学习精通。检索于 2018 年 4 月 1 日,来自https://machine learning mastery . com/Adam-optimization-algorithm-for-deep-learning/
- JaeDukSeo/Only_Numpy_Basic。(2018).GitHub。2018 年 4 月 1 日检索,来自https://github . com/JaeDukSeo/Only _ Numpy _ Basic/blob/master/treenet/man 1 . txt
- 自动微分。(2018).En.wikipedia.org。于 2018 年 4 月 1 日检索,来自https://en.wikipedia.org/wiki/Automatic_differentiation
使用 Tensorflow 试验 twitter 数据
Credits — author : Diogo Palhais; illustrator : Tatuna Gverdtsiteli
机器学习和人工智能最吸引人的地方在于,通过使用它们,它让我们有可能开始重新思考一切——你可以从完全不同的角度看待一切,我认为,有时这种“重新思考”的事实是新发明的关键。
几天前我有过这样的时刻,这真的很有趣,我决定写下这个实验。
我大约在 7 年前创建了我的 twitter 账户,但我并没有经常使用它,几个月后,我将它与我的一个网站连接起来,并在上面安装了“自动转发”机器人。在这之后,很多事情都变了,我没有时间建立我的网站,我删除了这个机器人,因为我并不真正喜欢社交网络——我的 twitter 账户已经暂停了几年。
几个月前,我决定开始使用 Twitter。我想和其他人分享我的出版物,我的公开回购(或者不仅仅是我的)——所以这就是我决定重新加入 Twitter 的原因,但是当然,根据我的账户过去的活动,我有兴趣完全不同的追随者。所以,老实说,这对我的动力影响很大。
我决定寻找这样的用户——我也会对他们感兴趣。
起初,当你在 Twitter 上开始活动时,你没有太多的帖子(当然我删除了:D 的旧帖子)和关注者——你关注的人不会关注你的可能性很大,你需要长时间添加真正有趣的帖子,以尽可能最好地展示自己。
我们已经提到了“添加关注者”,所以在我开始写这个故事的主要部分之前,我想分享一下 Twitter 的规则和限制,因为在 Twitter 上对不道德行为的处罚是非常严重的。
以下是一些重要的链接:
要了解更多关于以下内容,请阅读以下常见问题。我们不限制您可以拥有的关注者数量…
help.twitter.com](https://help.twitter.com/en/rules-and-policies/twitter-following-rules) [## 自动化规则
此页面主要面向开发人员。对于 Twitter 用户:你最终要对所采取的行动负责…
help.twitter.com](https://help.twitter.com/en/rules-and-policies/twitter-automation)
S o,我们的目标是根据 Twitter 的用户数据(我们稍后会生成)建立分类模型,预测用户未来的行为——当我们向他/她发出追随请求时,这个用户是否会追随我们。所以,简而言之——这应该有助于我们找到未来会追随我们的人。
起初,我需要 Python 包,因为直接与 Twitter api 通信不是一个好主意,而且需要更多的时间,所以正如我们所知,Python 是“包含电池”的,我很容易就找到了一个很好的包,它具有我在这个项目中需要的所有功能,更重要的是,它还有很好的文档。
以下是链接:
[## 欢迎阅读 python-twitter 的文档!- python-twitter 3.4.2 文档
编辑描述
python-twitter.readthedocs.io](https://python-twitter.readthedocs.io/en/latest/index.html)
要使用这个包,首先我们需要使用 pip 安装它。
$ pip install python-twitter
在这之后,我们需要来自 Twitter 的 api 凭证,您可以很容易地从这里获得:
[## Twitter 开发者平台
Twitter 是世界上企业和个人联系的最佳场所。自从早期的 Twitter 人…
developer.twitter.com](https://developer.twitter.com/)
如果看起来有点混乱,您可以通过截图查看详细说明:
[## 入门- python-twitter 3.4.2 文档
如果那个页面上的信息有任何问题,Twitter 会投诉,你可以修复。(确保…
python-twitter.readthedocs.io](https://python-twitter.readthedocs.io/en/latest/getting_started.html)
好了,现在我们可以成功地连接 Twitter api 了:
现在是开始数据挖掘的时候了。我们需要收集足够的数据来训练我们的模型,这里有两个选项来获得它:第一个,这更难,我这样做是因为我没有任何选择——我们应该尝试关注有趣的人,并保存他们是否关注我们,以及第二个选项——对于那些已经有足够多朋友和追随者的人来说——你可以使用这些数据来训练你的模型。
在我的情况下,第二个选择行不通,我不得不选择更难的一个。因此,对于第一个场景,我需要在 Twitter 上找到受欢迎的人,他们大多发布关于编程/机器学习的帖子,因为他们的粉丝对我来说也非常好,所以我开始收集关于这类用户的数据。
首先,我选择“一个 Twitter 摇滚明星”用户,他总是发布关于编程或 ml 的帖子,然后获得他/她的追随者列表:
在那之后,我试着得到关于他们每一个人的详细信息。我正在使用的软件包会为每个用户返回这样的数据:
这里是非常有趣的信息,我可以用它来训练我的模型,但是我不想关注他们中的每一个人,我只想关注那些和我有相同兴趣并且有一些活动的人(见第 28 行)。
尽管事实上,Twitter api 和我们的软件包都让我们有可能非常容易地关注用户:
尽管如此,你必须小心,这样你的行为才不会看起来像垃圾邮件或者违反 Twitter 规则。
所以,如你所见,我用简单的“如果条件”来过滤那些不活跃或者没有足够多朋友的人。因为我想保存最大限度过滤的数据。
我决定在关系数据库中保存关于用户的信息,我使用 Sqlite 作为数据库,因为它对我们来说绝对足够了,我不想浪费时间在这种事情上。此外,在应用程序端,我只使用 sqlite3 包来连接数据库,没有任何orm
,我希望它尽可能简单。
对于第二个场景,我们使用几乎相同的代码,但不是从其他用户的关注者那里获取数据,而是获取关于我们的关注者和关注者的数据,并将所有这些信息保存在我们的表中。
首先,我们获得关于我们的追随者和追随者的信息:
最后,我们将所有内容保存到表中,就像前面的例子一样。
所以,我已经有了我需要的信息。
我想开始训练我的模型,为此,我需要为它选择特征。我们已经看到了 Twitter api 的结果。我决定只用其中的几个来训练我的模型:created_at
、favourites_count
、friends_count
、friends_count
、statuses_count.
虽然,我对培训过程并不满意,但我认为很容易猜到原因:仅根据这些数据很难猜测一个用户是否仍然活跃地使用 Twitter 帐户,也许他/她有很多帖子,但都是 1 年前发布的,所以我决定从功能列表中删除列created_at
和statuses_count
,代之以添加关于最后发布日期的信息。
您可以通过以下方式获取相关信息:
我决定将这个字符串转换成整数格式,并保存这个用户上一次发 tweet 之后已经过了多少天。我为它写了一个小函数:
我已经可以在主循环中使用这个函数了:
为您的模型收集数据并不是一件容易的工作,它需要最少几天,有时超过几周,所以在那些日子里,用户发生了很多变化,他们的数据已经保存在我们的数据库中,所以我编写了代码,使我的数据总是最新的(例如:朋友列表、关注者列表等),我可以在开始创建我的模型之前运行这些代码。
最后,我的数据是这样的:
我不知道你使用哪个 ide 或编辑器,我几乎总是选择 Intellij 产品,在这种情况下我使用 Pycharm。我也使用相同的 ide 来连接 sqlitedb,它让我们可以很容易地将数据转换成 csv 格式。
I check that I want header as a first row.
训练、评估、预测
现在是最有趣的部分。最后一步,我们可以使用 Google Colab ,我认为这是最有用的 Google 产品之一。
首先,我正在导入必要的包。
接下来,我们需要上传我们的 csv 文件,当你使用 Colab 时,这真的很容易,你只需要 2 行代码,然后是验证码。
上传文件后,我们可以用 Panda 打开它,看看它是什么样子。
也许你已经知道,在 Twitter 上存在私人账户,这意味着,在他们允许之前,你不能看到用户的帖子。因此,在这种情况下,你看不到用户的最后一篇文章。在我看来,特性days_after_last_post
真的很重要,我决定不使用用户进行训练,他们不会给出关于这些数据的信息。我们可以像这样在 sql 中添加这个过滤器:
select ud.* from users_data ud where ud.days_after_last_post is not null;
或者你可以在这里过滤,在 Colab。
我们还可以使用 panda 查看我们有多少关注者:
现在,我们可以为我们的特征和标签创建变量:
当我们已经有了我们的特性和目标时,为了方便起见,我们将使用 Scikit-learn 来拆分数据。Scikit-learn 有一个train_test_split
函数,用于将熊猫的数据帧分割成一个训练和测试集。
我们给目标和特征作为参数给train_test_split
函数,它返回随机打乱的数据。我们有 30%的数据用于测试集,70%的数据用于训练集。
现在,我将为每个特性调用函数numeric_column
,因为幸运的是我所有的特性都是数值型的。接下来,我将为特性列创建列表,
现在我们可以为特性列创建列表。
输入功能、测试和评估
我们需要输入函数,它必须返回一个元组,包含两个元素:特征和标签列表,我们将此输入函数用于我们的模型,因为当我们训练它时,我们必须将特征和标签传递给模型。
但是,当然,我们并不一定要手写它,它已经有了一个名为‘pandas _ input _ fn’的函数,我们将使用它:
现在是实例化模型的时候了
我们准备训练我们的模型:
我们训练了它,现在,我们能够评估我们的模型。为了评估,我们将eval_fn
作为参数传递给evaluat
函数:
你可以在屏幕上看到,在我的例子中,准确率是 80%+,我认为,对于这种数据来说,这是正常的——我只有大约 1400 个用户的信息,只有 4 个功能。人们的决定有时并不依赖于这些特征,所以我们的准确性现在令我满意。现在我可以用这个模型对真实数据进行预测。
预言;预测;预告
最后,我们可以获得这些用户的列表,这些用户将根据我们的模型的预测回复我们的好友请求。
当然,您可以更好地训练您的模型以获得更高的准确性,您可以使用不同的功能或更改任何您想要的功能,因为这个实验只是为了好玩,为了花更多时间使用 Tensorflow 和其他库。
感谢您花时间阅读这个故事:
风格转换的不同损失配置实验
当我参加杰瑞米·霍华德的优秀的程序员前沿深度学习时,我对风格转移很感兴趣。我想探究改变损耗配置如何改变生成的图像。我想看看使用不同的损耗网络如何产生不同的图像。我用的不同损耗网络是 vgg-16 和 vgg-19。这是一篇关于我的发现的博文。
那些不熟悉风格转移的人可以阅读这篇介绍其工作原理的博客文章。
所有实验都是使用以下内容和样式图像完成的:
left (content image), right (style image) used in these experiments
这些实验中使用的所有预训练损耗网络都是从 tensorflow 瘦模型库下载的。除非特别说明,否则初始图像是内容图像,使用的预训练网络是 vgg-16。要找出 conv1_2、conv2_2 等指的是哪些层,请运行
在本次回购中。以下所有实验均使用本报告中给出的代码进行。
实验 1:一次从一层使用风格损失进行训练
我使用这 5 层的输出来计算样式损耗:conv1_2、conv2_2、conv3_3、conv4_1 和 conv5_1。作为一个开始实验,我将内容权重和电视权重设置为零,将图像初始化为“噪声”。并使用这些层中的每一层生成样式图像(每次使用一层来计算样式损失)。生成的风格图像应该与绘画的仿作相对应。
以下是产出:
image created using loss from conv1_2, conv2_2 and conv3_3 (left to right)
image created using loss from conv4_1 (left) and conv5_1 (right)
在早期层(conv1_2 和 conv2_2)的输出中,风格图像中需要较小感受野(如咖啡色背景)的图案是显著的。在后面的层(conv3_3 和 conv4_1)中,更大的图案更明显。conv5_1 的输出看起来更像垃圾。我认为这是因为在该层很少激活。所以对损失贡献不大。下面的初始损失也显示了同样的情况。
为了生成风格化的图像,我使用 conv3_3 来计算内容损失。
当我保持所有 5 层的权重等于 1 时,以下是图像初始化为“内容”时的层内容和样式损失值:
layer-wise style loss values for initial image ‘content’
当我保持所有 5 层的权重相等时,以下是图像初始化为“噪波”时的层内容和样式损失值:
layer-wise style loss values for initial image ‘noise’
显然,在这两种情况下,后面的层对样式损失的贡献都非常小。在大多数出版的关于风格转换的作品中,所有层的权重都是一样的,这没有意义。
接下来,我想看看如果我只使用其中一层来训练,会产生什么样的风格化图像。
Output image when trained with gram matrix from layer conv1_2 and conv2_2 (left to right)
Output image when trained with gram matrix from layer conv3_3 and conv4_1 (left to right)
Output image when trained with gram matrix from layer conv5_1
从上面生成的图像可以明显看出,当我们从 conv1_2 移动到 conv5_1 时,笔触的大小会增加。【conv5 _ 1 的输出中有一些奇怪的模式。很可能是因为 conv5_1 没有包含太多的信息(我不得不将这一层的损失缩放 1e6 来生成此图像)。所以这只是噪音。这 5 个中我最喜欢的输出?conv3_3 的输出。
实验 2:利用一次一层的内容损失进行训练
我使用 3 层的输出来逐一计算内容损失:conv2_2、conv3_3、conv4_1。
我首先尝试通过将样式权重和电视权重设置为 0 来查找生成的图像,并计算每个内容层的损失,即仅使用内容损失。
Image created using content loss from conv2_2
Image created using content loss from conv3_3
Image created using content loss from conv4_1
可以看出,当我们从 conv2_2 移至 conv4_1 时,仍能捕捉到窗口等高层信息,但边缘、拐角等低层信息越来越模糊。
接下来,我生成了风格化的图像(使用内容,风格和电视损失)。对于风格损失,我使用层 conv3_3。我想检查一下,如果我更改内容层,上一个实验中 conv3_3 层的图像输出会有什么变化。
以下是生成的图像:
Output image when trained with features from layer conv2_2 and conv3_3 (left to right)
Output image when trained with features from layer conv4_1
很明显。当我们从 conv2_2 移到 conv4_1 时,建筑的边缘变得更钝,颜色变得更淡。捕获的原始内容要少得多。
实验 3:使用损失网络中两个最大汇集层之间不同层的风格损失进行训练
接下来,我想看看在两个最大池层之间使用不同的层来计算样式损失是否会改变生成的风格化图像。为此,我使用了以下层“conv3_1”、“conv3_2”和“conv3_3”。
images generated by training using only the style loss: conv3_1, conv3_2, conv3_3 (left to right)
以上是仅使用风格损失进行训练时的输出。conv3_3 的输出与 conv3_1 和 conv3_2 的输出截然不同。
接下来,我尝试通过使用这些图层来计算风格损失,从而创建风格化的图像。用于内容丢失的层是 conv2_2。
以下是生成的图像:
image generated for loss calculated from layer conv3_1
image generated for loss calculated from layer conv3_2, conv3_3 (left, right)
magnified view of image generated using style loss from conv3_1
artifacts shown with black underlining (the image is the same as conv3_3 shown above)
在 conv3_1 和 conv3_3 之间,上图(conv3_3 输出)中带黑色下划线的伪像明显更高。有趣的是,conv3_3 的仿体不同于 conv3_1 和 conv3_2。生成的图像也是如此。
实验 4:使用不同大小的风格图像进行训练
我使用 conv2_2 层的输出来计算内容损失:conv2_2。对于风格损失,我使用权重为 1 的 conv2_2。我没有使用原始尺寸(928x514)的样式图像,而是调整了图像的大小,使短边等于特定的尺寸,并在中间裁剪了较大的尺寸,以提取一个正方形。我试的尺码是 128,256,384 和 512。
以下是生成的图像:
stylized images for style image sizes 128 (left) and 256 (right)
stylized images for style image sizes 384 (left) and 512 (right)
stylized image for default style image size : 514x928
使用较小尺寸的样式图像生成的图像不好看,甚至不能显示样式图像的笔触。
同样,很明显,随着风格图像尺寸的增加,生成的图像更好地捕捉了画家的笔触。
实验 5:使用不同的 vgg 网络(vgg16 和 vgg19)进行训练
接下来,我从 vgg16 和 vgg19 生成图像。内容损耗用 conv2_2 计算,风格损耗用 conv3_1 计算。
首先,我只生成了模仿作品(保持内容和电视权重为零)。生成了以下仿作:
pastiches generated left: vgg-16, right: vgg-19
生成的仿作几乎没有任何不同。因此,我期望程式化的图像几乎没有什么不同,但我完全错了。这些是生成的图像:
Output by training using vgg-16 (left) and vgg-19 (right) loss networks
使用 vgg-19 生成的图像看起来更好,捕捉内容更好。我对此很感兴趣,并决定绘制图像在训练过程中的内容损失、风格损失和总损失。
content loss, style loss and total loss of image as it gets trained
**更重要的是,vgg-19 的起始风格损失值远低于 vgg-16。我的猜测是,生成的图像之所以不同,是因为网络对内容和风格损失赋予了不同的“隐含”权重。**所谓“隐含”权重,我指的是网络本身赋予内容和风格损失的权重,而不是因为我指定的内容风格和电视权重。
注意,这里 vgg16 和 vgg19 表示不同的功能。因此,这种比较并不完全意味着“vgg-19”的绝对含量损失低于“vgg-16”。这只是表明,在优化图像的同时,vgg-16 的风格损失变得更加重要。
注:-对于后续实验,使用 conv2_2 计算(6,7,8)含量损失,conv3_1 计算风格损失。
实验 6:使用不同初始化(“噪声”/“内容”)的训练
image generated with initial ‘content’ (left) and initial ‘noise’ (right)
content loss, style loss and total loss of image for both these initial conditions as it gets trained
可以看出,内容和噪声图像都收敛到几乎相同的损失值。尽管生成的图像不同。使用“内容”初始化时,损耗收敛更快。
实验 7:使用不同类型的衬垫进行训练(相同/有效)
images generated using padding ‘SAME’ (left) and ‘VALID’ (right) in the loss network
content loss, style loss and total loss of image for both these types of padding as it gets trained
损失值相差不大。结果完全符合我的预期。
实验 8:使用不同类型的汇集(最大/平均)进行训练
image generated with pooling ‘avg’ (left) and pooling ‘max’ (right)
content loss, style loss and total loss of image for both these types of pooling as it gets trained
可以看到,使用“max”生成的图像有奇怪的点。使用“avg”生成的图像更加均匀。更重要的是,“平均值”的总损失收敛速度比“最大值”快得多。
实验 9:使用不同风格权重值进行训练
我想看看样式权重对生成的图像有什么影响。为此,我决定对内容层 conv2_2 和样式层 conv3_1 使用 vgg-19,样式权重设置为 200、400、800、1600 和 3200。生成了以下图像:
left image: style-weight 200, right image: style-weight 400
left image: style-weight 800, right image: style-weight 1600
style-weight 3200
**可以看出,在使用风格权重 3200 生成的图像中,画家的笔触要突出得多。**原始内容(颜色等)不太突出。
实验 10:使用不同的总变化损失值进行训练
我想看看总变差损失对生成的图像有什么影响。为此,我决定对内容层 conv2_2 和样式层 conv3_1 使用 vgg-19,总变差损失为零,下一个电视重量设置为 200。生成了以下图像:
Image created using default content and style weight and tv weight = 0. On careful observation, it becomes visible that image is quite rough.
Image created using default content and style weight and tv weight = 200. Roughness present in the previous image is gone
总变差损失有助于去除生成图像的粗糙纹理。从上面两幅图像中可以观察到,一幅有总变差损失,另一幅没有,总变差损失非零的图像非常平滑。
实验 11:使用风格图像的不同裁剪区域进行训练
我裁剪了样式图像的不同区域,以了解它如何影响生成的图像的质量。
以下是提取的样式图像部分:
style image portions used for training the image: left region, center region, right region of the style image (left to right)
complete style image
和以前一样,我首先为左侧区域、中间区域、右侧区域和完整的图像生成了仿制品。
使用了 vgg-16 网络。使用的样式层是 conv3_1。
left region (left), center region (right)
right region (left) and complete image (right)
右侧区域的仿作明显不同于左侧、中间区域和完整图像的仿作。这是预料之中的,因为样式图像的右边区域明显不同于所有其他区域,甚至不同于整个样式图像本身。
接下来生成风格化的图像,内容层是 conv2_2,样式层是 conv3_1。内容重量、风格重量和电视重量在规范中给出(分别为 8 和 200)。
生成了以下图像:
stylized image generated using left region (left) and center region (right)
stylized image generated using right region (left) and using whole style image (right)
如我们所见,从右侧区域生成的图像明显不同于从左侧、中间区域和完整图像生成的图像。
如果您喜欢这篇文章,请点击下面的小拍手图标帮助他人找到它。非常感谢!
一种新卷积的实验
警告:这篇文章假设读者对 CNN 有一定的了解
卷积有很多我不喜欢的地方。它们中最大的,特别是在后面的层中的大多数权重非常接近于零。这说明这些权重中的大多数没有学到任何东西,也没有帮助网络处理任何新信息。
所以我想修改卷积运算来解决这个问题。这篇博文强调了我在这个方向上做的实验和结果。
实验#1
本质上,每个 2D 卷积运算都是一个矩阵乘法运算。其中矩阵的维数为(内核大小 x 内核大小 x 输入通道,输出通道),假设卷积维数为(内核大小,内核大小,输入通道,输出通道)。为了简单起见,我在文章中称这个矩阵为维度为(m,n)的卷积矩阵。
如果我们能够保持卷积矩阵的列是正交的(以可微分的方式),我们可以确保输出特征图中的每个通道捕获任何其他特征图中不存在的信息。更重要的是,这可以帮助我们创建权重更容易解释的神经网络。
是的,使用线性代数中的一些技巧(一个是 householder 变换,另一个是 givens 旋转),有一些可微的方法来确定这一点。我使用户主转换,因为它在 GPU 上要快得多。
代码在这个文件里。
这个想法是这样的:
不是在卷积滤波器中保持所有 mxn 个可训练变量,在偏差中保持所有 n 个可训练变量,而是以可微分的方式从另一组可训练变量生成滤波器和偏差。
更具体地,对于维数为(m,n)的卷积矩阵,创建 n 个维数为 m 的向量。第一个向量(比如 v1)将有 m-n+1 个可训练变量(开头用 n-1 个零填充),第二个(比如 v2) m-n+2 个(用 n-2 个零填充),第三个(比如 v3),m-n+3 个(用 n-3 个零填充),等等。接下来归一化所有这些向量。使用这些向量创建 n 个 householder 矩阵,按照 v1v2v3…*vn 的顺序乘以向量。合成矩阵的维数为 m×m,并且是正交的。取这个矩阵的前 n 列。结果矩阵的大小为(m,n)。并将其用作卷积矩阵。
看起来这个操作非常耗时,但实际上对于一个 3×3×64×128 的卷积,意味着 576×576 大小的矩阵的 128 次矩阵乘法。考虑到这种卷积是在 256x256 大小的图像上执行的(这意味着(256x256)x(3x3x64x128) flops),这并不算什么。
如果您必须创建一个偏置和过滤器,用 m + 1 替换 m 进行上述过程,从大小为(m+1,n)的结果矩阵中提取最上面的行并将其用作偏置,使用剩余的(m,n)矩阵作为过滤器。
如果您使用批量规范化,这种想法将不起作用,因为列的正交性假设不成立。
对于这些实验,我使用了具有类似 vgg 架构的 cifar-10。代码是在相同的回购。
结果是非常非常令人失望。
plots of cross_entropy and accuracy on training data
plots of cross_entropy and accuracy on validation data
可以看出,基线和正交卷积之间的所有曲线的结果都很差。更重要的是,正交卷积的训练时间明显更长。这是时间单位的曲线图:
plot of training time per iter for baseline/orthoconv
从图中可以看出,时间平均高出 7 倍。有很多方法可以加速这段代码,但是由于结果不佳,我没有朝那个方向前进。
我的直觉是,它不起作用的原因是,由于所有列向量必须正交的约束,模型的优化前景受到严重限制。为了测试我的直觉,我做了下一个实验。
实验#2
在下一个实验中,我没有使用 householder 乘法产生的卷积权重和偏差,而是添加了另一个损失项,称为“正交性损失”。正交性损失计算如下:
设卷积矩阵的维数为(m,n),偏差向量的维数为(n),连接这两个向量形成一个维数为(m+1,n)的矩阵。称这个矩阵为 m。计算这个矩阵的列范数,称它为 N(它是一个维数为(1,N)的矩阵)。
计算转置(M)*M .计算转置(N)*N .并将两个矩阵相除。在结果矩阵中,a(i,j)包含矩阵 m 中索引 I 和 j 处的列向量之间角度的余弦值。通过平方此矩阵中的所有元素来创建新矩阵。求矩阵中所有元素的和(除了轨迹)。将所有卷积层的这个值相加,我们将结果值称为正交损失或正交损失。我将其乘以一个称为正交权重的超参数,并将其添加到总损耗中。
我使用不同的正交权重值做了实验:我尝试了 0.1、1、10、100,inf 对应于前面实验中描述的卷积。
orthogonality loss for all different experiments
初始正交性损失(没有乘以权重)约为 40。这远远大于交叉熵本身。然而,网络学会了在几次迭代内将它推到零。
从上图可以看出,网络很快学会了保持卷积矩阵中的所有列向量正交。当正交权重设置为零时,正交性损失不断增加,而对于其他情况(0.1、1、10、100),它稳定在接近零的值。这意味着如果我们增加加权正交性损失,卷积矩阵学习的权重确实是正交的。
cross entropy and accuracy on training data
从上图可以看出,随着正交权重的增加,网络变得难以训练。
cross entropy and accuracy on validation data
但是该网络实现的验证准确度/交叉熵非常接近正交权重为 0 的验证准确度/交叉熵。又一次失望,因为我希望它会给出更好的结果。但至少比以前的结果要好。
接下来,为了更仔细地检查,我决定只绘制正交权重 0 和正交权重 0.1。
cross entropy and accuracy on training data
cross entropy and accuracy on validation data
可以看出,两个网络收敛到相同的验证交叉熵和准确度。正交权重为 0 的网络训练交叉熵较高。这种方式表明,增加正交权重会使网络更好地泛化(更高的训练损失,但相同的验证损失)。
接下来,为了测试这是否适用于其他数据集,我决定用 CIFAR-100 进行同样的实验。
cross entropy, accuracy and ortho_loss on training data
cross entropy and accuracy on validation data
这些结果确实推广到 CIFAR-100。更重要的是,我们可以看到,正交性权重为 0.1 的网络表现出与正交性权重为 0 的网络相同的验证精度。如 ortho_loss 比较图所示,正交权重为 0.1 的网络学习卷积矩阵中的正交列。
实验#3
接下来,被这些结果激起了兴趣,我决定尝试将的相同想法用于递归神经网络。在这个 repo 中使用代码(除非特别说明,否则是默认架构),我决定通过给 LSTM 增加正交性损失来进行实验。注意,正交性损失= sum_square(I-transpose(M)*M)其中 M 是隐藏到隐藏状态矩阵。它不同于正交性损失,在正交性损失中,我们不关心所有列是否有范数 1。
以下是结果(我对正交性损失尝试了这些不同的权重:0.001、0.0001、0.00001、0.000001、0.000001、0):
cross entropy and orthonormality loss as network gets trained for 20 epochs
同样,当我们减小正交权重时,交叉熵减小得更快。接下来,为了更好地比较两个最佳模型的正交权重,我决定绘制权重为 0 和 0.0000001 的交叉熵和正交损失值。
cross entropy and orthonormality loss as network gets trained for 20 epochs for only two weights (0, 0.0000001)
同样没有太大的差别,但它设法匹配基线结果。
结论
我从这个小项目中学到的最重要的事情是神经网络非常复杂。即使看起来不错的想法也可能失败,因为大多数时候,当人们想到一个想法时,他们只是根据网络的最终训练状态来考虑它(就像我的情况一样,我希望矩阵的列是正交的)。但是,如果您考虑到网络必须遍历一条路径以进行优化的事实,大多数好的想法似乎马上就变得索然无味了(就像我的情况一样,很明显,我在实验#1 中严格限制了模型可以采用的路径)。
此外,我尝试了许多非标准(我自己的发明)的调整,使网络击败基线。没有一个管用。实际上,我很高兴我成功地重现了基线结果,尽管我添加了一个比交叉熵本身更大的损失项。
我也对图像分割做了同样的实验。得出了相似的结果。为了简洁起见,这里没有提到它们。
我也相信这项研究有助于更好地可视化卷积层的权重。我计划下一步探索这个问题。
本博客中给出的所有实验都可以使用这些回复进行复制:
正交卷积— Github repo 用于我的正交卷积思想的实验
github.com](https://github.com/singlasahil14/orthogonal-convolution) [## 新加坡 14/char-rnn
通过在 GitHub 上创建一个帐户来为 char-rnn 开发做贡献。
github.com](https://github.com/singlasahil14/char-rnn)
如果您喜欢这篇文章,请点击下面的小拍手图标帮助他人找到它。非常感谢!
Tensorflow 中合成模式生成网络/变分/普通自动编码器的实验
GIF from this website
我真的很想了解更多关于自动编码器(普通的和变化的)和组合模式生成网络的知识,这就是我写这篇文章的原因。所以我决定做一些实验,比如……
情况 a) 合成模式产生网络 情况 b)使用自动编码器聚类数据
情况 c)使用变分自动编码器聚类数据
情况 d)使用自动编码器去表情图像
请注意,这篇文章是为我自己做的各种实验的存档结果。所以这篇文章没有任何具体的目标。另外,请注意,我不会在这篇文章中讨论这些架构背后的任何理论。
自动编码器简介
Video from Arxiv Insights
对于任何刚刚开始学习这个主题的人,我在上面链接了一个令人惊叹的 youtube 视频。它很好地描述了什么是自动编码器,以及它可以用在什么地方。
此外,如果您想要自动编码器的其他内容,请单击此处。
案例一) 组分产网
黑框 →比例因子输入(我设置为 1.0)
红框→X 坐标输入
蓝框→Y 坐标输入
天蓝框 →各坐标半径差输入
首先,让我们使用神经网络创建一些艺术品。O toro 在这里发表了一篇关于 CPPN 是什么的惊人博文,如果你感兴趣,请去阅读。(即使你不是,我也强烈推荐阅读这本书,它真的是一个令人惊叹的解释。).
Image created by Neural Network
如上所述,当我们将最终输出向量设置为 3 时,我们甚至可以创建彩色图像的颜色序列。(或者甚至是 RGBA,如果你愿意的话。).最后,请注意 CPPN 不一定要有类似于自动编码器的网络架构。
微型部分——通过对数损失函数进行反向传播
Image from this website
如果我们正在处理灰度图像,我们可以很容易地将该问题视为分类任务,因此我们可以使用 log Loss 函数来训练我们的网络。然而,由于我们正在执行手动反向传播,我们需要知道幕后的数学。
Image from this website
现在,我将向你展示这个等式是如何折叠的,就像上面看到的那样,但是如果你对数学的细节感兴趣的话。请点击这里,这里点击或者这里点击。另外,如果你对最大对数似然和交叉熵之间的差异感兴趣,点击这里。
情况 b)使用自动编码器对数据进行聚类
蓝色矩形 →我们网络的编码器部分
红色矩形 →我们网络的解码器部分
让我们首先做最简单的任务,我们将聚类 MNIST 数据集到一个三维潜在空间。看看我们能达到什么样的效果。首先让我们使用最大似然估计作为我们的成本函数。
左图 Gif →为 1000 个数据点创造潜在空间
右图 Gif →随时间重建图像
如上所述,当我们观察 1000 个数据点的潜在空间时,我们可以观察到具有相似属性(如曲线或边缘)的每个数字都聚集在一起。然而,这里需要注意的是,我们可以观察到范围相当大,仅 Y 轴的范围就从 0 到-70,这意味着数据更加分散。(如果我们想要生成新数据,这可能是一个问题。)
接下来让我们使用作为均方误差成本函数。
左 Gif →为 1000 个数据点创建潜在空间
右 Gif →随时间重建图像
即使我们使用均方误差作为我们的损失函数,网络在聚类数据点方面做得还不错,但是,再次注意每个轴的范围相当大。
情况 c)使用变分自动编码器聚类数据
蓝色矩形 →我们网络的编码器部分
红色矩形 →我们网络的解码器部分
现在,让我们使用变型自动编码器对我们的数据进行聚类,关于什么是变型自动编码器的详细解释,请点击此处、此处或此处。首先,让我们再次使用最大似然估计作为我们的损失函数。
左侧 Gif →为 1000 个数据点创建潜在空间
右侧 Gif →随时间重建图像
如上所述,网络在聚集每个数据点方面做得很好。然而,一个不同于普通自动编码器的是轴的范围。这是变型自动编码器与普通自动编码器相比的一个特性。再次理论解释请阅读链接。接下来,让我们看看如果使用均方误差函数会发生什么。
蓝色矩形 →我们网络的编码器部分
红色矩形 →我们网络的解码器部分
即使使用 MSE,我们也可以观察到集群看起来很棒,轴的范围不像普通的自动编码器那样大。最后,我想看看我们是否使用了 Kullback-Leibler 散度损失函数。
左侧 Gif →为 1000 个数据点创建潜在空间
右侧 Gif →随时间重建图像
因为我们不再有任何重建损失,所以网络没有任何动机来创建看起来像原始图像的图像。然而,观察一些点如何映射到更高的 z 轴是非常有趣的。
案例 d)使用自动编码器对图像进行去表情处理
左侧图像 →添加表情符号的图像
中间图像 →无表情符号的图像
右侧图像 →自动编码器去除表情符号的图像
这是一项非常简单的任务,因为去噪自动编码器是这类网络的标准用例。
图像顺序 →表情图像、原始图像、去表情图像
当我们看到自动编码器的进展时,我们可以观察到,随着网络的训练,它在消除图像中出现的表情符号方面做得更好。然而,我们可以清楚地看到一个问题,网络不知道如何填充表情符号占据的空间。现在我们可以让它保持原样,但将来我会计划解决这个问题。
交互代码
对于谷歌实验室,你需要一个谷歌帐户来查看代码,你也不能在谷歌实验室运行只读脚本,所以在你的操场上做一个副本。最后,我永远不会请求允许访问你在 Google Drive 上的文件,仅供参考。编码快乐!同样为了透明,我在 github 上上传了所有的训练日志。
要访问案例 a 的代码,请点击此处。
要访问案例 b 的代码,请点击此处,要查看日志,请点击此处。
要访问案例 c 的代码,请点击此处,日志的请点击此处。
要访问案例 d 的代码,请点击此处。
最后的话
很抱歉没有解释每个网络背后的理论,但这篇文章的目的实际上是为了实现我的一些实验。
如果发现任何错误,请发电子邮件到 jae.duk.seo@gmail.com 给我,如果你希望看到我所有写作的列表,请在这里查看我的网站。
同时,在我的 twitter 上关注我这里,访问我的网站,或者我的 Youtube 频道了解更多内容。我还实现了广残网,请点击这里查看博文 t。
参考
- 导数表。(2018).Math2.org。检索于 2018 年 6 月 23 日,来自http://math2.org/math/derivatives/tableof.htm
- tf.atan | TensorFlow。(2018).张量流。检索于 2018 年 6 月 23 日,来自https://www.tensorflow.org/api_docs/python/tf/atan
- 导数:普通神经网络激活函数的导数。(2014).聪明的机器。检索于 2018 年 6 月 23 日,来自https://theclevermachine . WordPress . com/2014/09/08/derivation-derivatives-for-common-neural-network-activation-functions/
- 导数表。(2018).Math.com。检索于 2018 年 6 月 23 日,来自http://www.math.com/tables/derivatives/tableof.htm
- 可变自动编码器。(2018).YouTube。检索于 2018 年 6 月 23 日,来自https://www.youtube.com/watch?v=9zKuYvjFFS8
- matplotlib,R. (2018 年)。在 matplotlib 中删除保存的图像周围的空白。堆栈溢出。检索于 2018 年 6 月 23 日,来自https://stack overflow . com/questions/11837979/remove-white-space-around-a-saved-image-in-matplotlib
- [复本],H. (2018)。如何在 Matplotlib (python)中隐藏轴和网格线?堆栈溢出。检索于 2018 年 6 月 23 日,来自https://stack overflow . com/questions/45148704/how-to-hide-axes-and-gridlines-in-matplotlib-python
- 合成模式生成网络。(2018).En.wikipedia.org。检索于 2018 年 6 月 23 日,来自https://en . Wikipedia . org/wiki/composition _ pattern-producing _ network
- 大トロ. (2018). Blog.otoro.net. Retrieved 23 June 2018, from http://blog.otoro.net/
- RGBA 颜色空间。(2018).En.wikipedia.org。检索于 2018 年 6 月 23 日,来自 https://en.wikipedia.org/wiki/RGBA_color_space
- 最大似然估计。(2018).En.wikipedia.org。检索于 2018 年 6 月 23 日,来自 https://en.wikipedia.org/wiki/Maximum_likelihood_estimation
- 均方差。(2018).En.wikipedia.org。检索于 2018 年 6 月 23 日,来自https://en.wikipedia.org/wiki/Mean_squared_error
- Mallya,A. (2018)。反向投影。arun mallya . github . io . 2018 年 6 月 23 日检索,来自http://arunmallya.github.io/writeups/nn/backprop.html
- (2018).Ttic.uchicago.edu。检索于 2018 年 6 月 23 日,来自http://ttic . uchicago . edu/~ shubhendu/Pages/Files/lecture 3 _ flat . pdf
- (2018).Ics.uci.edu。检索于 2018 年 6 月 23 日,来自https://www.ics.uci.edu/~pjsadows/notes.pdf
- (2018).[在线]可从以下网址获取:https://www . quora . com/What-is-the-differences-between-maximum-likelihood-and-cross-entropy-as-a-loss-function【2018 年 6 月 23 日获取】。
- 带图例的散点图— Matplotlib 2.2.2 文档。(2018).Matplotlib.org。检索于 2018 年 6 月 23 日,来自https://matplotlib . org/gallery/lines _ bars _ and _ markers/scatter _ with _ legend . html
- 颜色示例代码:colormaps _ reference . py—Matplotlib 2 . 0 . 2 文档。(2018).Matplotlib.org。检索于 2018 年 6 月 23 日,来自https://matplotlib . org/examples/color/colormaps _ reference . html
- 对抗性自动编码器的向导指南:第 1 部分,自动编码器?。(2017).走向数据科学。检索于 2018 年 6 月 23 日,来自https://towards data science . com/a-wizards-guide-to-adversarial-auto encoders-part-1-auto encoder-d9a5f 8795 af 4
- 教程-什么是可变自动编码器?—贾恩·阿尔托萨尔。(2018).贾恩·阿尔托萨尔。检索于 2018 年 6 月 23 日,来自https://jaan . io/what-is-variable-auto encoder-vae-tutorial/
CM1K 神经网络芯片的实验
2017 年 3 月,我获得了来自麻省理工学院沙盒项目的资金,利用 T2 的 CM1K 神经网络芯片 T3 开发了一款产品。CM1K 是一个集成电路,它在硬件中实现了 RBF 和 KNN 分类器,这应该比在软件中实现这些算法提供了更好的性能。我提议用这个芯片作为分线板的基础,可以与流行的业余爱好者电子平台(如 Raspberry Pi 或 Arduino )接口。所有代码和原理图都可以在这个项目的 Github 页面上找到。
先前的工作
在随机搜索谷歌以了解是否存在类似 CM1K 的芯片后,我受到启发开始了这个项目——我想知道是否有人开发出了在硬件中实现机器学习算法的 ASIC。我很快发现了 CM1K,但是项目例子很少。
我确实发现了 Braincard ,一个失败的 Indiegogo 整合 CM1K 的分线板活动。这与我打算开发的东西非常相似,声称可以将 CM1K 与 Pi、Arduino 和 Intel Edison 进行接口。尽管失败了,我并没有对我的想法失去信心——brain card 似乎缺乏成功所需的文档和业余爱好者社区中的可见性,这并不一定说 CM1K 本身有什么不好。
Sad reacts only 😦
一个有趣的注意事项是,Braincard 活动实际上隶属于 cogn mem。经过一番挖掘,我发现多家公司似乎都有关联:认知记忆、通用视觉和神经记忆等等。它们似乎都是由这种芯片技术的发明者 Guy Paillet 联系在一起的。如果你想去兔子洞,看看他的 LinkedIn 简介…无论如何,我最好的猜测是,Braincard 是 General Vision 试图增加业余爱好者市场对 CM1K 的需求。
我发现第三方使用 CM1K 的例子更少。我找到的几个参考资料是这个简单的分线板和这个研究论文。不幸的是,这两个来源都缺乏任何清晰的文档来证明 CM1K 的实际应用。
很难找到 CM1K 接受测试的例子。随着 Cognimem 宣称“无限可能”,我有动力建立一个分线板,并为自己评估 CM1K。
开发分线板
我最初计划在春天完成几个版本的分线板。第一个是一个相当简单的分组讨论板,由以下部分组成:
- CM1K 本身
- 为芯片供电的 3.3v 和 1.2v 稳压器
- 提供时钟信号的 27 MHz 振荡器
- 在需要的地方拉起电阻和滤波帽
- 电源指示灯
- 标题将 IC 上的每一行分开
然后,该板可以连接到我想要的任何平台上,一旦我开发了软件,并能够评估使用芯片的最佳方式,我就可以设计第二块板,它具有所需的额外功能,可以与我选择的平台很好地接口。
由于时间限制,我从未接近完成第二个设计。无论如何,在我运行的实验中,事实证明几乎不需要它:将第一个 rev 板与 I2C 上的 Raspberry Pi 连接起来非常简单。
Schematic!
我开始在高原设计分线板。绘制原理图相当简单,但布局花了我一段时间。我决定试着把所有东西都放进 2 平方英寸的空间里,这给了我太多的发挥空间。我在电路板边缘排列了接头,并将 IC 放在中央。我最初认为我可以把这块板分成两层,但是经过两次尝试后,我不能完全把它布置好。我最大的难点是试图将 1.2v 和 3.3v 线干净利落地分配给 IC 上所有分散的电源引脚。经过三次重新设计尝试,我选定了四层设计,第三层分为 1.2v 和 3.3v 电源层。1.2v 层直接位于 IC 下方,因此需要 1.2v 输入的所有引脚都向后走线,有一个过孔直接通向 1.2v 层。然后,3.3v 电源引脚可以向前走线,过孔向下到平面。由于所有外设都使用 3.3v 电压,因此很容易为电路板的其余部分提供 3.3v 电压。
Routing complete!
电路板设计完成后,我需要将它发送给 fab。我上一次这样做是在几年前,当时我在奥什公园为我的高中机器人团队做了一些东西。在这一点上,我需要的板比批处理服务提供的要快得多,所以我最终选择了 4pcb.com 的 T4,用 T6 的 66 each T7 交易以 66 美元的价格得到了我的两块板。作为一名学生,我可以免除最低订购量,这非常棒。
My breakout board straight from the fab in all its glory.
一旦我的主板和所有组件到达,这是组装的时间。我把它带到 MITERS 并开始用热风枪焊接所有东西。每一个组件都非常容易地关闭……除了集成电路,它需要一点工作来做好。我开始与此,并嗡嗡作响的所有突破引脚,以确保它被钉下来的权利。经过多次反复的嗡嗡声和毛细作用,并试图小心翼翼地应用更多的焊料,它似乎没问题。
All populated!
焊接完成后,我把电路板拿到电源前,插上电源。关键时刻平静地过去了:电源灯亮了,主板没有开始冒烟或发热。接下来,我决定第一次尝试使用示波器来检查振荡器的输出。起初,输出似乎真的很糟糕,但在无法找到我的板中的故障后,我意识到我对如何设置示波器没有任何线索。经过一些谷歌搜索和一些校准,我得到了一个输出,至少符合我要去的频率(即使它不是完全干净)。哦,好吧,不管怎样,事情似乎解决得很好。
The moment of truth!
随着这些初始测试的完成,是时候连接分线板并开始编码了!
开发软件
我首先将分线板连接到我身边的一个 3.3v Arduino Micro,选择它是因为它是我唯一一个具有 3.3v 逻辑电平的 Arduino。布线很简单:我只要接上两条 I2C 线,必要时在 GND 上绑几个配置引脚,就能让 I2C 正常工作。然后,我编写了一个函数,成功地从 CM1K 的 NCOUNT 寄存器中读取数据。在将其推广到可以读取/写入任何任意寄存器的功能后,我能够验证 CM1K 的硬件似乎按照数据手册中的规定工作。
硬件通过验证后,我和我的一个朋友聊了聊,他建议我试着根据 MNIST 数据集对芯片进行基准测试。我认为这是一个有价值的目标,并着手使用 CM1K 在 MNIST 上实现 KNN 分类。
我决定我不想担心将 MNIST 训练数据集安装到我的 Arduino 上,所以我拿起了一个 Raspberry Pi Zero W 以及一些外围设备,以使布线更容易。我像对 Arduino 一样连接好它,然后开始工作!
The Raspi Setup in all its glory.
我决定用 Python 编写我的所有代码,使用 smbus 模块通过 I2C 与 CM1K 对话。我首先根据 CM1K 硬件手册中的一些伪代码编写了一个简单的测试脚本。该脚本使用一个测试寄存器 TESTCAT,该寄存器写入与每个单个神经元的类别相同的值。然后,它遍历每个神经元,并检查以确保其存储的类别与写入 TESTCAT 的值相匹配。这个脚本起作用了,所以我决定是时候干脏活了。
第一步是对 MNIST 图像进行降采样。每个图像都是一个很小的 28x28 像素的图像,但是 CM1K 将每个神经元中的数据存储为一个长度为 256 的向量,存储字节值。因此,使用单个字节来表示每个像素的颜色值,我必须将每个图像压缩到 16x16 像素,这样我就可以将一个图像放入每个向量中。这很简单:我使用 python-mnist 作为一种简单的方式来获取训练数据,然后使用 Pillow 和 Numpy 来对图像进行重新采样。除了向下采样到 16x16,我的代码还将每个图像展平为一个长度为 256 的向量,该向量可以馈送到 CM1K。
由于单个 CM1K 只能容纳 1,024 个向量,所以我编写代码从训练集中随机选择 1,024 个图像来实际使用。鉴于完整的训练集总共使用了 60,000 张图像,我担心这会给芯片的性能带来巨大的限制。
训练过程只是将这些图像中的每一个都写入 CM1K。我使用了芯片的保存和恢复模式,这种模式可以让你将一个向量直接写入每个神经元的内存,而无需调整它们的激活功能(当芯片运行在 RBF 模式下时,这是相关的,但不是 KNN),从而加快了这个过程。
然后,测试过程对 CM1K 运行可配置数量的测试图像。我开始简单地选择最近的邻居(k=1),但这样得到了可怕的结果(不幸的是,我做的是糟糕的科学,没有记录这些结果)。然而……在最近的邻居之间快速实现多数投票(所以我可以任意 k≥1)后,我的运气变了!事不宜迟——
结果
—结果证明,我最终还是能获得相当好的结果!总的来说,我最好的成绩(图中没有)是在 k=5 的情况下,对 100 个样本进行 89%的准确率测试。
Results! Sexy progress bar courtesy of tqdm.
这种精确度让我非常高兴。根据 Yann Le-Cun 的网站,这不是最先进的,但却是可靠的 B+(如果你四舍五入的话,是 A-)。然而,让我有些沮丧的是脚本有多慢,特别是考虑到使用这种神经网络硬件的一个大承诺是它会相对较快。然而,它以不到 5 个样本/秒的速度进行训练和测试,我觉得这有点令人失望。
我可以通过将 Pi 上的 I2C 时钟速度更改为 400 kbps(CM1K 的理论极限)来稍微解决这个问题。这给了我稍微好一点的结果,整体提升速度达到每秒 7 个样本。
结论
在 CM1K 上运行 KNN,我能够成功地对 MNIST 数据集中随机选择的 100 幅图像进行分类,准确率为 89%,测试和训练速度约为每秒 7 个样本。这看起来并不太糟糕,但一个重要的问题是,这是否真的比在软件中运行 KNN 算法更好。
我最接近回答这个问题的方式是在 GitHub 上找到的一个 CM1K 模拟器上运行我自己代码的修改版本。考虑到仿真 CM1K 显然不是在 Raspberry Pi 上实现 KNN 算法的最快方式,这个测试并没有真正演示那么多。但是,我很好奇比较性能。
如您所见,与在实际芯片上运行我的代码相比,准确性和速度都受到了影响。从某些方面来看,这有点奇怪,尽管看起来很振奋人心。然而,我对此持保留态度,因为我真的不能指望模拟器代码。
我的直觉是,举例来说,如果用写得很好的 C 代码实现,软件 KNN 会比 CM1K 有更好的性能。也就是说,我也可以用 CM1K 优化很多方法。我相信这是真的,特别是考虑到 CM1K 理论上应该能够在大约 10 微秒内加载一个完整的矢量,这是根据数据手册中给出的时钟速度和周期数计算的。以这个理论上的最大值运行,它应该能够每秒训练 1000 个样本,这意味着在我目前的方法中有很多开销。
优化思路包括:
- 用 C 重写代码,以消除 Python 解释中的开销
- 在 CM1K 上使用并行数据总线,而不是 I2C,考虑到 Raspberry Pi GPIO 的限制,这可能涉及一些硬件重新设计(可能使用移位寄存器)
即使 CM1K 在软件中运行 KNN 的速度比 Pi 运行 KNN 的速度快,接下来出现的问题是,无论如何,是否有必要离线运行机器学习算法。在大多数应用程序中,将这类计算交给服务器似乎更可行。随着越来越多的嵌入式设备连接到互联网(这已经是一种趋势了,它现在有自己的流行语了!),嵌入式离线模式识别好像会变得越来越没用。然而,这仍然是一件有趣的事情。
我打算暂时搁置这个项目,去做其他事情。然而,对于如何继续前进,我确实有很多想法:
- 将另一个分线板和两个 CM1K 菊花链连接在一起:这将允许我在不牺牲速度的情况下获得更好的性能
- 执行上面描述的优化来提高我当前设置的速度
- 尝试 CM1K 的 RBF 模式(相对于 KNN 模式)
- 为 Pi 编写/找到一个合适的 KNN 实现,以便在 CM1K 上与 KNN 并行比较
- 使用 Arduino 作为主设备,使用 SD 卡模块存储训练数据
- 使用 CM1K 开发一些示例应用程序。在这一点上,我的首要想法是开发一个基于语音命令或脑电波导航的移动机器人
最后一点需要注意的是,General Vision/Cognimem 的技术现已内置于 Arduino 101 芯片的处理器中。这可能有助于将他们的技术引入主流爱好者市场,尽管我从未发现许多人使用芯片这一功能的例子。
伙计们,现在就到这里吧!对 CM1K 进行实验,并尝试开发一款几乎不为广大业余爱好者所知的芯片,是一件非常有趣的事情。希望这篇博文能给这个神秘的小家伙一点启发!如果您有任何意见或问题,请随时通过电子邮件与我联系。
专家观点:“用户与虚拟现实互动的方式允许极其普遍的信息收集
我们采访了 DreamSail Games 的商业分析师兼虚拟现实游戏开发者辛迪·马洛里
《创新企业》的高级编辑詹姆斯·奥文登采访了纽约商业分析师辛迪·马洛里,期待她在下个月举行的 2017 年游戏分析峰会上的 VR 演讲。
辛迪·马洛里(Cindy Mallory)是一名商业分析师,也是梦之帆游戏公司(DreamSail Games)的虚拟现实游戏开发者,该公司制作了包括《刀锋芭蕾》(Blade Ballet)在内的获奖游戏。她在 DreamSail 的重点是分析管理,她通过定义、分析和记录使用新兴技术进行游戏创作的要求来协助虚拟现实开发。她还创建并维护了一个公司数据库,用于记录 KPI 和归档相关审计。
在她于今年 4 月 26 日至 27 日在旧金山举行的游戏分析峰会上发表演讲之前,我们采访了她。
你是如何开始你的职业生涯的?
我学习生物化学,重点是数学和物理。实验室研究的方法使我为数据分析做好了准备;当我计算酶反应速率、进行动力学分析、读取紫外线波长和修改实验以便更好地运行时,我已经在做这些了。这是我第一次接触趋势分析和预测建模。我的项目是分离和纯化用于生物燃料应用的重组克隆酶。在我在一个交友网站上发表个人简介之前,我一直在做实验,目的是纯化大肠杆菌中生长的蛋白质…
一个纽约的游戏设计师把我研究项目的 3D 模型扔进了游戏引擎。我被迷住了。我开始涉猎一些编码语言、商业策略和数据驱动营销。我接受了中城虚拟现实创意工作室 DreamSail Games 的一个职位,担任他们的商业分析师。每当我能把我的方法从生物化学转移到商业领域时,我就拼命工作。
为什么在视频游戏开发中跟踪 KPI 很重要,你认为哪些是最重要的?
基于规模、资金、方法和行业标准,每个工作室都有不同的分析文档需求。我认为重要的是首先分解你工作室的需求,并创建一个利益相关者一致目标的列表。您可以用度量标准将目标分解成不同的维度,然后找出哪些测量数据的工具最适合您。
我为 DreamSail Games 创建了一个 KPI 数据库,将指标分为营销、财务和游戏内指标。在发展过程中,KPI 可以作为衡量兴趣的温度计。Alexa、Google Analytics、脸书洞察、SteamWorks Financial、GameAnalytics 和 StreamHatchet 都提供了可用于监控社交提及和营销活动功效的数据。
您在跟踪 KPI 时面临哪些挑战,您对那些希望克服这些挑战的人有什么建议?
我创建了一个系统来记录和归档我的 KPI 的每周快照,使我能够以一致和全面的方式与网站管理员和分析套件进行交互。记录信息并不困难。最大的障碍在于有效的报告生成和数据可视化。
我是一个熟悉有条不紊地倾倒数据集的女孩。列出和计算价值很容易,真正的挑战在于评估。整理信息宝藏、挑选趋势以战略性地支持营销提案的能力……这是我不断磨练的技能。能够将电子表格格式的信息转换成清晰、直观的报告,让您的团队做出明智的决策,这一点非常重要。
与游戏的其他领域相比,你认为虚拟现实领域特有的分析挑战是什么?
为 VR 游戏收集数据的新技术的出现已经令人兴奋。cognitiveVR 和 Ghostline 等平台是分析解决方案,可以绘制用户交互、可视化会话、收集硬件数据,并鼓励 A/B 测试和反馈驱动的设计。有如此多的 SDK 正在开发,以协助游戏分析,挑战不在于创新;这是个伦理问题。许多新技术依赖于实时处理玩家的生理和行为信息。
用户与虚拟现实交互的方式允许极其普遍的信息收集。生物触觉和位置跟踪将随着虚拟现实硬件的每一次迭代而显著改善。随着技术的进步,沉浸感也会提高,但访问个人数据不应该成为代价。我加入 VR/AR 协会娱乐行业委员会的一个原因是帮助建立 VR 空间关于数据收集、同意、存储和个人信息传输的标准。
你认为虚拟现实领域最激动人心的发展是什么?你认为这个行业将走向何方?
我试图通过跟踪初创企业收购和风险资本融资来描绘出该行业的进展。值得关注的一家新浪潮外围虚拟现实公司 Ultrahaptics 正在通过超声波传感器阵列提供触觉虚拟按钮技术的开发套件。除了体积捕捉,内外跟踪也是 VR 和 AR 的热门技术。我正在密切关注 8i(高保真立体视频)和 Fove(低延迟眼睛跟踪和有凹渲染)。我也为 OEM 生态系统的爆发感到兴奋。随着价格在 300-500 美元之间的个人电脑驱动的头盔显示器向消费者提供,高端虚拟现实将变得更加容易获得。戴尔(Dell)和联想(Lenovo)等制造商正忙着为一系列 Windows 10 VR 就绪型电脑推出 HMD 套件。
就个人而言,我对混合现实感到非常兴奋。通过照片或视频等传统 2d 媒体分享空间体验是一项挑战。对玩家视角的不稳定、扁平的记录不能传达虚拟现实的存在。混合现实是向观众介绍虚拟现实的一种奇妙方式…它看起来真的很酷。告诉我你从来没有盯着一个电子游戏,并希望自己在环境中。传统的绿屏设置需要将物理相机与虚拟世界中的相机对准,以合成捕捉混合现实游戏。这种方法既费时又繁琐。我对原型丽芙魔方太着迷了。这是一个便携式绿色屏幕房间,将彻底改变内容创作者处理 VR 流媒体的方式。我很高兴地宣布,DreamSail Games 与 LIV 合作,将首批 50 个 LIV 立方体中的一个带到纽约市(以及游戏分析峰会!).
你认为性别仍然是游戏中的一个问题吗?你认为公司在改善这个问题上做得足够多了吗?你认为还可以做些什么?
我们都记得 Gamergate。女性和非独联体个人融入游戏文化的斗争仍在激烈进行。白皮书展示了在访问虚拟现实方面的差距,并强调了从事虚拟现实开发的女性在工资和雇佣方面的差距。作为一个习惯于在我的领域中成为少数派的女性,收集受众细分报告表明“聪明”的做法是设计一款旨在安抚男性千禧一代的游戏是毁灭性的。话虽如此,VR 是一个平等的时机已经成熟的空间。围绕支持虚拟现实领域女性的运动,形成了令人惊叹的开发者和布道者社区。
一个必须解决的问题是虚拟空间中的骚扰。传统的游戏平台一直局限于语音、信息和 2D 屏幕上的虚拟角色动作。随着社交 VR 的出现,空间骚扰的案例早已如雨后春笋。开发者需要主动解决对虚拟现实礼仪的担忧,并努力杜绝有害行为。我觉得公司已经意识到了不平等的问题,只要社区积极主动地要求安全的游戏空间,开发者就会非常乐意去遵守。
游戏工作室能够分享数据和分析见解来开发更好的虚拟现实吗?或者竞争太大了?
当然,这已经发生了。在 GDC、Twitchcon 和 PAX 这样的大会上展出时,我很幸运地遇到了一些了不起的游戏开发者,他们很友好地回复了我荒谬的电子邮件。我发出请求(带笑脸),询问关于他们游戏的活跃会话统计数据、营销活动的功效以及开发系统查询的私密开发问题,从生产持续时间到团队规模,再到敏捷软件偏好。我为我的团队培养的行业指导和支持系统展示了在虚拟现实领域为了更大的利益而分享的意愿。我们正处于一个未知的领域,拥有颠覆性的技术。在线社区提供支持,同时开发人员创建教程、举办讲座和发布开发博客。
巧合的是,我的演讲将是关于我在虚拟现实领域的智力合作。合作竞争,也称为合作竞争,是博弈论中记载的一个主要内容。竞争与合作并存的机制发生在利益一致的行业。相互竞争的公司的集体贡献创造了一种鼓励的现象,促进了研究和知识共享。这反过来又加速了内容创建、VR 开发可访问性和消费者采用率。随着 DreamSail 越过 R&D 和前期制作进入垂直切片开发,我有了一些为争夺相同的小群体的 VR 工作室工作的导师和朋友。在生产的早期阶段,先锋开发人员提供的见解和合作伙伴关系,他们支持我们取得成功,使一切都变得不同。
在游戏分析峰会上,您可以听到辛迪以及该领域其他行业领先的演讲人的更多内容。点击 查看完整议程 。
原刊此处。
可解释性:最后一英里
为了让你的用户理解你的模型,仅仅“可解释”是不够的——你需要提供最终的解释
可解释或可解释的模型已经从近乎空想变成了日益普遍的业务需求。然而,尽管有越来越多的方法可用于解释模型,但这些仍然是技术工具,针对的是需要理解他们创建的模型的统计和数据科学实践者。对于创建最终用户可以理解的模型来说,它们是必要的,但还不够。
创建一个最终用户可以理解的模型,一方面意味着确保他们基本理解模型中的输入和输出变量是什么,另一方面意味着他们理解这些变量在模型中如何操作。
在每一种情况下,最终的演示对于确保实现无缝用户体验的最终目标至关重要。虽然相对明显的是,输入变量本身是复杂模型的输出,或者变量具有不透明的名称,如“Var1 ”,会增加用户的困惑,而不是帮助他们理解,但有时不清楚需要多少解释。
部分问题在于,从建模者的角度来看,重要的是变量中包含了什么——模型的比率输入的名称很可能指的是构成比率的变量。显然,这对变量的用户来说意义不大。想想会计比率的名称——“速动比率”、“酸性测试”,或者物理和工程中的无量纲常数,如雷诺数(在简单的水平上,它表示流体中的湍流程度)。
雷诺数虽然没有一个完美的交流名称(从这个角度来看,“湍流数”可能是一个改进),但它确实说明了以不同的方式将模型输入的计算与其在模型中的意义分离的概念——在不同的背景下,不同的工程模型中使用多个雷诺数,但基本上以相同的方式使用雷诺数——来量化流体的湍流。对于管道和通道中的流动,对于穿过流体下落的颗粒,对于搅拌槽中的叶轮以及对于填充床中流动的流体,都有一个雷诺数——所有这些都有不同的计算,都至少在基本层面上表达了相同的概念。
在数据科学模型中,这有两种方式。一个是,如果你想在尽可能多的地方重用你的模型,为了可移植性,用一种独立于它们的成分的方式来标记你的变量是很方便的。例如,在信贷风险模型中,由于当地税收或其他监管原因,收入或资产可能有不同的计算方法。
第二点更为重要——如果其他人要使用模型,您的界面将需要标记,而在模型中引用变量含义的标记比解释其成分的标记更能向用户解释输入。在雷诺数的情况下,解释“表示湍流趋势的常数,其中较高的数更倾向于湍流”更有用,并且比“直径、速度和流体密度与流体粘度之比”更能解释其在模型中的用途。
当然,这个变量定义必须易于用户访问。如果它足够短,悬停或工具提示是一个很好的方法。否则,一个易于访问的定义屏幕将确保您的用户理解您的模型的输入。
很明显,解释变量是什么是不够的——你需要确保你的用户理解他们如何一起工作以确保最终的结果。最大的障碍可以说是机器学习算法通过考虑非线性关系和相互作用来实现准确性,而这些特别难以可视化。
现有的模型解释器(如 LIME)通过假设在靠近模型表面上任意点的区域中,相互作用效应和非线性效应可以忽略不计来简化这些方面。如果你的模型需要理解的重要方面是你的模型如何对单个案例进行评级,那么这就是正确的方法。
如果对你的用户来说,理解整个模型的趋势更重要,创建可视化,可能基于附加模型,梳理出非线性的方面,可能是更用户友好的方法。
罗伯特·德格拉夫是《进行中的书’【懒惰的数据科学家】 的作者,可通过 LeanPub 获得。他最近为 Medium 撰写的文章是 保持用户的信任。
可解释人工智能:数据科学家的新挑战
在我们开始之前,让我提一下,在这篇文章中,我将使用可解释性和可解释性这两个词来描述同一个概念。
也就是说,让我们想象一下这样一种情况,有人要求银行贷款,而由信贷风险评估中专门的机器学习算法驱动的计算机拒绝了这一要求。雇员无法解释这样一个明确的答案的原因,肯定会被留在一个非常尴尬的位置。
在机器学习的进步正在到达医学、刑事司法系统和金融市场等关键领域的背景下,这种情况肯定会更加频繁。事实上,人们越来越担心人工智能代理的可接受性和信任问题,因为它们缺乏可解释性。多年来,性能优先于可解释性,导致了包括计算机视觉、自然语言处理和序列建模在内的几个领域的巨大进步。然而,由不愿接受基于人工智能的决策所驱动的关键问题可能会导致一种全新的动态,其中可解释性可能是评估模型的关键措施之一。在本文中,我将讨论一些具体的原因,为什么它会是一个主要的区别。还将提出一些方法来开发强大的算法,同时保持良好的可解释性。
"有一个精确的模型是好的,但是解释导致更好的产品. "
数据科学的进步一直是由寻找解决任何问题的最佳性能模型推动的。从数学的角度来看,模型的搜索集中于成本函数的最小化或似然函数的最大化。因此,模型的性能几乎完全是根据我们根据一些正确选择的度量标准得到的结果来衡量的。这种趋势导致了越来越复杂的算法,以牺牲可解释性为代价。事实上,一些数据科学家甚至可能断言 “让机器学习算法难以理解的东西也是让它们成为优秀预测者的东西” 。它们很复杂,这就是为什么对大多数领域从业者来说,它们看起来像***【黑盒】*** 。
Interpretability vs performance seen through machine learning techniques (non exhaustive)
上图描绘了机器学习算法的两个可解释性级别:
- **高解释性:**这一层包括传统的回归算法(例如线性模型)、决策树以及分类规则。基本上它们近似单调线性函数。
- **可解释性低:**这个级别包括高级机器学习技术,如支持向量机、高级集成方法和深度学习。他们复杂的谎言
在这两者之间,你可以找到一些方法,根据学习过程中应用的约束,这些方法可以被归入任何一类(单调性约束可以应用于集成方法,并且一些实现已经可用)。
可解释性是对人类观察者理解模型所做预测背后的原因的程度的衡量,在准确性之间找到正确的平衡变得越来越有必要。这可能是让算法对日常用户尽可能透明的关键。这种对 【以用户为中心】 的关注点的改变,可能会对该技术在各种领域的应用和接受产生影响,使他们能够更舒适地适应以更现实的方式执行任务。
尽管应用机器学习的许多核心方面在不同领域都是相同的,但它们不能应用于每个行业。机器学习方法非常不同,特别是在银行、保险公司、医疗保健提供商和其他受监管的行业。原因主要是他们倾向于法律甚至伦理要求,这些要求倾向于越来越多地限制黑盒模型的使用。作为一个例子,我可以列举公平信用报告法案第 609(f)(1)条
应向消费者提供在所用模型中对消费者信用评分产生不利影响的所有关键因素,其总数不得超过 4 个
最重要的是,这显然意味着人们应该提供关于如何获得模型响应的见解。直接后果是将可能方法的范围缩小到最简单的方法,因为它们易于解释,除非我们找到方法将上下文添加到最先进算法的预测中。
更不用说,这种趋势更多的是加强监管约束,而不是减缓监管约束。
An ever growing list of legal and ethical considerations surrounding businesses
所有这些因素都在很大程度上导致了行业普遍不愿意采用和部署由机器学习系统驱动的高级数据产品。面对这样的限制,研究越来越多地集中于确定处理模型可解释性的方法。
据我所知,实现模型可解释性的途径主要有两种:和 局部可解释 。前者旨在使整个决策过程完全透明和全面,而后者侧重于为每个决策提供解释。
“当我们开始一个数据科学项目时,现在的最佳做法可能是首先确定我们希望达到的可解释性程度。”
事实上,首先决定可解释性的程度将指导我们选择可能实现的算法和技术。具体来说,这意味着是选择一个简单的模型并使其更加强大(以实现全局可解释性*),还是使用一个我们可以使其更加可解释的复杂模型(以至少实现局部可解释性)。下表呈现了一个**-的详尽列表 的技巧处理模型的可解释性。*
也许你已经注意到局部可解释性比全局可解释性有更多的细节。这主要是由于在解释复杂模型方面所做的巨大努力,但是采用了局部边界方法。
最后,当我们用正确的方法实现我们的算法时,最后的问题在于如何评估模型的可解释性。有两种方法可以更好地表示最终模型所赋予的理解程度:
- 模拟具有已知特征和内在含义的数据,以对抗模型对我们在该上下文中已有先验知识的解释。
- ****测试数据扰动下的稳定性在显式变量中加入少量噪声。可信的解释可能不会因为微小的变化而发生剧烈的变化。
希望您在这个非常重要的“最近”关注点的旅途中过得愉快。如果您有任何问题或意见,我将很高兴欢迎进一步讨论。在我的下一篇文章中,我将通过一个真实世界的用例来直接解决这个问题,以便更好地理解上面的所有含义。
如果需要进一步的阅读资料,请不要犹豫参考下面的链接。
我还要感谢对本文做出贡献的同事们何塞·桑切斯、纳尔逊·费尔南德斯、西蒙·帕尔马。
https://arxiv.org/pdf/1606.03490.pdf
**【https://distill.pub/2018/building-blocks/ **
Navdeep Gill 和 Patrick Hall 的《机器学习可解释性简介》
可解释的人工智能与解释人工智能——第一部分
深度学习够深吗?
Framework of Explainable Deep Learning, source Society of Mind (Marvin Minskey)
尽管最近深度学习(DL)取得了显著的成果,但由于欠拟合、过拟合或不完整的训练数据等几个原因,它总是存在产生妄想和不切实际的结果的风险。例如,职业围棋选手 Lee Sedol 的著名棋步 78 导致了 Alpha Go 的妄想行为、对抗性攻击以及 DeepXplore 在 Nvidia DAVE-2 自动驾驶汽车平台中发现的错误行为,其中系统决定对同一输入图像做出两种不同的决定,唯一的区别是亮度级别。这些例子推动人工智能研究人员更加专注于打开深度学习的黑匣子,避免只依赖模型的准确性。
前一段时间,我在为非人工智能职业准备一个关于人工智能状态的研讨会。由于人工智能目前是一个流行词,并且流行词通常有很多定义,我不得不选择一个。人工的定义很清楚,但是智能呢?我搜索并找到了马文·明斯基对人工智能最合理和相关的定义:
我们的模型包含过程,使我们能够解决我们认为困难的问题。
“黑盒”是那些我们还不了解的过程的名称。
实际上,这是这个定义的修改版本,我用“黑盒”代替了“智能”,用“模型”代替了“头脑”虽然我已经改变了它,但定义仍然成立。
这些论点告诉我们这些事情:a)黑盒和智能是一样的,b)复杂的问题需要复杂的解决方案,c)简单、可理解的过程很可能不适合复杂的问题,如自动驾驶汽车和机器翻译,以及 d)盒子越暗,它就越智能。
因此,当我们要求深度学习科学家打开黑盒时,这可能意味着限制模型能力。
但是真的吗?
人类大脑中的大多数过程都是模糊的,我们不理解它们,这是正确的,但我们仍然可以解释我们的决定和想法。我们的解释通常由陈述和理由组成。我们的讲解不涉及统计推断分析(除非和题目有关)。
所以问题是:我们如何解释或决定?
人类的大脑由两个不同的系统组成,大脑用这两个系统来形成思想。这两个系统是:
系统 1: 是一种快速、直观、无意识和情绪化的、刻板的、自动的,并利用与过去经验的相似性来做出决定
系统 2: 是一个缓慢的、有意识的、有逻辑的、努力的系统,使用高级推理来做出决策
Two systems of thinking
系统 1 做出不需要太多注意力和常识的自动决定,比如走路、拿着物体、理解简单的句子或者在高速公路上开车。系统 2 进行高级推理,这需要常识,比如理解法律条款或在拥挤的城市中驾驶汽车,这不仅需要车道间驾驶的知识,还需要城市内交通规则和人为因素的知识。
那么接下来的问题是:系统 1 和系统 2 在 AI 中代表什么?
1988 年,马文·明斯基出版了他的书《心智的社会》。这本书最有趣的部分之一是在人脑中表现知识的框架。
Framework for representing knowledge, source Society of Mind (Marvin Minskey)
大脑中的知识由七层组成(忽略小词,输入层)。考虑到最近的人工智能技术,我将对它们的功能解释如下:
- **神经网络:**代表 ANN/DL。这一层的主要目标是避免维数灾难,并构建一个高层次的分布式/非纠缠表示。这一层代表大脑最直观的部分(系统 1)。这是刻板和自动的。学习缓慢而艰难,解释困难
- **K 线和 k 线树:**马文·明斯基把 k 线看做记忆线。但我提出 k 线层代表的是所谓的归纳编程。为解决某些问题而学习的一系列程序。这一层是系统 1 和系统 2 之间的第一个桥梁。它比 NN 层更有逻辑性,使用的推理更多。更容易学习和解释。
- **语义网络:**表示知识图、语义网或本体。它再次更接近系统 2 的方向。通过断开或连接两个事实(节点),一次性学习变得更加容易。
- 框架:框架是一种数据结构,具有关于特定对象或概念的典型知识。它和第三层一样,但是有更多的解释和更容易学习
- 常识台词:这里我把最后三层都合并成了一层。这些层的目标是将不同的领域连接在一起,形成常识和常识,例如,在城市中驾驶汽车。它和第四层一样,但是有更多的解释和更容易学习
考虑到以上几点,我们得出以下结论:
Framework of Explanation Deep Learning, source Society of Mind (Marvin Minskey)
- 我们所谓的深度学习实际上还没有深到可以解释的程度
- 我们所说的深度学习实际上还不足以执行一次性学习
- 实现可解释人工智能的关键是缩小四层知识之间的差距
- 通过弥合这些差距,我们实现了一个可以使用系统 2 解释自己的人工智能,同时它在直观的系统 1 中保持复杂的解决方案
- 通过弥合这些差距,我们实现了一个可以使用系统 1 解决直观体验问题,并可以使用系统 2 概括和解决推理问题的人工智能
- 解释人工智能的目标不仅是建立信任,而且是提高性能和实现人工智能的一般智能
在本系列文章的下一部分中,我将深入研究旨在弥补上述框架缺陷的最新技术。从使用时间或形状来解释系统 1 的决策开始,通过最近的神经符号研究和归纳逻辑编程,由 Yoshua Bengio 解决意识先验,最后如何建立一个解释 AI 模型而不是解释 AI 模型。
敬请期待!
模型解释策略
可解释的人工智能(第二部分)
了解模型解释技术、局限性和进步
Source: Pixabay
介绍
本文是我针对 ***【可解释的人工智能(XAI)***系列文章的延续。如果你还没有阅读第一篇文章,我肯定会建议你快速浏览一下 【第一部分——人类可解释机器学习的重要性】 ,它涵盖了人类可解释机器学习的内容和原因,以及模型解释的必要性和重要性及其范围和标准。在本文中,我们将从我们停下来的地方开始,进一步扩展到机器学习模型解释方法的标准,并探索基于范围的解释技术。本文的目的是让您很好地理解现有的、传统的模型解释方法,以及它们的局限性和挑战。我们还将讨论经典的模型准确性与模型可解释性之间的权衡,最后看看模型解释的主要策略。
简而言之,我们将在本文中讨论以下几个方面。
- 模型解释的传统技术
- 传统技术的挑战和局限
- 准确性与可解释性的权衡
- 模型解释技术
这应该让我们为第 3 部分中模型解释的详细实践指南做好准备,所以请继续关注!
模型解释的传统技术
模型解释的核心是找到更好地理解模型决策政策的方法。这是为了实现公平、问责和透明,这将使人类有足够的信心在现实世界的问题中使用这些模型,这些问题对商业和社会有很大影响。因此,现在有一些已经存在很长时间的技术,可以用来以更好的方式理解和解释模型。这些可以分为以下两大类。
- 探索性分析和可视化技术,如聚类和降维。
- 模型性能评价指标如 精度、 、 ROC 曲线、AUC (用于分类模型)和(R-square)、 均方根误差、平均绝对误差 (用于回归模型)
让我们简单地更详细地看一下这些技术。
探索性分析和可视化
探索性分析的想法并不是全新的。多年来,数据可视化一直是从数据中获取潜在洞察力的最有效工具之一。这些技术中的一些可以帮助我们从我们的数据中识别关键特征和有意义的表示,这些数据可以给出可能影响模型以人类可解释的形式做出决策的指示。
降维技术在这里非常有用,因为我们经常处理非常大的特征空间(维数灾难),降维有助于我们可视化并了解什么可能影响模型做出特定决策。其中一些技术如下。
现实世界问题中的一个例子是,通过使用单词嵌入检查它们的语义相似性,并使用 t-SNE 对其进行可视化,来尝试可视化哪些文本特征可能对模型有影响,如下所述。
Visualizing word embeddings using t-SNE (Source: Understanding Feature Engineering (Part 4) — Deep Learning Methods for Text Data — Towards Data Science)
您还可以使用 t-SNE 来可视化著名的 MNIST 手写数字数据集,如下图所示。
Visualizing MNIST data using t-SNE using sklearn. Image courtesy of Pramit Choudhary and the Datascience.com team.
另一个例子是通过利用 PCA 进行降维来可视化著名的 IRIS 数据集,如下图所示。
Principal Component Analysis on the IRIS dataset
除了可视化数据和特征之外,某些更直观、更易理解的模型,如决策树,有助于我们直观地了解做出某个决策的确切方式。下面描述了一个示例树,它帮助我们以人类可理解的方式可视化确切的规则。
Visualizing human-interpretable rules for a decision tree model (Source: Practical Machine Learning with Python, Apress 2018)
然而,正如我们所讨论的,我们可能无法为其他模型获得这些规则,这些模型不像基于树的模型那样可解释。此外,巨大的决策树总是变得非常难以想象和解释。
模型性能评估指标
模型性能评估 是任何数据科学生命周期中选择最佳模型的关键步骤。这使我们能够看到我们的模型表现如何,比较不同模型的各种性能指标,并选择最佳模型。这也使我们能够 调整和优化模型中的超参数 ,以获得对我们正在处理的数据给出最佳性能的模型。典型地,基于我们正在处理的问题的类型,存在某些标准的评估度量。
- **监督学习—分类:**对于分类问题,我们的主要目标是预测离散的分类响应变量。混淆矩阵在这里非常有用,我们可以从中获得一系列有用的指标,包括准确度、精确度、召回率和 F1 分数,如下例所示。
Classification Model Performance Metrics (Source: Practical Machine Learning with Python, Apress 2018)
除了这些指标,我们还可以使用其他一些技术,如 ROC 曲线和 AUC 分数,如下图中葡萄酒质量预测系统所示。
ROC Curve and AUC scores (Source: Practical Machine Learning with Python, Apress 2018)
ROC 曲线下的面积是客观评估分类器性能的一种非常流行的技术。在这里,我们通常试图平衡真阳性率(TPR)和假阳性率(FPR)。上图告诉我们,**‘high’**
级葡萄酒的 AUC 分数是**0.9**
,这意味着模型给**‘high’**
(正级)级葡萄酒分配的分数比给**NOT ‘high’**
(或**‘low’**
(负级)级葡萄酒分配的分数高的概率是 90%。有时,如果 ROC 曲线交叉,结果可能会产生误导并难以解释(来源: 测量分类器性能:ROC 曲线下面积的连贯替代方法 )。
- **监督学习—回归:**对于回归问题,我们可以使用标准指标,如决定系数(R 平方)、均方根误差(RMSE) 和平均绝对误差(MAE) 。
- **无监督学习—聚类:**对于基于聚类的无监督学习问题,我们可以使用类似于剪影系数、同质性、完整性、V-measure 和卡林斯基-哈拉巴兹指数的度量。
传统技术的局限性和更好模型解释的动机
我们在前面的技术中讨论的技术肯定有助于理解更多关于我们的数据、特征以及哪些模型可能是有效的。然而,在试图辨别模型如何工作的人类可解释的方式方面,它们相当有限。在任何数据科学问题中,我们通常在静态数据集上构建模型,并获得我们的目标函数(优化损失函数),该函数通常在满足基于模型性能和业务需求的特定标准时部署。通常,我们利用上述探索性分析和评估指标的技术来决定我们数据的整体模型性能。然而,在现实世界中,由于数据特征的可变性、增加的约束和噪声,模型的性能在部署后通常会随着时间的推移而降低并停滞不前。这可能包括环境的变化、功能的变化以及增加的约束。因此,简单地在相同的特征集上重新训练模型是不够的,我们需要不断检查特征在决定模型预测中的重要性,以及它们在新数据点上的工作情况。
例如,入侵检测系统 (IDS),一个网络安全应用程序,容易受到规避攻击,攻击者可能会使用对抗性输入来击败安全系统(注意:对抗性输入是攻击者故意设计的例子,以欺骗机器学习模型做出错误的预测)。在这种情况下,模型的目标函数可能充当现实世界目标的弱代理。可能需要更好的解释来识别算法中的盲点,以通过修复易于受到敌对攻击的训练数据集来建立安全的模型(有关进一步的阅读,请参见 Moosavi-Dezfooli 等人,2016 年, DeepFool 和 Goodfellow 等人,2015 年, 解释和利用敌对示例 )。
此外,由于我们正在处理的数据的性质,模型中经常存在偏差,就像在罕见的预测问题(欺诈或入侵检测)中一样。度量不能帮助我们证明模型预测决策的真实情况。此外,这些传统形式的模型解释对于数据科学家来说可能很容易理解,但由于它们本质上是理论性的,并且通常是数学性的,因此在尝试向(非技术)业务利益相关者解释这些内容以及尝试仅基于这些指标来决定项目的成功标准时,存在很大的差距。仅仅告诉业务部门,*“我有一个准确率为 90%的模型”*还不足以让他们在现实世界中开始信任该模型。我们需要对模型的决策策略进行人类可解释的解释(HII ),这些决策策略可以用适当和直观的输入和输出来解释。这将使有洞察力的信息能够容易地与同行(分析师、经理、数据科学家、数据工程师)共享。使用这种形式的解释,可以根据投入和产出进行解释,可能有助于促进更好的沟通和合作,使企业能够做出更有信心的决定(例如,金融机构的风险评估/审计风险分析)。
重申一下,我们将模型解释(新方法)定义为能够解释预测模型的 公平性 (无偏性/非歧视性) 责任性 (可靠的结果),以及*(能够查询和验证预测决策)——目前是关于监督学习问题。*
准确性与可解释性的权衡
在模型性能和可解释性之间存在一种典型的权衡,就像我们在机器学习中有标准偏差和方差的权衡一样。在行业中,您经常会听到业务利益相关者倾向于更易于解释的模型,如线性模型(线性\逻辑回归)和树,这些模型直观、易于验证,并易于向非数据科学专家解释。这增加了人们对这些模型的信任,因为它的决策策略更容易理解。然而,如果您与解决行业中真实世界问题的数据科学家交谈,他们会告诉您,由于真实世界数据集固有的高维性和复杂性,他们通常不得不利用机器学习模型,这些模型可能是非线性的,本质上更加复杂,通常无法使用传统方法(集成、神经网络)进行解释。因此,数据科学家花费大量时间试图改善模型性能,但在这个过程中,他们试图在模型性能和可解释性之间取得平衡。
Model performance vs. interpretability (Source: https://www.datascience.com))
*上图显示了一个客户贷款批准问题的模型决策边界。我们可以清楚地看到,具有单调决策边界的简单、易于解释的模型在某些场景中可能工作良好,但通常在现实世界的场景和数据集中,我们最终会使用具有非单调决策边界的更复杂、更难以解释的模型。因此,为了加强我们的动机,我们需要模型解释,以便我们能够说明预测模型的公平性(无偏性/非歧视性)责任性(可靠的结果)和透明性(能够查询和验证预测决策)。有兴趣的读者可以查阅文章, 【迈向机器学习的喷射时代】 *。除此之外,我肯定会推荐读者查看我个人最喜欢的一篇文章,我在这个系列中改编了很多内容, “用 Skater 解释预测模型:拆箱模型不透明度” 其中更详细地谈到了这一点。
* [## 用 Skater 解释预测模型:打开模型不透明度
深入探究作为理论概念的模型解释,以及对滑手的高层次概述。
www.oreilly.com](https://www.oreilly.com/ideas/interpreting-predictive-models-with-skater-unboxing-model-opacity)
模型解释技术
有各种各样的新模型解释技术试图解决传统模型解释技术的局限性和挑战,并试图对抗经典的可解释性与模型性能之间的权衡。在这一节中,我们将看看其中的一些技术和策略。请记住,我们的重点将是涵盖模型不可知的解释技术,因为这些技术将真正帮助我们走向可解释的人工智能(XAI) 。
使用可解释的模型
开始模型解释的最简单的方法是使用开箱即可解释的模型!这通常包括您的常规参数模型,如线性回归、逻辑回归、基于树的模型、规则拟合,甚至像 k-最近邻和朴素贝叶斯这样的模型!根据主要功能对这些模型进行分类的方法是:
- 线性:通常,如果特征和目标之间的关联是线性建模的,那么我们有一个线性模型。
- 单调性:单调模型确保特性和目标结果之间的关系在特性上(在其值的整个范围内)总是在一个一致的方向上(增加或减少)。
- 交互:您可以随时使用手动特征工程向模型添加交互特征、非线性。有些型号还会自动创建它。
Christoph Molnar 的优秀著作, 【可解释机器学习】 有一个很好的表格总结了以上几个方面。
Source: Interpretable Machine Learning, Christoph Molnar
需要记住的一点是,其中一些模型可能过于简单,因此我们可能需要考虑更好的方法来构建和解释更复杂、性能更好的模型。
特征重要性
特征重要性是预测模型依赖特定特征的程度的通用术语。通常,一个特征的重要性是在我们改变了该特征的值之后模型预测误差的增加。像 Skater 这样的框架基于一个信息论标准来计算,在给定一个给定特征的扰动的情况下,测量预测变化的熵。直觉告诉我们,一个模型的决策标准越依赖于一个特征,我们就越会看到预测随着对一个特征的扰动而变化。然而,像 SHAP 这样的框架,使用特征贡献和博弈论的组合来得出 SHAP 值。然后,它通过对整个数据集的 SHAP 值进行平均来计算全局要素重要性。以下是人口普查数据集中溜冰者要素重要性图的标准示例。
看起来Age
和Education-Num
是最重要的两个特征,其中Age
负责模型预测在扰动/置换Age
特征时平均变化 14.5%。因此,总而言之,模型不可知特性重要性的全局解释背后的概念非常简单。
- 我们通过计算扰动特征后模型预测误差的增加来衡量特征的重要性。
- 如果扰动某个要素的值会增加模型误差,则该要素是“重要的”,因为模型依赖于该要素进行预测。
- 如果扰动某个特征的值使模型误差保持不变,则该特征是“不重要的”,因为模型基本上忽略了该特征的预测。
Breiman (2001) 为随机森林引入了排列特征重要性度量。基于这一想法, Fisher、Rudin 和 Dominici (2018) 提出了特征重要性的模型不可知版本——他们称之为模型依赖*。*
部分相关图
部分相关性描述了某个功能对模型预测的边际影响,使模型中的其他功能保持不变。部分相关的导数描述了特征的影响(类似于回归模型中的特征系数)。部分相关性图(PDP 或 PD 图)显示了某个特性对先前拟合模型的预测结果的边际影响。PDP 可以显示目标和特征之间的关系是线性的、单调的还是更复杂的。部分相关图是一种全局方法:该方法考虑了所有实例,并陈述了某个特征与预测结果的全局关系。下图显示了一些 PDP 示例。
PDP for 1 feature
我们用溜冰者和 SHAP 来说明教育水平对挣更多钱的影响。这是一个单向 PDP,显示了一个特征对模型预测的影响。我们还可以构建双向 PDP,显示两个特征对模型预测的影响。下图显示了一个示例。
PDP for 2 features
在上述 PDP 中,您可以清楚地看到影响模型预测的特性的效果和相互作用。受教育程度更高、每周工作时间更长的显著中年人挣钱更多!
全球代理模型
我们已经看到了用特征重要性、依赖图、不太复杂的模型来解释机器学习模型的各种方法。但是有没有一种方法可以建立真正复杂模型的可解释的近似值呢?谢天谢地,我们有全球代理模型,正是为了这个目的!全局代理模型是一种可解释的模型,它被训练成近似黑盒模型的预测,而黑盒模型本质上可以是任何模型,不管其复杂性或训练算法如何,这是模型不可知的!
通常,我们基于被视为黑盒模型的基本模型,近似一个更易解释的代理模型。然后,我们可以通过解释代理模型得出关于黑盒模型的结论。用更多的机器学习来解决机器学习的可解释性!
(可解释的)替代模型的目的是在可解释的同时尽可能接近基础模型的预测。拟合代理模型是一种模型不可知的方法,因为它不需要关于黑盒模型内部工作的信息,只使用输入和预测输出的关系。基本黑盒模型类型和代理模型类型的选择是分离的。基于树的模型不是太简单,而是可解释的,是构建代理模型的好选择。
Skater 介绍了使用**TreeSurrogates**
作为解释模型的学习决策策略(用于归纳学习任务)的手段的新颖想法,这是受 Mark W. Craven 的工作(称为特雷潘算法)的启发。我们将在本系列的第 3 部分中用例子介绍特雷普恩模型。目前,Christoph Molnar 在他的一书中出色地讲述了构建代理模型的主要步骤。
- 选择数据集这可以是用于训练黑盒模型的同一数据集,也可以是来自同一分布的新数据集。根据您的应用程序,您甚至可以选择数据的子集或点的网格。
- 对于所选数据集,获取基础黑盒模型的预测。
- 选择一个可解释的替代模型(线性模型、决策树等等)。
- 对数据集及其预测训练可解释的模型。
- 恭喜你!你现在有了一个代理模型。
- 衡量代理模型复制黑盒模型预测的能力。
- 解释/可视化代理模型。
当然,这是一个高层次的说明,TREPAN 等算法在内部做得更多,但整体工作流程仍然保持不变。
Sample illustration of a surrogate tree model
上图是从复杂的 XGBoost 黑盒模型近似而来的代理树模型。我们将在第 3 部分从头开始构建它,敬请关注!有趣的是,与 XGBoost 模型的 87%的准确度相比,这个模型具有 83%的总准确度。还不错!
局部可解释的模型不可知解释(LIME)
LIME 是由 Riberio Marco、Singh Sameer 和 Guestrin Carlos 设计的一种新算法,用于使用本地可解释替代模型(如线性分类器/回归器)来评估任何基础估计量(模型)的行为。这种形式的综合评估有助于产生局部忠实的解释,但可能不符合全局行为。基本上,石灰解释是基于本地代理模型。这些替代模型是可解释的模型(如线性模型或决策树),是根据原始黑盒模型的预测学习的。但是,LIME 没有试图拟合一个全球代理模型,而是专注于拟合局部代理模型,以解释为什么会做出单一预测。事实上,也可以作为 GitHub 上的一个 开源框架,并且是基于本文 中 介绍的工作。
这个想法非常直观。首先,试着忘掉你已经做过的事情!忘记训练数据,忘记你的模型是如何工作的!认为你的模型是一个黑盒模型,里面有一些神奇的事情发生,你可以输入数据点,并得到模型预测的结果。你可以随时探测这个神奇的黑箱,得到输入和输出预测。现在,你的主要目标是理解为什么你作为一个神奇的黑盒子对待的机器学习模型,给出了它产生的结果。LIME 试着为你做这件事!它测试当你把数据集的变化或扰动输入黑盒模型时,黑盒模型的预测会发生什么。通常,LIME 会生成一个由扰动样本和相关黑盒模型预测组成的新数据集。在这个数据集上,LIME 然后训练可解释的模型,该模型通过采样实例与感兴趣实例的接近度来加权。以下是标准的高级工作流程。
- 选择您感兴趣的实例,您希望对其黑盒模型的预测进行解释。
- 扰动数据集,获得这些新点的黑盒预测。
- 根据与感兴趣的实例的接近程度对新样本进行加权。
- 将加权的、可解释的(替代)模型拟合到有变化的数据集上。
- 通过解释本地模型来解释预测。
下面是一个在 Skater 框架中使用 LIME 的示例,它解释了为什么该模型预测一个人将赚超过 50K 美元。
Explaining predictions with LIME
我们将使用人口普查数据集来构建模型,并在下一篇文章中用 LIME 更详细地探索它们。
沙普利值和沙普利加法解释(SHAP)
****SHAP(SHapley Additive exPlanations)是解释任何机器学习模型输出的统一方法。SHAP 将博弈论与局部解释相结合,结合了以前的几种方法,并基于他们所声称的,代表了唯一可能一致且局部精确的附加特征归因方法!(详情请查看 SHAP 夹纸)。SHAP 是一个优秀的模型解释框架,它基于对 Shapley 值的调整和增强,我们将在本节中深入探讨。再次感谢 Christoph Molnar 的 惊人的模型解释书 ,我将无耻地将它改编到本教程中,因为在我看来,这可能是理解这个概念的最佳方式!
通常,模型预测可以通过假设每个特征是游戏中的【玩家】来解释,其中预测是支出。Shapley 值——一种来自联合博弈论的方法——告诉我们如何在特性之间公平地分配‘支付’*。让我们举一个说明性的例子。*
*假设你训练了一个机器学习模型来预测公寓价格。对于某个公寓,它预测 300,000 €,你需要解释这个预测。公寓面积50 平米,位于二楼,附近有公园和*禁止养猫。所有公寓的平均预测价格是 31 万€。与平均预测相比,每个特征值对预测的贡献有多大?
线性回归模型的答案很简单:每个特征的影响是特征的权重乘以特征值减去所有公寓的平均影响:这只是因为模型的线性。对于更复杂的模型,我们该怎么做?一种选择是我们刚刚讨论过的石灰。另一个不同的解决方案来自合作博弈理论: 由 Shapley 创造的 Shapley 值 ,是一种根据玩家对总支出的贡献将支出分配给玩家的方法。玩家在联盟中合作,并从合作中获得一定的收益。
- **“游戏”是数据集的单个实例的预测任务。
- **‘增益’是该实例的实际预测减去所有实例的平均预测。
- **‘玩家’是实例的特征值,协同接收增益(=预测某个值)。
因此,在我们的公寓示例中,特征值**‘park-allowed’**
、**‘cat-forbidden’**
、**‘area-50m-sq’**
和**‘floor-2nd’**
共同实现了 300,000€的预测。我们的目标是解释实际预测(300,000€)和平均预测(310,000€)的差异:差异为-10,000€。答案可能是:**‘park-nearby’**
号贡献了 3 万€;**‘size-50m-sq’**
贡献了一万€;**‘floor-2nd’**
贡献了 0€;**‘cat-forbidden’**
出资 5 万€。捐款加起来是-10,000€:最终预测减去平均预测公寓价格。
Shapley 值是一个特征值在所有可能的联合中的平均边际贡献。联盟基本上是用于估计特定特征的 shapley 值的特征的组合。通常情况下,要素越多,它就开始呈指数增长,因此可能需要花费大量时间来计算大数据集或宽数据集的这些值。下图显示了评估**‘cat-forbidden’**
的 Shapley 值所需的所有特征值组合。
第一行显示了没有任何特征值的联盟。第二、第三和第四行显示不同的联盟——由**‘|’**
分隔——联盟规模逐渐增大。对于这些联盟中的每一个,我们计算有和没有**‘cat-forbidden’**
特征值的预测公寓价格,并取其差值以获得边际贡献。Shapley 值是边际贡献的(加权)平均值。我们用来自公寓数据集的随机特征值替换不在联盟中的特征的特征值,以从机器学习模型获得预测。当我们对所有特征值重复 Shapley 值时,我们得到特征值之间预测的完整分布(减去平均值)。SHAP 是沙普利值的增强。
SHAP (SHapley 附加解释)为每个特征分配一个特定预测的重要性值。其新颖的组成部分包括:识别一类新的加性特征重要性度量,理论结果表明在这一类中有一个唯一的解决方案,具有一组理想的性质。通常,SHAP 值试图将模型(函数)的输出解释为引入条件期望的每个特征的效果的总和。重要的是,对于非线性函数,引入特征的顺序很重要。SHAP 值由所有可能的排序的平均值产生。博弈论的证据表明这是唯一可能的一致方法。下面的图来自 KDD 18 论文, 一致的个性化特征归属为树系综 很好地概括了这一点!
Understanding SHAP value
下面是一个使用 SHAP 来解释模型在预测一个人的收入是否大于 5 万美元时的决策的例子
Explaining model predictions with SHAP
看到模型背后的关键驱动因素(特性)做出这样的决定是很有趣的!我们还将在本系列的第 3 部分中用实际操作的例子来介绍这一点。
结论
这篇文章将帮助你在通往可解释人工智能(XAI)的道路上迈出更明确的步伐。您现在知道了模型解释的必要性和重要性。第一篇文章中关于偏见和公平的问题。在这里,我们研究了模型解释的传统技术,讨论了它们的挑战和局限性,还介绍了模型可解释性和预测性能之间的经典权衡。最后,我们研究了当前最先进的模型解释技术和策略,包括特征重要性、PDP、全局代理、局部代理和 LIME、shapley 值和 SHAP。就像我之前提到的,让我们努力实现人类可解释的机器学习和 XAI,为每个人揭开机器学习的神秘面纱,并帮助增加对模型决策的信任。*
下一步是什么?
在本系列的第 3 部分中,我们将会看到一个使用我们在本文中学到的所有新技术来构建和解释机器学习模型的综合指南。为此,我们将使用几个最先进的模型解释框架。
- 关于使用最新的模型解释框架的实践指南
- 使用 ELI5、Skater 和 SHAP 等框架的特点、概念和示例
- 探索概念并观察它们的实际应用——特征重要性、部分相关图、替代模型、用石灰的解释和说明、SHAP 值
- 基于监督学习示例的机器学习模型解释
敬请期待,这肯定会变得更加有趣和令人兴奋!
请查看 “第一部分——人类可解释机器学习的重要性” ,其中涵盖了人类可解释机器学习的内容和原因,以及模型解释的必要性和重要性及其范围和标准(如果您还没有了解的话)!
我在我的书中覆盖了很多机器学习模型解释的例子, 【用 Python 实现实用的机器学习】 。为了您的利益,代码是开源的!
有反馈给我吗?或者有兴趣与我一起从事研究、数据科学、人工智能甚至发表一篇关于TDS的文章?可以在LinkedIn上联系我。
** [## Dipanjan Sarkar -数据科学家-英特尔公司| LinkedIn
查看 Dipanjan Sarkar 在世界最大的职业社区 LinkedIn 上的个人资料。Dipanjan 有 6 份工作列在…
www.linkedin.com](https://www.linkedin.com/in/dipanzan/)**
动手机器学习模型解释
可解释的人工智能(第三部分)
解释机器学习模型的综合指南
介绍
鉴于人工智能在行业中的快速采用,解释机器学习模型不再是一种奢侈品,而是一种必需品。本文是我针对 ***【可解释人工智能(XAI)***系列文章的延续。这里的想法是通过炒作,使您拥有开始解释任何黑盒机器学习模型所需的工具和技术。如果您想快速浏览一下,下面是本系列的前几篇文章(但不是本文的强制要求)。
- 第 1 部分——人类可解释机器学习的重要性’***😗**涵盖了人类可解释机器学习的内容和原因,以及模型解释的需求和重要性及其范围和标准
- 第二部分——模型解释策略’它涵盖了人类可解释的机器学习的方式,我们在其中查看了与模型解释的主要策略相关的基本概念。
在本文中,我们将为您提供实践指南,展示以模型不可知的方式解释潜在黑盒机器学习模型的各种方法。我们将致力于一个真实世界的人口普查收入数据集,也称为成人数据集*,可在 UCI ML 知识库中获得,在那里我们将预测人们的潜在收入是否超过 5 万美元/年。*
这篇文章的目的是多方面的。第一个主要目标是让我们自己熟悉主要的最新模型解释框架(它们中的许多都是 LIME 的扩展——我们已经在本系列的 第 2 部分 中详细介绍的为模型解释提出的原始框架和方法)。
我们将在教程中介绍以下模型解释框架的使用。
我们将在本教程中讨论的主要模型解释技术包括以下内容。
- 特征重要性
- 部分相关图
- 模型预测解释结合局部解释
- 用基于代理树的模型构建可解释模型
- 用 SHAP 值进行模型预测解释
- 依赖&与 SHAP 的互动剧情
事不宜迟,让我们开始吧!
正在加载必要的依赖项
鉴于这是一个模型解释的实践指南,我们将在本文中使用大量的框架和工具。我们建议您加载以下依赖项,以充分利用本指南!
记住调用**shap.initjs()**
函数,因为**shap**
中的很多图都需要 JavaScript。
加载并查看人口普查收入数据集
你其实可以从 UCI ML 资源库 中获取 人口普查收入 数据集(俗称 成人数据集 )。幸运的是**shap**
为我们提供了这个数据集的一个已经清理过的版本,我们将在这里使用它,因为这篇文章的目的是模型解释。
查看数据属性
让我们看看数据集的主要特征或属性。
***((32561, 12), (32561,))***
Census Dataset Features
我们将很快解释这些特性。
查看类别标签
让我们来看一下 < = $50K ( **False**
)和*>【50K】**(**True**
)收入的人的分布,这是我们要预测的阶级标签。*
***In [6]: Counter(labels)****Out[6]: Counter({0: 24720, 1: 7841})***
鉴于我们应该让更少的人拥有更高的收入,肯定会出现一些阶级失衡。
了解人口普查收入数据集
现在让我们来看看我们的数据集属性,并理解它们的含义和重要性。
我们总共有 12 个特征,我们的目标是预测一个人的收入是超过 5 万美元 ( **True**
)还是低于 5 万美元 ( **False**
)。因此,我们将建立和解释一个分类模型。
基础特征工程
这里,我们将带有字符串值的分类列转换为数字表示。通常,XGBoost 模型本身是一个基于树的模型,可以处理分类数据,所以我们在这里不对这些特性进行一次性编码。
在我们建立分类模型之前,是时候建立我们训练和测试数据集了。
构建训练和测试数据集
对于任何机器学习模型,我们总是需要训练和测试数据集。我们将在训练数据集上构建模型,并在测试数据集上测试性能。我们维护两个数据集(一个具有编码的分类值,一个具有原始值),因此我们可以使用编码的数据集进行训练,但在以后需要时使用原始数据集进行模型解释。
***((22792, 12), (9769, 12))***
Our encoded dataset
我们还在一个单独的数据帧中用实际(未编码的)值维护我们的基本数据集(对以后的模型解释有用)。
***((22792, 12), (9769, 12))***
Our actual dataset
训练分类模型
现在,我们将使用流行的 XGBoost 框架在我们的训练数据上训练和构建基本的 boosting 分类模型,这是一个优化的分布式梯度 boosting 库,旨在实现高效、灵活和可移植性。
***Wall time: 8.16 s***
根据测试数据进行预测
在这里,我们像往常一样,使用训练好的模型对测试数据集进行预测。
***array([0, 0, 1, 0, 0, 1, 1, 0, 0, 1])***
模型性能评估
是时候对模型进行测试了!让我们评估一下我们的模型在测试数据上的预测表现如何。为此,我们使用我的漂亮的**model_evaluation_utils**
模块,它在内部利用**scikit-learn**
为我们提供标准的分类模型评估指标。
默认模型解释方法
默认情况下,很难评估开箱即用的机器学习模型的特定模型解释方法。逻辑回归等参数模型更容易解释,因为模型的参数总数是固定的,与数据量无关,并且可以利用参数系数对模型的预测决策进行一些解释。
非参数模型更难解释,因为参数总数保持无界,并且随着数据量的增加而增加。一些非参数模型,如基于树的模型,确实有一些现成的模型解释方法,如特征重要性,这有助于我们了解哪些特征可能对模型做出预测决策有影响。
来自 XGBoost 的经典特性重要性
在这里,我们尝试 XGBoost 附带的全局特性重要性计算。该模型使我们能够根据以下内容来查看特性的重要性。
- ***特征权重:*这是基于一个特征在所有树中出现的次数
- ***增益:*这是基于使用该功能的拆分的平均增益
- ***覆盖率:*这是基于使用该特性的分割的平均覆盖率(受影响的样本数)
请注意,它们都是相互矛盾的,这激发了模型解释框架的使用,如 SHAP,它使用了被称为 SHAP 值的东西,声称具有一致性保证(意味着它们通常会正确地排列特性)。
Feature Importance Plots from XGBoost
使用 ELI5 进行模型解释
ELI5 是一个 Python 包,帮助调试机器学习分类器,并以一种易于理解的直观方式解释它们的预测。这可能是三个机器学习框架中最容易开始的,因为它只需要阅读最少的文档!然而,它不支持真正的模型不可知的解释,对模型的支持大多局限于基于树的和其他参数\线性模型。让我们看看在我们的分类模型上使用 ELI5 进行模型解释的一些直观方式。
安装说明
我们建议使用**pip install eli5**
安装这个框架,因为**conda**
版本似乎有点过时。也可以根据需要随意查看 文档 。
ELI5 的特性重要性
通常,对于基于树的模型,ELI5 不做任何特殊处理,而是使用我们在上一节中讨论的现成的特性重要性计算方法。默认情况下,使用*‘gain’**,这是该特性在树中使用时的平均增益。*
***eli5.show_weights(xgc.get_booster())***
用 ELI5 解释模型预测决策
向技术人员或更面向业务的人员解释模型预测决策的最佳方式之一是检查各个数据点的预测。通常,ELI5 通过显示每个特征的权重来实现这一点,这些权重描述了该特征对所有树的最终预测决策的影响程度。这里的 描述了 计算重量的思路;ELI5 为 XGBoost 和大多数 scikit-learn 树集成提供了该算法的独立实现,这无疑是朝着模型不可知解释的方向发展,但不像 LIME 那样纯粹是模型不可知的。
通常,预测可以被定义为特征贡献的总和+偏差(即,由覆盖整个训练集的最顶端区域给出的平均值)
预测一个人什么时候的收入<= $50K
Here we can see the most influential features being the 【 、、**Hours per week**
、、**Marital Status**
、、、**Occupation**
、、、**Relationship**
预测一个人的收入何时超过 5 万美元
这里我们可以看到最有影响力的特征是**Education**
、 **Relationship**
、 **Occupation**
、 **Hours per week**
& **Marital Status**
看到相似的特征如何在解释这两个类的模型预测决策中发挥有影响的作用,肯定是有趣的!
用溜冰者解释模型
Skater 是一个统一的框架,能够对所有形式的模型进行模型解释,以帮助人们使用模型不可知的方法构建现实世界用例经常需要的可解释的机器学习系统。它是一个开源的 python 库,旨在从全局(基于完整数据集的推理)和局部(关于单个预测的推理)两个方面揭开黑盒模型的已知结构。
Skater 最初以一个酸橙叉开始,但后来发展成为一个独立框架,具有各种各样的特性和能力,可以对任何黑盒模型进行模型不可知的解释。该项目最初是一个研究想法,旨在为研究人员和实践者找到更好的可解释性(最好是人类的可解释性)来预测【黑盒】。
安装滑冰者
你通常可以使用一个简单的**pip install skater**
来安装 Skater。有关依赖关系和安装说明的详细信息,请查看安装滑板。
📖证明文件
我们建议你去查阅溜冰者的详细资料。
算法
溜冰者有一套模型解释技术,其中一些在下面提到。
用法和示例
由于该项目正在积极开发中,了解用法的最佳方式是遵循交互式笔记本的图库中提到的示例。但是我们将使用在我们的人口普查数据集上训练的模型来展示它的主要能力。
溜冰者的全球诠释
预测模型是从输入空间到输出空间的映射。解释算法分为提供领域区域统计数据和度量标准的算法,如要素的边缘分布或整个训练集的联合分布。在一个理想的世界中,将存在一些允许人类在任意数量的维度中解释决策函数的表示。鉴于我们通常一次只能直观地看到几个维度的可视化,全局解释算法要么聚集特征空间,要么划分特征空间的子集。
目前,skater 支持的模型不可知的全局解释算法包括部分依赖和特征重要性,以及一个非常新的树代理版本。我们将在这里讨论特性重要性和部分依赖图。
创建解释对象
skater 包中的一般工作流是创建解释、创建模型和运行解释算法。通常情况下,**Interpretation**
会消耗一个数据集,以及可选的一些元数据,比如特性名称和行 id。在内部,**Interpretation**
将生成一个**DataManager**
来处理数据请求和采样。
- 局部模型(
**InMemoryModel**
): 要创建一个基于局部函数或方法的溜冰者模型,将预测函数传递给一个**InMemoryModel**
。用户可以选择将数据样本传递给 examples 关键字参数。这仅用于推断输出类型和格式。开箱即用,skater 允许模型返回**numpy**
数组和**pandas**
数据帧。 - 可操作模型(
**DeployedModel**
): 如果您的模型可以通过 API 访问,那么使用一个**DeployedModel**
,它包装了请求库。**DeployedModels**
需要两个函数,一个输入格式化程序和一个输出格式化程序,它们对请求库进行发布和解析。输入格式化程序接受一个**pandas**
DataFrame 或一个**numpy**
ndarray,并返回一个可以转换成 JSON 的对象(比如 dict)来发布。输出格式化程序将 requests.response 作为输入,并返回一个**numpy**
ndarray 或**pandas**
DataFrame。
我们将使用以下工作流程:
- 构建一个解释对象
- 构建内存模型
- 执行解释
对溜冰者的重要性
特征重要性是预测模型依赖特定特征的程度的通用术语。给定给定特征的扰动,溜冰者特征重要性实现基于信息理论标准,测量预测变化的熵。直觉告诉我们,一个模型的决策标准越依赖于一个特征,我们就越会看到预测随着对一个特征的扰动而变化。使用的默认方法是**prediction-variance**
,它是给定数据扰动时预测变化的平均绝对值。
Feature Importances from Skater
部分依赖
部分相关性描述了某个功能对模型预测的边际影响,使模型中的其他功能保持不变。部分相关的导数描述了特征的影响(类似于回归模型中的特征系数)。本文改编自 T. Hastie、R. Tibshirani 和 J. Friedman 的《统计学习要素》。2、斯普林格。2009.
部分相关性图(PDP 或 PD 图)显示了某个特性对先前拟合模型的预测结果的边际影响。PDP 可以显示目标和特征之间的关系是线性的、单调的还是更复杂的。滑冰者可以显示一维和二维等离子体显示器
影响模型预测的“年龄”的 PDP
让我们看看**Age**
特性是如何影响模型预测的。
PDP for the Age feature
看起来,与年轻人或老年人相比,中年人赚更多钱的机会稍高一些。
“教育程度”的 PDP 影响模型预测
让我们看看**Education-Num**
特性是如何影响模型预测的。
PDP for the Education-Num feature
看起来受教育程度越高,赚更多钱的机会就越大。不奇怪!
影响模型预测的“资本收益”的 PDP
让我们看看**Capital Gain**
特性是如何影响模型预测的。
PDP for the Capital Gain feature
不出所料,资本收益越高,赚钱的机会就越多,大约在 $5K 到$8K 之间急剧上升。
影响模型预测的“关系”的 PDP
记住,关系是用数字表示的分类变量编码的。我们先来看看它是如何表示的。
Label Encoding for Relationship
现在让我们看看**Relationship**
特性是如何影响模型预测的。
PDP for the Relationship feature
有趣的是,已婚人士(夫妻)比其他人更有可能赚更多的钱!
双向 PDP 显示特征“年龄”和“教育程度”之间的相互作用,以及它们对超过 50K 美元收入的影响
我们在这里对所有数据样本进行了更深入的模型解释,试图在双向部分依赖图的帮助下,看到**Age**
和**Education-Num**
之间的相互作用,以及它们对模型预测此人是否会赚更多钱的概率的影响。
Two-way PDP showing effects of the Age and Education-Num features
有趣的是,教育水平越高,中年人(30-50 岁)赚更多钱的机会越大!
双向 PDP 显示了“教育-数字”和“资本收益”功能之间的相互作用,以及它们对获得超过 50K 美元收入的影响
我们在这里对所有数据样本进行了更深入的模型解释,试图在双向部分依赖图的帮助下,看到**Education-Num**
和**Capital Gain**
之间的相互作用,以及它们对模型预测此人是否会赚更多钱的概率的影响。
Two-way PDP showing effects of the Education-Num and Capital Gain features
基本上,更好的教育和更多的资本收益会让你赚更多的钱!
滑冰者的地方诠释
有可能通过两种方式实现本地解释。首先,可以使用简单的可解释辅助或替代模型(如线性回归器)在单个输入附近近似复杂预测模型的行为。第二,可以使用基本估计量来理解单个预测的行为,使用基于输入和输出的直观近似函数。
局部可解释的模型不可知解释(LIME)
LIME 是由 Riberio Marco、Singh Sameer 和 Guestrin Carlos 设计的一种新算法,用于使用可解释的替代模型(如线性分类器/回归器)来评估任何基础估计量(模型)的行为。这种形式的综合评估有助于产生局部忠实的解释,但可能不符合全局行为。基本上,石灰解释是基于本地代理模型。这些替代模型是可解释的模型(如线性模型或决策树),是根据原始黑盒模型的预测学习的。但是,LIME 没有试图拟合一个全球代理模型,而是专注于拟合局部代理模型,以解释为什么会做出单一预测。
这个想法非常直观。首先,试着忘掉你已经做过的事情!忘记训练数据,忘记你的模型是如何工作的!认为你的模型是一个黑盒模型,里面有一些神奇的事情发生,你可以输入数据点,并得到模型预测的结果。你可以随时探测这个神奇的黑箱,得到输入和输出预测。
现在,你的主要目标是理解为什么你作为一个神奇的黑盒子对待的机器学习模型,给出了它产生的结果。LIME 试着为你做这件事!它测试当你把数据集的变化或扰动输入黑盒模型时,黑盒模型的预测会发生什么。通常,LIME 会生成一个由扰动样本和相关黑盒模型预测组成的新数据集。在这个数据集上,LIME 然后训练可解释的模型,该模型通过采样实例与感兴趣实例的接近度来加权。以下是标准的高级工作流程。
- 选择您感兴趣的实例,您希望对其黑盒模型的预测进行解释。
- 扰动数据集,获得这些新点的黑盒预测。
- 根据与感兴趣的实例的接近程度对新样本进行加权。
- 将加权的、可解释的(替代)模型拟合到有变化的数据集上。
- 通过解释本地模型来解释预测。
我们推荐你阅读 Christoph Molnar 关于模型解释的优秀著作中的第章,其中详细讨论了这一点。
用石灰解释溜冰者的模型预测
溜冰者可以利用石灰来解释模型预测。通常,它的**LimeTabularExplainer**
类有助于解释对表格(即矩阵)数据的预测。对于数值特征,它会根据训练数据中的平均值和标准差,通过从正态(0,1)采样并执行平均值居中和缩放的逆操作来扰动它们。对于分类特征,它通过根据训练分布进行采样来进行扰动,并在值与被解释的实例相同时生成为 1 的二元特征。**explain_instance()**
函数为预测生成解释。首先,我们通过随机扰动实例中的特征来生成邻域数据。然后,我们学习这个邻域数据上的局部加权线性(代理)模型,以可解释的方式解释每个类。
由于 XGBoost 在使用数据帧构建模型时在特性名称排序方面有一些问题,我们将使用**numpy**
数组构建相同的模型,以使 LIME 工作起来,而没有特性重新排序的额外麻烦。请记住,正在建立的模型与我们视为黑盒机器学习模型的集合模型是相同的。
***XGBClassifier(base_score=0.5, booster='gbtree', colsample_bylevel=1,
colsample_bytree=1, gamma=0, learning_rate=0.1,
max_delta_step=0, max_depth=5, min_child_weight=1,
missing=None, n_estimators=500, n_jobs=1,
nthread=None, objective='binary:logistic',
random_state=42, reg_alpha=0, reg_lambda=1,
scale_pos_weight=1, seed=None, silent=True,
subsample=1)***
预测一个人的收入<= $50K
Skater gives a nice reasoning below showing which features were the most influential in the model taking the correct decision of predicting the person’s income as 何时低于 5 万美元。
Local interpretations with LIME in Skater
预测一个人的收入何时超过 5 万美元
Skater 在下面给出了一个很好的推理,显示了在模型中哪些特征是最有影响力的,并做出了正确的决定,预测此人的收入为 超过 5 万美元。
Local interpretations with LIME in Skater
使用 Skater 通过树代理获得更多可解释模型的途径
我们已经看到了用特征、依赖图甚至时间来解释机器学习模型的各种方法。但是,我们能从一个真正复杂的黑盒模型中建立一个更容易解释的近似模型或代理模型吗?比如我们的 XGBoost 模型,它有数百个决策树。
在这里,我们介绍了使用**TreeSurrogates**
作为解释模型的学习决策策略(用于归纳学习任务)的手段的新想法,这是受 Mark W. Craven 的工作(称为特雷潘算法)的启发。
我们推荐查看以下关于 TREPAN 算法构建代理树的优秀论文。
简而言之,Trepan 以最佳优先的方式构建决策树。它维护一个树叶队列,当从队列中移除树叶时,树叶被扩展成子树。对于队列中的每个节点,Trepan 存储,
- 训练示例的子集,
- 另一组实例(查询实例),
- 一组约束。
存储的训练样本子集仅由到达该节点的那些样本组成。如果节点是内部节点,则使用查询实例和训练示例来选择分裂测试,如果节点是叶节点,则确定类标签。约束集描述了实例为了到达节点而必须满足的条件;在为新创建的节点绘制一组查询实例时,会用到这些信息。Trepan 中扩展节点的过程与传统的决策树算法非常相似:为节点选择一个分裂测试,并为测试的每个结果创建一个子节点。每个孩子要么成为树的一片叶子,要么被放入队列中等待将来的扩展。
对于 Skater 的实现,为了构建可解释的代理模型,基本估计器(Oracle)可以是任何形式的监督学习预测模型——我们的黑盒模型。通过学习类似于 Oracle 所学习的决策边界(来自基础模型的预测用于学习决策树表示),使用决策树(用于分类/回归)来近似解释。该实现还生成保真度分数,以量化基于树的代理模型对 Oracle 的近似。理想情况下,全球和局部的真实解释得分应为 0。让我们来看看实际情况吧!
***注:*该实现目前处于试验阶段,将来可能会有所改变。
使用解释器实例调用 TreeSurrogate
我们可以使用前面实例化的解释对象来调用 TreeSurrogate 功能。
使用代理模型来学习由基本估计器学习的决策边界
现在,我们可以在数据集上拟合这个代理模型,以了解我们的基本估计量的决策边界。
- 报告与基本估计值相比的保真度值(越接近 0 越好)
- 学员使用 F1 分数作为分类的默认选择指标。
***0.009***
查看每个特征的位置
我们这样做是因为代理树中的特征名称不显示(但存在于模型中)
可视化代理树
我们现在可以使用下面的代码来可视化我们的代理树模型。
Our surrogate tree model
来自代理树的有趣规则
从上面的树中你可以观察到一些有趣的规则。
- 如果
**Relationship**
< 0.5(表示 0)**Education-num**
<= 9.5 并且**Capital Gain**
<= 4225→***70%的机会使人< = $50K*** - 如果
**Relationship**
< 0.5(表示 0)**Education-num**
<= 9.5 并且**Capital Gain**
>= 4225→***94.5%的几率中人>【50K】*** - 如果
**Relationship**
< 0.5(表示 0)**Education-num**
>= 9.5 并且**Education-num**
也是>= 12.5→***94.7%的几率人做成> $50K***
请随意从中导出更多有趣的规则以及您自己的模型!现在让我们看看代理模型在测试数据集上的表现。
代理模型性能评估
现在让我们根据测试数据来检查代理模型的性能。
正如预期的那样,该模型的性能下降了不少,但我们仍然获得了总的 F1 分83%,相比之下,我们的提升模型的分数 87% 相当不错!
SHAP 的模型解释
***SHAP(SHapley Additive exPlanations)*是解释任何机器学习模型输出的统一方法。SHAP 将博弈论与局部解释相结合,结合了以前的几种方法,并基于他们所声称的,代表了唯一可能一致且局部精确的附加特征归因方法!(请务必检查 SHAP 夹纸了解详情)。我们在本系列的第二部分 中也详细介绍了这一点。
装置
SHAP 可以从 PyPI 安装
***pip install shap***
或者康达锻造
***conda install -c conda-forge shap***
这个框架真正令人敬畏的方面是,虽然 SHAP 值可以解释任何机器学习模型的输出,但对于真正复杂的集成模型来说,它可能会很慢。但是他们开发了一种用于树集成方法的高速精确算法(树 SHAP arXiv 论文)。快速 C++实现支持 XGBoost 、 LightGBM 、 CatBoost 和 scikit-learn 树模型!
SHAP (SHapley 附加解释)为每个特征分配一个特定预测的重要性值。其新颖的组成部分包括:识别一类新的加性特征重要性度量,理论结果表明在这一类中有一个唯一的解决方案,具有一组理想的性质。通常,SHAP 值试图将模型(函数)的输出解释为引入条件期望的每个特征的效果的总和。重要的是,对于非线性函数,引入特征的顺序很重要。SHAP 值由所有可能的排序的平均值产生。博弈论的证据表明这是唯一可能的一致方法。
理解 Shapley 值的直观方式如下:特征值以随机顺序进入一个房间。房间里的所有特征值都参与了游戏。沙普利值 ϕᵢⱼ 是特征值 xᵢⱼ 通过加入之前已经进入房间的任何特征的平均边际贡献,即
下面的图来自 KDD 18 号论文, 一致个性化特征归属为树系综 很好地概括了这一点!
现在让我们深入 SHAP,并利用它来解释我们的模型!
用 SHAP 解释预测
这里我们使用集成到 XGBoost 中的树 SHAP 实现来解释测试数据集!请记住,基于您正在构建的模型类型,有多种解释器方法。我们估计一组样本(测试数据)的 SHAP 值
***Expected Value: -1.3625857***
这将返回 SHAP 值的矩阵(**# samples**
,**# features**
)。每一行加起来就是该样本的模型输出和模型输出的期望值之间的差值(该值存储为解释器的**expected_value**
属性)。通常,这种差异有助于我们解释为什么模型倾向于预测特定的班级结果。
预测一个人的收入何时< = 5 万美元
SHAP 在下面给出了一个很好的推理,显示了哪些特征在模型中最有影响力,正确的决定是预测个人的收入为 低于 5 万美元 。以下说明显示了将模型输出从基础值(我们传递的训练数据集的平均模型输出)推至实际模型输出的各种功能。将预测值推高的要素显示为红色,将预测值推低的要素显示为蓝色。
预测一个人的收入何时超过 5 万美元
同样,SHAP 在下面给出了一个很好的推理,显示了在模型中哪些特征是最有影响力的,正确的决定是预测这个人的收入 大于 50K 。
可视化和解释多重预测
SHAP 的一个关键优势是它可以构建美丽的互动情节,可以同时可视化和解释多种预测。在这里,我们将前 1000 个测试数据样本的模型预测决策可视化。
上述可视化可以以多种方式进行交互。默认的可视化显示了一些有趣的模型预测模式决策。
- 前 100 个测试样本都可能收入超过 5 万美元并且他们已婚或\有良好的资本收益或\并且有更高的教育水平!
- 接下来的 170 多个测试样本可能都收入少于或等于 5 万美元而且他们大多未婚和\或年龄很小或离婚!
- 接下来的 310 多个测试样本大多倾向于收入超过 5 万美元的人,他们有不同的背景,包括已婚人士、不同年龄、教育水平和职业的人。推动模型预测更高收入的最主要特征是结婚的人,即关系:丈夫还是妻子!
- 剩余的 400 多个测试样本大多倾向于收入少于 5 万美元,他们的情况各不相同,但主要模式包括关系:未婚或离婚和年龄非常小!
非常有趣的是,我们如何找出导致模型做出特定决策的模式,并能够为这些决策提供解释。
SHAP 的重要特征
这基本上是取整个数据集的 SHAP 值的平均值,并将其绘制成一个简单的条形图。
SHAP feature importance plot
SHAP 汇总图
除了典型的要素重要性条形图,SHAP 还使我们能够使用每个要素的 SHAP 值的密度散点图来确定每个要素对验证数据集中个体的模型输出的影响程度。要素按所有样本的 SHAP 量值总和排序。请注意,当散点不在一条线上时,它们会堆积起来以显示密度,每个点的颜色代表该个体的特征值。
SHAP summary plot
有趣的是, 年龄 和 婚姻状况 特征比 资本收益 特征具有更大的总模型影响,但是对于那些 资本收益 重要的样本,它具有比 年龄 或 婚姻状况 更大的影响。换句话说, 资本收益 对少数预测影响较大,而 年龄 或 婚姻状况 对所有预测影响较小。
SHAP 依赖图
SHAP 相关图显示了单个(或两个)要素对整个数据集的影响。他们绘制了许多样本中某个特性的值与该特性的 SHAP 值。SHAP 相关图类似于部分相关图,但是考虑了特征中存在的交互作用,并且仅在由数据支持的输入空间的区域中定义。单个特征值处 SHAP 值的垂直离差由交互作用影响决定,可以选择另一个要素进行着色,以突出显示可能的交互作用。
你也会注意到它和溜冰者的部分依赖情节的相似性!
影响模型预测的“年龄”的 PDP
让我们看看**Age**
特性是如何影响模型预测的。
PDP for the Age feature
就像我们之前观察到的一样。中年人的 shap 值略高,这推动了模型的预测决策,即与年轻人或老年人相比,这些人赚的钱更多
“教育人数”影响模型预测的 PDP
让我们看看**Education-Num**
特性是如何影响模型预测的。
PDP for the Education-Num feature
教育程度越高,shap 值越高,推动模型的预测决策说,与教育程度较低的人相比,这些人赚的钱更多。
影响模型预测的“关系”的 PDP
让我们看看**Relationship**
特性是如何影响模型预测的。
PDP for the Relationship feature
正如我们在模型预测解释中观察到的,已婚人士(丈夫或妻子)的 shap 值略高,推动模型的预测决策,认为这些人比其他人赚得更多!
影响模型预测的“资本收益”的 PDP
让我们看看**Capital Gain**
特性是如何影响模型预测的。
PDP for the Capital Gain feature
双向 PDP 显示了特征“年龄”和“资本收益”之间的相互作用,以及它们对获得超过 50K 美元收入的影响
单个特征值处 SHAP 值的垂直离差由交互作用影响决定,选择另一个特征进行着色以突出可能的交互作用。在这里,我们试图看到Age
和Capital Gain
之间的相互作用,以及它们对 SHAP 值的影响,这导致模型在双向部分依赖图的帮助下预测这个人是否会赚更多的钱。
Two-way PDP showing effects of the Age and Capital Gain features
有趣的是,资本收益越高,中年人(30-50 岁)赚更多钱的机会越大!
双向 PDP 显示了“教育-数量”和“关系”特征之间的相互作用,以及它们对创造超过 50K 美元收入的影响
在这里,我们试图看到**Education-Num**
和**Relationship**
之间的相互作用,以及它们对 SHAP 值的影响,这导致模型在双向部分依赖图的帮助下预测这个人是否会赚更多的钱。
Two-way PDP showing effects of the Education-Num and Relationship features
这很有趣,因为在某些情况下两者的特征是相似的,我们可以看到典型的已婚人士,无论是丈夫还是妻子,都有最高的机会赚更多的钱!
双向 PDP 显示了特征“婚姻状况”和“关系”之间的相互作用,以及它们对获得超过 5 万美元收入的影响
在这里,我们试图看到**Marital Status**
和**Relationship**
之间的相互作用,以及它们对 SHAP 值的影响,这导致模型在双向部分依赖图的帮助下预测这个人是否会赚更多的钱。
Two-way PDP showing effects of the Marital Status and Relationship features
有趣的是,受教育程度越高,丈夫或妻子(已婚)挣更多钱的机会越大!
双向 PDP 显示特征“年龄”和“每周小时数”之间的相互作用,以及它们对创造超过 50K 美元收入的影响
在这里,我们试图看到**Age**
和**Hours per week**
之间的相互作用,以及它们对 SHAP 值的影响,这导致模型在双向部分依赖图的帮助下预测这个人是否会赚更多的钱。
Two-way PDP showing effects of the Age and Hours per week features
这里没什么特别的,工作最多的中年人赚的钱最多!
结论
如果你正在阅读这篇文章,我真的想称赞你在阅读这本关于机器学习模型解释的庞大而全面的教程上所做的努力。这篇文章应该帮助你利用最先进的工具和技术,这将有助于你在通往可解释的人工智能(XAI)的道路上。基于我们在 第二部分 中学到的概念和技术,在本文中,我们实际上在一个在真实世界数据集上训练的复杂机器学习集成模型上实现了它们。我鼓励您用自己的模型和数据集来尝试这些框架,探索模型解释的世界!
下一步是什么?
在本系列的第 4 部分中,我们将会看到一个在非结构化数据(如文本,甚至深度学习模型)上构建解释模型的综合指南!
- 非结构化数据集上的动手模型解释
- 深度学习模型的高级模型解释
敬请关注一些有趣的内容!
***注意:*随着时间的推移,这一领域出现了许多快速发展,包括许多新工具和框架的发布。如果您希望我介绍任何其他流行的框架,请随时联系我。我对此非常感兴趣,并将在未来的某个时候开始研究 H2O 的模型解释能力。
本文使用的代码可以在 my GitHub 上获得,也可以作为交互式 Jupyter 笔记本 。
请查看 “第一部分——人类可解释机器学习的重要性” ,其中涵盖了人类可解释机器学习的内容和原因,以及模型解释的必要性和重要性及其范围和标准(如果您还没有了解的话)!
还有 第 2 部分——模型解释策略’,它涵盖了人类可解释的机器学习的方式,我们在其中看到了与模型解释的主要策略相关的基本概念。**
有反馈给我吗?或者有兴趣与我一起从事研究、数据科学、人工智能甚至发表一篇关于TDS的文章?可以在LinkedIn上联系我。
** [## 人工智能顾问&数据科学导师-跳板| LinkedIn
查看 Dipanjan Sarkar 在世界最大的职业社区 LinkedIn 上的个人资料。Dipanjan 有 2 份工作列在…
www.linkedin.com](https://www.linkedin.com/in/dipanzan)**