6.6. 随机投影#
sklearn.random_projection
模块实现了一种简单且计算效率高的降低数据维度的方法,它以可控的精度损失(作为额外方差)换取更快的处理速度和更小的模型大小。该模块实现了两种类型的非结构化随机矩阵:高斯随机矩阵 和 稀疏随机矩阵。
随机投影矩阵的维度和分布经过控制,以保持数据集任意两个样本之间的成对距离。因此,随机投影是基于距离的方法的合适近似技术。
参考文献
Sanjoy Dasgupta. 2000. Experiments with random projection. 在第十六届人工智能不确定性会议论文集 (UAI’00) 中,Craig Boutilier 和 Moisés Goldszmidt (Eds.)。Morgan Kaufmann Publishers Inc.,美国加利福尼亚州旧金山,143-151。
Ella Bingham 和 Heikki Mannila. 2001. Random projection in dimensionality reduction: applications to image and text data. 在第七届 ACM SIGKDD 国际知识发现和数据挖掘会议论文集 (KDD ‘01) 中。ACM,美国纽约州纽约市,245-250。
6.6.1. Johnson-Lindenstrauss 引理#
随机投影效率背后的主要理论结果是 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])
示例
参见 使用随机投影进行嵌入的 Johnson-Lindenstrauss 界限,了解关于 Johnson-Lindenstrauss 引理的理论解释以及使用稀疏随机矩阵的经验验证。
参考文献
Sanjoy Dasgupta 和 Anupam Gupta,1999。 An elementary proof of the Johnson-Lindenstrauss Lemma.
6.6.2. 高斯随机投影#
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. 稀疏随机投影#
SparseRandomProjection
使用稀疏随机矩阵来降低维度,将原始输入空间投影。
稀疏随机矩阵是密集高斯随机投影矩阵的替代方案,它保证了类似的嵌入质量,同时更节省内存,并允许更快地计算投影数据。
如果我们定义 s = 1 / density
,则随机矩阵的元素从以下分布中抽取:
其中,\(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)
参考文献
D. Achlioptas. 2003. Database-friendly random projections: Johnson-Lindenstrauss with binary coins. Journal of Computer and System Sciences 66 (2003) 671-687。
Ping Li, Trevor J. Hastie 和 Kenneth W. Church. 2006. Very sparse random projections. Proceedings of the 12th ACM SIGKDD international conference on Knowledge discovery and data mining (KDD ‘06). ACM, New York, NY, USA, 287-296。
6.6.4. 逆变换#
随机投影变换器具有 compute_inverse_components
参数。当设置为 True 时,在拟合过程中创建随机 components_
矩阵后,变换器会计算该矩阵的伪逆,并将其存储为 inverse_components_
。 inverse_components_
矩阵的形状为 \(n_{features} \times n_{components}\),并且它始终是一个稠密矩阵,无论 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