我有这个计算欧几里德相似度的程序。
from math import sqrt
def leeValoraciones(nomFichero):
lineas = [(l.strip()).split("\t") for l in (open(nomFichero).readlines())]
diccio = {}
for l in lineas:
diccio[int(l[0])] = {}
for l in lineas:
diccio[int(l[0])][int(l[1])] = (float(l[2]),float(l[3]))
return diccio
def euclideanDist(dic1, dic2):
# Compute the sum of squares of the elements common
# to both dictionaries
sum2 = sum([pow(dic1[elem]-dic2[elem], 2)
for elem in dic1 if elem in dic2])
return sqrt(sum2)
def euclideanSimilarity(dic1, dic2):
return 1/(1+euclideanDist(dic1, dic2))
diccio = leeValoraciones("u.data")
diccio2 = leeValoraciones("u.data")
euclideanSimilarity(diccio,diccio2)
当我运行程序时,它返回以下错误:
for elem in dic1 if elem in dic2])
TypeError: unsupported operand type(s) for -: 'dict' and 'dict'
有人可以帮助我吗? 提前谢谢。
答案 0 :(得分:0)
您的外部词典包含嵌套词典。你试图减去那些:
for l in lineas:
diccio[int(l[0])] = {}
for l in lineas:
diccio[int(l[0])][int(l[1])] = (float(l[2]),float(l[3]))
因此,您的字典具有结构{integer: {integer: (float, float)}}
,但您只能遍历外部字典。并不是说你可以减去最里面的元组。
您可能应该使用两个整数作为坐标,为您提供一个指向浮点元组的外部字典,格式为{(integer, integer): (float, float)}
。
你可以通过文件上的一个循环实现这一点,实际上不需要循环两次(或者首先将所有行读入内存)。使用csv
模块有助于将行读入行:
import csv
def leeValoraciones(nomFichero):
with open(nomFichero, 'rb') as csvfile:
reader = csv.reader(csvfile, delimiter='\t')
results = {}
for row in reader:
key = tuple(int(c) for c in row[:2])
value = tuple(float(c) for c in row[2:4])
results[key] = value
return results
但是,我不确定你要用这里计算欧几里德距离;你传入两个完全相同的文件构建的字典。这两个文件的所有点之间的欧几里德距离恰好为0。
如上所述,您不能将(float, float)
元组用作Euclidian空间中的单个点,您有一个系列点。你需要决定你计算距离的点数。
答案 1 :(得分:0)
首先,这是整个程序,如果没有,请发布整个程序。其次,我相信,从你的错误来看,for elem in dic1 if elem in dic2])
应该是
for elem in dic1:
if elem in dic2:
Do things
第三个也是最后一个,你的错误就是说你试图减去字典,这没有意义。尝试改为
for elem in dic1:
if elem in dic2:
dic1[elem]-dict2[elem]
现在,这个答案可能完全错误,但这就是你发布的内容。请发布整个代码,以及u.data
的内容