在Sklearn中使用稀疏矩阵会使算法变慢还是变快?



我有一个大而稀疏的训练数据。我想使用它与extratreecclassifier。考虑到计算时间,我不确定是否需要使用稀疏的csr_matrix或原始数据。使用该分类器,哪个版本的数据运行得更快?我们能否将其答案推广到所有具有稀疏能力的模型?

如果您的数据是稀疏的,那么额外的树分类器使用csc_matrix会更快。如果有疑问,我建议您对两个版本都进行基准测试。

如果你的数据足够稀疏,所有的算法都应该从使用适当的稀疏格式中受益。例如,基于点积的算法在处理稀疏数据时会快得多。

取决于你的数据

内存消耗。

如果你的数据是密集的,密集的表示需要d*sizeof(double)字节的数据(即通常是d * 8字节)。稀疏表示通常需要sparsity*d*(sizeof(int)+sizeof(double))。根据您的编程语言和代码质量,由于内存管理开销,它也可能更多。典型的Java实现增加了8字节的开销,并且将四舍五入到8字节的大小;因此稀疏向量可以很容易地使用16 + sparsity * d * 24字节。然后。

如果稀疏性为1,这意味着稀疏表示需要50% 以上的内存。我猜在实践中的内存权衡将是大约50%的稀疏性;如果你的实现没有仔细优化,甚至可能是30%——所以3个值中有1个应该是零。

内存消耗通常是个关键问题。你使用的内存越多,你的CPU就会有越多的页面错误和缓存丢失,这可能会对性能产生很大的影响(这就是为什么例如BLAS在为你的CPU缓存优化的块大小中执行大型矩阵乘法)。

优化和SIMD.

密集向量代码(例如BLAS)通常比稀疏操作优化得更好。特别是SIMD(单指令,多数据)CPU指令通常只能处理密集的数据。随机访问

许多算法可能需要随机访问向量。如果您的数据表示为double[]数组,则随机访问是O(1)。如果你的数据是一个稀疏向量,随机访问通常是O(sparsity*d),也就是说,你必须扫描向量来检查是否存在一个值。因此,对于某些操作,将矩阵转置可能是有益的,并且使用稀疏列而不是稀疏行。

另一方面,一些算法可能会从中受益。但是许多实现都内置了这样的优化,并且会自动处理这个问题。有时你也有不同的选择。例如,APRIORI处理行,因此可以很好地处理行稀疏数据。另一方面,Eclat是解决相同问题的算法,但它首先将所有数据转换为行稀疏形式,然后甚至计算列差异以进一步优化。

代码复杂性。

处理稀疏数据的代码通常要复杂得多。特别是,它不能很容易地利用SSE和类似的快速CPU指令。这就是为什么稀疏矩阵乘法比密集操作慢得多的原因之一——在不知道数据的某些特征的情况下优化这些操作是非常困难的。: - (

相关内容

  • 没有找到相关文章

最新更新