当前位置: 首页 > 知识库问答 >
问题:

如何计算Tensorflow中的Spearman关联

凌和颂
2023-03-14

我需要计算Pearson和Spearman的相关关系,并将其用作张量流的度量。

对于皮尔逊来说,这是微不足道的:

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

但对于斯皮尔曼,我是无知的!

从这个答案中:

    samples = 1
    predictions_rank = tf.nn.top_k(y_pred, k=samples, sorted=True, name='prediction_rank').indices
    real_rank = tf.nn.top_k(y_true, k=samples, sorted=True, name='real_rank').indices
    rank_diffs = predictions_rank - real_rank
    rank_diffs_squared_sum = tf.reduce_sum(rank_diffs * rank_diffs)
    six = tf.constant(6)
    one = tf.constant(1.0)
    numerator = tf.cast(six * rank_diffs_squared_sum, dtype=tf.float32)
    divider = tf.cast(samples * samples * samples - samples, dtype=tf.float32)
    spearman_batch = one - numerator / divider

但是这个返回NaN。。。

我试过:

size = tf.size(y_pred)
indice_of_ranks_pred = tf.nn.top_k(y_pred, k=size)[1]
indice_of_ranks_label = tf.nn.top_k(y_true, k=size)[1]
rank_pred = tf.nn.top_k(-indice_of_ranks_pred, k=size)[1]
rank_label = tf.nn.top_k(-indice_of_ranks_label, k=size)[1]
rank_pred = tf.to_float(rank_pred)
rank_label = tf.to_float(rank_label)
spearman = tf.contrib.metrics.streaming_pearson_correlation(rank_pred, rank_label)

但运行此命令时,我出现以下错误:

tensorflow.python.framework.errors_impl。InvalidArgumentError:输入必须至少有k列。有1个,需要32个

[{node metrics/spearman/TopKV2}}=TopKV2[T=DT_FLOAT,sorted=true,_device=“/job:localhost/replica:0/task:0/device:CPU:0”](lambda_1/add,metrics/pearson/pearson_r/variance_predictions/Size)]]

共有3个答案

周通
2023-03-14

top_k()。索引返回最佳元素的索引。斯皮尔曼需要军衔。他们是不同的。

例如,对于数组[3,1,2]:

>

斯皮尔曼需要[2,0,1]

您可以通过以下调用(使用tf.scatter\u nd())获得列组:

def my_spearman(y_pred, labels):
  predictions_rank = tf.argsort(tf.squeeze(y_pred))
  real_rank = tf.argsort(labels)
  r = tf.range(tf.shape(labels))
  real_rank = tf.scatter_nd(tf.expand_dims(real_rank, -1), r, tf.shape(real_rank))
  predictions_rank = tf.scatter_nd(tf.expand_dims(predictions_rank, -1), r, tf.shape(predictions_rank))
  rank_diffs = predictions_rank - real_rank
  rank_diffs_squared_sum = tf.reduce_sum(rank_diffs * rank_diffs)
  numerator = tf.cast(6 * rank_diffs_squared_sum, dtype=tf.float32)
  samples = tf.shape(rank_diffs)[0]
  divider = tf.cast(samples * samples * samples - samples, dtype=tf.float32)
  spearman = 1.0 - numerator / divider
  return spearman

请注意,如果元素不唯一,此算法将无法工作。相反,皮尔森相关系数应该根据等级计算:

def correlationMetric(x, y):
  x = tf.cast(x, tf.float32)
  y = tf.cast(y, tf.float32)
  n = tf.cast(tf.shape(x)[0], x.dtype)
  xsum = tf.reduce_sum(x, axis=0)
  ysum = tf.reduce_sum(y, axis=0)
  xmean = xsum / n
  ymean = ysum / n
  xvar = tf.reduce_sum(tf.math.squared_difference(x, xmean), axis=0)
  yvar = tf.reduce_sum(tf.math.squared_difference(y, ymean), axis=0)
  cov = tf.reduce_sum((x - xmean) * (y - ymean), axis=0)
  corr = cov / tf.sqrt(xvar * yvar)
  return corr

def my_spearman(y_pred, labels):
  predictions_rank = tf.argsort(tf.squeeze(y_pred))
  real_rank = tf.argsort(labels)
  r = tf.range(tf.shape(labels))
  real_rank = tf.scatter_nd(tf.expand_dims(real_rank, -1), r, tf.shape(real_rank))
  predictions_rank = tf.scatter_nd(tf.expand_dims(predictions_rank, -1), r, tf.shape(predictions_rank))
  spearman = correlationMetric(real_rank, predictions_rank)
  return spearman
艾才良
2023-03-14

根据本网站的定义,我一直致力于在tensorflow中直接实现Spearman秩相关系数(https://rpubs.com/aaronsc32/spearman-rank-correlation)我已经获得了以下代码(我将其共享,以防有人发现它有用)。

@tf.function
def get_rank(y_pred):
  rank = tf.argsort(tf.argsort(y_pred, axis=-1, direction="ASCENDING"), axis=-1)+1 #+1 to get the rank starting in 1 instead of 0
  return rank

@tf.function
def sp_rank(x, y):
  cov = tfp.stats.covariance(x, y, sample_axis=0, event_axis=None)
  sd_x = tfp.stats.stddev(x, sample_axis=0, keepdims=False, name=None)
  sd_y = tfp.stats.stddev(y, sample_axis=0, keepdims=False, name=None)
  return 1-cov/(sd_x*sd_y) #1- because we want to minimize loss

@tf.function
def spearman_correlation(y_true, y_pred):
    #First we obtain the ranking of the predicted values
    y_pred_rank = tf.map_fn(lambda x: get_rank(x), y_pred, dtype=tf.float32)
    
    #Spearman rank correlation between each pair of samples:
    #Sample dim: (1, 8)
    #Batch of samples dim: (None, 8) None=batch_size=64
    #Output dim: (batch_size, ) = (64, )
    sp = tf.map_fn(lambda x: sp_rank(x[0],x[1]), (y_true, y_pred_rank), dtype=tf.float32)
    #Reduce to a single value
    loss = tf.reduce_mean(sp)
    return loss
陶鹏
2023-03-14

您可以做的一件事是使用Tensorflow的函数tf.py_functionscipy.stats.spearmanr一起使用,并像这样定义输入和输出:

from scipy.stats import spearmanr
def get_spearman_rankcor(y_true, y_pred):
     return ( tf.py_function(spearmanr, [tf.cast(y_pred, tf.float32), 
                       tf.cast(y_true, tf.float32)], Tout = tf.float32) )
 类似资料:
  • 问题内容: 如果您有两个不相交的图,并且想要链接它们,请执行以下操作: 到这个: 有没有办法做到这一点?在某些情况下,这似乎可以使施工更容易。 例如,如果您有一个图,其输入图像为,并且想要优化输入图像(深梦风格),是否有一种方法可以仅用节点替换占位符?还是在构建图形之前必须考虑一下? 问题答案: TL; DR:如果可以将这两个计算定义为Python函数,则应该这样做。如果不能,那么TensorFl

  • 问题内容: 最近,我一直在玩 TensorFlow, 并提到该框架无法使用我所有可用的计算资源。在卷积神经网络教程中,他们提到 天真地采用模型参数的异步更新会导致次优的训练性能,因为单个模型副本可能会在模型参数的陈旧副本上进行训练。相反,采用完全同步更新将与最慢的模型副本一样慢。 尽管他们在教程和白皮书中都提到了这一点,但我并没有真正找到在本地计算机上进行异步并行计算的方法。可能吗 还是它是Ten

  • 问题内容: 我想通过Tensorflow计算Jacobian矩阵。 是)我有的: 是损失函数,都是可训练的变量,并且是许多数据。 但是,如果我们增加数据数量,则需要花费大量时间来运行该功能。有任何想法吗? 问题答案: 假设和是Tensorflow张量,并且取决于: 结果具有形状,并提供的每个元素相对于的每个元素的偏导数。

  • 本章将重点介绍如何开始使用分布式TensorFlow。目的是帮助开发人员了解重复出现的基本分布式TF概念,例如TF服务器。我们将使用Jupyter Notebook来评估分布式TensorFlow。使用TensorFlow实现分布式计算如下所述 - 第1步 - 为分布式计算导入必需的模块 - 第2步 - 使用一个节点创建TensorFlow集群。让这个节点负责一个名称为“worker”的作业,并在

  • 本文向大家介绍在R中对Spearman的相关性执行相关性测试时,如何避免出现“无法计算具有联系的精确p值”的警告?,包括了在R中对Spearman的相关性执行相关性测试时,如何避免出现“无法计算具有联系的精确p值”的警告?的使用技巧和注意事项,需要的朋友参考一下 当变量不是连续的但可以排序时,我们不使用皮尔逊相关系数来找到线性关系,在这种情况下,斯皮尔曼相关系数就出现了。由于spearman相关系

  • 本文向大家介绍请介绍Tensorflow计算图?相关面试题,主要包含被问及请介绍Tensorflow计算图?时的应答技巧和注意事项,需要的朋友参考一下 tensorflow是一个通过计算图的形式来表述计算的编程系统,可以把计算图看做一种有向图,tf中每一个计算都是计算图上的一个节点,而节点之间的边描述了计算之间的依赖关系