我已经看了好几次了,但仍然不明白这里有什么问题。这是下面写的余弦相似度函数,也是用2个向量调用的地方。
def cosine_sim(v1, v2):
return (lambda x,y,z: x / sqrt(y * z))(reduce(lambda x,y: (x[0] + y[0] * y[1], x[1] + y[0]**2, x[2] + y[1]**2), izip(v1,v2),(0,0,0)))
cosine_sim(first_vector,second_vector)
错误:
TypeError跟踪(最近一次通话) 在()中 ----> 1个cosine_sim(firstvector,secondvector)
cosine_sim(v1,v2)中的1 def cosine_sim(v1,v2): ----> 2 return(lambda x,y,z:x / sqrt(y * z))(reduce(lambda x,y:(x [0] + y [0] * y [1],x [ 1] + y [0] ** 2,x [2] + y [1] ** 2),izip(v1,v2),(0,0,0)))
TypeError:()缺少2个必需的位置参数:“ y”和“ z”
答案 0 :(得分:3)
您的reduce
调用返回三个tuple
,因此您要以lambda x, y, z
作为三个x
来调用tuple
,并且不带参数y
或z
。
最简单的解决方法是使用the splat operator, *
,将reduce
的返回结果打包,以便将三个{tuple
}转换为三个连续的位置参数:
def cosine_sim(v1, v2):
return (lambda x,y,z: x / sqrt(y * z))(*reduce(lambda x,y: (x[0] + y[0] * y[1], x[1] + y[0]**2, x[2] + y[1]**2), izip(v1,v2),(0,0,0)))
# change is here ^
请注意,单行这真是太丑了,您最好将它(至少)做成两层,以减少复杂性。即使保留reduce
,您也可以简化一下:
def cosine_sim(v1, v2):
x, y, z = reduce(lambda x,y: (x[0] + y[0] * y[1], x[1] + y[0]**2, x[2] + y[1]**2), izip(v1,v2),(0,0,0))
return x / sqrt(y * z)
这基本上是您lambda
所尝试的,但是开销较低(无需无故调用更多函数)。
完全删除reduce
会使其更长一点,但又更容易理解:
def cosine_sim(v1, v2):
x = y = z = 0
for a, b in izip(v1, v2):
x += a * b
y += a ** 2
z += b ** 2
return x / sqrt(y * z)
在可能的情况下为变量提供更好的名称,这是相当不错的代码(并且可能更快地启动)。