黑塞人的斯皮尔曼等级相关性

2024-05-15 01:48:11 发布

您现在位置:Python中文网/ 问答频道 /正文

我尝试将斯皮尔曼秩相关系数(wiki)作为xgboost的自定义目标函数来实现。我正在使用来自google的快速软排序(github)软件包进行可微排序,并使用tensorflow自动计算梯度。您可以在下面找到代码:

from fast_soft_sort.tf_ops import soft_rank
import tensorflow as tf
import numpy as np

def pearson_corr(x, y):
    
    xy_t = tf.concat([x, y], axis=0)
    mean_t = tf.reduce_mean(xy_t, axis=1, keepdims=True)
    cov_t = ((xy_t-mean_t) @ tf.transpose(xy_t-mean_t))/(x.shape[1]-1)
    cov2_t = tf.linalg.diag(1/tf.sqrt(tf.linalg.diag_part(cov_t)))
    corr_matrix = cov2_t @ cov_t @ cov2_t
    corr = tf.reduce_mean(corr_matrix) * 2 - 1 # equivalent to taking element [0][1] assuming the 2x2 corr matrix is symmetric and the diagonals are 1
    
    return corr

def spearman_corr(x, y):
    
    ranks = soft_rank(x, regularization_strength=0.1)
    corr = pearson_corr(ranks, y)
    
    return corr

def get_value_grad_and_hess(x, y, f):
    
    x_var = tf.Variable(x, dtype=tf.float32)
    y_var = tf.Variable(y, dtype=tf.float32)
        
    val, grad, hess = None, None, None

    with tf.GradientTape() as t2:
    
        with tf.GradientTape() as t1:
            
            val = f(x_var, y_var)
        
        grad = t1.gradient(val, x_var)    

    hess = t2.jacobian(grad, x_var)

    return val, grad, hess

# test with random input
x = np.random.rand(1, 10) # predictions
y = np.random.rand(1, 10) # labels

print('pearson:')
val, grad, hess = get_value_grad_and_hess(x, y, pearson_corr)
print(' value:',  val)
print(' gradient:', grad)
print(' hessian:', hess)

print('spearman:')
val, grad, hess = get_value_grad_and_hess(x, y, spearman_corr)
print(' value:',  val)
print(' gradient:', grad)
print(' hessian:', hess)

示例输出:

pearson:
 value: tf.Tensor(-0.3348779, shape=(), dtype=float32)
 gradient: tf.Tensor(
[[ 0.21893269  0.16921082  0.19409613 -0.00321923  0.07347419  0.29004234
  -0.07947832 -0.7088071   0.29586902 -0.4501205 ]], shape=(1, 10), dtype=float32)
 hessian: tf.Tensor(
[[[[ 0.04441248 -0.03097764  0.02028688 -0.20294864 -0.22516166
    -0.09771542 -0.06334648  0.42131865 -0.02681065  0.16094248]]

  [[-0.03097765  0.40132353  0.04399774 -0.07797898 -0.05632872
     0.04975905 -0.07172927 -0.17790946  0.06856277 -0.14871901]]

  [[ 0.02028689  0.04399772  0.44207606 -0.06522453 -0.03210837
     0.0911998  -0.07974204 -0.30411014  0.10508882 -0.22146425]]

  [[-0.20294863 -0.077979   -0.06522458  0.27985442 -0.12591925
    -0.13325104 -0.02723934  0.31153008 -0.10839472  0.14957213]]

  [[-0.22516167 -0.05632871 -0.03210838 -0.12591931  0.23029271
    -0.10794277 -0.04108595  0.30121914 -0.07069567  0.12773061]]

  [[-0.09771542  0.04975905  0.0911998  -0.13325103 -0.10794276
     0.4497667  -0.09163402 -0.12746409  0.11477053 -0.14748882]]

  [[-0.06334649 -0.07172926 -0.07974204 -0.02723937 -0.04108596
    -0.09163402  0.35762674  0.07487351 -0.09705587  0.03933275]]

  [[ 0.4213187  -0.17790946 -0.3041101   0.31153005  0.3012191
    -0.12746407  0.07487351 -0.09769349 -0.2807703  -0.12099396]]

  [[-0.02681071  0.06856281  0.1050889  -0.10839473 -0.07069571
     0.11477058 -0.0970559  -0.28077024  0.5259669  -0.23066193]]

  [[ 0.1609425  -0.14871901 -0.22146428  0.1495721   0.12773061
    -0.14748883  0.03933276 -0.12099396 -0.23066193  0.39175004]]]], shape=(1, 10, 1, 10), dtype=float32)

spearman:
 value: tf.Tensor(-0.3408205, shape=(), dtype=float32)
 gradient: tf.Tensor(
[[ 0.13679196  0.13627169  0.15643153 -0.10963751 -0.02715444  0.2698098
   0.20591483 -0.8303905   0.26787752 -0.20591483]], shape=(1, 10), dtype=float32)
 hessian: None

正如您所见,上面的代码为pearson相关函数生成了梯度和hessian,但对于Spearman相关函数,hessian是无的

有人知道为什么黑森人不适合斯皮尔曼的关联吗


Tags: valuevartfvalmeanprintpearsonhessian

热门问题