1 Star 6 Fork 4

OpenDocCN / apachecn-ml-zh

加入 Gitee
与超过 1200万 开发者一起发现、参与优秀开源项目,私有仓库也完全免费 :)
免费加入
克隆/下载
07.md 49.48 KB
一键复制 编辑 原始数据 按行查看 历史
布客飞龙 提交于 2022-01-02 01:27 . 2022-01-02 01:27:33

七、降维和成分分析

在这一章,我们将介绍和讨论一些非常重要的技术,可以用来进行降维和组件提取。在前一种情况下,目标是将高维数据集转换为低维数据集,以尽量减少信息损失。后者是一个过程,需要找到一个可以混合的原子字典,以建立样本。

特别是,我们将讨论以下主题:

  • 主成分分析 ( 主成分分析
  • 奇异值分解 ( 奇异值分解)和白化
  • 核主成分分析
  • 稀疏主成分分析和字典学习
  • 要素分析
  • 独立成分分析 ( ICA
  • 非负矩阵分解 ( NNMF )
  • 潜在狄利克雷分配 ( LDA )

技术要求

本章将介绍的代码需要以下内容:

示例可在 GitHub 资源库中获得,网址为https://GitHub . com/PacktPublishing/HandsOn-Unsupervised-Learning-with-Python/tree/master/chapter 07

主成分分析

降低数据集维数的最常见方法之一是基于样本协方差矩阵的分析。一般来说,我们知道随机变量的信息含量与其方差成正比。例如,给定一个多变量高斯,熵(我们用来测量信息的数学表达式)如下:

上式中,σ为协方差矩阵。如果我们(不失一般性)假设σ是对角的,那么很容易理解熵(按比例)大于每个单个分量的方差, σ i 2 。这并不奇怪,因为一个低方差的随机变量集中在均值附近,惊喜的概率很低。另一方面,当 σ 2 变得越来越大时,潜在的结果随着不确定性而增加,这与信息量成正比。

当然,组件的影响一般是不同的;因此,主成分分析 ( PCA )的目标是找到样本的线性变换,能够将它们投影到更低维的子空间上,从而保留最大可能量的初始方差。实际上,让我们考虑一个数据集,x∈ℜm×nT7:

我们想要找到的线性变换是一个新的数据集,如下所示:

在应用这样的转换之后,我们期望得到以下结果:

让我们开始考虑样本协方差矩阵(出于我们的目的,我们也可以采用有偏估计);为简单起见,我们还假设 X 的平均值为零:

这样的矩阵是对称的,是正半定的(不熟悉这些概念也没关系,但是对于证明后面的步骤很重要),所以它的特征向量构成了正交基。简单回顾一下,如果 A 是正方形矩阵,向量 v i 被称为与特征值相关联的特征向量 λ i ,如果下列情况成立:

换句话说,特征向量被转换成其自身的扩展或收缩版本(不能发生旋转)。证明协方差矩阵的特征向量定义协方差分量的方向(即数据集具有特定协方差分量的方向)并不难(但所有数学细节将被省略)。然而,原因很简单;事实上,在变换之后,新的协方差矩阵(变换数据集的, Z )是不相关的(即它是对角的),因为新的轴与协方差分量对齐。这意味着一个 versor(例如, v 0 = (1,0,0,...,0) )转化为σI2vI,所以是一个关联特征值与 i th 分量方差成正比的特征向量。

因此,为了找出哪些元素可以被丢弃,我们可以对特征值进行排序,从而得出以下结论:

对应的特征向量( v 1 ,v 2 ,...,v n )分别确定最大方差对应的分量,以此类推,直到最后一个。形式上,我们定义这样的特征向量为主成分;因此,第一主成分是与最大方差相关的方向,第二主成分与第一主成分正交,并且它与第二大方差相关,以此类推。在二维数据集的情况下,这个概念显示在下面的屏幕截图中:

Principal components of a bidimensional dataset; the first principal component lies along the axis with the largest variance, while the second one is orthogonal, and it's proportional to the residual variance

至此,问题差不多解决了;事实上,如果我们只选择第一个 k 主成分( v i ∈ ℜ n × 1 ),我们就可以构建一个变换矩阵,ak∈ℜn×k,从而将与第一个 k 特征值关联的特征向量作为行:

因此,我们可以通过使用以下矩阵乘法来转换整个数据集:

新数据集 Z 的维度等于 k <(或< < ) n ,并且它包含与组件数量成比例的原始方差量。例如,考虑到上一个截图中显示的例子,如果我们选择单个分量,所有的向量都被转换成沿着第一个主分量的点。当然,有一些信息的丢失,这必须逐案考虑;在接下来的几节中,我们将讨论如何评估这种损失并做出合理的决定。现在,我们将简要说明如何以有效的方式提取主成分。

奇异值分解的主成分分析

即使我们将采用完整的主成分分析实现,了解如何有效地执行这样的过程也是有帮助的。当然,最明显的方法是基于样本协方差矩阵的计算,它的特征分解(将输出特征值和相应的特征向量),然后最终,有可能建立转换矩阵。这种方法很简单,但不幸的是,它的效率也很低。主要原因是我们需要计算样本协方差矩阵,这对于大型数据集来说可能是一项非常长的任务。

奇异值分解 ( SVD )提供了一种高效得多的方式,这是一个线性代数过程,具有一些重要的特性:它可以直接对数据集进行操作,当提取到所需数量的组件时可以停止,并且有可以小批量工作的增量版本,克服了内存不足的问题。特别是考虑到数据集 X ∈ ℜ m × n ,SVD 可以表示如下:

U 为酉矩阵(即UUT= UTU = I,故UT= U-1)包含作为行的左手奇异向量( XX T 的特征向量); V (也是酉)包含右奇异向量作为行(对应于 X T X 的特征向量),而λ是包含sT29】的奇异值的对角矩阵(它们是XXTT33】和 X T 的特征值的平方根特征值按降序排序,特征向量重新排列以匹配相应的位置。由于 1/m 因子是乘法常数,不影响特征值的相对大小;因此,排序顺序保持不变。因此,我们可以直接使用 VU 并从λ中选择第一个顶级 k 特征值。特别是我们可以观察到以下结果(作为变换矩阵, A ,等于 V ):**

因此,通过使用 U k (仅包含顶部 k 特征向量)和λkT9】(仅包含顶部 k 特征值)的截断版本,我们可以直接获得低维变换数据集(具有 k 分量),如下所示:

这种方法快速、有效,并且当数据集太大而无法放入内存时,可以很容易地进行缩放。即使我们在本书中没有处理这样的场景,提到 scikit-learn TruncatedSVD类(执行仅限于 k 顶特征值的 SVD)和IncrementalPCA类(对小批量执行 PCA)也是有帮助的。出于我们的目的,我们将使用标准的PCA类和一些重要的变体,它们要求整个数据集适合内存。

白粉

奇异值分解的一个重要应用是白化过程,该过程强制数据集 X 具有零均值(即 E[X] = 0 或零中心),以具有单位协方差矩阵 C (它是实对称的)。这种方法非常有助于提高许多监督算法的性能,这些算法可以受益于所有组件共享的统一单一方差。

将分解应用于 C ,我们得到以下结果:

矩阵 V 的列是 C 的特征向量,而λ是包含特征值的对角矩阵(记住 SVD 输出奇异值,奇异值是特征向量的平方根)。因此,我们需要找到一个线性变换, z = Ax ,这样E【ZTZ】= I。当使用前面的分解时,这很简单:

从前面的等式中,我们可以推导出变换矩阵的表达式 A :

现在,我们将使用一个小的测试数据集展示美白的效果,如下所示:

import numpy as np

from sklearn.datasets import make_blobs

X, _ = make_blobs(n_samples=300, centers=1, cluster_std=2.5, random_state=1000)

print(np.cov(X.T))

显示数据集协方差矩阵的上一个块的输出如下:

[[6.37258226 0.40799363]
 [0.40799363 6.32083501]]

用于在通用数据集上执行白化的whiten()函数(零中心化是过程的一部分)如下所示(白化后correct参数强制进行比例校正):

import numpy as np

def zero_center(X):
    return X - np.mean(X, axis=0)

def whiten(X, correct=True):
    Xc = zero_center(X)
    _, L, V = np.linalg.svd(Xc)
    W = np.dot(V.T, np.diag(1.0 / L))
    return np.dot(Xc, W) * np.sqrt(X.shape[0]) if correct else 1.0

应用于X数组的白化结果如下截图所示:

Original dataset (left); whitened dataset (right)

我们现在可以检查新的协方差矩阵,如下所示:

import numpy as np

Xw = whiten(X)
print(np.cov(Xw.T))

输出如下:

[[1.00334448e+00 1.78229783e-17]
 [1.78229783e-17 1.00334448e+00]]

可以看到,矩阵现在是一个恒等式(误差最小),数据集也有一个空平均值。

MNIST 数据集的主成分分析

现在,让我们应用主成分分析,以降低 MNIST 数据集的维度。我们将使用 scikit-learn 提供的压缩版本(1,797,8 × 8 图像),但我们的任何考虑都不会受到这一选择的影响。让我们从加载和规范化数据集开始:

from sklearn.datasets import load_digits

digits = load_digits()
X = digits['data'] / np.max(digits['data'])

从理论讨论中,我们知道协方差矩阵特征值的大小与相应主成分的相对重要性(即解释的方差,因此也是信息量)成正比。因此,如果按降序排序,可以计算以下差异:

当组件数量 k → n 时,重要性趋于降低,我们可以通过选取第一个最大差异来选择最佳的 k ,这表明以下所有组件解释的差异量大幅下降。为了更好地理解这种机制,让我们计算特征值及其差(作为协方差矩阵, C ,是正半定的,我们确定λI≥0∀I∑(1,n) ):

import numpy as np

C = np.cov(X.T)
l, v = np.linalg.eig(C)
l = np.sort(l)[::-1]
d = l[:l.shape[0]-1] - l[1:]

展平图像(64 维阵列)的差异如下图所示:

Eigenvalue differences for each principal component

可以看出,第一主成分的差异非常大,对应于第四主成分(λ43T5)达到最大值;但是,接下来的差别还是很大的,而对应λ6T9】则有一个急跌。在这一点上,趋势几乎是稳定的(除了一些残余振荡),直到 λ 11 ,然后开始非常迅速地下降,趋于零。由于我们还是要有正方形的图像,我们就要选择 k = 16 (相当于每边除以四)。在另一个任务中,你可以选择,例如 k = 15 ,甚至k = 8;然而,为了更好地理解降维引起的误差,分析解释的方差也将是有帮助的。因此,让我们从执行主成分分析开始:**

from sklearn.decomposition import PCA

pca = PCA(n_components=16, random_state=1000)
digits_pca = pca.fit_transform(X)

digits_pca阵列是在拟合模型并将所有样本投影到对应于前 16 个主成分的子空间之后获得的。如果我们想要将原始图像与其重建进行比较,我们需要调用inverse_transform()方法,该方法执行到原始空间的投影。所以,如果 PCA 在本例中是一个变换,f(x):ℜ64→ℜ16T7】,逆变换是g(z):ℜ16→ℜ64t13】。下面的截图显示了前 10 位数字及其重构之间的比较:**

Original samples (top row); reconstructions (bottom row)

重建很明显是有损耗的,但是数字仍然是可区分的。现在,让我们通过对explained_variance_ratio_数组的所有值求和来检查总的解释方差,该数组包含每个分量的解释方差的相对量(因此任何 k < n 分量的和总是小于 1):

print(np.sum(pca.explained_variance_ratio_))

上一个片段的输出如下:

0.8493974642542452

因此,在降维到 16 个分量的情况下,我们解释了大约 85%的原始方差,这是一个合理的值,考虑到我们为每个样本丢弃了 48 个分量。

显示所有单个贡献的图如下截图所示:

Explained variance ratio corresponding to each principal component

正如预期的那样,这种贡献往往会减少,因为在这种情况下,第一个主要组成部分是负责任的;例如,对于颜色,一条线(如黑色或白色),而其余的线形成灰色阴影。这种行为非常普遍,几乎在每种情况下都能观察到。通过这个图表,也很容易找到额外的损失,以便进一步减少。例如,我们可以立即发现,对 3 个分量的严格限制将解释大约 40%的原始方差;所以,剩下的 45%被分成了剩下的 13 个部分。我邀请你重复这个例子,试图找到人类区分所有数字所需的最小组件数。

核主成分分析

有时,数据集不是线性可分的,标准的主成分分析不能提取正确的主成分。这个过程与第 3 章高级聚类中讨论的过程没有什么不同,当时我们面对的是非凸聚类的问题。在这种情况下,由于几何形状的原因,一些算法无法成功分离。在这种情况下,目标是根据主成分的结构来区分不同的类(在纯无监督的场景中,我们考虑特定的分组)。因此,我们希望处理转换后的数据集, Z ,并检测可区分阈值的存在。例如,让我们考虑以下截图:

Original dataset (left); PCA projected version (right)

由于原始数据集是线性可分的,在 PCA 投影后,我们可以立即找到允许检测第一个分量的阈值(这是唯一真正需要的),以便区分两个斑点。但是,如果数据集不是线性可分的,我们会得到一个不可接受的结果,如下图所示:

Original dataset (left); PCA projected version (right)

当几何形状更复杂时,找到可区分的阈值可能是不可能的。然而,我们知道将数据投影到更高维的空间可以使它们线性分离。特别是如果 x ∈ ℜ n ,我们可以选择一个合适的函数, f(x) ,这样y = f(x)∈ℜpT9】,用p>t23】n*。不幸的是,将这种转换应用于整个数据集可能非常昂贵;实际上,给定一个变换矩阵, A ,(带 n 个分量),单个主分量,A(t),投影后,可以写成如下形式(记住它们是协方差矩阵的特征向量):*

因此,单个向量的变换如下:

可以看到,变换需要点积的计算,f(xI)Tf(xI)。在这些情况下,我们可以使用所谓的内核技巧,它表示有特定的函数 K(,),称为内核,具有有趣的属性,如下所示:

换句话说,我们可以通过简单地计算每两个点的核来计算在高维空间中主成分上的投影,而不是执行点积,这需要在计算*f()*之后进行 n 次乘法。

一些常见的内核如下:

  • 径向基函数 ( 径向基函数,或高斯核:
  • 多项式核,次数为 p :
  • 乙状结肠核:

对于非常大的数据集,这个过程仍然相当昂贵(但是为了避免额外的时间,可以预先计算和存储内核值),但是它比标准的投影要高效得多。此外,它的优点是允许在可能进行线性判别的空间中提取主成分。现在,让我们将径向基函数核主成分分析应用于上一张截图中显示的半月形数据集。gamma参数等于1/σ2T4。在这种特殊情况下,主要问题是存在双重重叠。考虑到原始标准差约为 1.0(也就是 σ 2 = 1 ,我们至少需要三个标准差才能恰当区分;因此,我们将设置 γ = 10 :

from sklearn.datasets import make_moons
from sklearn.decomposition import KernelPCA

X, Y = make_moons(n_samples=800, noise=0.05, random_state=1000)

kpca = KernelPCA(n_components=2, kernel='rbf', gamma=10.0, random_state=1000)
X_pca = kpca.fit_transform(X)

投影结果如下图所示:

Original dataset (left); kernel PCA projected version (right)

可以看到,即使在这种情况下,第一个组件也足以做出决定(由于噪声,具有最小容差),将阈值设置为零可以分离数据集。我邀请读者测试其他内核的效果并应用它们,以便区分包含全 0 和全 1 的 MNIST 子集。

通过因子分析增加异方差噪声的鲁棒性

标准主成分分析的主要问题之一是这种模型在异方差噪声方面的固有弱点。如果你不熟悉这个术语,引入两个定义会很有帮助。多元去相关噪声项的特征在于对角协方差矩阵 C ,其可以具有两种不同的配置,如下所示:

  • C = diag(σ 2 ,σ 2 ,...,σ 2 ) :这种情况下,噪声定义为同态(所有分量方差相同)。
  • C = diag(σ1T3】2,σ2T7】2,...,σn2**),同σ12≠σ22...≠ σ n 2 :这种情况下,噪声定义为异方差(每个分量都有自己的方差)。

有可能证明,当噪声是同态时,主成分分析可以很容易地管理它,因为单个成分的解释方差以同样的方式受到噪声项的影响(也就是说,这相当于没有噪声)。相反,当噪声为异方差时,主成分分析的性能下降,结果可能是绝对不可接受的。为此,Rubin 和 Thayer(在 ML 因子分析的 EM 算法中,Rubin D .和 Thayer D .,mentorimetrika,47,1982)提出了一种替代的降维方法,称为因子分析,可以解决这类问题。

假设我们有一个以零为中心的数据集, X ,包含 m 样本xI∈ℜnT9】。我们的目标是找到一组潜在变量,zI∈ℜp(带 p < n )和一个矩阵, A (称为因子加载矩阵),这样每个样本都可以重写,如下所示:

因此,我们现在假设一个样本, x i 是一组高斯潜变量加上一个额外的异方差噪声项的组合。由于潜在变量的维数较低,这个问题与标准主成分分析非常相似,主要区别在于,现在我们考虑了异方差噪声(当然,术语 n 也可以为空,或同方差)。因此,当确定分量(即潜在变量)时,不同噪声方差的影响被包括在模型中,最终效果是部分滤波(去噪)。在前面提到的论文中,作者提出了一种优化算法,它在形式上并不复杂,但需要许多数学运算(为此,我们省略了任何证明)。该方法基于期望最大化 ( EM )算法,便于找到最大化对数似然的参数集。在本书中,我们不讨论所有的数学细节(可以在原始论文中找到),而是检查这种方法的属性,并将结果与标准主成分分析进行比较。

让我们从加载 Olivetti faces 数据集开始,将其置零,并创建一个异方差噪声版本,如下所示:

import numpy as np

from sklearn.datasets import fetch_olivetti_faces

faces = fetch_olivetti_faces(shuffle=True, random_state=1000)
X = faces['data']
Xz = X - np.mean(X, axis=0)

C = np.diag(np.random.uniform(0.0, 0.1, size=Xz.shape[1]))
Xnz = Xz + np.random.multivariate_normal(np.zeros(shape=Xz.shape[1]), C, size=Xz.shape[0])

下面的截图显示了一些原始且有噪声的图像:

Original images (upper line); noisy versions (lower line)

现在,让我们评估平均对数似然性(通过score()方法,在PCAFactorAnalysis类中都可用)如下:

  • 主成分分析,带有原始数据集和128组件
  • 主成分分析,带噪声数据集和128组件
  • 因子分析,含噪声数据集和128成分(潜在变量)

在下面的代码片段中,所有 3 个模型都被实例化和训练:

from sklearn.decomposition import PCA, FactorAnalysis

pca = PCA(n_components=128, random_state=1000)
pca.fit(Xz)
print('PCA log-likelihood(Xz): {}'.format(pca.score(Xz)))

pcan = PCA(n_components=128, random_state=1000)
pcan.fit(Xnz)
print('PCA log-likelihood(Xnz): {}'.format(pcan.score(Xnz)))

fa = FactorAnalysis(n_components=128, random_state=1000)
fa.fit(Xnz)
print('Factor Analysis log-likelihood(Xnz): {}'.format(fa.score(Xnz)))

上一个片段的输出如下:

PCA log-likelihood(Xz): 4657.3828125
PCA log-likelihood(Xnz): -2426.302304948351
Factor Analysis log-likelihood(Xnz): 1459.2912218162423

这些结果表明了在异方差噪声存在时因子分析的有效性。主成分分析获得的最大平均对数似然约为4657,在有噪声的情况下降至-2426。相反,因子分析获得的平均对数似然值约为 1,460,比使用主成分分析获得的对数似然值大得多(即使噪声的影响尚未完全滤除)。因此,每当数据集包含(或数据科学家怀疑它包含)异方差噪声时(例如,样本是通过不同仪器捕获的源的叠加获得的),我强烈建议将因子分析作为主要的降维方法。当然,如果需要其他条件(例如,非线性、稀疏性等),可以在做出最终决定之前评估本章中讨论的其他方法。

稀疏主成分分析和字典学习

标准 PCA 一般是密集分解;也就是说,向量一旦被变换,就是所有具有非零系数的分量的线性组合:

在前面的表达式中,系数 α i 几乎总是不同于零,因此所有的组件都参与了重建过程。出于降维的目的,这不是一个问题,因为我们对每个组件解释的方差更感兴趣,以便限制它们。然而,对于一些任务,分析更大的一组建筑原子是有帮助的,假设每个向量可以表示为它们的稀疏组合。最经典的例子是文本语料库,其中词典包含的术语比每个文档中包含的术语多得多。这种模型通常被称为字典学习算法,因为原子集合定义了一种字典,包含了所有可以用来创建新样本的单词。当原子的数量 k 大于样本的维度 n 时,字典称为过完备,表示往往比较稀疏。反之,当 k < n 时,字典称为**欠完备,**向量需要更密集。

通过对解的 L 1 范数施加惩罚,这样的学习问题可以很容易地通过函数的最小化来解决。这种约束导致稀疏的原因超出了本书的范围,但感兴趣的人可以在掌握机器学习算法, 博纳科尔索 g .**Packt Publications2018 中找到更长的讨论。

字典学习(以及稀疏主成分分析)的问题可以正式表达如下:

这是一种算法的特殊情况,其中组件 U k 被强制具有单位长度(除非有normalize_components=False参数),系数 V 被惩罚,以便增加它们的稀疏度(与系数成比例, α )。

让我们考虑 MNIST 数据集,执行 30 个分量的稀疏主成分分析(产生不完全字典)和中高稀疏度水平(例如, α = 2.0 )。数组X应该包含归一化样本,如下面的主成分分析示例所示:

from sklearn.decomposition import SparsePCA

spca = SparsePCA(n_components=30, alpha=2.0, normalize_components=True, random_state=1000)
spca.fit(X)

在训练过程结束时,components_数组包含原子,如下图所示:

Components extracted by the sparse PCA algorithm

不难理解,每个数字都可以用这些原子组成;然而,考虑到原子的数量,稀疏的数量不可能非常大。我们来考虑一下,比如数字X[0]的变换:

y = spca.transform(X[0].reshape(1, -1)).squeeze()

系数的绝对值如下图所示:

Absolute coefficients for the sparse transformation of the digit X[0]

显然有一些主导成分(例如 2、7、13、17、21、24、26、27 和 30),一些次要成分(例如 5、8 等)和一些无效或可忽略的成分(例如 1、3、6 等)。如果以相同的码长(30 个分量)增加稀疏度,则空分量对应的系数将降至零,而如果同样增加码长(例如 k = 100 ,则字典将变得过完备,空系数的数量也将增加。

非负矩阵分解

当数据集 X 为非负时,有可能应用因子分解技术,当任务的目标是提取与样本的结构部分相对应的原子时,该技术已被证明(例如在通过非负矩阵因子分解学习物体的部分,Lee D. D .,和 Seung,S. H .,Nature, 401,10/1999)更可靠。例如,在图像的情况下,它们应该是几何元素或者甚至更复杂的部分。非负矩阵分解 ( NNMF )强加的主要条件是所有涉及的矩阵必须是非负的并且 X = UV 。因此,一旦定义了一个规范 N (例如,弗罗贝尼乌斯),简单的目标就变成了以下内容:

当还需要稀疏性时,这通常是不可接受的(此外,为了允许更大的灵活性来改变解决方案以满足特定的要求),该问题通常通过在 Frobenius(对 L 2 的矩阵扩展)和 L 1 规范(例如,在 ElasticNet 中)上增加惩罚来表达(例如在 scikit-learn 中):

双重正则化通过避免类似于监督模型的过拟合的效果(由于解是次优的,它也更灵活地适应从相同的数据生成过程中提取的新样本),允许您获得样本的稀疏性和部分之间的更好匹配;这增加了通常可实现的可能性)。

现在,让我们考虑 MNIST 数据集,让我们将其分解为 50 个原子,最初设置 α = 2.0β = 0.1 (在 scikit-learn 中称为l1_ratio)。这种配置将强制中等稀疏度和强L2/弗罗贝纽斯正则化。该过程简单明了,类似于稀疏主成分分析:

from sklearn.decomposition import NMF

nmf = NMF(n_components=50, alpha=2.0, l1_ratio=0.1, random_state=1000)
nmf.fit(X)

在培训过程结束时,组件(原子)如下图所示:

Atoms extracted by the NNMF algorithm

与我们在标准词典学习中观察到的相反,原子现在的结构更加结构化,它们再现了数字的特定部分(例如,垂直或水平笔画、圆圈、点等);因此,我们可以期待更多的稀疏表示,因为更少的组件足以构建一个数字。考虑到上一节所示的例子(数字X[0],所有组件的绝对贡献如下图所示:

Absolute coefficients for the NNMF of the digit X[0]

三个成分占优势(3、24 和 45);因此,我们可以尝试将样本表示为它们的组合。系数分别为 0.19、0.18 和 0.16。结果如下截图所示(数字X[0]表示零):

Deconstruction of the digit X[0], based on three main components

有趣的是该算法是如何选择原子的。即使这个过程受到 αβ 参数的强烈影响,通过范数,我们可以观察到,例如第三个原子(截图中的第一个)可以被许多零、三、八共享;最后一个原子对 0 和 9 都有帮助。每当原子的粒度太粗时,带有较弱的 L 1 惩罚的过完备字典可能会有所帮助。当然,每个问题都需要具体的解决方案;因此,我强烈建议用领域专家来检查原子的结构。作为练习,我邀请您将 NNMF 应用于另一个小图像数据集(例如,Olivetti、Cifar-10 或 STL-10),并尝试找到隔离固定数量的结构部分所需的正确参数(例如,对于面部,它们可以是眼睛、鼻子和嘴巴)。

独立成分分析

当使用标准主成分分析(或其他技术,如因子分析)时,这些成分是不相关的,但不能保证它们在统计上是独立的。换句话说,假设我们有一个数据集, X ,从联合概率分布中得出,p(X);如果有 n 组件,我们不能总是确定以下等式成立:

然而,有许多重要的任务,基于一个叫做鸡尾酒会的常见模式。在这种情况下,我们可以假设(或者我们知道)许多不同且独立的来源(例如,声音和音乐)重叠并产生单个信号。此时,我们的目标是通过对每个样本应用线性变换来尝试分离源。让我们考虑一个白化的数据集, X (因此所有的成分都具有相同的信息内容),我们可以假设它是从高斯分布 N(0,I) 中采样的(这不是限制性条件,因为许多不同来源的重叠很容易收敛到正态分布)。因此,目标可以表达如下:

换句话说,我们将每个样本表示为多个独立因素的乘积,具有基于指数函数的先验分布。唯一必须绝对执行的条件是非高斯性(否则,组件变得不可区分);因此,函数 f k (z) 不能是二次多项式。在实践中,我们也希望包括适度的稀疏性,因此我们期望峰值和重尾分布(也就是说,概率仅在非常短的范围内很高,然后突然下降到几乎为零)。这种情况可以通过检查归一化的第四矩来验证,称为峰度:

对于高斯分布,峰度为 3。由于这通常是一个参考值,所有具有峰度(X) > 3 的分布称为超高斯或细峰度,而具有峰度(X) < 3 的分布称为亚高斯或扁峰度。前一类分布的一个例子是拉普拉斯分布,如下图所示:

Probability density functions of Gaussian distribution (left) and Laplace distribution (right)

不幸的是,峰度的使用因其相对于异常值缺乏鲁棒性而受到阻碍(也就是说,由于它涉及四次幂,即使很小的值也可以被放大并改变最终结果;例如,尾部有异常值的噪声高斯可以表现为超高斯)。为此,作者 Hyvarinen 和 Oja(在独立成分分析:算法与应用,Hyvarinen A .和 Oja,e .神经网络 13,2000)基于负熵的概念,提出了一种称为快速独立成分分析(FT6】astICAT8】)的算法。我们不打算在这本书里描述整个模型;然而,理解基本思想是有帮助的。可以证明,在所有方差相同的分布中,高斯分布的熵最大。因此,如果数据集 X (零中心)是从具有协方差的分布σ中提取的,则可以将 X 的负熵定义为高斯N(0;σ**)**X的熵:

因此,我们的目标是通过减少 H(X) 来减少 H N (X) (总是大于等于零)。FastICA 算法基于通过特定函数的组合对 H N (X) 的近似。最常见的称为 logcosh (也是 scikit-learn 中的默认值),如下所示:

有了这个技巧,负熵可以更容易地优化,最终的分解肯定包含独立的成分。现在,让我们将 FastICA 算法应用于 MNIST 数据集(为了强制更好的精度,我们正在设置max_iter=10000tol=1e-5):

from sklearn.decomposition import FastICA

ica = FastICA(n_components=50, max_iter=10000, tol=1e-5, random_state=1000)
ica.fit(X)

算法找到的 50 个独立组件(始终可通过components_实例变量获得)如下截图所示:

Independent components extracted by FastICA

在这种情况下,组件可以立即识别为数字的一部分(考虑到数据集的维度,我邀请读者通过将组件的数量减少和增加到 64 个来重复该示例,这是最大数量)。分量趋向于达到相应分布的平均位置;因此,用更少的数量,可以区分更结构化的模式(可以被认为是不同的重叠信号),而更大数量的组件导致更多以特征为中心的元素。然而,与 NNMF 相反,FastICA 并不保证提取样本的实际部分,而是提取更完整的区域。换句话说,虽然 NNMF 可以很容易地检测到,例如,一些单笔画,但快速独立分量分析倾向于将样本视为不同信号的总和,在图像的情况下,这通常涉及样本的整个维度,除非分量的数量急剧增加。为了更好地理解这个概念,让我们考虑奥利维蒂人脸数据集,它包含 400 幅 64 × 64 灰度肖像:

from sklearn.datasets import fetch_olivetti_faces

faces = fetch_olivetti_faces(shuffle=True, random_state=1000)

下面的截图显示了前 10 张脸:

Sample faces extracted from the Olivetti faces dataset

现在,让我们提取 100 个独立的组件:

ica = FastICA(n_components=100, max_iter=10000, tol=1e-5, random_state=1000)
ica.fit(faces['data'])

前 50 个组件绘制在下面的截图中:

50 (out of 100) independent components extracted by FastICA

正如你所看到的,每个组件都类似于一个元面(有时称为特征面),由于所有剩余的特征(即使它们在精确的样本集中不能立即识别),它们具有一些特定的、主要的特征以及次要的贡献。当组件数量增加到 350 时,效果变得更加明显,如下所示:

50 (out of 350) independent components extracted by FastICA

在这种情况下,次要特征不太占优势,因为有更多的重叠分布,并且它们中的每一个都集中在更原子的特征面上。当然,没有完整的领域知识,无法定义组件的最佳数量。例如,在 Olivetti 人脸数据集的情况下,识别特定的子元素(例如,眼镜的位置)或更完整的面部表情可能会有所帮助。在前一种情况下,较大数量的组件产生更集中的解决方案(即使它们在全局上不太容易区分),而在后一种情况下,较小数量的组件(如前一个示例)产生更完整的结果,在这种情况下可以评估不同的影响因素。就信号而言,分量的数量应该等于预期重叠因子的数量(假设它们是独立的)。例如,音频信号可以包含一个人在机场说话的录音,背景声音宣布航班。在这种情况下,场景可以由三个部分组成:两个声音和噪音。由于噪声将被部分分解为主要成分,最终数量将等于 2。

基于潜在狄利克雷分配的主题建模

我们现在将考虑另一种在处理文本文档时非常有用的分解(也就是 NLP)。理论部分不是很容易,因为需要很深的概率论和统计学习知识(可以在原论文潜伏狄利克雷分配,机器学习研究杂志, Blei D.Ng A.和 Jordan M. ,3,(2003)993-1022);因此,我们只讨论主要元素,没有任何数学参考(更紧凑的描述也出现在机器学习算法第二版,Bonaccorso,g ., Packt Publications ,2018)。让我们考虑一组文本文档, d j (称为语料库),其原子(或成分)是单词, w i :

收集所有单词后,我们可以建立一个字典:

我们还可以陈述以下不等式(*N()*计算一个集合的元素数):

这意味着文档之间的单词分布是稀疏的,因为单个文档中只使用了几个单词,而前者的选择是对称狄利克雷分布(模型以其命名),这是极其稀疏的(而且,它是分类分布的共轭先验,是一个一次多项式分布,所以很容易纳入模型)。概率密度函数(由于分布是对称的,参数 α i = α ∀ i )如下:

现在,让我们考虑将文档语义分组为主题, t k ,并且假设每个主题都由少量特殊单词表征:

这意味着话题之间的词语分布也是稀疏的。所以我们有全联合概率(单词、话题),我们要确定条件概率 p(w i |t k )p(tk| wI)。换句话说,给定一个文档,它是术语的集合(每个术语都有一个边际概率 p(w i ) ,我们要计算这样的文档属于特定主题的概率。由于文档被柔和地分配给所有的主题(也就是说,它可以不同程度地属于多个主题),我们需要考虑一个稀疏的主题-文档分布,从中可以得出主题-混合( θ i ):

类似地,我们需要考虑话题词分布(因为一个词可以不同程度地被更多话题分享),从中我们可以得出话题词混合样本, β j :

潜在狄利克雷分配 ( LDA )是一个生成模型(训练目标,以一种简单的方式,包括找到最优参数 αγ ),该模型能够从语料库中提取固定数量的主题,并用一组词来表征它们。给定一个样本文档,它能够通过提供主题混合概率向量( θ i = (p(t 1 )、p(t 2 )将其分配给一个主题,...,p(tk));它还可以处理看不见的文档(使用相同的字典)。

现在,让我们将 LDA 应用于 20 个新闻组数据集的一个子集,该子集包含数千条公开发布用于自然语言处理研究的消息。特别是,我们想要对rec.autoscomp.sys.mac.hardware子组进行建模。我们可以使用内置的 scikit-learn fetch_20newsgroups()功能,要求去掉所有不必要的页眉、页脚和引号(其他帖子附在答案上):

from sklearn.datasets import fetch_20newsgroups

news = fetch_20newsgroups(subset='all', categories=('rec.autos', 'comp.sys.mac.hardware'), remove=('headers', 'footers', 'quotes'), random_state=1000)

corpus = news['data']
labels = news['target']

此时,我们需要对语料库进行矢量化。换句话说,我们需要将每个文档转换成包含词汇表中每个单词的频率(计数)的稀疏向量:

我们将使用CountVectorizer类来执行这一步,要求去掉重音并删除相对频率很高但不具有代表性的终止词(例如,英语中的 and、the 等)。此外,我们正在强制标记器排除所有非纯文本的标记(通过设置token_pattern='[a-z]+')。在其他情况下,这种模式可能会有所不同,但在这种情况下,我们不想依赖数字和符号:

from sklearn.feature_extraction.text import CountVectorizer

cv = CountVectorizer(strip_accents='unicode', stop_words='english', analyzer='word', token_pattern='[a-z]+')
Xc = cv.fit_transform(corpus)

print(len(cv.vocabulary_))

上一个片段的输出如下:

14182

因此,每个文档都是一个 14,182 维的稀疏向量(很明显,大多数值都是空的)。我们现在可以通过强加n_components=2来执行 LDA,因为我们期望提取两个主题:

from sklearn.decomposition import LatentDirichletAllocation

lda = LatentDirichletAllocation(n_components=2, learning_method='online', max_iter=100, random_state=1000)
Xl = lda.fit_transform(Xc)

训练过程结束后,components_实例变量包含每对(单词和话题)的相对频率(以计数表示)。因此,在我们的例子中,它的形状是(2,14,182),而components_[i, j]元素,用 i ∈ (0,1)j ∈ (0,14,181) ,可以解释为这个词的重要性, j ,为了定义这个话题, i 。因此,我们将有兴趣检查,例如,这两个主题的前 10 个单词:

import numpy as np

Mwts_lda = np.argsort(lda.components_, axis=1)[::-1]

for t in range(2):
    print('\nTopic ' + str(t))
    for i in range(10):
        print(cv.get_feature_names()[Mwts_lda[t, i]])

输出如下:

Topic 0
compresion
progress
deliberate
dependency
preemptive
wv
nmsu
bpp
coexist
logically

Topic 1
argues
compromising
overtorque
moly
forbid
cautioned
sauber
explosion
eventual
agressive

很容易(考虑到一些非常特殊的术语)理解Topic 0被分配给comp.sys.mac.hardware,另一个被分配给rec.autos(不幸的是,这个过程不能基于自动检测,因为语义必须由人类来解释)。为了评估模型,让我们考虑两个示例消息,如下所示:

print(corpus[100])
print(corpus[200])

输出限于几行,如下所示:

I'm trying to find some information on accelerator boards for the SE. Has
anyone used any in the past, especially those from Extreme Systems, Novy or
MacProducts? I'm looking for a board that will support extended video,
especially Radius's two-page monitor. Has anyone used Connectix Virtual in
conjunction with their board? Any software snafus? Are there any stats
anywhere on the speed difference between a board with an FPU and one
without? Please send mail directly to me. Thanks.

...

The new Cruisers DO NOT have independent suspension in the front.  They
still
run a straight axle, but with coils.  The 4Runner is the one with
independent
front.  The Cruisers have incredible wheel travel with this system. 

The 91-up Cruiser does have full time 4WD, but the center diff locks in
low range.  My brother has a 91 and is an incredibly sturdy vehicle which
has done all the 4+ trails in Moab without a tow.  The 93 and later is even
better with the bigger engine and locking diffs.

所以第一个帖子明显和图形有关,第二个是政治信息。让我们计算两者的主题混合,如下所示:

print(Xl[100])
print(Xl[200])

输出如下:

[0.98512538 0.01487462]
[0.01528335 0.98471665]

因此,第一条消息属于Topic 0的概率约为 98%,而第二条消息几乎不属于Topic 1。这证实了分解工作正常。为了更好地了解总体分布情况,将属于每个类别的消息的混合可视化将会很有帮助,如下图所示:

Topic-mixtures for comp.sys.mac.hardware (left) and rec.autos (right)

如你所见,主题几乎是正交的。属于rec.autos的大部分消息都有 p(t 0 ) < 0.5p(t 1 ) > 0.5 ,而comp.sys.mac.hardware有轻微的重叠,其中没有p(t0)>0.5p(t 1】的消息组这可能是因为存在可以将两个主题限定为同等重要性的词语(例如,术语讨论辩论可以同等地出现在两个新闻组中)。作为练习,我邀请您使用更多子集,并尝试证明主题的正交性,并检测可能导致不正确作业的单词。

摘要

在这一章中,我们介绍了可用于降维和字典学习的不同技术。主成分分析是一种非常众所周知的方法,它涉及找到与方差较大的方向相关联的数据集的最重要的组成部分。这种方法具有对角化协方差矩阵和提供每个特征重要性的直接度量的双重效果,从而简化选择并最大化残差解释方差(可以用较少数量的分量解释的方差量)。由于主成分分析本质上是一种线性方法,它不能经常用于非线性数据集。为此,开发了一个基于内核的变体。在我们的例子中,您看到了径向基函数核如何能够将非线性可分数据集投影到子空间上,其中主成分分析可以确定判别分量。

稀疏主成分分析和字典学习是广泛使用的技术,当需要提取可以混合(线性组合)的建筑原子以产生样本时使用。在许多情况下,目标是找到一个所谓的过完备字典,这相当于说我们期望比实际用于构建每个样本的原子多得多的原子(这就是为什么表示是稀疏的)。虽然主成分分析可以提取不相关的成分,但它很少找不到统计独立的成分。为此,我们引入了独立分量分析的概念,这是一种为了从样本中提取重叠源而开发的技术,这些样本可以被认为是独立原因(例如,声音或视觉元素)的总和。另一种具有特殊特征的方法是 NNMF,它可以产生稀疏表示和一组类似于样本特定部分的成分(例如,对于一张脸,它们可以代表眼睛、鼻子等)。最后一节介绍了 LDA 的概念,LDA 是一种主题建模技术,在给定一个文档语料库(即一个文档属于每个特定主题的概率)的情况下,可以用来找到主题混合。

在下一章中,我们将介绍一些基于无监督范式的神经模型。具体来说,将讨论深度信念网络、自动编码器和无需协方差矩阵的特征分解(nor SVD)就能提取数据集主成分的模型。

问题

  1. 数据集 X 有一个协方差矩阵 C=diag(2,1) 。你对 PCA 有什么期待?
  2. 考虑到前面的问题,如果 X 以零为中心,球 B 0.5 (0,0) 为空,我们能假设 x = 0 (第一主成分)的阈值允许水平判别吗?
  3. 主成分分析提取的成分在统计上是独立的。这是正确的吗?
  4. 一个 Kurt(X) = 5 的分布适合 ICA。这是正确的吗?
  5. 包含样本( 1,2 )和( 0,-3 )的数据集 X 的 NNMF 是什么?
  6. 一个包含 10 个文档的语料库与一个包含 10 个术语的词典相关联。我们知道每份文件的固定长度是 30 个字。字典是不是太全了?
  7. 核主成分分析采用二次核。如果原始维数为 2,那么进行 PCA 的新空间的维数是多少?

进一步阅读

  • 稀疏编码在线词典学习,J. MairalF .巴赫J. Ponce和 G. Sapiro ,2009
  • 通过非负矩阵分解学习物体的各个部分李德德承宪自然,401,10/1999
  • 用于 ML 因子分析的 EM 算法鲁宾 D.和泰尔 D.心理测量学卡,47,1982
  • 独立成分分析:算法和应用海瓦里宁和欧嘉神经网络 13,2000
  • 信息论的数学基础钦钦人工智能多佛出版物
  • 潜在狄利克雷分配,机器学习研究杂志布莱 D.Ng A.和乔丹 M. ,3,(2003) 993-1022
  • 机器学习算法第二版博纳科索格帕克特出版,2018
  • 掌握机器学习算法博纳科索格帕克特出版,2018
1
https://gitee.com/OpenDocCN/apachecn-ml-zh.git
git@gitee.com:OpenDocCN/apachecn-ml-zh.git
OpenDocCN
apachecn-ml-zh
apachecn-ml-zh
master

搜索帮助