def skew(t): """ Computes the skewness of a :class:`Tensor`. Note: this function uses cross-approximation (:func:`tntorch.cross()`). :param t: a :class:`Tensor` :return: a scalar """ return tn.mean(((t - tn.mean(t)) / tn.std(t))**3)
def kurtosis(t, fisher=True): """ Computes the kurtosis of a :class:`Tensor`. Note: this function uses cross-approximation (:func:`tntorch.cross()`). :param t: a :class:`Tensor` :param fisher: if True (default) Fisher's definition is used, otherwise Pearson's (aka excess) :return: a scalar """ return tn.mean(((t - tn.mean(t)) / tn.std(t))**4) - fisher * 3
def var(t, marginals=None): """ Computes the variance of a :class:`Tensor`. :param t: a :class:`Tensor` :param marginals: an optional list of vectors :return: a scalar :math:`\ge 0` """ if marginals is not None: assert len(marginals) == t.dim() tcentered = t - tn.mean(t, marginals=marginals) pdf = tn.Tensor( [marg[None, :, None] / marg.sum() for marg in marginals]) return tn.dot(tcentered * pdf, tcentered) return tn.normsq(t - tn.mean(t)) / t.numel()
def var(t): """ Computes the variance of a :class:`Tensor`. :param t: a :class:`Tensor` :return: a scalar :math:`\ge 0` """ return tn.normsq(t - tn.mean(t)) / t.numel()
def normalized_moment(t, k, eps=1e-12): """ Compute a normalized central moment :math:`\\mathbb{E}[(t - \\mathbb{E}[t])^k] / \\sigma^k'. :param t: input :class:`Tensor` :param k: the desired moment order (integer :math:`\ge 1`) :param eps: relative error for rounding (default is 1e-12) :return: the :math:`k`-th order normalized moment of `t` """ return raw_moment(t - tn.mean(t), k=k, eps=eps) / tn.var(t)**(k / 2.) / t.numel()
def r_squared(gt, approx): """ Computes the :math:`R^2` score between two tensors (torch or tntorch). :param gt: a torch or tntorch tensor :param approx: a torch or tntorch tensor :return: a scalar <= 1 """ gt, approx = _process(gt, approx) if isinstance(gt, torch.Tensor) and isinstance(approx, torch.Tensor): return 1 - torch.dist(gt, approx)**2 / torch.dist(gt, torch.mean(gt))**2 return 1 - tn.dist(gt, approx)**2 / tn.normsq(gt-tn.mean(gt))
def normalized_moment(t, k, marginals=None, eps=1e-12, algorithm='eig'): """ Compute a normalized central moment :math:`\\mathbb{E}[(t - \\mathbb{E}[t])^k] / \\sigma^k'. :param t: input :class:`Tensor` :param k: the desired moment order (integer :math:`\ge 1`) :param marginals: an optional list of vectors :param eps: relative error for rounding (default is 1e-12) :return: the :math:`k`-th order normalized moment of `t` """ return raw_moment(t - tn.mean(t, marginals=marginals), k=k, marginals=marginals, eps=eps, algorithm=algorithm) / tn.var(t, marginals=marginals)**( k / 2.) # / t.numel()
def mean(self, **kwargs): """ See :func:`metrics.mean()`. """ return tn.mean(self, **kwargs)
def check(): x = t.torch() assert tn.relative_error(tn.mean(t), torch.mean(x)) <= 1e-3 assert tn.relative_error(tn.var(t), torch.var(x)) <= 1e-3 assert tn.relative_error(tn.norm(t), torch.norm(x)) <= 1e-3
def __init__(self, t, verbose=False): N = t.dim() self.N = N # Center the model (make it have mean 0) t -= tn.mean(t) # Compute the directional function: x1 + ... + xk for # every subset of variables cores = [] for n in range(N): I = t.shape[n] c = torch.eye(2)[:, None, :].repeat(1, 2 * I, 1) c[1, I:, 0] = torch.linspace(0, 1, I) cores.append(c) cores[0] = cores[0][1:2, ...] cores[N - 1] = cores[N - 1][..., 0:1] vecs = tn.Tensor(cores) # Center all directional functions (make them have mean 0) cores = [] for n in range(N): I = t.shape[n] c1 = torch.mean(vecs.cores[n][:, :I, :], dim=1, keepdim=True).repeat(1, I, 1) c2 = torch.mean(vecs.cores[n][:, I:, :], dim=1, keepdim=True).repeat(1, I, 1) cores.append(torch.cat([c1, c2], dim=1)) vecs_means = tn.Tensor(cores) vecs -= vecs_means # Compute the variance of all directional functions vecs_sq = vecs * vecs cores = [] for n in range(N): I = t.shape[n] c1 = torch.mean(vecs_sq.cores[n][:, :I, :], dim=1, keepdim=True) c2 = torch.mean(vecs_sq.cores[n][:, I:, :], dim=1, keepdim=True) cores.append(torch.cat([c1, c2], dim=1)) vecs_variance = tn.Tensor(cores) vecs_variance += tn.none(N) # To avoid division by 0 # Compute covariances between the model and all directional functions trep = tn.Tensor([c.repeat(1, 2, 1) for c in t.cores]) covs = tn.cross(tensors=[trep, vecs], function=lambda x, y: x * y, verbose=verbose) for n in range(N): I = t.shape[n] c1 = torch.mean(covs.cores[n][:, :I, :], dim=1, keepdim=True) c2 = torch.mean(covs.cores[n][:, I:, :], dim=1, keepdim=True) covs.cores[n] = torch.cat([c1, c2], dim=1) # Tensor containing all 2^N desired indices result = tn.cross(tensors=[covs, vecs_variance], function=lambda x, y: x / torch.sqrt(y), verbose=verbose) # Normalize result so that the largest index in absolute value is 1. # That should be useful for color coding result /= max(torch.abs(tn.minimum(result)), torch.abs(tn.maximum(result))) self.result = result