6.6. 随机投影#

sklearn.random_projection 模块实现了一种简单且计算效率高的方式,通过以可控的精度(作为额外方差)为代价来减少数据的维数,从而实现更快的处理时间和更小的模型尺寸。该模块实现了两种类型的非结构化随机矩阵:高斯随机矩阵稀疏随机矩阵.

随机投影矩阵的维数和分布经过控制,以便保留数据集任意两个样本之间的成对距离。因此,随机投影是基于距离的方法的合适近似技术。

参考文献

  • Sanjoy Dasgupta. 2000. 随机投影实验。 在第十六届人工智能不确定性会议(UAI’00)论文集,Craig Boutilier 和 Moisés Goldszmidt(编辑)。Morgan Kaufmann 出版社,旧金山,加利福尼亚州,美国,143-151。

  • Ella Bingham 和 Heikki Mannila. 2001. 降维中的随机投影:在图像和文本数据中的应用。 在第七届 ACM SIGKDD 国际知识发现与数据挖掘会议(KDD ‘01)论文集。ACM,纽约,纽约,美国,245-250。

6.6.1. Johnson-Lindenstrauss 引理#

随机投影效率背后的主要理论结果是 Johnson-Lindenstrauss 引理(引用维基百科)

在数学中,约翰逊-林德斯特罗姆引理是一个关于将高维空间中的点嵌入到低维欧几里得空间中的低失真嵌入的结果。该引理指出,高维空间中的一小部分点可以嵌入到一个低得多的维度的空间中,以至于点之间的距离几乎保持不变。用于嵌入的映射至少是 Lipschitz 的,甚至可以取为正交投影。

仅知道样本数量,johnson_lindenstrauss_min_dim 保守地估计随机子空间的最小尺寸,以保证随机投影引入的有限失真。

>>> from sklearn.random_projection import johnson_lindenstrauss_min_dim
>>> johnson_lindenstrauss_min_dim(n_samples=1e6, eps=0.5)
663
>>> johnson_lindenstrauss_min_dim(n_samples=1e6, eps=[0.5, 0.1, 0.01])
array([    663,   11841, 1112658])
>>> johnson_lindenstrauss_min_dim(n_samples=[1e4, 1e5, 1e6], eps=0.1)
array([ 7894,  9868, 11841])
../_images/sphx_glr_plot_johnson_lindenstrauss_bound_001.png
../_images/sphx_glr_plot_johnson_lindenstrauss_bound_002.png

示例

参考文献

6.6.2. 高斯随机投影#

The GaussianRandomProjection 通过将原始输入空间投影到一个随机生成的矩阵上,将维度降低,该矩阵的组件是从以下分布中抽取的 \(N(0, \frac{1}{n_{components}})\).

以下是一段简短的代码片段,说明如何使用高斯随机投影变换器。

>>> import numpy as np
>>> from sklearn import random_projection
>>> X = np.random.rand(100, 10000)
>>> transformer = random_projection.GaussianRandomProjection()
>>> X_new = transformer.fit_transform(X)
>>> X_new.shape
(100, 3947)

6.6.3. 稀疏随机投影#

The SparseRandomProjection 通过使用稀疏随机矩阵将原始输入空间投影到一个随机生成的矩阵上,将维度降低。

稀疏随机矩阵是密集高斯随机投影矩阵的替代方案,它保证了类似的嵌入质量,同时更节省内存,并允许更快地计算投影数据。

如果我们定义 s = 1 / density,则随机矩阵的元素从以下分布中抽取

\[\begin{split}\left\{ \begin{array}{c c l} -\sqrt{\frac{s}{n_{\text{components}}}} & & 1 / 2s\\ 0 &\text{with probability} & 1 - 1 / s \\ +\sqrt{\frac{s}{n_{\text{components}}}} & & 1 / 2s\\ \end{array} \right.\end{split}\]

其中 \(n_{\text{components}}\) 是投影子空间的大小。默认情况下,非零元素的密度设置为 Ping Li 等人推荐的最小密度:\(1 / \sqrt{n_{\text{features}}}\).

以下是一段简短的代码片段,说明如何使用稀疏随机投影变换器。

>>> import numpy as np
>>> from sklearn import random_projection
>>> X = np.random.rand(100, 10000)
>>> transformer = random_projection.SparseRandomProjection()
>>> X_new = transformer.fit_transform(X)
>>> X_new.shape
(100, 3947)

参考文献

6.6.4. 逆变换#

随机投影变换器具有 compute_inverse_components 参数。当设置为 True 时,在拟合过程中创建随机 components_ 矩阵后,变换器计算该矩阵的伪逆并将其存储为 inverse_components_。The inverse_components_ 矩阵的形状为 \(n_{features} \times n_{components}\),并且始终是密集矩阵,无论组件矩阵是稀疏还是密集。因此,根据特征和组件的数量,它可能会使用大量内存。

当调用 inverse_transform 方法时,它计算输入 X 与逆组件转置的乘积。如果在拟合过程中计算了逆组件,则它们会在每次调用 inverse_transform 时被重复使用。否则,它们会在每次调用时重新计算,这可能很昂贵。结果始终是密集的,即使 X 是稀疏的。

以下是一段简短的代码示例,说明如何使用逆变换功能。

>>> import numpy as np
>>> from sklearn.random_projection import SparseRandomProjection
>>> X = np.random.rand(100, 10000)
>>> transformer = SparseRandomProjection(
...   compute_inverse_components=True
... )
...
>>> X_new = transformer.fit_transform(X)
>>> X_new.shape
(100, 3947)
>>> X_new_inversed = transformer.inverse_transform(X_new)
>>> X_new_inversed.shape
(100, 10000)
>>> X_new_again = transformer.transform(X_new_inversed)
>>> np.allclose(X_new, X_new_again)
True