了解分类指标
对于一个简单的二进制分类任务,初学者经常被大量的度量标准所迷惑。在这里,我给出了敏感性(也称为回忆)、特异性和精确性的自下而上的解释。
从事分类指标工作的人经常会遇到像真阳性率、假阳性率、召回率和精确度这样的术语,深入理解它们的含义是很有用的。
实际上有很多很好的来源来解释这些术语,但是真正的理解只能来自于坐下来思考问题。此外,我们有自己思考问题的方式,所以没有放之四海而皆准的方法。在这篇笔记中,我将我对这些术语的理解具体化,以供我参考,也供任何和我想法相同的人参考。
可视化的分类问题形式https://commons.wikimedia.org/wiki/File:Precisionrecall.svg
我将采用不同的方法,而不是直接介绍所有这些术语,并让读者经历我在阅读这些术语时遇到的同样的困惑。**我将讲述一个情景和一个实验,并通过数学来解决问题。只有到最后我才会说出这些术语。**这样一来,读者就会理解这个概念,然后再为这些名字而烦恼。
让我们来看一个场景,其中有一些状态可以是真(T)或假(F)。这可以说是个人的新冠肺炎状态,或者在 Imagenet 中图像是否是猫的图像。然后,我们有一个分类器,可能是那些可以嗅出新冠肺炎阳性患者的酷狗之一,或者是你最喜欢的 CNN 分类器,可以区分猫和非猫。当它们“认为”样本为真(T)时,它们将输出正(P ),当它们“认为”样本为假(F)时,它们将输出负(N)。
现在,在这一点上,我们有一些可以考虑的自然量。
- 我们可以看看人口概率是真还是假,即 P(T)和 P(F)。请注意,它们的总和为 1。这可能是已知的(Imagenet 中的猫)或未知的(新冠肺炎病例的真实实例),在后者中我们可能有估计。
- 我们可以通过询问真实样本被发现为正 P(P|T)或负 P(N|T)的概率来查看我们的分类器执行得有多好。请注意,P(P|T) + P(N|T)=1 作为真实样本,只能以某种方式进行标记。类似地,我们可以讨论 P(P|F)和 P(N|F ),它们的和也是 1。
- 我们还可以通过询问样本被发现为阳性的概率的反问题来查看我们的分类器表现如何,实际上是真 P(T|P)和假 P(F|P)。这些加起来也必须是 1,因为标记为阳性的样本必须是真或假,即 P(T|P) + P(F|P) = 1。同理,我们可以讲 P(T|N)和 P(F|N)。
现在我要讲一下贝叶斯定理。如果你只是知道它,但没有内化它,我会建议你停下来思考一下,努力理解它。这不是很难,可以用维恩图来理解。如果你没有听说过它,那么你应该在维基百科上阅读它,然后像我建议的那样努力思考它。我不会在这里激励它,只是简单地使用它。
现在,使用贝叶斯定理,我们可以联系上述数量
很明显,我还可以写出另外三个关系式,但是请注意,其中一个是通过 T F 和 P N 从上面得到的,另外两个是通过上面第 3 点中提到的概率总和为 1 得到的。此外,从商业角度来看,上述形式通常是最有用的。差不多了!我们只需要用上面第二点提到的概率总和来稍微调整一下。
就是这样!这就是全部了。然而上面的一些术语有特殊的名称,我现在介绍一下。左边的家伙,P(T|P)叫精密。这是一个非常有用的指标,因为它量化了那些被分类为阳性的样本中有多少部分是真实的。P(P|T)被称为灵敏度或召回,它是被分类器分类为阳性的真实样本的分数。最后,P(N|F)与前面的量非常相似,不幸地不被称为对否定的回忆(这将使生活变得更简单,所以…显然不是),而被称为特异性。
通常,医学中报道的测试或分类器的度量是灵敏度和特异性。然而,人们经常提到,如果真实的人口密度是偏斜的,即 P(T) << P(F). Let’s see why that is the case. Let me massage the above expression further
Now suppose we have a super fundoo 分类器具有非常高的灵敏度 P(P|T) = 1 和非常高的特异性 P(N|F) = .99,那么人们可能会天真地认为该分类器非常好。然而,假设我们有 P(F)/P(T) ~ 1000,那么我们仍然会得到 10%的精度。
可以论证的是,从医学或商业的角度来看,精确度和召回率/敏感度通常比特异性和召回率/敏感度更有利于权衡比较。
理解分类建模中的精度、灵敏度和特异性,以及如何用混淆矩阵计算它们
直观、易于记忆的示例,用于理解常见的分类指标
照片由 Alwi Alaydrus 在 Unsplash 上拍摄
根据分类模型成功生成预测后,您会想知道预测的准确性。当涉及到分类模型时,准确性可能是一个非常微妙的概念,因为对您的模型有意义的度量标准将根据您的模型的目的而变化。例如,你是否试图预测一个病人是否患有癌症?还是想预测一个人是男是女?在评估这些模型时,您最有可能关注不同的指标,因为正如您所想象的,做出不正确的预测会产生不同的成本。
为了理解这些复杂性,让我们使用这些度量来评估一个分类模型。我们将使用的数据来自 Kaggle 著名的 泰坦尼克号——从灾难中学习的机器 分类比赛。数据集的每一行都描述了泰坦尼克号上的一名乘客。比赛的目的是利用提供的特征(如性别、年龄等。)来预测给定乘客是活着还是死了。
评估指标
在不进行任何数据清理或特征工程的情况下,我们将通过在训练数据上拟合我们的模型来生成基线逻辑回归模型,然后在同一数据集上进行预测。为简单起见,我们将使用没有任何缺失值的特性和以下指标来评估模型的准确性:
- 混淆矩阵
- 准确(性)
- 分类错误率
- 精确
- 灵敏度
- 特征
模型
我们将使用数据集中的Pclass
、Sex
、Age
、SibSp
、Parch
和Fare
列来尝试和预测Survived
,从而将逻辑回归模型拟合到我们的数据中。
符合我们的模型,现在让我们产生我们的预测。
评估我们的模型
现在我们有了一些预测,我们可以评估模型以确定它对实际类的预测有多好。理解我们模型准确性的一个关键是混淆矩阵。为了生成一个,我们将使用caret
包中的confusionMatrix
函数。该函数要求我们将输入作为因子提供,因此我们将进行转换并显示矩阵:
在查看上面的结果时,我们可以看到我们的基线模型表现得不是很好。对角线上的值,从左上角到右下角,是模型准确预测的类。列标题表示实际类别,行标签表示预测类别。用视觉表示法来理解混淆矩阵通常更容易:
作为一个例子,如果我们看第一列(“活的”、“活的”),这是真阳性,我们看到模型正确地识别了 108 个活着的个体,但是,看左下角的(“活的”、“死的”),这是假阴性,我们看到模型预测 234 个实际活着的个体死亡。
混淆矩阵对于理解我们将用于评估该模型的指标至关重要。
准确(性)
由 Ricardo Arce 在 Unsplash 上拍摄
在我们将要讨论的所有指标中,准确性是最直接的,也是您可能最熟悉的。当涉及到分类模型时,准确性主要是一个高层次的抽查,几乎不应该是用来评估您的模型的唯一指标。可以使用混淆矩阵中的值计算准确度:
当您的响应变量中有不平衡的类时,问题就来了。例如,如果您试图检测欺诈,而 1,000 笔交易中只有 1 笔是欺诈性的,即使您预测每笔交易都没有欺诈,您仍然会有一个 99.9%准确的模型。然而,也许一个欺诈案件会造成数百万美元的损失。我们知道,对于这样的模型,预测一个欺诈性交易将是模型的重点,我们的指标应该进行调整,以帮助我们了解模型在这方面的表现。因此,在大多数分类设置中,准确性需要进一步分解,以分析模型如何预测我们关心的结果。
让我们来看看我们模型的准确性:
## [1] 0.2065095
我们的模式真的很艰难。我们只是在 21%的时间里预测实际的类。
分类错误率
这个度量是准确性的反义词。它向我们展示了我们的结果被错误分类的频率。其计算方法如下:
我们可以通过从 1 中减去我们的准确性度量来找到我们的模型的分类错误率。
## [1] 0.7934905
我们的模型在大约 79%的时间里预测错误的类别。
精确
精度是指实际阳性与预测阳性的比率。当误报的成本很高时,最常使用这种度量。例如,在一个将电子邮件分类为垃圾邮件或垃圾邮件的模型中,我们需要非常高的精确度,以便相关和重要的电子邮件不会被发送到垃圾文件夹或被阻止(误报)。这里假阳性的代价很高。精度计算如下:
对于我们的模型,我们必须稍微扩展一下这个故事,以使精度有意义。假设我们继承了一大笔钱,作为泰坦尼克号的历史爱好者,我们想给模型中确定的每个幸存者的家庭寄去 1000 美元。我们绝对不希望发送不必要的钱,所以我们真的希望我们的模型具有高精度,这意味着,我们尽可能多地向实际幸存者的家庭发送钱,并真正限制向遇难乘客的家庭发送钱的频率。
让我们看看我们模型的精度:
## [1] 0.1858864
我们模型的精确度是糟糕的。如果我们按照现在的模式发送 1,000 美元的礼物,只有大约 19%的家庭会收到礼物,其余的钱按照我们的目标都是浪费!
敏感度(回忆)
当你关注于识别阳性结果并且假阳性的成本很低时,灵敏度或回忆是重要的——这意味着只要我们识别尽可能多的实际阳性,我们就可以拾取一些假阳性。如果我们要预测一名患者是否患有癌症,灵敏度必须高得令人难以置信,这样我们才能捕捉尽可能多的阳性病例,即使这意味着我们会引入一些实际上没有患癌症的患者。这里假阳性的成本很低。灵敏度计算如下:
让我们假设我们想给模型中确定的每个幸存者的家庭送一朵玫瑰。我们没有足够的钱给幸存者和死者的家人送花,所以我们必须做出选择。在我们内心深处,对我们来说非常重要的是,我们至少要给真正幸存者的家庭送去玫瑰。然而,我们不介意最终给遇难乘客的家庭送去一些玫瑰。我们在好市多大量购买玫瑰,所以它们相当便宜。在这种情况下,我们希望我们的敏感度非常高,以便尽可能多的幸存者家庭收到玫瑰,即使少数非幸存者家庭也收到玫瑰。
让我们计算一下我们模型的敏感度:
## [1] 0.3157895
我们模型的灵敏度真的是相当可怕。如果我们使用这个模型,只有 32%的幸存者家庭会得到一朵玫瑰!那是不能接受的!
特征
特异性是真阴性与所有阴性结果的比率。如果你担心你的否定率的准确性,并且肯定的结果有很高的成本,那么这个指标是有意义的——所以如果没有必要,你就不要吹这个口哨。例如,如果你是一名审计员,正在检查财务交易,一个肯定的结果意味着一年的调查,但是找不到一个结果只会给公司造成 50 美元的损失。特异性计算如下:
假设我们想给我们的模型所识别的死亡乘客的家人发送一封手写的邮件。自从 1912 年泰坦尼克号沉没以来,我们觉得这些家庭有时间从他们的损失中恢复过来,所以不会因为收到一张纸条而心烦意乱。然而,我们觉得给幸存者的家人发一封短信是不可思议的麻木不仁,因为他们的死亡时间会更近(最后一位泰坦尼克号幸存者于 2009 年去世,享年 97 岁),而家人仍然沉浸在悲痛之中。
让我们计算一下我们模型的特异性:
## [1] 0.1384335
我们的专一是可耻的!如果我们使用目前的模型,大约 86%的纸币接收者会记住他们最近的损失!我们不能这样!
结论
在查看我们模型的衡量标准时,有一点是清楚的:我们不应该将这种模型用于任何类型的礼物赠送。我们的模型非常不准确,只会引起恐慌。
虽然我们不会根据这个练习给泰坦尼克号幸存者写任何手写的笔记,但我们以一种令人难忘的方式学习了一些用于分类模型的最常用的度量标准。当然,还有其他重要的指标,如 F1 得分、ROC 曲线和 AUC,但是,我们将把这个讨论留到以后。
谢谢大家的支持!
感谢您阅读本文!如果你觉得有帮助,请给我一两下掌声:)
用购物篮分析理解消费者行为
了解用于优化零售和电子商务行业销售的数据挖掘技术
塔曼娜·茹米在 Unsplash 拍摄的照片
预测客户的兴趣是许多商业模式中采用的策略。公司在各种策略上进行了大量投资,从进行客户调查到建立复杂的机器学习模型以更好地了解客户行为。
使用的一个比较突出的方法是市场篮子分析,这是一种数据挖掘技术,可以识别表现出强关系的产品。
这项研究可以识别出表面上看不出来的高相关性产品。这是一个重要的工具,因为知道哪些产品有利于购买其他产品可以使企业以更大的成功率推广和推荐商品。
在这里,我们将涵盖市场篮子分析的来龙去脉。
市场篮子分析
购物篮分析是关联规则挖掘的一种形式,它发现具有强关联或相关性的项目。
在解释购物篮分析之前,重要的是要涵盖一些关键术语。
在一个事务中购买的一组项目被称为一个项目集。
一个关联规则本质上是一个 if-then 语句,旨在建立所购买商品之间的关系。
假设你正在网上寻找一部新手机。将手机放入购物车后,您决定也要买一个手机壳。您将手机壳添加到购物车中并进行购买。
在这种情况下,项目集是{Phone,Phone Case}。
此项集的关联规则是:if {Phone},then {Phone Case}。
项目集中的乘积可以分为两组:前因和后果。
前件指的是位于关联规则左侧的产品。
结果是指位于关联规则右侧的产品。
在这个例子中,先行词是电话,而结果词是手机壳。
购物篮分析需要找到表现出最强关联的项目集。
也就是说,通过识别和评估项目的所有组合来找到最显著的项目集是困难的,因为它提出了两个问题。
问题#1 :单从表面价值来看,我们无法区分最显著的项目集。
有了上面的例子,购买手机和购买手机壳有很强的相关性就说得通了。但是,如何评价表面上没有那么直接联系的物品呢?
幸运的是,有一些评估指标可以帮助定量地衡量前因和后果之间的联系。
support 度量测量项目集的频率。换句话说,它将告诉您购买项目集中的产品的频率。
支持度量的公式为:
置信度衡量的是在购买了前因的情况下,购买后果的可能性。
置信度度量的公式为:
提升指标衡量购买前因对购买后果的影响。
提升度量的公式为:
如果关联的提升为 1,那么前件和后件的购买是独立的。
如果一个关联的提升大于 1,购买前因会增加购买后果的可能性。
如果一个关联的提升值小于 1,购买前因会降低购买后果的可能性。
通过这些评估指标,我们可以筛选出不符合标准的产品组合。
问题 #2 :考虑到项目集组合的总数,我们无法处理所有的项目集。
简单来说,测试和评估每一个可能的唯一项集是不合理的。
客观地说,如果你有 1000 种不同的产品,那么在寻找最佳关联规则时,你需要考虑 499,500 种不同的两种商品的组合。任何大小组合的总数都超过了海滩上沙粒的数量。
谢天谢地,有一个简单的方法可以绕过这个问题。
apriori 算法是一种有效的替代方法,可以帮助识别频繁项集,同时过滤掉不频繁的项集。它可以不考虑项目集,而不必对它们进行评估。本文不会涉及 apriori 算法的内部工作原理,但是如果你感兴趣,你可以在这里了解更多。
缺点
尽管购物篮分析是一种非常有用的数据挖掘技术,但它绝不是对消费者行为的可靠研究。
首先,即使产品之间的关联显示出有希望的评价指标,它也不能直接证明产品之间的因果关系。毕竟,相关性不等于因果关系。
其次,像任何数据挖掘技术一样,购物篮分析容易出错。它可能会错误地忽略重要的关联或错误地包含不重要的关联。
在你进行分析的时候,记住这些缺点,以免你从你的发现中得出错误的结论。
个案研究
我们可以通过对一个存储电子商务购买的数据集(无版权保护)进行研究来演示市场购物篮分析,该数据集可以在这里访问。
这是数据集的预览。
代码输出(由作者创建)
我们只对每位顾客购买的商品感兴趣,这在“子类别”栏中有提及。让我们将这个列转换成一个列表的列表,每个列表代表一个项集。
代码输出(由作者创建)
执行市场篮分析需要计算每个项目集中关联的支持度、置信度和提升度量,如果手动执行,可能会非常耗时。谢天谢地,Python 中的 mlxtend 模块允许我们轻松地执行这样的操作。
现在我们有了项目集列表,我们必须使用 apriori 算法来删除不常用的项目集。这样做需要对数据进行一次热编码。
mlxtend 模块有自己的编码器,可以对项集进行一次性热编码。
代码输出(由作者创建)
使用 mlxtend 模块,我们可以使用 apriori 算法来识别支持值大于或等于 0.1 的项集。
代码输出(由作者创建)
因为目标是识别具有强关系的产品,所以我们将使用 association_rules 函数来查找关联类型符合要求的产品。
在这种情况下,如果一个项集中的提升值超过 1,我们将认为该关联是理想的。
代码输出(由作者创建)
根据结果,有手帕和披肩的项目集具有最高的提升值。值得探究的是,为什么购买手帕会增加购买披肩的可能性,反之亦然。
请记住,这项研究只证实了这两个项目之间的强相关性,而不是因果关系。
从这一分析中得出的一个误导是,向购买披肩的人积极推销手帕是最理想的。只有在进一步探索这两个项目之间的潜在关系后,才能得出这样的结论。
结论
能够理解消费者的行为几乎就像是一种超能力。
这就是为什么购物篮分析作为一种技术脱颖而出,在寻找客户购买的模式和趋势时可以依赖。
这种分析本身似乎很简单,但它是产品推荐和促销系统基础的一部分,服务行业在未来许多年都将依赖这种系统。
我祝你在数据科学的努力中好运!
参考
- 罗山,B. (2019)。电子商务数据,第 2 版。于 2021 年 11 月 12 日从 https://www.kaggle.com/benroshan/ecommerce-data.取回
理解对比学习
学习如何使用自我监督学习法进行无标签学习。
拉奎尔·马丁内斯在 Unsplash 上拍摄的照片
什么是对比学习?
对比学习 是一种机器学习技术,用于通过教导模型哪些数据点相似 或不同来学习无标签数据集的**总体特征。****
让我们从一个简单的例子开始。想象你是一个新生婴儿,正在试图理解这个世界。在家里,我们假设你有两只猫和一只狗。
即使没有人告诉你他们是“猫”和“狗”,你可能仍然会意识到,与狗相比,这两只猫看起来很相似。
(左)照片由埃德加拍摄于 Unsplash |(右上)照片由拉娜·维德诺瓦拍摄于 Unsplash |(右下)图片由鲁比·施曼克拍摄于 Unsplash
仅仅通过识别我们毛茸茸的朋友之间的异同,我们的大脑就可以学习我们世界中物体的高级特征。
**例如,我们可能下意识地认为两只猫的耳朵是尖的,而狗的耳朵是下垂的。或者我们可以对比 (提示-提示)狗凸出的鼻子和猫扁平的脸。
本质上,对比学习允许我们的机器学习模型做同样的事情。它查看哪些数据点对是【相似】【不同】,以便了解关于数据的更高层次的特征*,甚至在之前的还有分类或分割等任务。*
这个为什么这么厉害?
这是因为我们可以训练模型学习大量关于我们的数据 没有任何注释或标签, 因此得名, 自我监督学习。
视网膜的眼底图像,带注释。来源:[1]
在大多数真实世界的场景中,我们没有为每张图片贴标签。以医学成像为例。为了创建标签,专业人员必须花费无数时间来查看图像,以手动分类、分段等。
通过对比学习,即使只有一小部分数据集被标记,也可以显著提高模型性能。
既然我们理解了什么是对比学习,以及它为什么有用,让我们看看对比学习是如何工作的。
对比学习是如何工作的?
在本文中,我重点关注 SimCLRv2 ,这是谷歌大脑团队最近提出的最先进的对比学习方法之一。对于其他的对比学习方法,如脸书的 MoCo,我建议回顾下面的文章。
**
幸运的是, SimCLRv2 非常直观。
整个过程可以简明地描述为三个基本步骤:
- 对于我们数据集中的每个图像,我们可以执行两个增强组合(即裁剪+调整大小+重新着色、调整大小+重新着色、裁剪+重新着色等。).我们希望模型知道这两个图像是“相似的”,因为它们本质上是同一图像的不同版本。
- 为此,我们可以将这两幅图像输入到我们的深度学习模型(Big-CNN,如 ResNet)中,为每幅图像创建矢量表示。目标是训练模型为相似的图像输出相似的表示。
将图像表示为矢量表示。来源:Amit Chaudhary 的图解 SimCLR 框架, amitness
- 最后,我们试图通过最小化对比损失函数来最大化两个向量表示的相似性。
SimCLRv2 框架概述。作者图。照片由埃德加在 Unsplash 上拍摄
随着时间的推移,模型将了解到两个猫的图像应该具有相似的表示,并且猫的表示应该不同于狗的表示。
这意味着模型能够区分不同类型的图像,甚至不知道图像是什么!
我们可以将这种对比学习方法进一步分解为三个主要步骤:数据扩充、编码和损失最小化。
1)数据扩充
来源:Amit Chaudhary 的图解 SimCLR 框架, amitness
我们随机执行以下增强的任意组合:裁剪、调整大小、颜色失真、灰度。在我们的批处理中,我们对每个图像做两次*,以创建两个增强图像的正对*。**
2)编码
然后我们使用我们的 Big-CNN 神经网络,我们可以简单地认为它是一个函数, h = f(x), ,其中“x”是我们的一个增强图像,到将我们的两个图像编码为矢量表示。
作者图片
然后将 CNN 的输出输入到一组称为**投影头、*z =*******g(h)**的密集层,将数据转换到另一个空间。经验表明,这一额外步骤可以提高性能[2]。
如果您不熟悉潜在空间和向量表示,我强烈推荐您在继续之前阅读我的文章,这篇文章直观地解释了这个概念。
*
通过将我们的图像压缩到潜在空间表示中,模型能够学习图像的高级特征。
事实上,当我们继续训练模型以最大化相似图像之间的向量相似性时,我们可以想象模型正在学习潜在空间中相似数据点的聚类。
例如,猫的表现形式会更接近,但离狗的表现形式更远,因为这是我们训练模型学习的内容。
3)表示的损失最小化
现在我们有了两个向量, z ,我们需要一种方法来量化它们之间的相似性。
来源:Amit Chaudhary 的图解 SimCLR 框架, amitness
因为我们正在比较两个向量,自然的选择是余弦相似度,这是基于空间中两个向量之间的角。
空间中的 2D 矢量。作者图片
合乎逻辑的是,当向量在空间上越靠近(它们之间的角度越小),它们就越相似。因此,如果我们将**余弦(两个向量之间的角度)作为度量,**我们将在角度接近 0 时获得高相似性,否则获得低相似性,这正是我们想要的。
我们还需要一个可以最小化的损失函数。一种选择是 NT-Xent(归一化温度标度交叉熵损失)。
我们首先计算两幅增强图像相似的概率**。**
来源:Amit Chaudhary 的图解 SimCLR 框架,友好
注意,分母是 e^similarity( 所有对的总和,包括负对。负对通过在我们的增强图像和我们批次中的所有其他图像之间创建对来获得。
最后,我们将这个值放在一个 -log() 中,使得最小化这个损失函数对应于最大化两个增强图像相似的概率。
来源:Amit Chaudhary 的图解 SimCLR 框架, amitness
要了解更多关于 SimCLR 的细节,我推荐阅读下面的文章。
*https://amitness.com/2020/03/illustrated-simclr/
SimCLR 版本 2
值得注意的是,自最初发布 SimCLR 框架以来,作者对管道进行了以下重大改进[2]:
- 更大的 ResNet 型号用于 Big-CNN 编码器——152 层 Res-Net,3 倍宽的通道,选择性内核,注意机制。
- 更多投影头— 转换中间表示时使用三个密集层,而不是两个。
对比学习的应用
半监督学习
当我们只有很少的标签时,或者如果很难获得特定任务(即临床注释)的标签,我们希望能够使用已标记数据和未标记数据来优化我们模型的性能和学习能力。这就是半监督学习的定义。
一种在文献中日益流行的方法是无监督预训练、有监督微调、知识提炼范式【2】。
半监督学习范式综述。来源:[2]
在这种范式中,自我监督对比学习方法是一个关键的“预处理”步骤,它允许大 CNN 模型(即 ResNet-152)在试图使用有限的标记数据对图像进行分类之前,首先从未标记数据中学习一般特征。
谷歌大脑团队证明了这种半监督学习方法非常具有标签效率,并且更大的模型可以带来更大的改进,特别是对于低标签分数。
随着模型变大,模型在各种标签分数下的最高精度。来源:[2]
NLP 模拟
有趣的是,类似的自我监督方法已经在自然语言处理领域广泛使用。
例如, Word2Vec ,一种将文本转换为嵌入向量的算法,使用了类似的自我监督方法。在这种情况下,我们希望句子中彼此更接近的单词具有更相似的向量表示。
来源:克里斯·麦考密克的图, Word2Vec 教程——跳格模型
因此,我们通过在一个窗口内的单词之间创建配对来创建我们的“积极配对”。我们使用一种叫做负采样的技术来创建我们的负对。
这篇文章包含了对 Word2Vec 算法的直观和详细的解释。
http://jalammar.github.io/illustrated-word2vec/
就像 SimCLRv2 一样,Word2Vec 允许“相似”的单词在潜在空间中具有更相似的向量表示,我们可以将这些学习到的表示用于更具体的下游任务,如文本分类。
关键要点
- 对比学习是一种自我监督、独立于任务的深度学习技术,允许模型学习数据,甚至是没有标签的*。*
- 模型通过学习哪些类型的图像是相似的,哪些是不同的,来学习关于数据集的一般特征。
- SimCLRv2 是对比学习方法的一个示例,该方法学习如何表示图像,使得相似的图像具有相似的表示,从而允许模型学习如何区分图像。
- 对数据有大致了解的预训练模型可以微调用于特定任务,如图像分类当标签稀缺时显著提高标签效率,并有可能超过监督方法。
我希望这篇文章对什么是对比学习,对比学习是如何工作的,以及什么时候你可以将对比学习应用到你自己的项目中,提供一个清晰的直觉。自我监督学习真的很神奇!
参考
【1】Islam 等.利用视网膜眼底图像进行基于深度学习的糖尿病视网膜病变早期检测和分级,2018
理解卷积神经网络
看一看引擎盖下面
图片由维基共享资源上的 Cecbur 提供
在本文中,我将训练一个深度神经网络来对图像进行分类,但我也将让您了解神经网络本身内部正在发生什么,以及卷积实际上是如何工作的。
我们将探讨以下部分。
卷积
∘ 滤波器
∘ 池化
网络
∘ 预处理
∘ 模型
∘ 训练网络
预测
神经网络“看到”了什么?
我将向你展示网络的运行,向你展示当它通过潜入它的“大脑”——网络的各层——做出决定时,它实际上“看到”了什么,我们将一起努力理解它如何决定图像的重要特征。
当你看到一只猫的图像时,你(也就是你的大脑)是如何识别出图像中有一只猫的?即使你以前没有见过具体的动物,你又如何区分猫和狗呢?
这些问题很难回答。也许我们应该从简单的开始…
你如何给计算机编程来识别图像中的猫?一只随机出现在图片中的猫。
你可以通过观察猫的不同特征来捕捉猫的本质,比如毛发的长度和颜色或者耳朵的形状。
但是这种方法有几个大问题。
首先,不同种族的猫看起来很不一样,你不可能捕捉到它们所有的特征。第二,不依赖于猫在图像中位置就能检测出猫的算法并不简单。
如果你观察像素,左边有一只猫的图像和右边有一只猫的图像看起来非常不同。
你如何独立于猫的位置和大小来检测猫?这是一个非常棘手的问题,如果不是不可能的话,通过经典编程来解决。
回旋
卷积的思想是通过以一种非常聪明的方式检测猫的特征来解决上述问题。
我们使用有监督的机器学习算法,而不是显式地对它们编程。
也就是我们拿一个有一定架构的神经网络。然后我们给它看很多带有相应标签的图像(像猫和狗,通过训练,它会学习当我们要对猫狗的图像进行分类时,哪些特征是最重要的。
然而,标准的神经网络不能立即解决上述“大小和位置”问题。
这就是回旋的用武之地。你看,卷积通过使一些像素值变大和变小来突出一些形状。因此他们改变了形象。
过滤
它的工作方式如下。我们用过滤器,这只是二维数组的数字,你应该想象我们通过图像的像素。
对于图像的每个像素值,将滤镜居中放置在该像素的“上方”,并将滤镜的每个数字乘以其正下方的像素。我们将这些新值作为像素放在新图像中。
图片由 Vincent Dumoulin,Francesco Visin 在维基共享资源上提供
这些操作的结果被传递到网络的下一层。
这类似于视觉皮层中的神经元对特定刺激的反应,因此这种架构受到生物大脑的启发。
—维基百科
更低级地说,对于每个过滤器,结果图像是输入图像的变换,其中,根据过滤器,一些特定的形状被突出显示。
联营
CNN 的第二个要素是池的概念。
共用是指通过将 n×n 个像素向下映射到 1 个像素来对图像进行缩减像素采样。同样,您应该想象一个 n×n 的数组在图像上移动,但这次不需要多次映射像素,而是将不相交的正方形映射到像素。
图片由 Andreas Maier 在维基共享资源上提供
此过程将保留重要特征,但会缩小图像大小。例如,如果我们使用一个 2×2 的数组进行池化,得到的图像将缩小 4 倍。
网络
在这一段中,我将向你展示如何处理未经预处理的图像数据!
首先要做的是获取一些数据。
在本教程中,我将从 Kaggle 下载狗和猫的图像。你可以在这里得到它们。
我已经解压了 train.zip 并将文件夹放在名为 data 的目录中。也就是说,我有路径 data/train ,所有的训练图像都在这里。
如果一个图像以“猫”开始,那么它是一只猫的图像,如果它以“狗”开始,那么它是一只狗的图像。我将使用此模式将训练数据分类为狗和猫。
预处理
现在我们需要做一些预处理。我将创建两个函数来完成这项工作。
现在只需创建一些目录,并使用适当的参数运行这些函数。
您可以通过运行以下命令进行快速检查,以确保它正常工作:
输出应该是
11250
11250
1250
1250
现在我们已经完成了预处理部分,好戏就要开始了。
模型
让我们构建将要训练的神经网络的架构,并将其保存到一个名为 model 的变量中。
现在如果我们跑
print(model.summary())
我们得到以下输出
让我们试着从这个图像中理解神经网络的架构。您应该注意的第一件事是,第一次卷积后得到的变换图像看起来是 148×148 的形状,即使我们输入的网络图像是 150×150 的形状。
原因很简单。当第一次卷积发生时,我们使用一个 3 × 3 的阵列在图像上滑动。现在,由于数组中的每个值都需要在图像中的某个像素之上,所以数组的中心不能在图像边缘的任何像素之上,因为这样一来,数组中的一些相邻数字下面就没有像素了。
因此,我们切掉边缘,留下一个 148×148 的图像。
此外,请注意,由于我们使用了一个 2×2 的数组,因此池层的输出要小 4 倍(每边的一半)。
在进入网络的第二状态之前,我们有三对卷积池层。
第二个状态是实际分类发生的地方。在展平层之后,神经网络查看卷积的提取特征,并尝试将它们分类为狗或猫。
通过查看代码,您可能会注意到最后一层仅由一个神经元组成。这个神经元的激活函数是 sigmoid 函数,它是
σ(x)= 1/(1+e^(-x)).
当 x 是一个非常大的负数时,sigmoid(x)变得接近 0 ,当 x 是一个非常大的正数时,sigmoid(x)变得接近 1 。
神经网络因此学习到根据 sigmoid 函数的这种二元行为来对猫和狗进行分类。
既然我们已经设计了模型,我们需要训练它。首先,让我们创建一些生成器。
反过来,这些发生器将把数据成批地输入神经网络。标签将从我们在预处理阶段创建的图像的文件夹名称中继承。
我们还将进行图像增强,这是确保我们的网络“看到”更多数据的一种方式。如果它没有在训练数据中以一个角度看到一只正在攀爬的猫,它可能不会在训练时将其归类为猫。在将图像传送到网络之前,通过以不同方式旋转、移动、剪切和翻转图像,我们将确保训练数据捕获尽可能多的特征。
你可能会注意到我们也在重新缩放图像。这是标准做法,被称为规范化。其思想是,重要的是像素值之间的关系,而不是像素值本身。
当然,这不仅适用于图像数据。
这个生成器很酷的一点是,实际转换的图像没有保存在磁盘上,你的训练数据保持不变。就在它们被馈送到网络进行训练之前,在 RAM 中动态地发生增强。
我们还需要将目标大小设置为 150×150,因为这是我们告诉模型的输入形状。
训练网络
让我们训练模型。
你不需要 TensorBoard 回调,但是如果你知道它是什么,请随意使用它。我将在另一篇文章中讨论这个问题。
当我运行时,我得到了大约 0.76 的验证精度,这意味着它正确地分类了大约 76%以前没有见过的图像。当然,这是在我们调整模型的超参数等等之前。
如果我们得到更多的训练数据,精确度就会提高。另一种获得更好模型的方法是使用迁移学习,在一个巨大的预先训练好的模型上建立你的网络。我将在另一篇文章中向您展示如何做到这一点。通过这种方式,你可以得到 90%以上的精确度。
预测
让我们以下面一只猫为例。
图片由维基共享资源上的 Alvesgaspar 提供
我们可以问我们新训练的神经网络这是猫还是狗。
我运行这段代码时的输出是
cat
非常好。
神经网络“看到”了什么?
让我们试着深入了解一下,试着弄清楚网络认为哪些特性是重要的。
让我们看一下训练数据中的一幅图像,看看它是如何通过网络进行转换的。以下图像是训练好的网络中卷积层的输出,让我们了解网络学习到的哪些滤波器最重要。
作者图片
作者图片
作者图片
如果你仔细观察,你会发现在第一次回旋后,猫的胡须和耳朵都亮了,这表明这些是将它归类为猫的重要特征。
如果你看第三个图像,似乎眼睛也很重要。
这表明,卷积神经网络可以识别形状,而不管形状的大小和位置,因为它通过卷积来学习哪些过滤器最重要。然后,具有 sigmoid 输出的简单神经网络通过反向传播校准其权重,以从卷积中对这些图像特征进行分类。
这篇短文展示了 TensorFlow 必须提供的一些强大的 API。希望这也能给我们一个关于卷积到底是什么的直觉。
如果您有任何问题、评论或顾虑,请在 LinkedIn 上给我发短信。
https://www.linkedin.com/in/kasper-müller-96ba95169/
了解卷积神经网络(CNN)
对最强大的深度学习工具之一及其构建模块的温和介绍
本文将涵盖卷积神经网络(CNN)的所有主要方面,它们如何工作以及这项技术的主要构件。本文中使用的参考资料可以在我的 github 资源库中找到。
卷积神经网络(CNN)或简称为卷积网络是一种至少在其一层中使用卷积运算而不是矩阵乘法的神经网络。
这种类型的网络有效地用于数据元素与其相邻元素具有某种关系的应用中,如图像(由二维像素阵列表示)或时间序列或音频文件(由规则时间帧中的一维数据点样本序列表示)。
由于能够有效地提取图像特征,细胞神经网络被广泛应用于目标检测、人脸识别、语义分割、图像处理和操作等任务中。一些摄像头也有基于 CNN 的智能过滤器,自动驾驶汽车使用这些网络来导航和检测障碍物,许多其他系统都基于这种方法。
卷积运算
卷积是两个函数之间的线性数学运算。给出了函数 x(t) 和 w(a) ,分别称为输入和内核。函数 x 与 w 的卷积超过 a ,对于给定的为:
通配符运算符 (xw) 代表卷积,输出***【s(t)通常称为特征图。
该算子可以扩展到离散函数,这是在一维 CNN 上使用的情况(例如用于时间序列的情况):
而在 2D 卷积的情况下,非常用于图像处理,并且考虑到将I 作为输入图像,并且将 K 作为二维核,卷积可以表示为:**
通常核比图像小,卷积使用一个核来处理整个图像。由于简化的表示,每个卷积核(或层)需要学习少量的参数。
另一方面,由于标准 ann(人工神经网络)使用权重矩阵将给定层的神经元连接到前一层的输出,每个权重将代表一个单一的连接,因此对于相同的任务,ann 将需要学习比等效 CNN 多得多的参数。
图像卷积
正如我已经说过的,卷积广泛用于图像处理。通过改变使用的内核,有可能操纵模糊和形状,改变图像的风格或检测其边缘。下图显示了一些不同内核在基础映像上的应用。
在基础映像上使用不同的内核。内核是在它们各自的图像下表示的矩阵。图片作者。
核应用于图像的每个像素,核和图像受影响区域之间的卷积运算的结果将成为输出图像上的新像素,如下图所示。但是,内核不能应用于边界像素,因为内核的一部分会在图像之外,因此,生成的图像比原始图像稍小。
图像上的二维卷积。内核(蓝色)应用于图像(红色)。操作的结果将成为输出图像的新像素(绿色)。由于内核不能应用于真实图像之外,因此绿色区域是卷积发生的地方,从而产生一个稍小的图像。在卷积过程中,内核将滑过原始图像。图片作者。
在上图中,5x5 内核(蓝色)与 16x12 图像(红色)的卷积将产生 12x8 图像(绿色)。新的宽度和高度可以用下面的公式计算:
在 CNN 上,我们认为卷积是网络的一层,但是每层可以有一个以上的核。输出将具有与内核数量相同的特征映射。
例如,具有 4 个内核的卷积层接收尺寸为(winxhinx 1)的灰度图像,将产生尺寸为(woutxhoutx 4)的矩阵作为输出。该矩阵将不再被认为是图像,而是对应于由该层的四个内核检测的特征的一组四个特征图。
通过在构成网络结构的层上链接特征地图和内核,CNN 可以捕捉图像上存在的各种特征,这是允许这些网络学习识别物体和其他特征的过程。
多核过滤器
在多通道图像中,如 RGB 图像或由网络内层产生的特征图,卷积将在每个通道一个核的情况下发生。所有这些内核一起形成一个滤波器,每个滤波器的内核数量与输入图像的通道数量相同。
多核过滤器示例。图片作者。
每个滤波器将产生一个单一的特征图,因此我们需要通过求和或求平均值来聚集各个内核的输出,从而产生该滤波器的单一输出。
使用 n 滤镜的图层将生成 n 特征地图作为图层的输出。
填料
为了避免图像边缘像素上的内核卷积问题,我们可以在输入上应用填充。我们可以通过简单地在边框上添加更多的像素来放大它。
下图说明了三种类型的填充:零填充(a)在输入图像的周界上插入值 0;将内部像素反射到边界上的反射填充;以及用常数值(包括 0)填充新边框的常量填充 ©。**
填充边界的大小可以由网络的创建者决定,但通常我们选择一个值来消除输出图像上的缩减效果。我们可以用下面的公式计算新的尺寸:
联营
当网络学习最佳滤波器以仅从图像中提取相关特征时,每个滤波器也将产生噪声和与后续层不相关的信息。我们可以在卷积示例中看到,边缘检测器发现了一些不属于狗的像素。
池技术用代表像素组的值来代替像素组。下图说明了大小为 2 的MaxPool
,它将像素分组为 2x2 的正方形,并用最强像素的值替换整个组。类似地,我们可以执行AvgPool
,其中产生的像素是组的平均强度。
最大池操作。图片作者。
作为池层的直接结果,信息被压缩,只保留对后续层最重要的信息并减少干扰。输出也减少了一个因子,该因子取决于池大小(在本例中,输出的宽度和高度是输入的一半),因此每个卷积需要处理的像素更少,结果网络变得更有效。
下图说明了MaxPool
和AvgPool
在应用于狗图像的边缘检测器结果中的应用。
池技术在边缘图像上的应用。图片作者。
MaxPool
的另一个重要方面是,它使网络对输入端的小转换更加健壮。由于相邻像素被所有像素中的最高值替换,如果转换将最重要的像素保留在同一组中,结果将保持不变。
进展
我们还可以使用步长卷积来降低图像(或特征图)在各层中的维数。stride 参数表示每次迭代后内核将行走多少像素(或矩阵元素)。
在前面的例子中,我们使用了 stride = 1,这意味着内核将移动到下一个像素,当一行结束时,它将继续下一行。下图的上半部分通过对红色输入应用 5x5 内核来说明这种情况。蓝色方块代表每次迭代中内核的中心。
图片的下半部分代表步幅= 2 的情况。在这种情况下,当在行上行走时,内核将跳过一个像素,当行结束时,它也将在继续之前跳过一整行。正如我们所看到的,内核停止的像素比前一种情况少,所以生成的图像更小。
比较跨距= 1(上)和跨距= 2(下)的卷积。产生的输出大小不同。图片作者。
当我们想要恢复小于输入的输出时,维数减少是很重要的,例如编码器想要压缩图像,或者二进制分类器有一个单一的值作为输出。
我们可以为宽度( wstride )和高度( hstride )定义不同的步幅,因此可以使用下面的表达式来计算得到的尺寸。
转置卷积
在其他应用中,我们可能希望在一层之后增加输出的维度。一些生成方法通常从压缩表示(如潜在向量)开始,并通过层增加维度,直到输出生成最终图像。
实现这一点的一种方法是使用转置卷积(很多时候会被反卷积误操作),即在输入图像通过“传统”卷积之前,结合使用填充和步幅来放大输入图像,从而使输出大于输入。
下图说明了通过使用核为 3x3 且步幅= 1 的转置卷积,从 3x3 输入生成 5x5 图像的过程。
转置卷积。图片作者。
在 5x5 图像中,内核为 3x3 且步幅= 1 的“传统”卷积将生成 3x3 特征图作为输出,因此我们需要使用相同的参数执行转置卷积,以实现相反的操作。
它分两步走:
- 图像将在其原始像素(红色)之间以及边界上插入零值像素(灰色)。
- 现在,卷积将应用于放大的图像,内核为 3x3,步幅= 1。
为了计算转置卷积后的输出维数,我们可以使用以下公式:
转置卷积并不是增加图层输出维度的唯一方法。其他架构使用传统的调整大小技术,如最近邻插值,然后是传统的卷积层。
棋盘文物
转置卷积的一个缺点是,当通过图像时,内核会重叠,从而加强这些区域中像素的重要性。结果,生成的图像(或特征图)将具有周期性出现的棋盘状伪像。这种机制可以在下图中看到。
产生棋盘状伪像的机制。图片作者。
通过使用其他技术,如上面提到的调整卷积大小,我们可以避免这种影响。
结论和意见
关于卷积有很多东西要学,但第一步是理解基础知识,我希望这篇文章对很多人有帮助。
这篇课文改编自我的硕士学位论文。
特别感谢我的狗布鲁斯,他好心地让我给他拍照并用作例子。他是最好的男孩。
如果你喜欢这个帖子…
支持我一杯咖啡!
给我买杯咖啡!**
看看这个很棒的帖子
**</5-tips-to-start-a-career-in-data-211ad15a7ca8>
参考
奥登纳等。艾尔。反卷积和棋盘状工件
古德费勒等人。艾尔。深度学习。第九章:卷积网络
一般化和网络设计策略。技术报告 CRG-TR-89–4
Dumoulin,v .,Visin,F.: 深度学习卷积算法指南。arXiv:1603.07285 (2016 年)
拉德福德,a .,梅斯,l .,钦塔拉,S.: 深度卷积生成对抗网络的无监督表示学习。**
手动理解卷积与张量流
你觉得我们可以手工匹配 TensorFlow 吗?你打赌!
图片由作者提供,灵感来自来源。
1.目的
TensorFlow 和各种其他用于机器学习的开源库,如 SciPy,提供了这些用于执行卷积的内置函数。然而,尽管这些函数很好,但是打开引擎盖去发现代码背后的强大功能是值得的。在我看来,如果没有卷积层,计算机视觉就会像蝙蝠一样瞎。因此,我希望您喜欢这篇文章,因为我们将深入研究构成卷积层的卷积,并一起了解全局。
我为此制作的 Jupyter 笔记本在我的 GitHub 上。
2.背景
卷积对于计算机视觉中的深度学习任务来说并不新鲜。它们只是图像处理中使用的一种技术。在图像处理中,卷积运算是将输入图像的每个元素与其局部相邻元素相加的过程,通过内核进行加权。输出大小将取决于以下因素:
图片由作者提供,灵感来自来源。
3.输入过滤器
玉米粒有各种形状和大小。这些内核组成了滤波器,滤波器是卷积层中使用的一个参数。对于本文,我将坚持使用基于边缘检测的普通过滤器:
图片作者。
4.输入音量
为了便于对示例进行数学检查,我将使用 5x5x3 的随机输入量:
图片作者。
5.零填充
通常,零填充被添加到输入图像中。因此,在本例中,我将添加一个零填充,P=1,这将返回 7x7x3 的输入量:
图片作者。
6.进展
对于这个例子,步幅将是 S=2。
7.手算输出量
将过滤器通过左上方输入体积的局部感受野:
图片作者。
按步幅移动,S=2:
图片作者。
手动将它投入使用:
现在将过滤器通过整个输入体积:
图片由作者提供,灵感来自来源。
8.使用张量流
厉害!与我在上一节中手工做的相匹配。现在让我们试着以 S=1 的步幅传递一个图像。
图片作者。
图片作者。
使用 TensorFlow:
图片作者。
不出所料!TensorFlow 和手动定制功能产生相同的卷积图像。边缘检测过滤器现在真的更有意义了,因为你可以看到玩具驯鹿周围的线条。
这是卷积神经网络(CNN)如此伟大的原因之一。随着卷积层被训练,权重(核)被更新,并且有希望创建有意义的特征图,以使用训练过的模型来执行你的计算机视觉任务。
感谢您的阅读!我希望你已经学到了一些关于卷积的新知识,如果你还不能看到的话,我希望你能在这之后看到更大的图景。
9.参考
1.内核(图像处理)[https://en . Wikipedia . org/wiki/Kernel _(图像处理)]
2.TF . nn . conv 2d[【https://www.tensorflow.org/api_docs/python/tf/nn/conv2d】T2
3.Python。特拉维斯·奥列芬特。用于科学计算的 Python,《科学与工程中的计算》, 9,10–20(2007 年 b) K. Jarrod Millman 和 Michael Aivazis。面向科学家和工程师的 Python,科学与工程中的计算,13,9–12(2011)
4.张量流。马丁·阿巴迪、阿希什·阿加瓦尔、保罗·巴勒姆、尤金·布莱夫多、陈质枫、克雷格·西特罗、格雷格·科拉多、安迪·戴维斯、杰弗里·迪恩、马蒂厄·德文、桑杰·格玛瓦特、伊恩·古德菲勒、安德鲁·哈普、杰弗里·欧文、迈克尔·伊萨德、拉斐尔·约泽福维茨、杨青·贾、卢卡斯·凯泽、曼朱纳斯·库德鲁尔、乔希·莱文伯格、丹·曼内、迈克·舒斯特、拉杰特·蒙加、雪莉·穆尔、德里克·默里、克里斯·奥拉、黄邦贤·施伦斯、伯努瓦·施泰纳 TensorFlow:异构系统上的大规模机器学习,2015。tensorflow.org 提供的软件。
5.SciPy。保利·维尔塔宁、拉尔夫·戈默斯、特拉维斯·奥列芬特、马特·哈伯兰、泰勒·雷迪、戴维·库尔纳波、叶夫根尼·布罗夫斯基、皮鲁·彼得森、沃伦·韦克塞、乔纳森·布赖特、斯蒂芬·范德沃特、马修·布雷特、约书亚·威尔逊、贾罗德·米尔曼、尼古拉·马约罗夫、安德鲁·纳尔逊、埃里克·琼斯、罗伯特·克恩、埃里克·拉森、希杰·凯里、i̇lhan·波拉特、余峰、埃里克·摩尔、杰克·范德普拉斯、丹尼斯·拉克萨尔德、约瑟夫·佩尔(2019)SciPy 1.0-Python 中科学计算的基本算法。预印本 arXiv:1907.10121
6.NumPy。特拉维斯·奥列芬特。美国 NumPy 指南:特雷戈尔出版公司(2006 年)。(b)斯蒂芬·范德沃特、克里斯·科尔伯特和盖尔·瓦洛夸。NumPy 数组:高效数值计算的结构,科学与工程中的计算,13,22–30(2011)
7.IPython。费尔南多·佩雷斯和布莱恩·格兰杰。IPython:用于交互式科学计算的系统,科学与工程中的计算,9,21–29(2007)
8.Matplotlib。亨特,“Matplotlib:2D 图形环境”,《科学与工程中的计算》,第 9 卷,第 3 期,第 90–95 页,2007 年。
9.熊猫。韦斯·麦金尼。Python 中统计计算的数据结构,第 9 届科学中的 Python 会议录,51–56(2010)
10.sci kit-学习。法比安·佩德雷戈萨、加尔·瓦洛夸、亚历山大·格拉姆福特、文森特·米歇尔、贝特朗·蒂里翁、奥利维尔·格里塞尔、马蒂厄·布隆德尔、彼得·普雷登霍弗、罗恩·韦斯、文森特·杜伯格、杰克·范德普拉斯、亚历山大·帕索斯、戴维·库尔纳波、马蒂厄·布鲁彻、马蒂厄·佩罗特、爱德华·杜谢斯奈。sci kit-learn:Python 中的机器学习,机器学习研究杂志,12,2825–2830(2011)
11.sci kit-图像。斯蒂芬·范德沃特、约翰内斯·l·舍恩伯格、胡安·努涅斯-伊格莱西亚斯、弗朗索瓦·布洛涅、约书亚·d·华纳、尼尔·雅戈、伊曼纽尔·古亚尔特、托尼·于和 scikit-image 供稿者。sci kit-Image:Python 中的图像处理,PeerJ 2:e453 (2014)
用随机几何图形理解 DBSCAN 和 K-NN
作者提供的图片
实践教程
从距离矩阵到图形
在这篇文章中,我们将更详细地探索空间网络的具体属性,并使用它们来深入了解两种流行的机器学习算法,k-最近邻和 DBSCAN 。
我们从关注最简单的例子随机几何图形 (RGG)开始探索空间网络。rgg 是通过简单地将节点随机放置在某个(比如说,2D)空间中,并在某个距离 d 内的任何一对节点之间添加一条边来构建的
虽然这种结构可能看起来像是只有最纯粹的数学家才会玩的那种东西,但它是一种令人惊讶的有用的图形结构,在现实世界中具有实际应用,例如用于近距离连接无人机的自组网络。
亚马逊最近甚至有一项这类应用的专利,你可以在 USPTO 阅读更多内容,内华达大学机器人实验室的研究人员提出了一种无人机协调搜救行动的算法。
随机几何图形
事不宜迟,让我们建造我们自己的 RGG。我们首先在单位正方形中随机放置 100 个节点:
下一步是连接在一定距离 d 内的所有节点。为此,我们计算包含所有节点对之间距离的距离矩阵。
计算全距离矩阵有点浪费,因为它需要 O(N)个工作。一种更复杂的方法是使用 KDTrees 来实现线性性能,但这超出了本文的范围,因为我们只是试图熟悉这些概念,而不是开发一个实际的实现。
使用这个矩阵,我们可以很容易地计算每对节点之间的距离分布 P(d)和距离的累积分布 C(d)。
该分布遵循准钟形曲线(实际分布更有趣一点)。从累积分布可以清楚地看出,根据我们为 RGG 选择的阈值 d,我们将得到或多或少的边缘。
在 GitHub 存储库中,您可以使用一个交互式工具来查看距离矩阵和图形在您更改阈值时是如何变化的:
如果你更倾向于数学,你可以把这个阈值距离矩阵想象成图的一个加权邻接矩阵。在以后的文章中,我们会有更多关于邻接矩阵的内容,但是现在你需要知道的是,邻接矩阵只是一个矩阵,其中每个非零元素对应于两个节点之间的一条单独的边。
k-最近邻
k-最近邻算法是一个众所周知的机器学习算法家族,可用于分类或回归。这两种情况下的基本思想都相当简单。如果你想知道一个新数据点的标签或值应该是什么,你可以咨询它的 k 近邻,然后简单地采用大多数。k 的具体值是在训练模型时必须定义的超参数。
与随机几何图形的联系现在应该很清楚了。我们简单地将每个节点与其 k 个最近的节点连接起来,而不是仅仅将每个节点与某个距离 d 内的所有其他节点连接起来。
当我们玩这个游戏,并连接每个先前的节点到它的 5 个最近的邻居,我们得到:
如果你仔细检查这个矩阵,你会开始注意到一些不寻常的东西。它是不对称的!确认这一点最容易的地方是沿着主对角线,你偶尔会注意到一边有一个值,而另一边没有。这似乎是一个非常奇怪的结果。如果我们的距离度量是对称的,欧几里德距离肯定是对称的,那么网络怎么可能不是对称的呢?原因可以用一个简单的例子来说明。
想象一下,由于某种奇怪的命运转折,你发现自己完全孤独,迷失在撒哈拉沙漠中。在那个时刻,地理上离你最近的 5 个人可能在最近的城市,但是他们都有比你更近的人!你只是一个古怪的异类。验证这种直觉的一种方法是检查节点的入度分布。您会发现,与每个节点恰好有 k 条传出边的出度不同,一个节点可以有更多或更少的传入边,这取决于它与聚类外围的接近程度以及有多少离群值。
这是关于 k-NN 算法的基本观点。更中心的节点将通过许多短距离链路连接,而离群点将连接到较远且具有很少或根本没有传入边的节点。
一个形象化的观点可以让我们明白这一点。这里我们绘制了与上图中的距离矩阵相对应的有向图。如果你仔细观察靠近图中心的孤立节点,你会注意到,虽然它有 5 条长的向外的边,但由于它的外围位置,它只有一条向内的边……迷失在撒哈拉沙漠的中央。
自然,如果我们要测量这个图中的距离分布,它看起来会与我们之前看到的非常不同,因为我们严格限制了允许的距离,只保留每个节点的 k 个最短外出边。
基于密度的噪声应用空间聚类
基于密度的含噪声应用空间聚类(DBSCAN)是一种无监督聚类算法,其明确目标是以有效的方式识别任意形状的聚类。最初的 KDD 论文将算法概括为:
为了找到一个聚类,DBSCAN 从一个任意点 p 开始,并从 p wrt 中检索所有密度可达的点。Eps 和 MinPts。如果 p 是一个核心点,这个过程产生一个聚类 wrt。Eps 和 MinPts(见引理 2)。如果 p 是一个边界点,没有点是从 p 密度可达的,DBSCAN 访问数据库的下一个点。
我们可以通过将该算法转换成网络算法来更直观地表达该算法,该网络算法明确地利用了我们上面讨论的 RGG 和 k-NN 算法的特征。DBSCAN 通过连接(用有向边)距离小于一定距离的点(节点)来识别数据集中的聚类(就像在 RGG s 中一样)。外围节点和离群节点的输出少于 k(就像在中的 k-NN )。相比之下,任何在规定距离内有 k 个或更多邻居的节点称为“核心节点”。最后,数据中的聚类可以用结果图中的连接组件来唯一标识。
这种显式构建每个节点的邻域的方法计算量大,需要 O(N)存储空间,而更有效的实现(如原始论文中的实现)可以显著降低内存和计算需求。
def net_DBSCAN(X, eps=0.17, min_samples=5):
# Building the neighborhood matrix and truncate it
# at the maximum distance
matrix = distance_matrix(X, X)
matrix[matrix >= eps] = 0 # Build the directed graph using the non-zero elements of the matrix
G = nx.DiGraph()
G.add_edges_from(np.asarray(np.nonzero(matrix)).T) # Create an undirected version of the network for ease of core computation
G2 = G.to_undirected() # Find all core nodes
results = {}
results['core_sample_indices_'] = [node_i
for node_i, k in G2.degree()
if k >= min_samples-1] # Use the connected components to label each node
# as belonging to each cluster
labels = []
for label, comp in enumerate(nx.connected_components(G2)):
for node in comp:
labels.append(label) results['labels_'] = np.asarray(labels)
results['G'] = G # Identify the outlier nodes.
results['non_core'] = set(np.arange(X.shape[0])) - set(results['core_sample_indices_']) return results
当我们将上面的代码应用到 two moons 数据集时,我们得到:
其中蓝色和紫色表示数据集中的两个集群,绿色方块表示“非核心”节点。与 sklearn 实现完美匹配:
我们希望你喜欢这种看待古老的 k-NN 和 DBSCAN 算法的方式,并对它们如何工作有了新的认识。你可以在我们的伙伴 GitHub 库【https://github.com/DataForScience/Graphs4Sci找到这篇文章中分析的所有代码
当然,别忘了注册我的时事通讯,这样你就不会错过另一篇文章了。
理解深度可分卷积和移动网络的效率
移动网和深度可分卷积的解释
简介:
在卷积神经网络(CNN)中,2D 卷积是最常用的卷积层。MobileNet 是一种 CNN 架构,速度更快,模型更小,使用了一种新的卷积层,称为深度方向可分离卷积。由于模型的尺寸较小,这些模型被认为对于在移动和嵌入式设备上实现非常有用。因此得名 MobileNet。
关于 MobileNets 的原始论文可在此处获得— MobileNets:用于移动视觉应用的高效卷积神经网络
表 1。MobileNet 与 GoogleNet 和 VGG 16 的参数和准确性比较(来源:原始论文中的表格)
表 1 清楚地显示了即使是最深入的 MobileNet 架构也比著名的 CNN 架构具有更少的参数。较小的 MobileNets 只有 130 万个参数。此外,模型的大小明显更小。虽然 VGG16 型号可以占用高达 500 MB 的磁盘空间,但 MobileNet 只需要 16–18MB。这使得它非常适合在移动设备上加载。
图一。MobileNets 可以用于移动设备上的对象检测、分类、属性检测,甚至是地标识别(来源:图片来自原论文)
深度方向卷积;
差异 —
2D 卷积和深度卷积之间的主要区别在于,2D 卷积是在所有/多个输入通道上执行的,而在深度卷积中,每个通道保持分离。
接近 —
- 3 维输入张量被分成单独的通道
- 对于每个通道,输入与滤波器(2D)进行卷积
- 然后将每个通道的输出叠加在一起,得到整个 3D 张量的输出
图形描述 —
图二。深度方向卷积的图解说明(来源:图片由作者创建)
深度方向可分离卷积;
深度方向卷积通常与另一个步骤(深度方向可分离卷积)结合使用。这包含两个部分— 1 .过滤(所有前面的步骤)和 2。组合(根据需要,组合 3 个颜色通道以形成“n”个通道——在下面的示例中,我们将看到如何组合 3 个通道以形成 1 个通道输出)。
图 3。深度方向可分离卷积的图解说明(来源:图片由作者创建)
为什么深度可分卷积如此高效?
深度方向卷积是 -所有通道上的 1x1 卷积
假设我们有一个大小为 8x8x3 的输入张量,
并且期望的输出张量的大小是 8×8×256
在 2D 回旋——
所需的乘法次数—(8×8)x(5x5x 3)x(256)=1,228,800
在深度方向可分离卷积中
所需的乘法次数:
a.滤波 —分成单通道,所以需要 5x5x1 滤波器来代替 5x5x3,由于有三个通道,所以需要的 5x5x1 滤波器总数为 3,所以,
(8x8)x(5x5x 1)x(3)= 3800
b.合并 —所需通道总数为 256,因此,
(8x8) x (1x1x3) x (256) = 49,152
乘法总数= 3800+49152 =53952
因此,2D 卷积需要 1,228,800 次乘法运算,而深度方向可分离卷积只需要 53,952 次乘法运算即可达到相同的输出。
最后,
1,228,800/53,952 = 23 倍减去所需乘法运算
因此深度方向可分卷积的效率很高。这些是在 MobileNet 架构中实现的层,用于减少计算数量并降低功耗,以便它们可以在没有强大图形处理单元的移动/嵌入式设备上运行。
MobileNet
- 使用 深度方向可分离卷积
- 使用两个 S 收缩超参数:
a.调整通道数量的宽度乘数
表二。MobileNet 中的宽度乘数(来源:原始论文中的表格)
b.分辨率倍增器,调整特征图和输入图像的空间尺寸
表 3。MobileNet 中的分辨率乘数(来源:原始论文中的表格)
架构—MobileNet 的第一层是全卷积,而所有后续层都是深度方向可分离的卷积层。所有层之后是批量标准化和 ReLU 激活。最终分类层具有 softmax 激活。完整的架构如表 4 所示。
表 4。MobileNet 架构(来源:原始论文中的表格)
图 4。左:标准卷积层,右:MobileNet 中深度方向可分离的卷积层(来源:图片来自原论文)
图 4 显示了普通 CNN 模型和 MobileNets 在架构流程上的区别。在图像的左侧,我们看到一个 3x3 卷积层,后面是批归一化和 ReLU,而在右侧,我们看到深度方向可分离卷积层,由一个 3x3 深度方向卷积和一个批范数和 ReLU 组成,后面是一个 1x1 点方向卷积,再后面是一个批范数和 ReLU。
结论:
MobileNets 是专门为移动设备设计的非常高效的小型深度学习架构。由于尺寸较小,与较大的全卷积架构相比,精度会有所下降,但这种情况非常微小。例如,在 Stanford dogs 数据集上,Inception V3 模型的准确率为 84%,而最大的 MobileNet 的准确率为 83.3%。但是如果我们看看每个模型架构的参数数量,Inception V3 有 2320 万个参数,而 MobileNet 只有 330 万个参数。此外,仅仅通过使用宽度倍增器或分辨率倍增器,就可以制作更小更快的 MobileNet 版本。这使得 MobileNets 成为移动和嵌入式设备上非常受欢迎的深度学习模型。
接下来,我打算展示如何使用 TensorFlow 在 python 中从头开始创建 MobileNet 架构。
参考文献:
- Howard,A. G .,Zhu,m .,Chen,b .,Kalenichenko,d .,Wang,w .,Weyand,t .,Andreetto,m .和 Adam,H. (2017)。MobileNets:用于移动视觉应用的高效卷积神经网络
理解设计文档原则
行业笔记《数据科学家生产力指南》
使用正确的设计文档有效运行您的数据项目
来源( Unsplash
一个好的设计文档离不开一个好的数据科学家和工程师——Vincent Tatan,Google ML 工程师
在大多数情况下,工程师花了 18 个月的时间思考和撰写如何最好地为客户服务的文档。— 尤金·严,亚马逊数据科学家
上个月,我展示了设计文档不可否认的重要性,它将设计文档解释为构建和运行机器学习系统的概念灯塔。
由于设计文档非常重要,我很乐意分享我创建设计文档的原则,以有力地执行您的数据项目。
为什么?
来源( memegen )
设计文档提供了 概念灯塔来指导您的数据项目 。
- 设计文档从概念上指导 您在每一步中理解您的目标、影响和执行,以使利益相关者受益。设计文件确保您的项目落地产生影响。
- 设计文档为您节省设计时间在执行之前突出实施和替代解决方案。
- 设计文档主持团队间的讨论,集体讨论最佳解决方案并实施数据项目。
- 设计文档是永久的人工制品为未来的合作巩固你的想法。
谁啊。
你的读者是你写设计文档的关键原因。在每篇设计文档中,你必须了解你的受众,例如:
- 你自己:确定学习旅程,集思广益,制定未来有影响力的项目。
- 团队成员:识别协作点、升级和系统特定影响。在设计文档中,您需要将您的假设与团队成员的现有知识保持一致。
- 跨部门:识别跨部门协作。你的设计文档需要传达先验知识和成功标准。
- 高管:做决策。您需要提供可靠的建议来推动高级指标(例如:用户采用率、收入和商誉)
- **外部:**培养专业声誉和网络。你需要提供可靠的外卖,避免使用术语。
为合适的空间(环境)寻找合适的设计文档类型
我想强调三种不同的环境,它们需要不同类型的设计文档。对于术语,我将强调这些环境为解决方案空间:架构空间、实现空间和想法空间。
具有各自解决方案空间的设计文档层次结构(由作者提供)
建筑空间(稳定)
设计文件特征
- 目标:记录解决复杂问题并直接影响用户的系统的高层架构。
- 主要受众:高管、技术主管
- 时间:缓慢平稳。理想情况下,除非出现中断,否则它很少发生变化。
设计文件的类型
- 架构文档:记录具有明确目标的高层系统架构,例如,project Google Loon 旨在解决可靠的互联网基础设施匮乏的问题。
- **北极星指标:**确定衡量高管沟通成败的关键指标。例如,在面向客户的应用中,衡量标准将是用户采用率,而 it 将在反滥用应用中保护用户。
实施空间(启动)
设计文档特征
- 目标:促进系统设计实施,例如数据存储、ML Ops、数据隐私访问等。该文档确保数据产品得到正确的发布、扩展和评估。
- 主要受众:技术领导、跨部门(尤其是上下游应用)
- 时间:中度变化
设计文件的类型
- 系统设计:突出系统实施流程图、上下游交互、数据存储、申诉等。
- **时间表发布文档:**强调系统发布的进度和时间表。在谷歌,我们有标准的操作程序(SOP)来确保每次发布都得到适当的维护和扩展。
- **隐私文档:**管理关于用户或其他敏感机构的机密数据。
想法空间(实验)
设计文档特征
- 目标:试验小的调整、想法头脑风暴和快速反馈收集。创意空间允许数据专业人员寻找创意,以快速产生重大影响。
- 主要受众:包括跨部门的所有人
- 时间:高度动态。每天都有一个寻呼机被起草、分析和丢弃。你的目标是迅速失败,然后继续前进。
设计文件的类型
- **一页纸:**快速移动设计文档,以促进早期的想法审查。随着想法成长为成熟的概念,一页纸将被提升为两页纸和系统设计文档。
- 学习之旅:根据过去的演示、设计文档、发布的模型来确定学习之旅。在大公司,学习之旅对于跟踪跨部门和地区合作中快速发生的变化是必要的。
- **执行前评估:**如果我们推出一个产品(例如:模型/调整),预期的影响是什么?
- 执行后评估:在过去推出的产品后有什么影响(例如:模型/调整)?
- **预分析:**当产品推出时,哪些可能会出错?
- **事后分析:**过去推出产品后有哪些出了问题?
“如果你不知道你想在你的演讲中达到什么目的,你的观众永远也不会知道。”—哈维·戴蒙德
管理设计文档的五个原则
这些是关于如何管理设计文档的简单指南。
- 从想法开始:总是在一页纸上开始你的实验(想法空间)。创建一个思想实验,并在投入更多时间之前迅速进行头脑风暴。
- **在较低层次的空间投入时间:**空间越高(想法→实现→架构),就应该投入更多的时间。最多花 1 周在一页纸上(想法空间),1 个月在实施/分析空间,1 个季度/学期在架构空间。当然这取决于范围,但你得到了要点。
- 优先考虑有前途的 One Pagers: 根据影响推广和调整你的 One Pagers。如果这个想法是为了交叉协作,花更多的时间考虑你的目标如何与高层空间(北极星度量、系统设计等)保持一致。
- **登陆北极星:**对于一般的成功指标,关注时间投入最低的想法(例如:对机器学习的小调整),对北极星指标有很大影响。这有助于你为在更高的空间着陆打下坚实的基础。
- 直接指向金块:你的设计文档需要尽可能直接地将观众指向金块。空间越高,这个金块应该越直接。
结论
一般来说,通过了解这些原则,你将创建设计文档来帮助你:
- 在所有概念空间中导航动态的、不明确的或未被很好理解的项目。
- 产生具有高影响力的项目,这些项目可以促进高管沟通。
- 优化时间投资,以获得突出北极星指标的最佳效果。
我希望这篇文章能帮助您创建设计文档,并有效地运行您的数据项目。
索利·迪奥·格洛丽亚。
关于作者
文森特用 ML @ Google 对抗网络滥用。文森特使用高级数据分析、机器学习和软件工程来保护 Chrome 和 Gmail 用户。
除了在谷歌的工作,文森特还是《走向数据科学媒体》的特约撰稿人,为全球 100 多万观众的有志 ML 和数据从业者提供指导。
在空闲时间,文森特在佐治亚理工学院攻读硕士学位,并为铁人三项/自行车旅行进行训练。
最后,请通过 LinkedIn , Medium 或 Youtube 频道 联系文森特
参考
- Eugene Yan post 如何为机器学习系统撰写设计文档
- Clement Mihailescu 谈什么是软件工程中的设计文档
理解数据科学 R 中的降维和主成分分析
什么是降维,我们如何使用 R 中的主成分分析来确定重要的特征
当你在数据科学和分析领域工作时,处理高维数据是其中的一部分。您可能有一个包含 600 个甚至 6000 个变量的数据集,其中一些列在建模中被证明是重要的,而另一些是无关紧要的,一些是相互关联的(如体重和身高),还有一些是完全相互独立的。我们非常清楚使用数以千计的特征对于我们的模型来说既乏味又不切实际,因此我们的目标是创建一个维数减少的数据集(全部不相关),以尽可能多地解释原始数据集中的变化。从高维数据到低维数据的转换需要我们提出 a)统计解决方案和 b)数据压缩活动,一种称为 PCA(主成分分析)的技术。
图片由 @marcojodoin 在【unsplash.com】T2 上
在本文中,我们将讨论三个目标:
- 理解降维的必要性
2.执行 PCA 并分析数据变化和数据组成
3.确定在数据识别中最有用的特征
“PCA 是机器学习中的一种无监督学习技术,它通过显示数据集中的最大变化(通过关注实际区分数据的变量),将高排名矩阵的维度降低为低排名矩阵,从而捕捉原始数据的本质。”
PCA 产生主成分(等于特征的数量),这些主成分按照方差的顺序排列(PC1 显示最大方差,PC2 显示第二大方差,依此类推)。为了更详细地理解这一点,让我们使用 r 中的 prcomp()函数来处理一个样本数据集。我使用了一个在data . world**(一个开源平台)**上可用的数据集,它为您提供了几种不同品牌的披萨的营养成分。我只保留了 A、B & C 品牌的披萨。csv 使我们的分析简单易懂。
步骤 1:导入库并将数据集读入表格
确保您在当前目录中。csv 被放置(使用 getwd())或者能够使用 setdw()将其更改为当前文件。
library(dplyr)
library(data.table)
library(datasets)
library(ggplot2)data <- data.table(read.csv("Pizza.csv"))
第二步:理解数据
这些函数告诉你 a)维数,即矩阵的行 x 列 b)数据的前几行和 c)变量的数据类型。
dim(data)
head(data)
str(data)
基本初始功能(图片由作者提供)
第三步:获取主成分
我们希望让我们的目标变量为空,因为我们希望我们的分析告诉我们有不同类型的比萨饼品牌。一旦我们完成了这些并复制了数据集以保持原始值,我们将运行 prcomp()。scale = TRUE,以便在分析前将变量缩放到单位方差。
pizzas <- copy(data)
pizzas <- pizza[, brand := NULL]pca <- prcomp(pizzas, scale. = TRUE)
关于 prcomp()需要知道的重要事情是,它返回 3 样东西:
- x : 存储数据的所有主要成分,我们可以使用这些成分来绘制图表,并了解 PC 之间的相关性。
- sdev :计算标准差,了解每台电脑在数据上有多少变化
- **旋转:**确定哪个加载分数对 PCA 图有最大影响,即最大坐标(绝对值)
第四步:使用 x
尽管目前我们的数据具有两个以上的维度,但我们可以使用 x 绘制我们的图表。通常,前几个 PCs 捕获最大方差,因此 PC1 和 PC2 绘制在下面以理解数据。
pca_1_2 <- data.frame(pca$x[, 1:2])
plot(pca$x[,1], pca$x[,2])
PC1 对比 PC2 图(图片由作者提供)
该图清楚地向我们展示了前两个 PCs 如何根据定义它们的特征将数据分成三个聚类(或 B & C 比萨饼品牌)。
步骤 5:使用 sdev
这里我们使用 sdev 的平方,并计算每台电脑的变化百分比。
pca_var <- pca$sdev^2pca_var_perc <- round(pca_var/sum(pca_var) * 100, 1)barplot(pca_var_perc, main = "Variation Plot", xlab = "PCs", ylab = "Percentage Variance", ylim = c(0, 100))
百分比变化图(图片由作者提供)
这个柱状图告诉我们,PC1 显示了几乎 60%的数据变化,PC2 显示了 20 %, PC3 显示了 12%,其余的 PC 捕捉到的数据变化很少。
步骤 6:使用旋转
这一部分解释了在区分比萨饼品牌时,哪些特征最重要;旋转将权重分配给特征(技术上称为负载), PC 的“负载”数组称为特征向量。
PC1 <- pca$rotation[,1]PC1_scores <- abs(PC1)PC1_scores_ordered <- sort(PC1_scores, decreasing = TRUE)names(PC1_scores_ordered)
(图片由作者提供)
我们看到变量*‘cal’(样品中每 100 克的卡路里量)是区分品牌的最重要特征,其次是‘mois’*(样品中每 100 克的水含量),依此类推。
第七步:利用两个最重要的特征区分品牌
ggplot(data, aes(x=data$cal, y=data$mois, color = data$brand)) + geom_point() + labs(title = “Pizza brands by two variables”)
通过权重最大的柱形成聚类(图片由作者提供)
该图清楚地显示了如何代替数据集中给我们的 8 列,仅两列就足以理解我们有三种不同类型的比萨饼,从而使 PCA 成为一种成功的分析工具,将高维数据减少到较低的一列,用于建模和分析目的。
这篇文章背后的灵感来自于约翰·霍普斯金在 Coursera 上开设的数据科学专业的第三门课程和 Josh Starmer 的 StatQuest。
将离散卷积理解为多项式乘法
卷积是数字信号处理中的一种基本运算
作者插图
卷积是数字信号处理中的基本运算。它通常由以下公式定义:
DSP 书籍从这个定义开始,详细解释如何计算。我们通过傅立叶变换了解了时域卷积与频域乘法的相同之处。有限和无限脉冲响应滤波器的操作用卷积来解释。这成为所有数字滤波器设计的基础。然而,卷积本身的定义仍然有些深奥。对我来说,这个定义一直有点神奇,直到我仔细研究了多项式代数。然后,关于这个定义如何自然产生的实现发生了。从那以后,它一直伴随着我。我妹妹今天让我解释卷积运算。最初,我试图用典型的 DSP 方法来解释,但毫无效果。最后,我回到了多项式乘法的方法,这对她来说是显而易见的。所以它来了。
考虑两个简单的多项式:
计算他们的产品:
如果我们把 h(x)写成
那么我们可以将 h(x)的系数匹配为:
一种模式似乎正在形成。让我们更大胆地使用二次多项式:
这是他们的产品:
h(x)现在具有系数为 4 的度:
由以下等式给出:
是时候概括了。我们现在来看两个 J 次多项式 f(x)和 l 次多项式 g(x)。
它们的乘积是 J+1 次多项式 h(x ):
其中多项式系数由以下关系式给出:
假设 f_k 和 g_k 对于没有指定它们的索引被假设为零。即,对于负 n,f_n 和 g_n 均为零,n > J 时 f_n 为 0,n > L 时 g_n 为零,建议读者检查 h_n 的定义是否与之前 1 次和 2 次多项式相乘的结果一致。事实上,如果我们忽略无穷和的收敛问题,那么假设多项式系数分别在 f(x)和 g(x)的指数[0,J]和[0,K]之外为零,那么将该公式写成:
我们现在可以为多项式 f(x),g(x)和 h(x)的系数形成(有限)序列 f[n],g[n],h[n],并将卷积运算定义为:
其中该定义源于将序列视为相应多项式的系数。
总结:如果我们把数字序列看成多项式的系数,那么它们的卷积不过是对应多项式的乘积。
关于收敛性的一个注释:一般来说,收敛对于有限序列来说不是问题。然而,它与 IIR 滤波器相关,因为它们的脉冲响应有无限多项。从实分析可以看出,如果序列 f_n 和 g_n 是绝对可和的,则卷积和是收敛的。即,如果总和:
收敛,那么它们的卷积对每个 n 也收敛。
理解领域适应
了解如何设计深度学习框架,使他们能够适应领域
詹妮弗·罗在 Unsplash 上的照片
注意——我假设读者对神经网络及其工作有一些基本的了解。
领域适应是计算机视觉的一个领域,我们的目标是在源数据集上训练神经网络,并在与源数据集显著不同的目标数据集上确保良好的准确性。为了更好地理解领域适配及其应用,让我们先来看看它的一些用例。
- 我们有许多用于不同目的的标准数据集,如用于德国交通标志识别的 GTSRB,用于交通灯检测的 LISA 和 LARA 数据集,用于对象检测和分割的 COCO 等。然而,如果你想让神经网络很好地完成你的任务,例如印度道路上的交通标志识别,那么你必须首先收集印度道路的所有类型的图像,然后为这些图像做标记,这是一项既费力又耗时的任务。这里我们可以使用域自适应,因为我们可以在 GTSRB(源数据集)上训练模型,并在我们的印度交通标志图像(目标数据集)上测试它。
- 在许多情况下,很难收集数据集,这些数据集具有训练健壮的神经网络所需的所有变化和多样性。在这种情况下,在不同计算机视觉算法的帮助下,我们可以生成大型合成数据集,这些数据集具有我们需要的所有变化。然后在合成数据集(源数据集)上训练神经网络,在真实数据(目标数据集)上测试。
为了更好地理解,我假设我们没有可用于目标数据集/域的注释,但这并不是唯一的情况。请继续阅读进一步的解释。
因此,在领域自适应中,我们的目标是在标签或注释可用的一个数据集(源)上训练神经网络,并在标签或注释不可用的另一个数据集(目标)上确保良好的性能。
分类管道(图片由作者提供)
现在让我们看看如何实现我们的目标。考虑上述图像分类的情况。为了从一个领域适应另一个领域,我们希望我们的分类器能够很好地处理从源数据集和目标数据集中提取的特征。因为我们已经在源数据集上训练了神经网络,所以分类器必须对源数据集表现良好。然而,为了使分类器在目标数据集上表现良好,**我们希望从源数据集和目标数据集提取的特征是相似的。**因此,在训练的同时,我们实施特征提取器来提取源和目标域图像的相似特征。
成功的域名改编(图片由作者提供)
基于目标域的域适应类型
根据可从目标域获得的数据类型,域适应可分为以下几类:
- 监督的-您已经标记了来自目标域的数据,并且目标数据集的大小与源数据集相比要小得多。
- 半监督 —您既有目标域的已标记数据,也有未标记数据。
- 无监督 —你有很多目标领域的未标记样本点。
领域适应技术
主要使用三种技术来实现任何域自适应算法。以下是用于领域适应的三种技术:
- 基于散度的领域适应
- 基于对抗的领域适应
- 基于重构的域适应
现在让我们一部分一部分地来看每一种技术。
基于散度的领域适应
基于散度的域适应的工作原理是最小化源和目标分布之间的一些基于散度的标准,因此导致域不变特征。常用的基于差异的标准有对比域差异、相关比对、最大平均差异(MMD)、Wasserstein 等。为了更好地理解这个算法,我们先来看一些分歧。
在最大平均差异(MMD)中,我们试图找出给定的两个样本是否属于同一分布。我们将两个分布之间的距离定义为特征的平均嵌入之间的距离。如果我们有两个分布,比如说集合 X 上的 P 和 Q 。然后用一个特征映射 𝜑 定义 mmd:x→h,其中 h 称为再生核希尔伯特空间。MMD 的配方如下所述
为了更好地理解 MMD,请看下面的描述 — 如果两个分布的矩相似,则它们是相似的。通过应用一个核,我可以变换变量,使得所有的矩(一阶、二阶、三阶等)。)进行计算。在潜在空间中,我可以计算出矩之间的差,然后求平均值。
在相关性比对中,我们尝试使用 MMD 中的线性变换来比对源和目标域之间的相关性(二阶统计量)。
训练期间(图片由作者提供)
推理过程中(图片由作者提供)
上面的架构假设源域和目标域具有相同的类。在上述架构中,在训练期间,我们最小化两个损失,分类损失和基于散度的损失。分类损失通过更新特征提取器和分类器的权重来保证良好的分类性能。而基于散度的损失通过更新特征提取器的权重来确保源和目标域的特征是相似的。在推断时间内,我们只需从我们的神经网络传递目标域图像。
所有的发散通常是非参数的和手工制作的数学公式,其不特定于数据集或我们的问题,如分类、对象检测、分割等。因此,这种基于公式的方法对于我们的问题来说并不是非常个性化的。然而,如果可以基于数据集或问题来学习散度,那么与传统的预定义散度相比,它有望表现得更好。
基于对抗的领域适应
为了实现基于对抗的领域适应,我们使用 GANs。如果你对 GANs 不太了解,请看这里的。
这里,我们的生成器只是特征提取器,我们添加了新的鉴别器网络,它学习区分源和目标域特征。由于这是一个双人游戏,鉴别器帮助生成器生成源域和目标域不可区分的特征。由于我们有一个可学习的鉴别器网络,我们学习提取特征(特定于我们的问题和数据集),这有助于区分源域和目标域,从而帮助生成器产生更鲁棒的特征,即不容易区分的特征。
培训期间—来源(图片由作者提供)
训练期间—针对目标(图片由作者提供)
假设分类的问题,我们用的是两个损耗,分类损耗和鉴别器损耗。分类损失的目的在前面已经解释过了。鉴别器损失有助于鉴别器正确区分源和目标域特征。这里我们使用梯度反向层(GRL)来实现对抗性训练。GRL 块是一个简单的块,它在反向传播时将梯度乘以-1 或负值。在训练期间,为了更新生成器,我们有来自两个方向的梯度,第一个来自分类器,第二个来自鉴别器。由于 GRL,来自鉴别器的梯度乘以负值,从而导致训练发生器的效果与鉴别器的方向相反。例如,如果优化鉴别器损失函数的计算梯度是 2,那么我们用-2 更新生成器(假设负值是-1)。通过这种方式,我们试图以这样一种方式训练生成器,即使是鉴别器也不能区分源域和目标域的特征。GRL 层在许多关于领域适应的文献中非常常用。
基于重构的域适应
这是基于图像到图像翻译的思想。一种简单的方法是学习从目标域图像到源域图像的转换,并在源域上训练分类器。利用这个想法,我们可以引入多种方法。图像到图像转换的最简单模型可以是基于编码器-解码器的网络,并使用鉴别器来加强编码器-解码器网络,以产生与源域相似的图像。
训练期间(图片由作者提供)
测试期间(图片由作者提供)
另一种方法是我们可以使用自行车甘斯。在循环 GAN 中,我们使用两个基于编码器-解码器神经网络。一个用于将目标变换到源域,另一个用于将源变换到目标域。我们同时训练两个在两个域(源和目标)中生成图像的 gan。为了确保一致性,引入了周期一致性损失。这确保了从一个域到另一个域的变换,以及从一个域到另一个域的变换,会产生与输入大致相同的图像。因此,两个配对网络的全部损耗是两个鉴别器的 GAN 损耗和周期一致性损耗的总和。
结论
我们已经看到了三种不同的技术,它们可以帮助我们实现或实现不同的领域适应方法。它在图像分类、目标检测、分割等方面有着广泛的应用。在某些方面,我们可以说这种方法类似于人类学习视觉识别不同事物的方式。我希望这篇博客能让你对我们如何看待不同的领域适配管道有一个基本的了解。
成为 介质会员 解锁并阅读介质上的许多其他故事。关注我们的Medium,阅读更多此类博文。
理解估计偏差和偏差-方差权衡
北大西洋的海面温度。图片来源: NOAA OSPO 根据使用条款
另外,如何根据偏差、方差和均方差来比较估计量
统计估计量可以根据其预测的偏差程度、其性能的一致性以及其预测的效率来评估。你的模型的预测质量取决于它所使用的估计器的质量。
在本文中,我们将详细介绍偏差的特性,并学习如何测量它。
通过一个叫做偏差-方差权衡的概念,估计者的偏差恰好与估计者预测的方差相结合,因此,我们也将学习这个概念。
最后,我们将讨论估计量的均方误差及其对回归建模的适用性,我们将展示如何使用偏差、方差及其均方误差的属性来评估总体均值的各种估计量。
什么是估计量?
估计量是用于预测或估计某个未知量的值的任何程序或公式,例如,您的航班的起飞时间,或今天的纳斯达克收盘价。
在我们的日常生活中,我们倾向于使用各种类型的估计量,甚至没有意识到这一点。以下是我们常用的一些估计类型:
基于好(或坏!)判断
你让你的股票经纪人朋友估计你最喜欢的股票一年后的价格会有多高。在这种情况下,你很可能得到价格的 区间估计 ,而不是点估计。
基于经验法则和一些计算的估计量
你使用一些评估技术,比如工作分解结构,来评估完成下一个家庭装修项目需要付出的努力。
基于轮询的估计量
你问奇数个朋友,他们认为谁会赢得下一次选举,你接受多数人的结果。
在每种情况下,你都希望估计一个你不知道的参数。
在统计建模中,均值,尤其是总体的均值,是一个经常被估计的基本参数。
让我们看一个现实生活中的数据样本。
以下是一年中特定时间东北大西洋表面温度的数据集:
东北大西洋实时海表温度数据集下载自 data.world 下 CC BY 4.0
这个数据集包含许多遗漏的读数。我们将通过将它加载到 Pandas 数据帧中并删除包含缺失温度值的所有行来清理它:
**import** pandas **as** pddf = pd.**read_csv**('NE_Atlantic_Sea_Surface_Temperatures.csv', **header**=0, **infer_datetime_format**=True, **parse_dates**=['time(UTC)'])df = df.**dropna**()**print**(df)
我们得到以下输出:
清除了所有 NaN 行的数据集(图片由作者提供)
在将近 800,000 个数据点(n=782,668)的情况下,这个数据集构成了一个非常大的数据样本。通常,你将不得不凑合使用十几个、几百个、偶尔几千个样本。
让我们打印出该示例中温度值的频率分布:
**from** matplotlib **import** pyplot **as** pltdf['sea_surface_temperature(degree_C)'].**hist**(**bins**=50)plt.**show**()
我们得到如下的情节:
东北大西洋温度值的直方图(图片由作者提供)
现在,假设我们希望估计整个东北大西洋的平均表面温度,换句话说,人口平均值。
这里有三种可能的总体均值估计量:
- 估计值#1: 我们可以取上述样本中最小和最大温度值的平均值:
y_min = df['sea_surface_temperature(degree_C)'].**min**()
y_max = df['sea_surface_temperature(degree_C)'].**max**()
**print**('**y_min**='+**str**(y_min) + ' **y_max**='+**str**(y_max))
**print**('**Estimate #1 of the population mean**='+**str**((y_max-y_min)/2))
我们得到以下输出:
y_min=0.28704015899999996 y_max=15.02521203Estimate #1 of the population mean=**7.3690859355**
- 估计值#2: 我们可以从样本中选择一个随机值,并将其指定为总体均值:
rand_temp = df.**sample**()['sea_surface_temperature(degree_C)'].**iloc**[0]
print('**Estimate #2 of the population mean**='+**str**(rand_temp))
我们得到以下输出:
Estimate #2 of the population mean=**13.5832207**
- 估计值#3: 我们可以使用下面的估计值,它平均出数据样本中的所有温度值:
人口平均值的估计值(图片由作者提供)
y_bar = df['sea_surface_temperature(degree_C)'].**mean**()
**print**('**Estimate #3 of the population mean**='+**str**(y_bar))
我们得到以下输出:
Estimate #3 of the population mean=**11.94113359335031**
我们应该使用哪个估计量?可以看出,第三个估计量——y _ bar,即 n 值的平均值——提供了总体均值的无偏估计。不过话说回来,前两个也是!
无论如何,这可能是更好地理解偏差概念的好时机。
估计偏差
假设你正在打篮球。当一些球穿过球网时,你会发现你大部分的投球都是在篮筐下的一点。在这种情况下,无论你用什么技术来估计投掷的正确角度和速度,都是低估了(未知的)角度和速度的正确值。你的估计值有负偏差。
一个有偏见的扣篮技术,似乎更多的时候,低于位于人物中心的篮子(图片由作者提供)
通过练习,你的投掷技术会提高,你也能更频繁地扣篮。从偏见的角度来看,你开始超过篮子的次数和低于篮子的次数差不多。你已经设法减少了评估技术的偏差。
一种更少偏见,更“平衡”的扣篮技术,在这种技术中,失误经常发生在图中心的篮筐两侧(图片由作者提供)
偏差-方差权衡
从上面两张图中,您可能会发现一个明显的方面,即在第一张图中,虽然偏倚很大,但遗漏镜头的“分散性”较小,导致结果的方差较低。在第二个图中,偏差无疑减少了,因为错过的镜头分布更加均匀,但这也导致了更高的分布,也就是更高的方差。
第一种技术似乎具有较大的偏差和较小的方差,第二种技术则相反。这不是巧合,很容易证明(事实上,我们将在后面证明!)在你的评估技术的偏差和方差之间有一个直接的交换。
如何计算估计量的偏差
让我们继续篮球的例子。我们可以看到篮筐的位置(两个图中间的橙色点)是保证扣篮的投掷角度和投掷速度的(未知)群体平均值的代表。失误(蓝点)代表你的技术对投掷角度和速度的总体平均值的估计。
用统计学的术语来说,每一次投掷都是一次产生结果的实验。结果的值是球(蓝点)在包含篮子的垂直平面上的位置。
如果你假设每一次投掷的结果都独立于前一次投掷(这在现实生活中几乎是不可能的,但是让我们一起玩吧!),我们可以定义 n 个独立,同分布的随机变量 y_1,y_2,y_3,…y_n 来代表你的 n 投。
让我们回忆一下我们的 n 样本平均值估计量:
人口平均值的估计值(图片由作者提供)
请注意,这意味着 y_bar 与我们的样本 n 值有关,即 n 球投掷,或 n 海洋表面温度等。转到海洋温度的例子,如果我们收集另一组 n 海洋温度值并平均它们,我们将得到样本平均值 y_bar 的第二个值。大小为 n 的第三个样本将产生第三个样本平均值,依此类推。所以,样本均值 y_bar 本身就是一个随机变量。而且就像任何随机变量一样, y_bar 有一个概率分布和一个期望值,用 E(y_bar) 表示。
我们现在可以为总体平均值定义估计量 y_bar 的偏差如下:
总体均值的估计量 y_bar 的偏差,是样本均值 y_bar 的期望值与总体均值的差值。公式如下:
总体均值估计量的偏差(图片由作者提供)
一般来说,给定一个总体参数 θ (如平均值、方差、中位数等。),以及 θ 的一个估计量 θ_cap ,则 θ_cap 的偏差为 θ_cap 的期望值与总体参数 θ 的实际(真)值之差,如下:
估计量的偏差 θ_cap 对于总体参数θ*(图片由作者提供)*
样本均值作为总体均值的无偏估计量
我们现在将展示我们之前看到的 n 个样本值的平均值估计器 y_bar ,在其预测总体平均值的能力中证明了零偏差。
使用偏差表达式, y_bar 的偏差由下式给出:
总体均值估计量的偏差(图片由作者提供)
现在,我们来计算 E(y_bar) :
样本均值 y_bar 的期望值(图片由作者提供)
随机变量 y_1,y_2,y_3,…y_n 都围绕总体均值*同分布。*因此,他们每个人都有一个期望值:
样本均值 y_bar 为零偏差(图片由作者提供)
零偏差估计器不一定是个好东西。事实上,回想一下我们也考虑过的平均表面温度的下列两个估计量:
人口平均数的另外两个估计值(图片由作者提供)
由于每个随机变量 y_i 的期望值是总体均值,估计器(1)和(2)各有一个偏差 B(。)= E(y_bar)- = - =0 。
但是常识告诉我们,估计量#(1)和#(2)明显劣于均值-of- n- 样本 - 值估计量#(3)。因此,必须有其他的性能度量,通过这些度量,我们可以评估 n- 样本值的平均值估计的适用性,并显示它优于其他估计。
其中一个度量是均方误差 (MSE)。
估计量的均方误差及其在回归建模中的适用性
对于大多数处理回归模型的人来说,均方误差是一个熟悉的性能度量。诸如用于线性模型的普通最小二乘(OLS)估计器之类的一些估计器,以及一些神经网络估计器寻求最小化训练数据和模型预测之间的均方误差。
考虑回归模型的一般方程:
具有附加残差的回归模型的一般方程(图片由作者提供)
其中,y _ OBS=【y _ 1,y_2,y_3,…y _ n】=训练数据样本, X*=回归变量矩阵,* β_ cap*=拟合*
是模型的预测。 f( X,β_cap)=y_cap 是观测值向量 y_obs 对应的拟合值向量。 所以,上面的模型方程可以简洁地写成如下:
带有附加残差的回归模型(图片由作者提供)
估计函数y _ cap***= f(.)是:*
估计函数的均方误差 f( X,β_cap) (图片由作者提供)
回归模型的估计函数通常会(但不总是)尝试最小化 MSE。
MSE 的上述等式可以用期望值的语言写成如下:
估计函数的均方误差 f( X,β_cap) (图片由作者提供)
请注意,我们还颠倒了括号中术语的顺序,只是为了保持惯例。
从下图可以看出,上述两个 MSE 方程是等价的:
以期望值表示的 MSE 公式(图片由作者提供)
从上图中我们看到,常用的均方误差公式只是简单地假设每个均方差 (y_i-y_cap_i) 出现的概率均匀分布在区间【0,n】,上导致每个概率为 1/n.
让我们回到估计量的 MSE 的一般公式:
估计函数的均方误差 f( X,β_cap) (图片由作者提供)
假设我们使用 n 个样本值的平均值估计器 y_bar 。因此, y_cap=y_bar ,因此 y_obs 现在是理论上已知的(但实际上未观察到的)总体均值。因此,样本均值 y_bar 的 MSE 可以表示如下:
样本均值 Y_bar 的均方误差(图片由作者提供)
为了计算 y_bar 的 MSE,我们将使用期望理论的以下结果:
随机变量 Y 的期望和方差之间的关系(图片由作者提供)
将上述公式应用于 MSE 表达式的 R.H.S .,我们得到以下结果:
样本均值 Y_bar 的 MSE(图片由作者提供)
让我们检查上面等式的 R.H.S。正方形下面的第一项是 E(y_bar-),我们知道,它是样本均值 y_bar 的偏差。
因为总体均值是一个常数,所以 R.H.S. 方差(y_bar- ) 的第二项就是方差(y_bar) 。因此,R.H.S 是偏差(平方)和 y_bar 的方差之和。
我们可以将这一发现归纳如下:
任何总体参数 θ 的估计量 θ_cap 的均方误差,是估计量 w.r.t. θ 的偏差 B(θ_cap) 与估计量 w.r.t. θ 的方差 Var(θ_cap) 之和:
偏差-方差权衡(图片由作者提供)
在估计任何数量时,人们常常以某个目标均方误差为目标。上述等式清楚地表明,为了实现指定的均方误差,必须在估计器的偏差和方差之间进行权衡。
**当 θ_cap=Y_bar,n 个样本值的平均值时,我们可以计算 Y_bar 的 MSE,如下所示:
样本平均值的均方误差(图片由作者提供)
我们已经证明了样本均值是总体均值的无偏估计量。所以偏置(y_bar) 为零。让我们计算样本均值的方差。
样本均值的方差(图片由作者提供)
我们现在将使用 n 个独立随机变量 y_1,y_2,y_3,…y_n 的线性组合的方差的以下性质:
n 个独立随机变量线性组合的方差(图片由作者提供)
这里,C1,C2,…,c_n 是常数。将此结果应用于 y_bar ,我们得到:
独立同分布随机变量样本均值的方差(图片由作者提供)
**y_1,y_2,y_3,…y_n 不仅是独立的随机变量,而且是同分布的,因此它们都具有相同的均值和方差,并且等于这两个参数各自的总体值。具体来说,对于所有的 i , Var(y_i) = σ。因此:
独立同分布随机变量样本均值的方差(图片由作者提供)
因此,我们已经表明n-I . I . d .随机变量的平均值估计量的方差是 σ /n.
独立同分布随机变量样本均值的方差(图片由作者提供)
这个结果也证实了我们的直觉,随着样本量的增加,样本均值的方差应该减少。
将这一结果插回到公式中用于 MSE(y_bar) ,记住 Bias(y_bar)=0 ,我们得到:
n 个独立同分布随机变量样本均值的均方误差(图片由作者提供)
现在让我们回到大西洋东北部表面温度的数据集。我们的样本量是 782,668。我们考虑了未知总体均值的以下三种估计量:
总体均值的三个候选估计值(图片由作者提供)
让我们使用偏差、方差和 MSE 的度量来比较三种估计器的性能,如下所示:
我们可以看到n 个样本值的平均值估计量(估计量#3)具有零偏差,并且在三个候选值中具有最低的方差和最低的均方误差。
摘要
- 估计量是用来预测或估计某个未知量的值的任何程序或公式。
- 给定一个总体参数 θ (如平均值、方差、中位数等。),以及 θ 的一个估计量 θ_cap , θ_cap 的偏差是 θ_cap 的期望值与总体参数 θ的实际(真)值之差。****
- 样本均值,当表示为 n 个独立同分布随机变量的平均值时,是总体均值的无偏估计量。
- n 独立同分布随机变量的样本均值方差为 σ /n ,其中 σ 为总体方差。****
- 估计量的均方误差** θ_cap 是:1)其偏差的平方和 2)其方差之和。因此,对于任何期望的均方误差,在估计器输出的偏差和方差之间总是有一个折衷。**
- 使用小偏差估计量的回归模型不一定比使用大偏差估计量的回归模型具有更高的拟合优度。还应该考虑估计量的其他属性,如 MSE、一致性和效率。
- 一些估计量,如最大似然估计量,并不寻求最小化均方误差。对于这样的估计器,人们使用拟合优度度量来测量它们的性能,例如偏差。
参考文献和版权
数据集
东北大西洋实时海表温度数据集下载自 data.world 下 CC BY 4.0
形象
北大西洋的海面温度。图片来源: NOAA OSPO 根据使用条款
本文中所有其他图片的版权归 Sachin Date 所有,版权归 CC-BY-NC-SA 所有,除非图片下方提到了不同的来源和版权。
感谢阅读!如果你喜欢这篇文章,请 关注我 获取关于回归和时间序列分析的技巧、操作和编程建议。
理解分类建模中的评估指标
凯文·Ku 在 Unsplash 上的照片
更好地理解分类模型性能的指南
动机
分类建模成为机器学习中广泛使用的技术之一,例如欺诈检测、流失分析、疾病检测以及图像分类。为了了解分类建模中的模型性能,我们使用分类结果表,通常我们称之为混淆矩阵。
在大多数情况下,大多数人可能只是观察模型产生的精度值来确定模型的性能。但是,在某些情况下,我们不能简单地使用准确性来确定模型的性能(例如,当数据不平衡时)。在本文中,我将告诉您如何在分类建模中正确使用评估指标。
注意:在这篇文章中,我将解释二进制分类情况下的评估指标。
这个概念
首先,我们必须先了解评估指标。在机器学习中,评估指标对于帮助我们理解模型性能非常重要,从而确定我们可以从分析中给出的建议。在分类建模中,评估指标是根据真阳性(TP)、假阳性(FP)、真阴性(TN)和假阴性(FN)计算的。所有这些值都以表格形式列出(为了进一步解释,我们称之为混淆矩阵),如下图所示。
困惑矩阵(图片来自作者)
根据建模目的或使用的数据,应适当考虑将要使用的评估指标,这样结果就不会误导。在这里,我将解释分类建模中的一些评估指标,以及何时应该正确使用它们。
准确(性)
分类建模中最常见的评估指标。此指标衡量正确预测与评估的实例总数的比率。
此指标可用于大多数情况,但我建议在数据平衡时使用(即多数类和少数类的差异不太大)。
精确
精度度量用于测量从肯定类别中的全部预测模式中正确预测的肯定模式。
回忆还是敏感
灵敏度度量用于测量被正确分类的肯定模式的比例。
我建议您在少数类为阳性的数据不平衡时(例如,新冠肺炎或其他疾病数据集)使用此指标。当然,你不想错误地将一个阳性患者预测为阴性患者)。
分析不平衡数据时经常发生(图像由 Imgflip 生成)
特征
与敏感性相反,特异性度量用于测量被正确分类的阴性模式的比例。
当少数类为正类的数据不平衡时,建议使用敏感度指标;当少数类为负类的数据不平衡时,建议使用特异性指标,例如,流失数据集。
f1-分数
最后一个是 F1 成绩。该指标代表召回值和精确值之间的调和平均值
,也可以写成如下形式。
当数据集不平衡时,建议使用此指标。
例子
为了在实践中了解更多,这里我用 Kaggle 的 Pima 印度糖尿病数据库给出一个例子。分析将使用 R 编程语言进行。
皮马印度糖尿病数据库(图片来自 Kaggle
像往常一样,首先,我们需要导入库和数据。
library(car)
library(MASS)
library(tseries)
library(lmtest)
library(tidyverse)
library(imbalance)
library(mice)
library(caret)
library(caTools)
library(rsample)#Data Importing
data=read.csv("data_input/diabetes.csv")
我们按如下方式检查数据汇总。
> str(data)
'data.frame': 768 obs. of 9 variables:
$ Pregnancies : int 6 1 8 1 0 5 3 10 2 8 ...
$ Glucose : int 148 85 183 89 137 116 78 115 197 125 ...
$ BloodPressure : int 72 66 64 66 40 74 50 0 70 96 ...
$ SkinThickness : int 35 29 0 23 35 0 32 0 45 0 ...
$ Insulin : int 0 0 0 94 168 0 88 0 543 0 ...
$ BMI : num 33.6 26.6 23.3 28.1 43.1 25.6 31 35.3 30.5 0 ...
$ DiabetesPedigreeFunction: num 0.627 0.351 0.672 0.167 2.288 ...
$ Age : int 50 31 32 21 33 30 26 29 53 54 ...
$ Outcome : int 1 0 1 0 1 0 1 0 1 1 ...
然后,让我们检查数据中是否存在缺失值,如下所示。
> md.pattern(data)
/\ /\
{ `---' }
{ O O }
==> V <== No need for mice. This data set is completely observed.
\ \|/ /
`-----'Pregnancies Glucose BloodPressure SkinThickness Insulin BMI
768 1 1 1 1 1 1
0 0 0 0 0 0
DiabetesPedigreeFunction Age Outcome
768 1 1 1 0
0 0 0 0
缺失的价值分析(图片由作者提供)
没有缺失值!因此,我们好进行下一步。让我们绘制因变量(即数据中的结果)来找出数据集是否不平衡。
#Data Visualization
ggplot(data, aes(Outcome))+geom_bar()
imbalanceRatio(data,classAttr = "Outcome")
“结果”变量的数据可视化(图片由作者提供)
> imbalanceRatio(data,classAttr = "Outcome")
[1] 0.536
我们可以看到数据集是不平衡的,其中少数类是正类(标为 1)。因此,我们有兴趣了解将从模型中产生的灵敏度指标。
接下来,我们将数据分为数据训练和数据测试,如下所示。
#Data Splitting
split=initial_split(data,prop=0.7)
data.train=training(split)
data.test=testing(split)
对于本文中的例子,我将使用逻辑回归对这些数据进行建模。您可以尝试使用不同的模型和/或优化它来查看不同的结果。
> #Modeling
> model=glm(Outcome~.,data=data.train,family=binomial(link="logit"))
> summary(model)Call:
glm(formula = Outcome ~ ., family = binomial(link = "logit"),
data = data.train)Deviance Residuals:
Min 1Q Median 3Q Max
-2.4025 -0.7510 -0.4492 0.7687 2.7652Coefficients:
Estimate Std. Error z value Pr(>|z|)
(Intercept) -7.930549 0.818065 -9.694 < 2e-16 ***
Pregnancies 0.117947 0.037190 3.171 0.00152 **
Glucose 0.032608 0.004247 7.678 1.61e-14 ***
BloodPressure -0.009801 0.006241 -1.570 0.11633
SkinThickness 0.003591 0.008125 0.442 0.65849
Insulin -0.001708 0.001088 -1.569 0.11657
BMI 0.083122 0.017663 4.706 2.53e-06 ***
DiabetesPedigreeFunction 0.615187 0.340094 1.809 0.07047 .
Age 0.015894 0.010867 1.463 0.14358
---
Signif. codes: 0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1 ‘ ’ 1(Dispersion parameter for binomial family taken to be 1)Null deviance: 699.94 on 537 degrees of freedom
Residual deviance: 530.59 on 529 degrees of freedom
AIC: 548.59Number of Fisher Scoring iterations: 4
通过编写如下代码,让我们来看看这个使用来自caret
库的confusionMatrix
的示例模型的性能。
> pred=predict(model,data.test,type='response')
> pred=ifelse(pred>0.5,1,0)
> confusionMatrix(table(actual=data.test$Outcome,pred),positive="1")
Confusion Matrix and Statisticspred
actual 0 1
0 136 17
1 28 49
Accuracy : 0.8043
95% CI : (0.7471, 0.8536)
No Information Rate : 0.713
P-Value [Acc > NIR] : 0.001005
Kappa : 0.5446
Mcnemar's Test P-Value : 0.136037
Sensitivity : 0.7424
Specificity : 0.8293
Pos Pred Value : 0.6364
Neg Pred Value : 0.8889
Prevalence : 0.2870
Detection Rate : 0.2130
Detection Prevalence : 0.3348
Balanced Accuracy : 0.7858
'Positive' Class : 1
乍一看,我们可能会说基于精度的模型性能良好,其中精度为 0.8043。但是,如果我们从敏感度上看,得分仅为 0.7424,这意味着预测结果仍有许多假阴性(FN),因此我们可以说该模型仍需要一些改进以增加敏感度得分,从而减少假阴性的发生。
让我们看看,如果我们从第一个模型中删除统计上最不重要的变量(即SkinThickness
变量),会看到不同的结果。
> model2=glm(Outcome~Pregnancies+Glucose+BloodPressure+Insulin+BMI+DiabetesPedigreeFunction+Age,data=data.train,family=binomial(link="logit"))
> summary(model2)Call:
glm(formula = Outcome ~ Pregnancies + Glucose + BloodPressure +
Insulin + BMI + DiabetesPedigreeFunction + Age, family = binomial(link = "logit"),
data = data.train)Deviance Residuals:
Min 1Q Median 3Q Max
-2.1998 -0.7277 -0.4219 0.7465 2.7713Coefficients:
Estimate Std. Error z value Pr(>|z|)
(Intercept) -8.1105881 0.8266014 -9.812 < 2e-16 ***
Pregnancies 0.1408917 0.0387610 3.635 0.000278 ***
Glucose 0.0356517 0.0043220 8.249 < 2e-16 ***
BloodPressure -0.0118975 0.0061181 -1.945 0.051819 .
Insulin -0.0010592 0.0009106 -1.163 0.244758
BMI 0.0793557 0.0158026 5.022 5.12e-07 ***
DiabetesPedigreeFunction 1.1127198 0.3435883 3.239 0.001201 **
Age 0.0085905 0.0114574 0.750 0.453386
---
Signif. codes: 0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1 ‘ ’ 1(Dispersion parameter for binomial family taken to be 1)Null deviance: 708.97 on 537 degrees of freedom
Residual deviance: 516.31 on 530 degrees of freedom
AIC: 532.31Number of Fisher Scoring iterations: 5> pred2=predict(model2,data.test,type='response')
> pred2=ifelse(pred2>0.5,1,0)
> confusionMatrix(table(actual=data.test$Outcome,pred2),positive="1")
Confusion Matrix and Statisticspred2
actual 0 1
0 150 11
1 29 40
Accuracy : 0.8261
95% CI : (0.7708, 0.8728)
No Information Rate : 0.7783
P-Value [Acc > NIR] : 0.04490
Kappa : 0.5526
Mcnemar's Test P-Value : 0.00719
Sensitivity : 0.7843
Specificity : 0.8380
Pos Pred Value : 0.5797
Neg Pred Value : 0.9317
Prevalence : 0.2217
Detection Rate : 0.1739
Detection Prevalence : 0.3000
Balanced Accuracy : 0.8112
'Positive' Class : 1
结果好多了!我们可以看到敏感度得分增加到 0.7843,这意味着我们可以从预测结果中减少假阴性的发生(从混淆矩阵中可以看出)。
完整的代码如下。
library(car)
library(MASS)
library(tseries)
library(lmtest)
library(tidyverse)
library(imbalance)
library(mice)
library(caret)
library(caTools)
library(rsample)#Data Importing
data=read.csv("data_input/diabetes.csv")
summary(data)
str(data)
md.pattern(data)#Data Visualization
ggplot(data, aes(Outcome))+geom_bar()
imbalanceRatio(data,classAttr = "Outcome")#Data Splitting
split=initial_split(data,prop=0.7)
data.train=training(split)
data.test=testing(split)#Modeling
model=glm(Outcome~.,data=data.train,family=binomial(link="logit"))
summary(model)
pred=predict(model,data.test,type='response')
pred=ifelse(pred>0.5,1,0)
confusionMatrix(table(actual=data.test$Outcome,pred),positive="1")model2=glm(Outcome~Pregnancies+Glucose+BloodPressure+Insulin+BMI+DiabetesPedigreeFunction+Age,data=data.train,family=binomial(link="logit"))
summary(model2)
pred2=predict(model2,data.test,type='response')
pred2=ifelse(pred2>0.5,1,0)
confusionMatrix(table(actual=data.test$Outcome,pred2),positive="1")
结论
我们到了。在本文中,您将学习如何根据建模目的或分析中使用的数据来正确使用评估指标。
像往常一样,如果您有任何问题,请随时在我的联系人下面提问或讨论!下一篇文章再见,保持健康!
作者的联系人
中:https://medium.com/@radenaurelius
参考
[1] Lever,j .,Krzywinski,m .,& Altman,N. (2016)。分类评价。性质。
[2]m . hos sin 和 m . n . Sula Iman(2015 年)。审查数据分类评估的评估指标。国际数据挖掘杂志&知识管理过程,第 5 卷,第 2 期,第 1–11 页。
https://www.kaggle.com/uciml/pima-indians-diabetes-database
了解特性的重要性以及如何在 Python 中实现它
了解最实用的数据科学概念之一
弗洛里安·施梅兹在 Unsplash 上的照片
请务必 订阅此处 千万不要错过另一篇关于数据科学指南、诀窍和技巧、生活经验等的文章!
目录
- 介绍
- 什么是特性重要性
- 为什么特性重要性如此有用?
- Python 中特性的重要性
- 具有梯度的特征重要性
介绍
有了所有可用的包和工具,构建一个机器学习模型并不困难。然而,构建一个好的机器学习模型就是另一回事了。
如果你认为机器学习只是简单地将数百列数据扔进一个笔记本,并使用 scikit-learn 建立一个模型,那么请再想想。
经常被忽视的一件大事是为这些模型选择合适的特征。无用的数据会导致偏见,从而扰乱我们机器学习的最终结果。在本文中,我们将讨论在机器学习中起关键作用的特征重要性。
在本文中,我们将介绍什么是特性重要性,为什么它如此有用,如何用 Python 代码实现特性重要性,以及如何在 Gradio 中可视化特性重要性。
什么是特征重要性?
要素重要性是指为给定模型的所有输入要素计算分数的技术-分数仅代表每个要素的“重要性”。较高的分数意味着特定特征将对用于预测某个变量的模型产生较大的影响。
为了更好的理解,让我们举一个现实生活中的例子。假设你要在工作地点附近买一套新房子。在买房时,你可能会考虑不同的因素。你做决定时最重要的因素可能是房产的位置,因此,你可能只会寻找靠近你工作地点的房子。要素重要性以类似的方式工作,它将根据要素对模型预测的影响对要素进行排序。
为什么特性重要性如此有用?
特征重要性非常有用,原因如下:
1)数据理解。
构建模型是一回事,但理解进入模型的数据是另一回事。像相关矩阵一样,特征重要性允许您理解特征和目标变量之间的关系。它还可以帮助您了解哪些功能与模型无关。
2)模型改进。
训练模型时,可以使用根据要素重要性计算的分数来降低模型的维度。较高的分数通常被保留,较低的分数被删除,因为它们对模型不重要。这不仅简化了模型,还加快了模型的工作速度,最终提高了模型的性能。
3)模型的可解释性。
特性重要性对于向其他涉众解释和交流您的模型也很有用。通过计算每个特征的得分,可以确定哪些特征对模型的预测能力贡献最大。
特征重要性背后的数学原理
有不同的方法来计算特征重要性,但本文将只关注两种方法:基尼重要性和排列特征重要性。
基尼系数
在 Scikit-learn 中,Gini 重要度用于计算节点杂质,而特征重要度基本上是节点杂质的减少量,该减少量通过从样本总数中到达该节点的样本数来加权。这就是所谓的节点概率。假设我们有一棵有两个子节点的树,我们的等式是:
这里我们有:
nij =节点 j 重要性
wj=到达节点 j 的加权样本数
Cj=节点 j 的杂质值
左(j) =节点 j 左边的子节点
右(j) =节点 j 右边的子节点
这个等式给出了节点 j 的重要性,用于计算每个决策树的特征重要性。单个特征可以用在树的不同分支中。因此,我们计算特征重要性如下。
根据树中存在的所有特征值的总和对特征进行归一化,然后用它除以随机森林中的树的总数,我们得到总体特征重要性。这样,您可以更好地理解随机森林中的特性重要性。
置换特征重要性
排列特征重要性背后的思想很简单。当我们改变一个特性的值时,通过注意误差的增加或减少来计算特性的重要性。如果置换值导致误差发生巨大变化,这意味着该特征对我们的模型很重要。这种方法最好的一点是,它可以应用于每一个机器学习模型。它的方法是模型不可知的,这给了你很大的自由。背后没有复杂的数学公式。置换特征重要性基于如下工作的算法。
- 用原始值计算均方误差
- 打乱要素的值并进行预测
- 计算混洗值的均方误差
- 比较它们之间的区别
- 按降序对差异进行排序,以获得重要性从高到低的特征
Python 中特性的重要性
如果你想自己测试代码,就去看看Saturn cloud,一个可扩展的、灵活的数据科学平台。
在本节中,我们将使用波士顿数据集创建一个随机森林模型。
首先,我们将导入所有需要的库和数据集。
import numpy as np
import pandas as pd
from sklearn.datasets import load_boston
from sklearn.model_selection import train_test_split
from sklearn.ensemble import RandomForestRegressor
from sklearn.inspection import permutation_importance
from matplotlib import pyplot as plt
下一步是加载数据集,并将其分成测试集和训练集。
boston = load_boston()X = pd.DataFrame(boston.data, columns=boston.feature_names)
y = boston.targetX_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.25, random_state=42)
接下来,我们将创建随机森林模型。
rf = RandomForestRegressor(n_estimators=150)
rf.fit(X_train, y_train)
一旦创建了模型,我们就可以进行特征重要性分析,并将其绘制在图表上,以便于解释结果。
sort = rf.feature_importances_.argsort()plt.barh(boston.feature_names[sort], rf.feature_importances_[sort])plt.xlabel("Feature Importance")
RM 是每个住宅的平均房间数,从上面可以看出,它是预测目标变量的最重要的特征。
具有梯度的特征重要性
Gradio 是一个漂亮的包,有助于为机器学习模型创建简单的交互式界面。使用 Gradio,您可以实时评估和测试您的模型。关于 Gradio 的一个有趣的事情是,它使用单个参数计算要素重要性,我们可以与要素进行交互,以查看它如何影响要素重要性。
这里有一个例子:
首先,我们将导入所有需要的库和数据集。在这个例子中,我将使用 Seaborn 库中的 iris 数据集。
**# Importing libraries**
import numpy as np
import pandas as pd
import seaborn as sns**# Importing data**
iris=sns.load_dataset("iris")
然后,我们将拆分数据集,并将其放入模型中。
from sklearn.model_selection import train_test_splitX=iris.drop("species",axis=1)
y=iris["species"]
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.25) from sklearn.svm import SVCmodel = SVC(probability=True)
model.fit(X_train,y_train)
我们还将创建一个将在 Gradio 界面中使用的预测函数。
def predict_flower(sepal_length, sepal_width, petal_length, petal_width):
df = pd.DataFrame.from_dict({'Sepal Length':[sepal_length],
'Sepal Width': [sepal_width],
'Petal Length': [petal_length],
'Petal Width': [petal_width]}) predict = model.predict_proba(df)[0] return {model.classes_[i]: predict[i] for i in range(3)}
最后,我们将安装 Gradio 和 Pip 并创建我们的界面。
**# Installing and importing Gradio** !pip install gradio
import gradio as grsepal_length = gr.inputs.Slider(minimum=0, maximum=10, default=5, label="sepal_length")sepal_width = gr.inputs.Slider(minimum=0, maximum=10, default=5, label="sepal_width")petal_length = gr.inputs.Slider(minimum=0, maximum=10, default=5, label="petal_length")petal_width = gr.inputs.Slider(minimum=0, maximum=10, default=5, label="petal_width")gr.Interface(predict_flower, [sepal_length, sepal_width, petal_length, petal_width], "label", live=True, interpretation="default").launch(debug=True)
gr.Interface 接受一个解释参数,该参数为我们提供了模式特征的重要性。下面是结果:
图例告诉您更改该功能将如何影响输出。所以增加花瓣长度和花瓣宽度会增加在 virginica 类的信心。只有在增加花瓣长度让你更快“更红”(更自信)的意义上,花瓣长度才更“重要”。
感谢阅读!
如果你做到了这一步,恭喜你!希望你已经彻底理解了什么是特性重要性,它为什么有用,以及你实际上如何使用它。
如果您觉得这很有用,请关注我以获取更多内容。同时,我祝你在学习上一切顺利!
感谢阅读!
务必 订阅此处 千万不要错过另一篇关于数据科学指南、诀窍和技巧、生活经验等的文章!
我希望你觉得这很有趣,很有见地。在评论里让我知道你最喜欢的 2022 年的数据可视化是什么!
不确定接下来要读什么?我为你挑选了另一篇文章:
或者您可以查看我的媒体页面:
https://terenceshin.medium.com/