|
|
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%的改进,虽然不是很大,但足以证明它的使用是合理的。 |
|
|
user2995603 · 数组中相似项的序列 8 年前 |
|
|
Dan · 在TestComplete中使用“like”是可能的吗? 8 年前 |
|
|
zer02 · Rails:一种检查DB中重复项的方法?关联数据源 11 年前 |
|
|
Shani · 查找具有不同长度[闭合]的特征向量的相似性度量 12 年前 |