具有注意机制的序列到序列模型的直观理解和逐步实现
使用具有注意机制的序列到序列体系结构进行英语到印地语的神经机器翻译
如果你曾经使用过谷歌翻译或者曾经与 Siri、Alexa 或谷歌助手进行过交互,你就见证了序列对序列(seq2seq)神经架构的直接影响。Seq2seq 模型构成了机器翻译、图像和视频字幕、文本摘要、聊天机器人以及任何您可能想到的包括从一个数据序列到另一个数据序列的转换的任务的基础。
我们这里的重点是机器翻译,基本上是将一种语言的句子 x 翻译成另一种语言的句子 y 。机器翻译是 seq2seq 模型的主要用例,并通过注意机制得到改进。关于这类主题的文章通常涉及大量代码段的实现和来自多个库的大量 API 调用,而没有对概念本身的直观理解。在这里,我们将对理论和实现进行充分的公正。除了实现之外,我们还将详细了解 seq2seq 架构和关注点的每个组件代表什么。本文使用的代码可以在这里 找到 。
目标
- 在 Tensorflow 中实现、训练和测试英语到印地语的机器翻译模型。
- 对编码器、解码器和注意机制的作用在每一步形成直观和透彻的理解。
- 讨论如何进一步改进现有模型。
读取数据集
首先,我们导入我们将需要的所有库。在这个实现中使用的英语到印地语的语料库可以在 Kaggle 这里找到。将下载一个名为“Hindi _ English _ Truncated _ corpus . CSV”的文件。确保在 pd.read_csv() 函数中放置正确的文件路径,与您的文件系统中的路径相对应。
让我们快速浏览一下我们正在处理的数据集。这相当简单。
预处理数据
在我们继续我们的编码器、解码器和注意力实现之前,我们需要以一种可以用数学方法解释的方式预处理我们的数据。请注意,预处理步骤还取决于我们正在处理的数据类型。例如,在这里考虑的数据集中,也有包含空字符串的句子。我们需要相应地处理这种情况。如果使用其他数据集,可能还会有一些额外或更少的步骤。预处理的步骤包括:
- 在单词和标点符号之间插入空格
- 如果手边的句子是英语,我们用空格代替除了 (a-z,a-z,“), “?”, “!”,“,”
- 多余的空格被从句子中删除,关键字“sentencestart”和“sentenceend”被分别添加到句子的前面和后面,以让我们的模型清楚地知道句子何时开始和结束。
以上每个句子的三个任务都是使用 preprocess_sentence()函数实现的。我们还在开始时初始化了所有的超参数和全局变量。请务必阅读下面的这些超参数和全局变量。我们将在需要时使用它们。
- 遍历包含英语和印地语句子对的每个数据点,确保不考虑包含空字符串的句子,并且句子中的最大字数不大于值 *MAX_WORDS_IN_A_SENTENCE。*采取这一步骤是为了避免矩阵稀疏。
- 下一步是向量化我们的文本语料库。具体来说, fit_on_texts() 为每个单词分配一个唯一的索引。 texts_to_sequences() 将一个文本句子转换成一个数字列表或向量,其中数字对应于单词的唯一索引。 pad_sequences() 通过追加 oov_token (来自 vocab token)足够的次数以使每个向量具有相同的长度,从而确保所有这些向量最终具有相同的长度。 tokenize_sentences() 封装了以上这些功能。
- 接下来,我们从完整的数据集中获取训练集,然后对训练集进行批处理。我们训练模型的句子对的总数是 51712。
编码器
Seq2seq 架构涉及两个长短期记忆(LSTM)在原文中。一个用于编码器,另一个用于解码器。请注意,我们将在编码器和解码器中使用 GRU(门控循环单元)来代替 LSTM,因为 GRU 需要较少的计算能力,并且给出与 LSTM 几乎相似的结果。编码器涉及的步骤:
- 输入句子中的每个单词被嵌入并表示在具有 embedding_dim (超参数)维度的不同空间中。换句话说,你可以说词汇中的单词数量被投射到一个具有嵌入维度的空间上。这一步确保了相似的词(如船&船,人&男孩,跑&走等。)就位于这个空间的附近。这意味着单词“*man”*和单词“ boy ”被预测到的几率几乎相同(不完全相同),而且两个单词的意思相似。
- 接下来,嵌入的句子被馈入 GRU。编码器 GRU 的最终隐藏状态成为解码器 GRU 的初始隐藏状态。编码器中的这个最终 GRU 隐藏状态具有源句子的编码或信息。源句子的这种编码也可以由所有编码器隐藏状态的组合来提供[我们将很快看到,这一事实对于注意力概念的存在是必不可少的]。
解码器(无需注意)
注意:在这一节中,我们将理解不涉及注意力的情况下的解码器。这对于理解注意力和解码器的作用是很重要的,这将在前面的章节中解释。
解码器 GRU 网络是生成目标句子的语言模型。最终的编码器隐藏状态被用作解码器 GRU 的初始隐藏状态。给予解码器 GRU 单元以预测下一个的第一个字是类似于“ sentencestart ”的开始标记。这个令牌用于预测所有的 num_words 个单词出现的概率。在训练时,使用预测的概率张量和实际单词的一键编码来计算损失。该损失被反向传播以优化编码器&解码器中的参数。同时,具有最大概率的单词成为下一个 GRU 单元的输入。重复上述步骤,直到出现类似“句子 end 的结束标记。
无需注意的编码器-解码器模型
这种方法的问题:
- 信息瓶颈:如上所述,对于解码器来说,编码器的最终隐藏状态变成了初始隐藏状态。这造成了信息瓶颈,因为源句子的所有信息都需要在最终状态下被压缩,与在句子中很久以前看到的信息相比,这也可能偏向于在句子末尾的信息。
解决方案:我们通过不仅仅依赖编码器最终状态来获得源语句的信息,而且使用来自编码器的所有输出的加权和来解决上述问题。那么,你问哪个编码器输出的权重比另一个大呢?注意这里的救援,我们将在接下来的部分讨论这一点。
现在注意点
注意力不仅为瓶颈问题提供了解决方案,还为句子中的每个单词赋予了权重。你看,源序列在编码器输出中有它的信息,在解码器中被预测的字在相应的解码器隐藏状态中有它的信息。我们需要知道哪个编码器输出保存了与解码器隐藏状态相似的信息。因此,这些编码器输出和解码器隐藏状态被用作数学函数的输入,以产生注意力得分向量。当预测一个单词时,在每一步计算这个注意力得分向量(在解码器中的每个 GRU 单元)。该向量确定每个编码器输出的权重,以找到加权和。
注意力的一般定义:给定一组向量“值”和一个向量“查询”,注意力是一种计算依赖于查询的值的加权和的技术。
在我们的 seq2seq 架构的上下文中,每个解码器隐藏状态(查询)关注所有编码器输出(值),以获得取决于解码器隐藏状态(查询)的编码器输出(值)的加权和。
加权总和是值中包含的信息的选择性汇总,其中查询确定关注哪些值。这个过程就像将查询投影到值空间中,以在值空间中找到查询(得分)的上下文。高分表示对应的值与查询更相似。
根据原文注意,解码器决定源句中需要注意的部分。通过让解码器具有注意机制,我们将编码器从必须将源句子中的所有信息编码成固定长度向量的负担中解脱出来。利用这种新方法,信息可以在注释序列中传播,解码器可以相应地选择性地检索注释序列。
还记得我们刚刚谈到的数学函数吗?嗯,有几种方法可以找到注意力得分(相似度)。主要的例子如下:
- 基本点积注意
- 倍增注意力
- 附加注意力
在这里,我们不会深入讨论每一个问题。一个简单的谷歌搜索就足以深入其中。对于我们的实施,我们将考虑基本点积注意事项,因为它最容易掌握。你已经猜到这一类注意力是做什么的了。从名字判断,它是输入矩阵的点积。
请注意,基本的点积注意力有一个假设。它假设要进行点积的轴上的两个输入矩阵的维数需要相同,才能进行点积。在我们的实现中,这个维度由超参数 hidden_units 给出,并且对于两个编码器&解码器是相同的。
编码器输出加权和的计算
理论太多。现在让我们回到代码上来!我们将定义我们的注意力类别。
- 取编码器输出张量和解码器隐藏状态的点积,得到注意力得分。这是通过 Tensorflow 的 matmul() 函数实现的。
- 我们取上一步得到的注意力分数的最大值。这样做是为了使分数正常化,并使值在区间[0,1]内。
- 编码器输出与相应的注意力分数相乘,然后相加得到一个张量。这基本上是编码器输出的加权和,由 reduce_sum() 函数实现。
解码器(注意)
在我们的解码器类中采取了以下步骤。
- 就像编码器一样,我们在这里也有一个嵌入层,用于目标语言中的序列。序列中的每个单词都表示在嵌入空间中,其中具有相似含义的相似单词接近。
- 我们还通过使用当前解码器隐藏状态和编码器输出来获得编码器输出的加权和。这是通过调用我们的注意力层来完成的。
- 我们连接在上面两个步骤中获得的结果(嵌入空间中序列的表示和编码器输出的加权和)。这个级联张量被发送到我们解码器的 GRU 层。
- 该 GRU 层的输出被发送到一个密集层,该层给出所有 hindi_vocab_size 个单词出现的概率。概率高的单词暗示模型认为这个单词应该是下一个单词。
注意的编码器-解码器模型
培养
我们定义我们的损失函数和优化器。选择稀疏分类交叉熵损失和 Adam 优化器。每个培训步骤涉及的步骤:
- 从编码器对象获取编码器序列输出和编码器最终隐藏状态。编码器序列输出将用于寻找注意力分数,并且编码器最终隐藏状态将成为解码器的初始隐藏状态。
- 对于要在目标语言中预测的每个单词,我们给出一个输入单词、先前的解码器隐藏状态和编码器序列输出作为解码器对象的参数。返回单词预测概率和当前解码器隐藏状态。
- 具有最大概率的字被认为是下一个解码器 GRU 单元(解码器对象)的输入,并且当前解码器隐藏状态成为下一个解码器 GRU 单元的输入隐藏状态。
- 使用单词预测概率和目标句子中的实际单词来计算损失,并反向传播。
在每个历元中,为每一批调用上述训练步骤,并最终存储和绘制对应于每个历元的损失。
补充说明:在步骤 1 中,为什么我们仍然使用编码器的最终隐藏状态作为解码器的第一个隐藏状态?
这是因为,如果我们这样做,seq2seq 模型将作为一个单一系统进行优化。反向传播是端到端的。我们不想分别优化编码器和解码器。并且,没有必要通过这个隐藏状态获得源序列信息,因为我们现在已经有了我们的注意力:)
测试
为了测试我们的模型在训练后的表现,我们定义了一个函数,该函数接收一个英语句子,并根据我们的模型的预测返回一个印地语句子。让我们实现这个函数,我们将在下一节中看到结果的好坏。
- 我们接受英语句子,对其进行预处理,并将其转换为长度为 MAX_WORDS_IN_A_SENTENCE 的序列或向量,如最开始的“预处理数据”部分所述。
- 这个序列被输入到我们训练过的编码器中,编码器返回编码器序列输出和编码器的最终隐藏状态。
- 编码器的最终隐藏状态是解码器的第一个隐藏状态,输入到解码器的第一个字是开始标记“sentencestart”。
- 解码器返回预测的单词概率。具有最大概率的单词成为我们预测的单词,并被附加到最终的印地语句子中。这个字作为下一个解码器层的输入。
- 预测单词的循环继续,直到解码器预测到结束标记“sentenceend”或单词数量超过某个限制(我们将该限制保持为 MAX_WORDS_IN_A_SENTENCE 的两倍)。
结果
先说结果和发现。我用 NVidia K80 GPU 在 Kaggle 上运行代码,上面的代码中给出了超参数。100 个纪元,训练用了 70 分钟。损失与时期的关系图如下所示。
在训练了 35 个纪元后,我尝试将随机的英语句子扔给我们的 translate_sentence() 函数,结果有些令人满意,但在某种程度上仍有疑问。显然,超参数可以进一步优化。
35 个周期后的结果
但是超参数并不是唯一要对实际翻译中的一些偏差负责的因素。让我们就可以实现以使我们的模型表现得更好的一些要点进行一个小小的讨论。
可能的改进
在实现我们的模型时,我们已经对编码器、解码器和注意机制有了非常基本的了解。根据可用的时间和计算能力,以下是可以尝试和测试的一些要点,以了解它们在实施时是否工作良好:
- 编码器和解码器使用堆叠 GRU
- 使用不同形式的注意力如上所述
- 使用不同的优化器
- 数据集大小的增加
- 使用波束搜索解码代替贪婪解码
我们看到的解码是贪婪解码。我们假设具有最高概率的字是最终预测的字,并输入到下一个解码器状态。这种方法的问题是没有办法撤销这个决定。另一方面,波束搜索解码考虑来自单词概率分布的前 k 个可能单词,并检查所有可能性。你可以阅读更多关于波束搜索解码和一些其他可能的解码这里。
我希望这里提供的信息增加了您对 NLP 和 seq2seq 架构的理解。关注推广更多这样的内容。你也可以在 LinkedIn 上和我联系。
参考
- 【https://arxiv.org/abs/1409.3215】原文为序对序架构没有注意
- https://arxiv.org/abs/1409.0473原文为序对序架构关注
- 数据集:https://www . ka ggle . com/aiswaryaramachandran/hindienglish-corpora
- 斯坦福 CS224N:具有深度学习的| Winter 2019 |第八讲—翻译,Seq2Seq,注意
- https://www . tensor flow . org/tutorials/text/NMT _ with _ attention
对特征向量的直观理解:PCA 的关键
真正理解主成分分析(PCA)需要对线性代数背后的概念,尤其是特征向量有一个清晰的理解。有许多文章解释了 PCA 及其重要性,尽管我发现有一些文章解释了 PCA 背后的直觉。
这篇文章的目的是给特征向量一个直观的理解,使你更好地理解主成分分析。PCA 算法的步骤不是本文的重点。
首先,我想从可视化线性代数的一些基本概念开始。
线性变换
矩阵在线性空间中被称为函数或“变换”——这意味着,在线性空间中对向量进行变换后,保持了线性度。参考下面的例子-
在图中,我们看到一个向量a =【2 ^ 2】在乘以矩阵 b 后,被转换成向量【4 ^ 2】
图 1(左)显示了变换前的矢量“a ”,图 2 显示了被矩阵 B“变换”后的矢量“a”
基础变更
在标准坐标系中,单位矢量 i 和 j 被认为是“基”矢量。这些标准基向量成为测量我们系统的一种方式。
但是,如果我们想改变基本向量,因为我们的数据在不同的系统中可能看起来更好呢?
例如,如果我们在二维空间中有一些数据点。
二维平面中的分散数据
这个视图告诉我们一些关于数据的信息,但是如果我们旋转坐标轴,我们可以得到一个更清晰的视图。
新轴以数据的平均值为中心。这种旋转使我们更容易测量数据的分布或方差。它还清楚地显示了存在两个不同的数据组。
那么,我们如何着手改变基础呢?—线性变换。
矩阵乘法只不过是把当前坐标系的基变换成矩阵定义的新坐标系。矩阵的列向量给出了新基向量的位置。
以前面的线性变换为例,我们将向量 a 乘以矩阵 B ,我们找到了向量 a 在矩阵 B 的基本向量所跨越的新坐标系中的位置。参见下图。
图 1(左)显示了标准坐标系中的矢量 a。图 2(右)显示了放置在矩阵 B 给出的新坐标系中的矢量 a
如果我们想“回到”原来的坐标系,我们只需将“新向量”乘以基矩阵变化的倒数 B 。
因此,将矢量*【4 ^ 2】乘以 B 的逆,就得到矢量【2 ^ 2】*。
特征向量和特征值
特征向量和特征值如何适应所有这些?
在线性变换期间,可能存在一些保持在它们的原始跨度上的向量,并且仅被缩放或收缩。换句话说,它们的方向保持不变。数学上,它被表达为—
由变换 A 给出的特征向量 x 的表达式
λ是与特征向量 x 相关联的特征值,矩阵 A 被称为应用于向量 x 的变换。
表示为变换函数的特征向量
从几何学上讲,我们可以用下面的方式来形象化它
向量 x 上的变换导致将其拉伸 2 倍(请注意,方向或跨度没有变化)
这里,对向量 x 的变换将它拉伸到两倍的长度。因此,与该变换相关的特征值是 2。负特征值与翻转向量或反转向量方向相关。
是什么让它们如此有用?
由特征向量给出的坐标系被称为*特征基,*它可以写成对角矩阵,因为它将每个基向量缩放了某个值。
具有 N 个特征向量的对角矩阵
对角矩阵使计算变得非常容易。考虑将矩阵提升到 100 的幂,在非对角矩阵的情况下,这将成为一项艰巨的任务。在对角矩阵的情况下,计算相当简单。
对角矩阵使计算更容易
根据 PCA
PCA 的目标是最小化冗余和最大化方差以更好地表达数据。这是通过找到与数据点的协方差矩阵相关联的特征向量来实现的。然后将数据投影到由这些特征向量构成的新坐标系上。要进一步了解 PCA,请查阅参考文献[1]和[2]。
我希望这能作为对特征向量的直观理解,并帮助你更好地理解 PCA 算法。
参考文献—
所有的图表都是用-https://www.desmos.com/制作的
- PCA 教程—https://arxiv.org/pdf/1404.1100.pdf
- http://www.math.union.edu/~jaureguj/PCA.pdf
- https://www.khanacademy.org/math/linear-algebra/
- 关于线性代数的精彩系列 3 blue 1 brown—【https://www.youtube.com/watch?v=fNk_zzaMoSs】T2&list = plzhqobowt qd D3 mizm 2 xvfitgf 8 he _ ab&index = 1
对随机化奇异值分解的直观理解
随机线性代数奇异值分解的 Python 实现
矩阵分解是许多机器学习问题的强大工具,它已经广泛用于数据压缩、降维和稀疏学习等。在许多情况下,为了用低秩结构逼近数据矩阵,奇异值分解(SVD)通常被证明是最佳选择。然而,大数据矩阵(例如,8k 乘 10k 矩阵)的准确且有效的 SVD 在计算上具有挑战性。为了解决这种情况下的奇异值分解,许多算法通过应用随机线性代数方法被开发出来。最重要的算法之一是随机化 SVD,它对于分解任何具有相对较低秩的大型矩阵具有竞争效率。
图 SVD 主要发展的时间表。(图片来自[2])
这篇文章将介绍随机奇异值分解的基本思想。为了帮助读者更好地理解随机化 SVD,我们在本文中还提供了相应的 Python 实现。另外,这个帖子的 Jupyter 笔记本可以在这里找到。
初步的
奇异值分解公式
我们首先回顾奇异值分解的概念。你可能已经知道,SVD 是线性代数中最重要的分解公式之一。对于任意给定的矩阵 A ,SVD 具有如下形式
a=uσv**^t
其中矩阵和 V 分别由左和右奇异向量组成。σ的对角线项为奇异值。
一个小矩阵例子
以一个 3 乘 3 的矩阵为例,我们可以通过使用 Python 中的numpy.linalg.svd()
来计算 SVD。让我们看一看:
*import numpy as npA = np.array([[1, 3, 2],
[5, 3, 1],
[3, 4, 5]])
u, s, v = np.linalg.svd(A, full_matrices = 0)
print('Left singular vectors:')
print(u)
print()
print('Singular values:')
print(s)
print()
print('Right singular vectors:')
print(v)
print()*
在这种情况下,奇异值为 9.3427、3.2450 和 1.0885。
*Left singular vectors:
[[-0.37421754 0.28475648 -0.88253894]
[-0.56470638 -0.82485997 -0.02669705]
[-0.7355732 0.48838486 0.46948087]]Singular values:
[9.34265841 3.24497827 1.08850813]Right singular vectors:
[[-0.57847229 -0.61642675 -0.53421706]
[-0.73171177 0.10269066 0.67383419]
[ 0.36051032 -0.78068732 0.51045041]]*
随机化奇异值分解
基本理念
随机化 SVD 可以分为三个主要步骤。对于任意给定的 m -by- n 矩阵,如果我们强加一个目标秩 k 与 k < min( m , n ),那么如图 2 所示的第一步就是**
- 1)通过 -k 生成大小为 n- 的高斯随机矩阵ω**,**
- 2)计算新的 m -by- k 矩阵 Y ,
- 以及 3)对矩阵 Y 应用 QR 分解。
注意,第一步需要返回 m -by- k 矩阵 Q 。
图 2:随机化 SVD 的第一步。(图片来自[2])
然后,如图 3 所示的第二步是
- 4)将 Q 的转置矩阵与矩阵 A 相乘,得到一个 k -by- n 矩阵 B ,
- 以及 5)计算矩阵 B. 的 SVD 这里,不是计算原矩阵 A , B 的 SVD,而是一个更小的矩阵来进行工作。
由于矩阵*的奇异值(即σ**)和右奇异向量(即 V )也是原矩阵A 的奇异值和右奇异向量,我们应该保留矩阵 B 计算的奇异值和右奇异向量***
图 3:随机化 SVD 的第二步和第三步。(图片来自[2])
如图 3 所示,如果将第一步中导出的矩阵 Q 与 B 的左奇异向量组合,就可以得到第三步中矩阵*【A*的左奇异向量(即 U )。
一个小矩阵例子
即使我们在上面已经学习了随机化 SVD 的基本思想,如果没有直观的例子,它也不会真正清楚。为此,我们遵循前面提到的小矩阵奇异值分解。
首先,让我们尝试编写随机化 SVD 的 Python 函数。这里,我们将使用两个 Numpy 函数,即np.linalg.qr()
和np.linalg.svd()
。
**import numpy as npdef rsvd(A, Omega):
Y = A @ Omega
Q, _ = np.linalg.qr(Y)
B = Q.T @ A
u_tilde, s, v = np.linalg.svd(B, full_matrices = 0)
u = Q @ u_tilde
return u, s, v**
现在,让我们用 3 乘 3 矩阵(rank = 2
表示 k 用kmin(m, n )来测试一下:
**np.random.seed(1000)A = np.array([[1, 3, 2],
[5, 3, 1],
[3, 4, 5]])
rank = 2
Omega = np.random.randn(A.shape[1], rank)
u, s, v = rsvd(A, Omega)
print('Left singular vectors:')
print(u)
print()
print('Singular values:')
print(s)
print()
print('Right singular vectors:')
print(v)
print()**
这个随机 SVD 示例的结果是:
**Left singular vectors:
[[ 0.38070859 0.60505354]
[ 0.56830191 -0.74963644]
[ 0.72944767 0.26824507]]Singular values:
[9.34224023 3.02039888]Right singular vectors:
[[ 0.57915029 0.61707064 0.53273704]
[-0.77420021 0.21163814 0.59650929]]**
回想一下,这个矩阵的奇异值是 9.3427 、 3.2450 和 1.0885。在这种情况下,随机化 SVD 的前两个奇异值为 9.3422 和 3.0204 。
我们可以看到,由这两种 SVD 算法计算的第一奇异值非常接近。但是,随机化 SVD 的第二奇异值略有偏差。有没有其他方法可以改善这个结果?又是怎么做到的?
答案是肯定的!
幂迭代随机奇异值分解
为了提高随机奇异值分解的质量,可以直接使用幂迭代法。关于幂迭代的更多细节,请参见[1]第 39 页,第 40 页也有一个 Matlab 实现。
在下面的 Python 代码中,power_iteration()
是迭代计算 m -by- k 矩阵 Y 然后通过 QR 分解导出 m -by- k 矩阵 Q 的函数。
**import numpy as npdef power_iteration(A, Omega, power_iter = 3):
Y = A @ Omega
for q in range(power_iter):
Y = A @ (A.T @ Y)
Q, _ = np.linalg.qr(Y)
return Qdef rsvd(A, Omega):
Q = power_iteration(A, Omega)
B = Q.T @ A
u_tilde, s, v = np.linalg.svd(B, full_matrices = 0)
u = Q @ u_tilde
return u, s, v**
让我们测试一下新的rsvd()
函数:
**np.random.seed(1000)A = np.array([[1, 3, 2],
[5, 3, 1],
[3, 4, 5]])
rank = 2
Omega = np.random.randn(A.shape[1], rank)
u, s, v = rsvd(A, Omega)
print('Left singular vectors:')
print(u)
print()
print('Singular values:')
print(s)
print()
print('Right singular vectors:')
print(v)
print()**
结果是:
**Left singular vectors:
[[ 0.37421757 0.28528579]
[ 0.56470638 -0.82484381]
[ 0.73557319 0.48810317]]Singular values:
[9.34265841 3.24497775]Right singular vectors:
[[ 0.57847229 0.61642675 0.53421706]
[-0.73178429 0.10284774 0.67373147]]**
回想一下:
- 奇异值分解的奇异值有: 9.3427 , 3.2450 ,1.0885。
- 无幂迭代的随机化 SVD 奇异值有: 9.3422 和 3.0204 。
- 幂迭代的随机化 SVD 奇异值为: 9.3427 和 3.2450 。
如您所见,幂迭代随机化 SVD 提供了极其精确的奇异值。
图像压缩
如上所述,可以使用 SVD 或随机化 SVD 来压缩(低秩)信号矩阵。事实上,使用奇异值分解压缩图像的方法非常简单:直接对图像进行奇异值分解,只保留主奇异值和左/右奇异向量。在随机奇异值分解方面,我们可以先预先确定主奇异值的个数,然后通过随机奇异值分解得到奇异值和左/右奇异向量。
对于我们的评估,我们选择莉娜的彩色图像作为我们的数据。这张图片的尺寸是 256×256×3。在这里,我们通过只选择绿色通道来构建一个大小为 256×256 的矩阵*。*
- 直接使用 SVD
- 使用随机奇异值分解代替
从这个图像压缩实验中我们可以看出:
- 1)通过与 SVD 相比较,随机化的 SVD 也可以产生具有规定的低秩的精确压缩(这里,我们设置
rank = 50
)。 - 2)随机化的 SVD 是计算友好的。通过指定
rank = 50
,随机化 SVD 的总 CPU 时间约为 11.6 ms ,而 SVD 的总 CPU 时间为 31.5 ms 。
摘要
在本文中,您发现了 SVD 的随机化线性代数方法。具体来说,您学到了:
- 随机化奇异值分解的基本思想。
- 如何用 Python 实现随机化的 SVD?
你有什么问题吗?
参考
[1]史蒂文·l·布伦顿,j·内森·库兹(2019)。数据驱动的科学与工程:机器学习、动力系统和控制。第 37–41 页。
[2] N .本杰明·埃里克森,谢尔盖·沃罗宁,史蒂文·l·布伦顿,j .内森·库兹(2016)。使用 R. arXiv 的随机矩阵分解:1608.02148。[ PDF
用于时尚图像多类分类的直观 CNN 创建
服装图像分类中使用 Keras 的卷积神经网络创建的分步走查
Img 改编自 Pixabay 通过链接
在之前的文章中,我创建了一个卷积神经网络(CNN)用于二值图像分类。在本文中,我将为零售营销行业创建另一个 CNN。**本文的独特之处在于:不同格式的输入数据需要不同的数据处理方法,不同的 CNN 架构支持多类分类。**它被分成 6 部分。
- 问题陈述
- 数据处理
- 模型结构
- 模型编译
- 模型拟合
- 模型评估
让我们开始旅程吧🏃♀️🏃♂️.
- 问题陈述
我们得到了一组来自零售业的图片。任务是创建一个 CNN 模型来预测一个时尚形象的标签:0 为 t 恤;1 作为裤子;2 作为套头衫;3 作为着装;4 作为外套;5 作为凉鞋;6 as 衬衫;7 作为球鞋;8 as 包;9 作为踝靴。
2.数据处理
我们使用的数据是具有 70,000 幅图像的 Fashion MINST 数据集,其中 60,000 幅用于训练集,10,000 幅用于测试集。所有图像都是灰度,高 28 像素,宽 28 像素。每个像素代表像素的暗度,范围从 0(黑色)到 255(白色)。
图 1 是训练数据的一个片段。请注意,代表图像的每一行都有一个关联的标签和 784 像素值。
图 1 训练数据片段
首先,读入训练和测试数据,将数据帧类型转换为 NumPy 数组。
fashion_train_df = pd.read_csv(‘fashion-mnist_train.csv’,sep=’,’)
fashion_test_df = pd.read_csv(‘fashion-mnist_test.csv’, sep = ‘,’)
training = np.array(fashion_train_df, dtype = ‘float32’)
testing = np.array(fashion_test_df, dtype=’float32')
如果您想以彩色或灰度模式查看图像,请尝试以下方式:
i = random.randint(1,60000)
plt.imshow( training[i,1:].reshape((28,28)) )
plt.imshow( training[i,1:].reshape((28,28)) , cmap = ‘gray’)
接下来,在 0 和 1 之间缩放独立变量,即像素。
X_train = training[:,1:]/255
y_train = training[:,0]
X_test = testing[:,1:]/255
y_test = testing[:,0]
然后,将训练数据分成训练集和验证集,验证占 20%。通过验证集,将评估模型对新数据进行概括预测的能力。
X_train, X_validate, y_train, y_validate = train_test_split(X_train, y_train, test_size = 0.2, random_state = 12345)
最后,我们需要重塑 X_train , X_validate , X_test 。这是一个临界点。 Keras 只接受 CNN 特殊形状的输入数据,即(批量大小,像素宽度,像素高度,颜色通道数)。因此,
X_train = X_train.reshape((-1, 28, 28, 1))
X_test = X_test.reshape(X_test.shape[0], *(28, 28, 1))
X_validate = X_validate.reshape(X_validate.shape[0], *(28, 28, 1))
请注意,有两种方法用于重塑上述数据,达到了相同的目的。第一种方法为 Numpy 设置第一维度进行推断,第二种方法用*定义第一维度。
太好了,现在数据已经准备好训练模型了😎。
3.模型建立
一般来说,建立一个 CNN 需要 4 个步骤:卷积、最大池化、扁平化和完全连接。在这里,我们将建立一个有两个卷积层的 CNN 模型。
3.1 卷积
从根本上说,CNN 是基于卷积的。简而言之,卷积使用一个核矩阵来扫描给定的图像,并应用滤镜来获得某种效果,如模糊和锐化。在 CNN 中,核用于特征提取,以选择图像中最重要的像素,同时保持像素之间的空间关系。
如果你想要一个详细的概念解释,请点击查看上一篇文章。请随意探索这个神奇的网站来可视化卷积如何工作。另一个很棒的 T4 网站是瑞尔森大学的。它直观、互动地展示了 CNN 是如何工作的。
具体来说,
classifier = Sequential()
classifier.add(Conv2D(64,3, 3, input_shape = (28,28,1), activation=’relu’))
注意,特征检测器的数量 n 设置为 64,特征检测器为 3×3 阵列。 input_shape 是我们通过卷积对其应用特征检测器的输入图像的形状。我们设置为 *(28,28,1)。*这里,1 是灰度图像的通道数,28x28 是每个通道中的图像尺寸。这需要与 X_train 、 X_test 、 X_validate 的形状相同。
最后一个参数是激活函数。我们使用 ReLU 去除特征图中的负像素值。这是因为根据卷积中使用的参数,我们可能会在特征图中获得负像素。移除负像素增加了非线性分类问题的非线性。
3.2 最大池化
最大池化是通过滑动表格并取表格中的最大值来减小卷积产生的特征图的大小。最终,它的目标是在不丢失图像中的关键特征和空间结构信息的情况下,减少完全连接层中的节点数量。
具体来说,我们使用 MaxPooling2D() 函数来添加池层。一般来说,我们使用 2x2 的表格进行合并。
classifier.add(MaxPooling2D(pool_size = (2, 2)))
3.3 辍学
辍学是过度拟合的解决方案。辍学是怎么回事🤔?在每次训练迭代期间,一些神经元被随机禁用,以防止它们过于依赖彼此。通过覆盖这些神经元,神经网络每次都保留不同的架构,帮助神经网络学习数据的独立相关性。这可以防止神经元过度学习。
具体来说,
classifier.add(Dropout(0.25))
注意,我们在每次迭代中将 25%的神经元设置为禁用。
3.4 卷积和最大池化
基于之前的实验,添加第二层用于卷积和最大池以提高模型性能。
classifier.add(Conv2D(32,3, 3, activation=’relu’))
classifier.add(MaxPooling2D(pool_size = (2, 2)))
3.5 扁平化
展平是将所有缩减后的特征地图汇集成一个矢量,作为完全连接图层的输入。
具体来说,
classifier.add(Flatten())
3.6 完全连接
通过以上操作,我们将输入图像转换为一维向量。现在让我们使用这个向量作为输入来构建一个分类器。具体来说,
classifier.add(Dense(output_dim = 32, activation = ‘relu’))
classifier.add(Dense(output_dim = 10, activation = ‘sigmoid’))
注意,对于第一隐藏层,作为隐藏层中的节点数的 output_dim 被设置为 32。请随意尝试更多。使用 ReLU 作为激活功能。
完成后,祝贺你完成了模型制作。图 2 是我们构建的🎉🎉。
图 2 CNN 架构图(作者创建的 Img)
4.模型编译
添加完所有图层后,让我们为训练配置 CNN。要做的一个重要决定是损失函数。至于建议,如果一个样本可以有多个类或者标签,使用categorial _ cross entropy。如果类是互斥的(例如,当每个样本恰好属于一个类时),使用sparse _ category _ cross entropy。这里用后者。
classifier.compile(loss =’sparse_categorical_crossentropy’, optimizer=Adam(lr=0.001), metrics =[‘accuracy’])
5.模型拟合
我们根据数据对模型进行 50 次迭代训练。该模型每 512 个样本更新其梯度。使用( X_validate , y_validate )评估模型损耗和精度。
epochs = 50
history = classifier.fit(X_train, y_train, batch_size = 512, nb_epoch = epochs, verbose = 1, validation_data = (X_validate, y_validate))
最终我们得到了一个训练精度为 92% 和测试精度为 90% ✨✨
6.模型评估
现在,让我们在测试集上评估模型。具体来说,
evaluation = classifier.evaluate(X_test, y_test)
我们获得了一个 90% 的测试准确率!如果你想知道如何计算精度,请阅读这篇文章。
下面的图 3 显示了图像的预测标签和真实标签的视图。这个模型似乎不擅长区分套头衫(2)、衬衫(6)和外套(4)。
图 3 预测和真实类别比较
如果你想用更多的数据训练模型,可以随意探索这个链接。如果你想查一个零售业数据科学创新的真实案例,可以查这个页面。
太好了!如果你觉得这篇文章有帮助,请随意点击👏s!如果需要源代码或者更多 CNN 用例,请访问我的 Github 页面🤞🤞。
用于癌症预测的支持向量机
支持向量机介绍及基于 Sklearn 的乳腺癌预测模型建立
来自 Unsplash 的细胞图像
在这篇文章中,我将解释支持向量机(SVM)如何工作,并建立一个乳腺癌预测的 SVM 模型。全文分为以下六个部分。
- SVM 简介
- 问题陈述
- 数据处理
- 模型拟合和评估
- 模型优化
现在让我们开始旅程🏃♂️🏃♀️.
- SVM 简介
支持向量机(SVM)最初在 20 世纪 60 年代开发,然后在 20 世纪 90 年代完善,在机器学习领域非常流行。它适用于可线性分离的数据,其中可以画线来分隔两个类别。SVM 是如何运作的🤔?
为简单起见,假设给出两列数据 x1 和 x2 。为了区分 x1 和 x2 ,我们画了几条边界线,如图 1 所示。根据新数据的位置,这些线会产生不同的结果。但是如何决定哪条线是最好的分离呢🤔?SVM 就是这么做的。
图 1 SVM 分类图(作者创建的 Img)
SVM 通过最大边距搜索最佳边界,如图 2 所示。换句话说,为了使这条线成为 SVM 的结果,从支持向量到边界的两个距离之和必须最大化。因此,只有支持向量对 SVM 结果有贡献。从概念上讲,它是一个简单的算法。
图 2 SVM 分类原则(作者创建的 Img)
为什么 SVM 与其他机器学习算法相比很特别?假设我们正在对水果进行分类:苹果或梨。大多数机器学习算法会看最像苹果的苹果,所以它知道苹果是什么。类似地,它试图通过查看梨的最典型特征来了解什么是梨,如图 3 所示。
图 3 应用/梨按普通 ML 分类(来自 pixabay 的水果图像)
但对 SVM 来说,情况恰恰相反。如图 4 所示,SVM 试图观察更像梨或非标准苹果的苹果,以及更像苹果的梨。这些最不典型的梨和苹果充当支持向量。通过观察极端案例,SVM 旨在找到区分不同阶层的最佳分界线。
图 4 SVM 对苹果/梨的分类(来自 pixabay 的水果图像)
2.问题陈述
乳腺癌是全球女性中最常见的癌症,占所有癌症病例的 25%。早期诊断可以大大增加存活的机会。关键的挑战是将肿瘤分为恶性 0 级或良性 1 级。
3.数据处理
我们的数据来自UCI机器学习库这里。有 569 个癌症数据实例,其中 212 个是恶性的,357 个是良性的。从癌症图像中提取了 30 个特征。
首先,以字典的形式读入数据,并转换成带有“数据”和“目标”列的数据帧。
from sklearn.datasets import load_breast_cancer
cancer = load_breast_cancer()
df_cancer = pd.DataFrame(np.c_[cancer[‘data’], cancer[‘target’]],
columns = np.append(cancer[‘feature_names’], [‘target’]))
图 5 显示了数据片段。显然,所有的特征都是数值。不需要数据编码。
图 5 输入数据片段
接下来,准备训练数据 X 和 y 并分割数据,测试集占 20%。
X = df_cancer.drop([‘target’],axis=1)
y = df_cancer[‘target’]
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size = 0.20, random_state=5)
拟合模型之前的一个必要步骤是特征缩放,以避免一个特征支配其他小特征并减少密集计算。这里我们使用基于单位的归一化来得到范围[0,1]内的所有值。
具体来说,
min_train = X_train.min()
range_train = (X_train — min_train).max()
X_train_scaled = (X_train — min_train)/range_trainmin_test = X_test.min()
range_test = (X_test — min_test).max()
X_test_scaled = (X_test — min_test)/range_test
4.模型拟合和评估
为了拟合和评估该模型,我们从 sklearn 获取 SVM 类。
from sklearn.svm import SVC
from sklearn.metrics import classification_report, confusion_matrix
svc_model = SVC()
svc_model.fit(X_train_scaled, y_train)
y_predict = svc_model.predict(X_test_scaled)
cm = confusion_matrix(y_test, y_predict)
经过测试,如图 6 的混淆矩阵所示,该模型显示了 96% ✨✨.的准确性
图 6 SVM 测试结果的混淆矩阵
5.模型优化
SVM 有两个有助于优化模型的关键参数。
第一个是 C 参数,控制正确分类训练点和具有平滑边界之间的权衡。小的 C 使得错误分类的成本(惩罚)很低,从而产生平滑的边界。然而,如果使用大的 C 参数,这意味着错误分类的高成本,迫使模型更严格地解释输入数据,并可能过度拟合。
**第二个是伽玛参数。**它控制单个训练集的影响范围。有了大的 gamma ,模型将有一个很近的范围,对靠近超平面的点赋予更高的权重。该模型具有过度拟合的高风险,产生更弯曲的边界。然而,使用小的 gamma ,该模型将更加一般化,因为远离超平面的更多数据点将被训练。
具体来说,我们使用网格搜索来调整 C 和伽马参数。
from sklearn.model_selection import GridSearchCV
param_grid = {‘C’: [0.1, 1, 10, 100], ‘gamma’: [1, 0.1, 0.01, 0.001], ‘kernel’: [‘rbf’]}grid = GridSearchCV(SVC(), param_grid, refit=True, verbose=4)
grid.fit(X_train_scaled, y_train)
通过以上,我们找到了如图 7 所示的 C 和 gamma 的最佳参数。
图 7 网格搜索后的最佳参数
我们再次测试了模型,发现精度提高了 0.97,如图 8 所示。该模型仅将 3 个病例错误分类为恶性,这是一个不错的结果,因为这种错误分类不会对诊断造成任何显著影响🎉🎉。
图 8 优化后 SVM 测试结果的混淆矩阵
太好了!如果你觉得这篇文章有帮助,请随意点击👏s!如果你需要一些额外的,访问我的 Github 页面🤞🤞。
凭直觉,我们如何(更好地)理解逻辑回归
逻辑回归和线性判别分析密切相关。这里有一个直观的方法来理解它们,并帮助我们定义 Softmax 回归
在我之前的文章中,我介绍了 5 个分类原则,它们帮助我们定义了 5 种以上的算法。
我们用于逻辑回归的直觉是“平滑直线”。平滑函数是一个逻辑函数。现在,我们如何更好地理解我们是如何想出这个逻辑函数的呢?
和上一篇文章一样,我们将用蓝点和红点来解释 1D 情况的原理。
LDA 和逻辑回归是如何关联的
为了解释 LDA(线性判别分析),思路是先建立两个正态分布。对于新的点 x,我们可以考虑:
- PDF_b(x) 其中 PDF_b:为蓝点的概率密度函数
- PDF_r(x) 带 PDF _ r:红点的概率密度函数
- p(B) :蓝点比例
- p® :红点比例
新点为蓝色的最终概率为:
p(B)×PDF _ B(x)/(p(B)×PDF _ B(x)+p®×PDF _ R(x))
现在让我们看看普通的 PDF:
由于我们考虑到在 LDA 的情况下,两个类别的标准偏差是相同的,因此我们可以简化,x 项将消失,这就是为什么我们称之为线性判别分析。
如果我们不采用同标准差的假设(这意味着两个类别具有相同的标准差),x 项将保持不变,该算法称为二次判别分析。
所以对 LDA 来说,我们最终会得到这样的结果:
1/(1+exp(ax+b))
是的,一个逻辑函数!
当然,参数 a 和 b 与实际的 logistic 回归是不同的。
我们可以比较结果,在这种情况下,我们可以看到结果实际上非常接近(绿色曲线是 logistic 回归,黑色曲线是 LDA)。
结论:LDA 和逻辑回归产生的最终概率是逻辑函数。这两种方法之间的唯一区别在于
- 逻辑回归使用最大似然来估计参数
- LDA,参数来自一个正态分布的估计均值和方差以及每类的比例(先验概率)
简化普通 PDF
既然知道正态 PDF 中的 x 会在同方差的假设下不了了之,也许一开始就可以直接去掉。
所以我们可以直接考虑:
我们可以测试一些参数,以便绘制曲线。让我们从蓝色曲线 fb(x)开始:
- 首先,我们可以让 a_b=1(蓝点的参数 a)
- 对于 b_b,我们可以说曲线应该通过点(x =蓝点的平均值,y=1)
我们认为红色曲线的情况是对称的:
- a_r =-1
- 红色曲线应该通过该点(x =红点的平均值,y=1)
比率的计算
当我们计算比率得到最终概率时
我们最后还会有一个逻辑功能。
下面我们可以看到比例(黑线)。记住这里的参数 a 和 b 是手动选择的。
但即使如此,我们可以看到,在给定的情况下,它实际上并没有那么糟糕。下图中的绿线是逻辑回归模型,而黑线是用我们手动选择的参数计算的比率。
结论:logistic 回归是一个归一化的指数函数(由两类定义)。
Softmax 回归
凭着“平滑直线”的直觉,对于多个预测类的情况,不容易一概而论。但是有了归一化指数函数的思想,我们可以增加更多的类。
对于 K 类,我们可以考虑这个归一化的指数函数来估计 x 属于类 j 的概率
这是一个包含 3 个类别的图表
这被称为 softmax 回归,现在你知道在这个花哨的名字背后,它只是逻辑回归的一个非常简单的概括。
因为您知道逻辑回归非常接近 LDA,所以 softmax 回归的结果应该接近多类 LDA ,如下图所示:
如果你发现一些不够直观的东西,或者如果你有任何问题,请评论,这将有助于我提高我的写作。
凭直觉,我们如何建立非线性分类器
直观地
现实生活中的问题往往是非线性的,所以让我们看看算法是如何处理非线性可分数据的。
在我的文章 直观地说,我们如何理解不同的分类算法 中,我介绍了 5 种数据分类的方法。
但是我用的玩具数据是几乎线性可分。因此,在本文中,我们将看到算法如何处理非线性可分离数据。
让我们举一些 1D 的简单例子。
- 左图(或第一幅图):带有一些噪声的线性可分数据
- 右图(或第二个图形):非线性可分离数据
LDA 和标准差
LDA 表示线性判别分析。所以根据定义,它应该不能处理非线性可分数据。但也许我们可以做些改进,让它发挥作用?
让我们回到 LDA 的定义。想法是建立两个正态分布:一个用于蓝点,另一个用于红点。关于这两个正态分布的标准差的计算,我们有两个选择:
- 我们可以为这两个类选择相同的标准差
- 或者不同的标准偏差
同方差和线性判别分析
LDA 的思想包括比较两个分布(一个用于蓝点,一个用于红点)。或者我们可以计算蓝点密度的比率来估计新点属于蓝点的概率。
当估计正态分布时,如果我们认为两个类别的标准差相同,那么我们可以简化:
在上面的等式中,让我们用蓝色点的下标 b 和红色点的下标 r 来记录平均值和标准偏差。
最后,经过简化,我们得到了一个逻辑函数。
异方差和二次判别分析
如果我们为每一类保留不同的标准差,那么 x 项或二次项将保持不变。
在下图中,我们可以看到,如果红点和蓝点的标准偏差不同,会更有意义:
然后我们可以看到两条曲线接触的地方有两个不同的点,这意味着它们是相等的,所以,概率是 50%。我们可以用这两个交点作为两个决策边界。
正是因为二次项导致了二次方程,所以我们得到了两个零点。所以我们称这种算法为 QDA 或二次判别分析。
总之,用 LDA 提出非线性分类器是一种非常直观的方法:必须考虑不同类别的标准偏差是不同的。
但明显的缺点是,如果非线性更复杂,那么 QDA 算法就不能处理它。例如,如果我们需要 3 个线性边界的组合来分类数据,那么 QDA 将失败。
逻辑回归和一个二次项
逻辑回归在非线性可分数据面前表现也很差。我们可以在下面看到结果。
作为我上一篇文章的提醒,下面的图表显示了概率(蓝线和红线),您应该最大化乘积以获得逻辑回归的解。
我们知道 LDA 和逻辑回归是非常密切相关的。它们的最终模型是相同的,具有逻辑功能。但是参数的估计是不同的。你可以直观地阅读这篇文章 ,我们如何(更好地)理解逻辑回归 。
我们可以看到,从 LDA 到 QDA,区别在于二次项的存在。那么,为什么不尝试通过增加一个 x 项来改善逻辑回归呢?这就是为什么它被称为二次逻辑回归。
然后将一个变量的初始数据转化为两个变量的数据集。现在,我们可以看到数据似乎表现为线性。
我们可以对这两个变量进行逻辑回归,得到如下结果。因为我们有两个输入和一个介于 0 和 1 之间的输出。然后我们可以将算法创建的表面可视化。
然后就可以找到决策边界,对应的是概率等于 50%的线。哪一个是 LR 表面和 y=0.5 的平面的交点
在 2D,我们可以画出一条线,作为我们的决策界限。我们可以把概率作为颜色的不透明度。
现在,二次 Logistic 回归和二次判别分析是什么关系?在 1D,唯一的区别是参数估计的不同(对于二次逻辑回归,是似然最大化;对于 QDA ,参数来自均值和标准差估计)。
现在为了更高的维度。QDA 可以考虑协方差。至于 QDA,二次逻辑回归也无法捕捉数据中更复杂的非线性。
SVM 及其内核
手动添加二次项的技巧同样适用于 SVM。下面的结果表明,超平面分隔符似乎捕捉到了数据的非线性。(带 X 的点是支持向量。)
数学家们找到了其他转换数据的“技巧”。其中一个技巧是应用一个高斯内核。之后我们会看到一个快速的证明。但是解释它的一个直观的方法是:不要把支持向量(这里它们只是点)看作孤立的,而是把它们看作围绕着某种分布。
我们先来看线性可分的数据,直觉仍然是分析前沿地区。代替线性函数,我们可以考虑采用由支持向量的分布形成的分布的曲线。我们可以看到支持向量【在边界】更重要。
现在让我们回到非线性可分的情况。我们可以应用同样的技巧,得到以下结果。
决策值是所有分布的加权和加上一个偏差。
我们可以注意到,在边境地区,我们有直线段。
最后,我们可以计算概率来对这些点进行分类。
内核技巧的想法可以看作是将数据映射到一个更高维度的空间。并且新的空间被称为特征空间。
在多项式核的情况下,我们的初始空间(x,1 维)被转换成 2 维(由 x 和 x 形成)。在高斯核的情况下,维数是无限的。我们可以用泰勒级数将指数函数转换成多项式形式。
来想象内核的变化。我们可以考虑分类器的双重版本。
将内核应用于原始版本相当于将其应用于对偶版本。
通过添加二次项的先前变换可以被认为是使用多项式核:
而在我们的例子中,参数 d(度)是 2,系数 c0 是 1/2,系数γ是 1。
因为
因此,高斯变换使用一个名为 RBF ( 径向基函数 ) 内核或高斯内核的内核。
结论:核技巧被用于 SVM,使其成为一个非线性分类器。实际上,同样的方法可以应用于逻辑回归,我们称之为核逻辑回归。
kNN 和决策树呢?
通过构造,kNN 和决策树是非线性模型。所以他们在非线性可分数据面前会表现的很好。
提醒一下,这是两种算法的原理。
对于 kNN,我们考虑一个局部常数函数,并为一个新点找到最近的邻居。然后邻居类的比例会导致最终的预测。
对于一棵分类树,思路是:分而治之。原则是除以最小化一个度量(可以是基尼系数或熵)。因此在生长树时可以找到非线性决策边界。
这是我们玩具数据决策树的结果。
下面是非线性分类器的工作原理:
- 使用 LDA,我们考虑不同类别数据的异方差,然后我们可以捕捉一些非线性。但是它是有限的,并且不能捕捉更复杂的非线性。
- 使用 SVM,我们使用不同的内核将数据转换到一个特征空间,在这里数据是更加线性可分的。内核的性质可以非常多样,因此我们可以处理更复杂的非线性。
- 对于逻辑回归,我们可以用一个二次项来转换它,或者我们可以使用内核技巧。
- kNN 将考虑非线性,因为我们只分析邻域数据。
- 有了决策树,连续数据的分割可以在任何地方进行,只要指标指示我们继续分割数据以形成更同质的部分。
我花了很多时间试图找出一些直观的方法来考虑不同算法之间的关系。我希望它对你也有用。
我在这里没有讨论的另一种转换数据的方式是神经网络。您可以阅读下面的文章来了解如何操作。
“神经网络”这个术语可能看起来很神秘,为什么一个算法叫做神经网络?它真的模仿真实的…
towardsdatascience.com](/intuitively-how-do-neural-networks-work-d7710b602e51)
对于不同分类器的原理,你可能会对这篇文章感兴趣。
机器学习算法有时可以被视为一个黑盒,那么我们如何以更直观的方式来解释它们呢?
towardsdatascience.com](/intuitively-how-can-we-understand-different-classification-algorithms-principles-d45cf8ef54e3)
凭直觉,我们如何理解不同的分类算法原理
机器学习算法有时可以被视为一个黑盒,那么我们如何以更直观的方式来解释它们呢?
在下图中,给定蓝点和红点,我们可以看到有一个模式。作为人类,我们可以用我们的“直觉”来区分它们,并预测一个新点的颜色。
例如,我们大多数人可能会说图中的黑点属于蓝点类别。但是你如何用数学的方式表达这种“直觉”呢?你会看到不同的直觉导致我们所知道的所有算法…
如果蓝点和红点对你来说可能比较抽象,那么让我们来看一些真实世界的例子。
- 肿瘤的诊断(B 为良性,M 为恶性),具有两种不同的肿瘤特征。
- 垃圾邮件检测:使用两个变量,美元符号的频率和单词“remove”的频率。
你可能已经知道一些可行的分类算法:逻辑回归、kNN、LDA(线性判别分析)、SVM、决策树等等。
但是理解它们直观吗?
首先,为了简化问题,我们将在本文中考虑 1D 的情况(我们将在另一篇文章中考虑 2D 的情况)
正如我们在下图中看到的,我们只有一个预测值,即 X,目标变量是 Y,有两个类,红点和蓝点。
注意,从数学上来说,“红”或“蓝”没有任何意义,所以我们将这个变量转换成一个二进制变量:1 代表“蓝”,0 代表“红”。这就对应了这个问题:圆点是蓝色的吗?1 代表真,0 代表假。当然,这只是约定俗成。
在现实世界的例子中,“圆点是蓝色的吗?”可以是:肿瘤是不是恶性的?这封邮件是不是垃圾邮件?
第一个原则:邻居分析
对于一个给定的点,其思想是查看该点的邻居。
邻居是什么?离最近的的那些?
“接近”是什么意思?最短的距离?
什么是距离?在这里,它只是指 x 的两个值之差(x 是一个实数)。
现在,给定一个新点,我们可以计算这个点和其他点之间的距离。我们可以选择最接近的。
但是有多少呢?这是这种方法的一个大问题:我们选择多少点?
首先,我们称这个数为 k,k=5。
现在我们可以检查邻居的等级。如果你有一个类的多数,那么你可以用多数类来预测。在我们的例子中,如果邻居的多数类是 1,那么新点很有可能属于类 1。
注意“多数”原则。所以如果我们选择了 k=4,那么就很难决定了。因此,如果 k 是奇数,它有助于作出明确的决定。
现在可以计算一个新点的概率,我们有下图:
这个原理叫做 kNN,意思是 K 近邻。
现在,这个算法的特别之处在于,由于你不知道要保留哪些点,所以你必须为每个预测保留所有的点。这就是为什么我们说这个算法不是基于模型的,而是基于实例的。
第二个原则:全球比例和正态分布
我们刚刚在上面说过,选择数字 k 是不方便的,我们没有对我们的观察结果进行任何建模。
现在我们该怎么办?首先,让我们考虑所有的人口。如果您这样做,那么您的预测对所有新点都是一样的:多数类和概率将是多数类的比例。
这可能有点简单化了。为了做得更好,我们可以考虑点的正态分布。为什么是正态分布?这很简单,简化了所有的计算。这真的是个好理由吗?嗯,这就是我们所说的“建模”。
所有的模型都是错的,但有些是有用的。—乔治·博克斯,著名统计学家
现在,我们可以问一个更好的问题,而不是数邻居:我离蓝点或红点有多远。换句话说:给定一个新点,这个点是蓝色或红色的概率是多少?
- 这个新点离蓝色点有多近?我们考虑蓝点(标注为 PDF_b)的概率密度函数,距离(或者说接近度)将是 PDF_b(x)
- 新点离红色点有多近?我们考虑红点(记为 PDF_r)的概率密度函数,距离(或者说接近度)将是 PDF_r(x)
为了知道新点更接近哪种颜色,我们只需比较两个概率密度。下图中,黑色曲线代表比率: PDF_b/(PDF_b+PDF_r)
现在,就建模而言,令人惊讶的是:使用 kNN,您必须保留所有的点才能做出决定,现在您只需使用几个参数,如均值和标准差,以便定义正态分布。
在之前的数据集中,我们有相同数量的蓝点和红点。如果数字不同,我们可以用两个密度的比例来加权。
现在类似线性判别分析、二次判别分析、朴素贝叶斯分类器等算法都在使用这个原理。
它们之间有什么区别?
还记得我们必须计算正常密度吗?为了得到正态分布,我们必须计算平均值和标准差。就手段而言,很简单。但是对于标准差,我们有两个选择。我们可以计算每个类的标准差,或者,为了简化,我们可以认为这两个类的标准差是相同的。为什么我们可以使用两个标准差的加权值。为什么是“线性”对“二次”呢?为此,我写了另一篇文章:直观地说,我们如何才能建立非线性分类器。
第三个原则:分析前沿领域
根据前面的原则,我们可以看到,在对整个数据集建模之后,我们得出了一个决策边界。
现在,我们可以想:如果目标是找到一个前沿,为什么我们不直接分析前沿领域?
“边界区域”可以用 M(表示边距)来定义,M 是我们选择用来定义“边界区域”的两点之间的距离。我们可以将红色圆点的候选点记为**,将蓝色圆点的候选点记为。用数学术语来说,我们有:**
M=B-A
首先让我们考虑这两个类是线性可分的。然后我们可以计算红点的最大值(我们得到 A) ,蓝点的最小值(我们得到 B) 。(注意,在 1D 的情况下,最小值和最大值很容易定义。但是当维度更高时,它可能更复杂。)
现在*非常直观的(见下面的引用),*我们可以选择两个值的平均值作为决策边界。
最大化间隔看起来不错,因为决策[区间]附近的点代表非常不确定的分类决策:分类器几乎有 50%的机会做出任何决定。具有较大裕度的分类器做出的分类决策确定性不低。这给了你一个分类安全裕度— 支持向量机:线性可分的情况
但是如果有一个类 0 的值非常接近类 1 呢?那么我们将会有如下图所示的边界:
现在我们有了这种直觉,第二种情况下定义的决策边界并不是最优的:边界区域很小。现在,如果我们保持前面的 M,让异常点,如下所示:
我们可以为异常点添加一个惩罚项,它可以是异常点和 a 之间的距离。
更好的是,我们可以用一个系数对惩罚进行加权,我们称之为 c。因此,最终的决策标准是:
M - C ×(红色异常点- S_r)
(保证金减去加权罚金)
一般来说,如果有几个异常点,我们可以对它们进行求和:
M - C × ( ∑(红色异常点- S_r) + ∑ (S_b -蓝色异常点))
通过这样做,我们还解决了如下图所示的点不是线性可分的情况下的问题(记住,我们说过我们可以首先考虑点是线性可分的,这样我们就可以得到我们直观的“边界区域”)。)
现在,这个原理被用于 SVM(支持向量机),为了得到 SVM 的最终版本,我们必须做一些小的调整(我们将在另一篇文章中讨论它们)。而为什么叫“支持”呢?因为你使用不同的点(称为“支持向量”)来最大化边际(或者更准确地说是惩罚边际)。
第四个原则:寻找最佳曲线
对于这个原理,让我们考虑一条直线来模拟作为 x 的函数的 y。
y=a × x + b
为了简化这个问题的求解,我们可以考虑直线会经过每一类的均值,如下图所示。
现在,当 y=0.5 时,你可以考虑 x 的值,这可以作为你决定 y 属于 0 类还是 1 类的边界。
但是用这个模型,对于 x 的大值,你会得到 y > 1,对于 x 的小值,y <0. So what can we do? Let’s smooth it. Like this?
Come on, we can do better, like this?
To do the smoothing in the graph above, we can use this function for example
p(x)= 1 / (1+exp(-(a × x + b)))
To understand why we use this function, you can note that we find the initial straight line : y(x)=a × x + b in this function, and we can define: sigma(y)= 1 / (1+exp( -y )))
So we have : p(x)=sigma(y(x))=1 / (1+exp(-(a × x + b)))
To visualize the smoothing effect, we can see the graph of sigma below
- when x is very big, the output is very close to 1
- when x is very small, the output is very close to 0
And now the task is to find the parameters: a and b. To achieve this goal, we can consider the probability of each point to be correctly classified.
- For the blue dots, the probability value is p(x);
- For the red dots, the probability value is 1-p(x).
The criterion is the maximization of the overall probability: we multiply all the probabilities (for class 0 and class 1). And we try to maximize the result.
P_overall = product (p(x), for class 1) × product ( (1-p(x), for class 0)
Or in a simpler form
P_overall = product (p(x)×y +(1-p(x))×(1-y))
The mathematical trick is then to take the log and to take the derivatives, etc. But it turns out that there is not an easy way (a closed formula) to find the parameters, and we have to solve it numerically.
Below we can see the situation for different values of a 和 b 。垂直线段代表每个点的概率。所有这些概率的乘积应该最大化,以便优化 a 和 b 。
这是逻辑回归使用的原理,因为我们之前看到的 sigma 函数的名字,叫做逻辑函数。
(如果你觉得这个解释不够直观,可以看看这篇文章:直观地说,我们如何(更好地)理解 Logistic 回归
第五个原则:避免错误
最后一个原则是关于选择决策边界时可能犯的错误。
现在有哪些错误:
- 如果在该区域中,蓝色点占多数,那么红色点就是错误;
- 如果红点占多数,那么蓝点就是错误。
当找到决策边界时,这些点被分成两个区域。这个想法是为了描述区域的“同质性”:错误越少越好。
现在让我们找一个函数来描述区域的“均匀性”。以 p 为例,作为第 1 类的比例。我们得到 0 类的比例为(1-p)。
现在有了 p 和(1-p),我们能做什么?让我们从非常简单的操作开始。
- Sum?嗯,再想想。
- 产品。嗯,让我看看,这是一张图表。
所以这个函数是对称的,这是一个必需的特性,因为这个函数应该对任何一个类都有效。并且该函数的输出可以指示该区域的“均匀性”:越低越好
- 当 p 接近 1 时,几乎所有的点都是蓝色的,指示值很低
- 当 p 接近 0 时,那么几乎所有的点都是红色的,那么指标也很低
- 当 p 为 0.5 时,那么我们有相同数量的红点和蓝点,这不是理想的状态。该指标处于最高水平。
为了找到决策边界,我们必须测试不同的 x 值。对于 x 的每个值,创建两个区域:左手侧区域和右手侧区域。对于每一方,我们可以计算指标,然后我们用每个区域的分数比例对它们进行加权,以获得总体指标。
现在,我们可以测试作为决策边界的所有点,并查看指标如何变化。
现在,我们可以采用指标的最低级别来找到 x 的最佳值。注意,由于我们有一个阶跃函数,我们可以计算定义指标最低级别的两个 x 值的平均值。
这个原则的特别之处在于,你可以在每个区域中继续寻找其他决策边界。我们将在另一篇专门讨论该原则的文章中看到,这样做的好处是您可以轻松处理非线性情况。
所以一步一步,我们可以一个一个的找到最优前沿。
这里我们有一个决策树,关于每一步不同的决策界限。
现在的问题是:我们什么时候停止?可以有不同的规则…
这个原则也被认为是“分而治之”。它让我们能够生长决策树。这些树也是更复杂算法的基础,如随机森林或梯度推进机器。
让我们回顾一下:
- 原则 1:检查邻居,我们得到 KNN
- 原则二:考虑全球比例和正态分布,我们可以做 LDA,QDA,或者 NB。
- 原则三:研究边疆地区,尽量做到“干净”和大。我们得到了 SVM。
- 原则四:画一条直线,平滑,试着调整。我们得到逻辑回归
- 原则 5:分而治之。我们得到了决策树。
请注意,我们没有完成五个原则的所有推理:
- 用 kNN 法测定水中的钾
- 决策树中的停止规则
- 系数 C 的确定
- 逻辑回归中 a 和 b 的确定
对于机器学习从业者来说,你可以注意到我自愿没有使用技术术语,也许你可以评论并把技术术语放在正确的上下文中:硬边、软边、梯度下降、凸性、超平面、先验概率、后验概率、损失函数、交叉熵、最大似然估计、过拟合……
当我们谈论机器学习和人工智能时,我们总是谈论神经网络,但为什么我们在这里没有提到它们?实际上,我们确实看到了一个简单的神经网络的例子**,它是逻辑回归,关于它的文章即将发表。**
使用的玩具数据非常简单:这两个类是线性可分的。这些算法是如何处理非线性可分的数据的?你可以阅读这篇文章:直观地,我们如何才能建立非线性分类器。
直观来看,神经网络是如何工作的?
直观地
“神经网络”这个术语可能看起来很神秘,为什么一个算法叫做神经网络?它真的能模仿真正的神经元吗,又是如何模仿的呢?
在我上一篇关于 直观上,我们如何理解不同的分类算法 的文章中,我介绍了分类算法的主要原理。然而,我使用的玩具数据非常简单,几乎是线性可分的数据;在现实生活中,数据几乎总是非线性,所以我们应该让我们的算法能够处理非线性可分数据。
简单逻辑回归和非线性数据
让我们比较一下逻辑回归对于几乎线性可分数据和非线性可分数据的表现。
通过下面的两个玩具数据,我们可以看到,当数据几乎是线性可分时,逻辑回归有助于我们找到决策边界,但当数据不是线性可分数据时,逻辑回归无法找到明确的决策边界。这是可以理解的,因为逻辑回归只能将数据分成两部分。
在本文中,我们将尝试以不同的方式重用逻辑回归,并尝试使其适用于非线性数据。
组合逻辑回归
当观察蓝点和红点时,数据是非线性的,因为我们可以看到有 3 个部分,我们应该找到两个决策边界。那么,如果…如果我们试着结合两个逻辑回归会怎么样?
例如,我们有这两个基于逻辑回归的模型。
我们称它们为 h1 和 h2。
然后,我们可以将 h1 和 h2 结合起来,用另一个逻辑回归进行最终预测。
然后,您可以用 h1 和 h2 各自的逻辑函数表达式来替换它们:
然后我们可以通过找到不同的系数来解决问题,你猜怎么着,最终的结果是相当令人满意的:我们可以看到,两个组合的 Logistic 回归给了我们两个决策边界。
更好的表现
让我们回到我们模型的最终表达式:
这个表情可能看起来挺吓人的。让我们给它加点艺术感。
让我们画一些东西来以更易读的方式表示这些函数:
横向来看,甚至会更好:
让我们指定所有要确定的系数,我们可以将它们放在线上,这样更容易理解:
我们可以将线性函数和 sigmoid 函数分开,以更好地提高可读性。
长方形?不,圆圈更好。等等,你看到我看到的了吗?
哇,它们就像…神经元!
图片来自 123rf
我们可以添加更多的颜色使它更好。连接代表重量,我们可以让它们变粗来代表更大的数字。用一种颜色,我们可以代表这个符号。
- 这里,绿色是正的,红色是负的。
数学家是艺术家!
神经网络词汇
现在让我们围绕这个神经网络创造一个全新的世界。
让我们创建不同的层:输入、输出和隐藏层。
当计算给定输入值的输出值时,必须遍历所有隐藏层。所以你会从左边走到右边。姑且称之为“正向传播”。
最后,您将计算出一个估计的输出,并且您必须将它与实际输出进行比较。这个误差将帮助我们微调权重。为此,我们可以使用梯度下降,我们必须计算不同的导数。
由于最终会计算误差,因此我们会在输出层之前调整神经元的权重。我们总是会从右向左调整。所以姑且称之为“反向传播”。
二维空间会发生什么
现在让我们考虑两个输入变量,这是玩具数据。
直观上,我们可以看到两个决策边界就足够了。所以让我们应用两个隐藏的神经元:
然后,我们可以通过用周围区域数据测试神经网络来可视化最终结果。我们可以看到模型做得相当好。
现在,既然我们知道在神经网络内部只有逻辑回归,我们可以尝试将转换的不同步骤可视化。
隐藏层转换
让我们看看 H1:输入数据是原始的蓝点和红点。H1 是一个有两个输入变量的逻辑回归,所以结果是一个表面。
然后第二个隐藏神经元 H2 是类似的。
输出图层 O1 是一个逻辑回归,也接受两个输入,因此我们也有一个表面来表示结果。而 O1 的输入是数值在 0 和 1 之间的两个数据系列,因为它们是两个逻辑回归的结果。然后我们可以看到,如果我们取值 0.5 到表面,最初的蓝点和红点可以线性分成两部分。
那么在这个神经网络中发生了什么呢?在某种意义上,我们可以说神经网络将非线性可分离的数据转化为几乎线性可分离的数据。
另一个可视化
隐藏层有两个神经元,所以是二维的。因此,如果我们想看到这种转变,我们希望看到点是如何在平面上移动的。我们知道这些点的最终位置在单位正方形(0,1)x(0,1)中。
我们可以分别看到蓝点和红点。注意,箭头指向最终位置。
然后我们可以看到最后的逻辑回归。
原始数据不是线性可分的,但是经过变换后,它们被移动到单位正方形中,在那里它们变得几乎线性可分。
另一个更复杂数据的可视化
现在让我们考虑另一个玩具数据。凭直觉,你会应用多少个隐藏神经元?
嗯,3 个神经元就足够了,如下图所示:
我们可以看到每个神经元的逻辑回归曲面。
隐藏神经元 2
隐藏神经元 3
对于输出神经元,它有 3 个输入(因为它们是逻辑回归的结果,值在 0 和 1 之间),我们可以在一个单位立方体中可视化它们。
我们可以创建一个动画来更好地可视化
让我们回顾一下:
- 初始 2D 数据不是线性可分的。
- 它们被转换成 3D 空间(在一个隐藏层中有 3 个神经元)。
- 经过变换后,它们变得几乎线性可分。
- 最后,简单的逻辑回归允许我们对转换后的数据进行线性分类。
- 最终的逻辑回归有 3 个输入变量。因此该模型可以预测三维空间中每个点的概率。这就是为什么我们可以看到立方体充满了彩色点。决策边界是一个曲面。
更复杂的神经网络可以捕捉甚至更复杂的输入数据关系。但我们可以看到原理相当简单:隐藏神经元的目的是将非线性可分离的数据转换到一个可以线性分离的空间。
如果你对其他分类器如何处理非线性可分离数据感兴趣,你可以看看下面的文章:
现实生活中的问题通常是非线性的,所以让我们看看算法是如何处理非线性可分数据的。
towardsdatascience.com](/intuitively-how-can-we-build-non-linear-classifiers-10c381ed633e)
凭直觉,在找到你的完美伴侣之前,你应该和多少男人约会
直观地
你可以看到这篇文章的标签是数据科学,概率统计专题。是的,这是正确的,有一个数学模型来定义最佳策略。
用平面图标制作的图标
为了找到你的完美伴侣,最好的策略是什么?第一个的家伙是不是最好的?我们必须和尽可能多的 T2 男人约会才能找到最好的吗?
但你很容易理解,这两种策略都是有风险且非最优:第一种情况,如果你和第一个约会的男生结婚,你以后会后悔;在第二种情况下,你可能会失去一些好的比赛机会,并最终孤独终老。
为了确定对你来说什么是最好的策略,你必须知道你想约会的男人总数,因为也许你想在某个截止日期前结婚,也许你没有时间或者不想和很多人约会。
值得注意的是,最佳男朋友的概念只是你选择了的约会总数(n)中的最佳男朋友。所以如果你选择了一次约会,那么根据定义,你已经选择了最好的一次。
为了简化数学模型,需要指定以下几个假设:
- 都可以对比评级,你可以毫不含糊的说谁更好。
- 如果你拒绝了一个男生,你就不能收回你的决定。不然就太容易了。
- 他们一个接一个地到来,顺序是随机的,你只能在给定的时间里和一个人约会。
- 当然只能选择一次。
现在的问题是:如何选择那个家伙,使得(被选择的家伙是最好的那个)的概率最高?
随机策略还是固定策略
首先让我们看看最简单的选择方式:随机策略。
如果你的策略是在任何一步随机停止,选择那个家伙,**不做比较,**那么推理如下 : 对于每一步,他是最好的概率是 1/n 。而停在步骤 I 选择他的概率也是 1/n 。
既然不比较也不研究小伙,那么这两个事件(小伙最优秀和小伙被选中)可以认为是独立。所以我们可以有下面的结果:
现在我们来看另一种选择方式:固定策略。
为了简化词汇,我会说 guy i ,对于你在步骤 i 遇到的那个家伙。指数 i 与第 I 次约会有关,与男生无关。值得注意的是:这里随机的是你选择约会的次次,而不是在所有男生中选择一个男生。
如果你选择总是留在第一选择的*。那么他是最好的那个的概率是: 1 /总数= 1/ n*
如果你选择永远留在第二选择*,不管是什么原因*。那么概率将是:
- 第一,guy 1 应该不是最好的那个。但是嘿,这个概率很高:(n-1)/n
- 知道了这一点,第二个人是最好的概率是 1/(n-1)
- 最后,总是选择第二个人的最终概率也是 1/n 。
如果您选择始终使用第三个选择:,理由非常相似
我们现在可以概括推理,如果你选择总是保持你的第一个选择*:1/n .*
所以在没有任何有意义的策略(随机策略或固定策略)的情况下,从 10 个家伙中选出最佳家伙的概率是 10% 。
凭直觉,你知道你可以做得更好:你希望能够将现在的人与以前的人进行比较。
所以现在就来详细说一下对比策略吧!
比较策略
该战略包括两个阶段:
- 第一阶段:我们可以称之为观察阶段,这是一个你最终总是会离开那个人的阶段,但是你会有一个和其他人比较的基础。观察阶段的最佳人选,我们称他为参考人选。
- 第二阶段:我们可以称之为选择阶段,我们将比较当前的家伙和所有以前的家伙,如果她或他比所有以前的更好,那么你选择这个。这就等于说,你会选择第一个比你在观察期约会的男生更好的。
为了选择最好的一个,或者换句话说,为了在选择我们的家伙时有最高的概率,唯一要确定的参数是:在观察阶段我们应该和多少个家伙约会?
拒绝的最佳次数
如果你约会的总数是 10,那么答案是 3!
听起来可能很无情,用这个策略,你应该和三个男生约会,然后拒绝他们(因为他们只是观察阶段的一部分)。然后从第 4 个家伙开始,如果他比之前所有的都好(这也和对比参考家伙是一样的),你就可以和他在一起了。
而且用这个策略,选到最优的概率差不多有 40% !
这比随机策略好 4 倍。
为什么?让我们做个示范。
用小数字演示
为了演示 10 个人的比较策略,我们将通过首先与一个人迭代,然后与两个人迭代,然后与三个人迭代,以此类推。
只有一个家伙
如果你选择只和一个男人约会*,那么我们不能说他是最好的还是最差的,事实上,他两者都是!***
两个家伙
如果你选择和两个男人约会,那么你只有两个选择。你可以和第一个人在一起,也可以和第二个人在一起。没有区别。所以你有 50%的概率选择最好的一个。
值得注意的是,随机策略会产生相同的结果。
三个家伙
如果你选择和 3 个家伙约会,那么我们要做一些概率计算。假设我们可以用★来给他们打分,因为有 3 个人:★★是最好的,而★是最差的。
有 6 种可能的情况。请注意,选项 1 表示你第一次遇见一个男生,选项 2 表示你第二次遇见一个男生,等等…
坚持你的第一选择
如果你决定坚持你的第一选择,那么选择最佳选择的概率是 6 分之 2。(我们的场景表中的场景 1 和 2)。
*所以**概率是 33%,*这和随机策略的概率是一样的。
拒绝第一个选择,然后选择
如果你决定拒绝第一个,那么你的第一选择将是你的观察阶段。而从第二个选择开始,你会选择:如果他比之前所有的都好,那你就和他在一起,如果不是,你就继续(并以第三个结束)。
现在你可以看到,使用这种策略,你最终得到最佳策略的概率是 6 分之 3。
或者换句话说,概率是 50% 。
拒绝第一和第二个选择,选择第三个
对于这种策略,概率很容易计算,它是 6 中的 2,即 33%。
在总共 3 个人的情况下:
- 如果你遵循随机策略,那么选择最佳家伙的概率是 33% 。
- 如果用比较策略遵循我们的最优策略,那么概率是 50% !
一个广义的论证
现在让我们尝试推广两个给定参数的概率 P 的计算
- n,男生总数
- r,拒绝的次数
这一次,我们必须使用条件概率,因为在这个策略中,事件是相关的。
那么我们必须不同地考虑这两个阶段:
- 在观察阶段:我们会全部拒绝。所以概率是 0
- 在选择阶段:对于盖伊 I,知道他是最好的一个,那么他实际被选中的概率就是之前所有的盖伊都没有被选中的概率。或者从步骤(r+1)到步骤(i-1)的家伙。
换句话说:
- 从步骤(r+1)到步骤(i-1)的人并不比观察阶段的人更好(否则,他会被选中)
- 在第(i-1)个家伙中,最好的家伙在第 r 个家伙中。
现在我们可以通过分析(i-1)个之前的家伙来计算选择这个家伙 I 的概率,知道他是最好的一个:
- 成为(i-1)个男生中最好的一个的概率是: 1/(i-1)
- 既然观察阶段有 r 个家伙,那么概率是: r/(i-1)
现在我们可以把之前所有人的概率加起来:
数值应用和模拟
现在有了这个公式,我们可以很容易地计算出给定数字 n 的概率,然后我们可以找到最佳的拒绝次数(这是概率最高的数字)。
下面是结果表:
你看。对于 10 个男生,你的最佳策略是拒绝前 3 个男生。
现在你想约会更多?好的,这些是概率和最优拒绝数:
对于那些想要更多的人,让我们来看看拒绝的最佳数量以及任何总数的相关概率。
下图显示了不同总数的最佳选择的概率(最大概率)向一个百分比收敛。比率 r/n(拒绝次数/总次数)也是如此。
我们可以显示比率 r/n,而不是在 x 轴上显示 r。我们得到下面的两个图表。
**
对于那些了解微积分的人来说,我们可以证明曲线会收敛到
然后我们可以找到最大值(通过求导),我们得到最佳比值:1/e ≈ 0.368
最优概率的极限也是:1/e
(e 是欧拉数:e ≈ 2.72)
最佳人选策略的结论
让我们回顾一下:
- 定义你想约会或可能约会的男生总数。例如,你 20 岁,你想在 30 岁前找到你的完美伴侣。你觉得你可能会和 10 个男人约会。
- 拒绝最佳绷绳数,定义参考绷绳。在 10 的情况下,你应该拒绝前 3 个家伙。而在现实生活中,对他们进行排名是比较困难的,所以要研究你的排名标准。
- 现在不要让下一个比参考人更好的人走。如果没有,你可能会在截止日期前找不到任何人。
- 如果你是对方,一定不要处于观察阶段,为了最大化你的机会,你宁愿成为选择阶段的第一个家伙。
现在,如果你和你遇到的第一个男人结婚了,并且正在读这篇文章,请记住,这只是一个模型
所有的模型都是错的,但有些是有用的。
明智地使用它。😃
1/e 最佳选择定律
实际上我们已经看到了统计学中非常著名的东西,这种策略也被称为 1/e 策略,它可以应用于其他现实生活中的问题,比如:
- 招聘候选人
- 购买汽车
- 买房子
- 等等。
记住,现实生活总是不同于数学模型。
直觉上…或者不是,你不应该只看成功的人来变得成功
克服生存偏见就是认识到丢失的东西可能包含重要的信息
科比·门德斯在 Unsplash 上的照片
最近,我和一个孩子进行了一次谈话,他告诉我:“我长大后要成为一名足球运动员。这样我就能赚很多钱,买一栋大房子”。除了这么小就有令人担忧的物质主义心态,这个推理背后的明显的生存偏见让我笑了。
是的,如果你在电视上看到所有的足球运动员,你可能会认为这是一个特别赚钱的职业;然而,这种推理是有偏见的,因为你没有考虑到那些没有成为明星的人。
只有孩子有生存偏见吗?不,成年人也很容易落入这个陷阱。
生存偏差背后的故事
维基百科:生存
也许你以前已经听说过生存偏差:一个著名的例子是研究二战飞机的统计学家亚伯拉罕·瓦尔德的故事。军方告诉沃尔德,许多飞机坠毁,返航的飞机上有许多弹孔。军队跟踪返航飞机上弹孔的位置,以了解在哪里加固飞机。
假设返航飞机上的弹孔分布如下:
当你看这个图的时候,你会在哪里加固这些平面?
陆军最初的做法是:“好吧,我们看着回来的飞机,我们看到他们被击中最严重的地方:所以我们应该加强这些削弱的部分,不是吗?”。根据上图,我们应该加固机翼,不是吗?
然而,沃尔德说不,那将是确切地说是错误的决定。
沃尔德已经意识到**这个结论只是基于幸存者得出的,但是那些没有回来的飞机呢?**事实上,这些洞表明这些飞机被击中后仍然能够回来。所以我们掌握的信息是不完整的。被击中而没有回来的飞机有了更准确的信息,知道哪些零件需要加固。
误解:如果你想学习如何生存,你应该关注幸存者。
真相:如果你不看失败,你就无法知道是什么让一个幸存者不同于一个失败者。
然而,如果军队犯了这样的错误,这是否意味着我们在日常生活中也容易产生这种偏见?是的,当然。
我们可以在日常生活中的许多其他例子中看到生存偏差。
存活率偏差示例
生存偏差可能发生在你的研究中有两个类别的时候,其中一个你可以标记为“幸存者”:在商业中它可能是成功的对不成功的;在医学上,可以是活人 vs 死人;在一局中,可以是胜者 vs 败者。
如果你决定创办一家初创企业,只考虑那些已经成功的企业,你会忘记,大多数初创企业在头两年都会失败。
在医学中,排除偏见尤其重要:医生应该记住治疗没有像预期的那样奏效的次数以及奏效的次数,以免他们忘记一些重要的事情。
例如,现在在我们看来显而易见的是,放血毫无用处,无助于治愈任何疾病(事实上它的危害更大)。然而,这种基于抽血可以帮助身体保持平衡和健康的信念的做法,已经延续了 2000 多年,直到 19 世纪末。为什么这么久?嗯,这正是因为幸存者偏差:在某些情况下,放血可能会产生积极的结果,如果没有完整的科学方法,只考虑幸存者。
现在记住这一事实尤为重要,因为我们都在焦急地等待新冠肺炎的治愈方法:一些治疗可能声称是成功的,但如果没有对照组,就很难从科学上证明这一点。希望不应该影响我们的判断。
维基百科放血
或者一个更简单的例子:你听说有人成功地尝试了一种新的饮食方式,并且正在考虑尝试减肥。然而,如果有些人通过一周只吃苹果成功减肥(例如),并在他们的博客上谈论它,你不会听到有人尝试同样的饮食,但效果并不那么好。
在我们的社会中,我们倾向于向在他们的领域中成功的人聚集,而不是从失败的人那里寻求建议(即使他们能给我们有趣的建议关于你应该 而不是 做)。
“一个效果很好的愚蠢决定在事后会变成一个明智的决定.”——心理学家丹尼尔·卡内曼在《思考的快慢》中
那么,数据科学家能从这些课程中学到什么呢?
为什么数据科学家需要了解生存偏差
作为一名数据科学家,您需要处理提供给您的数据。你应该从你所拥有的数据中获得洞察力。所以,你给出的结论取决于你掌握的数据。那么,如果您因为最重要的数据不是您拥有的数据而遗漏了一些重要信息,该怎么办呢?
最近要给某个行业做一个流失模型。
然而,GDPR(一般数据保护条例)刚刚开始在该公司实施,例如,一些搅拌机的数据不再可用:因为它们很久以前就搅拌过,出于隐私原因,数据只能存储一定数量的年,除非我们得到客户某种形式的同意。
例如,数据集是在 2020 年建立的。我有 1990 年的客户数据,到 2020 年,仍然是数据集中的客户。但是我没有 2015 年之前离开的客户的数据。这里有生存偏差吗?
事实上,是的,我没有 1990 年至 2015 年之间的客户数据,也没有这一时期的客户数据。那么如何应对呢?
在这种情况下,一个简单的方法是对所有人群进行相同的参考,并通过仅选取合同开始日期早于或等于 2015 年的人群来开始分析。
在其他情况下,可能没有一个简单的解决方案,因此您可能不得不在给出有偏见的结论之前停止分析,因为一些重要的数据丢失了。
简而言之,生存偏差被定义为“一种认知偏差,当某人试图根据过去的成功做出决定,而忽视过去的失败时就会出现这种偏差。”科学是一种从表象中过滤出真实的方法。乍一看似乎很直观的东西可能不是一个好的答案。
库存管理—应对不可预测的需求
使用 Python 对随机需求进行供应链分析
这篇文章旨在解决产品随机需求带来的挑战。这是一个案例研究,处理不同产品的需求分布,并使用蒙特卡罗模拟来最佳地管理其库存并获得预期利润。
想象一下,你是一个高度定制产品的经销商,因此每个客户对该产品的需求都是独特的。你不可能每天都收到这种产品的订单。一些产品可能会因季节性而有所不同,而另一些则可能有潜在的趋势。为了对这种随机需求进行数学建模,您必须获取每种产品至少在过去 12 个月的销售信息。
现在,顾客有时会走进商店,却买不到他们想要的特定商品。虽然很难对消费者行为建模,但我们可以提供一个粗略的估计,即客户在任何给定的一天下订单的概率为“p”。这个 p 可以简单的用去年的订单数除以工作日数来计算。
除非或直到你有一个特定的客户合同,另一个不确定性是订单大小。在本案例研究中,假设订单大小遵循一个分布参数未知的对数正态分布(这是常见的情况)。因此,获取产品的历史销售额非常重要。
本案例着眼于 4 种不同产品的销售,并试图采用持续审查或定期审查政策来管理其库存。目标是最大化其预期 利润。
附加产品数据
根据去年的销售情况,下面给出了每种产品的需求分布直方图。
每种产品的需求分布。按作者分类的图表
你可以看到对每种产品需求的明显差异。例如,产品 2 是每天都有人购买的大批量产品(p = 1),平均订单量为 649。而产品 4 有 24%的时间被购买,其平均订单规模约为 150。下表提供了每种产品的汇总,可以完全根据过去的销售数据进行计算。
每个产品的摘要
理解交付周期期间的需求统计数据非常重要。
将这些数字放入上下文中,产品 1 的交付周期是 9 天(如前所述),因此在这 9 天中,分销商可以预期平均有 705 个订单。在下原始订单时,需要考虑到这一点,否则经销商总是无法满足需求。
定期审查
有了定期审查系统,库存检查和再订购只在指定的时间点进行。例如,可以每周、每两周、每月或其他周期检查库存并下订单。当一个公司或企业处理多种产品时,定期审查系统的优点是要求在相同的预设定期审查时间下几个项目的订单。有了这种类型的库存系统,多种产品订单的装运和接收就很容易协调。在前面讨论的订购量、再订购点系统下,各种产品的再订购点可能在完全不同的时间点遇到,使得多种产品的订单协调更加困难。[1]
具有概率需求的定期审查模型的库存模式。[1]
在定期审查政策方法中,在一定时间后补充库存。这个时间周期取决于审核周期和交付周期。蒙特卡洛技术被用来模拟商店中每种产品的日需求量。从上一节的分布图中,我们注意到,除了产品 2 之外,并不是每一种产品都在每天被购买。计算出的预期订单比例表明当天产品被购买的概率。例如,对于产品 1,预期比例是 0.76,这意味着在一年中的任何一天,客户都有 76%的机会购买产品 1。
如果购买一种产品,那么需求遵循对数正态分布。通过取每日数值的对数,将前一年的需求分布转换为对数正态分布。为了模拟日常顾客购买行为,从 0 到 1 范围内的均匀分布中选取一个随机数。
从对数正态分布中提取的 Python 代码
进行蒙特卡罗模拟来模拟需求行为和一次实现的利润计算。在模拟中,该算法每天迭代,试图捕捉产品的库存水平。这是为了生成当天的产品需求。
为定期审查进行蒙特卡罗模拟
该算法的逻辑如下:
- 如果当前库存水平可以完全满足需求,则库存水平会根据需求和当天售出的单位数量的增量而减少
- 如果库存水平不能完全满足需求,那么现有库存就是当天售出的数量
为了对定期检查策略进行建模,该算法会跟踪一年中的当天。如果一年中的某一天等于审核期,则下订单将库存补充到数量为 M 的订单。该值是决策变量,并作为输入传递给算法。在该特定产品的交付周期结束后,库存会根据所下的订单数量进行更新。这将持续 365 天。
产品 1 的库存模拟。按作者分类的图表
一个 365 天模拟的库存水平可用于确定商店当年的利润。所有售出的单位都乘以产品售价来计算收入。
成本分为三个部分,
- 产品成本、
产品成本的计算方法是将每种产品的单位成本乘以订购数量的总和。 - 订购成本
订购成本的计算方法是将当年的订购次数乘以该产品的单项订购成本。将一年中每天的库存水平汇总,以表明一年中有多少库存。 - 持有成本。
然后通过将持有的股票数量乘以产品的单位尺寸和持有单位的每日成本来计算持有成本。
从收入中减去这些成本,得到当年实现的相应利润。损失的单位数量被合计并除以当年的需求,以给出当年订单损失的比例。
年利润的数学公式如下。
计算年利润的 Python 代码
该模拟被执行 10,000 次,以给出每次利润和订单损失比例的多种实现。这些结果用于绘制直方图,并计算利润的平均值和标准偏差,以及特定订单直到点(M)的订单丢失比例。下图是产品 1 的一个模拟,订单数量为 2071。
产品 1 的利润和订单损失分布。作者配图。
类似地,这个练习可以针对一系列值 M 进行,以确定给我们最高预期利润的值。从下图中可以看出,对于产品 1,我们模拟了 1000 到 3000 之间的数值范围。这给出了 87,863 美元*的最佳预期利润(再次运行模拟时,87,992 美元是最佳利润)*截至 2071 年的订单。
对其他产品进行这些实验,并相应地计算它们的最佳值。由于利润线性依赖于需求和与特定产品相关的成本,因此可以计算出该函数的最大值。
产品 1 —模拟结果。作者配图。
使用一个月的审查期,下表列出了每种产品的最佳订购点、预期年利润和一年中的订单损失比例。
备选方案 1——定期审查
持续审查
在多周期模型中,库存系统以许多重复的周期连续运作;存货可以从一个时期结转到下一个时期。每当库存位置达到再订购点时,就会发出 Q 单位的订单。因为需求是概率性的,所以无法提前确定再订购点的到达时间、订单之间的时间以及 Q 单位的订单到达库存的时间。[1]
具有概率需求的订货批量、再订购点模型的库存模式。[1]
请注意,每当 Q 单位的订单到达时,库存就会增加或跳跃。基于概率需求,库存以非恒定速率减少。只要达到再订购点,就会下新订单。有时, Q 单位的订单数量会在库存为零之前到达。然而,在其他时候,更高的需求会导致在收到新订单之前缺货。与其他订单数量、再订购点模型一样,经理必须确定库存系统的订单数量 Q 和再订购点 r 。[1]
在该策略中,分销商能够定期检查库存,并确定他们希望在哪个点下订单(即再订购点)。分销商还可以指定他们每次想要订购的数量(即订购数量)。
蒙特卡洛模拟中的逻辑被更新用于持续审查策略。
为持续审查进行蒙特卡罗模拟
每天,该算法都会检查库存水平,并将其与再订购点进行比较。
- 如果库存水平低于或等于再订购点,它就会下订单。但是这种库存只有在产品交付周期结束后才能变现。例如,产品 1 有 9 天的提前期,如果在第 52 天下订单,库存将在第 61 天补充。
- 然后,在更新库存水平时,它遵循与定期审查算法相似的决策逻辑。
- 利润和预期订单损失的计算类似于定期审查政策的计算。
产品 1 的库存模拟。作者配图。
对于每个产品,这些结果的模拟再次进行 10,000 次。这些结果用于绘制直方图,以计算订单数量 2002 和再订购点 812 的利润和订单损失比例的平均值和标准偏差。下图是产品 1 的一个模拟。
产品 1 的利润和订单损失分布。作者配图。
通过在每种产品的一系列值之间执行网格搜索,可以计算出优化利润函数的订货量和再订货点的组合。如下图所示,对于产品 1,这些值是针对订单数量从 1000 到 3000 以及再订购点在 500 到 1100 之间进行模拟的。该图似乎显示了一个凹函数,表示利润的最大值。
产品 1 —网格搜索结果。作者配图。
在产品 1 的这个场景中,根据模拟,2002 年的订单数量和 812 的再订购点的最大利润为$110,174。
使用这种策略,下表列出了每种产品的最佳再订购点、最佳订购数量、预期年利润和一年中的订单损失比例。
备选方案 2——持续审查
定论
持续审查和定期审查政策各有优点。定期审查政策有一个固定的审查周期,使组织能够更好地预测一段时间内的订单。而持续审查政策保持订单规模不变,并在下订单的时间方面提供灵活性。由于持续审核策略中的决策变量比定期审核中的决策变量多两个,因此持续审核策略的解决方案空间可能会更大。
定期审查政策和持续审查政策的利润比较
从上表中我们可以清楚地看到,就每种产品的预期利润而言,持续审查政策优于定期审查政策。持续审查政策的总预期利润比定期审查的总预期利润高 25%。如果决策完全基于预期总利润,研究建议持续审查政策作为更好的选择。
GitHub 链接
所有的图表和代码都可以在我的 GitHub 资源库中找到,请随意下载并根据您的用例修改数字。
https://github . com/wiredtoserve/data science/tree/master/inventory management
参考
[1]安德森、斯威尼、威廉姆斯、卡姆、科克伦、弗莱、奥尔曼。管理科学导论:决策的定量方法。2015 年第 14 版。Cengage 学习。第 457-478 页
用机器学习研究时态数据中的异常
利用 Python 和机器学习分析时序数据,并交互可视化。
这是你要做的:
概观
在这本笔记本中,我们将探索脸书的开源萨里玛模型先知来识别时间序列数据中的异常值。以下是你将学到的东西:
- 什么是时序数据?
- 萨里玛是什么?
- 构建一个简单的优化器来自动优化 Prophet 模型
- 如何使用 Prophet 预测数据
- 使用 Prophet 和 Bokeh 识别交互式仪表板中的异常值
- 使用散景创建用于调查的时序仪表板布局
什么是时态数据?
在我的上一篇文章中,我们使用了空间数据——也就是说,空间中某个地方存在的带有坐标的数据。时态数据通常是空间数据的伴生物,它是任何具有相关时间或日期的数据。时态数据对于全面理解数据集至关重要,能够理解与时间相关的统计数据(趋势、季节性和异常值)将显著提高您处理业务数据的整体能力。
在我擅长的国家安全和国防领域,可能没有比时态数据更重要的数据类型了。时态数据有助于我们了解时间模式,并对未来做出预测。在本文中,这也是您将要学习的内容。
我们的数据
我们将使用来自武装冲突地点事件数据库的数据,具体范围缩小到伊拉克。数据可以从 github 这里下载,或者从 ACLED 网站下载。我们将分析 2016 年至 2020 年伊拉克冲突事件数据的趋势和季节性,预测这些数据,并识别异常值。然后,我们将创建一个配套的折线图,它将允许我们深入特定的事件类别,这样我们就可以在发现异常值后对其进行调查。走吧!
加载库
首先,让我们导入必要的库。我们将使用所有的 Bokeh 来创建我们的交互式图形,fbprophet 用于 prophet 预建模型,sklearn 用于模型优化,pandas 用于一些数据操作。
加载数据
你可以在 Github 上找到我在本笔记本中使用的具体数据。然而,我强烈建议你在这个练习中尝试使用你自己的时间序列数据!
在这个代码块中,我们将使用 value_counts() 方法来获取我们的折线图所需的数据。我们希望可视化每天的事件数量,因此我们将 value_counts() 应用于我们的日期组。
在整篇文章中,您将看到我在处理日期时间数据时喜欢应用的一些实践。首先,每次对数据帧进行操作时,我都会对其进行重新排序——这有助于减少稍后我们训练模型时的错误。我也总是喜欢在我的数据帧中有一列是日期时间格式,另一列是字符串格式。我使用 datetime 列进行分析,string 列用于标签、图例和工具提示。
提取分类数据
接下来,我们想要为每个事件类型获取 value_counts() 。最终产品将是一个可视化,允许用户在折线图中选择一个时间窗口,然后在第二个合作伙伴可视化中显示相关事件类型。我们将遵循与上面相同的步骤,但是现在针对 event_type 字段中的每个事件类型。我们将使用 groupby() 方法来实现这一点。
打扫
接下来,只需删除重复项并重新排序我们的值。
为什么是先知?
Prophet 是 facebook 开发的开源 SARIMA 模型。SARIMA 是一种时间序列回归*(解读:预测)*技术,它考虑了时间序列数据集的各种统计属性,包括移动平均、季节性和趋势。趋势是时序数据的一个属性,与数据集中的总体正增长和负增长有关。季节性与数据集中的周期性变化有关,例如周末活动的定期减少或每天下午活动的增加。
Prophet 最初是为了满足脸书的预测需求而开发的,因为 facebook office 严重依赖时间序列预测来设定目标和衡量进展。你可以通过观看由 Prophet 开发者提供的视频来了解更多关于 Prophet 及其起源的信息。
Prophet 需要两个数据源才能工作:‘ds’,代表日期戳,以及**‘y’**,目标变量。如果您正在跟随这款笔记本,那么我们已经做到了这一点——如果没有,那么为了您自己的数据,请记住这一点。
模型优化
模型优化是任何机器学习项目的关键要素。所有机器学习模型都有一个或两个关键参数,需要进行优化以实现模型的最佳性能。对于 Prophet,该参数为change point _ prior _ scale。此参数定义了模型响应数据集中的变点的灵活程度,需要进行优化以防止过度拟合和欠拟合。
为了对此进行优化,我们将使用一个非常简单的优化模型。它简单地遍历用户定义的历元,测试每个参数,并选择返回最低误差的参数。为此,我们将使用均方误差统计。
有关使用均方误差进行模型优化的更多信息,请参见本文关于均方误差和线性回归。
训练模型
既然模型已经优化,我们就用我们的数据来训练它。你会看到,根据我提供的数据, MSE (均方差)大约为 38。这可能看起来很高,但对于时间序列预测来说非常好——通常 MSE 低于 50 对这些目的来说是好的。
如果想进一步降低错误率,常见的技术是在训练模型之前对数据应用指数平滑。把它想象成时间序列数据的缩放和标准化——你可以在这里了解更多关于时间序列数据的指数平滑。
绘制数据
我们将使用散景来绘制数据。交互性是使您的数据可视化脱颖而出并为您的客户提供更多用途和洞察力的一种很好的方式。尽管有其他库和方法来创建交互式可视化,但 Bokeh 是我的首选库。然而,这不是一个散景教程。如果不熟悉散景,可以试试他们的 入门指南 。
基本上,我们将原始数据绘制为散景图内的线字形,并绘制不确定性界限,在 Prophet 数据帧中表示为 yhat_upper 和 yhat_lower 作为面积图。
分析趋势和季节性
如上所述,趋势和季节性是时间序列数据的两个关键统计属性。理解这些因素对于理解数据本身至关重要。Prophet 用 plot_components 方法使这变得简单。
在下面的图表中,你可以看到伊拉克冲突事件在过去几年中一直呈总体负面趋势(随着 ISIS 被稳步击败)。然而,你可以看到在整个 2020 年都有小幅上升的趋势——这是由于多种因素,包括冠状病毒疫情和美国从该地区的多个基地撤军,导致 is is 活动增加。
就季节性而言,你可以看到一些有趣的模式——周五和穆斯林安息日的活动通常很少。你可以在 3 月-6 月看到一个活动高峰,这是众所周知的常见的西部沙漠战斗季节,因为温暖的气温使干河谷变干,使地形更容易通过;这也是典型的穆斯林斋月。有趣的是,数据还显示了 10 月至 11 月的高活动量,很可能是由于炎热的夏季过后天气变冷。就近年来而言,这也是一个充满政治冲突和抗议的年度时期。
绘制异常值
接下来,我们将识别时间序列数据中的异常值。这些事件超出了由 Prophet 模型确定的趋势和季节性。这对国家安全和国防数据至关重要。例如,在伊拉克,我们知道恐怖活动有季节性的上升和下降。那些季节性上涨来的时候,怎么知道是不是比平时差?异常值检测有助于识别恐怖活动的可能死灰复燃,让我们有更好的准备。
我们将使用一种简单的方法——我们寻找超出 Prophet 预测的不确定性上限的数据点,然后绘制该点。在最终的图中,我们可以看到,几乎整个 2016 年都充满了高于预期的恐怖活动,2019 年底和 2020 年初也是如此-这是由于伊拉克总理阿卜杜勒-迈赫迪向新总理卡迪米移交权力后的政治不稳定,2019 年 10 月开始的重大抗议和骚乱活动,以及上述因素,如美国撤军和冠状病毒疫情。
绘制分类数据
我想更彻底地调查异常活动。我想知道,在活动增加的时候,哪些类型的事件构成了这些数据——简易爆炸装置、常规战争等等。为此,我们将绘制第二个图来可视化数据。
散景自动链接共享列数据源的图之间的选择。因为两个图的数据来自相同的数据框,一个图中的选择将自动反映在第二个图中。我们需要做的只是在视觉上对元素进行样式化,以吸引人们对所选元素的注意,并明确不同时期流行的类别。
在这个数据的例子中,我们将使用散景中的 selection_glyph 和 nonselection_glyph 属性,使数据在未被选中时不可见。这将使我们能够很容易地看到我们在原始图中选择的时间窗口的主要数据类型。
该代码片段仅显示了一个层的绘图。完整代码见笔记本。
主绘图使用一个 box_select 工具来动态改变可视化。将鼠标光标放在图中并拖动以选择时间窗口,观察可视化显示的变化!
摘要
现在,您可以通过 Prophet 机器学习模型使用 SARIMA 预测技术来分析时间序列数据。您可以自动优化您的模型,并使用它来了解数据中的趋势和季节性属性。您可以在交互式图表中绘制该信息,以便以后在仪表板或 web 应用程序中发布。伟大的作品!
使用熊猫和海牛调查数据集
克里斯·利维拉尼在 Unsplash 上的照片
在数据分析师的生活中,有成百上千的事情要做。数据准备、清理、探索性分析,然后可视化结果。通过熊猫和 Seaborn 图书馆,我研究了“IMDB 数据集”,并得出了一些结论。
数据集
我在分析中使用了 IMDB 数据集。它有 21 列和 10,866 行。
下载这里
清洁部分
首先,导入分析所需的所有库。
我必须从数据集中删除不需要的列。如果您不想使用数据集中的某些列,最好只在清理部分删除它们。
然后,我检查数据集中的重复行,并从中删除一行。
下一步是寻找 NaNs,我在我的数据集中的选择性列中发现了许多 NaNs 值。虽然 NaN 值在对象类型列中,但我决定用空白替换它们。
此外,我研究了数据类型,并更改了“release_year”列的 dtype。然后,在数据集中添加类似“利润”和“利润水平”的列,以供将来分析。
分析和可视化部分
使用熊猫的“情节”方法,我将这些年来上映的电影数量可视化。就这样,我想象了 1960 年至 2015 年期间大多数发行的类型电影。
利用小提琴图,我找到了历年(2011–2015)的“利润”数字分布。在此期间,您可能会发现许多异常值,但这些异常值不会被删除。
为了观察 2011 年至 2015 年期间电影的运行时间,我对遭受损失和获得大量利润的电影都使用了群集图。2011 年上映了一部时长 900 分钟的电影。这显然像是一个异常值,但这不是打字错误或错误的数据。所以,我也必须把它保存在数据集中。
我用条形图根据电影的运行时间水平检查了电影的平均预算。
结论
分析数据集后,我得出了以下结论:
- 大多数电影都是在 2014 年上映的。自 1960 年以来,电影发行数量的趋势线呈正曲线。
- 导演喜欢拍“戏剧”电影。大多数上映的电影都属于“戏剧”类型。
- 2015 年是电影行业最赚钱的一年。
- 最赚钱的年份是 2011 年至 2015 年,赚钱的电影超过 100 分钟,而亏损的电影只有 90 分钟左右。
- 令人惊讶的是,120-150 分钟长的电影的预算是 90-120 分钟长的电影的两倍多。但是,超过 180 分钟的最长电影的预算低于平均预算。
你可以在这里 找到整个代码 !!
如需讨论和更好的解决方案,请在我的 Linkedin 上留言!
调查 JSON 模块
探索 Python 中最流行的数据格式之一
JSON 是 JavaScript Object Notation 的缩写,创建它的目的是帮助提高数据传输的效率。它做到了这一点,现在它是网络数据传输的黄金标准。在这篇博文中,我将介绍如何使用 JSON 模块在 Python 中利用存储在 JSON 文件中的数据。
首先,我们要加载我们的 JSON 文件。我将在这篇文章中浏览的文件包含了 2001 年以来纽约市的竞选财务数据。正如这篇文章的标题所提到的,Python 中有一个非常有用的 JSON 模块,可以非常容易地导入,这使得处理 JSON 文件更加容易。
**import** json
要加载一个 JSON 文件,首先使用 Python 内置的 open 函数打开文件。然后,将文件对象传递给 JSON 模块的 load 方法。完成之后,最好检查一下 JSON 文件是作为哪种数据类型加载的。你认为它会是什么数据类型?
如果你猜是一本字典,干得好!JSON 文件通常是以分层的嵌套结构创建的,这意味着它们可能会令人困惑,甚至一开始会让人不知所措。但是,JSON 中的许多数据类型在 Python 中有相同的伙伴,只是名称不同。例如:
- Python 列表,元组 = JSON 数组
- Python str = JSON 字符串
- Python float , int = JSON 编号
- Python 真 = JSON 真
- pythonFalse= JSON False
- 无 = JSON 空
由于 JSON 模块的优秀开发人员,您可以使用 Python 中许多您熟悉的方法来研究您的 JSON 文件。一些例子:
- 检查字典的关键字:
- 检查值的数据类型:
- 将字典视为数据框架:
- 查看键中值的数量:
- 和预览数据:
因此,虽然 JSON 文件的结构可能有点吓人,但 Python 中的 JSON 模块允许您以一种对熟悉 Python 的人来说既高效又舒适的方式进行 EDA。如果您想获得一些关于如何研究嵌套数据的实践,JSON 文件是一个很好的资源。
感谢您的阅读!
基于机器学习的胸片新冠肺炎感染可解释预测研究
我们能否通过应用神经网络和可解释算法来发现胸部 X 线新冠肺炎的特征?
编剧:布雷克·范贝罗&马特·罗斯
摘要
- 探索一种可解释的机器学习模型来区分新冠肺炎阳性患者的胸部 x 光片。
- 开发了深度卷积神经网络来分类胸部 X 射线。我们开源的模型基础设施是可扩展的、模块化的和有据可查的,这将允许其他研究人员通过构建这个库来快速迭代。参见我们的 GitHub 库。
- LIME 算法被用来解释模型的预测。
- 我们邀请在机器学习或医疗保健领域拥有专业知识的研究人员、个人和组织为这个项目的发展做出贡献(联系信息在本文末尾)。
- 这个项目是一个早期的原型,而不是一个医疗诊断工具。构建这个库需要更多的数据和专业知识。
介绍
毫无疑问,这篇文章的读者知道新冠肺炎教的迅速传播。这种传染病对公众健康和国家经济构成严重威胁。加拿大和世界各地的病例数呈指数增长。研究人员已经接受了行动呼吁,并试图了解更多关于 SARS 冠状病毒 2(新型冠状病毒)。为了支持这些努力,机器学习研究人员正在使用他们的技能来揭示更多关于该病毒的信息。例如,研究人员基于 ResNet50 开发了 COVNet 框架,以区分新冠肺炎病例的 CT 扫描和其他类型的社区获得性肺炎[1]。
本文记录了一项应用机器学习方法搜索可解释模型的实验,以根据胸部 X 射线(CXR)区分与新冠肺炎相关的肺炎病例。尽管机器学习可能有助于解决这个问题,但模型做出的任何预测(无论多么成功)都将受到医疗保健提供商的仔细审查。必须为模型的预测提供解释。我们希望可解释的机器学习模型将为新冠肺炎不断增长的知识做出积极贡献。
为什么要研究 x 光?
由于逆转录聚合酶链式反应(RT-PCR)检测试剂盒供应有限,因此有必要探索识别和优先处理新冠肺炎疑似病例的替代方法。在我们的城市加拿大伦敦,新冠肺炎测试结果的周转时间目前报告为 24 小时[2]。在农村和偏远地区,这一周转时间可能更长。尽管 CT 扫描被用于对怀疑患有新冠肺炎的患者进行临床检查,但价格昂贵。因此,较小的中心获得 CT 扫描仪的机会可能有限。x 光机更便宜,也更便携,因此是一个可行的选择。
需要澄清的是,这篇文章并没有声称 CXRs 应该被用于新冠肺炎的诊断。加拿大放射科医师协会建议遵循 CDC 的指导方针,即 CXR 和 CT 不应用于诊断新冠肺炎[3]。该建议指出,病毒测试是目前诊断新冠肺炎的唯一手段,即使患者在 CXR 或 CT 上有提示性特征。也就是说,一些研究表明,放射成像(特别是 CT)可能与 RT-PCR 一样敏感[4]。这些发现展示了为什么我们决定探索这一途径,并构建开源工具来支持进一步的研究。同样重要的是要注意,正常的成像并不意味着患者没有被新型冠状病毒感染,只是他们没有表现出新冠肺炎呼吸系统疾病的迹象。
目标
- 确定是否可以训练机器学习分类器来区分新冠肺炎和 CXRs 的病例。
- 确定是否可以训练机器学习分类器来区分新冠肺炎病例的 cxr 与其他肺炎和正常病例。
- 应用众所周知的可解释性算法(LIME)来获得模型预测的解释。使用解释为特征工程和数据选择提供信息。
- 与对合作感兴趣的其他人联系以加强这项工作(我们最重要的目标)。
数据
数据集
出于本实验的目的,数据取自两个存储库:
- GitHub 上的新冠肺炎影像数据收集库正在收集越来越多的来自国际上的新冠肺炎病例的已鉴定的 cxr 和 CT 扫描。我们想借此机会感谢蒙特利尔大学的约瑟夫·保罗·寇恩和他的同事们,感谢他们在收集这个数据集方面所做的辛勤工作。样本图像见图 1a 。
- Kaggle 上提供的 RSNA 肺炎检测挑战数据集包含几个已识别的 cxr,并包括一个标签,指示图像是否显示肺炎的证据[6]。我们想借此机会感谢北美放射学会和所有其他相关实体创建了这个数据集。样本图像见图 1b 。
**图 1a(左)😗*一个来自数据集(1)的 CXR 的例子,标签为新冠肺炎。**图 1b(右)😗*取自数据集(2)的 CXR 的示例,标记为显示肺炎的证据。
在撰写本文时,第一个数据集包含 76 个新冠肺炎阳性患者的后前位(PA) CXR 图像。它还包含一些具有替代发现(如 SARS)的患者的 cxr。包含第二个数据集是为了增加可用的数据量,以提高我们的分类器的辨别能力。第二个数据集不仅包含正常的 cxr,还包含几个肺炎患者的 cxr。在从这两个数据集中仅选择PA cxr时要小心谨慎。尽管两个数据集都包含前后(AP) CXRs,我们假设包含两者可能会过度影响模型预测。正如贝尔、琼斯等人所描述的那样。艾尔。与 PA CXRs 相比,AP CXRs 的缺点包括结构外观上的差异[7]。
在训练之前,来自两个数据集的数据被合并成一个由大约 1000 幅图像组成的大数据集。我们希望在一个更大的数据集上训练,但是我们担心会产生太多的类别不平衡。数据集由一个包含文件名和相关标签的数据帧组成。然后,数据集被随机分为训练集、验证集和测试集,注意保持这些集中的类比例不变。
数据预处理
在训练之前,对图像本身进行预处理。使用 ImageDataGenerator (来自 tensorflow.keras)在训练之前执行图像批次的预处理。对图像应用了以下变换:
- 图像大小调整为以下形状:224×224×3。通过减小图像尺寸,减少了神经网络中的参数数量。
- 对图像进行阈值处理以去除任何非常亮的像素,并修补缺失的区域。这样做是为了从图像中删除尽可能多的文本注释。有人假设,特定于一个地区或机构的注释可能会破坏预测。稍后将详细介绍。
- 对图像的像素值进行了变换,使得它们的平均值为 0。
- 图像的像素值除以图像内图像像素的标准偏差。通常,通过缩放图像使其像素值在范围*【0,1】内,从而使图像标准化。*相反,我们选择根据图像的标准偏差进行重新调整,因为数据集来自不同的来源。我们不能对 RSNA 数据集说话,但蒙特利尔大学的数据集包含从几个来源拍摄的图像。
二元分类
我们首先考虑一个二元分类问题,目标是检测 X 射线是否显示新冠肺炎感染的证据。分类员将 x 光图像归入非新冠肺炎类或新冠肺炎类。深度卷积神经网络架构被训练来执行二进制分类。使用 Adam 优化器和分类交叉熵损失来训练该模型。所有的训练代码都是用 TensorFlow 2.0 编写的。
体系结构
经过无数次迭代,我们得到了一个使用剩余连接的深度卷积神经网络架构。由于新冠肺炎威胁迫在眉睫,本文发布后将进行详尽的超参数搜索。此外,网络的规模受到限制,以适应平均 GPU 硬件资源,但在扩大网络规模以利用更大的计算可用性时,指标有望得到改善。未来的工作将努力训练一个众所周知的残差网络(如 ResNet50)并利用预训练权重的迁移学习。图 2 总结了二元分类器的架构。
图 2: 二进制模型的架构概述。在该图中,残差块由两个卷积层定义,第一个卷积层的输入与第二个卷积层的输出相连,后面是最大池层。剩余的块串联连接,然后是 2 个完全连接的层。预测类§是最终层的 softmax 激活的 argmax。
防止过度配合的措施
我们应用了多种策略来应对过度拟合,如 L2 权重正则化、剔除正则化和数据扩充(训练集图像旋转多达 10 )。
阶级不平衡
由于可公开获得的严重新冠肺炎病例 cxr 的稀缺,我们被迫应用类别不平衡方法来减轻一个类别超过其他几个类别的影响。如果你精通机器学习,你就会知道,当一个类的代表性不足时,分类问题的准确率可能会高得令人误解。我们进退两难,因为我们也不想将我们的训练数据限制在只有 76 个非新冠肺炎的例子,因为总共会有大约 150 个图像。因此,当模型错误分类一个正面的例子时,我们应用类别加权来惩罚模型。类权重最初仅根据数据集中的比例进行计算。结果并不令人满意。因此,我们在项目的配置文件中为用户提供了一个选项,以便对代表不足的类进行更大的加权(除了计算出的权重之外)。这种干预将我们的精度和召回指标提高到原型的可接受值。
结果
训练实验完成后,训练指标在 TensorBoard 中可视化。参见图 3 a 关于培训和验证损失与纪元的示例。
图 3a: 二元分类器的训练(橙色)和验证(蓝色)损失与时期的关系
报告了测试装置的结果图 3b 。请注意,测试集包含不到 100 幅图像,其中只有 8 幅图像属于新冠肺炎类。图 3c 和 3 d 分别显示了混淆矩阵和 ROC 曲线。
图 3b: 二元分类器模型在测试集上的性能度量
**图 3c(左)😗*测试集上二元分类器预测的混淆矩阵。**图 3d(右)😗*二元分类器测试集预测的 ROC 曲线。
多类分类
尽管二元分类对于确定新冠肺炎 CXRs 是否具有任何可识别的模式是有信息的,但它更适用于将新冠肺炎重症病例与其他肺炎(尤其是其他病毒性肺炎)分开。我们在这里的目标是开发一个模型,可以将 CXR 图像分类为以下类别之一:正常、肺炎或新冠肺炎感染。我们重复了本文前面描述的相同的数据预处理技术。该模型架构与我们的二进制分类器非常相似,除了在末端具有 3 个节点的完全连接层(每个类一个节点)。
结果
一旦训练实验完成,训练指标就在 TensorBoard 中可视化。参见图 4a 中训练和验证损失与历元的示例。
图 4a: 多类分类器的训练(橙色)和验证(蓝色)损失与时期的关系
报告了测试集的结果图 4b 。报告了与新冠肺炎感染相对应的类别的二元指标(即精确度、召回率、F1 分数)。图 4c 和 4d 分别显示了新冠肺炎等级的混淆矩阵和 ROC 曲线。尽管该模型识别了大多数新冠肺炎病例,但是可以看出该模型的准确性明显较低。较低的整体准确性意味着多类别模型学会区分新冠肺炎类别与“正常”和“其他肺炎”类别比学会区分“正常”和“其他肺炎”类别更好。该模型的未来版本必须在训练期间找到更好的类权重平衡,以确保其他类保持独特。
图 4b: 多类分类器模型在测试集上的性能度量
**图 4c(左)😗*多类分类器关于新冠肺炎类的测试集预测的混淆矩阵。**图 4d(右)😗*二元分类器关于新冠肺炎类的测试集预测的 ROC 曲线。
可解释性
可解释性的必要性
正如本文前面提到的,这个模型必须是可解释的。深度卷积神经网络不是固有可解释的;相反,它们被认为是“黑盒”。根据一份关于放射学中人工智能伦理的国际声明,“透明度、可解释性和可解释性是建立患者和提供者信任的必要条件”[8]。临床医生不可能完全相信算法的预测,也不应该相信。通过解释为什么我们的模型预测新冠肺炎感染或缺乏感染,任何对改善该系统感兴趣的研究人员或临床医生可以理解为什么该模型做出特定的决定。目前,我们采用 LIME 算法[9]来解释模型预测。
追求可解释的机器学习模型不仅在道德上是负责任的,而且对研究人员来说,确保模型中没有数据泄漏或意外偏差也是有益的。我们很高兴我们探索了可解释性方法,因为我们注意到在我们的模型和数据科学社区中其他人的方法中有多种可能的数据泄漏来源。
石灰解释
我们使用局部可解释的模型不可知解释(即 LIME)来解释我们训练的神经网络分类器的预测[7]。我们使用了作者的 GitHub 资源库中可用的实现。LIME 扰动一个例子中的特征,并拟合一个线性模型以在该例子周围的特征空间的局部区域中逼近神经网络。然后,它使用线性模型来确定哪些特征对该示例的模型预测贡献最大。通过将 LIME 应用于我们训练过的模型,我们可以根据我们看到的任何明显无关紧要的特征或领域专家的见解进行有根据的特征工程。我们还可以判断模型是否正在学习任何非预期的偏差,并通过附加的特征工程来消除该偏差。
对于图像数据,LIME 认为特征是图像的超像素。我们使用快速移动模式搜索分割算法【10】来产生这些分割。在我们的项目中,解释在视觉上表现为 LIME 认为对原始图像预测贡献最大的超像素的叠加。绿色的超像素表示对预测类别贡献最大的区域。相反,红色的超像素表示对预测类别贡献最大的区域。
请参见图 5a 和 5b 了解测试集中两个二元分类器图像预测的时间解释的可视化表示。图 5 c、5d、5e 和 5f 显示了对测试集中图像的多类分类器预测的选择的时间解释。很明显,这个模型还有很长的路要走,因为胸腔外部的超像素继续出现在解释中。
**图 5a(左)😗*二元模型对测试集中的非新冠肺炎示例的预测的时间解释的示例。预测类匹配图像的地面真实类(即,非新冠肺炎)。有助于和不利于新冠肺炎预测的超像素分别被涂成绿色和红色。**图 5b(右)😗*二元模型对测试集中的新冠肺炎示例的预测的时间解释的示例。有助于和不利于新冠肺炎预测的超像素分别被涂成绿色和红色。
测试集中多类模型对 CXRs 预测的实例说明。对预测类有贡献的超像素和对预测类有贡献的超像素分别被着色为绿色和红色。**图 5c(左上)😗*对正常 CXR 的正确预测的简要说明。**图 5d(右上)😗*对被诊断患有新冠肺炎的患者的 CXR 的正确预测的简要说明。**图 5e(左下角)😗*对显示不同肺炎证据的 CXR 上的正确预测的简要说明。**图 5f(左上)😗*对一个正常 CXR 的错误预测的简要说明。该模型错误地将这种 CXR 归类为显示另一种肺炎的证据。
由石灰解释推动的改进
- 图像上打印的明亮字符
在训练我们的二元分类器并首次生成石灰解释后,我们注意到包含明亮文本的超像素通常突出显示为绿色,这表明它们有助于模型的预测。也许其中一个数据集比另一个数据集包含更多的特殊字符。这一发现促使我们尝试移除和修复亮度超过某一阈值的像素。在其他预处理步骤之前,如果一个像素的亮度高于 230(255 中的一个),则使用周围像素作为参考[11]对其进行修复 T12。这种方法似乎改善了解释,因为文本区域很少被突出显示。然而,这种方法对于不太明亮的文本区域效果不好。如果亮度截止阈值设置得太低,我们可能会切除 X 射线中可能存在的伪影,这将导致真正的患者信息被删除。我们邀请其他人就这个问题提出更好的解决方案。要么我们找到一种更好的方法来从图像中删除文本数据,要么我们在一个完全没有字符打印在图像上的数据集上进行训练。 - 非新冠肺炎图像
的儿科数据集的无意利用最初,我们使用保罗·穆尼的经典胸部 x 光图像数据集(可在 Kaggle 上获得)作为我们的非新冠肺炎图像集合。该数据集包含分类为正常病例、细菌性肺炎病例和病毒性肺炎病例的 X 射线。在训练二元和多类分类器之后,我们注意到图像右侧和左侧的黑柱在 LIME 解释中被频繁报告为支持非新冠肺炎 cxr 预测的重要特征。鉴于这些区域在患者体外,很明显它们不应该被一致地强调为对预测有贡献。在仔细阅读了 Kaggle 上这个数据集的描述后,我们发现它的所有 cxr 都是从 1 到 5 岁的儿科患者中获取的。这构成了数据泄漏,因为该模型可能会拾取成人与儿童 X 射线的特征。这可能解释了为什么我们最初在测试集上实现了高性能指标。这向我们强调了结合可解释的人工智能实现机器学习模型的必要性。我们注意到,在过去的 2 周内,这种利用相同儿科数据集对 cxr 进行新冠肺炎分类的方法已经在数据科学界发表了多次。我们希望这个项目可以帮助纠正这些错误的结果。
虽然 LIME 是一个优秀的可解释性算法,但在不久的将来,我们将会应用和比较其他模型不可知的可解释性算法。
结论
本文描述的项目是应用机器学习区分新冠肺炎感染重症患者和 CXR 的一种尝试。这项工作绝不是为了临床使用;这纯粹是探索性的。然而,我们希望这个项目将继续改进,并可能提供有助于新冠肺炎医学研究的见解。我们相信可解释性是产生一个帮助医疗工作者和研究人员的算法系统的关键。这个项目将继续发展,并将相应地提供更新。
与我们合作
随着新冠肺炎疫情继续将社会置于越来越大的压力之下,具有共同目标的研究人员团结起来至关重要。请将这篇文章视为对有兴趣合并或扩展这项工作的个人或组织的公开呼吁。我们已经看到类似的项目在进行中,并愿意共同努力。
对不同专业知识的需求
这个项目是由加拿大伦敦市人工智能研究和创新实验室的成员完成的。我们认识到,我们的工作会因其他人而大大加强。我们需要有不同专业知识的人来推进这个项目。特别是:
- 需要临床专家来阐明临床需求,评估模型解释,并告知未来的数据预处理方法和模型设计决策。
- 需要数据科学专业知识来提高模型性能和可解释性技术。
- 如果项目被转移到生产中,可能需要软件工程专业知识来帮助转换项目。
如果您有兴趣,请联系我们(见下面的联系信息)。
需要更多数据
缺乏公开可用的新冠肺炎阳性 cxr 是改进这种原型模型性能的严重障碍。在小于 100 PA 新冠肺炎 cxr 的情况下,训练可概括的模型是具有挑战性的。机器学习的一个基本原则是,你训练的数据越多,你的模型对看不见的数据的表现就越好。
如果您能够提供更多身份认证数据或有兴趣签署数据共享协议,请联系我们:
马特·罗斯,
人工智能经理,
信息技术服务,
城市经理办公室,
伦敦金融城公司
maross @ London . ca | 226 . 449 . 9113
查看代码
请看这个项目的 GitHub 库。我们邀请您贡献您的想法。存储库的 README.md 解释了项目的组织,并提供了如何开始的详细说明。
参考
- 长度李等,“人工智能在胸部 CT 上区分与社区获得性肺炎”,放射学,2020。可提供:10.1148/radio . 2020200905
- “新冠肺炎测试政策和指南”,lhsc.on.ca ,2020 年。【在线】。可用:https://www.lhsc.on.ca/palm/labs/covid.html#main-content.【访问日期:2020 年 3 月 27 日】。
- 加拿大放射学家协会和加拿大胸部放射学会关于影像部门新冠肺炎管理的声明。加拿大放射学家协会,2020 年。
- Y.方等,“胸部 CT 对的敏感性:与 RT-PCR 的比较”,放射学,2020。可用:https://pubs.rsna.org/doi/10.1148/radiol.2020200432.
- J.科恩,《新冠肺炎影像资料集》, GitHub ,2020 年。【在线】。可用:【https://github.com/ieee8023/covid-chestxray-dataset. 【访问时间:2020 年 3 月 17 日】。
- “RSNA 肺炎检测挑战”, Kaggle ,2020。【在线】。可用:https://www . ka ggle . com/c/rsna-肺炎-检测-挑战。【访问日期:2020 年 3 月 22 日】。
- D.贝尔和 j .琼斯,《胸片》,放射医学。【在线】。可用:https://radiopaedia.org/articles/chest-radiograph.【访问日期:2020 年 3 月 26 日】。
- 放射学中人工智能的伦理:欧洲和北美多协会声明。美国放射学院,2020 年。
- 米(meter 的缩写))里贝罗、s·辛格和 c·盖斯特林,“我为什么要相信你?”,第 22 届 ACM SIGKDD 知识发现与数据挖掘国际会议论文集— KDD '16,2016。可用:https://dl.acm.org/doi/10.1145/2939672.2939778.【2020 年 3 月 25 日获取】。
- A.Vedaldi 和 S. Soatto,“模式搜索的快速转换和核心方法”,计算机科学讲义,第 705–718 页,2008 年。可用:https://link . springer . com/chapter/10.1007% 2f 978-3-540-88693-8 _ 52。【2020 年 3 月 25 日访问】。
- 《修复》,Scikit-image.org,2020 年。【在线】。可用:https://sci kit-image . org/docs/dev/auto _ examples/filters/plot _ inpaint . html【访问时间:2020 年 3 月 25 日】。