首页 > 编程知识 正文

python安装scipy,稳定双共轭梯度法

时间:2023-05-05 19:01:28 阅读:161803 作者:4404

使用scipy和numpy进行数据计算时,感觉运行速度很慢,但程序已经到了使用内积运算的地步,所以真的不知道该如何优化。 如果能优化内积运算就好了,如果能朝着这个目标,写文章盘点各种内积优化方法的话,我想也能贡献出自己的绵薄之力。

开头写两点自己的经验,抛砖引玉,等待大家的意见。 因为自己对Scipy和Numpy不熟悉,所以有不正确的地方。 另外,请多多修改。

在说我的优化之前,首先,scipy.sparse的矩阵包中,牵扯到矩阵运算,矩阵的格式优选csr_matrix和csc_matrix否则一定很慢你会怀疑人生。

特别说明1本文的实验在ipython或jupyter环境下进行,时间消耗测试使用“%timeit”命令,Scipy版本为“0.19.1”。

特别说明2程序中,由于向list稀疏矩阵的变换、矩阵的变换、矩阵的连接和矩阵的更新等很多非计算操作都有内存操作,时间成本相当高,可以提前处理,所以在测量时间消耗时,他们在性能优化中,减少内存操作和减少CPU命令数量这两个原则很重要。 详情请参阅《Python高性能编程》第六章。

特别说明3如果你是计算专业的学生,请学好《计算机架构导论》、《操作系统》、《数据结构》、《离散数学》、0103010。 前两本书在硬件和操作系统级别上了解了编程语言的特性,结合相关书籍,可以立即了解为什么会变快,为什么会变慢,为什么某些语言样式会变快,以及为什么会变慢后二本教你如何优化你的算法。 例如,现在从山北到山南,可以从北麓登上山顶再去南山脚,也可以绕着山跑,从北麓去南山脚。 当然,这些书起到作用的,不仅如此,还有科学班生和培训班生的区别。 计算机编程不是学习几种编程语言和数据结构那么简单。

一、大小矩阵内积运算当两个规模相同的矩阵为内积时,选择CSC和CSR相差不大,时间效应相同。 但是将当为一大一小矩阵时,就有一些技巧,可以节约时间b作为大矩阵,将s作为小矩阵。

CSR形式的情况下,SB的速度快,与BS相比节约了一半的时间。 在CSC形式的情况下,BS的速度更快,与SB相比可以节约一半的时间。

上述两种方法,时间相近,不分伯仲之间。 以下是我的计算示例。

import scipy.sparseasspdefis _ CSR _ instance (MTX ) :ifisinstance ) MTX, sp.CSR _ matrix (: returntrueelse : returnfalsedefis _ CSC _ instance (MTX ) :ifisinstance ) MTX, sp.CSC _ matrix (: returntrueelse : returnfalsea _ MTX=sp.CSC _ matrix ([1.1 .3.]*120] ) MTX=0 is_CSR_instance(MTX_t ) printu 'n (ncsclittlebig ' print type (a _ MTX ),type ) MTX_t ) printa_MTX nsr littlebig ' a_MTX_r=a _ MTX.tocsr () mtx_T_r=mtx_T.tocsr ) )打印类型) a _ MTX _ r ), typ PPS MTX _ t _ r.shape % timeitc=a _ MTX _ r.dot (MTX _ t _ r ) a _ MTX _ t=a _ MTX.ta _ MTX _ t=a _ a ncsrbiglittle ' MTX=MTX.tocsr (a _ MTX _ t=a _ MTX _ t.tocsr ) (printtype ) MTX ),type ) a _ MTX )

CSC littlebig class ' scipy.sparse.CSC.CSC _ matrix ' class ' scipy.sparse.CSC.CSC _ m

atrix'>(1, 360) (360, 30000)100 loops, best of 3: 17.4 ms per loopcsr little×big<class 'scipy.sparse.csr.csr_matrix'> <class 'scipy.sparse.csr.csr_matrix'>(1, 360) (360, 30000)100 loops, best of 3: 8.13 ms per loopcsc big×little<class 'scipy.sparse.csc.csc_matrix'> <class 'scipy.sparse.csc.csc_matrix'>(30000, 360) (360, 1)100 loops, best of 3: 8.31 ms per loopcsr big×little<class 'scipy.sparse.csr.csr_matrix'> <class 'scipy.sparse.csr.csr_matrix'>(30000, 360) (360, 1)100 loops, best of 3: 17.6 ms per loop 二 多矩阵内积优化

不好意思,这条优化有时有效有时无效,所以暂时不要完全相信,欢迎各位对此条多提意见。

当有多个矩阵进行内积计算时,可以通过矩阵拼接将多次内积计算合并为一次节约时间。时间优化效果与矩阵的中需要计算的非零数据次数成反比,需要计算的次数越多,节约的时间越少。假设稀疏矩阵中,非零元素随机出现,那么需要计算的非零数据次数非常少,所以有近似结论:矩阵越稀疏,需要计算的非零数据越少,节约的时间越多。矩阵稠密度是非零元素个数与矩阵总元素数的比值。

本实验有两个组,对照组为一个1×N与一个M×N的矩阵做四次内积,实验组为一个1×4N的矩阵与一个M×4N的矩阵做一次内积。实验分3次:例1,例2和例3:

例1中,两个矩阵稠密度为100%,对照组时间消耗略高。例2中,两个矩阵稠密度为33.34%,对照组时间较高。例3中,两个矩阵稠密度分别为16.7%和8.3%,对照组时间消耗明显很高。

实验公共代码

import scipy.sparse as spdef quadra_dot(a_mtx, b_mtx): a = a_mtx * b_mtx b = a_mtx * b_mtx c = a_mtx * b_mtx d = a_mtx * b_mtx def uni_dot(a_mtx, b_mtx): a = a_mtx * b_mtxdef density(mtx): non_zeros_numbers = len(mtx.data) * 1.0 m, n = mtx.shape print non_zeros_numbers / (wzdjz) 例1 a_mtx = sp.csr_matrix([[2.23, 1.56, 3.47]*120]*300)mtx = sp.csr_matrix([[1.07, 2.19, 3.12]*120]*30000)print(u"对照组:")b_mtx = mtx.Tb_mtx = b_mtx.tocsr()print type(a_mtx), type(b_mtx), a_mtx.shape, b_mtx.shape# 测试时间消耗%timeit quadra_dot(a_mtx, b_mtx)print(u"实验组:")c_mtx = sp.vstack((b_mtx, b_mtx))c_mtx = sp.vstack((c_mtx, b_mtx))c_mtx = sp.vstack((c_mtx, b_mtx))a_mtx = sp.hstack((a_mtx, a_mtx))a_mtx = sp.hstack((a_mtx, a_mtx))c_mtx = c_mtx.tocsr()a_mtx = a_mtx.tocsr()print type(a_mtx), type(c_mtx), a_mtx.shape, c_mtx.shape%timeit uni_dot(a_mtx, c_mtx)

例1输出:

对照组:<class 'scipy.sparse.csr.csr_matrix'> <class 'scipy.sparse.csr.csr_matrix'> (300, 360) (360, 30000)1 loop, best of 3: 29.8 s per loop实验组:<class 'scipy.sparse.csr.csr_matrix'> <class 'scipy.sparse.csr.csr_matrix'> (300, 1440) (1440, 30000)1 loop, best of 3: 28 s per loop 例2 a_mtx = sp.csr_matrix([[2.23, 1.56, 3.47]*120]*300)mtx = sp.csr_matrix([[1.07, 2.19, 3.12]*120]*30000)density(a_mtx)density(mtx)# 代码与例1的对应部分相同,不在重复...

例2输出:

density 0.3333density 0.3333对照组:<class 'scipy.sparse.csr.csr_matrix'> <class 'scipy.sparse.csr.csr_matrix'> (300, 360) (360, 30000)1 loop, best of 3: 9.06 s per loop实验组:<class 'scipy.sparse.csr.csr_matrix'> <class 'scipy.sparse.csr.csr_matrix'> (300, 1440) (1440, 30000)1 loop, best of 3: 8.85 s per loop 例3 a_mtx = sp.csr_matrix([[0., 0., 0., 0., 13.23, 0., 0., 0., 1.32, 0., 0., 0., 0., 0., 0., 0., 13.23, 0., 0., 0., 1.32, 0., 0., 0.]*5]*300)mtx = sp.csr_matrix([[1.07, 0., 0., 0., 1.30, 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0.0, 0., 0., 0.]*5]*30000)density(a_mtx)density(mtx)# 代码与例1的对应部分相同,不在重复...

例2输出:

density 0.166666density 0.083333对照组:<class 'scipy.sparse.csr.csr_matrix'> <class 'scipy.sparse.csr.csr_matrix'> (300, 120) (120, 30000)1 loop, best of 3: 559 ms per loop实验组:<class 'scipy.sparse.csr.csr_matrix'> <class 'scipy.sparse.csr.csr_matrix'> (300, 480) (480, 30000)1 loop, best of 3: 374 ms per loop 三 稀疏矩阵归一化和转置,不会影响矩阵计算性能

相同格式的稀疏矩阵做点乘速度很快,不同格式速度仅仅慢一丢丢。比如归一化和转置之后, 不转格式不会影响速度.

某些情况下在点乘计算前,需要进行归一化操作,比如计算cosine相似度,需要对两个稀疏矩阵分别做行归一化和列归一化,或者转置。在进行归一化或者转置后,矩阵的格式可能会发生改变.

这里使用的是sklearn.preprocessing.normalize函数进行归一化的。对于稀疏矩阵,行归一化的返回值是CSR矩阵,列归一化的返回值是CSC矩阵(实验结果见下面代码);之所以这么这么做,是为了提高计算速度,同时也降低计算难度,sklearn的做法是:如果是sparse矩阵,当是行归一化时,就将原始矩阵转为CSR格式,这样就可以对矩阵的data(data是sparse.csr_matrix的一个属性)中的每行的元素,进行快速归一化。当列归一化时,转为CSC矩阵,然后对data中的列元素进行快速归一化。如果你不明白为什么如此操作的好处,请参看稀疏矩阵压缩原理。

转置操作输入CSR矩阵返回CSC矩,阵输入CSC矩阵返回CSR矩阵。至于转置为何也会改变矩阵格式,答案也是速度快,编码简单,为什么呢?自己动手计算一下吧。

版权声明:该文观点仅代表作者本人。处理文章:请发送邮件至 三1五14八八95#扣扣.com 举报,一经查实,本站将立刻删除。