Source code for limix.qc._boxcox

from __future__ import division

from brent_search import brent


[docs]def boxcox(x): r"""Box-Cox transformation for normality conformance. It applies the power transformation .. math:: f(x) = \begin{cases} \frac{x^{\lambda} - 1}{\lambda}, & \text{if } \lambda > 0; \\ \log(x), & \text{if } \lambda = 0. \end{cases} to the provided data, hopefully making it more normal distribution-like. The λ parameter is fit by maximum likelihood estimation. Parameters ---------- X : array_like Data to be transformed. Returns ------- boxcox : ndarray Box-Cox transformed data. Examples -------- .. plot:: >>> import limix >>> import numpy as np >>> import scipy.stats as stats ... >>> np.random.seed(0) ... >>> x = stats.loggamma.rvs(0.1, size=100) >>> y = limix.qc.boxcox(x) ... >>> plt = limix.plot.get_pyplot() ... >>> _, (ax1, ax2) = plt.subplots(2, 1) >>> _ = stats.probplot(x, dist=stats.norm, plot=ax1) >>> _ = stats.probplot(y, dist=stats.norm, plot=ax2) >>> plt.tight_layout() """ import dask.array as da import numpy as np if isinstance(x, da.Array): return _boxcox(da, x) return _boxcox(np, x)
def _boxcox(lib, x): from numpy_sugar import epsilon from scipy.stats import boxcox_llf from scipy.special import boxcox as bc x = lib.asarray(x).astype(float) m = x.min() if m <= 0: m = max(lib.abs(m), epsilon.small) x = x + m + m / 2 lmb = brent(lambda lmb: -boxcox_llf(lmb, x), -5, +5)[0] return bc(x, lmb)