Почему корреляция Пирсона отличается между Tensorflow и Scipy - PullRequest
0 голосов
/ 21 ноября 2018

Я вычисляю корреляцию Пирсона двумя способами:


В Tensorflow я использую следующую метрику:

tf.contrib.metrics.streaming_pearson_correlation(y_pred, y_true)

Когда я оцениваю свою сеть на тестовых данных, я получаюследующие результаты:

потери = 0,5289223349094391

Pearson = 0,3701728057861328

(потеря mean_squared_error)


Затем я прогнозирую тестовые данные и вычисляю те же показатели с помощью Scipy:

import scipy.stats as measures
per_coef = measures.pearsonr(y_pred, y_true)[0]
mse_coef = np.mean(np.square(np.array(y_pred) - np.array(y_true)))

И получаю следующие результаты:

Pearson = 0.5715300096509959

MSE = 0.5289223312665985


Это известная проблема?Это нормально?

Минимальный, полный и проверяемый пример

import tensorflow as tf
import scipy.stats as measures

y_pred = [2, 2, 3, 4, 5, 5, 4, 2]
y_true = [1, 2, 3, 4, 5, 6, 7, 8]

## Scipy
val2 = measures.pearsonr(y_pred, y_true)[0]
print("Scipy's Pearson = {}".format(val2))

## Tensorflow
logits = tf.placeholder(tf.float32, [8])
labels = tf.to_float(tf.Variable(y_true))

acc, acc_op = tf.contrib.metrics.streaming_pearson_correlation(logits,labels)

sess = tf.Session()
sess.run(tf.local_variables_initializer())
sess.run(tf.global_variables_initializer())
sess.run(acc, {logits:y_pred})
sess.run(acc_op, {logits:y_pred})

print("Tensorflow's Pearson:{}".format(sess.run(acc,{logits:y_pred})))

1 Ответ

0 голосов
/ 21 ноября 2018

В приведенном вами минимальном проверяемом примере y_pred и y_true являются списками целых чисел.В первой строке scipy.stats.measures.pearsonr source вы увидите, что входные данные преобразованы в массивы с цифрой x = np.asarray(x).Мы можем увидеть результирующие типы данных этих массивов через:

print(np.asarray(y_pred).dtype)  # Prints 'int64'

При делении двух чисел int64 SciPy использует точность float64, тогда как TensorFlow будет использовать точность float32 в примере выше.Разница может быть довольно большой, даже для одного деления:

>>> '%.15f' % (8.5 / 7)
'1.214285714285714'
>>> '%.15f' % (np.array(8.5, dtype=np.float32) / np.array(7, dtype=np.float32))
'1.214285731315613'
>>> '%.15f' % (np.array(8.5, dtype=np.float32) / np.array(7, dtype=np.float32) - 8.5 / 7)
'0.000000017029899'

Вы можете получить одинаковые результаты для SciPy и TensorFlow, используя точность float32 для y_pred и y_true:

import numpy as np
import tensorflow as tf
import scipy.stats as measures

y_pred = np.array([2, 2, 3, 4, 5, 5, 4, 2], dtype=np.float32)
y_true = np.array([1, 2, 3, 4, 5, 6, 7, 8], dtype=np.float32)

## Scipy
val2 = measures.pearsonr(y_pred, y_true)[0]
print("Scipy's Pearson: \t\t{}".format(val2))

## Tensorflow
logits = tf.placeholder(tf.float32, [8])
labels = tf.to_float(tf.Variable(y_true))

acc, acc_op = tf.contrib.metrics.streaming_pearson_correlation(logits,labels)

sess = tf.Session()
sess.run(tf.local_variables_initializer())
sess.run(tf.global_variables_initializer())
sess.run(acc, {logits:y_pred})
sess.run(acc_op, {logits:y_pred})

print("Tensorflow's Pearson: \t{}".format(sess.run(acc,{logits:y_pred})))

prints

Scipy's Pearson:        0.38060760498046875
Tensorflow's Pearson:   0.38060760498046875

Различия между вычислениями SciPy и TensorFlow

В отчетах о результатах тестов, которые вы сообщаете, разница довольно высока.Я взглянул на источник и обнаружил следующие отличия:

1.Обновление ops

Результат tf.contrib.metrics.streaming_pearson_correlation не является состоянием без сохранения состояния.Возвращает коэффициент корреляции op вместе с update_op для новых входящих данных.Если вы вызовите обновление операции с другими данными до вызова коэффициента операции с фактическим значением y_pred, это даст совершенно другой результат:

sess.run(tf.global_variables_initializer())

for _ in range(20):
    sess.run(acc_op, {logits: np.random.randn(*y_pred.shape)})

print("Tensorflow's Pearson: \t{}".format(sess.run(acc,{logits:y_pred})))

print

Scipy's Pearson:        0.38060760498046875
Tensorflow's Pearson:   -0.0678008571267128

2.Различные формулы

SciPy:

TensorFlow:

Хотя математически то же самое, вычисление коэффициента корреляции отличается в TensorFlow.Он использует выборочную ковариацию для (x, x), (x, y) и (y, y) для вычисления коэффициента корреляции, который может вносить различные ошибки округления.

...