我有大量数据(大约 8GB)。我想用机器学习来分析它。所以,我认为我应该使用 SVD 然后 PCA 来降低数据维度以提高效率。但是,MATLAB 和 Octave 无法加载如此大的数据集。
我可以使用哪些工具对如此大量的数据进行 SVD?
我有大量数据(大约 8GB)。我想用机器学习来分析它。所以,我认为我应该使用 SVD 然后 PCA 来降低数据维度以提高效率。但是,MATLAB 和 Octave 无法加载如此大的数据集。
我可以使用哪些工具对如此大量的数据进行 SVD?
首先,当您有许多协变维度并希望通过将数据点旋转到新的正交基并仅采用具有最大方差的轴来减小问题大小时,会使用降维。使用 8 个变量(列),您的空间已经是低维的,进一步减少变量数量不太可能解决内存大小的技术问题,但可能会严重影响数据集质量。在您的具体情况下,看看在线学习更有希望方法。粗略地说,这些方法不是使用整个数据集,而是一次取一小部分(通常称为“小批量”)并逐步构建模型。(我个人喜欢将“在线”一词解释为对来自互联网的一些无限长的数据源的引用,例如 Twitter 提要,您无法一次加载整个数据集)。
但是,如果您真的想将像 PCA 这样的降维技术应用于不适合内存的数据集怎么办?通常,数据集表示为大小为n x m的数据矩阵X,其中n是观察数(行),m是变量数(列)。通常,内存问题仅来自这两个数字之一。
当观测值过多,但变量的数量从小到中时,可以增量构建协方差矩阵。实际上,典型的 PCA 包括构建大小为m x m的协方差矩阵并对其应用奇异值分解。对于m =1000 个 float64 类型的变量,协方差矩阵的大小为 1000*1000*8 ~ 8Mb,它很容易放入内存中,并且可以与 SVD 一起使用。因此,您只需要构建协方差矩阵,而无需将整个数据集加载到内存中——这很容易完成任务。
或者,您可以从数据集中选择一个小的代表性样本并近似协方差矩阵。该矩阵将具有与正常矩阵相同的所有属性,只是准确性稍差一些。
另一方面,有时,当您有太多变量时,协方差矩阵本身将不适合内存。例如,如果您使用 640x480 图像,则每个观察值都有 640*480=307200 个变量,这会产生一个 703Gb 的协方差矩阵!这绝对不是您希望保留在计算机内存中的内容,甚至不是您希望保留在集群内存中的内容。所以我们需要在根本不建立协方差矩阵的情况下减少维度。
我最喜欢的方法是Random Projection。简而言之,如果您有大小为n x m的数据集X,您可以将其乘以大小为m x k的一些稀疏随机矩阵R(其中k << m ),并获得尺寸小得多的新矩阵X' n x k具有与原始属性大致相同的属性。为什么它有效?好吧,您应该知道 PCA 旨在找到一组正交轴(主成分)并将您的数据投影到第一个k其中。事实证明,稀疏随机向量几乎是正交的,因此也可以用作新的基础。
而且,当然,您不必将整个数据集X乘以R - 您可以将每个观察x单独或以小批量转换为新的基础。
还有一些类似的算法称为Random SVD。我对此没有任何实际经验,但您可以在此处找到带有解释的示例代码。
作为底线,这里有一个关于大数据集降维的简短清单:
不要打扰。
编程的第一条规则——这也适用于数据科学:让所有东西都解决一个小测试问题。
所以对你的数据进行随机抽样,比如 100,000 行。尝试不同的算法等。一旦您对所有工作都满意,您可以尝试更大(和更大)的数据集 - 并查看随着添加更多数据而测试错误如何减少。
此外,您不想仅将 svd 应用于 8 列:当您有很多列时应用它。
PCA 通常通过在协方差矩阵上计算 SVD 来实现。
计算协方差矩阵是一个令人尴尬的并行任务,因此它与记录数量成线性关系,并且在多台机器上分布是微不足道的!
只需对您的数据进行一次传递即可计算均值。然后第二遍计算协方差矩阵。这可以通过 map-reduce 轻松完成 - 本质上它与再次计算均值相同。协方差中的总和项对于并行化来说是微不足道的!在对许多类似大小的值求和时,您可能只需要注意数字。
当您有大量变量时,情况会有所不同。但在 8 GB 系统上,您应该能够使用 BLAS 库在内存中运行多达 20.000 维的 PCA。但是随后您可能会遇到 PCA 不再那么可靠的问题,因为它具有太多的自由度。换句话说:它很容易过拟合。我已经看到了至少有 10*d*d 记录(或者是 d^3)的建议。因此,对于 10000 个维度,您应该至少有 10 亿条记录(10000 个维度......这是很多!),以使结果在统计上可靠。
尽管您可能会找到一些可以让您在单台机器上执行此操作的工具,但您已经进入了考虑像 Spark 这样的“大数据”工具的范围,特别是如果您认为您的数据集可能会增长。Spark 有一个名为 MLlib 的组件,它支持 PCA 和 SVD。该文档有示例。