2.5. 分解信号为组件(矩阵分解问题)#

2.5.1. 主成分分析 (PCA)#

2.5.1.1. 精确 PCA 和概率解释#

PCA 用于将多元数据集分解为一组连续的正交分量,这些分量解释了最大量的方差。在 scikit-learn 中,PCA 被实现为一个转换器对象,它在 fit 方法中学习 \(n\) 个分量,并可用于在新数据上将其投影到这些分量上。

PCA 在应用 SVD 之前会对每个特征的输入数据进行中心化处理,但不会进行缩放。可选参数 whiten=True 可以将数据投影到奇异空间,同时将每个分量缩放到单位方差。如果下游模型对信号的各向同性有很强的假设,这通常很有用:例如,对于具有 RBF 核的支持向量机和 K-Means 聚类算法就是这种情况。

以下是一个鸢尾花数据集的示例,该数据集包含 4 个特征,投影到解释最大方差的 2 个维度上。

../_images/sphx_glr_plot_pca_vs_lda_001.png

PCA 对象还提供了 PCA 的概率解释,可以根据其解释的方差量给出数据的似然度。因此,它实现了一个 score 方法,该方法可在交叉验证中使用。

../_images/sphx_glr_plot_pca_vs_fa_model_selection_001.png

示例

2.5.1.2. 增量 PCA#

PCA 对象非常有用,但对于大型数据集存在一些限制。最大的限制是 `PCA` 只支持批处理,这意味着要处理的所有数据都必须适合主内存。IncrementalPCA 对象使用一种不同的处理形式,允许进行部分计算,这些计算几乎与 `PCA` 的结果完全匹配,同时以小批量方式处理数据。`IncrementalPCA` 可以通过以下方式实现出核主成分分析:

  • 使用其 partial_fit 方法处理从本地硬盘或网络数据库顺序获取的数据块。

  • 使用 numpy.memmap 在内存映射文件上调用其 fit 方法。

IncrementalPCA 仅存储分量和噪声方差的估计,以便增量更新 `explained_variance_ratio_`。这就是为什么内存使用量取决于每个批次中的样本数量,而不是数据集中要处理的样本总数。

与 `PCA` 一样,`IncrementalPCA` 在应用 SVD 之前会对每个特征的输入数据进行中心化处理,但不会进行缩放。

../_images/sphx_glr_plot_incremental_pca_001.png
../_images/sphx_glr_plot_incremental_pca_002.png

示例

2.5.1.3. 使用随机 SVD 进行 PCA#

通常,通过丢弃与较低奇异值相关的分量奇异向量,将数据投影到保留大部分方差的低维空间中很有意义。

例如,如果我们使用 64x64 像素的灰度图像进行人脸识别,数据的维度为 4096,在如此宽的数据上训练 RBF 支持向量机速度很慢。此外,我们知道数据的内在维度远低于 4096,因为所有的人脸图像看起来都有些相似。样本位于一个维度低得多的流形上(例如,约 200)。PCA 算法可以用于线性变换数据,同时降低维度并保留大部分解释的方差。

在这种情况下,使用可选参数 `svd_solver='randomized'` 的 `PCA` 类非常有用:由于我们将丢弃大部分奇异向量,因此将计算限制在实际执行变换的奇异向量的近似估计上会更有效。

例如,下图显示了从 Olivetti 人脸数据集中提取的 16 个样本肖像(围绕 0.0 中心化)。右侧是前 16 个奇异向量,重塑为肖像。由于我们只需要一个大小为 \(n_{\mathrm{samples}} = 400\)\(n_{\mathrm{features}} = 64 \times 64 = 4096\) 的数据集的前 16 个奇异向量,因此计算时间不到 1 秒。

orig_img pca_img

如果我们记 \(n_{\max} = \max(n_{\mathrm{samples}}, n_{\mathrm{features}})\)\(n_{\min} = \min(n_{\mathrm{samples}}, n_{\mathrm{features}})\),则随机 `PCA` 的时间复杂度为 \(O(n_{\max}^2 \cdot n_{\mathrm{components}})\),而 `PCA` 中实现的精确方法的复杂度为 \(O(n_{\max}^2 \cdot n_{\min})\)

随机 `PCA` 的内存占用也与精确方法的 \(n_{\max} \cdot n_{\min}\) 成正比,而随机 `PCA` 的内存占用与 \(2 \cdot n_{\max} \cdot n_{\mathrm{components}}\) 成正比。

注意:当 `whiten=False`(默认值)时,`svd_solver='randomized'` 的 `PCA` 中的 `inverse_transform` 实现不是 `transform` 的精确逆变换。

示例

References

2.5.1.4. 稀疏主成分分析(SparsePCA 和 MiniBatchSparsePCA)#

SparsePCA 是 PCA 的一个变体,旨在提取能够最佳重建数据的稀疏分量集。

小批量稀疏 PCA(MiniBatchSparsePCA)是 `SparsePCA` 的一个变体,速度更快但精度较低。通过在给定迭代次数的情况下,遍历特征集的少量块来达到更高的速度。

主成分分析(`PCA`)的缺点是该方法提取的分量表达式完全是稠密的,即在表示为原始变量的线性组合时,它们具有非零系数。这会使解释变得困难。在许多情况下,真实的底层分量可以更自然地想象为稀疏向量;例如,在人脸识别中,分量可能自然地映射到人脸的各个部分。

稀疏主成分提供了更简洁、更易于解释的表示,清楚地强调了哪些原始特征有助于样本之间的差异。

下面的示例说明了使用稀疏 PCA 从 Olivetti 人脸数据集中提取的 16 个分量。可以看到正则化项如何引起许多零值。此外,数据的自然结构导致非零系数在垂直方向上是相邻的。模型不强制执行此数学约束:每个分量都是一个 \(\mathbf{R}^{4096}\) 中的向量 \(h\),在人类友好的 64x64 像素图像可视化期间,除了表示为 64x64 像素图像之外,没有垂直相邻的概念。下面显示的组件看起来是局部的,这是数据内在结构的效应,使得这种局部模式最小化了重建误差。存在一些考虑相邻性和不同类型结构的稀疏诱导范数;有关此类方法的审查,请参阅 [Jen09]。有关使用稀疏 PCA 的更多详细信息,请参阅下面的示例部分。

pca_img spca_img

请注意,稀疏 PCA 问题有许多不同的表述。此处实现的基于 [Mrl09] 。所解决的优化问题是一个 PCA 问题(字典学习),对分量施加了 \(\ell_1\) 惩罚。

\[\begin{split}(U^*, V^*) = \underset{U, V}{\operatorname{arg\,min\,}} & \frac{1}{2} ||X-UV||_{\text{Fro}}^2+\alpha||V||_{1,1} \\ \text{subject to } & ||U_k||_2 \leq 1 \text{ for all } 0 \leq k < n_{components}\end{split}\]

||.||_Fro 表示 Frobenius 范数,||.||_{1,1} 表示逐元素矩阵范数,即矩阵中所有元素的绝对值之和。稀疏诱导的 `||.||_{1,1}` 矩阵范数还可以防止在训练样本很少时从噪声中学习分量。通过超参数 `alpha` 可以调整惩罚的程度(以及稀疏度)。小值导致因子化得到轻微正则化,而大值则将许多系数收缩为零。

注意

虽然 `MiniBatchSparsePCA` 类具有在线算法的精神,但它没有实现 `partial_fit`,因为该算法是在特征方向上在线的,而不是在样本方向上。

示例

References

[Mrl09]

J. Mairal, F. Bach, J. Ponce, G. Sapiro(2009)的“Online Dictionary Learning for Sparse Coding”

[Jen09]

R. Jenatton, G. Obozinski, F. Bach(2009)的“Structured Sparse Principal Component Analysis”

2.5.2. 核主成分分析 (kPCA)#

2.5.2.1. 精确核 PCA#

KernelPCA 是 PCA 的扩展,它通过使用核函数(参见成对度量、亲和性和核函数)实现非线性降维 [Scholkopf1997]。它有许多应用,包括去噪、压缩和结构化预测(核依赖估计)。`KernelPCA` 支持 `transform` 和 `inverse_transform`。

../_images/sphx_glr_plot_kernel_pca_002.png

注意

KernelPCA.inverse_transform 依赖于核脊回归来学习从 PCA 基到原始特征空间的样本映射函数 [Bakir2003]。因此,使用 `KernelPCA.inverse_transform` 获得的重构是一个近似值。有关更多详细信息,请参见下面的示例链接。

示例

References

[Scholkopf1997]

Schölkopf, Bernhard, Alexander Smola, and Klaus-Robert Müller. “Kernel principal component analysis.” International conference on artificial neural networks. Springer, Berlin, Heidelberg, 1997.

[Bakir2003]

Bakır, Gökhan H., Jason Weston, and Bernhard Schölkopf. “Learning to find pre-images.” Advances in neural information processing systems 16 (2003): 449-456.

2.5.2.2. 核 PCA 的求解器选择#

虽然在 `PCA` 中,分量的数量受特征数量的限制,但在 `KernelPCA` 中,分量的数量受样本数量的限制。许多真实世界的数据集有大量的样本!在这些情况下,找到 *所有* 分量的完整 kPCA 是浪费计算时间,因为数据主要由前几个分量描述(例如,`n_components <= 100`)。换句话说,在核 PCA 拟合过程中进行特征值分解的中心化 Gram 矩阵的有效秩远小于其大小。这种情况可以使用近似特征值求解器来加速,而精度损失非常小。

特征值求解器#

当请求的 `n_components` 数量远小于样本数量时,可以使用可选参数 `eigen_solver='randomized'` 来*显著*减少计算时间。它依赖于随机分解方法,在较短的时间内找到近似解。

随机 `KernelPCA` 的时间复杂度为 \(O(n_{\mathrm{samples}}^2 \cdot n_{\mathrm{components}})\),而使用 `eigen_solver='dense'` 实现的精确方法的时间复杂度为 \(O(n_{\mathrm{samples}}^3)\)

随机 `KernelPCA` 的内存占用也与精确方法的 \(n_{\mathrm{samples}}^2\) 成正比,而随机 `KernelPCA` 的内存占用与 \(2 \cdot n_{\mathrm{samples}} \cdot n_{\mathrm{components}}\) 成正比。

注意:此技术与 使用随机 SVD 进行 PCA 中的技术相同。

除了上述两种求解器之外,还可以使用 `eigen_solver='arpack'` 作为获取近似分解的另一种方法。实际上,只有当要查找的分量数量非常少时,此方法才提供合理的执行时间。当所需分量数量严格小于 10 且样本数量严格大于 200 时,默认启用此选项。有关详细信息,请参阅 `KernelPCA`。

References

2.5.3. 截断奇异值分解和潜在语义分析#

TruncatedSVD 实现奇异值分解(SVD)的一个变体,该变体仅计算 \(k\) 个最大的奇异值,其中 \(k\) 是用户指定的参数。

TruncatedSVD 与 `PCA` 非常相似,但不同之处在于矩阵 \(X\) 不需要中心化。当从特征值中减去 \(X\) 的列(每个特征)均值时,对结果矩阵进行截断 SVD 等同于 PCA。

关于截断 SVD 和潜在语义分析 (LSA)#

当截断 SVD 应用于词-文档矩阵(由 `CountVectorizer` 或 `TfidfVectorizer` 返回)时,这种变换被称为潜在语义分析(LSA),因为它将这些矩阵转换为低维度的“语义”空间。特别是,LSA 被认为可以对抗同义词和多义词(两者大致意味着一个词有多个含义)的影响,这些影响会导致词-文档矩阵过于稀疏并表现出较低的余弦相似度等度量。

注意

LSA 也被称为潜在语义索引(LSI),尽管严格来说,这指的是它在信息检索中的持久索引中的使用。

数学上,截断 SVD 应用于训练样本 \(X\) 会产生一个低秩近似 \(X\)

\[X \approx X_k = U_k \Sigma_k V_k^\top\]

在此操作之后,\(U_k \Sigma_k\) 是经过变换的训练集,具有 \(k\) 个特征(在 API 中称为 `n_components`)。

为了变换测试集 \(X\),我们将其乘以 \(V_k\)

\[X' = X V_k\]

注意

自然语言处理(NLP)和信息检索(IR)文献中的大多数 LSA 处理都会交换矩阵 \(X\) 的轴,使其形状为 `(n_features, n_samples)`。我们以不同的方式呈现 LSA,以更好地匹配 scikit-learn API,但找到的奇异值是相同的。

虽然 `TruncatedSVD` 转换器可以处理任何特征矩阵,但在 LSA/文档处理场景中,建议在 tf-idf 矩阵上使用它,而不是原始频率计数。特别是,应启用子线性缩放和逆文档频率(`sublinear_tf=True, use_idf=True`),以使特征值更接近高斯分布,从而补偿 LSA 对文本数据的错误假设。

示例

References

2.5.4. 字典学习#

2.5.4.1. 带预计算字典的稀疏编码#

SparseCoder 对象是一个估计器,可用于将信号转换为固定、预先计算的字典(如离散小波基)的原子稀疏线性组合。因此,该对象不实现 `fit` 方法。变换相当于一个稀疏编码问题:找到一种表示数据的方法,使其成为尽可能少字典原子数的线性组合。所有字典学习的变体都实现了以下变换方法,这些方法可通过 `transform_method` 初始化参数进行控制:

阈值处理速度非常快,但不能实现精确的重建。文献已证明其在分类任务中有用。对于图像重建任务,正交匹配追踪可实现最精确、无偏的重建。

通过 `split_code` 参数,字典学习对象提供了将稀疏编码结果中的正值和负值分开的可能性。这在将字典学习用于提取将用于监督学习的特征时很有用,因为它可以让学习算法为特定原子的负载分配与相应正载不同的权重。

单个样本的拆分代码长度为 2 * n_components,并使用以下规则构建:首先,计算长度为 n_components 的常规代码。然后,`split_code` 的前 `n_components` 个条目用常规代码向量的正数部分填充。拆分代码的后半部分用代码向量的负数部分填充,但仅以正数形式。因此,`split_code` 是非负的。

示例

2.5.4.2. 通用字典学习#

字典学习(`DictionaryLearning`)是一个矩阵分解问题,旨在找到一个(通常是过度完备的)字典,该字典能很好地稀疏编码拟合的数据。

将数据表示为过度完备字典的原子稀疏组合被认为是哺乳动物初级视觉皮层的工作方式。因此,应用于图像块的字典学习在图像处理任务(如图像补全、修复和去噪)以及监督识别任务中已被证明能取得良好效果。

字典学习是一个优化问题,通过交替更新稀疏代码来解决,作为多个 Lasso 问题的解决方案,同时固定字典,然后更新字典以最好地拟合稀疏代码。

\[\begin{split}(U^*, V^*) = \underset{U, V}{\operatorname{arg\,min\,}} & \frac{1}{2} ||X-UV||_{\text{Fro}}^2+\alpha||U||_{1,1} \\ \text{subject to } & ||V_k||_2 \leq 1 \text{ for all } 0 \leq k < n_{\mathrm{atoms}}\end{split}\]

pca_img2 dict_img2

||.||_Fro 表示 Frobenius 范数,`||.||_{1,1}` 表示逐元素矩阵范数,即矩阵中所有元素的绝对值之和。在通过此过程拟合字典后,变换只是一个稀疏编码步骤,它与所有字典学习对象共享相同的实现(参见带预计算字典的稀疏编码)。

还可以约束字典和/或代码为正数,以匹配数据中可能存在的约束。以下是应用了不同正约束的人脸。红色表示负值,蓝色表示正值,白色表示零。

dict_img_pos1 dict_img_pos2

dict_img_pos3 dict_img_pos4

References

2.5.4.3. 小批量字典学习#

MiniBatchDictionaryLearning 实现了一个更快但精度较低的字典学习算法版本,更适合大型数据集。

默认情况下,`MiniBatchDictionaryLearning` 将数据分成小批量,并通过在指定迭代次数下循环遍历小批量来以在线方式优化 NMF 模型。然而,目前它没有实现停止条件。

该估计器还实现了 `partial_fit`,它通过仅一次遍历一个小批量来更新字典。当数据一开始不易获得,或者数据不适合内存时,可以将其用于在线学习。

../_images/sphx_glr_plot_dict_face_patches_001.png

下图显示了从浣熊脸图像的一部分提取的 4x4 像素图像块中学习到的字典的外观。

../_images/sphx_glr_plot_image_denoising_001.png

示例

2.5.5. 因子分析#

在无监督学习中,我们只有一个数据集 \(X = \{x_1, x_2, \dots, x_n \}\)。这个数据集在数学上如何描述?一个非常简单的 连续 潜在 变量 模型 \(X\)

\[x_i = W h_i + \mu + \epsilon\]

向量 \(h_i\) 称为“潜在”是因为它未被观察到。 \(\epsilon\) 被认为是噪声项,其分布为均值为 0、协方差为 \(\Psi\)(即 \(\epsilon \sim \mathcal{N}(0, \Psi)\))的高斯分布,\(\mu\) 是某个任意的偏移向量。这样的模型称为“生成”模型,因为它描述了 \(x_i\) 如何从 \(h_i\) 生成。如果我们使用所有 \(x_i\) 作为列形成矩阵 \(\mathbf{X}\),并将所有 \(h_i\) 作为列形成矩阵 \(\mathbf{H}\),则可以写出(在适当定义 \(\mathbf{M}\)\(\mathbf{E}\) 的情况下)

\[\mathbf{X} = W \mathbf{H} + \mathbf{M} + \mathbf{E}\]

换句话说,我们分解了矩阵 \(\mathbf{X}\)

如果 \(h_i\) 给定,则上述方程自动暗示以下概率解释

\[p(x_i|h_i) = \mathcal{N}(Wh_i + \mu, \Psi)\]

对于完整的概率模型,我们还需要潜在变量 \(h\) 的先验分布。最直接的假设(基于高斯分布的良好性质)是 \(h \sim \mathcal{N}(0, \mathbf{I})\)。这产生了高斯作为 \(x\) 的边缘分布

\[p(x) = \mathcal{N}(\mu, WW^T + \Psi)\]

现在,在没有任何进一步假设的情况下,拥有潜在变量 \(h\) 的想法是多余的——\(x\) 可以完全由均值和协方差来建模。我们需要对这两个参数中的一个施加更具体的结构。一个简单的附加假设是关于误差协方差 \(\Psi\) 的结构

  • \(\Psi = \sigma^2 \mathbf{I}\):这个假设导致了 `PCA` 的概率模型。

  • \(\Psi = \mathrm{diag}(\psi_1, \psi_2, \dots, \psi_n)\):这个模型称为 `FactorAnalysis`,一个经典的统计模型。矩阵 W 有时被称为“因子载荷矩阵”。

这两种模型本质上都估计一个具有低秩协方差矩阵的高斯分布。因为这两种模型都是概率性的,所以它们可以集成到更复杂的模型中,例如,因子分析混合模型。如果对潜在变量假设非高斯先验,则会得到非常不同的模型(例如,`FastICA`)。

因子分析*可以*产生与 `PCA` 相似的分量(其载荷矩阵的列)。但是,不能对这些分量做出任何一般性陈述(例如,它们是否正交)。

pca_img3 fa_img3

与 `PCA` 相比,因子分析的主要优点在于它可以独立地对输入空间中每个方向的方差进行建模(异方差噪声)。

../_images/sphx_glr_plot_faces_decomposition_009.png

这允许在存在异方差噪声的情况下进行比概率 PCA 更好的模型选择。

../_images/sphx_glr_plot_pca_vs_fa_model_selection_002.png

因子分析通常后面会跟着一个因子旋转(使用 `rotation` 参数),通常是为了提高可解释性。例如,Varimax 旋转最大化载荷平方和的方差,即,它倾向于产生更稀疏的因子,每个因子只受少数几个特征的影响(“简单结构”)。例如,参见第一个示例。.

示例

2.5.6. 独立成分分析 (ICA)#

独立成分分析将多变量信号分离成加性子分量,这些子分量具有最大的独立性。它在 scikit-learn 中使用 `Fast ICA` 算法实现。通常,ICA 不用于降维,而是用于分离叠加信号。由于 ICA 模型不包含噪声项,因此为了使模型正确,必须应用白化。这可以通过内部使用 `whiten` 参数或手动使用 PCA 变体之一来完成。

它通常用于分离混合信号(一个称为盲源分离的问题),如下面的示例所示。

../_images/sphx_glr_plot_ica_blind_source_separation_001.png

ICA 还可以用作一种非线性分解,用于查找具有一定稀疏性的分量。

pca_img4 ica_img4

示例

2.5.7. 非负矩阵分解 (NMF 或 NNMF)#

2.5.7.1. 带 Frobenius 范数的 NMF#

NMF [1] 是一种替代的分解方法,它假定数据和分量是非负的。当数据矩阵不包含负值时,`NMF` 可以代替 `PCA` 或其变体使用。它通过优化样本 \(X\) 与矩阵乘积 \(WH\) 之间的距离 \(d\) 来找到非负元素组成的两个矩阵 \(W\)\(H\) 的分解。最常用的距离函数是平方 Frobenius 范数,它是欧几里得范数到矩阵的明显扩展。

\[d_{\mathrm{Fro}}(X, Y) = \frac{1}{2} ||X - Y||_{\mathrm{Fro}}^2 = \frac{1}{2} \sum_{i,j} (X_{ij} - {Y}_{ij})^2\]

与 `PCA` 不同,向量的表示是通过叠加分量以加性方式获得的,而没有减法。这种加性模型在表示图像和文本方面非常有效。

[Hoyer, 2004] [2] 中的观察表明,当仔细约束时,`NMF` 可以产生数据集的基于部分(parts-based)的表示,从而产生可解释的模型。下面的示例显示了 `NMF` 从 Olivetti 人脸数据集中的图像找到的 16 个稀疏分量,并与 PCA 的特征脸进行了比较。

pca_img5 nmf_img5

`init` 属性决定了所应用的初始化方法,这对方法的性能有很大影响。`NMF` 实现了一种称为非负双奇异值分解(Nonnegative Double Singular Value Decomposition)的方法。NNDSVD [4] 基于两个 SVD 过程,一个近似数据矩阵,另一个利用单位秩矩阵的代数性质近似部分 SVD 因子中的正数部分。基本的 NNDSVD 算法更适合稀疏分解。其变体 NNDSVDa(其中所有零值都设置为等于数据所有元素的均值)和 NNDSVDar(其中零值设置为小于数据均值除以 100 的随机扰动)在稠密情况下被推荐。

请注意,乘法更新 ('mu') 求解器无法更新初始化中的零值,因此当与引入大量零值的基本 NNDSVD 算法一起使用时,它会导致较差的结果;在这种情况下,应优先选择 NNDSVDa 或 NNDSVDar。

`NMF` 也可以通过设置 `init="random"` 来用正确缩放的随机非负矩阵进行初始化。还可以将整数种子或 `RandomState` 传递给 `random_state` 以控制可重现性。

在 `NMF` 中,可以向损失函数添加 L1 和 L2 先验以正则化模型。L2 先验使用 Frobenius 范数,而 L1 先验使用逐元素 L1 范数。与 `ElasticNet` 一样,我们通过 `l1_ratio`(\(\rho\))参数控制 L1 和 L2 的组合,并通过 `alpha_W` 和 `alpha_H`(\(\alpha_W\)\(\alpha_H\))参数控制正则化的强度。先验按样本数(\(n\_samples\))乘以 \(H\),按特征数(\(n\_features\))乘以 \(W\),以保持其影响相互之间以及与数据拟合项的平衡,使其尽可能独立于训练集的大小。然后,先验项为

\[(\alpha_W \rho ||W||_1 + \frac{\alpha_W(1-\rho)}{2} ||W||_{\mathrm{Fro}} ^ 2) * n\_features + (\alpha_H \rho ||H||_1 + \frac{\alpha_H(1-\rho)}{2} ||H||_{\mathrm{Fro}} ^ 2) * n\_samples\]

则正则化目标函数为

\[d_{\mathrm{Fro}}(X, WH) + (\alpha_W \rho ||W||_1 + \frac{\alpha_W(1-\rho)}{2} ||W||_{\mathrm{Fro}} ^ 2) * n\_features + (\alpha_H \rho ||H||_1 + \frac{\alpha_H(1-\rho)}{2} ||H||_{\mathrm{Fro}} ^ 2) * n\_samples\]

2.5.7.2. 带 beta 散度的 NMF#

如前所述,最常用的距离函数是平方 Frobenius 范数,它是欧几里得范数到矩阵的明显扩展。

\[d_{\mathrm{Fro}}(X, Y) = \frac{1}{2} ||X - Y||_{Fro}^2 = \frac{1}{2} \sum_{i,j} (X_{ij} - {Y}_{ij})^2\]

NMF 中可以使用其他距离函数,例如(广义)Kullback-Leibler(KL)散度,也称为 I-散度。

\[d_{KL}(X, Y) = \sum_{i,j} (X_{ij} \log(\frac{X_{ij}}{Y_{ij}}) - X_{ij} + Y_{ij})\]

或 Itakura-Saito (IS) 散度。

\[d_{IS}(X, Y) = \sum_{i,j} (\frac{X_{ij}}{Y_{ij}} - \log(\frac{X_{ij}}{Y_{ij}}) - 1)\]

这三个距离是 beta 散度族 \(\beta = 2, 1, 0\) 的特例,分别对应 \(\beta = 2, 1, 0\) [6]。beta 散度定义为:

\[d_{\beta}(X, Y) = \sum_{i,j} \frac{1}{\beta(\beta - 1)}(X_{ij}^\beta + (\beta-1)Y_{ij}^\beta - \beta X_{ij} Y_{ij}^{\beta - 1})\]
../_images/beta_divergence.png

注意,此定义在 \(\beta \in (0; 1)\) 时无效,但可以连续扩展到 \(d_{KL}\)\(d_{IS}\) 的定义。

NMF 实现的求解器#

`NMF` 使用坐标下降 ('cd') [5] 和乘法更新 ('mu') [6] 实现了两种求解器。'mu' 求解器可以优化所有 beta 散度,包括 Frobenius 范数(\(\beta=2\))、(广义)Kullback-Leibler 散度(\(\beta=1\))和 Itakura-Saito 散度(\(\beta=0\))。请注意,对于 \(\beta \in (1; 2)\),'mu' 求解器的速度比其他 beta 值快得多。还请注意,当 beta 为负数(或 0,即 'itakura-saito')时,输入矩阵不能包含零值。

'cd' 求解器只能优化 Frobenius 范数。由于 NMF 的潜在非凸性,不同的求解器可能会收敛到不同的局部最小值,即使在优化相同的距离函数时也是如此。

NMF 最适合与 `fit_transform` 方法一起使用,该方法返回矩阵 W。矩阵 H 存储在拟合模型中的 `components_` 属性中;`transform` 方法将根据这些存储的分量分解新矩阵 X_new。

>>> import numpy as np
>>> X = np.array([[1, 1], [2, 1], [3, 1.2], [4, 1], [5, 0.8], [6, 1]])
>>> from sklearn.decomposition import NMF
>>> model = NMF(n_components=2, init='random', random_state=0)
>>> W = model.fit_transform(X)
>>> H = model.components_
>>> X_new = np.array([[1, 0], [1, 6.1], [1, 0], [1, 4], [3.2, 1], [0, 4]])
>>> W_new = model.transform(X_new)

示例

2.5.7.3. 小批量非负矩阵分解#

MiniBatchNMF [7] 实现了一个更快但精度较低的非负矩阵分解(即 `NMF`)版本,更适合大型数据集。

默认情况下,`MiniBatchNMF` 将数据分成小批量,并通过在指定迭代次数下循环遍历小批量来以在线方式优化 NMF 模型。`batch_size` 参数控制批次的大小。

为了加速小批量算法,还可以对过去的批次进行缩放,使其重要性低于较新的批次。这是通过引入一个由 `forget_factor` 参数控制的遗忘因子来实现的。

该估计器还实现了 `partial_fit`,它通过仅一次遍历一个小批量来更新 `H`。当数据一开始不易获得,或者数据不适合内存时,可以将其用于在线学习。

References

2.5.8. 潜在狄利克雷分配 (LDA)#

潜在狄利克雷分配是离散数据集(如文本语料库)的生成概率模型。它也是一种主题模型,用于从文档集合中发现抽象主题。

LDA 的图形模型是一个三层生成模型。

../_images/lda_model_graph.png

上面图形模型中表示的符号说明(可以在 Hoffman 等人(2013)中找到)

  • 语料库是 \(D\) 个文档的集合。

  • 文档 \(d \in D\)\(N_d\) 个词的序列。

  • 语料库中有 \(K\) 个主题。

  • 方框表示重复采样。

在图形模型中,每个节点都是一个随机变量,并在生成过程中起作用。阴影节点表示观察到的变量,未着色节点表示隐藏(潜在)变量。在这种情况下,语料库中的词是我们唯一观察到的数据。潜在变量决定了语料库中主题的随机混合以及文档中词的分布。LDA 的目标是利用观察到的词来推断隐藏的主题结构。

关于文本语料库建模的细节#

在对文本语料库进行建模时,该模型假设以下生成过程,语料库包含 \(D\) 个文档和 \(K\) 个主题,其中 \(K\) 对应于 API 中的 `n_components`:

  1. 对于每个主题 \(k \in K\),抽取 \(\beta_k \sim \mathrm{Dirichlet}(\eta)\)。这提供了词的分布,即词出现在主题 \(k\) 中的概率。 \(\eta\) 对应于 `topic_word_prior`。

  2. 对于每个文档 \(d \in D\),抽取主题比例 \(\theta_d \sim \mathrm{Dirichlet}(\alpha)\)\(\alpha\) 对应于 `doc_topic_prior`。

  3. 对于文档 \(d\) 中的每个词 \(n=1,\cdots,N_d\)

    1. 抽取主题分配 \(z_{dn} \sim \mathrm{Multinomial} (\theta_d)\)

    2. 抽取观察到的词 \(w_{dn} \sim \mathrm{Multinomial} (\beta_{z_{dn}})\)

对于参数估计,后验分布为:

\[p(z, \theta, \beta |w, \alpha, \eta) = \frac{p(w,z,\theta,\beta|\alpha, \eta)}{p(w|\alpha, \eta)}\]

由于后验分布是难以处理的,变分贝叶斯方法使用一个更简单的分布 \(q(z,\theta,\beta | \lambda, \phi, \gamma)\) 来近似它,并且这些变分参数 \(\lambda\)\(\phi\)\(\gamma\) 被优化以最大化证据下界(ELBO)。

\[\log\: P(w | \alpha, \eta) \geq L(w,\phi,\gamma,\lambda) \overset{\triangle}{=} E_{q}[\log\:p(w,z,\theta,\beta|\alpha,\eta)] - E_{q}[\log\:q(z, \theta, \beta)]\]

最大化 ELBO 等同于最小化 \(q(z,\theta,\beta)\) 和真实后验 \(p(z, \theta, \beta |w, \alpha, \eta)\) 之间的 Kullback-Leibler (KL) 散度。

LatentDirichletAllocation 实现在线变分贝叶斯算法,并支持在线和批量更新方法。虽然批量方法在遍历完数据后更新变分变量,但在线方法从迷你批量数据点更新变分变量。

注意

虽然在线方法保证收敛到局部最优,但最优点的质量和收敛速度可能取决于迷你批量大小和与学习率设置相关的属性。

LatentDirichletAllocation 应用于“文档-词项”矩阵时,该矩阵将被分解为“主题-词项”矩阵和“文档-主题”矩阵。“主题-词项”矩阵存储在模型的 components_ 中,而“文档-主题”矩阵可以从 transform 方法计算得出。

LatentDirichletAllocation 还实现了 partial_fit 方法。当数据可以按顺序获取时,此方法很有用。

示例

References

另请参阅 邻域组件分析 (NCA) 降维,用于使用邻域组件分析进行降维。