为什么Tensorflow和Scipy之间的Pearson相关性不同

时间:2018-11-21 02:08:16

标签: python python-3.x tensorflow scipy metrics

我用两种方法计算皮尔逊相关性:


在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 :(得分:4)

在您提供的最小可验证示例中,class Site_Controller extends MY_Controller { function __construct() { parent::__construct(); } # added this method public function home() { $this->load->view("site/index.php"); } } y_pred是整数列表。在y_true source的第一行中,您将看到使用scipy.stats.measures.pearsonr将输入转换为numpy数组。我们可以通过以下方式查看这些数组的结果数据类型:

x = np.asarray(x)

在除以两个print(np.asarray(y_pred).dtype) # Prints 'int64' 数时,SciPy使用int64精度,而在上例中,TensorFlow将使用float64精度。即使是单个分区,差异也可能很大:

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' float32使用y_pred精度,您可以获得SciPy和TensorFlow相同的结果:

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})))

SciPy与TensorFlow的计算之间的差异

在您报告的测试分数中,差异很大。我查看了source,发现了以下区别:

1。更新操作

Scipy's Pearson: 0.38060760498046875 Tensorflow's Pearson: 0.38060760498046875 的结果不是无状态的。它返回相关系数op以及新输入数据的tf.contrib.metrics.streaming_pearson_correlation。如果在使用实际的update_op调用系数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})))

2。不同的公式

SciPy:

TensorFlow:

在数学上相同的同时,在TensorFlow中相关系数的计算不同。它使用(x,x),(x,y)和(y,y)的样本协方差来计算相关系数,从而可能引入不同的舍入误差。