Безошибочный способ сравнения двух 2D-массивов для точности - PullRequest
0 голосов
/ 22 января 2019

В настоящее время я обучаю LSTM, который классифицирует кадры. Я пытаюсь сравнить два двухмерных массива, чтобы проверить точность моего прогноза и цели. В настоящее время я искал не наивные способы решения этой проблемы с помощью NumPy / SciPy.

Мне известно, что существует np.testing.assert_array_equal (x, y), который использует Assertion для вывода результатов. Я ищу способ решения этой проблемы с помощью NumPy / SciPy, чтобы я мог сохранять результаты, а не распечатывать Assert:

Arrays are not equal

(mismatch 14.285714285714292%)
 x: array([0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0])
 y: array([0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0])
x = np.asarray([[0, 0, 0], [0, 0, 0], [0, 0, 0], [0, 0, 0], [0, 0, 0], [0, 0, 0], [0, 0, 0]])

y = np.asarray([[0, 0, 0], [0, 0, 0], [0, 0, 1], [0, 1, 0], [1, 0, 0], [0, 0, 0], [0, 0, 0]])

try:
    np.testing.assert_array_equal(x, y)
    res = True
except AssertionError as err:
    res = False
    print (err)

Я ищу способ, которым я могу хранить несоответствие этих двух массивов без использования наивного способа (две сравнительные петли):

accuracy = thisFunction(x,y)

Я уверен, что в NumPy есть что-то, что может решить эту проблему, мне не повезло с поиском встроенных функций.

Ответы [ 2 ]

0 голосов
/ 22 января 2019

np.array_equal(x, y) примерно эквивалентно (x == y).all(). Вы можете использовать это для вычисления расхождений:

def array_comp(x, y):
    """
    Return the status of the comparison and the discrepancy.

    For arrays of the same shape, the discrepancy is a ratio of mismatches to the total size.
    For arrays of different shapes or sizes, the discrepancy is a message indicating the mismatch.
    """
    if x.shape != y.shape:
        return False, 'shape'
    count = x.size - np.count_nonzero(x == y)
    return count == 0, count / x.size
0 голосов
/ 22 января 2019

Как отметил hpaulj в комментарии, вы можете использовать numpy.allclose() для проверки равенства массива с допустимым отклонением до некоторого значения допуска (см. Ниже или примечания NumPy).

Вот небольшая иллюстрация с двумя простыми массивами с плавающей точкой.

In [7]: arr1 = np.array([1.3, 1.4, 1.5, 3.4]) 
In [8]: arr2 = np.array([1.299999, 1.4, 1.4999999, 3.3999999999]) 

In [9]: np.allclose(arr1, arr2) 
Out[9]: True

numpy.allclose вернет True, если соответствующие элементы в массивах отличаются (только до значения допуска). В противном случае он вернется False. NumPy по умолчанию для значений относительного и абсолютного допуска: rtol=1e-05, atol=1e-08 соответственно.


Сказав, что, если вы хотите сравнить только int массивы, то вам лучше использовать numpy.array_equal(), что составляет ок. В 8 раз быстрее, чем numpy.allclose.

In [17]: arr1 = np.random.randint(23045) 
In [18]: arr2 = np.random.randint(23045) 

In [19]: %timeit np.allclose(arr1, arr2) 
22.9 µs ± 471 ns per loop (mean ± std. dev. of 7 runs, 10000 loops each)

In [20]: %timeit np.array_equal(arr1, arr2) 
3.99 µs ± 68.6 ns per loop (mean ± std. dev. of 7 runs, 100000 loops each)
...