![]() |
1
2
弯腰是最快的! 我在上面的代码和我在comp上找到的版本上做了一些测试,有关结果和代码,请参见下面的内容: pearson 14.7597990757 sim_pearson 15.6806837987 scipy:pearsonr 0.451986019188 try: import psyco psyco.full() except ImportError: pass from math import sqrt def sim_pearson(set1, set2): si={} for item in set1: if item in set2: si[item] = 1 #number of elements n = len(si) #if none common, return 0 similarity if n == 0: return 0 #add up all the preferences sum1 = sum([set1[item] for item in si]) sum2 = sum([set2[item] for item in si]) #sum up the squares sum_sq1 = sum([pow(set1[item], 2) for item in si]) sum_sq2 = sum([pow(set2[item], 2) for item in si]) #sum up the products sum_p = sum([set1[item] * set2[item] for item in si]) nom = sum_p - ((sum1 * sum2) / n ) den = sqrt( (sum_sq1 - (sum1)**2 / n) * (sum_sq2 - (sum2)**2 / n) ) if den==0: return 0 return nom/den # from http://stackoverflow.com/questions/1307016/pearson-similarity-score-how-can-i-optimise-this-further def pearson(v1, v2): vs = [(v1[val],v2[val]) for val in v1 if val in v2] n = len(vs) if n==0: return 0.0 sum1,sum2,sum1_sq,sum2_sq,p_sum = 0.0, 0.0, 0.0, 0.0, 0.0 for v1,v2 in vs: sum1+=v1 sum2+=v2 sum1_sq+=v1*v1 sum2_sq+=v2*v2 p_sum+=v1*v2 # Calculate Pearson score num = p_sum-(sum1*sum2/n) temp = max((sum1_sq-pow(sum1,2)/n) * (sum2_sq-pow(sum2,2)/n),0) if temp: return num / sqrt(temp) return 1.0 if __name__ == "__main__": import timeit tsetup = """ from random import randrange from __main__ import pearson, sim_pearson from scipy.stats import pearsonr v1 = [randrange(0,1000) for x in range(1000)] v2 = [randrange(0,1000) for x in range(1000)] #gc.enable() """ t1 = timeit.Timer(stmt="pearson(v1,v2)", setup=tsetup) t2 = timeit.Timer(stmt="sim_pearson(v1,v2)", setup=tsetup) t3 = timeit.Timer(stmt="pearsonr(v1,v2)", setup=tsetup) tt = 1000 print 'pearson', t1.timeit(tt) print 'sim_pearson', t2.timeit(tt) print 'scipy:pearsonr', t3.timeit(tt) |
![]() |
2
4
真正的速度增加将通过移动到麻木或坐骨神经痛。除此之外,还有一些微优化:例如
类似的东西
然后
等等,这些是否都能带来时间优势,都需要微基准。根据你是如何使用这些返回平方的系数,可以节省一个sqrt(这类似于在几何中使用点之间距离的平方,而不是距离本身,并且出于同样的原因——可以节省一个sqrt;这很有意义,因为系数是一个距离,有点…;-)。 |
![]() |
3
2
如果可以使用scipy,可以使用皮尔逊函数: http://www.scipy.org/doc/api_docs/SciPy.stats.stats.html#pearsonr
或者您可以从中复制/粘贴代码(它具有自由许可证)
http://svn.scipy.org/svn/scipy/trunk/scipy/stats/stats.py
(寻找)
|
![]() |
4
1
我建议改变一下:
到
做
而不是
最后6行替换为:
|
![]() |
5
1
因为看起来你在做大量的数值计算,你应该 Psyco 一枪它是一个JIT编译器,用于分析运行的代码并优化某些操作。安装它,然后在文件顶部放置:
这将启用psyco的jit,并且应该免费加快代码的速度:(实际上不是,它占用了更多的内存) |
![]() |
6
0
如果对任何数学函数的输入都受到相当大的限制,则可以使用查找表而不是数学函数。这可以以存储表所需的额外内存为代价为您赢得一些性能(速度)。 |
![]() |
8
0
我会把我的答案贴出来,把它和问题区分开来。这是上面描述的一些技术的组合,这些技术似乎提供了迄今为止最好的改进。
编辑:看起来psyco为这个版本提供了15%的改进,虽然不是很大,但足以证明它的使用是合理的。 |