Как вычислить корреляцию Спирмена в Tensorflow - PullRequest
0 голосов
/ 21 ноября 2018

Задача

Мне нужно вычислить корреляции Пирсона и Спирмена и использовать их как метрики в тензорном потоке.

Для Пирсона это тривиально:

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 ...


В соответствии с определением Википедии : enter image description here

Я пытался:

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)

Нозапустив это, я получил следующую ошибку:

tenorflow.python.framework.errors_impl.InvalidArgumentError: вход должен содержать не менее k столбцов.Имел 1, нужно 32

[[{{показатель узла / spearman / TopKV2}} = TopKV2 [T = DT_FLOAT, sorted = true, _device = "/ job: localhost / replica: 0 / task: 0 /устройство: ЦП: 0 "] (лямбда_1 / добавить, метрики / Pearson / Pearson_r / variance_predictions / Size)]]

1 Ответ

0 голосов
/ 12 апреля 2019

Одна вещь, которую вы можете сделать, это использовать функцию Tensorflow tf.py_function для использования с scipy.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) )
...