文章目录
sklearn.decomposition
主成分分析 (PCA)
精确的 PCA 和概率解释
PCA 用于将多变量数据集分解为一组解释最大方差的连续正交分量。在 scikit-learn 中,PCA
被实现为一个 转换器 对象,它在其 fit
方法中学习
n
n
n 个分量,并可以用于新数据在这些分量上的投影。
PCA 在应用 SVD 之前会对每个特征的输入数据进行中心化,但不进行缩放。可选参数 whiten=True
可以在将数据投影到奇异空间时,对每个分量进行单位方差的缩放。如果下游模型对信号的各向同性有强烈的假设,这通常是很有用的:例如,对于使用 RBF 核的支持向量机和 K-Means 聚类算法。
下面是鸢尾花数据集的示例,该数据集由 4 个特征组成,投影到解释最大方差的 2 个维度上:
PCA
对象还提供了 PCA 的概率解释,可以根据其解释的方差量给出数据的似然度。因此,它实现了一个 score
方法,可以在交叉验证中使用:
示例:
sphx_glr_auto_examples_decomposition_plot_pca_iris.py
sphx_glr_auto_examples_decomposition_plot_pca_vs_lda.py
sphx_glr_auto_examples_decomposition_plot_pca_vs_fa_model_selection.py
增量 PCA
PCA
对象非常有用,但对于大型数据集有一定的限制。最大的限制是 PCA
仅支持批处理,这意味着要处理的所有数据必须适应主内存。IncrementalPCA
对象使用不同形式的处理,并允许进行部分计算,几乎与 PCA
的结果完全匹配,同时以小批量方式处理数据。IncrementalPCA
可以通过以下方式实现基于外存的主成分分析:
- 在本地硬盘或网络数据库上顺序获取数据块,并使用其
partial_fit
方法。 - 使用
numpy.memmap
将其fit
方法调用到内存映射文件上。
IncrementalPCA
仅存储组件和噪声方差的估计值,以便逐步更新 explained_variance_ratio_
。这就是为什么内存使用量取决于每个批次的样本数,而不是要处理的数据集中的样本数。
与 PCA
一样,IncrementalPCA
在应用 SVD 之前会对每个特征的输入数据进行中心化,但不进行缩放。
示例:
sphx_glr_auto_examples_decomposition_plot_incremental_pca.py
使用随机 SVD 的 PCA
通常有趣的是将数据投影到一个保留大部分方差的低维空间,通过丢弃与较低奇异值相关联的奇异向量。
例如,如果我们使用 64x64 像素的灰度图片进行人脸识别,数据的维度是 4096,对这样宽的数据训练 RBF 支持向量机非常慢。此外,我们知道数据的固有维度远低于 4096,因为所有的人脸图片看起来都有些相似。样本位于远低于 4096 的维度的流形上(例如,大约为 200)。PCA 算法可以用于线性转换数据,同时降低维度并保留大部分解释的方差。
在这种情况下,使用 PCA
类并设置可选参数 svd_solver='randomized'
非常有用:由于我们将丢弃大部分奇异向量,因此将计算限制在近似估计的奇异向量上,以便实际执行转换更加高效。
例如,下面显示了奥利维蒂人脸数据集中 16 个样本肖像(以 0.0 为中心)。右侧是重塑为肖像的前 16 个奇异向量。由于我们只需要一个大小为 n s a m p l e s = 400 n_{samples} = 400 nsamples=400 和 n f e a t u r e s = 64 × 64 = 4096 n_{features} = 64 \times 64 = 4096 nfeatures=64×64=4096 的数据集的前 16 个奇异向量,所以计算时间小于 1 秒:
如果我们记
n
max
=
max
(
n
s
a
m
p
l
e
s
,
n
f
e
a
t
u
r
e
s
)
n_{\max} = \max(n_{\mathrm{samples}}, n_{\mathrm{features}})
nmax=max(nsamples,nfeatures) 和
n
min
=
min
(
n
s
a
m
p
l
e
s
,
n
f
e
a
t
u
r
e
s
)
n_{\min} = \min(n_{\mathrm{samples}}, n_{\mathrm{features}})
nmin=min(nsamples,nfeatures),则随机 PCA
的时间复杂度为
O
(
n
max
2
⋅
n
c
o
m
p
o
n
e
n
t
s
)
O(n_{\max}^2 \cdot n_{\mathrm{components}})
O(nmax2⋅ncomponents),而不是 PCA
中实现的精确方法的
O
(
n
max
2
⋅
n
min
)
O(n_{\max}^2 \cdot n_{\min})
O(nmax2⋅nmin)。
随机 PCA
的内存占用量也与精确方法不同,它与
2
⋅
n
max
⋅
n
c
o
m
p
o
n
e
n
t
s
2 \cdot n_{\max} \cdot n_{\mathrm{components}}
2⋅nmax⋅ncomponents 成正比,而不是
n
max
⋅
n
min
n_{\max} \cdot n_{\min}
nmax⋅nmin。
注意:PCA
中 svd_solver='randomized'
的 inverse_transform
实现即使在 whiten=False
(默认情况下)时也不是 transform
的精确逆变换。
示例:
sphx_glr_auto_examples_applications_plot_face_recognition.py
sphx_glr_auto_examples_decomposition_plot_faces_decomposition.py
参考文献:
- 算法 4.3 in
"Finding structure with randomness: Stochastic algorithms for constructing approximate matrix decompositions" <0909.4061>
Halko, et al., 2009 "An implementation of a randomized algorithm for principal component analysis" <1412.3510>
A. Szlam et al. 2014
稀疏主成分分析 (SparsePCA 和 MiniBatchSparsePCA)
SparsePCA
是 PCA 的一种变体,其目标是提取最佳重构数据的稀疏成分集。
小批量稀疏 PCA (MiniBatchSparsePCA
) 是 SparsePCA
的一种变体,速度更快但准确性较低。通过对给定迭代次数的特征集的小块进行迭代,可以提高速度。
主成分分析 (PCA
) 的缺点是通过该方法提取的成分仅具有稠密表达,即当作为原始变量的线性组合时,它们具有非零系数。这可能使解释变得困难。在许多情况下,真实的基础成分可以更自然地被想象为稀疏向量;例如,在人脸识别中,成分可能自然地映射到人脸的部分。
稀疏主成分提供了一个更简洁、可解释的表示,明确强调了原始特征对样本之间差异的贡献。
下面的示例演示了从奥利维蒂人脸数据集中使用稀疏 PCA 提取的 16 个成分。可以看到正则化项引入了许多零。此外,数据的自然结构导致非零系数垂直相邻。该模型在数学上不强制执行这一点:每个成分都是一个 h ∈ R 4096 h \in \mathbf{R}^{4096} h∈R4096 的向量,并且除了在人类友好的可视化(64x64 像素图像)期间,没有垂直相邻的概念。下面显示的成分之所以出现局部效果,是由于数据的固有结构的影响,这使得这种局部模式最小化重构误差。存在考虑相邻性和不同类型结构的稀疏诱导范数;有关此类方法的综述,请参阅 [Jen09]。有关如何使用稀疏 PCA 的更多详细信息,请参见下面的示例部分。
请注意,稀疏主成分分析(Sparse PCA)问题有很多不同的表述方式。这里实现的方法基于 [Mrl09]。所求解的优化问题是一个带有 ℓ 1 \ell_1 ℓ1 惩罚项的主成分分析(字典学习)问题:
( U ∗ , V ∗ ) = arg min U , V 1 2 ∣ ∣ X − U V ∣ ∣ Fro 2 + α ∣ ∣ V ∣ ∣ 1 , 1 subject to ∣ ∣ U k ∣ ∣ 2 < = 1 for all 0 ≤ k < n c o m p o n e n t s \begin{aligned} (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 <= 1 \text{ for all } 0 \leq k < n_{components} \end{aligned} (U∗,V∗)=U,Vargminsubject to 21∣∣X−UV∣∣Fro2+α∣∣V∣∣1,1∣∣Uk∣∣2<=1 for all 0≤k<ncomponents
其中
∣
∣
.
∣
∣
Fro
||.||_{\text{Fro}}
∣∣.∣∣Fro 表示弗罗贝尼乌斯范数,
∣
∣
.
∣
∣
1
,
1
||.||_{1,1}
∣∣.∣∣1,1 表示逐元素矩阵范数,即矩阵中所有元素的绝对值之和。稀疏惩罚项
∣
∣
.
∣
∣
1
,
1
||.||_{1,1}
∣∣.∣∣1,1 还可以在训练样本较少时防止噪声对学习到的成分的影响。通过超参数 alpha
可以调整惩罚程度(从而调整稀疏程度)。较小的值会得到一个轻度正则化的分解,而较大的值会将许多系数收缩为零。
[!NOTE]
虽然MiniBatchSparsePCA
类在设计上是一个在线算法,但它并没有实现partial_fit
方法,因为该算法是沿着特征方向进行在线学习,而不是样本方向。
示例:
sphx_glr_auto_examples_decomposition_plot_faces_decomposition.py
参考文献:
核主成分分析(kPCA)
精确核主成分分析
KernelPCA
是主成分分析(PCA)的扩展,通过使用核函数(见 metrics
)实现非线性降维 [Scholkopf1997]。它具有许多应用,包括去噪、压缩和结构化预测(核依赖估计)。KernelPCA
支持 transform
和 inverse_transform
方法。
[!NOTE]
KernelPCA.inverse_transform
方法依赖于核岭回归(kernel ridge)来学习将样本从 PCA 基向量映射回原始特征空间的函数 [Bakir2003]。因此,使用KernelPCA.inverse_transform
得到的重构结果是一个近似值。请参考下面链接中的示例以了解更多细节。
示例:
sphx_glr_auto_examples_decomposition_plot_kernel_pca.py
参考文献:
选择核主成分分析的求解器
在 PCA
中,主成分的数量受到特征数量的限制,而在 KernelPCA
中,主成分的数量受到样本数量的限制。许多真实世界的数据集具有大量的样本!在这些情况下,使用完整的 kPCA 找到 所有 主成分会浪费计算时间,因为数据主要由前几个主成分描述(例如 n_components<=100
)。换句话说,在核 PCA 拟合过程中进行特征中心化的格拉姆矩阵的有效秩远小于其大小。在这种情况下,近似特征值求解器可以提供速度加快而几乎不损失精度的效果。
特征值求解器
可选参数 eigen_solver='randomized'
可以在所需的 n_components
数量相对于样本数量较小时,显著地减少计算时间。它依赖于随机分解方法,在较短的时间内找到一个近似解。
随机 KernelPCA
的时间复杂度为
O
(
n
s
a
m
p
l
e
s
2
⋅
n
c
o
m
p
o
n
e
n
t
s
)
O(n_{\mathrm{samples}}^2 \cdot n_{\mathrm{components}})
O(nsamples2⋅ncomponents),而精确方法(使用 eigen_solver='dense'
实现)的时间复杂度为
O
(
n
s
a
m
p
l
e
s
3
)
O(n_{\mathrm{samples}}^3)
O(nsamples3)。
随机 KernelPCA
的内存占用量也与样本数量成正比,为
2
⋅
n
s
a
m
p
l
e
s
⋅
n
c
o
m
p
o
n
e
n
t
s
2 \cdot n_{\mathrm{samples}} \cdot n_{\mathrm{components}}
2⋅nsamples⋅ncomponents,而精确方法的内存占用量为
n
s
a
m
p
l
e
s
2
n_{\mathrm{samples}}^2
nsamples2。
注意:这种技术与 RandomizedPCA
中的技术相同。
除了上述两种求解器之外,还可以使用 eigen_solver='arpack'
作为获取近似分解的替代方法。在实践中,当要找到的主成分数量非常小时,这种方法只能在非常短的时间内提供合理的执行时间。当所需的主成分数量小于 10(严格)且样本数量大于 200(严格)时,默认情况下会启用该方法。有关详细信息,请参见 KernelPCA
。
参考文献:
- dense 求解器:scipy.linalg.eigh 文档
- randomized 求解器:
- 算法 4.3 in
"Finding structure with randomness: Stochastic algorithms for constructing approximate matrix decompositions" <0909.4061>
Halko, et al. (2009) "An implementation of a randomized algorithm for principal component analysis" <1412.3510>
- Szlam et al. (2014)
- 算法 4.3 in
- arpack 求解器:scipy.sparse.linalg.eigsh 文档
18. 2. Lehoucq, D. C. Sorensen, and C. Yang, (1998)
截断奇异值分解和潜在语义分析
TruncatedSVD
实现了奇异值分解(SVD)的一种变体,仅计算
k
k
k 个最大奇异值,其中
k
k
k 是用户指定的参数。
TruncatedSVD
与 PCA
非常相似,但不同之处在于矩阵
X
X
X 不需要被居中。当从特征值中减去
X
X
X 的列均值后,在结果矩阵上进行截断 SVD 等价于 PCA。
关于截断 SVD 和潜在语义分析(LSA)
当将截断 SVD 应用于术语-文档矩阵(由 ~sklearn.feature_extraction.text.CountVectorizer
或 ~sklearn.feature_extraction.text.TfidfVectorizer
返回)时,这种转换被称为潜在语义分析(LSA),因为它将这些矩阵转换为低维的“语义”空间。特别是,LSA 可以解决同义词和多义词(两者都大致意味着每个单词有多个含义)导致的术语-文档矩阵过于稀疏,并在诸如余弦相似度等度量下表现出较差的相似性的问题。
[!NOTE]
LSA 也被称为潜在语义索引、LSI,尽管严格来说,这是指其在信息检索目的中的持久索引中的使用。
数学上,对训练样本 X X X 应用截断 SVD 会产生一个低秩近似 X X X:
X ≈ X k = U k Σ k V k ⊤ X \approx X_k = U_k \Sigma_k V_k^\top X≈Xk=UkΣkVk⊤
在此操作之后,
U
k
Σ
k
U_k \Sigma_k
UkΣk 是具有
k
k
k 个特征的转换后的训练集(在 API 中称为 n_components
)。
要对测试集 X X X 进行转换,我们将其与 V k V_k Vk 相乘:
X ′ = X V k X' = X V_k X′=XVk
[!NOTE]
在自然语言处理(NLP)和信息检索(IR)文献中,大多数关于 LSA 的处理都会交换矩阵 X X X 的轴,使其形状为n_features
×n_samples
。我们以一种与 scikit-learn API 更匹配的方式呈现 LSA,但找到的奇异值是相同的。
虽然 TruncatedSVD
转换器适用于任何特征矩阵,但在 LSA/文本处理环境中,建议使用它来处理 tf-idf 矩阵,而不是原始频率计数。特别是,应该打开子线性缩放和逆文档频率(sublinear_tf=True, use_idf=True
),以使特征值更接近高斯分布,从而弥补 LSA 对文本数据的错误假设。
示例:
sphx_glr_auto_examples_text_plot_document_clustering.py
参考文献:
- Christopher D. Manning, Prabhakar Raghavan and Hinrich Schütze (2008), Introduction to Information Retrieval, Cambridge University Press, chapter 18: Matrix decompositions & latent semantic indexing
字典学习
使用预先计算的字典进行稀疏编码
- 正交匹配追踪(
omp
) - 最小角度回归(
least_angle_regression
) - 通过最小角度回归计算的 Lasso
- 使用坐标下降法的 Lasso(
lasso
) - 阈值法
阈值法非常快,但不能产生准确的重建结果。在文献中已经证明它们在分类任务中很有用。对于图像重建任务,正交匹配追踪可以产生最准确、无偏的重建结果。
通过 split_code
参数,字典学习对象提供了将稀疏编码结果中的正值和负值分开的可能性。当字典学习用于提取用于监督学习的特征时,这是很有用的,因为它允许学习算法对特定原子的负载的负权重和相应的正负载之间进行不同的赋值。
单个样本的分割代码的长度为 2 * n_components
,并且使用以下规则构建:首先,计算长度为 n_components
的常规代码。然后,将 split_code
的前 n_components
个条目填充为常规代码向量的正部分。分割代码的后半部分填充为代码向量的负部分,但只有正号。因此,split_code
是非负的。
示例:
sphx_glr_auto_examples_decomposition_plot_sparse_coding.py
通用字典学习
字典学习(DictionaryLearning
)是一个矩阵分解问题,其目标是找到一个(通常是过完备的)字典,以便对拟合数据进行稀疏编码。
将数据表示为过完备字典中原子的稀疏组合被认为是哺乳动物的初级视觉皮层的工作方式。因此,在图像块上应用字典学习已被证明在图像处理任务(如图像补全、修复和去噪)以及监督识别任务中取得良好的结果。
字典学习是一个优化问题,通过交替更新稀疏编码(作为多个 Lasso 问题的解),考虑字典固定,然后更新字典以最佳拟合稀疏编码。
( U ∗ , V ∗ ) = arg min U , V 1 2 ∣ ∣ X − U V ∣ ∣ Fro 2 + α ∣ ∣ U ∣ ∣ 1 , 1 subject to ∣ ∣ V k ∣ ∣ 2 < = 1 for all 0 ≤ k < n a t o m s \begin{aligned} (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 <= 1 \text{ for all } 0 \leq k < n_{\mathrm{atoms}} \end{aligned} (U∗,V∗)=U,Vargminsubject to 21∣∣X−UV∣∣Fro2+α∣∣U∣∣1,1∣∣Vk∣∣2<=1 for all 0≤k<natoms
∣
∣
.
∣
∣
Fro
||.||_{\text{Fro}}
∣∣.∣∣Fro 表示弗罗贝尼乌斯范数,
∣
∣
.
∣
∣
1
,
1
||.||_{1,1}
∣∣.∣∣1,1 表示逐元素矩阵范数,即矩阵中所有元素的绝对值之和。在使用这种过程拟合字典之后,变换就变成了一个与所有字典学习对象共享相同实现的稀疏编码步骤(参见 SparseCoder
)。
还可以将字典和/或编码约束为正值,以匹配数据中可能存在的约束。下面是应用不同正性约束的面部图像。红色表示负值,蓝色表示正值,白色表示零。
下图显示了从从浣熊脸部图像的一部分提取的4x4像素图像块学习的字典的样子。
示例:
sphx_glr_auto_examples_decomposition_plot_image_denoising.py
参考文献:
- “Online dictionary learning for sparse coding”
10. Mairal, F. Bach, J. Ponce, G. Sapiro, 2009
小批量字典学习
MiniBatchDictionaryLearning
实现了字典学习算法的更快但不太准确的版本,更适用于大型数据集。
默认情况下,MiniBatchDictionaryLearning
将数据划分为小批量,并通过循环迭代小批量进行在线优化,直到达到指定的迭代次数。然而,目前它没有实现停止条件。
该估计器还实现了 partial_fit
方法,通过仅对小批量进行一次迭代来更新字典。当数据不是从一开始就可用,或者数据不适合内存时,可以使用此方法进行在线学习。
sklearn.cluster
用于字典学习的聚类
请注意,当使用字典学习来提取表示(例如稀疏编码)时,聚类可以作为学习字典的良好代理。例如,MiniBatchKMeans
估计器具有计算效率高和实现 partial_fit
方法的特点,可以进行在线学习。
示例:sphx_glr_auto_examples_cluster_plot_dict_face_patches.py
sklearn.decomposition
因子分析
在无监督学习中,我们只有一个数据集 X = { x 1 , x 2 , … , x n } X = \{x_1, x_2, \dots, x_n \} X={x1,x2,…,xn}。如何用数学方式描述这个数据集?一个非常简单的连续潜变量模型是
x i = W h i + μ + ϵ x_i = W h_i + \mu + \epsilon xi=Whi+μ+ϵ
向量 h i h_i hi 被称为“潜变量”,因为它是未观察到的。 ϵ \epsilon ϵ 被认为是一个噪声项,其分布服从均值为0,协方差为 Ψ \Psi Ψ 的高斯分布(即 ϵ ∼ N ( 0 , Ψ ) \epsilon \sim \mathcal{N}(0, \Psi) ϵ∼N(0,Ψ)), μ \mu μ 是任意的偏移向量。这样的模型被称为“生成式”,因为它描述了如何从 h i h_i hi 生成 x i x_i xi。如果我们将所有的 x i x_i xi 作为列组成矩阵 X \mathbf{X} X,将所有的 h i h_i hi 作为矩阵 H \mathbf{H} H 的列,那么我们可以写成(使用适当定义的 M \mathbf{M} M 和 E \mathbf{E} E):
X = W H + M + E \mathbf{X} = W \mathbf{H} + \mathbf{M} + \mathbf{E} X=WH+M+E
换句话说,我们对矩阵 X \mathbf{X} X 进行了分解。
如果给定 h i h_i hi,上述方程自动暗示了以下概率解释:
p ( x i ∣ h i ) = N ( W h i + μ , Ψ ) p(x_i|h_i) = \mathcal{N}(Wh_i + \mu, \Psi) p(xi∣hi)=N(Whi+μ,Ψ)
对于一个完整的概率模型,我们还需要对潜变量 h h h 进行先验分布。最直接的假设(基于高斯分布的良好性质)是 h ∼ N ( 0 , I ) h \sim \mathcal{N}(0, \mathbf{I}) h∼N(0,I)。这导致 x x x 的边缘分布为高斯分布:
p ( x ) = N ( μ , W W T + Ψ ) p(x) = \mathcal{N}(\mu, WW^T + \Psi) p(x)=N(μ,WWT+Ψ)
现在,如果没有进一步的假设,拥有潜变量 h h h 的想法将是多余的—— x x x 可以完全用均值和协方差来建模。我们需要对这两个参数中的一个施加一些更具体的结构。一个简单的附加假设涉及误差协方差 Ψ \Psi Ψ 的结构:
-
Ψ
=
σ
2
I
\Psi = \sigma^2 \mathbf{I}
Ψ=σ2I:这个假设导致了
PCA
的概率模型。 -
Ψ
=
d
i
a
g
(
ψ
1
,
ψ
2
,
…
,
ψ
n
)
\Psi = \mathrm{diag}(\psi_1, \psi_2, \dots, \psi_n)
Ψ=diag(ψ1,ψ2,…,ψn):这个模型被称为
FactorAnalysis
,是一个经典的统计模型。矩阵 W 有时被称为“因子载荷矩阵”。
因子分析(Factor Analysis)可以产生与主成分分析(PCA)相似的成分(其载荷矩阵的列)。然而,不能对这些成分做出任何一般性的陈述(例如它们是否正交):
相对于PCA,因子分析的主要优势在于它可以独立地对输入空间的每个方向建模方差(异方差噪声):
这使得在存在异方差噪声的情况下,比概率PCA更好地进行模型选择:
因子分析通常会在因子旋转之后进行(使用旋转参数),通常是为了提高解释性。例如,Varimax旋转最大化了平方载荷的方差之和,即它倾向于产生更稀疏的因子,每个因子仅受到少数特征的影响(“简单结构”)。请参见下面的第一个示例。
示例:
sphx_glr_auto_examples_decomposition_plot_varimax_fa.py
sphx_glr_auto_examples_decomposition_plot_pca_vs_fa_model_selection.py
独立成分分析(ICA)
独立成分分析(Independent Component Analysis,ICA)将多变量信号分离成最大独立的加性子分量。在scikit-learn中,它使用Fast ICA
算法实现。通常,ICA不用于降维,而是用于分离叠加的信号。由于ICA模型不包括噪声项,为了使模型正确,必须应用白化。可以使用whiten参数内部进行白化,也可以使用PCA的某个变体手动进行白化。
它经典地用于分离混合信号(称为盲源分离问题),如下面的示例所示:
ICA还可以用作另一种非线性分解,以找到具有一定稀疏性的分量:
示例:
sphx_glr_auto_examples_decomposition_plot_ica_blind_source_separation.py
sphx_glr_auto_examples_decomposition_plot_ica_vs_pca.py
sphx_glr_auto_examples_decomposition_plot_faces_decomposition.py
非负矩阵分解(NMF或NNMF)
使用Frobenius范数的NMF
NMF
是一种替代分解方法,假设数据和分量都是非负的。在数据矩阵不包含负值的情况下,可以将NMF
插入到PCA或其变体中。它通过优化样本
X
X
X与矩阵乘积
W
H
WH
WH之间的距离
d
d
d,找到样本
X
X
X的两个非负元素矩阵
W
W
W和
H
H
H的分解。最常用的距离函数是平方Frobenius范数,它是欧几里德范数对矩阵的明显扩展:
d F r o ( X , Y ) = 1 2 ∣ ∣ X − Y ∣ ∣ F r o 2 = 1 2 ∑ i , j ( X i j − Y i j ) 2 d_{\mathrm{Fro}}(X, Y) = \frac{1}{2} ||X - Y||_{\mathrm{Fro}}^2 = \frac{1}{2} \sum_{i,j} (X_{ij} - {Y}_{ij})^2 dFro(X,Y)=21∣∣X−Y∣∣Fro2=21i,j∑(Xij−Yij)2
与PCA不同,向量的表示是通过叠加分量而不是减去分量来获得的。这种加法模型对于表示图像和文本非常有效。
[Hoyer, 2004]观察到,当受到仔细限制时,NMF
可以产生数据集的基于部件的表示,从而得到可解释的模型。下面的示例显示了从Olivetti人脸数据集中使用NMF
找到的16个稀疏分量,与PCA特征脸进行比较。
init属性确定应用的初始化方法,这对方法的性能有很大影响。NMF
实现了非负双奇异值分解(Nonnegative Double Singular Value Decomposition)方法。NNDSVD基于两个SVD过程,一个近似数据矩阵,另一个近似结果的部分SVD因子的正部分,利用了单位秩矩阵的代数性质。基本的NNDSVD算法更适合稀疏因子分解。在稠密情况下,建议使用其变体NNDSVDa(其中所有零被设置为数据的所有元素的均值)和NNDSVDar(其中零被设置为小于数据均值除以100的随机扰动)。
请注意,乘法更新(‘mu’)求解器无法更新初始化中存在的零,因此当与引入大量零的基本NNDSVD算法一起使用时,会导致结果较差;在这种情况下,应优先选择NNDSVDa或NNDSVDar。
NMF
还可以通过将init参数设置为"random"来使用正确缩放的随机非负矩阵进行初始化。还可以传递整数种子或RandomState以控制可重现性。
在NMF
中,可以通过在损失函数中添加L1和L2先验来对模型进行正则化。L2先验使用Frobenius范数,而L1先验使用逐元素的L1范数。与~sklearn.linear_model.ElasticNet
类似,我们使用l1_ratio(
ρ
\rho
ρ)参数控制L1和L2的组合,使用alpha_W和alpha_H(
α
W
\alpha_W
αW和
α
H
\alpha_H
αH)参数控制正则化的强度。为了使其对数据拟合项尽可能独立于训练集的大小,这些先验项分别乘以样本数(
n
_
s
a
m
p
l
e
s
n\_samples
n_samples)和特征数(
n
_
f
e
a
t
u
r
e
s
n\_features
n_features)。然后,先验项为:
$$
(\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
$$
使用beta散度的NMF
如前所述,最常用的距离函数是平方Frobenius范数,它是欧几里德范数对矩阵的明显扩展:
d F r o ( X , Y ) = 1 2 ∣ ∣ X − Y ∣ ∣ F r o 2 = 1 2 ∑ i , j ( X i j − Y i j ) 2 d_{\mathrm{Fro}}(X, Y) = \frac{1}{2} ||X - Y||_{Fro}^2 = \frac{1}{2} \sum_{i,j} (X_{ij} - {Y}_{ij})^2 dFro(X,Y)=21∣∣X−Y∣∣Fro2=21i,j∑(Xij−Yij)2
在NMF中可以使用其他距离函数,例如(广义)Kullback-Leibler(KL)散度,也称为I散度:
d K L ( X , Y ) = ∑ i , j ( X i j log ( X i j Y i j ) − X i j + Y i j ) d_{KL}(X, Y) = \sum_{i,j} (X_{ij} \log(\frac{X_{ij}}{Y_{ij}}) - X_{ij} + Y_{ij}) dKL(X,Y)=i,j∑(Xijlog(YijXij)−Xij+Yij)
或者Itakura-Saito(IS)散度:
d I S ( X , Y ) = ∑ i , j ( X i j Y i j − log ( X i j Y i j ) − 1 ) d_{IS}(X, Y) = \sum_{i,j} (\frac{X_{ij}}{Y_{ij}} - \log(\frac{X_{ij}}{Y_{ij}}) - 1) dIS(X,Y)=i,j∑(YijXij−log(YijXij)−1)
这三个距离是beta散度家族的特例,其中 β = 2 , 1 , 0 \beta = 2, 1, 0 β=2,1,0。beta散度由以下公式定义:
d β ( X , Y ) = ∑ i , j 1 β ( β − 1 ) ( X i j β + ( β − 1 ) Y i j β − β X i j Y i j β − 1 ) 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}) dβ(X,Y)=i,j∑β(β−1)1(Xijβ+(β−1)Yijβ−βXijYijβ−1)
请注意,如果 β ∈ ( 0 ; 1 ) \beta \in (0; 1) β∈(0;1),则此定义无效,但可以连续地扩展到相应的 d K L d_{KL} dKL和 d I S d_{IS} dIS定义。
NMF实现的求解器
‘cd’ 求解器只能优化 Frobenius 范数。由于 NMF 的底层非凸性,即使优化相同的距离函数,不同的求解器也可能收敛到不同的极小值。
NMF 最好使用 fit_transform
方法,该方法返回矩阵 W。矩阵 H 存储在拟合模型的 components_
属性中;方法 transform
将基于这些存储的分量对新矩阵 X_new 进行分解:
import numpy as np
from sklearn.decomposition import NMF
X = np.array([[1, 1], [2, 1], [3, 1.2], [4, 1], [5, 0.8], [6, 1]])
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)
示例:
sphx_glr_auto_examples_decomposition_plot_faces_decomposition.py
sphx_glr_auto_examples_applications_plot_topics_extraction_with_nmf_lda.py
小批量非负矩阵分解
MiniBatchNMF
实现了非负矩阵分解(即 ~sklearn.decomposition.NMF
)的更快但不太准确的版本,更适用于大型数据集。
默认情况下,MiniBatchNMF
将数据划分为小批量,并通过循环迭代指定次数的小批量来在线方式优化 NMF 模型。batch_size
参数控制批次的大小。
为了加速小批量算法,还可以对过去的批次进行缩放,使其比新批次的重要性更低。这是通过引入所谓的遗忘因子(由 forget_factor
参数控制)来实现的。
该估计器还实现了 partial_fit
方法,该方法通过仅对小批量进行一次迭代来更新 H
。当数据不是从一开始就可用,或者数据不适合内存时,可以使用此方法进行在线学习。
参考文献:
潜在狄利克雷分配(LDA)
潜在狄利克雷分配(Latent Dirichlet Allocation,简称 LDA)是一种用于离散数据集(如文本语料库)的生成概率模型。它也是一种用于从一系列文档中发现抽象主题的主题模型。
LDA 的图模型是一个三层生成模型:
请注意上述图模型中的符号,这些符号可以在 Hoffman 等人的论文中找到:
- 语料库是一个包含 D D D 个文档的集合。
- 文档是一个包含 N N N 个单词的序列。
- 语料库中有 K K K 个主题。
- 方框表示重复采样。
在图模型中,每个节点都是一个随机变量,并在生成过程中起到一定的作用。阴影节点表示观察变量,未阴影节点表示隐藏(潜在)变量。在这种情况下,我们只观察到语料库中的单词数据。潜在变量确定了语料库中主题的随机混合以及文档中单词的分布。LDA 的目标是利用观察到的单词来推断隐藏的主题结构。
建模文本语料库的详细信息
在建模文本语料库时,该模型假设具有 D D D 个文档和 K K K 个主题的语料库的生成过程如下,其中 K K K 对应于 API 中的 n_components:
- 对于每个主题 k ∈ K k \in K k∈K,从 D i r i c h l e t ( η ) \mathrm{Dirichlet}(\eta) Dirichlet(η) 中抽取 β k \beta_k βk。这提供了一个词的分布,即单词在主题 k k k 中出现的概率。 η \eta η 对应于 topic_word_prior。
- 对于每个文档 d ∈ D d \in D d∈D,从 D i r i c h l e t ( α ) \mathrm{Dirichlet}(\alpha) Dirichlet(α) 中抽取主题比例 θ d \theta_d θd。 α \alpha α 对应于 doc_topic_prior。
- 对于文档
d
d
d 中的每个单词
i
i
i:
- 从 M u l t i n o m i a l ( θ d ) \mathrm{Multinomial}(\theta_d) Multinomial(θd) 中抽取主题分配 z d i z_{di} zdi
- 从 M u l t i n o m i a l ( β z d i ) \mathrm{Multinomial}(\beta_{z_{di}}) Multinomial(βzdi) 中抽取观察到的单词 w i j w_{ij} wij
对于参数估计,后验分布为:
p ( z , θ , β ∣ w , α , η ) = p ( z , θ , β ∣ α , η ) p ( w ∣ α , η ) p(z, \theta, \beta |w, \alpha, \eta) = \frac{p(z, \theta, \beta|\alpha, \eta)}{p(w|\alpha, \eta)} p(z,θ,β∣w,α,η)=p(w∣α,η)p(z,θ,β∣α,η)
由于后验是难以计算的,变分贝叶斯方法使用一个更简单的分布 q ( z , θ , β ∣ λ , ϕ , γ ) q(z,\theta,\beta | \lambda, \phi, \gamma) q(z,θ,β∣λ,ϕ,γ) 来近似后验,并且优化这些变分参数 λ \lambda λ、 ϕ \phi ϕ、 γ \gamma γ 以最大化证据下界(ELBO):
log P ( w ∣ α , η ) ≥ L ( w , ϕ , γ , λ ) = △ E q [ log p ( w , z , θ , β ∣ α , η ) ] − E q [ log q ( z , θ , β ) ] \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)] logP(w∣α,η)≥L(w,ϕ,γ,λ)=△Eq[logp(w,z,θ,β∣α,η)]−Eq[logq(z,θ,β)]
最大化 ELBO 等价于最小化变分分布 q ( z , θ , β ) q(z,\theta,\beta) q(z,θ,β) 与真实后验 p ( z , θ , β ∣ w , α , η ) p(z, \theta, \beta |w, \alpha, \eta) p(z,θ,β∣w,α,η) 之间的 Kullback-Leibler(KL)散度。
LatentDirichletAllocation
实现了在线变分贝叶斯算法,并支持在线和批量更新方法。批量方法在每次完整遍历数据后更新变分变量,而在线方法则从小批量数据点更新变分变量。
[!NOTE]
尽管在线方法保证收敛到局部最优点,但最优点的质量和收敛速度可能取决于小批量大小和与学习率设置相关的属性。
当在“文档-词”矩阵上应用 LatentDirichletAllocation
时,该矩阵将被分解为“主题-词”矩阵和“文档-主题”矩阵。而“主题-词”矩阵存储在模型的 components_
中,“文档-主题”矩阵可以从 transform
方法中计算得到。
LatentDirichletAllocation
还实现了 partial_fit
方法。当数据可以按顺序获取时,可以使用此方法。
示例:
sphx_glr_auto_examples_applications_plot_topics_extraction_with_nmf_lda.py
参考文献:
- “Latent Dirichlet Allocation”
4. Blei, A. Ng, M. Jordan, 2003 - "Online Learning for Latent Dirichlet Allocation”
13. Hoffman, D. Blei, F. Bach, 2010 - “Stochastic Variational Inference”
13. Hoffman, D. Blei, C. Wang, J. Paisley, 2013 - “The varimax criterion for analytic rotation in factor analysis”
8. 6. Kaiser, 1958
另请参阅 nca_dim_reduction
以进行邻域分量分析的降维。