首页后端开发Python如何理解可视化利器t

如何理解可视化利器t

时间2023-06-02 11:45:01发布访客分类Python浏览564
导读:如何理解可视化利器t?T 分布随机近邻嵌入(T-Distribution Stochastic Neighbour Embedding)是一种用于降维的机器学习方法,它能帮我们识别相关连的模式。t-SNE 主要的优势就是保持局部结构的能力。...

如何理解可视化利器t?

T 分布随机近邻嵌入(T-Distribution Stochastic Neighbour Embedding)是一种用于降维的机器学习方法,它能帮我们识别相关连的模式。t-SNE 主要的优势就是保持局部结构的能力。这意味着高维数据空间中距离相近的点投影到低维中仍然相近。t-SNE 同样能生成漂亮的可视化。

当构建一个预测模型时,第一步一般都需要理解数据。虽然搜索原始数据并计算一些基本的统计学数字特征有助于理解,但没有什么是可以和图表可视化展示更直观的。然而将高维数据拟合到一张简单的图表(降维)通常是非常困难的,这就正是 t-SNE 发挥作用的地方。

在本文中,我们将探讨 t-SNE 的原理,以及 t-SNE 将如何有助于我们可视化数据。

t-SNE 算法概念

这篇文章主要是介绍如何使用 t-SNE 进行可视化。虽然我们可以跳过这一章节而生成出漂亮的可视化,但我们还是需要讨论 t-SNE 算法的基本原理。

t-SNE 算法对每个数据点近邻的分布进行建模,其中近邻是指相互靠近数据点的集合。在原始高维空间中,我们将高维空间建模为高斯分布,而在二维输出空间中,我们可以将其建模为 t 分布。该过程的目标是找到将高维空间映射到二维空间的变换,并且最小化所有点在这两个分布之间的差距。与高斯分布相比 t 分布有较长的尾部,这有助于数据点在二维空间中更均匀地分布。

控制拟合的主要参数为困惑度(Perplexity)。困惑度大致等价于在匹配每个点的原始和拟合分布时考虑的最近邻数,较低的困惑度意味着我们在匹配原分布并拟合每一个数据点到目标分布时只考虑最近的几个最近邻,而较高的困惑度意味着拥有较大的「全局观」。

因为分布是基于距离的,所以所有的数据必须是数值型。我们应该将类别变量通过二值编码或相似的方法转化为数值型变量,并且归一化数据也是也十分有效,因为归一化数据后就不会出现变量的取值范围相差过大。

T 分布随机近邻嵌入算法(t-SNE)

http://www.jmlr.org/papers/volume9/vandermaaten08a/vandermaaten08a.pdf

Jake Hoare 的博客并没有详细解释 t-SNE 的具体原理和推导过程,因此下面我们将基于 Geoffrey Hinton 在 2008 年提出的论文详细介绍 t-SNE 算法。如果读者对这一章节不感兴趣,也可以直接阅读下一章节 Jake Hoare 在实践中使用 t-SNE 进行数据可视化。

https://nlml.github.io/in-raw-numpy/in-raw-numpy-t-sne/

因为 t_SNE 是基于随机近邻嵌入而实现的,所以首先我们需要理解随机近邻嵌入算法。

随机近邻嵌入(SNE)

假设我们有数据集 X,它共有 N 个数据点。每一个数据点 x_i 的维度为 D,我们希望降低为 d 维。在一般用于可视化的条件下,d 的取值为 2,即在平面上表示出所有数据。

SNE 通过将数据点间的欧几里德距离转化为条件概率而表征相似性(下文用 p_j|i 表示):

如果以数据点在 x_i 为中心的高斯分布所占的概率密度为标准选择近邻,那么 p_j|i 就代表 x_i 将选择 x_j 作为它的近邻。对于相近的数据点,条件概率 p_j|i 是相对较高的,然而对于分离的数据点,p_j|i 几乎是无穷小量(若高斯分布的方差σ_i 选择合理)。

其中σ_i 是以数据点 x_i 为均值的高斯分布标准差,决定σ_i 值的方法将在本章后一部分讨论。因为我们只对成对相似性的建模感兴趣,所以可以令 p_i|i 的值为零。

现在引入矩阵 Y,Y 是 N*2 阶矩阵,即输入矩阵 X 的 2 维表征。基于矩阵 Y,我们可以构建一个分布 q,其形式与 p 类似。

对于高维数据点 x_i 和 x_j 在低维空间中的映射点 y_i 和 y_j,计算一个相似的条件概率 q_j|i 是可以实现的。我们将计算条件概率 q_i|j 中用到的高斯分布的方差设置为 1/2。因此我们可以对映射的低维数据点 y_j 和 y_i 之间的相似度进行建模:

我们的总体目标是选择 Y 中的一个数据点,然后其令条件概率分布 q 近似于 p。这一步可以通过最小化两个分布之间的 KL 散度(损失函数)而实现,这一过程可以定义为:

因为我们希望能最小化该损失函数,所以我们可以使用梯度下降进行迭代更新,我们可能对如何迭代感兴趣,但我们会在后文讨论与实现。

使用 NumPy 构建欧几里德距离矩阵

计算 p_i|j 和 q_i|j 的公式都存在负的欧几里德距离平方,即-||x_i - x_j||^2,下面可以使用代码实现这一部分:

为了更高的计算效率,该函数使用矩阵运算的方式定义,该函数将返回一个 N 阶方阵,其中第 i 行第 j 列个元素为输入点 x_i 和 x_j 之间的负欧几里德距离平方。

使用过神经网络的读者可能熟悉 exp(⋅)/∑exp(⋅) 这样的表达形式,它是一种 softmax 函数,所以我们定义一个 softmax 函数:

注意我们需要考虑 p_i|i=0 这个条件,所以我们可以替换指数负距离矩阵的对角元素为 0,即使用 np.fill_diagonal(e_x, 0.) 方法将 e_x 的对角线填充为 0。

将这两个函数放在一起后,我们能构建一个函数给出矩阵 P,且元素 P(i,j) 为上式定义的 p_i|j:

感到困惑?

在上面的代码段中,Sigmas 参数必须是长度为 N 的向量,且包含了每一个σ_i 的值,那么我们如何取得这些σ_i 呢?这就是困惑度(perplexity)在 SNE 中的作用。条件概率矩阵 P 任意行的困惑度可以定义为:

其中 H(P_i) 为 P_i 的香农熵,即表达式如下:

在 SNE 和 t-SNE 中,困惑度是我们设置的参数(通常为 5 到 50 间)。我们可以为矩阵 P 的每行设置一个σ_i,而该行的困惑度就等于我们设置的这个参数。直观来说,如果概率分布的熵较大,那么其分布的形状就像对平坦,该分布中每个元素的概率就更相近一些。

困惑度随着熵增而变大,因此如果我们希望有更高的困惑度,那么所有的 p_j|i(对于给定的 i)就会彼此更相近一些。换而言之,如果我们希望概率分布 P_i 更加平坦,那么我们就可以增大σ_i。我们配置的σ_i 越大,概率分布中所有元素的出现概率就越接近于 1/N。

所以如果我们希望有更高的困惑度,将σ_i 增大将使条件概率分布变得更加平坦。实际上这增加了每个点的近邻数,这就是为什么我们常将困惑度参数大致等同于所需要的近邻数量。

搜索σ_i

为了确保矩阵 P 每一行的困惑度 Perp(P_i) 就等于我们所希望的值,我们可以简单简单地执行一个二元搜索以确定σ_i 能得到我们所希望的困惑度。这一搜索十分简单,因为困惑度 Perp(P_i) 是随σ_i 增加而递增的函数,下面是基本的二元搜索函数:

为了找到期望的σ_i,我们需要将 eval_fn 传递到 binary_search 函数,并且将σ_i 作为它的参数而返回 P_i 的困惑度。

以下的 find_optimal_sigmas 函数确实是这样做的以搜索所有的σ_i,该函数需要采用负欧几里德距离矩阵和目标困惑度作为输入。距离矩阵的每一行对所有可能的σ_i 都会执行一个二元搜索以找到能产生目标困惑度的最优σ。该函数最后将返回包含所有最优σ_i 的 NumPy 向量。

对称 SNE

现在估计 SNE 的所有条件都已经声明了,我们能通过降低成本 C 对 Y 的梯度而收敛到一个良好的二维表征 Y。因为 SNE 的梯度实现起来比较难,所以我们可以使用对称 SNE,对称 SNE 是 t-SNE 论文中一种替代方法。

在对称 SNE 中,我们最小化 p_ij 和 q_ij 的联合概率分布与 p_i|j 和 q_i|j 的条件概率之间的 KL 散度,我们定义的联合概率分布 q_ij 为:

该表达式就如同我们前面定义的 softmax 函数,只不过分母中的求和是对整个矩阵进行的,而不是当前的行。为了避免涉及到 x 点的异常值,我们不是您 p_ij 服从相似的分布,而是简单地令 p_ij=(p_i|j+p_j|i)/2N。

我们可以简单地编写这些联合概率分布 q 和 p:

同样可以定义 p_joint 函数输入数据矩阵 X 并返回联合概率 P 的矩阵,此外我们还能一同估计要求的σ_i 和条件概率矩阵:

所以现在已经定义了联合概率分布 p 与 q,若我们计算了这两个联合分布,那么我们能使用以下梯度更新低维表征 Y 的第 i 行:

在 Python 中,我们能使用以下函数估计梯度,即给定联合概率矩阵 P、Q 和当前低维表征 Y 估计梯度:

为了向量化变量,np.expand_dims 方法将十分有用,该函数最后返回的 grad 为 N*2 阶矩阵,其中第 i 行为 dC/dy_i。一旦我们计算完梯度,那么我们就能利用它执行梯度下降,即通过梯度下降迭代式更新 y_i。

我们对 t-SNE 的符号定义为:X 是原来的数据;P 是一个矩阵,显示了高维(原来的)空间中 X 中的点之间的亲和度(affinities,约等于距离);Q 也是一个矩阵,显示了低维空间中数据点之间的亲和度。如果你有 n 个数据样本,那么 Q 和 P 都是 n×n 的矩阵(从任意点到任意点的距离包含自身)。

现在 t-SNE 有自己的「独特的」测量事物之间距离的方式(我们下面就会介绍)、一种测量高维空间中数据点之间的距离的方式、一种测量低维空间中数据点之间的距离的方式以及一种测量 P 和 Q 之间的距离的方式。

根据原始论文,一个数据点 x_j 与另一个点 x_i 之间的相似度是 p_j|i,其定义为:「x_i 选取 x_j 为其近邻点(neighbor),而近邻点的选取与以 x_i 为中心的高斯分布概率密度成正比。」

「这是什么意思!」不要担心,我前面说了,t-SNE 有自己测量距离的独特方式,所以让我们看看用于测量距离(亲和度)的公式,然后从中取出我们理解 t-SNE 的行为所需的见解。

从高层面来讲,这就是算法的工作方式(注意和 PCA 不一样,这是一个迭代式的算法)。

图 3:t-SNE 工作流程

让我们一步步地研究一下这个流程。

这个算法有两个输入,一个是数据本身,另一个被称为困惑度(Perp)。

简单来说,困惑度(perplexity)是指在优化过程中数据的局部(封闭点)和全局结构的焦点的平衡程度——本文建议将其保持在 5 到 50 之间。

更高的困惑度意味着一个数据点会把更多的数据点看作是其紧密的近邻点,更低的困惑度就更少。

困惑度会实际影响可视化的结果,而且你需要小心应对,因为它可能会在可视化低维数据时出现误导现象——我强烈推荐阅读这篇文章了解如何使用 t-SNE 困惑度:http://distill.pub/2016/misread-tsne,其中介绍了不同困惑度的影响。

这种困惑度从何而来?它被用于求解式子 (1) 中的 σ_i,而且因为它们有单调的连接,所以可以通过二元搜索(binary search)找到。

所以使用我们提供给算法的困惑度,我们基本上会找到不同的 σ_i。

让我们看看公式为我们提供了哪些关于 t-SNE 的信息。

在我们探索公式 (1) 和 (2) 之前,需要知道 p_ii 和 q_ii 被设置为 0(即使我们将它们应用到两个相似的点上,公式的输出也不会是 0,这只是给定的值)。

所以看看公式 (1) 和 (2),我希望你注意到,当两个点很接近时(在高维表征中),分子的值大约为 1,而如果它们相距非常远,那么我们会接近无穷小——这将有助于我们后面理解成本函数。

现在我们可以了解关于 t-SNE 的一些事情了。

一是因为亲和度公式的构建方式,在 t-SNE 图中解读距离可能会出问题。

这意味着聚类之间的距离和聚类大小可能被误导,并且也会受到所选择的困惑度的影响(在上面我推荐的文章中,你可以看到这些现象的可视化)。

第二件要注意的事情是,怎么在等式 (1) 中我们基本上计算的是点之间的欧几里得距离?这方面 t-SNE 很强大,我们可以用任何我们喜欢的距离测量来取代它,比如余弦距离、Manhattan 距离,也可以使用任何你想用的测量方法(只要其保持空间度量(space metric),而且保持低维亲和度一样)——以欧几里得的方式会得到复杂的距离绘图。

比如说,如果你是一位 CTO,你有一些数据需要根据余弦相似度测量距离,而你的 CEO 想要你通过图表的形式呈现这些数据。我不确定你是否有时间向董事会解释什么是余弦相似度以及解读聚类的方式,你可以直接绘制余弦相似度聚类,因为欧几里得距离聚类使用 t-SNE——要我说,这确实很酷。

在代码中,你可以在 scikit-learn 中通过向 TSNE 方法提供一个距离矩阵来实现。

现在,我们知道当 x_i 和 x_j 更近时,p_ij/q_ij 的值更大;相反则该值更小。

让我们看看这会对我们的成本函数(被称为 KL 散度(Kullback–Leibler divergence))带来怎样的影响。让我们绘图,然后看看没有求和部分的公式 (3)。

图 4:没有求和部分的 t-SNE 成本函数

很难看明白这是啥?但我在上面给轴加了名字。

如你所见,这个成本函数是不对称的。

对于高维空间中临近的点,其得出了非常高的成本(p 轴),但这些点是低维空间中很远的点表示的;而在高维空间中远离的点则成本更低,它们则是用低维空间中临近的点表示的。

这说明在 t-SNE 图中,距离解释能力的问题甚至还更多。

t-SNE 可视化

我们将要使用的第一个数据集是基于物理特征分类的 10 种不同叶片。这种情况下,t-SNE 需要使用 14 个数值变量作为输入,其中就包括叶片的生长率和长宽比等。下图展示了 2 维可视化输出,植物的种类(标签)使用不同的颜色表达。

物种 Acer palmatum 的数据点在右上角形成了一个橙色集群,这表明它的叶子和其他物种有很大的不同。该示例中类别通常会有很好的分组,相同物种的叶子(同一颜色的数据点)趋向于彼此靠紧聚集在一起。左下角有两种颜色的数据点靠近在一起,说明这两个物种的叶子形状十分相似。

最近邻准确度表明给定两个随机点,它们是相同物种的概率是多少。如果这些数据点完美地根据不同物种而分类,那么准确度就会非常接近 100%,高准确度意味着数据能被干净地分为不同的集群。

困惑度

下面,我们对可乐品牌做了类似的分析。为了演示困惑度(perplexity)的影响,我们首先需要将困惑度设置为较低的值 2,每个数据点的映射只考虑最近邻。如下,我们将看到许多离散的小集群,并且每一个集群只有少量的数据点。

下面我们将 t-SNE 的困惑度设置为 100,我们可以看到数据点变得更加扩散,并且同一类之间的联系变弱。

在该案例中,可乐本身就要比树叶更难分割,即使一类数据点某个品牌要更集中一些,但仍然没有明确的边界。

在实践中,困惑度并没以一个绝对的标准,不过一般选择 5 到 50 之间会有比较好的结果。并且在这个范围内,t-SNE 一般是比较鲁棒的。

预测的解释

度量数据点之间的角度或距离并不能推断出任何数据上的具体或定量的信息,所以 t-SNE 的预测更多的是用于可视化数据。

在模型搭建前期直观地挖掘数据模式有助于指导数据科学下一步进程。如果 t-SNE 能很好地分割数据点,那么机器学习同样也能找到一种将未知新数据投影到相应类别的好方法。给定一种预测算法,我们就能实现很难搞的准确度。

上例中每一个类别都是孤立分类的,因此简单的机器学习模型就能将该类别与其他类别分离开。但如果类别重叠,我们可能就要构建更精细的模型做出预测。如下所示,如果我们按照某个品牌的偏好从 1 到 5 进行分类,那么类别可能更加离散、更难以预测,最近邻精度也会相对较低。

对比 PCA

很自然我们就希望将 t-SNE 和其他降维算法做比较。降维算法中比较流行的是主成分分析法(PCA),PCA 会寻找能尽可能保留数据方差的新维度。有较大的方差的数据保留的信息就越多,因为彼此不同的数据可以提供不同的信息,所以我们最好是保留彼此分离的数据点,因为它们提供了较大的方差。

下面是采用 PCA 算法对上文的树叶类别进行降维的结果,我们看到虽然左侧的橙色是分离的,但其它类别都有点混合在一起。这是因为 PCA 并不关心局部的最近邻关系,此外 PCA 是一种线性方法,所以它表征非线性关系可能效果并不是很好。不过 PCA 算法在压缩数据为更小的特征向量而投入到预测算法中有很好地表现,这一点它要比 t-SNE 效果更好。

结语

t-SNE 是一种可视化高维数据的优秀算法,它经常要比其它降维算法生成更具特点的可视化结果。

声明:本文内容由网友自发贡献,本站不承担相应法律责任。对本内容有异议或投诉,请联系2913721942#qq.com核实处理,我们将尽快回复您,谢谢合作!


若转载请注明出处: 如何理解可视化利器t
本文地址: https://pptw.com/jishu/58160.html
r语言和python有必要都学吗 python适合在什么城市工作

游客 回复需填写必要信息