按比例评估图像美学质量
或者,如何一次使用一个深度学习模型来改进搜索算法
迈尔斯·范德鲁文在 Unsplash 上的照片
问自己这样一个问题:“*你多久检查一次谷歌搜索的第二页?”。*我猜答案在 20%左右。在 HousingAnywhere ,我们也注意到同样的模式,84% 的搜索在第一页停止。这意味着成千上万的公寓和房间不会被用户看到。这就是为什么,作为一个中期住宿市场的核心,改进搜索算法是改善任何地方住房用户体验的关键。
问题是
在 HousingAnywhere 上,我们的用户首先从登录页面开始,在那里他们会看到一个搜索框,输入他们正在寻找的住宿地点和住宿日期。从那里,他们被定向到搜索页面,在那里他们可以根据更多要求进一步细化他们的搜索。点击任何搜索结果都会将用户引导至该住宿的列表页面。
搜索页面(图片作者提供)
列表页面(图片由作者提供)
我们在搜索页面上注意到的一个主要问题是,由于搜索算法没有考虑这一因素,图像质量差的列表经常出现在结果的顶部。这是不可取的,因为 HousingAnywhere 的主要使命之一是奖励“好”广告商,即那些提供详细信息、具有吸引力的广告客户。在我们的平台上,房客不需要进行现场查看就可以预订,这使得住宿照片成为决定房间是否被预订的主要因素之一。因此,需要一种模型来评估图像的质量,以便具有高质量图像的列表可以在搜索页面上获得提升。因此,为了获得更多的用户曝光率,图片质量差的列表需要增强它们的图片。
在处理画质的时候,我们衡量画质的方式主要有两个方面:技术和美学。前者处理像噪声、模糊、压缩这样的退化,而后者处理图片的吸引力即图像是否看起来令人愉快并显示房间的清晰概观。
但是你如何创建一个模型来决定一个图像在美学上是有吸引力的呢?幸运的是,有相当多的研究做了这个主题。最值得注意的是,这项由谷歌完成的研究。在研究中,引入了实现深度学习的解决方案来解决该问题。
https://ai.googleblog.com/2017/12/introducing-nima-neural-image-assessment.html
解决方案
总之,所提出的架构本身非常简单,我们有一个基线 CNN (MobileNet、Inception 等),其最后一层被大小为 10 的密集层所取代,之后是 Softmax 激活函数。主要成分是建议的损失函数,地球移动距离:
在统计学中,运土机的距离(EMD)是区域 D 上两个概率分布之间的距离的度量。非正式地,如果分布被解释为在区域 D 上堆积一定量的泥土的两种不同方式,EMD 是将一堆变成另一堆的最小成本;其中成本假定为移动的灰尘量乘以移动的距离。
该论文在美学视觉分析(AVA)数据集上展示了有希望的结果,但由于该数据集包含非常普通的图片(从风景到动物图片到不同物体的图片),它在只有房间图像的数据集上表现不佳。然后我们决定收集我们自己的数据集来执行迁移学习。
我们创建了一个由 5 名注释者组成的团队,每个人负责注释一个包含 1500 张图片的数据集。为了简单起见,我们决定将分数范围从 1-10 降低到 1-5。通过让多个注释者处理同一个数据集,我们试图减少在这个过程中产生的错误数量。例如,对于一个 5 分的图像,如果 4 个人记下了 5,但 1 个人错误地填了 1,则平均分数仍然很高(4.2),而不是 1。
我们提出了这些评定图像的标准,作为所有注释者遵循的通用指南:
The photo quality of the image (i.e. clear and not blurry)
The attractiveness of the room (aesthetic wise)
The relevance of the image (i.e. does it show a good overview of the room)
Try to relate yourself to the tenants, how likely would you book this room if the listing has that image
由于 MobileNet 的轻量级架构,我们决定将其作为基线 CNN,并以 90:10 的比例分割训练/测试集。该模型输出一个概率分布,从中计算平均分数。为了评估模型的质量,我们选择使用一个对利益相关者更直观的简单指标(平均绝对误差)。结果是非常有希望的,最好的 epoch 获得了 0.519 的 MAE。所以平均来说,这个模型与真实标签相差大约 0.5 分。
模型架构(图片由作者提供)
以下是模型输出的一些示例:
比分: 4.97 / 5 (来源:HousingAnywhere.com)
比分:【HousingAnywhere.com】4.71/5(来源:中国)
得分: 2.02 / 5 (来源:HousingAnywhere.com)
比分: 1.94 / 5 (来源:HousingAnywhere.com)
结果呢
在我们最初的 A/B 测试后,我们发现使用考虑了质量分数的搜索算法,治疗组从搜索页面到列表页面的转化率有了 5% 的提高。我们对结果非常满意,因为这是我们对搜索算法进行的为数不多的实验之一,达到了统计学意义。
建筑
为了生产模型,我们使用 Flask 和 Gunicorn 构建了一个 RESTful API。这种架构设置简单,性能相当好。发送给我们的服务的请求将包含图像 URL,然后服务将提取并发送给这些模型。该服务作为一个容器部署在谷歌云平台 Kubernetes Engine 上。这种架构虽然非常简单,但仍然允许我们根据需要进行扩展,以处理来自平台的流量。
应用架构(图片由作者提供)
为了让我们晚上睡得安稳,我们使用 Bugsnag 进行错误监控,使用 Prometheus 跟踪指标。当服务失败太多请求或请求处理时间超过阈值时,我们会设置警报。
Bugsnag 为 Flask 提供了本地支持,这使得调试错误变得非常简单。跟踪有关错误的详细信息,包括代码失败的位置和请求包含的内容。
从普罗米修斯收集到的数据会显示在 Grafana 上(图片由作者提供)
结论
就这样,我希望我已经成功地展示了如何在 HousingAnywhere 使用数据科学智能地解决一个复杂的业务用例。该模型的性能非常有前途,它有助于我们完成我们的使命,帮助租户找到最适合他们的住所。
最后,我要特别感谢 BI 团队和 Simone Pouw 校对了这篇文章,感谢 Idealo 团队展示了迁移学习是解决这个问题的关键。
使用 Inception V3 和 FID 评分评估图像相似性
衡量人工智能生成的图像与训练图像相似性的最佳方法是什么?
在过去的几年中,生成敌对网络或 gan 被广泛用于生成类似于训练集中给出的新图像(你可以使用动漫或自行车和许多 其他来查看一些很酷的例子)。根据生成图像的数量及其用途,对生成图像的质量进行视觉评估可能并不充分,并且单独的 FID 分数可能并不充分。在这里,我将尝试说明一种方法,以便更深入地分析生成的结果。
例如,考虑一个应用程序,其中为过采样生成新图像,以帮助从不平衡数据开始训练分类模型。在这种情况下,我们希望能够评估过采样图像和原始训练数据之间的相似性。理想情况下,它们应该与训练集足够相似,但也足够多样,覆盖原始数据集的整个领域,以便真正有助于模型训练。
在这个例子中,我不会训练任何模型,我将使用现有的图像集来说明该方法。为了简单起见,我将评估从 Kaggle fruits 数据集中提取的几种苹果之间的相似性。数据集包含在白色背景下的 100×100 像素的水果图像
我考虑了 7 类苹果,总共 1173 张图片:
数据集中每个苹果类别的图片数量(图片由作者提供)
数据集中的样本图像:
作者图片
为了评估图像之间的相似性,我将从计算苹果参考类别(例如红苹果 1 号)和所有其他类别之间的 FID 分数开始。FID 或弗雷歇初始距离是在训练生成模型(如 StyleGAN)时可以使用的度量之一。它是基于使用在 ImageNet 数据集上训练的 Inception V3 模型从每个图像提取的特征来计算的。
1.图像准备
在计算 FID 分数之前,输入图像需要经历一些转换,以使它们达到预训练的 Inception V3 模型所期望的良好格式:
- 大小为 299x299px 像素的 RGB 图像。简单地调整原始图像的大小会使它们变得太模糊,所以我选择用白色填充每个图像,直到达到预期的大小
- 将图像转换为张量(将像素值从 0–255 缩放到 0–1)
- 使用 ImageNet 训练集的平均值和标准偏差标准化图像
2.预训练的 Inception V3 模型和特征提取
首先实例化一个 inception v3 模型,并加载在 ImageNet 数据集上训练的现有模型的权重(它可以作为 pth 文件直接从 p ytorch 下载) :
Inception V3 模型已经被训练来执行分类,但是因为我们只对使用它来从我们的图像中提取特征感兴趣,所以我们需要移除计算分类概率的最后一层:
Inception V3 网络中的层(图片由作者提供)
为了访问中间层的输出,我们可以使用 torch vision 的特征提取模块:
现在,我们可以简单地使用特征提取器从任何批量图像中获取特征。结果应该是一个大小为 2048 的向量。
3.FID 计算
在这篇文章中已经介绍了计算弗雷谢特初始距离的公式。对于我的 Python 实现,我使用了这个教程作为灵感
我评估了 7 组水果和我的参考类别苹果红 1 之间的 FID 距离。红苹果 1 及其本身的 FID 为零,我们可以看到,除了蛇果看起来更不一样之外,其他类型苹果的得分非常相似:
苹果红 1 和其他类型苹果之间的 FID(图片由作者提供)
对于未受过训练的眼睛来说,所获得的结果不容易解释,因为在视觉上,蛇果和红色 1 之间的差异对我来说似乎不如红色、黄色 2 和红色 1 之间的差异重要。
作者图片
4.主成分分析和 TSNE 投影
为了进一步深入分析提取的特征,我们可以执行主成分分析或 PCA 来获得降维数据集。主成分分析表明,我们可以从 2048 个特征传递到 60 个特征,同时仍然保持数据集中 95%以上的方差。
累积解释差异(作者图片)
通过在 PCA 降维数据集上使用 TSNE,可以获得数据的 2D 可视化。
作者图片
我们可以看到,在每个类别中没有太多的可变性,但每个类别似乎都由 3-4 个子组组成。这并不奇怪,因为考虑的数据集包含从不同角度拍摄的苹果图像,可以解释观察到的行为。
作者图片
基于使用 Inception V3 模型提取的特征,苹果的每个类别似乎也可以与其他类型区分开来。
理想情况下,在我们分析由训练模型生成的合成图像的情况下,我们应该以生成的图像为目标,这些图像的特征实际上与训练集中的图像的特征没有区别:
作者图片
我希望这篇文章给你一些关于如何分析图像组之间的相似性和使用生成模型评估图像质量的想法。
评估森林火灾严重程度和范围绘图的准确性
使用 Python 3、GeoPandas 和“正常”Pandas 评估火灾严重程度和范围分类的准确性,数据来自 Planet,分析就绪数据来自 Sentinel-2,通过开放数据立方体。
使用 matplotlib 生成的火灾严重程度和范围直方图显示了类别可分性。图片作者。
在我的上一篇文章“用开放数据立方体绘制 2019-2020 年澳大利亚森林火灾”中,我介绍了使用 Sentinel-2 分析就绪数据生成差分标准化燃烧比(dNBR)的过程。dNBR 是一种非常有用且简单的算法,仅需要两个波段(红色和近红外),因此降低了计算资源方面的处理成本,进而降低了时间成本。有关 dNBR 算法的更多信息,请参见我以前的文章。
然而,如果没有某种形式的准确性评估来提供所生成结果的置信度,则任何结果都是无用的。下面是一个高层次的工作流程图,显示了我的结果的整个过程。在左侧,您可以看到创建 dNBR 栅格图层的 Sentinel-2 影像的处理过程。右侧是使用 Planet Dove 影像生成精确数据的过程(根据 Planet Education and Research 许可证)。
整个流程的高级工作流程。图片作者。
Gibson 等人在 2020 年对 dNBR 结果的准确性评估方法进行了描述[1]。该方法在图像上随机采样 n 个点,并基于错误彩色图像的特定视觉问题将它们视觉地解释为火灾严重程度等级:
图片作者。
设置准确度数据时要记住的是,要确保所有图像都可以进行分析,包括但不限于:
- 在相同的坐标系和数据中进行空间校正和投影,最好 RSME 小于 0.5 像素
- 随机样本的最小间隔或间距至少为 15 米(Sentinel-2 图像的空间分辨率为 15 米)
- 每节课至少 50 分,以尽可能减少统计偏差(或在合理范围内尽可能多)
- 随机采样您的坐标-选择“易于分类”的区域可能会导致错误的评估
- 我将结果 dNBR 值附加到实际分类观察的形状文件中。你可以选择把它们分开,但是我个人觉得这样更容易。
Python、GeoPandas 和普通熊猫的美妙之处在于,一旦汇编了准确的数据,我们就可以重复且超快速地运行这一过程。但是你为什么会问?我们不是只生成一个准确度值(例如,所有类别的准确度为 60%),而是可以通过随机抽取 n 个准确度点并将它们与实际结果交叉列表,基于多次运行该过程来提供一个范围。让我们看一下代码:
步骤 1 —加载必要的模块并读入数据
步骤 2-分离并绘制实际的课堂观察
步骤 3-将 dNBR 值映射到分类值
步骤 4 —随机抽取每个班级的 n=40 名学生
步骤 5-生成实际火灾严重程度与测量的分类火灾严重程度结果的交叉表格
步骤 6-计算火灾范围精确度
同样,这种方法的优点是可重复的随机抽样,以产生一个精度范围。该过程的准确性被评估为火灾严重性结果的 60-64%(分为未燃烧、低、中、高和极端的严重性类别)和火灾范围的 88-92%(分为未燃烧和燃烧的类别)。如果你想找到完整的笔记本,请访问位于https://github.com/yobimania/dea-notebooks的仓库。有关我如何生成原始结果的更多信息,请访问我的文章‘用开放数据立方体绘制 2019-2020 澳大利亚森林火灾’。
参考资料:
[1]:吉布森,R 等。艾尔(2020)。*使用 sentinel 2 和 random forest 绘制澳大利亚东南部火灾严重程度的遥感方法。*环境遥感 240,111702。
评估机器学习模型的可行性
在编写任何代码之前需要回答的问题
在开始新的建模任务之前,考虑进行可行性研究。预测模型的可行性研究将回答一些关键问题,这些问题可以帮助您和企业决定建模任务是否可能成功。
由 Unsplash 上的 krakenimages 拍摄的照片
机器学习的可行性研究
一个可行性研究是对一个提议的项目或系统的实用性的评估。
——维基百科
可行性研究在各个行业和学科中都很常见。它们是一种重要的项目规划工具,可以帮助您在投入资金或时间之前识别项目中的失败点。
我认为可行性研究对机器学习项目特别有用,因为 ML 项目通常是实验性的。它们失败的原因有很多,其中一些可以通过可行性研究提前确定。
可行性研究期间要问的问题
在对预测模型进行可行性研究时,我喜欢使用以下模板。
- 培训数据 —是否需要收集培训数据?如果是,需要花费多少时间和金钱?
- 预测特征— 根据领域专家的说法,哪些因素有可能预测目标变量?您可以访问这些数据吗?
- 数据源— 您需要访问哪些数据源?如果是内部的,你有数据工程师的支持吗?如果是外部的,供应商数据的成本是多少?
- 生产— 在生产中开发、部署和维护您的模型的努力程度如何?
培训用数据
乔纳森·博尔巴在 Unsplash 上拍摄的照片
让我们假设你的建模任务受到监督(因为如果没有,你的可行性研究的结论几乎总是“不可能成功”😅).
如果你没有训练数据,你应该尽早制定一个计划,知道如何获取数据,以及获取数据的成本。
你将需要在某个时候提出预算请求,并且你会很高兴手头有你的可行性研究。这是建立商业案例和证明预算要求的完美文件。
预测功能
用厨房水槽砸你的模特可不是个好主意。但是,你如何在可行性研究中提前缩小可能的预测特征呢?
理想情况下,你将有机会接触到主题专家,他们可以建议通常会导致你试图预测的结果的场景或风险因素。
您还可以研究一小部分数据样本,以加深对驱动目标结果的因素的理解。你可能需要在网上做一些研究,或者与客户交谈,以便了解你的数据点的背景。我发现这样做的收获总是值得投入时间的。
一旦您对驱动目标结果的因素有了定性的了解,您就可以更清楚地阐明您需要什么数据以及为什么需要。这有助于在提出数据请求时构建业务案例。
数据源
克里斯托弗·伯恩斯在 Unsplash 上拍摄的照片
完成上一步后,您应该很好地掌握了构建成功模型所需的数据。
在这一步中,您需要确定每个预测特征的数据将来自哪里。我认为数据访问的层次结构是这样的。
- 你已经可以访问的内部数据是最好的。
- 需要开发运营部门或数据工程部门的工作才能提供给您的内部数据是次佳选择。
- 内部无法获得的数据可以从客户、合作伙伴或政府那里免费获得。
- 供应商或数据集成商可能有你需要的数据。这种数据从来都不便宜,需要长时间的合同谈判和内部集成/消化时间,并且经常遭受销售过程中隐藏的数据质量问题。
- 网络抓取可能值得考虑,但有许多挑战。请记住,抓取是违反大多数大型网站的使用条款的。因此,即使你建造了一座精致的攻城塔来穿过他们的防御墙,法律上也不允许你使用你掠夺的数据。
- 如果你已经做到这一步,假设数据是不可用的。评估缺乏数据对项目整体的影响。没有这些数据,项目有可能成功吗?
生产
努力程度
对于数据科学项目来说,评估工作水平 (LOE)可能很难,因为它们通常包含实验或迭代阶段。根据实验和探索的结果,整个项目的时间表可以缩短或延长。
所以我更喜欢将 ML 项目分解成相当精细的步骤,每个步骤都有自己的爱好。这样,不确定性小的步骤(比如工程化一个特定的特性)可以得到一个可靠的 LOE,而不确定性大的步骤(比如在业务用户反馈后迭代一个模型原型)可以得到一个 LOE 范围。
我发现这种方法有助于产品经理对将您的模型集成到产品路线图中更有信心。
速赢
当把项目分解成步骤时,我也喜欢在早期加入一些快速见效的东西。对于企业来说,交付增量价值的项目计划比最终只交付价值的项目计划更容易接受。
车型生命周期
请务必考虑整个型号生命周期。即使您的团队不直接负责部署和维护的所有方面,您也需要确信项目不会遇到任何障碍。记住,可行性研究的目的是评估成功的可能性;如果没有生产的途径(即使你能开发出一个模型),你可能应该终止这个项目,继续前进。
人数和时间表
您详细的 LOE 评估是提出员工请求的重要工具。比如说,你可以展示一个有 3 个头的时间线和一个有 4 个头的时间线。如果你是一个需要从零开始建立数据科学团队的团队,你也可以展示一个时间表。
https://skillenai.com/2020/12/09/build-a-data-science-team-from-scratch/
结论
对您的数据科学项目进行可行性研究是实现以下目标的好方法:
- 在编写任何代码之前,尽早捕捉故障点。
- 构建业务案例,并为数据和人员编制提出资源请求。
- 增加您的项目进入产品路线图的机会。
评估研究和数据科学项目的可行性
客观项目评估—得出 ORA 分数
阿迪·戈尔茨坦的照片
第 1 部分—技术成功的概率
你正在提议一个项目,该项目具有有希望的投资回报、对业务的积极影响以及可以使公司在竞争中脱颖而出的营销潜力。目前为止还不错。你继续澄清,在项目完成之前,不知道哪些技术障碍可能会破坏项目。而且即使完成了,你也明白你的公司可能不会选择采用。但是不管后一种可能性,你能在预算中增加几十万美元来完成这个项目吗?嗯?一个和善的老板可能会让你回到办公桌前做些功课。典型的老板可能只是困惑地盯着你。但是他们会吗?事实证明,许多数据科学、人工智能、物联网和其他“性感”的技术项目都是在这些情况下获得批准的。
有序科学已经走进了一些这样的项目。他们的领导者从健康的乐观和被过度的“内部观点”驱动的高期望值开始(参见丹尼尔·卡内曼,思考,快与慢)。但他们的愿景最终无法在糟糕的数据、不成熟的先驱技术、专业知识不足以及抵制创新的公司文化的严酷现实中存活下来。
最初为什么要启动这些项目?答案并不简单。我们遇到的大多数公司都进行了评估,试图量化和衡量风险。但这种评估无法评估最近才出现的人工智能和数据科学技术。这些公司缺乏客观的措施和机制来阻止低成功概率的项目。最终,他们被竞争对手被夸大的成功所诱惑,尽管有时是可疑的。由于害怕被落在后面,这些公司不顾谨慎,蹒跚着走向发展。
在这篇文章的剩余部分,我将讨论序数科学用来评估技术和商业成功概率的客观标准。我将介绍由此产生的 ORA 分数,该分数旨在为启动或放弃一个项目的决策插入一个客观性的度量。这涉及到一些数学问题,但这没有发挥作用的思想和原则重要。数据科学、人工智能和应用数学带来了丰厚的回报,但你选择做什么项目,在什么章程下决定了它们为你的公司做了多少。
可行性研究。
可行性研究决定了项目成功的可能性。它提供了这种概率的单一测量,但包括两个独立的评估。第一个是技术成功的概率——P(T)。它侧重于项目原型或概念证明。第二个因素决定了商业成功的可能性——P©。它评估的可能性,原型可以扩大到生产和采用的公司或其客户。这两个度量的乘积就是成功的概率:P(S) = P(T)P©。我们将每个测量值视为一个独立变量。当评估商业成功的可能性时,我们假设原型已经被成功开发。
在解开每个分数的推导之前,我应该澄清我们的方法很少是静态的。大多数数据科学和研究项目都有共同的特征,并受益于一致的风险评估方法。然而,通常有必要使评估的细节适应项目的组织特性,并考虑行业垂直市场的细微差别。请考虑,就像我们必须考虑每个项目一样,什么适合您的需求。这样做的目的是保持客观,并避免调整评估参数的诱惑,以便您最喜欢的项目返回一个更好的,但膨胀的分数。
技术成功评估。
估计技术成功的概率(从现在开始指定为 P(T ))是一种识别突出风险因素的练习,然后在将值代入数学函数之前,以一致的尺度对每个因素进行单独评分。简单。但究竟什么是“技术成功”?
P(T)的定义如下:在给定现有数据、可用技术、所需研究和开发的情况下,原型将完成并在精心设计的实验室或受限生产环境中执行规定功能的可能性。P(T)以百分数给出。
定义很重要,因为它设定了对可交付成果的期望。我们将 P(T)的范围限制在为测试技术而设计的原型上,并让一个温和的怀疑者相信这种方法是可行的。测试应该在有限但有代表性的情况下运行,并使用经过审查的数据集。为什么会有限制?它们减少了开发原型所需的时间,而不影响评估。它们通过促进微小的、持续的调整来减少与最终目标不一致的机会。它们降低了投资风险。同时,该过程仍然验证生产解决方案所需的困难组件和算法。
我们在前期的项目阶段定义了原型的细节:概念开发。这是另一篇文章的主题,我们将假设我们的原型有明确的目的、相关的用户角色、功能定义和不可接受的故障模式。
现在,我们评估构建原型需要什么。我将把这个过程压缩成一系列的问题,这些问题引出调查,并给出一个从 1 到 10 的分数,其中 1 是绝对否定,10 是绝对肯定。我们将评估分为四个同等权重的类别:数据、技术、业务和专业知识。
数据:
1.我们拥有所有必需的数据特征
2.每个特征的数据都是完整的
3.每个特征的数据都清晰而准确
4.我们有能力综合模拟样本数据
5.我们可以在没有官僚障碍的情况下访问数据
技术:
6.大多数所需技术的技术准备水平(TRL)。(见 NASAhttps://www . NASA . gov/directorates/heo/scan/engineering/technology/technology _ readiness _ level)
7.单个必需组件的最低 TRL
8.我们可以访问相关解决方案的源代码或库
9.我们可以获得低 TRL 成分的综合文件。
10.我们有计算能力来获得足够的结果
11.我们有一个清晰的路径来验证结果的正确性
业务:
12.这个项目有一个强大的内部拥护者
13.这个项目有很高的内部投资回报率
14.项目团队有明确的章程
15.该项目有充足的预算
专长:
16.客户有一名内部主题专家
17.该团队(序数科学)的专业知识与低 TRL 成分完全一致
18.该团队已经成功地完成了在概念上相似的空间中的研究和原型开发
19.该团队可以利用外部资源,就低 TRL 组件进行咨询
20.在最初的研究阶段,该团队被授予一定程度的独立性
我们给 20 个参数中的每一个赋值,然后把数字代入我们开发的公式。我们将得出的数字称为“ORA 得分”——有序风险评估得分。
ORA 评分
S 是单个参数分数的数组,其中 s 是 1 到 10 之间的整数
N 是一组参数,在我们的例子中 N = 20
C 是压缩系数, C = aN ,其中 a = 3(凭经验选择)
W 是确定每个参数关键程度的参数权重数组,其中 s 是 1 到 6 之间的整数。 w = 6 对于单个参数当 s = 1 时会有将 P(T) 压制在 0.5 以下的效果。
w 对于所有的 W 是最安全的,除非特别权重的原因很好理解。
如果你说“啊?”对于以上所述,不要担心——给我们打电话,我们会为您做可行性评估。这是我们的职责。如果你跟着走,那么在重量上要小心。它们非常重要,必须在您的业务环境中有意义。对于所有特征,它们始终不等于 1。我们如何得到我们的权重向量是一个商业秘密,但是通过大量的实验,你可以得到一个适合你的环境的合理的集合。
定义 P(T)的主要目的是决定是否继续下一阶段。前进的正确门槛是什么?我不知道。我们通常以 70%的技术成功可能性来启动我们的项目,但是环境和客户的风险承受能力同样重要。应该通过与利益相关者的业务讨论来确定适当的阈值。
我将在这里结束可行性文章的第一部分,在下一篇文章中继续“第二部分——商业成功的可能性”。
最初发表在我们的序数科学博客上:https://www . Ordinal Science . com/post/assessing-the-probability-of-research-and-data-Science-projects
例如,评估数据流的质量对于数字化至关重要
意见
为了方便企业客户,我们必须不断将客户旅程数字化。因此,从客户渠道和服务接触点产生了大量数据。这些数据要么是客户自愿提供的信息,要么是从系统及其处理过程中作为日志生成的大量数据。
逐渐地,在物联网世界中,我们看到机器做出决策。这些决策要么让客户对什么更好产生深刻的认识,要么减少他们对服务关系的焦虑。为了使机器模型产生可操作的见解,需要实时获得各种高质量的数据。
管理数据质量的经典模型
1960 年代的数据被认为是在孤岛中管理的,通常是物理上的,同时也有有限的技能组合来产生见解。然而,投资于管理高质量信息的人获得了更好的收入。
然后是商业智能解决方案的出现,它可以被称为今天的复古功能。然而,是一种为报告和分析模型使用数据的有效方式。多年来,组织一直专注于将数据移动到单个参考存储中,如具有提取-转换-加载(ETL)功能的仓库。这是公司普遍采用的第一代数据质量模型。
在将数据加载到仓库中之前,会针对质量的上下文维度(如有效性)对数据质量进行评估。这种模型可以称为第一代数据质量管理模型。
图 1:EDW 或仓库的第一代数据质量管理
由于需要处理往往过于庞大且结构多样的数据集,大数据作为一种能力已经发展起来。虽然 lake 使用提取、加载和转换的概念,但是在提取数据并将其加载到登陆存储时,会对数据的质量进行评估。
物联网数据质量管理高级模型
我们不能不强调运动数据的质量,这些数据经常被用于实时人工智能模型,包括欺诈检测和其他消费活动和分析过程。第一个数据质量挑战通常是为机器学习企业用例获取正确的数据。
错误数据 — 即使业务目标明确,数据科学家也可能无法找到正确的数据作为 ML 服务/算法的输入,以实现预期的结果。
正如任何数据科学家都会告诉你的,开发模型没有理解和以正确的方式处理问题/用例复杂。确定适当的数据可能是一个巨大的挑战。你必须有“正确的数据”
作为数据质量维度的数据覆盖率,用于 ML 用例
术语“覆盖”用于描述是否包含所有正确的数据。例如,在一家投资管理公司中,可能存在不同的客户群以及与这些客户相关联的不同子产品。如果不包括描述客户和相关产品的所有交易(行),您的机器学习结果可能会有偏见或完全误导。众所周知,收集所有数据(通常来自不同的子实体、销售点系统、合作伙伴等。)可能很难,但它对你的结果至关重要。
流媒体数据质量管理的新生模型——第二代
当务之急是查看由外部参与者(包括客户、外部合作伙伴和传感器等)流入环境的数据的质量。发现数据质量问题的方法可能与某些维度特别相关。
- 完整性—数据是否符合您对完整性的预期?
- 一致性—确保结构、语义的一致性并实施业务策略
- 及时性—数据是系统滞后还是手动滞后?
- 有效性—数据是否以指定的格式传输,是否符合标准
- 唯一性——相似的数据是否已经作为实例存在于生态系统中?
流数据质量架构是什么样的?
让我们来看一个甚至在数据落地之前就自动处理数据以保证质量的架构。这与数据通过管道传输到着陆区并按传统方式进行质量评估的选择截然不同。通常数据以更高的速度进入,因为它需要实时处理。同时,高速度的特征可以与质量管理相结合。
- 创建一个捕获客户人口统计详细信息的客户应用程序
- 声明两个消费应用程序——一个用于 MDM,另一个用于分析沙箱。
- 对从客户注册产品的在线门户获得的数据进行增量质量分析
- 使用一致性和有效性数据质量规则,使用 ksql 对到达的数据运行数据质量测试
- 根据验证结果向客户发回通知
- 捕捉仪表板中的指标以便可视化
注意—堆栈的选择是本机的,而不是使用 Kafkaconnect。
图 2:评估流中的数据质量。礼貌:Tejasvi Addagada
- 使用 Python 实例化客户数据流
我使用 Faker 生成客户数据,同时也使用属性姓名、地址、电话号码、工作、电子邮件、出生日期。我使用 IntelliJ 来运行脚本。
注意:在项目结构中,将项目 SDK 修改为 Python 3.6。还要安装软件包——Faker 5 . 8 . 0,coverage 5.4,kafka-python 2.0.2,pip 21.0.1,pymongo 3.11.2,python-dateutil 2.8.1,setuptools 52.0.0,six 1.15.0,text-unidecode 1.3 1.3
启动一个名为 data.py 的新 Python 脚本,并导入 Faker
from faker import Faker
fake = Faker()
def get_registered_user():
return {
"name": fake.name(),
"address": fake.address(),
"phone": fake.phone_number(),
"job": fake.job(),
"email": fake.email(),
"dob": fake.date(),
"created_at": fake.year()
}
if __name__ == "__main__":
print(get_registered_user())
2 。安装汇流卡夫卡&创建主题
融合平台试用版可从链接下载—https://docs . confluent . io/platform/current/quick start/ce-quick start . html
confluent local services start
您的输出应该如下所示
Starting Zookeeper
Zookeeper **is** [UP]
Starting Kafka
Kafka **is** [UP]
Starting Schema Registry
Schema Registry **is** [UP]
Starting Kafka REST
Kafka REST **is** [UP]
Starting Connect
Connect **is** [UP]
Starting KSQL Server
KSQL Server **is** [UP]
Starting Control Center
Control Center **is** [UP]
启动服务的第一步是创建一个主题 custchannel。
kafka-topics — bootstrap-server localhost:9092 — topic custchannel — create
3.使用 Python 创建一个生产者,持续发送数据
创建一个名为 producer_cust_ch.py 的新 Python 脚本,并从我们全新的 Kafka-Python 库中导入 JSON 、 *time.sleep、*和 KafkaProducer 。
from time import sleep
from json import dumps
from kafka import KafkaProducer
然后初始化一个卡夫卡制作人
- bootstrap _ servers =[’ localhost:9092 ']:设置生成器应该联系的主机和端口,以引导初始集群元数据。
- value _ serializer = lambda x:dumps(x)。encode(‘utf-8’) :声明数据在发送到代理之前序列化方式的函数。这里,我们将数据转换为 JSON 文件,并将其编码为 utf-8。
producer = KafkaProducer(bootstrap_servers=['localhost:9092'],
value_serializer=lambda x:
dumps(x).encode('utf-8'))
下面的代码将使用 Faker 在步骤 1 中定义的方法创建客户记录。让我们在一个无限循环中生成客户记录,而您可以随时从 UI 中终止生成器。在同一个循环中,数据将使用 send 方法通过管道传输到生成器。
if __name__ == "__main__":
while 1 == 1:
registered_user = get_registered_user()
print(registered_user)
producer.send("custchannel", registered_user)
time.sleep(10)
图 3:生产者使用 python,在 IntelliJ。礼貌:Tejasvi Addagada
在屏幕底部,由 Faker 功能创建并发送给生产者的客户记录被打印出来,正如我在向生产者发送数据的循环中所指示的那样。
4.拥有一个包含数据库和集合的名称空间,用于在 MongoDB 上存储传入的客户记录
MongoDB 进入这个行业才 5 年,但是它的能力可以很好地与 OLTP 和 OLAP 一起工作。对于这个例子,我将它用作客户数据存储。这将是与第一个消费应用程序相关联的数据库。
命令使用将创建一个新的数据库,如果它不存在
>use custchannel
switched to db custchannel
我将创建一个具有相同名称 custchannel 的集合,并插入示例记录。
图 4: Mongo,创建数据库,收集和插入样本记录。礼貌:Tejasvi Addagada
5。为消费者数据创建 2 个消费者群体(应用程序)
我使用 Python 实例化了第一个消费应用程序和相关的消费者以及 Kafka 中的一个组。
现在,让我们创建一个新文件 consumer_cust_ch.py 并从 pymongo 导入 JSON.loads 、 KafkaConsumer 类和 MongoClient 。
from kafka import KafkaConsumer
from pymongo import MongoClient
from json import loads
作为下一个逻辑片段,我将创建一个 KafkaConsumer 并使用下面的参数
- 第一个参数是题目, custchannel 。
- bootstrap _ servers =[’ localhost:9092 ']
- auto _ offset _ reset = ’ earliest ':该参数处理用户在集群关闭后重新开始读取,可以设置为 earliest 或 latest 。当设置为 latest 时,消费者接收在订阅主题之后或从最后提交的偏移量到达主题的消息。如果您想从头重新阅读所有消息,请选择最早的*。*
- enable _ auto _ commit = True:确保消费者提交其读取以补偿每个间隔。
- auto _ commit _ interval _ ms = 1000 ms:设置两次提交的时间间隔。
- group_id=‘custdq’ :一个重要的方面是,我们需要定义一个组,因为我们有多个消费应用程序接收相同的流。
- 值反序列化器将数据反序列化为 JSON 格式,这与值序列化器执行的功能相反。
*consumer = KafkaConsumer(
'custchannel',
bootstrap_servers=['localhost:9092'],
auto_offset_reset='latest',
enable_auto_commit=True,
group_id='custdq',
value_deserializer=lambda x: loads(x.decode('utf-8')))*
在相同的消费者代码中,我们将连接到一个名为 custchannel 的 MongoDB。我已经用一个示例文档创建了一个集合,并将该集合命名为 custchannel。
*client = MongoClient('localhost:27017')
collection = client.custchannel.custchannel*
消费者会一直听经纪人的话。可以使用 value 属性访问消息的值。然后,我们将数据插入到集合 custchannel 中,同时当值作为文档插入到集合中时,我们还打印一个确认
*for message in consumer:
message = message.value
collection.insert_one(message)
print('{} added to {}'.format(message, collection))*
*当您运行消费者组 *custdq,*时,消息将被存储到 Mongo 数据库 *custchannel 中。在运行窗口中,我们可以看到存储的消息。
图 5:消费者,在 Intellij 中使用 Python。礼貌:Tejasvi Addagada
在图 2 中,我们可以看到记录计数随着消息被插入到集合 custchannel 中而增加。
6.创建另一个消费者群体来阅读相同的信息
我们可以让多个消费者读取来自同一个生产者的消息,只要它们与不同的组相关联。属于同一个群体的消费者将不能整体消费同一个话题。
由于汇合服务已经启动,下面的代码将创建一个消费者组 mdm 。
*kafka-consumer-groups.sh --bootstrap-server localhost:9092 --topic custchannel --group mdm*
我们可以看到这个消费群体 mdm 订阅了同一个话题 custchannel。生产者生成的信息现在显示在终端上。为了会话的目的,您可以将偏移设置为最早的。
图 6:创造第二个消费群体。礼貌:Tejasvi Addagada
7。让我们来看看 KSQL,从主题中声明一个流
*我已经定义了一个流 *custdqdemo,来自步骤 2,custchannel 中创建的主题。消息的格式可以在参数 VALUE_FORMAT 中指定为 JSON。客户记录 name、address、job、email dob 中的属性用它们的数据类型指定给 KSQL。
*ksql> CREATE STREAM custdqdemo (name VARCHAR, address VARCHAR, phone VARCHAR, job VARCHAR, email VARCHAR, dob VARCHAR, created_at VARCHAR) \>>WITH (VALUE_FORMAT = 'JSON', KAFKA_TOPIC = 'custchannel');*
在执行上述语句时,流 custdqdemo 被创建,如下面的屏幕截图所示
图 7: Ksql 流创建。礼貌:Tejasvi Addagada
我们可以查看来自主题 custchannel 的消息,这些消息在我们查询流时显示。
图 8:查询来自主题的消息流。礼貌:Tejasvi Addagada
8。通过数据质量验证评估流并创建异常流
当我们到达模拟的最后一站时,我们将查看针对流中的每个消息验证的两个数据质量规则。这些规则将以查询的形式持续运行。
*CREATE STREAM custexcep AS
SELECT name,
CASE
WHEN dob < '1980-01-01' THEN 'Policyexception'
WHEN job = 'Arboriculturist' THEN 'Not standard profession'
ELSE 'Correct'
END AS Quality
FROM CUSTDQDEMO;*
图 9:在流上使用 Ksql 脚本评估异常。礼貌:Tejasvi Addagada
在 ksql 脚本中,我使用一个简单的 case 语句来检查
a.如果客户的出生日期在 1980 年之后,政策例外。
b.有效的职业/工作名称。
*有一个新的属性 quality,它在运行数据质量规则时捕获预定义的异常消息,如上面的屏幕截图所示。一个名为 *custexcep 的新流被创建。该持久性源可用于监控动态数据的数据质量问题。
Ksql 中有更成熟的功能来减轻监控开销,我们可以在接下来的博客中看到。
来源
介绍 Kafka 消费者:开始使用新的 Apache Kafka 0.9 消费者客户端
Asset2Vec:将 3D 对象转化为矢量,然后再转化回来
行业笔记
我们如何使用 NeRF 将我们的整个 3D 对象目录嵌入到一个共享的潜在空间中,这对图形的未来意味着什么
在我目前担任人工智能研究主管的 Datagen ,我们创建常见 3D 环境的合成照片级真实感图像,用于训练计算机视觉算法。例如,如果你想教一个房屋机器人在一个脏乱的卧室中导航,就像下面这样,这将花费你相当多的时间来收集足够大的训练集的真实图像[人们通常不喜欢外人进入他们的卧室,他们肯定不会喜欢给他们的混乱拍照]。
凌乱卧室的合成图像(图片由作者提供)。
我们使用图形软件生成了上面的图像。一旦我们(在软件中)建立了环境和其中所有东西的 3D 模型,我们就可以使用它的光线跟踪渲染器在我们想要的任何光照条件下,从我们喜欢的任何相机视点生成场景的图像。我们已经完全控制了。
现在,如果你认为收集真实图像很难,那么等到你尝试标记这些图像。你需要启动一个漫长而昂贵的标记操作,教人类如何根据你的标准标记这些像素。当然,使用合成图像,我们可以轻松地为图像的任何方面生成像素完美的标签,包括人类无法评估的东西,如深度和表面法线贴图。
从左上顺时针方向:不同光照条件下渲染的场景,表面法线贴图,深度贴图,对象类标签(图片由作者提供)。
收集资产
为了帮助我们的用户训练她的机器人,我们需要生成成千上万个像上面这样的卧室,我们需要用东西填满它们:家具、布、书、用过的杯子、遥控器等等。因此,我们维护了一个艺术家制作的 3D 对象的大型目录(我们称之为资产 ) *。*我们的产品目录涵盖 100 多万件商品,我们对此深感自豪。
每个资产对象由一个详细的 3D 网格(由三角形组成的多边形结构,它定义了对象的形状)和一个纹理贴图(一个图像,它定义了对象的外观,就好像它是一个用来覆盖网格表面的毯子)。
资源(左)由网格结构(中)和纹理贴图(右)表示。图片作者。
除了在视觉上定义对象的网格和纹理贴图之外,为每个资产存储的其余信息是 3D 艺术家决定放入文本元数据文件中的任何内容,如对象的类型(“餐椅”),以及当时似乎相关的任何标签。
因此,在目录中搜索(例如,“给我所有有三条腿的表”)只能使用它们的元数据属性来完成。如果艺术家没有写下每张桌子的腿数,那么要知道哪些桌子是三条腿的,唯一的方法就是一个一个地打开它们的 3D 模型文件去看。
资产-2-Vec
相反,我们建议在嵌入空间中编码每个资产,这将封装整个资产的形状和外观。与 Word2Vec 非常相似,它为字典中的每个单词提供一个“代码”向量,该向量对应于一个 n 维空间中的一个位置,这样语义相似的单词就彼此靠近,我们希望为我们的每个资产分配一个向量,这样我们就可以通过查看向量来判断资产的所有视觉属性。
将我们所有的 3D 资产编码成向量。图片作者。
理想情况下,我们还希望将形状属性(例如,腿的数量)与外观属性(如颜色或材料)分离开来。我们怎么知道向量确实抓住了物体的全部本质?最终的方法是能够从向量回到资产的 3D 模型。
您可以想象一个神经网络,它将学习读取向量作为输入,并输出资源的原始网格和纹理贴图。然而,这将是困难的。每个资源的网格都有完全不同的拓扑:不同数量的三角形,每个节点的不同含义,纹理贴图和网格之间不同的映射格式。我们还需要其他东西,一种适合所有资产的替代 3D 表示。
NeRF 来救援了
这就是 NeRF 的用武之地。正如你所记得的,在我之前的文章中,我展示了如何使用大约 40 张从不同角度拍摄的物体图像,我们可以训练一个神经网络来学习物体周围的整个空间。经过训练的神经网络将空间中的点 (x,y,z) 作为输入,并返回该点中材质的颜色 (r,g,b) 和不透明度(α)。网络对空间了解得如此之好,以至于渲染器可以拍摄对象的“照片”,只需通过沿着来自模拟“相机”的光线的点查询该网络。
NeRF 中心的神经网络(图片由作者提供)。
我们可以轻松获得 40 张图片,涵盖我们目录中的每项资产。我们简单地使用图形软件从它们的原始网格模型渲染它们(所以我们也可以渲染 80)。然后,我们可以使用这些图像来训练 NeRF 网络,以对物体周围的空间进行编码。网络训练完成后,我们可以生成一个短片,从各种新的角度展示物体,其中每一帧都是通过查询训练好的 NeRF 网络来渲染的。
左图:来自图形软件 Blender 的截图,其中我们从各个方向渲染了该资产的 80 幅合成图像(每个金字塔是一个模拟相机),用于训练 NeRF 网络。右图:通过查询训练好的 NeRF 网络,从 80 个新视点渲染的对象,跨越 360 度。作者图片。
我们接下来要做的是,使用单个 NeRF 网络,不仅对单个资产进行编码(就像上面的椅子),而且对我们目录中的所有椅子进行编码**。这个单一网络将拥有与 NeRF 网络完全相同的架构。唯一的区别是它将有一个额外的输入:分配给每把椅子的(潜在)向量,它将在训练期间学习。我们将像训练 NeRF 网络一样训练这个网络,除了我们将使用从我们目录中的所有**椅子上拍摄的照片。****
NeRF 网络,以潜在向量作为附加输入。在训练期间,资产的潜在向量也与全连接层的权重一起被学习(图片由作者提供)。
这种训练不同于普通训练,在某种意义上,除了其自身的权重之外,网络还学习与每把椅子相关联的一组特殊变量——其潜在向量(类似于嵌入层的学习方式)。当我们反向传播从渲染椅子图像获得的误差时,不仅更新了 NeRF 网络的权重,而且更新了分配给特定椅子的的潜在向量中的值(例如 vec 输入)。****
一旦我们训练了这个网络,我们就可以用它来制作产品目录中所有椅子的电影!要渲染任何特定的椅子,我们只需要在查询时将椅子的潜在代码作为输入提供给 NeRF 网络。
通过查询一个单个** NeRF 网络呈现的椅子资产示例。图片作者。**
潜在探索
我们不需要将自己局限于为当前目录中的资产学习的向量。我们还可以探索当我们任意改变潜在向量,或者混合和匹配来自两个不同资产的潜在向量时会发生什么。或许在不久的将来,我们能够通过以下方式用新资产丰富我们的产品目录:
混合潜在向量:当 NeRF 网络的输入将椅子 i 的潜在向量的 形状部分与椅子 j 的外观部分组合时,产生位置(I,j)的椅子。图片由作者提供。
为了直观地了解资产潜在空间的样子,我们可以使用 TSNE 算法将我们的资产放置在 2D 平面上(根据它们的潜在向量):
我们 522 个资产的向量的 T-SNE 图。对象类和子类之间的清晰分离。图片由作者提供。
我们可以看到,椅子的不同子类之间的区别是明显的,即使在一个子类中(即扶手椅),我们也可以很容易地找到椅子共享视觉属性的区域(即带木质扶手的扶手椅与带软垫扶手的扶手椅)。
这就是重点,不是吗?因为这意味着我们可以很容易地训练一个线性分类器(像 SVM 一样)来识别我们关心的任何视觉属性,只需给它提供少数正面和负面资产的向量,然后用它来标记其余的 100 万资产目录,而无需加载这些资产。这种特别的分类可以节省我们大量的时间!
潜伏是未来
最后,这种分析不仅适用于椅子,也适用于我们产品目录中的所有其他资产系列。我们可以想象一个未来,我们渲染的每个场景都将被这些潜影完全描述:每个资产的潜影,背景的潜影,姿势的潜影,相机角度,灯光。如果我们敢,我们可以想象一个未来,传统的网格和纹理贴图将不再被用来渲染合成但逼真的图像,就像上图中凌乱的卧室场景。
通过查询一个单个** NeRF 网络,我们的表资产的一个示例。图片作者。**
附录:解耦形状和外观
NeRF 网络有两个分支,一个用于不透明度(α),另一个用于颜色。为了分离潜在向量中的形状和外观部分,我们将输入的潜在代码分成两部分,并且仅向颜色分支显示外观部分,如下所示。这个技巧来自最近的 GIRRAFE 论文(尼迈耶和盖格,CVPR 2021)。
我们修改后的 NeRF 网络架构(图片由作者提供)。
为了更好地理解形状和外观子空间,我们对潜在向量的相关部分进行了 PCA 分析:
****
形状空间(上)和外观空间(下)的前 10 个 PCA 组件的图示。作者图片。
我们可以看到这些是如何控制椅子的各个方面的,如座位的大小,宽度,靠背的高度等。在外观空间中,我们可以看到 PCA 方向如何控制颜色,以及它们的饱和度、亮度和光照条件。
线性回归的假设
用 R 和 Python 实现
线性回归是一种统计模型,允许根据一个或多个独立变量(标为 x )的变化来解释因变量 y 。这是基于自变量和因变量之间的线性关系。
在本文中,我将快速浏览一遍线性回归模型,并涵盖进行线性回归时需要检查的五个假设。我将用 R 和 Python 讲述理论和实现。
线性回归基础—示例
让我们从描述线性回归的一个常见用例开始。我们将研究一个模型,在这个模型中,我们根据房屋的一些物理标准来解释和预测未来房屋销售的价格。
数据
我制作了一个模拟数据集,对这个练习非常有用。当然,既然数据不真实,解读就不会有价值。数据如下所示:
我们线性回归的数据
您可以使用 R 或 Python 通过以下代码片段从 S3 导入数据。
用 Python 从 S3 导入 CSV 文件:
使用 Python 从 S3 导入 CSV
从 S3 导入带有 R: 的 CSV 文件
从 S3 用 R 导入 CSV
线性回归模型
现在,我们感兴趣的是解释房价和其他变量之间的关系。为了对此进行建模,我们将进行线性回归,对以下公式进行建模:
在这个等式中,我们有:
- β0,截距系数,给出所有解释变量都为 0 的假设情况下的卖出价格值。
- 贝塔系数的 1 到 4,即斜率系数,给出了特定变量增加 1 步时的销售价格的增加。
- ε:模型无法解释的销售价格变化(这可能是随机变化或由于一些解释变量引起的变化)
拟合线性回归模型
进入假设之前的最后一步是拟合模型。对于 R 代码,我们将使用lm
函数,它是线性模型的定位函数。在 Python 实现中,我们将使用statsmodels
库。
用 Python 拟合线性回归
用 R 拟合线性回归
线性回归假设
因为本文的重点是涵盖假设检查,所以让我们跳过模型解释,直接进入您需要检查的假设,以确保您的模型构建良好。
线性回归假设 1 —观察值的独立性
线性回归的第一个假设是观测值的独立性。独立性意味着不同的例子之间没有关系。这不是看数据就能推断出来的:数据收集过程更有可能对此给出答案。
一个明显的依赖观察 (这是我们不想要的!) 可以在使用时间序列时发生。想象一下某个值的日常数据测量。在这种情况下,今天的价值比很久以前的价值更接近昨天的价值。
一个清晰的独立观测 *(这正是我们想要的!)*是实验研究,参与者被随机分配到治疗组。在这种情况下,分配是随机和强制的这一事实确保了观察值之间没有隐藏的关系。
线性回归假设 2 —没有隐藏或缺失的变量
线性回归模型的第二个假设是,你已经在你的模型中使用了所有相关的解释变量。如果你不这样做,你最终会得到一个错误的模型,因为模型会试图将系数赋给数据集中确实存在的变量。这通常被称为模型的错误设定。
如果在模型中加入一个变量会有很大的不同,那就意味着没有这个变量,模型是不正确的,没有用的。在这种情况下,你唯一能做的就是回到你的数据收集中去寻找必要的数据。
线性回归假设 3 —线性关系
线性回归的第三个假设是自变量和因变量之间的关系必须是线性的。
尽管这一假设并不总是在文献中被引用,但是检查它是合乎逻辑的并且是重要的。毕竟,如果你的关系不是线性的,你不应该使用线性模型,而应该使用大量存在的非线性模型。
您可以通过绘制每个自变量和因变量的散点图来轻松检查线性关系。您可以使用下面的 R 和 Python 代码来做到这一点。
使用 Python 检查线性关系
线性回归的假设-线性关系 Python
检查与 R 的线性关系
线性回归的假设—线性关系— R
虽然有许多其他方法来做散点图,这种方法是简单的,足够好地检查假设。
Python 代码生成的散点图
要搞清楚 1 对 1 的关系是否是线性的,需要判断数据点是或多或少在一条直线上,还是在一条直线周围。清晰的反模式是当你看到曲线、抛物线、指数或者基本上任何可以识别为非直线的形状时。
这些图没有显示完美的直线,但这不是问题。也没有任何明确的非线性模式,线性模型可能在这方面工作得很好。
线性回归假设 4 —残差的正态性
线性回归的第四个假设是残差应该遵循正态分布。从模型中获得残差后,使用直方图或 QQ 图进行测试相对容易。QQ 图有点难读,但解释起来更精确,所以让我们看看如何使用 R 和 Python 制作残差的 QQ 图。
使用 Python 检查残差的正态性:
线性回归的假设-残差中的正态分布 Python
使用 R 检查残差的正态性:
线性回归假设—残差中的正态分布— R
由 R 代码产生的 QQ 图
在 QQ 图中,您需要查看的是这些点是否在从左下方到右上方的直线上。当偏差发生时,它们通常位于线的低端或高端,而中间的偏差不太可能发生。
如果您看到任何类型的 S 形、指数曲线或直线以外的其他形状,这意味着您有问题:您的模型可能没有正确指定。可能你遗漏了一些变量,或者你的关系实际上不是线性的!您可能想要尝试非线性模型或线性模型的其他规格(使用不同的变量或变量的不同准备)。
在当前的例子中,显然有一个倒置的 S 形,这意味着模型可能有问题。
线性回归假设 5-没有或很少多重共线性
线性回归的第五个假设是不存在或很少存在多重共线性。多重共线性是指多个解释变量高度相关的现象。
那么为什么我们希望每个自变量和因变量之间有很强的相关性,而自变量之间没有相关性呢?原因是,如果两个独立变量相关,它们解释了相同的信息。该模型将无法知道两个变量中的哪一个实际上对因变量的变化负责。
您可以使用方差膨胀因子(简称 VIF)来测试多重共线性问题。VIF 表示一个自变量与其他自变量的相关程度。您可以使用以下代码在 R 和 Python 中计算 VIF。
使用 R 检查多重共线性:
线性回归的假设—使用 VIF 检验多重共线性
使用 Python 检查多重共线性:
线性回归的假设-使用 VIF-Python 检查多重共线性
Python 生成的 VIFs
VIF 从 1 开始,没有上限。VIF 为 1 是最佳值,因为这表示该变量不存在多重共线性。高于 5 或 10 的 VIF 表明模型中的自变量有问题。
在当前的模型中,浴室、卧室和平方米屋这些变量肯定有问题。它们之间似乎非常相关,因此有必要考察这些变量中的哪一个是解释销售价格所真正需要的。
线性回归假设 6 —同方差
线性回归的第六个假设是同方差。模型中的同方差意味着误差沿着因变量的值是恒定的。检验同方差的最好方法是用残差对因变量做一个散点图。您可以使用下面的 R 和 Python 代码来实现这一点。
使用 R 检查同质性:
线性回归的假设—同方差— R
使用 Python 检查同质性:
线性回归的假设-同方差 Python
线性回归的假设—同方差图
同方差意味着一个恒定的误差,你在寻找点与零线的恒定偏差。在当前情况下,您可以在右上角清楚地看到两个异常值。在其余的点中,你也看到顶部的点多,底部的点少。这显然不像零线附近的恒定方差。
如果你违反了同质异方差,这意味着你有异方差。您可能希望对输入数据做一些工作:可能需要添加或删除一些变量。另一个解决方案是进行转换,比如对因变量应用逻辑或平方根转换。
如果这不能改变什么,你也可以切换到**加权最小二乘模型。**加权最小二乘法是一种模型,c 可以处理非恒定方差,因此异方差不是问题。
线性回归假设 7 —所有独立变量与误差项不相关
线性回归模型的第七个诊断检查用于检查任何自变量和误差项之间是否存在相关性。如果发生这种情况,很可能是型号指定错误。你可能忘记了一个重要的解释变量。
您可以使用以下 R 和 Python 代码获得散点图:
在 Python 中检查 IVs 和残差之间的相关性:
线性回归的假设-独立变量和残差之间没有相关性 Python
检查 iv 和 R 中残差之间的相关性:
线性回归的假设—独立变量和残差之间没有相关性— R
线性回归的假设—独立变量和残差之间没有相关性
在这些散点图中,我们看不到任何明显的相关性。右下图可能是一个有争议的案例,但它也不是一个非常清晰和令人信服的问题。
线性回归假设 8 —误差项的观测值彼此不相关
我们要看的最后一个模型诊断是,误差项的观测值内部是否存在相关性。如果发生这种情况,您肯定违反了假设 1:观察值不是随机抽取的。
您可以通过绘制残差与残差阶数的关系来进行直观检查。以下代码片段允许您这样做:
在 Python 中检查残差自相关:
线性回归的假设-残差中的自相关 Python
检查 R 中的剩余自相关:
线性回归假设—残差中的自相关— R
线性回归假设-残差中没有自相关
如果出现一个模式,很可能是一个错误指定的模型。你可能忘记了一个重要的解释变量。或者您可能更适合使用另一系列模型。如果你有自相关,你可能想看看时间序列模型,如自回归移动平均或 ARMA。
如果你的线性回归假设被违反了怎么办?
下一个大问题当然是,如果你发现你的一个假设不成立,该怎么办?!不要担心:对于大多数无效假设的情况,你都可以做一些事情。以下概述了在假设无效的情况下可以采用的替代方法:
- 通过转换或添加缺失变量来处理输入数据可以解决许多问题
- 当你发现你有一个错误的设定时,非线性回归是一个很好的方法
- 如果观察到多重共线性,您可能希望在模型中使用较少的变量。你有强相关的解释变量,最好在它们之间进行选择。一种替代方法是使用例如主成分分析将它们制成一个复合变量。
- 如果您观察到同方差,您可以转向加权最小二乘模型,这是 OLS 的替代方案,可以处理
- 如果你的自变量与误差相关,你很可能处于一个错误指定的模型中,你应该选择正确的变量来包含在你的研究中
- 如果误差项彼此相关,您可能处于自相关存在的情况下,并且您可能擅长使用时间序列模型。
我希望这篇文章对你有用。感谢阅读,不要犹豫,继续关注更多!
逻辑回归的假设,解释清楚
理解并实现假设检验(用 Python ),这是最重要的数据科学建模技术之一
塞巴斯蒂安·斯坦尼斯在 Unsplash 上的照片
逻辑回归是一种非常有效的建模技术,自 20 世纪 40 年代发展以来,一直是统计学中的主流。
考虑到它的普及性和实用性,数据从业者应该在使用它处理数据和业务问题之前理解逻辑回归的基本原理。
在本文中,我们将通过理论解释和实践假设检验的 Python 实现来探索逻辑回归的关键假设。
内容
(1)理论概念&实践检验 (2)与线性回归 (3)总结与 GitHub 回购链接
照片由格伦·卡斯滕斯-彼得斯在 Unsplash 拍摄
理论概念&实践检验
为了在 Python 中实现假设检查,我们将使用经典的 泰坦尼克号数据集。完整的代码请看一下这个项目 的 GitHub repo。
假设 1—适当的结果类型
逻辑回归通常用作分类器,因此所用的逻辑回归类型(二元、多项式或有序)必须与数据集中的结果(因变量)相匹配。
默认情况下,逻辑回归假设结果变量为二元,其中结果的数量为两个(例如,是/否)。
如果因变量有三个或更多结果,则应使用多项式或顺序逻辑回归。
如何检查?
我们可以通过获得因变量中不同结果的数量来检验这一假设。如果我们要使用二元逻辑回归,那么在结果变量中应该只有两个唯一结果。
假设 2 —独立变量和对数优势的线性
逻辑回归的一个关键假设是,结果的 logit (又名 log-odds )与每个连续自变量之间的关系是线性*。*
logit 是比值比*的对数,其中 p =积极结果的概率(例如,在泰坦尼克号沉没中幸存)*
怎么查?
(一)Box-Tidwell 测试
盒形井 测试是用于检查预测值和逻辑值之间的线性。这是通过将连续独立变量与其对应的自然对数之间的对数转换交互* 项添加到模型中来实现的。*
例如,如果你的一个连续自变量是**Age**
,那么作为新变量添加的交互项将是**Age * ln(Age)**
。
作为 Box-Tidwell 测试的一部分,我们对数据集进行过滤,只保留连续的独立变量。
注意:虽然 R 有 *car*
库来用一行代码执行 Box-Tidwell,但我找不到任何可以做类似事情的 Python 包。
如果你有一个以上的连续变量,你应该在模型中包括相同数量的相互作用项。包含交互项后,我们可以重新运行逻辑回归并查看结果。
涉及 Box-Tidwell 变换的 Logit 回归结果示例|图片由作者提供
我们需要做的是根据它们的 p 值检查交互项年龄:Log_Age* 和费用:Log_Fare 的统计显著性。*
年龄:Log_Age 交互项的 p 值为 0.101 ( 不是统计显著,因为 p >为 0.05),这意味着自变量年龄与结果变量的 logit 线性相关*,并且假设得到满足。***
相反, Fare:Log_Fare 为统计显著(即 p≤0.05),表明 Fare 与 logit 之间存在非线性。
一种解决方案是通过结合高阶多项式项来执行变换,以捕捉非线性(例如, Fare )。
(二)目测
我们可以检查 logit 线性的另一种方法是通过目视检查每个预测值和 logit 值之间的散点图。
**费用变量与结果的对数概率的散点图|图片由作者提供
上述散点图显示了费用与对数优势比的清晰非线性模式,从而暗示违反了logit 线性假设。
假设 3—没有强烈影响的异常值
逻辑回归假设不存在或具有高度影响力的异常数据点,因为它们会扭曲模型的结果和准确性。
请注意,并非所有异常值都是有影响的观察值。相反,离群值有潜在的影响力。为了评估这一假设,我们需要检查是否满足两个标准,即有影响的和异常值。
怎么查?
(一)影响
我们可以用库克距离来确定一个数据点的影响,它是根据它的残差和杠杆来计算的。它总结了当特定的( i th)观察值被移除时回归模型中的变化。
关于使用什么截止值,有不同的意见。一个标准阈值是 4/N (其中 N =观察次数),意味着具有库克距离> 4/N 的观察被认为是有影响的。
statsmodel
包还允许我们可视化 GLMs 的影响图,例如影响属性的指数图([influence.plot_index](https://www.statsmodels.org/stable/generated/statsmodels.genmod.generalized_linear_model.GLMResults.get_influence.html)
):
库克距离的指数图示例。红色虚线表示厨师的距离界限,上面是作者认为有影响的点|图片
(二)离群值
我们使用标准化残差来确定一个数据点是否是异常值。绝对标准化残差值大于 3 的数据点代表可能的极端异常值。
(三)把两者放在一起
我们可以根据之前为库克距离和标准化残差定义的阈值,通过查找顶部观察值来识别具有强烈影响的异常值数据点。
当检测到异常值时,应该对它们进行相应的处理,例如删除或转换它们。
前 5 名最具影响力的异常值(以及相应的指数)|作者图片
假设 4-不存在多重共线性
多重共线性对应于数据包含高度相关的独立变量的情况。这是一个问题,因为它降低了估计系数的精度,削弱了逻辑回归模型的统计能力。
如何检查?
方差膨胀因子(VIF) 测量一组独立变量中多重共线性的程度。
从数学上来说,等于整个模型方差与一个只包含单个自变量的模型的方差之比。
VIF 的最小可能值是 1(即完全没有共线性)。根据经验,超过 5 或 10 的 VIF 值表示多重共线性的数量有问题。
以下是计算出的 VIF 值的示例。由于没有 VIF 值超过 5 ,假设成立。
VIF 价值观|作者图片
另一种检查方法是生成关联矩阵热图:
相关矩阵|作者图片
这种方法的问题是,当存在许多独立变量时,热图可能难以解释。
更重要的是,三个或更多变量之间可能存在共线性,即使没有一对变量被视为具有异常高的相关性。因此, VIF 是评估多重共线性的更好方法。
*https://kennethleungty.medium.com/membership *
假设 5——观察的独立性
观察值必须彼此独立,也就是说,它们不应该来自重复或成对的数据。这意味着每个观察不受其余观察的影响或与之相关。
怎么查?
对于我们的 Titanic 示例数据集来说,这种独立性假设是自动满足的,因为数据由单个乘客记录组成。
在处理时间序列数据时,这种假设更值得关注,因为时序观测值之间的相关性(自相关)可能是一个问题。
尽管如此,仍然有方法来检查非时间序列数据的观测值的独立性。在这种情况下,“时间变量”是观察的顺序(即指数)。
特别是,我们可以创建残差序列图,其中我们绘制了 logit 模型的偏差残差与观察值的指数。
剩余系列图|作者图片
由于上图中的残差似乎随机分布在零点的中心线周围,我们可以(直观地)推断该假设得到满足。
注:如果您希望了解更多关于逻辑回归中传统残差 vs .fit图的解释,请查看文章 此处 和 此处 。
假设 6 —足够大的样本量
对于数据集中的每个独立变量,应该有足够数量的观察值,以避免创建过度拟合的模型。
怎么查?
像库克的距离一样,有许多关于经验法则的观点来确定“足够大”的数量。
一个经验法则是,对于每个独立变量,至少应该有 10 个观察值,且结果最不频繁。我们可以通过检索每个变量的值计数来检查这一点。
另一种确定大样本量的方法是,的总观测数应大于 500 。我们可以通过获得整个数据帧的长度来检查这一点。**
与线性回归的比较
尽管逻辑回归的假设不同于线性回归,但这两种技术都有几个假设。
差异
- 逻辑回归不要求因变量和自变量之间存在线性关系。然而,它仍然需要独立变量与结果的对数概率线性相关。
- 线性回归需要同方差(常方差),但逻辑回归不需要。
- 误差项(残差)必须为正态分布,用于线性回归,但在逻辑回归中不需要。
类似
- 多重共线性缺失
- 观察是相互独立的
罗伯特·阿纳施在 Unsplash 上拍摄的照片
摘要
以下是我们已经讨论过的假设的回顾:
- 适当的结果类型
- 自变量的线性和对数比**
- 无强烈影响的异常值
- 缺少多重共线性
- 观察值的独立性
- 足够大的样本量
我还推荐探索附带的GitHub repo查看这六个假设检查的完整 Python 实现。
如果你对这个话题有任何反馈或建议,我期待在评论区听到你的意见。
在你走之前
*欢迎您**加入我的数据科学学习之旅!*点击此媒体页面,查看我的 GitHub ,了解更多精彩的教育数据科学内容。同时,享受运行逻辑回归的乐趣!
* [## 垂死的雷鲁问题,解释得很清楚
通过理解 ReLU 的缺点来保持你的神经网络的活力。](/the-dying-relu-problem-clearly-explained-42d0c54e0d24)
参考
在 GitHub repo 自述文件 中整理的参考资料完整列表*
亚述人还是巴比伦人?楔形文字中的语言识别
实践教程
古代美索不达米亚方言的语言模型
楔形文字泥板。来源: Rama ,维基共享
美索不达米亚是幼发拉底河和底格里斯河之间地区的一个古老名称,位于今天的伊拉克和土耳其、叙利亚和伊朗的部分地区。现代社会的“现代性”很大程度上归功于美索不达米亚人在农业、数学或冶金等领域的发明。在这些发明中,古代美索不达米亚人最伟大的成就之一是发展了 楔形文字手稿,并由此发展出最早的书写系统之一。这是公元前第三个千年,历史才刚刚开始。
楔形文字由印在新鲜泥板上的楔形符号组成。粘土是一种可以抵抗时间流逝而不会显著退化的材料。因此,考古学家设法找到了大量保存完好的石碑。该地区的粘土也非常便宜和丰富。这使得这种形式的经文非常受欢迎,不同的民族在很长一段时间里根据他们的语言改编了这种文字。因此,我们对美索不达米亚几千年来(书面)语言的演变有一个很好的记录。事实上,我们有这么多的记录跨越了这么长的时间,它们几乎是无法管理的。这就是数据科学的用武之地。
古代美索不达米亚地图。来源: Goran tek-en ,维基共享
本文的目的是展示如何编写一个简单的定制语言模型来识别楔形文字文本中的美索不达米亚语言和方言。为此,我们使用来自 Kaggle data challenge 的数据集https://www.kaggle.com/wilstrup/cuneiform-language-identification**识别楔形文字。该数据集包含大约 139,000 个楔形文字片段,还提供了语言或方言标签。有七个标签,包括夏季语 (SUX),一种孤立的语言,以及阿卡德语的六种方言:新亚述语(NEA),标准巴比伦语(STB),晚期巴比伦语(LTB),新巴比伦语(NEB),中巴比伦外围语(MPB),以及旧巴比伦语(OLB)。
如果你想知道这些字符的样子,下面的图片显示了我们的数据集的一个样本。很漂亮,对吧?
我们数据的子集。来源:作者对 Kaggle 数据集的分析
接下来,如果您想在本地机器上复制这个分析,我建议您下载这些字体中的一种。虽然这不会影响您复制分析的能力,但否则文本将无法正确呈现。
语言模型
一般来说,语言模型是单词序列的概率分布。在这个宽泛的定义中,我们可以找到不同类型的模型。一些最常见的使用 n-gram 的概念,即 n 个连续字符(单词)的序列,我们在其中分割文本。N-gram 模型在 NLP 文献中相当常见。它们的应用包括语音和手写识别以及机器翻译。因此,Python 中有一些众所周知的包,比如 NLTK ,用它们我们可以很容易地构建一个 N 元模型。
对于这项任务,我使用一个 N-gram 模型来预测楔形文字 N-gram 序列属于特定的古代美索不达米亚语言或方言的概率。在这个实现中,我们假设每个字符是一个单字。从技术上讲,楔形文字可以是一个完整的单词,也可以只是一个声音,但是我们会忽略这个事实。现在,你可能已经猜到了,如果我遵循这个挑战的简单路径,我就不会写这篇文章。相反,在这里我将向您展示如何从零开始构建一个 N 元模型。事实上,我在代码中使用的唯一 Python 库是numpy
和pandas
。我决定这样做有两个原因:首先,标准的 NLP 库是为处理拉丁字符而设计的,所以让它们适应楔形文字有点痛苦。第二,好玩!我坚信测试你在一个主题上的知识的最好方法是从基础开始,看看你是否能用尽可能少的专业库来编码它。**
我提出的 N-gram 模型实现受到了使用概率链规则和马尔可夫假设的经典 N-gram 模型的启发。简单来说,这个假设说明了一个 n 元文法在位置 t 的概率只取决于前面的 k n 元文法(其中 k 通常为 1)。因此,可以通过取其 n 元文法的条件概率的乘积来计算序列的概率,直到 t-k 。
嗯,我的代码并没有完全做到这一点,而是更接近和更简单。它实际上是计算每种语言的训练集中所有 n 元语法的无条件概率。然后,它通过乘以序列中出现的所有 n 元语法的无条件概率来估计观察到的序列属于每种语言的概率。选择概率最高的语言作为预测标签。
显然,可以开发更复杂的方法。然而,我发现这个非常简单的模型在测试集上已经表现得非常好了。
履行
现在我们对语言模型有了更好的理解,让我们看看如何为楔形文字编写自定义实现。就代码而言,这一部分有点重,但是请相信我:付出的努力是值得的!或者,您可以转到结果部分,了解故事的结局。
我们从一些辅助函数开始。第一个,我们称之为preprocess
,将楔形文字的字符串转换成对我们来说更方便的格式。它执行两个操作:首先,它添加一个句子开头和结尾的标记(我们分别称之为 B 和 E),然后它在字符之间添加一个空格。b 和 E 是有用的标记:它们帮助我们计算一个句子以给定字符开始和结束的概率。
预处理功能。来源:作者
现在,我们需要计算 n-grams!下面的两个函数是我们实现的核心,因为它们将文本分割成 n 个字母,并计算每个字母在我们的示例中出现的次数。
N-gram 计数函数。来源:作者
我们的最后一个帮助函数logprob
,将用于计算 n 元文法的整个序列的对数概率。在这种类型的问题中,我们通常处理非常小的概率,所以取对数通常是跟踪我们的数字的好主意。这里我们有另一个关于经典语言模型的简化。通常,N-gram 模型会在其词汇表中包含一个“未知”单词标记,以估计找到真正不常见单词的概率。然而,在我们的例子中,我们将简单地假设找到这样的字符的概率是 0.00001(比我们最稀有的一些字符低大约 10 倍)。
计算一个序列的对数概率。来源:作者
就是这样!这些都是我们需要的辅助函数。现在轮到定义一个类来包装我们的模型,您可以在下面的代码片段中看到。因为没有更好的名字,就叫它CuneiPy
吧。我们的包装类遵循经典的 Scikit-Learn 结构,包含两个方法:.fit()
和.predict()
。.fit()
方法计算每个 n 元语法和语言的无条件概率(记住,我们有七个)。这就是 n 元语法在 n 元语法总数中出现的次数。.predict()
方法获取楔形文字字符序列,并计算该序列属于我们的一种语言的概率。然后,它取概率最高的语言,选择它作为预测标签。
CuneiPy —模型的包装类。来源:作者
结果
如果你现在还和我在一起,你可能会想这个东西到底有没有用。你可能已经猜到了答案:是的!虽然肯定有改进的空间,但我们的简单模型在 1000 个观察值的测试集上表现得非常好,加权 f 1 分数约为 0.8(取决于训练-测试划分)。
测试CuneiPy
就像这样简单:
测试 CuneiPy。来源:作者
正如我们在.fit()
部分看到的,我们使用的是二元模型(因此 n = 2 )。列“楔形文字”是我们语言模型的输入,我们的目标列由数据集中的“lang”定义。下面的分类报告为我们提供了一个模型性能最佳的细分。也许不足为奇的是,该模型更善于识别新亚述语(NEA)和索姆利语(SUX),这两种最常见的语言。该模型也很好地识别了晚期巴比伦语(LTB ),尽管只有 11%的文本属于这种阿卡德方言。中巴比伦周边语(MPB)是我们的模型最难对付的方言。这与我们在样本中对这种语言的表述是如此之少(占所有观察结果的 3.9%)是一致的。
分类报告。来源:作者对 Kaggle 数据集的分析
主要外卖
在本文中,我们看到了如何创建一个定制的 N-gram 语言模型来预测古代美索不达米亚楔形文字的方言或语言。该模型是经典 N 元模型的一个版本,利用了概率链规则和马尔可夫假设。虽然简单,但该模型实现了 0.8 的 F1 分数。
我希望你喜欢这篇文章。如果你喜欢,你可以访问这个 Github 库中的代码。
如有任何反馈,请通过 LinkedIn或电子邮件联系我!
其核心是:图形数据库与关系数据库有什么不同?
通过谷歌搜索这个话题很容易找到一些答案,然而,正如我发现的,大多数答案只是简单地列出了好处
在当今永不停息的世界中,新数据不断产生,是大多数企业的基本资产。系统全天候可用,并且每天每秒都在生成数据。此外,数据生成和处理系统的复杂组合协作向用户提供服务。我最近多次遇到的一个问题——也是我仔细思考的结果——是:图形数据库有什么问题,它们有什么不同?通过谷歌搜索这个话题很容易得到一些答案,然而,正如我发现的,大多数答案只是简单地列出了好处。在这篇文章中,我想简单描述一下我对它们真正价值的理解——独立于大公司和技术影响者的营销幻灯片。
数据库维护和保存所有进入我们系统的先前处理过的事件的物化状态。
事件是进入我们系统的一个独立的、不变的信息。当我们建立一个数据库来处理和存储这样的事件时,我们必须做出各种设计决策:
- 我们想要存储什么数据?
- 是如何表现的?
- 我们在哪个抽象层存储数据?
- 我们希望处理哪些事件,以及如何将它们应用到我们的数据中?
例如:我们可以存储进入系统的原始事件,或者应用它们来更新我们的数据。
数据库有以特定方式存储数据的目的和原因。
例如,如果数据库充当面向用户的应用程序的持久层,以实时服务于用户请求,那么它应该包含一个表示,该表示保存可被特定请求集快速访问的数据。相反,对于需要考虑大量历史数据的统计业务问题,这可能不是最佳方法。
那么,图数据库和关系数据库有什么区别呢?随着图形数据库越来越受到许多公司的关注,并且大多数公司也有传统的关系数据库,我想在这里重点介绍这两个。
作者图片
关系数据库是实体优先的。
让我们从关系模型开始。关系数据库将数据存储在表中。表格代表一个实体。我称之为实体优先。方法是为一个表定义一个模式,然后在该表中只存储该特定类型的对象。因此,结构相似的数据存储在一起。
关系模型将关系存储为用户域中的数据。
在关系模型中,数据之间没有关系的概念。也就是说,您不能定义表之间的关系。为了在关系模型中链接数据,您必须显式地将关系建模到您的数据中。您无法区分实际数据和仅用于表示关系的数据。对关系建模的唯一方法是将其建模为表中的外键——作为实体的属性(一对一、多对一)或与附加表一起(一对多、多对多)。可以将映射表视为关系表,因此将关系视为实体。然而,它并不隐含在支持关系的技术中,而是我们在创造新的数据。这导致了一个基本的含义:关系数据库将外键存储为用户数据,即引用实体表中的另一个条目。因为引用是用户域中的数据,所以数据库不能有自动机制来管理它们——它们受制于用户逻辑。
作者图片
图形数据库是关系优先的。
相比之下,图模型对于实体(节点)和关系(边)有一个明确的概念,这使得它与众不同。因为我们可以直接定义实体之间的关系,所以我们不需要关心如何在我们的模式中显式地对它们建模。我们不需要了解外键,也不必编写如何存储它们的逻辑。我们定义一个实体和关系的模式,系统会处理它。如果我们想要对高度关联的数据建模,这有一个巨大的好处:实现可以有效地处理引用。图形数据库系统可以存储指向下一个相关实体的真实内存指针,而不是将额外的数据(引用)作为属性显式地存储在我们的数据表中。大多数图形数据库系统以类似于链表的结构存储数据。它们存储的是与相关数据的直接链接,而不是相似的对象。我会说他们是关系第一。
这两种方法中的上述差异导致了关于每一种都可以很好服务的用例的一些暗示。
图形数据库像面向对象语言一样存储数据。
由于关系数据库不包含关系的概念,我们需要将它们作为数据显式地建模到我们的模式中。这导致了与我们在大多数编程语言中使用的面向对象建模的差异。每个对象可以维护与其相关的其他对象的集合。这些引用通常是指向内存中对象的指针,我们不必显式地存储它们。我们也不需要在内存中找到具有外键属性的对象。因此,进行所谓的对象关系映射需要相当大的开销。
图形数据库像面向对象的语言一样存储数据——我们有指向相关对象的直接指针。因此,对象关系映射更加简单。
单个关系的遍历可以在恒定的时间内完成。
由于图数据库可以通过跟随内存指针从一个实体跳到一个相关的实体,我们称之为无索引邻接。我们不必在不同的表中查找外键(使用索引),或者更糟的是,在映射表中查找一个键,然后在第三个表中查找结果外键来跟踪关系。因此,单个关系的遍历可以在恒定的时间内完成。也就是说,它与存储在图形数据库中的数据大小无关。而我们必须扫描关系型索引中的一个——可能是多个——索引,而关系型索引随着数据的增长而增长。
就是感觉用 SQL 写多跳查询不对。
虽然确实可以在关系模型中对连接的数据和关系进行建模,但是一旦我们尝试使用 SQL 查询语言沿着多跳的路径前进,我们可能会觉得我们写下的东西并不是我们想要完成的事情。我们必须在某些条件下连接表,我们必须手动指定这些条件来查找相邻的数据——可能需要多次连接,因此会编写难看的嵌套查询。感觉很大,好像有很多开销正在发生。如果发生这样的事情,这通常是一个强烈的信号,表明我们正在使用一种不完全符合其设计的技术。我们不想连接整个表—我们想查找一个特定的数据点。
在图形数据库中,这看起来不同。因为它们被设计成基于连接结构来查询相关数据,所以它们提供了一种简洁而直观的语法来做到这一点。我们可以准确地指定我们想要查找的路径。没有连接条件或复杂的嵌套查询,没有映射表——只是我们想要找到的最简单的描述。
结论
图形和关系数据库在一个基本设计原则上是不同的:图形有关系的概念,而关系数据库没有。这就是为什么图形数据库可以更有效地管理相互关联的数据。尽管如此,两者都有其存在的理由:当分析接近单个数据点的整个上下文时,图形表现更好,使用起来更直观——可能有多次跳跃。但是,如果不需要探索高度连接和紧密连接的数据,关系模型可能同样可以很好地满足需求。
执掌数据科学、认识论和可知事物
流行阈值和贝叶斯定理入门
作者图片
- 宇宙是一个巨大而充满敌意的地方。作为人类,我们只能在这个无限小的空间中生存。我们的生存在一定程度上依赖于我们运用自己的智慧,做出理性选择以最好地适应环境的能力。
- 在很大程度上,智力是分类的自觉实践。
- 我们对事物、人、想法、感觉和实体进行分类,以避免危险,最大化我们的幸福,从而提高我们的生存能力。
- 我们的分类能力是归纳性的,因此受到贝叶斯定理的限制,这就造成了一个生存困境。
- 因此,鉴于我们对支配我们宇宙的规则的有限知识,当我们探索自然时,我们应该问这个问题:“我们所看到的,到底是什么?”
上面的序言,虽然过于简单和简化,但说明了一个无可争议的事实,即我们茁壮成长和生存的能力至少部分取决于我们的智力。尽管根植于我们的遗传密码及其在进化过程中提炼的潜力,我们的智力主要是通过对我们的世界进行推断并得出让我们能够最有效地导航的结论而获得的。但是这种推理过程有多准确和精确呢?事实证明——这取决于我们使用的推理类型。一方面,演绎推理声称,基于遵循明确定义和详尽的逻辑规则的前提,得出必然为真的结论。这种“自上而下”的推理在纯科学和应用科学中有许多应用——特别是逻辑和数学——从一系列基本原理中发展出一个完整的领域,并以绝对确定性得出内在一致的结论。虽然哥德尔的不完全性定理限制了第一性原理集的完备性、一致性和可判定性,但演绎推理中得到的结论是确定的。不幸的是,鉴于我们对支配我们宇宙和我们存在经验的基本原则的有限知识,生活很少是演绎的。相反,归纳推理是我们得出关于世界的结论的方法。归纳逻辑是一种推理方法,通过这种方法,一组观察结果被综合起来,得出一个普遍的原则——在这种情况下,结论是可能的——甚至经常是可能的——尽管不确定。这些结论的不确定程度取决于几个因素——但考虑到它们固有的不确定性——描述它们的语言本质上是统计的和概率的。将这一论点引向其逻辑结论——我们推测,我们绝对确定地了解任何事物的能力很可能是无法达到的。
贝叶斯定理
条件概率的贝叶斯定理方程。图片作者。
贝叶斯定理描述了基于与特定事件或观察相关的条件的先验知识的事件或观察发生的概率。贝叶斯方法的本质是提供一个数学模型,解释现有的信念如何根据新的证据而改变。值得注意的是,贝叶斯定理在生活的无数领域和方面都有应用,它是我们如何观察和与我们的世界互动的核心。
贝叶斯定理通过引入归纳逻辑的形式框架彻底改变了现代哲学,归纳逻辑是一种认知合理性的实用方法,作为一种扩展演绎逻辑定律的证明的方式,包括对归纳逻辑定律的证明。形式结构本身有两个主要元素:使用概率法则作为对理性信任度(或置信度)的约束,以及引入概率推理规则,即所谓的条件概率。
从数学上来说,贝叶斯定理的等式转化为给定事件或状态 B 时事件 A 的条件概率。上述关系等于给定事件 A 时事件 B 的概率乘以事件 A 与事件 B 的独立概率之比。虽然上述概念有些抽象,但应用于日常生活情况的具体示例可能有助于说明这一概念。
例如:
- 假设今天是九月的一个普通的星期二。在不知道其他情况下,今天下雨的概率有多大?你可以大胆猜测。就保证精度而言,这将是最糟糕的情况。同样,您可以根据您所在地理区域过去(比如说 10 年)的平均降雨天数来推断降雨的基准风险,然后根据今年迄今为止的降雨天数以及今年的剩余天数来推断今天的降雨可能性。现在——估计可能会非常不精确,因为有许多自由度我们没有考虑——但它仍然比猜测要好。毕竟,我们正在使用一些数据来获取知识。现在让我们通过引入新的“证据”或新的“数据”来“更新”我们的估计。说外面是阴天。今天下雨的可能性有多大*?当然,知道今天多云会增加下雨的可能性。使用贝叶斯方法,评估进一步的改进,直到我们能够获得更准确的信息,做出更精确的预测。这是贝叶斯方法的精髓——更多的信息等于更多(或更好、更精确)的知识。正如我们马上会看到的,流行阈值[1]限制了得出准确结论所需的必要证据数量——因此检索信息和新数据的过程不必是无限的。*
我们还可以描述一个医学筛查的常见例子:
- 根据居住国家的不同,女性从 40 岁或 50 岁开始接受乳房 x 光片和/或乳房超声波的定期乳腺癌筛查。乳房 x 光检查发现疑似乳腺癌病变的可能性有多大?在没有任何进一步信息的情况下,我们可以说,乳房 x 光片被解读为乳腺癌阳性的几率等于人群中乳腺癌的患病率。但是这种方法并没有考虑到女性的个体风险因素或症状。如果接受乳房 x 光检查的人有乳腺癌家族史怎么办?如果她感觉乳房或腋下有肿块怎么办?乳房 x 光片显示病变的机会随之增加。它增加的数量可以使用贝叶斯定理来计算。在这里,我们也观察到,当我们获得更多信息时,我们会更新我们的先验概率以检索新的风险估计,这无非是通过获得更准确的知识来完善我们的理解和更新我们的信念。
分类和混淆矩阵
混淆矩阵是一种总结分类算法性能的技术。它最基本的形式是画出一张 2x2 的表格,将我们试图了解的事物的真实状态/性质与我们观察到的预测进行比较。
混淆矩阵或 2x2 表。图片作者。
我们估计的“预测值”或“精确度”取决于几个变量:我们用来观察和预测的工具有多好,但更重要的是,我们试图了解的东西有多普遍。后一点就是所谓的基础利率谬误,它直接来自贝叶斯统计。
观察工具
我们用来探索世界的观察工具是无限的。给定适当的上下文,任何东西都可以用作获取知识的工具。比方说,你发现自己在一片土地上——一眼望不到边,空无一物。你会被问到这样一个问题:在过去的某个时候,你站的地方附近有一栋建筑的可能性有多大?甚至尝试一个猜测可能看起来令人生畏。如果在第二种情况下,除了你面前有一堵砖墙之外,一切都是一样的,那会怎么样呢?这能保证那里曾经有过建筑吗?不。这是否增加了曾经有过的可能性?是的,它确实如此,尽管砖墙在阐明建筑物的存在方面缺乏敏感性和特异性。从这个意义上说,这堵墙是一种观察工具,尽管它提供的信息质量很差,但它增加了人们了解世界的潜力。
从逻辑上讲,并不是每个工具都能有效地提供有用或准确的信息。这些工具的特征可以最好地描述为它们区分真实情况和虚假情况的能力,以及它们在预测中在各组之间产生多少重叠。他们的表现最好通过混淆矩阵来观察。
下面给出一个混淆矩阵的例子。尽管这个例子试图在医学筛查的背景下对疾病状态进行分类,但是对任何个人、概念、想法、主题或物理实体的任何分类都遵循相同的规则。用于观察的工具的灵敏度或“真阳性率”(在信息检索中也称为回忆*)被定义为总阳性(真预测和假预测)中真阳性的数量,而特异性或“真阴性率”(在信息检索中称为选择性)被定义为总阴性(真预测和假预测)中真阴性的数量。作为一个工具,混淆矩阵作为一个二元分类系统,允许我们计算上述参数。*
混淆矩阵中灵敏度(真阳性率)和特异性(真阴性率)参数的方程式。图片作者。
一个极限问题
在评估分类工具的有效性时,如果我们只考虑其敏感性和特异性参数,就会出现一个重大问题,因为这必然要求您在参与分类过程之前了解您试图分类的任何内容的真实状态。这种障碍在机器学习(ML)和人工智能(AI)中经常观察到。例如,你向计算机提供一组不同颜色的圆形水果的图像。你试图开发一个神经算法,在这个场景中的分类工具,来识别这个数据集中的苹果。即使算法非常优秀,它也需要一个黄金标准来比较它的发现。这产生了两个问题——首先,如上所述,您需要提前知道哪些水果是真正的苹果,以确定算法是否得出了正确的结论,这逆转了分类过程,并使其变得没有意义(如果您已经知道哪些是真正的苹果,为什么需要对它们进行分类?).但是第二,也许更重要的是,这些参数没有解释基本利率谬误。因此,我们需要其他参数来进行正确的认知归纳推理,并获得关于世界的更准确的知识。
精度/预测值
*基本比率谬误被定义为在主观判断事件的条件概率时,没有考虑事件的基本比率或先验概率的认知失误,为了解释基本比率谬误,需要不同的参数。这里是阳性和阴性预测值进入等式的地方。这些新的参数是流行率相关的,并通过以下问题在其适当的年表中处理分类过程:*在预测观察值的数量中,有多少对那些观察值的确认将被证明是正确的?不要问敏感度问的是什么:在确认的观察结果中,有多少是首先被正确预测的?前一个问题的答案是所谓的正预测值,或精度。观察工具的精度取决于它试图观察的事物有多普通。
混淆矩阵中阳性(精确度)和阴性(选择性)预测值参数的方程式。图片作者。
我们试图观察的事物的普遍性与其观察工具的精确度(阳性预测值)之间的比例由以下等式给出——贝叶斯定理的另一个直接结果:
其中ρ(ϕ)is 是精确度,a 是灵敏度,b 是特异性,ϕ是流行率。图片作者。
很容易观察到,上述比例不是线性的。换句话说,普及率的提高并不意味着精确度的同等提高。也许用不同的灵敏度和特异性值来图示这种关系更有用。
作为患病率函数的分类工具的精确度或阳性预测值。曲线下的面积越大,工具的性能越好。在这种情况下,红色的工具比蓝色的好,而蓝色本身又比黄色的工具好。图片由尼尔·d·戈尔茨坦提供。许可用于商业用途。(https://www . goldsteinepi . com/blog/relationships-between-observed-outcomes-and-true-prevention/)。
上述曲线的一个显著特征是,每条曲线上都有一个拐点,在拐点以下,精度下降最快。在这些低流行水平下,该测试可能并不那么可靠——在其预测中产生更多的假阳性而不是真阳性。我们把这个拐点称为“流行阈值”,它在决定世界上什么是可知的方面起着至关重要的作用。
流行阈值
如上所述,流行阈值[1]指的是流行水平,低于该水平时,测试的精确度下降得更快。从认知的角度来看,这意味着什么?这意味着,在这种情况下,对于一个真实的信号,我们会得到大量的噪声,或者假阳性预测。根据我们试图观察或分类的东西的流行程度,我们不会获得主要是纯信号——因此不可避免的问题是:鉴于贝叶斯限制将流行程度与我们的预测能力联系起来,以及鉴于我们试图观察的东西的低流行程度而做出的错误观察的数量——我们能够绝对确定地真正知道任何事情吗?答案很可能是否定的——除非在一个非常特殊的情况下,观察工具的特异性是 100%,在这种情况下,根据上面的等式,精度将等于 1。有多少观察工具的特异性是 100%?考虑到口译翻译过程中工具功能的自然变化、人为错误和信号丢失(机器的输出需要由得出这些结论的人来解释——这个过程也容易出错),很可能没有。上述事实很有趣,并且对我们观察可知世界的确定性有重要的哲学和认识论意义。然而,硬币的另一面(或在这种情况下,阈值)同样有趣。注意第一条红色曲线中超过患病率阈值的几乎水平的红线。图表的这一部分是什么意思?超过流行阈值,对于具有足够好的灵敏度和特异性参数的工具来说,增加流行对提高精确度只有很小的影响。也就是说,当我们已经收集了足够的信息来做出准确的预测时,增加信息量可能不会以显著的方式增加精确度。针对流行阈值校正信息检索的过程可以减少计算时间并减少不必要的资源使用。有鉴于此,计算工具流行阈值的等式如下,其中 a 是灵敏度, b 是特异性:
患病率阈值的等式(a =敏感性,b =特异性)。图片作者。
从图形上看,流行阈值可描述如下:
流行阈值线(绿色)将图形分为两个区域。在它之下,精确度水平随着流行程度的降低而下降。它上面的区域表明,添加额外的信息可能不会显著提高精度。图片作者。
请注意绿色垂直线是如何在图形的拐点或最大曲率点处截取图形的。这是流行阈值。在它之下,精确度水平随着流行程度的降低而下降。上面的区域表明,添加额外的信息可能不会显著提高精度[2]。
结论
哲学、认识论和贝叶斯理论之间的关系提供了一个奇妙的——也是令人谦卑的——工具来最好地理解我们对世界的推理理解的局限性。基于数学,我们得出一个不可避免的事实:我们不可能绝对确定地知道任何事情。也就是说,尽管有巨大的影响,流行阈值是一个简单的指标,它决定了工具的精确度以及我们对现实的理解开始失效的流行水平。开发更好的观察工具并获得足够的信息以保持在流行阈值以上,对于我们在世界上的观察得出更可靠的结论是必要的。
参考文献
- Balayla,2020。患病率阈值(ϕ e)和筛查曲线的几何形状。 Plos one , 15 (10),p.e0240215
- 巴拉伊拉,j . 2021。论筛选悖论的形式主义。 Plos one , 16 (9),p.e0256645。
ATOM:一个用于快速探索机器学习管道的 Python 包
优化建模自动化工具(ATOM)是一个开源的 Python 包,旨在帮助数据科学家对受监督的机器学习管道进行快速探索和实验。
介绍
在项目的探索阶段,数据科学家试图为他的特定用例找到最佳的管道。这通常包括应用标准的数据清理步骤、创建或选择有用的特性、尝试不同的模型等。测试多个管道需要许多行代码,将所有代码都写在同一个笔记本上通常会使代码变得冗长而混乱。另一方面,使用多台笔记本电脑会增加比较结果和保持概览的难度。最重要的是,为每个测试重构代码可能会很耗时。您执行过多少次相同的操作来预处理原始数据集?有多少次你从一个旧的存储库中复制并粘贴代码,以便在一个新的用例中重用它?
ATOM 旨在帮助解决这些常见问题。该包充当整个机器学习管道的包装器,帮助数据科学家快速找到解决其问题的好模型。避免无休止的导入和文档查找。避免反复重写相同的代码。只需几行代码,现在就可以执行基本的数据清理步骤,选择相关功能,并在给定数据集上比较多个模型的性能,从而快速了解哪种管道最适合当前任务。
原子可能采取的步骤示意图。
装置
通过pip
轻松安装 ATOM 的最新版本:
$ pip install -U atom-ml
或者通过conda
:
$ conda install -c conda-forge atom-ml
使用
理解软件包能为您做什么的最简单的方法是通过一个例子。在本例中,我们将:
- 加载数据集。我们将要使用的数据是来自 Kaggle 的澳大利亚天气数据集的变体。可以从这里下载。这个数据集的目标是预测明天是否会下雨,在目标列
RainTomorrow
上训练一个二元分类器。 - 分析要素的分布
- 估算缺失值
- 对分类列进行编码
- 对数据进行逻辑回归和随机森林模型拟合
- 比较两种模型的性能
我们将用不到 15 行代码完成所有这些工作!让我们开始吧。
加载数据集
我们开始从 csv 文件加载数据。
import pandas as pdX = pd.read_csv("weatherAUS.csv")
X.head()
ATOM 有两个主要的类,用于初始化管道:
- ATOMClassifier:用于二进制或多类分类任务。
- ATOMRegressor:用于回归任务。
对于这个例子,我们使用 ATOMClassifier。这里,我们用加载的数据集初始化一个 atom 实例。
from atom import ATOMClassifieratom = ATOMClassifier(X, y="RainTomorrow", test_size=0.3, verbose=2)
此外,我们指定 atom 应该以 70%-30%的比率分离训练和测试集中的数据集。
<< ================== ATOM ================== >>
Algorithm task: binary classification.
Dataset stats ====================== >>
Shape: (142193, 22)
Scaled: False
Missing values: 316559 (10.1%)
Categorical features: 5 (23.8%)
Duplicate samples: 45 (0.0%)
---------------------------------------
Train set size: 99536
Test set size: 42657
---------------------------------------
| | dataset | train | test |
|---:|:-------------|:------------|:------------|
| 0 | 110316 (3.5) | 77205 (3.5) | 33111 (3.5) |
| 1 | 31877 (1.0) | 22331 (1.0) | 9546 (1.0) |
我们收到的输出是数据集的简短摘要。我们可以立即看到数据集中缺少值和分类列。
分析数据集
将数据集加载到 atom 实例后,我们就可以开始分析它了。ATOM 为此提供了各种情节和方法。例如,为了绘制特征相关矩阵,我们可以键入。
atom.plot_correlation()
请注意,该图会自动忽略分类列。我们还可以使用Kolmogorov–Smirnov测试来调查特性的分布。
atom.distribution("Temp3pm")
ks p_value
weibull_max 0.0173 0.0053
beta 0.0178 0.0036
pearson3 0.0215 0.0002
gamma 0.0216 0.0002
lognorm 0.0217 0.0002
norm 0.0230 0.0001
invgauss 0.0649 0.0000
triang 0.0696 0.0000
uniform 0.1943 0.0000
expon 0.3376 0.0000
weibull_min 0.7675 0.0000
让我们绘制特征分布图,看看它是否确实符合威布尔 _ 最大值分布。
atom.plot_distribution("Temp3pm", distribution="weibull_max")
数据清理
既然我们已经了解了如何使用包来快速分析数据集,我们可以继续清理它。既然 sklearn 模型不接受缺失值,我们就应该去掉它们。我们可以使用 atom 的 impute 方法做到这一点。
atom.impute(strat_num="median", strat_cat="most_frequent")
所选择的参数规定,对于数字特征,我们用列的中位数进行估算,对于分类特征,我们用列的最频繁值(众数)进行估算。将数据集作为实例的一部分的好处之一是,我们不需要调用 fit 或 transform。基础转换器将自动适应定型集,并转换整个数据集。
Fitting Imputer...
Imputing missing values...
--> Dropping 702 samples for containing less than 50% non-missing values.
--> Imputing 351 missing values with median (12.0) in feature MinTemp.
--> Imputing 169 missing values with median (22.6) in feature MaxTemp.
--> Imputing 1285 missing values with median (0.0) in feature Rainfall.
--> Imputing 60160 missing values with median (4.8) in feature Evaporation.
--> Imputing 67131 missing values with median (8.5) in feature Sunshine.
--> Imputing 8667 missing values with most_frequent (W) in feature WindGustDir.
--> Imputing 8609 missing values with median (39.0) in feature WindGustSpeed.
--> Imputing 9402 missing values with most_frequent (N) in feature WindDir9am.
--> Imputing 3106 missing values with most_frequent (SE) in feature WindDir3pm.
--> Imputing 2096 missing values with median (21.1) in feature Temp3pm.
--> Imputing 1285 missing values with most_frequent (No) in feature RainToday.
为了对分类列进行编码,我们使用 atom 的编码方法。我们可以从类别编码器包中选择任何估计器来进行转换。
atom.encode(strategy="LeaveOneOut")
Fitting Encoder...
Encoding categorical columns...
--> LeaveOneOut-encoding feature Location. Contains 49 classes.
--> LeaveOneOut-encoding feature WindGustDir. Contains 16 classes.
--> LeaveOneOut-encoding feature WindDir9am. Contains 16 classes.
--> LeaveOneOut-encoding feature WindDir3pm. Contains 16 classes.
--> Ordinal-encoding feature RainToday. Contains 2 classes.
就这样,所有缺失值都被估算,分类特征用数值编码。atom 管道中的数据可以通过dataset
属性随时访问。
atom.dataset.head()
模特培训
既然数据集已经清理完毕,我们就可以开始拟合模型了。在这个例子中,我们将评估一个逻辑回归和一个随机森林模型在分类问题上的表现。所有可用的型号及其相应的缩写可在文档中找到。同样,一个简单的命令就足够了。
atom.run(models=["LR", "RF"], metric="f1")
**注意:**这是一个极简的例子。此外,还可以指定模型参数、使用多个指标、执行超参数调整和训练定制模型。详见文件。
Training ===================================== >>
Models: LR, RF
Metric: f1 Results for Logistic Regression:
Fit ---------------------------------------------
Train evaluation --> f1: 0.4716
Test evaluation --> f1: 0.4658
Time elapsed: 0.201s
-------------------------------------------------
Total time: 0.201s Results for Random Forest:
Fit ---------------------------------------------
Train evaluation --> f1: 0.9999
Test evaluation --> f1: 0.5434
Time elapsed: 14.976s
-------------------------------------------------
Total time: 14.976s Final results ========================= >>
Duration: 15.177s
------------------------------------------
Logistic Regression --> f1: 0.4658
Random Forest --> f1: 0.5434
这里发生了几件事。使用所提供的度量,在训练集上训练这两个模型,并在测试集上评估这两个模型。然后,为每个模型创建一个对象,并作为属性附加到atom
实例。它们通过模型的首字母缩略词(如随机森林模型的atom.RF
)来调用,并可用于进一步分析结果。
评估结果
最后,我们想要比较模型的性能。为了分析单个模型,我们使用前面提到的 model 子类。例如,为了检查随机森林的特征重要性,我们键入。
atom.RF.plot_feature_importance(show=10)
用于拟合数据的实际估算器(来自 scikit-learn 包),可通过模型的estimator
属性访问。
atom.RF.estimator
RandomForestClassifier(n_jobs=1)
但 ATOM 的真正强大之处在于,我们可以轻松地比较其管道中所有模型的性能。例如,通过绘制 ROC 曲线。
atom.plot_roc()
或者评估他们在多个指标上的表现。
atom.evaluate()
结论
ATOM 在机器学习项目的探索阶段协助数据科学家。它能够分析数据,应用标准的数据清理步骤,并在几行代码中比较多个模型的性能。但这还不是全部!ATOM 还可以帮助机器学习中的其他常见任务,例如:
- 检测并移除异常值
- 处理不平衡的数据集
- 比较在不同管道上训练的模型
- 执行超参数调谐
- 使用集成技术组合模型
- 还有更多…
欲了解更多信息,请查看该项目的 GitHub 或文档页面。对于 bug 或特性请求,请不要犹豫,在 GitHub 上打开问题或给我发电子邮件。
原子神经网络、计算的未来、量子过程和意识——伯特·卡彭教授深度访谈
马库斯·斯皮斯克在 Unsplash 上的照片
1987 年,卡彭教授获得了洛克斐勒大学的理论物理学博士学位。在飞利浦进行了两年的研究后,他于 1989 年回到学术界。为了更好地了解人类,他将研究领域转向了神经网络和机器学习。
Kappen 教授的研究兴趣在于统计物理学、计算机科学、计算生物学、控制理论和人工智能之间的接口。多年来,他一直认为计算、内存和能耗将是人工智能未来发展的主要挑战。Kappen 教授没有被这些挑战限制他的研究,而是最近在《自然》杂志上发表了一篇革命性的文章,题为“能够自适应的原子玻尔兹曼机器”。在这项工作中,他展示了在核水平上训练神经网络的可能性。这一发现可能是新一代算法的先驱,只消耗当前模型能量吸收的一小部分。在这次采访中,我们将讨论 Kappen 教授的发现,他的发现的潜在影响,以及我们是否可以在他的发现和人类之间建立联系。
Kappen 教授,您主要认为自己是物理学家还是计算机科学家?
那是一个困难的问题。我的大部分出版物都在机器学习期刊和会议上。从这个意义上说,我是一名计算机科学家。然而,我最常用的方法和方法论源于物理学。所以,我最终认为自己主要是一个物理学家。
例如,我的大部分工作是在近似推理上,它有效地近似了在非常大的概率模型中低阶统计的计算。这个问题由变分法和蒙特卡罗采样等各种技术主导,都植根于物理学。在我的大部分工作中,我将这些技术从物理学界转移到机器学习和人工智能领域。
你为什么决定从物理学转到计算机科学?
我攻读了理论高能粒子物理学的博士学位,并一直对该领域复杂的数学着迷。它有令人难以置信的美丽,我们有令人难以置信的成就,了解它是一种特权。
同时,我觉得它离我个人的日常生活很遥远。
在攻读博士学位期间,我一直对我的大脑是如何工作的非常感兴趣。“我”的概念和问题“我是谁?”一直让我着迷。这个问题可以用大脑、神经科学、AI、哲学的知识来回答。
我从粒子物理学转向人工神经网络,主要是受这种魅力的驱使。我发现这是一个美丽的领域,因为你正在以某种有限的方式模拟模仿人类的系统。因此,这是一种了解你自己的尝试。
人工智能的未来是否在物理学和计算机科学的交叉点上?
很难预测未来。例如,我没有看到深度学习的成功,尽管这些技术从 80 年代就已经存在了。令人惊讶的是,我们使用大量数据和计算能力获得了如此惊人的性能。也就是说,我认为这两个领域的交叉有着巨大的潜力。但是利润也可以来自其他各种各样的学科。
许多人声称,我们应该利用大脑的知识来帮助人工智能进步。这是一个令人信服的想法,但在实践中很难做到。对人工智能和新技术做出贡献的新颖大脑机制的数量非常少,如果不是没有的话。尽管如此,神经科学将激励我们进行这项研究,因此仍然与人工智能的未来相关,工程学和物理学的新见解也是如此。
总之,我认为有许多成功的道路和许多重要的贡献。当然,我特别感兴趣的是机器学习和物理学之间的接口。
我最近的工作就是这种界面的一个例子,在这里我们让物理学处理大量的计算问题。我们可以利用物理学来识别你基本上免费获得的属性,并将其用于我们的目的。
让我们谈谈你最近的工作。你在《自然》杂志上的论文有什么发现?
这是与来自奈梅亨(IMN)凝聚态物理研究组的 Alexander A. Khajetoorians 教授的合作。
他是世界上操纵表面单个原子的领导者之一。你知道 IBM 用 35 个原子写名字的老照片吗?他也可以做这样的事情。最近,他发现某些原子(在这种情况下是钴)在黑磷衬底的表面上可以有两种状态。本质上,这意味着这些原子与它们的基质相互作用;当电子云在原子表面机械移动时,原子周围的电子云可以有两种形态。你可以把这些原子想象成在两种状态下实现一个随机比特,原子的这种’舞蹈 s '可以作为电压来测量。
早些时候,IMN 发现,如果你把许多原子放在表面上,它们会以不同的时标跳舞,一些跳得很慢,而另一些跳得很快,并且是一种复杂的模式。这一发现激励我们与学习建立联系。
大脑可以被建模为一个由神经元和连接组成的神经网络,你们称之为突触。对于人脑中给定的突触连接,神经元实现某些功能,如感知或运动控制。本质上,当突触改变到其他状态时,学习就发生了。虽然神经元在很短的时间尺度(毫秒)内发生变化,但突触的变化要慢得多。后者可能需要几分钟、几小时、几天或更长时间(想想婴儿走路需要的时间)。
就像跳舞的原子一样,你可以把神经网络想象成由两种类型的变量组成的网络:一些移动得非常快,一些移动得非常慢。
在我们的工作中,我们在这个材料上展示了这两种类型的时标。时间尺度的分离是巨大的:快速变量在毫秒内变化,而慢速变量可能需要几秒、几分钟甚至更长时间才能变化,就像大脑一样。这种时标分离可以被认为是实现了一种记忆形式:慢变量随着时间的推移而改变,并改变了自旋阵列中快变量之间的连接性。
我们在一个简单的装置中建立了这个学习过程,在这个装置中我们排列了七个原子。
三个原子是我们的快速变量,神经元,四个慢速变量控制连通性和阈值,就像在经典神经网络中一样。因此,这个系统可以形式化为玻尔兹曼机器。
“我们在原子尺度上进行计算,接近能量消耗的下限.”
为什么这一发现如此重要?
它展示了如何让物理为你工作,这与传统的神经形态计算有着明显的区别。在神经形态计算中,人们构建一种充当神经元的材料,并在 CMOS 器件上物理实现;整个网络被设计成以你想要的方式运行。相比之下,我们并没有用我们的方法来设计一个网络,而是在材料出现和使用时观察它们的属性。我们的方法有巨大的扩展潜力。
我们只实验了七个原子。然而,这可以扩大到半导体行业的更大系统。通过掺杂材料,你可以在一小片材料中放大到数百万或数亿个自旋,并得到类似的“双时标行为”。
然而,我们面前仍然有大量的问题。我们还没有解决 I/O 问题;如何读取来自原子的信号?虽然还有很多事情要做,但原则上,这表明你可以使用一种可以自己学习的材料,而不是设计来这样做的。它还能够实现大规模应用,并且非常节能;我们在原子尺度上进行计算,接近能量消耗的下限。
“需要一千台计算机(每台都以千瓦级运行)来解决 AlphaGo,其总规模为兆瓦级。另一方面,大脑在大约 25 瓦的功率下工作(类似于灯泡)。我们的方法消耗的能量将低于大脑吸收的能量,因为翻转一个原子所用的能量非常低。”
与我们目前的网络相比,原子能网络可以节省多少能源?
这很难说,我也不能给你任何数字。主要的瓶颈是将模拟信号转换成数字信息的外围硬件。举个例子:需要 1000 台计算机(每台都以千瓦级运行)来解决 AlphaGo,其总量为兆瓦级。另一方面,大脑在大约 25 瓦的功率下工作(类似于灯泡),这是一个巨大的差异。我们的方法消耗的能量将低于大脑吸收的能量,因为翻转一个原子所用的能量非常低。但是,外围硬件的消耗也需要添加到消耗中
所以它节省了大量的能源。它是否也比当前的计算更快?
不会,但是(真正的)大脑也不是很快。生物细胞中动作电位的产生通常需要几毫秒(千分之一秒)。在现代计算机硬件中,这不会很快,因为你有时钟实例进入千兆赫(十亿分之一秒)。从这个意义上说,大脑是很慢的,我们的材料也不是很快。然而,我们的方法将是高度并行化的,而不是提高时钟周期的顺序过程。此外,我们可能会改变时间尺度来加快计算速度。然而,这不是我们目前的重点,因为我们正致力于时间尺度的分离。
还有哪些问题需要解决?
到目前为止,我们通过以特定的方式重新排列原子获得了时标的分离。我们的目标是在没有这种特殊几何排列的情况下获得时间刻度间隔。如果我们找到合适的原子来做这件事,我们将有更大的灵活性,因为我们可以把原子撒在基底上。在这种情况下,要获得有趣的结果,它们在哪里并不重要。
我们面临的另外两个挑战是:
- 扩大规模——在某种程度上,我们需要将其嵌入半导体设备。
- I/O 问题——如何将输入信号作为高维数组转换到某种傅立叶基,并在傅立叶模式下进行交互。
这两个都是公开的问题,我希望十年后才能看到这种实用的设备。
全球是否会有更多的研究小组关注这个课题,我们可以期待什么样的变化?
迄今为止,我们所做的一切都是独一无二的。我不能说有多少团体会关注这一点,但最初的反应是非常积极的。许多人对此很感兴趣,在凝聚态团体中,这也是一件新鲜事。
基于我们的工作,我们很可能会看到物理学和算法之间的相互作用发生变化。
对于神经形态计算,想法是无论一个人有什么软件想法,它都将被其他人构建到硬件中。硬件社区则专注于更快和/或更便宜地获得相同的功能。但是因为硬件是根据软件需求调整的,所以理论/算法社区对此兴趣不大。
我们的工作遵循不同的动力。在我们的例子中,我们评估物理学的哪些特性可供我们使用,以及它们如何服务于算法问题。然后,我们相应地创建新的算法。从这种动态变化中,我期待一套全新的不同算法的诞生。在量子领域也会遇到类似的动态,我们将根据硬件的量子特性来设计算法。
你认为这是从自下而上的方法到自上而下的方法的过渡吗?算法不再领先,硬件反而领先?
是的,在某种程度上,但它仍然是自上而下的。要了解自顶向下方法的局限性,让我们以大脑为例。大脑 90%是由水组成的,所以完全自上而下的方法需要我们的硅设备也是由水制成的,但事实并非如此。所以很明显,大脑原理不能完全实现,我们需要不同的材料。然而,使用不同的硬件可能会导致次优,因为大脑针对其自身类型的硬件进行了优化。
与此同时,大脑中的一些原理是可靠的和通用的。一个例子是本地计算;在所需变量存在的情况下执行本地计算比来回传送数据更有效。从算法上来说,这是一个具有挑战性的约束。此外,随机性在实践中也发挥了作用,理论上有一个论点,即随机系统比没有随机性的系统学习得更好。
总之,自上而下的原则可以帮助你选择自下而上的方法。
玻尔兹曼机器是一种无监督学习的形式。你也能在原子水平上创建监督算法吗?
是的。一般来说,无监督学习可以实现监督学习。你可以把你的位的 n-1 作为输入,然后第 n 位就是你训练所依据的输出。训练之后,你箝位 n-1 输入并查看第 n 位的值。
在我们最近关于量子玻尔兹曼机器的工作中,我们证明了这是可行的。此外,当使用 quantum 变体时,您可以获得一种功能,可以学习比传统的 Boltzmann 机器更多的问题。例如,假设你想学习一个 XOR-或奇偶校验问题(非线性)并用 n-1 个输入进行训练,第 n 个变量是输出。对于这些问题,经典玻尔兹曼机器仅学习线性分隔符,因此,没有隐藏变量的无监督方案不能学习正确的参数。然而,当使用只有可见单位的量子玻尔兹曼机时,你已经可以学习 XOR 问题了。这种可能性表明,量子设备已经可以“只”用一种非监督算法来执行复杂的监督学习。
一些人将意识与量子过程联系起来
让我们把人类和计算机联系起来;我们能从这些算法中更好地了解人脑吗?
此时此刻,从算法上理解人脑还很遥远。在过去的三十年里,我一直在寻找答案,如何用算法术语解释人类的思想和情感,以及我们为什么热爱音乐、艺术和美丽。
对我来说,还没有一种数学描述是令人满意的。例如,为了对音乐感知进行建模,你可以把它描述为一个隐马尔可夫模型,并且可能得到一个糟糕的或者好的表现。但不管结果如何,它并没有解决我如何在音乐中发现美,因为它与音乐没有任何联系。这些方法只是一堆公式,它们不能帮助我理解当我看到大美时我的体验。我们可以用算法术语来理解感知,但那些公式并不能解释我们意识的个人体验。这是一个复杂的话题,我的结论是没有算法方法足以理解意识。
罗伯特·M·皮尔西格的《禅与摩托车保养艺术》这本书给了我很大的启发。主角是一名英语老师,教一班学生英语写作。他对他们的平庸感到沮丧,并质疑如果学生遵循这些规则,设计一套规则来产生高质量文本的可能性。他发现不存在这样的规则系统,也不能写下来。因此,他总结出规则中无法捕捉到的高质量现象的存在。由于规则是算法,自然中存在某些我们无法用算法术语捕捉的概念。
我们看到的人工智能的一个问题是,它非常机械。从逻辑上讲,如果你继续遵循理性思维,你就停留在机械思维、算法和基于规则的系统的领域内。那样的话,你永远不会明白什么是意识(就像老师无法描述质量一样)。
哲学家丹尼尔·丹尼特(和许多其他人)声称意识是不存在的,是附带现象。同样,许多科学家也在与意识现象作斗争。他们工作的前提是,无论他们研究什么,都需要用理性的术语来描述;如果它不能被理性地研究,它就不能成为科学研究的主题。因此,在科学意义上,你可以说它不存在。
但是很明显,意识是存在的,因此我们需要用不同的方式来对待它。
我对量子计算的兴趣源于我解决意识问题的努力。我没有证据表明量子计算会提供答案。然而,算法思维有其局限性,其他任何东西都不会削减它。
我对这是否可能持开放态度。但是世界是量子的,我为什么不去尝试呢?
与我之前提到的科学家相反,有些人将意识与量子过程联系起来。这些链接令人着迷和兴奋,但也容易受到批评,充满了问题。例如,我们的量子计算机必须在非常接近绝对零度的温度下运行;否则所有的量子效应都被破坏了。那么量子过程是如何在大脑中运作的呢?大脑 37 摄氏度,潮湿,嘈杂;任何量子过程都有可能被扼杀,不可测量。
同时,有一些证据表明量子效应可能在生物学中发挥作用。各种论文提出了植物内的光合作用是基于量子效应的观点。其他人认为迁徙鸟类的磁罗盘也与量子效应有关。因此,在生物系统中,量子效应可以在室温下运行,这并不完全令人吃惊。但是很明显,我们不知道它是如何工作的,我对探索这些方向很感兴趣。
如果我们发现量子过程发生在大脑中,我们对大脑的理解会有什么变化?
量子过程有一个与经典思维相背离的显著特征;量子世界是整体的,不是还原论的。意识也不是还原论。然而,人类非常熟悉还原论的观点。为了理解事物是如何工作的,我们把它分解成几个部分,研究这些部分并理解它们之间的相互作用。基于这个过程,我们相信我们了解它是什么,它由什么组成。
这是一种非常普遍的方法,而且在科学领域已经证明非常成功。所有经典物理学也是还原论的;你有粒子、属性和相互作用,这符合我们对世界的经典理解。但是在量子世界里,事情就不一样了。您不能将特定属性分配给单个对象,因为这些对象的属性在它们交互的对象之间是共享的。因此,如果您有两个对象,您不能为它们中的任何一个分配属性,因为它们都是环境的函数。因此,量子世界不能通过还原论的方案来接近。
这是一种整体主义,我觉得很有吸引力。
量子力学的主要贡献者之一是大卫·玻姆。在他关于量子力学的教科书中,他用了整整一节来阐述量子过程和思维过程之间的相似性。他描述说,根据量子理论,你一测量到某样东西,你就与之发生了相互作用。一旦你与它互动,你就已经改变了系统。因此,你不能单独观察一个量子系统,因为你一观察到它就改变了它。它会变为特定状态,在测量后,您所知道的只是测量后的状态,但它不会告诉您系统在测量前的状态。
玻姆接着用思维过程进行类比。如果有人问你在想什么,你的想法会随着他们转向这个问题而改变。在那之前,你没有在思考问题,而现在你的思考过程是伴随着问题后的想法。这本书详细阐述了经典思维与逻辑的关系,以及量子逻辑可能是一个大脑过程。这一部分很吸引人,只有五页。回答你的问题,这些量子特征将是描述我们思维过程的一种方式。
所以现在我们必须证明量子过程可以在大脑中发生?
一种方法是提出量子力学是大脑的一种功能。然后你需要让它在 37 度的嘈杂环境下工作。但相反,你也可以做类似量子的处理,看看量子力学提出的概率逻辑。这个逻辑不同于经典逻辑,因此你会得到偏差。例如,贝叶斯法则在量子逻辑中并不成立,因为你会得到额外的术语。另一种方法是采取务实的观点,假设量子过程在大脑中。在这种情况下,我们可以承担该视图的后果,而不必关注实现。这样做,我们就可以用量子概率框架来描述各种情况。
一个特别的例子是’量子认知’,人们试图使用这种量子形式主义作为人类非理性行为的数学描述。众所周知,人们不遵循贝叶斯法则。也许量子修正项可以帮助解释人们行为中对贝叶斯法则的偏离。
如果我们发现自己在未来能够量化意识,那会是你探索理解人类大脑的最后一块拼图吗?
我想是的,但是我们必须首先证明这是真的。这种非还原论观点的整体图景与某人对美和艺术的感知有关。我拒绝那种可以建造一个经典装置来解释我如何感知美的想法。但是我可以想象一个量子设备可以用它的非还原论的整体特性做到这一点。
如果我们发现自己成功地做到了这一点,那将是惊人的,是真正的突破。但是现在,我们不知道这是否可能,我认为这值得研究。
我们的采访已经到了尾声;你有什么遗言吗?
我们的世界、社会和人民深受世界科学观的影响。西方的科学世界观是还原论的。遵循这种还原论的观点非常成功,并导致了许多成就,如工业革命和我们所有的技术。
同时也不给非物质方面留有余地。如果世界是物质的,你也是物质的,你和我都是精密的机器人,这是很难逃脱的结论。直到五年前,我自己也非常相信这个想法,因为我一直是一个务实的科学家,现在仍然如此。但这种观点暗示,任何一种无法用科学术语解释的外围思维都是不存在的。如果你认真对待这一科学观点,你可能会得出结论,精神信仰、感情或种族生理学不存在,因为我们无法测量它们。
说到底,我们只是一台复杂的计算机,这种观点是一种迷人的想法,正潜移默化地影响着我们所有人。它影响我们看待自己的方式,也影响我们看待社会的方式。如果我是机器,你是机器,我们都只是一堆机器。这是一个纯粹的唯物主义观点,很快导致一个纯粹的唯物主义社会,在那里我们无法用物质来解释的事情失去了重要性。这是经典物理学对我们社会的潜移默化的影响。意识到这一点很好,我们应该超越这一点。
这次采访是代表比荷卢人工智能协会进行的。我们汇集了来自比利时、荷兰和卢森堡的人工智能研究人员。
ATP 网球聚类分析
利用聚类分析分割网球运动风格
瑞安·塞尔在 Unsplash 上的照片
近年来,几乎所有的运动都是分析革命的一部分。《Moneyball》是奥克兰运动家队总经理比利·比恩的故事,他开创了一种数学方法来进行球探,随着这部电影进入公众视野,分析已经广泛传播到各种体育运动中:三分革命的篮球,迈克尔·洛佩兹(Michael Lopez)举办的“大数据碗”等活动的足球,甚至是英超联赛,利物浦在分析方面成为联盟领导者,帮助利物浦夺得联盟冠军。棒球是这项运动的自然起点,因为它的特点是 1 对 1 的比赛,投手对击球手,这使得量化个人价值和分离队友的积极和消极影响更加容易。人们可能会认为类似的创新也发生在网球上,这是另一项以 1 对 1 互动为特征的游戏,然而,网球在分析方面远远落后于其他运动。网球迷最近接触到的唯一先进的分析方法是 IBM Watson 的“比赛关键”,它强调了每个球员确保胜利的最重要的统计数据,可能来自基于树的方法。网球分析在公共领域的进步可以完全归功于杰夫·萨克曼,网球分析的比尔·詹姆斯。
萨克曼多年来孜孜不倦地收集比赛统计数据,使用定制的编码程序绘制比赛图表,并在 GitHub 和他的网站 Tennis Abstract 上发布数据集。此外,当诺瓦克·德约科维奇将宣扬数据在这项运动中的价值的策略教练克雷格·奥肖内西(Craig O’Shaughnessy)加入他的团队时,他给了那些过去追求网球分析激情项目的人一个象征性的推动。像其他涉及一对一比赛的游戏一样,ELO 分数被用来寻找玩家的相对实力。然而,许多参加过网球比赛的人都知道,网球是一项受比赛独特影响的运动。作为一名 6 英尺 7 英寸的大个子发球手,我在大学里打过网球,我讨厌遇到一个身材较小的“磨工”,他站在底线后面,打尽可能多的球,但不打算获胜。我假设,通过萨克曼的数据集和 K-Means 聚类分析,我将能够找到表征网球运动的不同风格的模式,并最终得出哪些聚类比其对手更有优势的结论。
萨克曼的基本“盒子得分”数据集为每场比赛提供了一个单独的行,最早可以追溯到 1968 年。我选择从 2011 年开始分析文件,作为一个相对随意的起点,但也是为了保持分析的相关性,因为游戏在过去 20 年里发生了重大变化。统计数据提供了每场比赛的基本情况,包括得分、第一发球权、双误等。该数据集不提供任何对打指标,如对打长度,该点是否是在赢家身上赢得的,强迫或非强迫失误,或是否是在网上赢得的。然而,基本的统计数据,如第一发球的百分比,发球得分的百分比,回球得分的百分比,可以让我们了解每个球员的比赛风格和相对实力。在将数据加载到 Python 中之后,我删除了任何相关统计数据的空值行。接下来,我为每个匹配创建了两行。第一行包含获胜者的统计数据,带有 Sackman 为获胜者提供的唯一 id,第二行将遵循相同的过程,但针对失败者。这一步是必要的,有两个原因,首先,统计数据是由赢家和输家组织的(即 w_ace 是胜利者 ace 的列,l_ace 是失败者 ace 的列),所以为了获得每个球员的统计数据,我必须创建单独的映射来对应他们在比赛中的统计数据,而不管结果如何。其次,我必须按日期和每个球员的 ID 进行排序,以便计算累计总数,然后用于计算统计数据,如每场比赛后的第一发球百分比。为了让你对数据有一个感觉,下面是德约科维奇在 ATP 巡回赛决赛对阵多米尼克·蒂姆的最后一场比赛后的职业生涯发球统计截图。
诺瓦克·德约科维奇在对阵多米尼克·蒂姆时的职业统计(2020 年 11 月 21 日)
我对每位玩家的复赛计算了相同的统计数据,以及总的统计数据,如所有获胜点数的百分比和每分钟点数,因为我认为这可能与对打长度相关(如上所述,这不在数据中)。令人惊讶的是,即使像诺瓦克·德约科维奇这样的球员也只赢得 55%的分数,这表明最佳球员和一般球员之间的差距相对较小,一般球员根据定义会赢得 50%的分数。这意味着 1%的改进对许多玩家来说可能是几十万美元的差别。
接下来,我利用 Scikit-Learn 的预处理库来标准化数据,然后将它提供给 Scikit-Learn 中的小批量集群功能。我尝试了不同的集群大小,从 2 到 10 不等,同时在图中寻找“肘部”(看起来有 4 个集群)。“肘”方法是一种非常主观的最佳集群度量方法,但对我的分析来说已经足够了(如果您需要对集群进行调整,请在这里检查)。
聚类的魔力又一次得到了回报,我能够在数据中找到四种不同的演奏风格。第一类的特征是最高的 ace 百分比、最高的个体和最高的第一发球获胜概率。他们赢得了大约 50%的分数,在硬地和草地球场打了最多的比赛,这是意料之中的。下一个集群似乎将平庸的玩家聚集在一起。从百分比来看,他们赢得的分数最少,在所有表面上的比赛分布比较均匀,赢得的比赛最少(38%)。虽然这是最大的群体,但球员在数据集中平均参加的比赛最少,这可能意味着这些球员往返于挑战者巡回赛和职业巡回赛之间,他们一直在努力做大。如果我选择增加集群大小,我想这个组将在更细粒度的级别上被分解。接下来,我们有了“全能选手”,这实质上是网球界对最佳个人选手的另一种说法。像费德勒、纳达尔和德约科维奇这样的球员很可能在这个组中,因为这个群体集体赢得了他们 53%的分数,每场比赛放弃了最少的破发点机会,并在第二次发球时赢得了最多的分数。最后,我们有红土场研磨机。他们有 37%的比赛是在红土上进行的,最高的是 5%,第一次发球的百分比和得分最低,但通过在回球时每场比赛创造最多的破发点来弥补这一点。下面是每个集群的各种汇总统计信息的详细图表。
根据我能够捕获的信息,汇总每个集群的统计信息
接下来,我检查了每个团队在总体上以及在不同表面上的不同胜率。
集群 X 对集群 Y 的胜率
集群 2,“全能选手”对所有参赛选手都是最公平的,我对玩研磨机的恐惧是不合理的,因为大型服务器实际上赢得了他们对集群 3 对手的 56%的比赛。同样有趣的是,在第 0 组中,“大人物”比其他组更有可能颠覆第 2 组。直觉上,这是有道理的,因为我们已经看到像约翰·伊斯内尔或凯文·安德森这样的球员在锦标赛中变得’热’,他们的力量似乎对任何人都太大了。另一方面,那些通常无法压倒对手而不得不依靠战术的磨炼者在结果上更加一致。下面是对应于硬地、红土和草地的图表,每组相对于总胜率的相对优势(特定场地胜率%-总胜率%),这也进一步说明了大发球者在硬地和草地球场上的专业知识以及研磨者在红土上的熟练程度。
图表可以被解读为在上述表面上集群 X 相对于集群 Y 的提高或降低的胜率
虽然这是一个起点,但 Jeff Sackman 还公布了 2011 年以来大满贯赛事的逐点数据,这些数据将进一步深入了解拉力赛指标,有望进一步将集群分为更具进攻性和净思维的群体,以及那些从基线拉力赛 10+杆的内容。在接下来的几周里,请在第 2 部分中寻找答案。
- 布鲁斯·舍恩菲尔德。数据(和一些激动人心的足球)如何将利物浦带到荣耀的风口浪尖。https://www . nytimes . com/2019/05/22/magazine/soccer-data-Liverpool . html
- 萨克曼杰夫。Gitbub 主页。【https://github.com/JeffSackmann
- 网球摘要 Elo 评分。http://tennisabstract.com/reports/atp_elo_ratings.html
- 萨克曼杰夫。衡量断点的影响。http://www . tennis abstract . com/blog/2019/01/04/measuring-the-impact-of-break-points/
全神贯注
一篇革命性论文“注意力是你所需要的”的摘要和使用 PyTorch 实现转换器
文森特·梵高带灰色毡帽的自画像,1887/88 年冬。(来源)
我成为机器学习工程师已经快 4 年了,我从现在所谓的“经典模型”,逻辑,基于树,贝叶斯等开始,从去年开始进入神经网络和深度学习。我会说我做得很好,直到我的注意力集中在“注意”上。我试着通过教程、讲座、指南来阅读,但没有什么能完全帮助我抓住核心思想。
所以我决定是时候正面面对公牛了,坐下来看了 arxiv 的论文,通过 Python 和 PyTorch 写了我的 实现 。这帮助我充分理解了核心概念。现在,正如他们所说,检查你的学习的最好方法是试着向别人解释,所以在这里我试着把我学到的东西分解。
历史
NLP 设计之间的比较来源
要理解为什么变形金刚在今天被大肆宣传,我们必须理解在它出现之前发生了什么。主导方法是使用 LSTM 或 GRU 等递归神经网络来实现序列到序列模型,其中编码器用于创建包含源序列所有信息的上下文向量,然后解码器将使用该上下文向量来逐序列生成新的令牌。
如上表所示,这种方法的问题是它不能将成对编码编码到上下文向量中。这意味着,当我们需要查看序列中的多个标记来预测时,基于 RNN 的模型做得不好,因为它们不能编码成对的关系。
体系结构
变压器的架构(来源)
2016 年 12 月,谷歌大脑团队提出了一种新的方法来模拟序列,这种方法在他们的论文中提出,注意力是你所需要的全部。随着大多数语言模型使用这种方法,包括一些业界最喜欢的方法,如 BERT 和 GPT-2,本文的影响还在继续
转换器设计由编码器和解码器组成,两者都包括多头注意模块和前馈模块,模型使用残差连接来连接结果并归一化以改进训练。然后,对于编码器和解码器,注意模块和前馈模块的子层重复 N 次。
编码器
编码器架构(来源)
编码器由 N = 6 个相同层的堆叠组成。每层有两个子层。第一个是多头自关注机制,第二个是简单的位置式全连接前馈网络。我们在两个子层的每一个周围使用剩余连接,然后进行层归一化。即每个子层的输出是 LayerNorm(x + Sublayer(x)),其中 Sublayer(x)是子层本身实现的函数。为了促进这些剩余连接,模型中的所有子层以及嵌入层产生维度 512 的输出。(来源)
输入令牌通过令牌嵌入层,由于模型不使用递归层,因此它使用位置嵌入来获取令牌的位置信息,这两者相加在一起。位置嵌入层不关心标记,而是关心标记的位置。来自令牌嵌入和位置嵌入的结果被逐元素地求和,然后通过模型的隐藏维度的平方根来缩放所得到的向量。
进行缩放是为了减少嵌入向量中的方差,因为这使得模型难以训练。该丢失被应用于最终的嵌入向量。然后通过 N 个编码层应用嵌入向量,以获得解码器使用的最终上下文向量。源掩码类似于源向量,当标记不是时包含 1,否则包含 0,这样做是为了避免注意力层聚焦在填充标记上。
首先,嵌入向量通过多头关注层,结果连同剩余连接被逐元素求和并通过层归一化。多头注意力作为键、值、和查询传递给源句子(稍后将详细介绍),这样做是为了让注意力网络关注源句子本身,因此得名自我注意力。
然后,产生的向量通过位置前馈网络,并与归一化层及其剩余连接一起传递。然后,结果被传递到下一层。
注意力
在这篇论文出现之前,注意力就已经在使用了,但是它在这里的实现方式对它的成功和广泛采用至关重要。这种体系结构不是作为增强上下文向量的支持模块,而是在其核心作为专家系统使用它。
注意机制(来源
单点产品注意
单个注意头取 3 个值作为输入,即查询(Q)、键(K)和值(V)。人们可以把注意力看作是将给定查询映射到键-值对的函数,相应的结果可以看作是描述哪个键-值对查询更重要的加权值。然后,将该值传递给 softmax 函数,以获得归一化权重,然后与值进行点积。
多头注意力
我们将维度划分为 h 组件,而不是通过单个点积注意力来应用查询、键和值。计算是并行进行的,然后将结果连接起来得到最终结果。这允许模型一起学习多个概念,而不是集中在单个概念上。
帮助我理解这一点的一个类比是这样的。想象一个由专家组成的房间,我们目前不知道谁是哪个主题的专家,所以我们将一个问题传入房间,并从每个专家那里获得结果,每个专家有一个置信概率。现在,最初每个专家对任何和每个主题都有相同的置信度得分。但是当我们反向传播和学习例子时,我们会发现哪个专家的回答对哪个主题更有用。
例如,当我提出一个关于汽车的问题时,每个专家都会提供他们的建议,但随着时间的推移,我们知道谁的答案对这个主题更有用,同样,其他一些专家对其他主题也有用。在这个例子中,单点产品注意力是专家,我们的多头注意力层是充满专家的房间,我们的查询、键和值是我们提出的问题。
解码器
解码器架构(来源)
解码器的工作方式类似于编码器,并对目标令牌而不是源令牌使用注意机制。除了它有两个多头注意力层的部分。第一种使用目标嵌入,第二种使用编码器输出作为键值对,前面的层输出作为查询。
在解码器模块之前,我们通过标准嵌入传递目标,并使用位置编码嵌入执行元素求和,这些执行与编码器中类似的工作。然后,结果通过 N 个解码器层,这里要注意的一点是,论文从未规定编码器和解码器中的层数必须相同。
解码器层由两个多头关注层组成,一个自关注,另一个编码器关注。第一个将目标令牌作为查询和键值对并执行自关注,而另一个将自关注层的输出作为查询,将编码器输出作为键值对。
第一个注意模块使用目标序列掩码,这样做是为了防止模型能够在我们并行处理所有令牌时看到序列中的下一个令牌。第二关注层使用自关注层的输出作为查询,编码器输出作为键值对,该模块还提供有源掩码,这样做是为了防止模型关注令牌。
两个多头注意力层之后是剩余连接和丢弃层,其被馈送到层标准化模块。然后,将结果作为位置前馈网络和另一组残差连接和层归一化模块传递。然后,将结果传递到下一层。
结论
理解这篇论文让我理解了最近出版的新变形金刚,如伯特,罗伯塔,GPT-3 等。这也让我有信心自己去阅读和实现更多的论文。我希望这是对你有用的完整阅读。如果我有任何错误,请告诉我,因为这将有助于我提高对这个概念的理解。
希望你喜欢这篇文章。
你可以在我的 GitHub 上找到实现
可以关注我 Linkedin
你可以在 中 上阅读我的其他文章
基于注意力的深度多示例学习
使用 PyTorch 和 AWS SageMaker 数据并行进行前列腺癌诊断
介绍
该帖子由以下部分组成:
第 1 部分 概述了为什么人工智能被定位于改变医疗保健行业。
第 2 部分 解释了一种称为多实例学习的机器学习技术,以及它为什么适合病理学应用。
这些作为 第 3 部分 的基础,概述了使用 PyTorch 和 AWS SageMaker 的数据并行工具包实现基于注意力的深度多实例学习模型用于前列腺癌诊断。
这篇文章的节略版已经发表在今日美国病理学家学会 2021 年 11 月刊上:见此。
第 1 部分—为什么人工智能定位于改变医疗保健行业
在深入研究代码之前,让我们后退一步,考虑一下为什么人工智能被定位于改变医疗保健。
人工智能今天的势头很大程度上可以归功于深度神经网络的成功,如果没有以下四种驱动力的完美风暴,这是不可能的:
- 越来越多的大规模数据集可用,例如 ImageNet 的 1500 万张带标签的图像,脸书的数十亿张图像库,YouTube 的视频库,每分钟增加 300 小时的视频,以及 Tesla 的驾驶数据集合,每小时增加 100 万英里的数据。
- 图形处理单元(GPU)的使用,以及后来更多的称为张量处理单元(TPU)的人工智能专用硬件,这些硬件针对训练深度学习模型进行了优化。TPU 由许多内核组成,这使它们能够处理大量数据并并行执行多个计算。OpenAI 在 2018 年的一份报告中提出,在 2012 年之前,人工智能计算的增长密切遵循摩尔定律,每两年翻一倍,而在 2012 年之后,计算每三到四个月翻一倍。总体而言,自 2012 年以来,这一计算指标已经增长了 300,000 多倍,而两年的翻倍期只会产生 16 倍的增长。
- 云计算的可用性使得存储大型数据集并使用它们来训练模型的能力变得更加容易获得和经济。
- 开源算法开发模块,如脸书的 PyTorch、谷歌的 TensorFlow、微软的 Cognitive Kit 等。
这种蓬勃发展的丰富资源推动了人工智能的快速发展,而此时医生们比以往任何时候都更加不知所措。在美国,尽管医疗保健从业人员的数量从 1975 年的 400 万增加到今天的 1600 万,但是新患者就诊的平均就诊时间已经从 1975 年的 60 分钟下降到今天的 12 分钟。除了面对不断增长的人口,医生还越来越多地被电子健康记录、管理式医疗、健康维护组织和相对价值单位所淹没,这转移了他们与患者建立有意义关系的注意力。与病人脱节的精疲力竭的医生更有可能做出带有认知偏见的判断。结果,他们条件反射性地安排不正确的测试,并随后曲解它们,导致误诊。2014 年的一项审查得出结论,美国每年面临大约 1200 万例误诊。
正如斯克里普斯研究转化研究所(Scripps Research Translational Institute)创始人兼主任埃里克·托普(Eric Schmidt)等医学博士所断言的那样,人工智能令人兴奋的前景在于使用相关患者数据的深度和全面收集,以改善决策,减少误诊和不必要的程序,指导测试的选择和解释,并推荐最安全的治疗方案。然而,医疗保健在多大程度上融入了人工智能,需要受到该行业对临床医生和患者之间的同理心和联系的内在需求的影响。医生给病人一种道德观念和核心价值观,这两者都是计算机无法复制的。有人断言,人工智能将很快变得足够复杂,足以导致其他行业的完全自动化,这引发了医疗专业人士的担忧,即人类参与医学是否将成为过去。然而,人工智能导致医学完全自动化的可能性仍然很遥远。那些参与人工智能的人有时间在医生和机器之间取得正确的平衡。
一个适当的平衡可能涉及到一个扮演数字助理角色的人工智能系统,它向医生发出最可能的诊断和最佳行动方案的警报,并让医生负责做出最终决定。“人在回路中”的方法符合弗里德曼的基本定理,即人类与计算机合作将永远优于人类单独工作,并保证了算法如何达到特定预测的透明度。⁴可解释人工智能是一套提供这种洞察力的流程或方法,对于在依赖人工智能系统的人之间建立信任,同时确保准确性、公平性和符合监管标准至关重要。可解释性为临床医生提供了质量控制和制衡,并可以帮助他们对依靠算法做出最终诊断更加自信。
稳健的模型需要开发出令人满意的可解释水平。但是如果做得正确,由此增加的工作流程和效率可以为临床医生提供更多的时间与患者联系。矛盾的是,机器的兴起可以恢复医学中的人性,并允许医学专业人员重新接触到他们最初追求医学生涯的动机。
第二部分——病理学中的人工智能
人工智能在医疗保健领域最有效的应用之一是医学成像。放射学、病理学和皮肤病学是依赖于视觉模式分析的专业,因此,由于与人工智能的集成,它们将经历快速而戏剧性的转变。
病理学家在癌症诊断中发挥着至关重要的作用,他们的报告有助于指导患者的治疗策略。通常,病理学家在显微镜下观察苏木精和伊红(H&E)染色的组织样本,并描述他们看到的细胞类型,它们是如何排列的,它们是否异常,以及任何其他对诊断重要的特征。一个世纪以来,使用显微镜检查含有组织样本的载玻片的做法基本上没有改变。然而,近年来,越来越多地使用数字载玻片扫描仪来数字化载玻片,以产生可以在计算机上检查的完整载玻片图像(WSIs)。然而,病理学家在采用 WSIs 和其他数字技术方面进展缓慢,这导致人工智能对病理学的入侵比预期的要慢。然而,WSIs 为将神经网络图像处理纳入病理学奠定了基础,从而使该领域的新人工智能辅助时代即将到来。
人工智能可用于执行通常由病理学家执行的常规工作流程,例如检测活检样本中的肿瘤组织,并根据形态学确定肿瘤亚型,从而提高效率和准确性。AI 在病理学方面的一个重要里程碑是 CAMELYON16 挑战,该挑战设定了开发算法的目标,以在淋巴结活检的 WSIs 中检测转移性乳腺癌。提供的数据集由 400 个 WSI 组成,病理学家在其中人工圈定转移癌的区域,是最大的标记病理数据集之一。这使得提交排名第一的团队(其算法表现与病理学家不相上下)能够利用监督学习。⁶
一般来说,监督学习是一种机器学习方法,其中向算法显示许多输入数据及其相应输出标签的序列,直到它可以检测到揭示这些输入和输出之间关系的潜在模式。这种技术允许它准确地标记以前没有见过的数据,并可用于分类(将输入分类到给定数量的类别中)或回归(给定输入,预测目标数值)任务。
监督学习的一个主要缺点是,它通常需要训练数据集由领域专家手工标记。在处理 WSIs 时尤其如此:就规模而言,大约 470 幅病理图像包含的像素数量与整个 ImageNet 数据集大致相同。此外,尽管 CAMELYON16 数据集是病理学中最大的数据集之一,但 400 个 WSI 不足以捕获临床中定期出现的各种病例。因此,获得一个适当大的数据集将是非常昂贵和耗时的,该数据集的数十亿像素的处理对于训练来说也是计算要求很高的。因此,在病理学中设计日常使用的监督学习模型是非常不切实际的。⁷
多实例学习(MIL)及其对病理学应用的适用性
MIL 是监督学习的一种变体,更适合于病理学应用。该技术包括为一组输入分配一个类标签——在这种情况下,称为实例包。虽然假设包中的每个实例都有标签,但是无法访问这些标签,并且它们在训练期间是未知的。如果行李中的所有实例都是阴性,则通常将行李标记为阴性;如果至少有一个阳性实例,则标记为阳性(称为标准 MIL 假设)。下图显示了一个简单的例子,在这个例子中,我们只知道一个钥匙串是否包含可以打开给定门的钥匙。这让我们可以推断绿色钥匙可以开门。
使用钥匙链的多实例学习的简化说明(作者提供的图片——灵感来自[ 来源)
MIL 公式自然适合基于成像的患者诊断的任务:类似于标准 MIL 假设,患病组织样本具有异常和健康区域,而健康组织样本仅具有健康区域。因此,可以将 WSIs 划分为多个区块,其中每个区块集合可以被标记为“恶性”或“患病”这些弱标记比强标记(即,由专家手动提供的患病区域的轮廓)更容易获得,因此将病理学家从必须自己注释 WSI 的艰苦任务中解救出来。MIL 模型也可以被制作成高度可解释的,这迎合了前面讨论的人工智能系统在医疗保健中的可解释性要求。⁸
此外,在病理学中使用 MIL 的一个特别令人兴奋的部分是,它可以集成到深度学习模型中,该模型允许创建一个平滑的端到端管道,其中 WSI 作为输入输入,诊断作为输出返回。作为副产品,深度加工模型可以从 WSIs 中自动发现新的抽象特征,这些特征在确定存活率、治疗反应和遗传缺陷方面比传统特征表现得更好。值得注意的是,可以直接从病理学实验室容易获得的 H&E 载玻片中获得这些见解,而不是进行可能昂贵的额外测试。⁹深磨形成了佩奇的基础。美国食品和药物管理局于 2021 年 9 月授权使用的 AI 公司前列腺癌软件。⁰
第 3 部分——使用 PyTorch 和 AWS SageMaker 的数据并行性工具包实现前列腺癌诊断的基于注意力的深度密值模型
在我的上一篇文章中,我进一步讨论了将 MIL 公式化为深度学习问题的优点。我还概述了在基于注意力的深度多示例学习 (Ilse 等人)中描述的模型的数学基础,该模型允许使用深度密耳进行 WSI 分类。⁸该模型使用了注意力机制的修改版本作为其聚合运算符,这比依赖于典型聚合运算符(如均值和最大值)的模型具有更大程度的可解释性。换句话说,这种基于注意力的 MIL 汇集算子提供了对每个实例对预测的包标签的贡献的洞察。
在这里,我们使用前列腺癌等级评估(PANDA) Kaggle 挑战赛中提供的数据集,包含 11,000 个数字化 H & E 染色前列腺活检的 WSI,来训练一个基于注意力的深度 MIL 模型,以根据 Ilse 等人的方法来诊断前列腺癌。目标是概述如何使用 PyTorch 和 AWS SageMaker 的数据并行工具包来实现这一点。
资料组
熊猫挑战数据集中的每个组织样本根据肿瘤的结构生长模式被分类为格里森模式,以及相应的 1-5 级 ISUP 等级。Gleason 评分是基于白色分支腔或腺组织在整个组织样本中的持续程度来确定的。腺体组织损失的增加意味着更严重,并且对应于更高的 Gleason 评分。如果在一次活组织检查中出现多个 Gleason 模式,则可以根据病理学家的判断,将其分为最常出现的模式和第二常出现的模式(分别为多数和少数)。
包含前列腺的前列腺癌活检示例的 Gleason 分级流程图(作者提供的图片——受[ 来源 ]的启发)
为了在深度模型中使用数据集,我参考了 Kaggle 笔记本后面的,以便将 WSIs 划分为每个 16x128x128 图块的集合。如 Ilse 等人所述,眼袋被标记为恶性或良性。ISUP 等级为 1、2、3、4 或 5 的载玻片被标记为“恶性”,而 ISUP 等级为 0 的载玻片被标记为“良性”⁸
每个 16 块瓷砖的集合可以被重构为一个由 16 个实例组成的袋子(图由作者提供)
模型
在下面的代码中,我们实现了 Ilse 等人使用的模型的修改版本,它考虑了上面描述的数据集。
import torch
import torch.nn.functional as F
import torch.nn as nn
class Attention(nn.Module):
def __init__(self):
super(Attention, self).__init__()
self.L = 512 # 512 node fully connected layer
self.D = 128 # 128 node attention layer
self.K = 1 self.feature_extractor_part1 = nn.Sequential(
nn.Conv2d(3, 36, kernel_size=4),
nn.ReLU(),
nn.MaxPool2d(2, stride=2),
nn.Conv2d(36, 48, kernel_size=3),
nn.ReLU(),
nn.MaxPool2d(2, stride=2)
)
self.feature_extractor_part2 = nn.Sequential(
nn.Linear(48 * 30 * 30, self.L),
nn.ReLU(),
nn.Dropout(),
nn.Linear(self.L, self.L),
nn.ReLU(),
nn.Dropout()
) self.attention = nn.Sequential(
nn.Linear(self.L, self.D),
nn.Tanh(),
nn.Linear(self.D, self.K)
) self.classifier = nn.Sequential(
nn.Linear(self.L * self.K, 1),
nn.Sigmoid()
) def forward(self, x):
x = x.squeeze(0) H = self.feature_extractor_part1(x)
H = H.view(-1, 48 * 30 * 30)
H = self.feature_extractor_part2(H) A = self.attention(H) # NxK
A = torch.transpose(A, 1, 0) # KxN
A = F.softmax(A, dim=1) # softmax over N M = torch.mm(A, H) # The probability that a given bag is malignant or benign
Y_prob = self.classifier(M) # The prediction given the probability (Y_prob >= 0.5 returns a Y_hat of 1 meaning malignant)
Y_hat = torch.ge(Y_prob, 0.5).float() return Y_prob, Y_hat, A.byte()
使用 AWS SageMaker 数据并行性(SDP)进行模型训练
一般来说,神经网络是通过在减少预测误差的方向上系统地调整它们的参数来训练的。一种常见的技术是随机梯度下降,其中这些参数变化使用称为小批量的相同大小的样本迭代发生。可以通过在一组独立的机器上平均分配小批量来加快训练时间,每台机器都有自己的模型、优化器和其他基本组件。这里,我们使用 AWS SageMaker 的数据并行工具包,该工具包已被证明比 PyTorch DistributedDataParallel 具有更好的性能。
数据并行性的示意图(作者提供的图片—灵感来自[ 来源)
SageMaker 笔记本设置
为了准备 SDP 培训,我们可以将上述数据上传到亚马逊 S3 桶中,并使用 SageMaker 预建的 PyTorch 容器启动一个 Jupyter 笔记本实例。对于这个项目,通过从 Amazon SageMaker Python SDK 调用 PyTorch 估计器来初始化训练。值得注意的是,我们传递训练脚本,指定实例计数和类型,并启用 SDP 分发方法,如下所示:
**import** **sagemaker** sagemaker_session = sagemaker.Session()
role = sagemaker.get_execution_role()**from** **sagemaker.pytorch** **import** PyTorch
estimator = PyTorch(base_job_name='pytorch-smdataparallel-histopathology-mil',
source_dir='code',
entry_point='train.py',
role=role,
framework_version='1.8.1',
py_version='py36',
instance_count=2,
instance_type= 'ml.p3.16xlarge',
sagemaker_session=sagemaker_session,
distribution={'smdistributed':{
'dataparallel':{
'enabled': **True**
}
}
},
debugger_hook_config=**False**,
volume_size=40)
ml.p3.16xlarge 是 SageMaker 数据并行工具包支持的三种实例类型之一,AWS 建议至少使用 2 个实例来获得最佳性能和最大收益。这种类型的一个实例包含 8 个 NVIDIA V100 GPUs,每个都有 16 GB 的内存。在这里,这相当于运行我们模型的 16 个独立副本。
然后,我们可以通过上传到 S3 的数据来拟合 PyTorch 估计值。这将我们的数据导入到训练集群的本地文件系统中,以便我们的 train.py 脚本可以简单地从磁盘中读取数据。
channels = {
'training': 's3://sagemaker-us-east-1-318322629142/train/',
'testing': 's3://sagemaker-us-east-1-318322629142/test/'
}
estimator.fit(inputs=channels)
入口点脚本
在我们的 train.py 入口点脚本中,我们定义了如下所示的 train 函数:
def train(model, device, train_loader, optimizer, epoch):
model.train() train_loss = 0.
train_error = 0.
predictions = []
labels = [] for batch_idx, (data, label) in enumerate(train_loader):
bag_label = label
data = torch.squeeze(data)
data, bag_label = Variable(data), Variable(bag_label)
data, bag_label = data.to(device), bag_label.to(device) # reset gradients
optimizer.zero_grad() # calculate error
bag_label = bag_label.float()
Y_prob, Y_hat, _ = model(data)
error = 1\. - Y_hat.eq(bag_label).cpu().float().mean().data
train_error += error # calculate loss
Y_prob = torch.clamp(Y_prob, min=1e-5, max=1\. - 1e-5)
loss = -1\. * (bag_label * torch.log(Y_prob) + (1\. - bag_label) * torch.log(1\. - Y_prob))
train_loss += loss.data[0] # Keep track of predictions and labels to calculate accuracy after each epoch
predictions.append(int(Y_hat))
labels.append(int(bag_label)) # backward pass
loss.backward() # step
optimizer.step() # calculate loss and error for epoch
train_loss /= len(train_loader)
train_error /= len(train_loader) print('Train Set, Epoch: {}, Loss: {:.4f}, Error: {:.4f},
Accuracy: {:.2f}%'.format(epoch, train_loss.cpu().numpy()[0],
train_error, accuracy_score(labels, predictions)*100))
我们还创建了一个函数,用于在训练完成后保存我们的模型:
def save_model(model, model_dir):
with open(os.path.join(model_dir, 'model.pth'), 'wb') as f:
torch.save(model.module.state_dict(), f)
在主守卫中,我们加载我们的数据集(详见仓库),训练超过 10 个历元,并保存我们的模型:
device = torch.device("cuda")
model = DDP(Attention().to(device))
optimizer = optim.Adam(model.parameters(), lr=0.0001, betas=(0.9, 0.999), weight_decay=0.0005)print('Start Training')
for epoch in range(1, 10 + 1):
train(model, device, train_loader, optimizer, epoch)save_model(model, args.model_dir)
部署、预测和评估
训练完成后,我们可以使用 PyTorch estimator 部署一个端点,该端点运行 SageMaker 提供的 PyTorch 模型服务器并托管我们训练好的模型。一般来说,部署用于在客户端应用程序上执行实时预测,但是这里我们部署是为了演示的目的。
**import** **sagemaker**
role = sagemaker.get_execution_role()
**from** **sagemaker.pytorch** **import** PyTorchModel
model = PyTorchModel(model_data=model_data, source_dir='code',
entry_point='inference.py', role=role, framework_version='1.6.0', py_version='py3')
现在,我们可以使用预测器来预测测试数据的标签,并确定我们的准确度分数:
predictions = []
true_labels = []for batch_idx, (data, label) in enumerate(test_loader):
_, Y_hat, _ = predictor.predict(data)
predictions.append(int(Y_hat))
true_labels.append(int(label))**from** **sklearn.metrics** **import** accuracy_score
accuracy_score(true_labels, predictions)
根据我在上述实施中的经验,我实现了 67.2%的准确率,比 Ilse 等人报告的准确率低了大约 7.5%。这可能是因为我选择了最大限度地降低 AWS SageMaker 培训成本:在这里,我只使用了数据集中 11,000 个 WSI 中的 624 个 WSI。此外,虽然文献中的模型被训练了超过 100 个时期,但是该模型仅被训练了 10 个时期。如果有更多的资金投入,我预计更大的训练数据集和更长的训练时间将导致更接近论文中看到的结果。
储存库(2021 年 10 月更新包含单元测试)
参考
1.托普·EJ。深度医学:人工智能如何让医疗保健再次人性化。基础书籍;2019.
2.Amodei D,Hernandez D. AI 和 compute。OpenAI。2018 年 5 月 16 日。https://openai.com/blog/ai-and-compute
3.辛格 H,迈耶安,托马斯 EJ。"门诊护理中诊断错误的频率:来自三项涉及美国成年人群的大型观察性研究的估计."BMJ 质量安全保险公司。2014.23(9): 727–731.
4.弗里德曼(2009 年)。生物医学信息学的一个“基本定理”。美国医学信息学协会杂志,16(2),169–170。https://doi.org/10.1197/jamia.m3092
5.坎帕内拉 G,汉纳 MG,Geneslaw L,等。在整个幻灯片图像上使用弱监督深度学习的临床级计算病理学。 Nat Med 。2019;25(8):1301–1309.
6.王博士、科斯拉博士、加尔盖亚博士、博士、贝克博士(2016 年)。用于识别转移性乳腺癌的深度学习。arXiv 预印本 arXiv: 1606.05718。
7.坎帕内拉,g .,汉娜,M. G .,Geneslaw,l .,米拉弗洛尔,a .,韦内克克劳斯席尔瓦,v .,布萨姆,K. J .,布罗吉,e .,路透,V. E .,克林姆斯特拉,D. S .,&富克斯,T. J. (2019)。在整个幻灯片图像上使用弱监督深度学习的临床级计算病理学。自然医学,25(8),1301–1309。https://doi.org/10.1038/s41591-019-0508-1
8.伊尔泽,硕士,托姆扎克,法学硕士,韦林,硕士(2018)。基于注意力的深度多示例学习。第 35 届国际机器学习会议录,瑞典斯德哥尔摩,PMLR 80。https://arxiv.org/abs/1802.04712.
9.Rajpukar P,Saporta A. 人工智能健康播客。PathAI 的 Aditya Khosla 博士的病理学人工智能和企业家精神。2020 年 12 月 16 日。https://theaihealthcpodcast . com/episodes/path olgy-ai-and-entrepreneurs-with-path ais-aditya-khosla。
10.麦考密克,J. (2021 年 9 月 27 日)。FDA 授权人工智能软件帮助识别前列腺癌。华尔街日报。
11.韦伯,e . &克鲁尚,O. (2020 年 12 月 9 日)。在 Amazon SageMaker [web log]上使用两个新的分布式培训库扩展深度学习。https://towards data science . com/scale-neural-network-training-with-sage maker-distributed-8 cf 3 aefcff 51。
12.Aws。(未注明)。AWS/亚马逊-sagemaker-examples 。GitHub。https://github . com/AWS/Amazon-sage maker-examples/blob/35 e 2 faf 7 D1 cc 48 cced f 0 B2 ede 1 da 9987 a 18727 a 5/training/distributed _ training/py torch/data _ parallel/Mn ist/py torch _ smdataparallel _ Mn ist _ demo . ipynb .
计算机视觉中的注意力
实践教程
在 PyTorch 中实现多头和 CBAM 注意模块
自从 Transformer 在作品“Attention is all you needle”中引入以来,NLP 领域出现了一种向用基于注意力的网络取代递归神经网络(RNN)的转变。在目前的文献中,已经有很多很棒的文章描述了这种方法。下面是我在评测中发现的最好的两个: 带注释的变形金刚 和 可视化解释的变形金刚 。
然而,在研究了如何在计算机视觉中实现注意力(最佳找到的文章: 理解注意力模块 、 CBAM 、 带代码的论文——注意 、自我注意、自我注意和 Conv )后,我注意到其中只有少数几篇清楚地描述了注意力机制,并在理论的同时包含了干净的代码。因此,本文的目标是详细描述计算机视觉中两个最重要的注意模块,并使用 PyTorch 将它们应用到一个实际案例中。文章的结构如下:
- 注意力模块介绍
- 计算机视觉中的注意方法
- 基于注意的网络的实现和结果
- 结论
1.注意力模块介绍
在机器学习的背景下,注意力是一种模仿认知注意力的技术,被定义为选择和专注于相关刺激的能力。换句话说,注意力是一种试图增强重要部分,同时淡出不相关信息的方法。
尽管这种机制可以分为几个家族(注意?立正!),我们关注自我注意力,因为这是计算机视觉任务中最流行的注意力类型。这是指将单个序列的不同位置相关联来计算同一序列的表示的机制。
为了更好的理解这个概念,我们来想一下下面这个句子:河岸。如果我们看不到单词 River 我们是否同意单词 Bank 失去了它的上下文信息?这实际上是自我关注背后的主要思想。它试图给出每个单词的上下文信息,因为单词的单个含义并不代表它们在句子中的含义。
正如自我关注的直观解释中所解释的,如果我们考虑上面给出的例子,自我关注的工作方式是将句子中的每个单词与其他每个单词进行比较,并重新加权每个单词的单词嵌入,以包括上下文相关性。输出模块的输入是没有上下文信息的每个单词的嵌入,而输出是具有上下文信息的类似嵌入。
2.计算机视觉中的注意方法
此处列出了持续更新的关注模块列表。从列出的几个中,我们重点介绍两个最受计算机视觉任务欢迎的:多头注意力和卷积块注意力模块(CBAM) 。
2.1。多头关注
多头注意力是注意力机制的一个模块,它并行运行一个注意力模块若干次。因此,要理解它的逻辑,首先需要理解注意力模块。两个最常用的注意力函数是https://paperswithcode.com/method/additive-attention和 点积注意力 ,后者是本工作感兴趣的一个。
关注模块的基本结构是有两个向量列表 x1 和 x2 ,一个是关注的,另一个是出席的。向量 x2 生成“查询”,而向量 x1 创建“键”和“值”。关注函数背后的思想是将查询和设置的键值对映射到输出。输出计算为值的加权和,其中分配给每个值的权重由查询与相应关键字的兼容性函数计算"T17 注意是您所需要的全部 T18"。输出计算如下:
正如在本讨论中提到的,键/值/查询概念来自检索系统。例如,当在 Youtube 上键入一个查询来搜索一些视频时,搜索引擎会将您的查询映射到一组键(视频标题、描述等)。)与数据库中的候选视频链接。然后,它会为您呈现最匹配的视频(值)。
在进入多头注意力之前,让我们运行这个点积注意力,多头注意力是本模块的一个扩展。下面是 PyTorch 中的实现。输入是[128, 32, 1, 256]
,其中 128 对应的是批次,32 对应的是序列长度,1 对应的是头数(对于多个关注头我们会增加),256 是特征数。
输出是:
*attn_output: [128, 32, 1, 256], attn_weights: [128, 1, 32, 32]
attn_output: [128, 32, 1, 256], attn_weights: [128, 1, 32, 16]*
从这个基本实现中可以得到一些启示:
- 输出将具有与查询输入大小相同的形状。
- 每个数据的注意力权重必须是一个矩阵,其中行数对应于查询的序列长度,列数对应于键的序列长度。
- 点积注意力中没有可学习的参数。
所以,回到多头注意力,这个人并行运行这个解释过的注意力模块几次。独立的注意力输出然后被连接并线性转换成期望的维度。下面是实现过程:
输出是:
*attn_output: [128, 32, 256], attn_weights: [128, 8, 32, 32]
attn_output: [128, 32, 256], attn_weights: [128, 8, 32, 32]*
从代码中可以看出:
- 例如,查询的线性层的输入是
[128, 32, 256]
。然而,正如在这篇文章中提到的,Linear
层接受任意形状的张量,其中只有最后一个维度必须与你在构造函数中指定的in_features
参数相匹配。输出将具有与输入完全相同的形状,只有最后一个维度将改变为您在构造函数中指定的out_features
。对于我们的例子,输入形状是一组128 * 32 = 4096
和256
特征。因此,我们将密集网络应用于序列长度的每个元素和批次的每个数据。 - 此外,我们添加了残余连接和层规范化,因为它是在变压器神经网络中实现的。但是,如果你只是想实现多头注意力模块,这些应该被排除在外。
因此,在这一点上你可能会疑惑,为什么我们要实现多头注意力而不是一个简单的注意力模块?根据论文注意力是你所需要的全部,“多头注意力允许模型共同注意来自不同位置的不同表征* 子空间 *的信息。用单一的注意力头,平均化抑制了这一点。”换句话说,将特征划分为头部允许每个注意力模块仅关注一组特征,从而提供更大的能力来编码每个单词的多种关系和细微差别。
如果在这一点上你还想深入了解这种类型的注意力,我鼓励你阅读这篇文章,它用很棒的插图详细解释了所有这个模块。
在结束之前,我只想提一下,我们已经使用了这个注意力模块,就好像我们在处理序列一样,但是这篇文章是关于图像的。如果你理解了这一点,序列和图像之间唯一的区别就是输入向量。对于图像来说,与序列长度相对应的是像素。因此,如果输入是[batch=128, no_channels=256, height=24, width=24]
,一个可能的实现可能是:
输出是:
*attn_output: [128, 256, 24, 24], attn_weights: [128, 8, 576, 576]*
2.2。卷积块注意模块(CBAM)
在 2018 年, S. Woo 等人(2018) 发表了一个新的注意力模块,名为卷积块注意力模块(CBAM),它和卷积运算一样,强调了沿通道和空间轴的有意义的特征。与多头注意力相比,这种类型的注意力是针对前馈卷积神经网络有意制造的,并且可以应用于深度网络中的每个卷积块。
CBAM 包含两个连续的子模块,称为通道注意模块(CAM)和空间注意模块(SAM)。这两个概念可能是谈论卷积时最重要的两个概念。通道是指每个像素的特征或通道的数量,而空间是指维度(h x w)的特征图。
- 空间注意模块(SAM) :该模块由三重顺序操作组成。它的第一部分称为通道池,它包括对输入(c×h×w)应用跨通道的最大池和平均池,以生成具有 shape (2 × h × w )的输出。这是卷积层的输入,卷积层输出一个单通道特征图(1 × h × w )。在通过 BatchNorm 和可选的 ReLU 传递这个输出之后,数据进入 Sigmoid 激活层。
- 通道注意模块(CAM) :该模块首先将输入张量分解成由全局平均池(GAP)和全局最大池(GMP)生成的 2 个后续维度向量( c × 1 × 1)。此后,输出通过完全连接层,然后是 ReLu 激活层。
想了解更多关于 CBAM 的信息,我推荐阅读这篇伟大的帖子,里面有很棒的解释图片。
下面是实现过程:
输出是:
*attn_output: [128, 256, 24, 24]*
3.基于注意的网络的实现和结果
在上述理论部分之后,本节将重点介绍两个注意层在一个实际案例中的实现。
具体来说,我们选择了 STL 数据集,并在一些图像中添加了白色补丁,如下图所示。任务是创建一个神经网络来分类这两种类型的图像。
STL 图像。那些标记为 1 的图像属于其图像具有白色斑块的类别,而那些标记为 0 的图像是没有白色斑块的图像。
然后,我们创建了三个类。第一个只是一个 CNN,而第二个包含多头注意力层,第三个包括 CBAM 模块。
下面是运行培训的代码。
这些是输出结果:
- CNN :
*Min train error: 0.0011167450276843738
Min test error: 0.05411996720208516*
- CNN +多头关注:添加关注层后性能有所提高,但关注图没有突出显示图像中带有白色斑块的部分。
*Min train error: 9.811600781858942e-06
Min test error: 0.04209221125441423*
**
由于有一些过度拟合和注意力层没有做它应该做的,我用卷积层重新实现了这一层。如果有人有什么建议,请在评论中留下。
- 基于 CNN + 1DConv 的多头关注:这一次稳定性和性能明显提高。此外,还可以观察到注意力层的输出是如何为包含它的图像高亮显示白色斑块的。
*Min train error: 0.00025470180017873645
Min test error: 0.014278276459193759*
**
- CNN + CBAM 注意:这一个呈现了最好的结果。显然可以在注意力层的输出中观察到白色斑块,并且训练非常稳定,实现了所有模型中最低的验证损失。
*Min train error: 2.786791462858673e-05
Min test error: 0.028047989653949175*
**
4.结论
总之,本文介绍了多头注意力和 CBAM 模块,这是计算机视觉中最流行的两个注意力模块。此外,它还包括 PyTorch 中的一个实现,其中我们对包含白色补丁(手动添加)的 CIFAR 数据集中的图像进行分类。
对于未来的工作,我认为将位置编码和注意力结合起来是很有趣的。在这里,我为感兴趣的人留下了一个链接。
如果你喜欢这篇文章,请考虑 订阅 。你将获得我所有的内容+所有其他来自牛逼创作者的文章!