7

以下のコード (コサイン類似度を計算するため) を私のコンピューターで繰り返し実行すると、1.0、0.9999999999999998、または 1.0000000000000002 が出力されます。正規化関数を取り出すと、1.0 しか返されません。浮動小数点演算は決定論的であるべきだと思っていました。毎回同じコンピューター上の同じデータに同じ操作が適用されている場合、プログラムでこれが発生する原因は何ですか? スタック上の正規化関数が呼び出されている場所と関係があるのでしょうか? どうすればこれを防ぐことができますか?

#! /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)))
4

1 に答える 1

14

浮動小数点演算は決定論的かもしれませんが、辞書キーの順序はそうではありません。

を呼び出すと.keys()、結果のリストの順序がランダムになる可能性があります。

したがって、ループ内の数学演算の順序も潜在的にランダムであるため、単一の浮動小数点演算は決定論的である可能性がありますが、一連の演算の結果は順序に大きく依存するため、結果は決定論的ではありません。 .

キーリストを並べ替えることで、一貫した順序を強制できます。

于 2014-02-08T06:27:44.183 に答える