当在我的计算机上重复运行时,下面的代码(用于计算余弦相似度)将输出1.0、0.9999999999999998或1.0000000000000002。当我取出normalize函数时,它将仅返回1.0。我认为浮点运算应该是确定性的。如果每次对同一台计算机上的相同数据执行相同的操作,将会导致我的程序中的此原因?可能与在规范中的哪个位置调用normalize函数有关?我该如何预防呢?

#! /usr/bin/env python3

import math

def normalize(vector):
    sum = 0
    for key in vector.keys():
        sum += vector[key]**2
    sum = math.sqrt(sum)
    for key in vector.keys():
        vector[key] = vector[key]/sum
    return vector

dict1 = normalize({"a":3, "b":4, "c":42})
dict2 = dict1

n_grams = list(list(dict1.keys()) + list(dict2.keys()))
numerator = 0
denom1 = 0
denom2 = 0

for n_gram in n_grams:
    numerator += dict1[n_gram] * dict2[n_gram]
    denom1 += dict1[n_gram]**2
    denom2 += dict2[n_gram]**2

print(numerator/(math.sqrt(denom1)*math.sqrt(denom2)))

最佳答案

浮点数学可能是确定性的,但字典键的顺序不是确定性的。

当您调用.keys()时,结果列表的顺序可能是随机的。

因此,循环中数学运算的顺序也可能是随机的,因此结果将不会是确定性的,因为尽管任何单个浮点运算都可能是确定性的,但是一系列运算的结果在很大程度上取决于顺序。

您可以通过对 key 列表进行排序来强制执行一致的顺序。

关于python - Python浮点确定性,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/21642779/

10-12 19:07