Евклидово расстояние: результаты различаются между питоном и numpy с большим количеством экземпляров - PullRequest
1 голос
/ 19 марта 2019

Я пытаюсь двумя способами реализовать квадратный результат евклидова расстояния.

По Numpy:

def inference(feature_list):
    distances = np.zeros(len(feature_list))
    for idx, pair in enumerate(feature_list):
        distances[idx] = euclidean_distances(pair[0].reshape((1, -1)), pair[1].reshape((1, -1))).item()
        distances[idx] = distances[idx] * distances[idx]
    return distances

По питону:

def inference1(feature_list):
    distances = np.zeros(len(feature_list))
    for idx, pair in enumerate(feature_list):
        for pair_idx in range(len(pair[0])):
            tmp = pair[0][pair_idx] - pair[1][pair_idx]
            distances[idx] += tmp * tmp

    return distances

Код для проверки результата:

def main(args):
    d = 128
    n = 100
    array2 = [(np.random.rand(d)/4, np.random.rand(d)/3) for x in range(n)]

    result = sample.inference(array2)
    print(list(result)) # print result 1


    result = sample.inference1(array2)
    print(list(result)) # print result 2

Результаты отличаются, когда n достигает 100000, в то время как результаты остаются теми же, когда n мало.

Почему это случилось? Как я могу получить тот же результат?

1 Ответ

0 голосов
/ 19 марта 2019

В этом минимальном примере мы видим, что разница между двумя результатами незначительна.

import numpy as np
from sklearn.metrics.pairwise import euclidean_distances

def inference_sklearn(feature_list):
    distances = np.zeros(len(feature_list))
    for idx, pair in enumerate(feature_list):
        distances[idx] = euclidean_distances(pair[0].reshape((1, -1)), pair[1].reshape((1, -1))).item()
        distances[idx] = distances[idx] * distances[idx]
    return distances

def inference_python(feature_list):
    distances = np.zeros(len(feature_list))
    for idx, pair in enumerate(feature_list):
        for pair_idx in range(len(pair[0])):
            tmp = pair[0][pair_idx] - pair[1][pair_idx]
            distances[idx] += tmp * tmp

    return distances


d = 128
ns = [100, 1000, 10000, 100000, 200000]
for n in ns: 
    print("n =", n)
    test_array = [(np.random.rand(d)/4, np.random.rand(d)/3) for x in range(n)]
    result_sklearn = inference_sklearn(test_array)
    result_python = inference_python(test_array)
    print(euclidean_distances([result_sklearn], [result_python])[0][0])

Выход:

n = 100
0.0
n = 1000
0.0
n = 10000
0.0
n = 100000
0.0
n = 200000
1.52587890625e-05

Не просто печатайте свои результаты, когда хотите проверить равенство. Также вы можете использовать numpy.set_printoptions для контроля качества печати ваших массивов.

...