def _eval_grid_fast(self, *args, **kwds): X = np.vstack(args) d, inc = X.shape dx = X[:, 1] - X[:, 0] Xnc = self._make_flat_grid(dx, d, inc) Xn = np.dot(self._inv_hs, Xnc) kw = self._kernel_weights(Xn, dx, d, inc) r = kwds.get('r', 0) if r != 0: fun = self._moment_fun(r) kw *= fun(np.vstack(Xnc)) kw.shape = (2 * inc, ) * d kw = np.fft.ifftshift(kw) y = kwds.get('y', 1.0) if self.alpha > 0: warnings.warn('alpha parameter is not used for binned kde!') # Find the binned kernel weights, c. c = gridcount(self.dataset, X, y=y) # Perform the convolution. z = np.real(ifftn(fftn(c, s=kw.shape) * fftn(kw))) ix = (slice(0, inc),) * d if r == 0: return z[ix] * (z[ix] > 0.0) return z[ix]
def prb_empirical(self, xi=None, hs_e=None, alpha=0.05, color='r', **kwds): """Returns empirical binomial probabiltity. Parameters ---------- x : ndarray position vector y : ndarray binomial response variable (zeros and ones) alpha : scalar confidence level color: used in plot Returns ------- P(x) : PlotData object empirical probability """ if xi is None: xi = self.get_grid(hs_e) x = self.x y = self.y c = gridcount(x, xi) # + self.a + self.b # count data if np.any(y == 1): c0 = gridcount(x[y == 1], xi) # + self.a # count success else: c0 = np.zeros(np.shape(xi)) prb = np.where(c == 0, 0, c0 / (c + _TINY)) # assume prb==0 for c==0 CI = np.vstack(self.prb_ci(c, prb, alpha)) prb_e = PlotData(prb, xi, plotmethod='plot', plot_args=['.'], plot_kwds=dict(markersize=6, color=color, picker=5)) prb_e.dataCI = CI.T prb_e.count = c return prb_e
def test_gridcount_1d(): data = DATA1D x = np.linspace(0, max(data) + 1, 10) dx = x[1] - x[0] c = wkg.gridcount(data, x) assert_allclose(c.sum(), len(data)) assert_allclose(c, [ 0.1430937435034, 5.864465648665, 9.418694957317207, 2.9154367000439, 0.6583089504704, 0.0, 0.12255097773682266, 0.8774490222631774, 0.0, 0.0 ]) t = np.trapz(c / dx / len(data), x) assert_allclose(t, 0.9964226564124143)
def test_gridcount_2d(): N = 20 data = DATA2D x = np.linspace(0, max(np.ravel(data)) + 1, 5) dx = x[1] - x[0] X = np.vstack((x, x)) c = wkg.gridcount(data, X) assert_allclose(c.sum(), N) assert_allclose(c, [[0.38922806, 0.8987982, 0.34676493, 0.21042807, 0.], [1.15012203, 5.16513541, 3.19250588, 0.55420752, 0.], [0.74293418, 3.42517219, 1.97923195, 0.76076621, 0.], [0.02063536, 0.31054405, 0.71865964, 0.13486633, 0.], [0., 0., 0., 0., 0.]], 1e-5) t = np.trapz(np.trapz(c / (dx**2 * N), x), x) assert_allclose(t, 0.9011618785736376)
def test_gridcount_3d(): N = 20 data = DATA3D x = np.linspace(0, max(np.ravel(data)) + 1, 3) dx = x[1] - x[0] X = np.vstack((x, x, x)) c = wkg.gridcount(data, X) assert_allclose(c.sum(), N) assert_allclose(c, [[[8.74229894e-01, 1.27910940e+00, 1.42033973e-01], [1.94778915e+00, 2.59536282e+00, 3.28213680e-01], [1.08429416e-01, 1.69571495e-01, 7.48896775e-03]], [[1.44969128e+00, 2.58396370e+00, 2.45459949e-01], [2.28951650e+00, 4.49653348e+00, 2.73167915e-01], [1.10905565e-01, 3.18733817e-01, 1.12880816e-02]], [[7.49265424e-02, 2.18142488e-01, 0.0], [8.53886762e-02, 3.73415131e-01, 0.0], [4.16196568e-04, 1.62218824e-02, 0.0]]]) t = np.trapz(np.trapz(np.trapz(c / dx**3 / N, x), x), x) assert_allclose(t, 0.5164999727560187)
def test_gridcount_4d(): N = 10 data = np.reshape(DATA2D, (4, N)) x = np.linspace(0, max(np.ravel(data)) + 1, 3) dx = x[1] - x[0] X = np.vstack((x, x, x, x)) c = wkg.gridcount(data, X) truth = [[[[1.77163904e-01, 1.87720108e-01, 0.0], [5.72573585e-01, 6.09557834e-01, 0.0], [3.48549923e-03, 4.05931870e-02, 0.0]], [[1.83770124e-01, 2.56357594e-01, 0.0], [4.35845892e-01, 6.14958970e-01, 0.0], [3.07662204e-03, 3.58312786e-02, 0.0]], [[0.0, 0.0, 0.0], [0.0, 0.0, 0.0], [0.0, 0.0, 0.0]]], [[[3.41883175e-01, 5.97977973e-01, 0.0], [5.72071865e-01, 8.58566538e-01, 0.0], [3.46939323e-03, 4.04056116e-02, 0.0]], [[3.58861043e-01, 6.28962785e-01, 0.0], [8.80697705e-01, 1.47373158e+00, 0.0], [2.22868504e-01, 1.18008528e-01, 0.0]], [[2.91835067e-03, 2.60268355e-02, 0.0], [3.63686503e-02, 1.07959459e-01, 0.0], [1.88555613e-02, 7.06358976e-03, 0.0]]], [[[3.13810608e-03, 2.11731327e-02, 0.0], [6.71606255e-03, 4.53139824e-02, 0.0], [0.0, 0.0, 0.0]], [[7.05946179e-03, 5.44614852e-02, 0.0], [1.09099593e-01, 1.95935584e-01, 0.0], [6.61257395e-02, 2.47717418e-02, 0.0]], [[6.38695629e-04, 5.69610302e-03, 0.0], [1.00358265e-02, 2.44053065e-02, 0.0], [5.67244468e-03, 2.12498697e-03, 0.0]]]] assert_allclose(c.sum(), N) assert_allclose(c, truth) t = np.trapz(np.trapz(np.trapz(np.trapz(c / dx**4 / N, x), x), x), x) assert_allclose(t, 0.4236703654904251)
def hstt(self, data, h0=None, inc=128, maxit=100, releps=0.01, abseps=0.0): '''HSTT Scott-Tapia-Thompson estimate of smoothing parameter. CALL: hs = hstt(data,kernel) hs = one dimensional value for smoothing parameter given the data and kernel. size 1 x D data = data matrix, size N x D (D = # dimensions ) kernel = 'epanechnikov' - Epanechnikov kernel. (default) 'biweight' - Bi-weight kernel. 'triweight' - Tri-weight kernel. 'triangular' - Triangular kernel. 'gaussian' - Gaussian kernel 'rectangular' - Rectangular kernel. 'laplace' - Laplace kernel. 'logistic' - Logistic kernel. HSTT returns Scott-Tapia-Thompson (STT) estimate of smoothing parameter. This is a Solve-The-Equation rule (STE). Simulation studies shows that the STT estimate of HS is a good choice under a variety of models. A comparison with likelihood cross-validation (LCV) indicates that LCV performs slightly better for short tailed densities. However, STT method in contrast to LCV is insensitive to outliers. Examples -------- x = rndnorm(0,1,50,1); hs = hstt(x,'gauss'); See also -------- hste, hbcv, hboot, hos, hldpi, hlscv, hscv, kde, kdebin References ---------- B. W. Silverman (1986) 'Density estimation for statistics and data analysis' Chapman and Hall, pp 57--61 ''' A = np.atleast_2d(data) d, n = A.shape amise_constant = self.kernel.get_amise_constant(n) ste_constant = self.kernel.get_ste_constant(n) sigmaA = self.hns(A) / amise_constant if h0 is None: h0 = sigmaA * amise_constant h = np.asarray(h0, dtype=float) ax1, bx1 = self._get_grid_limits(A) for dim in range(d): s = sigmaA[dim] datan = A[dim] / s ax = ax1[dim] / s bx = bx1[dim] / s xa = np.linspace(ax, bx, inc) xn = np.linspace(0, bx - ax, inc) c = gridcount(datan, xa) count = 1 h_old = 0 h1 = h[dim] / s delta = (bx - ax) / (inc - 1) while ((abs(h_old - h1) > max(releps * h1, abseps)) and (count < maxit)): count += 1 h_old = h1 kw4 = self.kernel(xn / h1) / (n * h1 * self.norm_factor(d=1)) kw = np.r_[kw4, 0, kw4[-1:0:-1]] # Apply 'fftshift' to kw. f = np.real(ifft(fft(c, 2 * inc) * fft(kw))) # convolution. # Estimate psi4=R(f'') using simple finite differences and # quadrature. ix = np.arange(1, inc - 1) z = ((f[ix + 1] - 2 * f[ix] + f[ix - 1]) / delta ** 2) ** 2 psi4 = delta * z.sum() h1 = (ste_constant / psi4) ** (1. / 5) _assert_warn(count < maxit, 'The obtained value did not converge.') h[dim] = h1 * s # end # for dim loop return h
def hisj(self, data, inc=512, L=7): ''' HISJ Improved Sheather-Jones estimate of smoothing parameter. Unlike many other implementations, this one is immune to problems caused by multimodal densities with widely separated modes. The estimation does not deteriorate for multimodal densities, because it do not assume a parametric model for the data. Parameters ---------- data - a vector of data from which the density estimate is constructed inc - the number of mesh points used in the uniform discretization Returns ------- bandwidth - the optimal bandwidth References ---------- Z. I. Botev, J. F. Grotowski, and D. P. Kroese (2010) "Kernel density estimation via diffusion" Annals of Statistics, Volume 38, Number 5, pages 2916-2957. ''' A = np.atleast_2d(data) d, n = A.shape ste_constant = self.kernel.get_ste_constant(n) ax1, bx1 = self._get_grid_limits(A) ste_constant2 = _GAUSS_KERNEL.get_ste_constant(n) def fixed_point(t, N, I, a2): ''' this implements the function t-zeta*gamma^[L](t)''' prod = np.prod # L = 7 logI = np.log(I) def fun(s, time): return (2 * pi ** (2 * s) * (a2 * exp(s * logI - I * pi ** 2 * time)).sum()) f = fun(L, t) for s in range(L - 1, 1, -1): K0 = prod(np.r_[1:2 * s:2]) / sqrt(2 * pi) const = (1 + (1. / 2) ** (s + 1. / 2)) / 3 time = (2 * const * K0 / N / f) ** (2. / (3 + 2 * s)) f = fun(s, time) return t - (2 * N * sqrt(pi) * f) ** (-2. / 5) h = np.empty(d) for dim in range(d): ax, bx = ax1[dim], bx1[dim] xa = np.linspace(ax, bx, inc) R = bx - ax c = gridcount(A[dim], xa) N = len(set(A[dim])) a = dct(c / len(A[dim]), norm=None) # now compute the optimal bandwidth^2 using the referenced method I = np.asfarray(np.arange(1, inc)) ** 2 a2 = (a[1:] / 2) ** 2 x = np.linspace(0, 0.1, 150) ai = x[0] bi = x[1] f0 = fixed_point(ai, N, I, a2) for xi in x[1:]: bi = xi f1 = fixed_point(bi, N, I, a2) if f1 * f0 <= 0: # print('ai = %g, bi = %g' % (ai,bi)) break else: ai = xi # use fzero to solve the equation t=zeta*gamma^[5](t) try: t_star = optimize.brentq(lambda t: fixed_point(t, N, I, a2), a=ai, b=bi) except Exception as err: t_star = 0.28 * N ** (-2. / 5) warnings.warn('Failure in obtaining smoothing parameter' ' ({})'.format(str(err))) # smooth the discrete cosine transform of initial data using t_star # a_t = a*exp(-np.arange(inc)**2*pi**2*t_star/2) # now apply the inverse discrete cosine transform # density = idct(a_t)/R; # take the rescaling of the data into account bandwidth = sqrt(t_star) * R # Kernel other than Gaussian scale bandwidth h[dim] = bandwidth * (ste_constant / ste_constant2) ** (1.0 / 5) # end for dim loop return h
def hste(self, data, h0=None, inc=128, maxit=100, releps=0.01, abseps=0.0): '''HSTE 2-Stage Solve the Equation estimate of smoothing parameter. CALL: hs = hste(data,kernel,h0) hs = one dimensional value for smoothing parameter given the data and kernel. size 1 x D data = data matrix, size N x D (D = # dimensions ) kernel = 'gaussian' - Gaussian kernel (default) ( currently the only supported kernel) h0 = initial starting guess for hs (default h0=hns(A,kernel)) Examples -------- x = rndnorm(0,1,50,1); hs = hste(x,'gauss'); See also -------- hbcv, hboot, hos, hldpi, hlscv, hscv, hstt, kde, kdefun References ---------- B. W. Silverman (1986) 'Density estimation for statistics and data analysis' Chapman and Hall, pp 57--61 Wand,M.P. and Jones, M.C. (1986) 'Kernel smoothing' Chapman and Hall, pp 74--75 ''' A = np.atleast_2d(data) d, n = A.shape amise_constant = self.kernel.get_amise_constant(n) ste_constant = self.kernel.get_ste_constant(n) sigmaA = self.hns(A) / amise_constant if h0 is None: h0 = sigmaA * amise_constant h = np.asarray(h0, dtype=float) ax1, bx1 = self._get_grid_limits(A) mu2, R = _GAUSS_KERNEL.stats[:2] ste_constant2 = _GAUSS_KERNEL.get_ste_constant(n) for dim in range(d): s = sigmaA[dim] ax = ax1[dim] bx = bx1[dim] xa = np.linspace(ax, bx, inc) xn = np.linspace(0, bx - ax, inc) c = gridcount(A[dim], xa) psi6NS = _GAUSS_KERNEL.psi(6, s) psi8NS = _GAUSS_KERNEL.psi(8, s) k40, k60 = _GAUSS_KERNEL.deriv4_6_8_10(0, numout=2) g1 = self._get_g(k40, mu2, psi6NS, n, order=6) g2 = self._get_g(k60, mu2, psi8NS, n, order=8) psi4 = self._estimate_psi(c, xn, g1, n, order=4) psi6 = self._estimate_psi(c, xn, g2, n, order=6) h1 = h[dim] h_old = 0 count = 0 while ((abs(h_old - h1) > max(releps * h1, abseps)) and (count < maxit)): count += 1 h_old = h1 gamma_ = ((2 * k40 * mu2 * psi4 * h1 ** 5) / (-psi6 * R)) ** (1.0 / 7) psi4Gamma = self._estimate_psi(c, xn, gamma_, n, order=4) h1 = (ste_constant2 / psi4Gamma) ** (1.0 / 5) # Kernel other than Gaussian scale bandwidth h1 = h1 * (ste_constant / ste_constant2) ** (1.0 / 5) _assert_warn(count < maxit, 'The obtained value did not converge.') h[dim] = h1 # end for dim loop return h
def hldpi(self, data, L=2, inc=128): '''HLDPI L-stage Direct Plug-In estimate of smoothing parameter. CALL: hs = hldpi(data,kernel,L) hs = one dimensional value for smoothing parameter given the data and kernel. size 1 x D data = data matrix, size N x D (D = # dimensions ) kernel = 'epanechnikov' - Epanechnikov kernel. 'biweight' - Bi-weight kernel. 'triweight' - Tri-weight kernel. 'triangluar' - Triangular kernel. 'gaussian' - Gaussian kernel 'rectangular' - Rectanguler kernel. 'laplace' - Laplace kernel. 'logistic' - Logistic kernel. L = 0,1,2,3,... (default 2) Note that only the first 4 letters of the kernel name is needed. Examples -------- x = rndnorm(0,1,50,1); hs = hldpi(x,'gauss',1); See also -------- hste, hbcv, hboot, hos, hlscv, hscv, hstt, kde, kdefun References ---------- Wand,M.P. and Jones, M.C. (1995) 'Kernel smoothing' Chapman and Hall, pp 67--74 ''' A = np.atleast_2d(data) d, n = A.shape amise_constant = self.kernel.get_amise_constant(n) ste_constant = self.kernel.get_ste_constant(n) sigmaA = self.hns(A) / amise_constant ax1, bx1 = self._get_grid_limits(A) mu2 = _GAUSS_KERNEL.stats[0] h = np.zeros(d) for dim in range(d): s = sigmaA[dim] datan = A[dim] # / s ax = ax1[dim] # / s bx = bx1[dim] # / s xa = np.linspace(ax, bx, inc) xn = np.linspace(0, bx - ax, inc) c = gridcount(datan, xa) psi = _GAUSS_KERNEL.psi(r=2 * L + 4, sigma=s) if L > 0: # High order derivatives of the Gaussian kernel Kd = _GAUSS_KERNEL.deriv4_6_8_10(0, numout=L) # L-stage iterations to estimate PSI_4 for ix in range(L, 0, -1): gi = self._get_g(Kd[ix - 1], mu2, psi, n, order=2 * ix + 4) psi = self._estimate_psi(c, xn, gi, n, order=2 * ix + 2) h[dim] = (ste_constant / psi) ** (1. / 5) return h
def hscv(self, data, hvec=None, inc=128, maxit=100, fulloutput=False): ''' HSCV Smoothed cross-validation estimate of smoothing parameter. Parameters ---------- data = data vector hvec = vector defining possible values of hs (default linspace(0.25*h0,h0,100), h0=0.62) inc = length of estimated kerneldensity estimate maxit = maximum number of iterations fulloutput = True if fulloutput is wanted Returns ------- hs = smoothing parameter hvec = vector defining possible values of hs score = score vector Examples -------- >>> import wafo.kdetools as wk >>> import wafo.stats as ws >>> data = ws.norm.rvs(0,1, size=(1,20)) >>> kernel = wk.Kernel('epan') >>> hs0 = kernel.hscv(data, fulloutput=False) >>> hs, hvec, score = kernel.hscv(data, fulloutput=True) >>> np.allclose(hs, hs0) True import matplotlib.pyplot as plt plt.plot(hvec, score) See also: hste, hbcv, hboot, hos, hldpi, hlscv, hstt, kde, kdefun References ---------- Wand,M.P. and Jones, M.C. (1986) 'Kernel smoothing' Chapman and Hall, pp 75--79 ''' A = np.atleast_2d(data) d, n = A.shape amise_constant = self.kernel.get_amise_constant(n) ste_constant = self.kernel.get_ste_constant(n) sigmaA = self.hns(A) / amise_constant if hvec is None: H = amise_constant / 0.93 hvec = np.linspace(0.25 * H, H, maxit) hvec = np.asarray(hvec, dtype=float) steps = len(hvec) score = np.zeros(steps) ax1, bx1 = self._get_grid_limits(A) ste_constant2 = _GAUSS_KERNEL.get_ste_constant(n) h = np.zeros(d) hvec = hvec * (ste_constant2 / ste_constant) ** (1. / 5.) k40, k60, k80, k100 = _GAUSS_KERNEL.deriv4_6_8_10(0, numout=4) mu2 = _GAUSS_KERNEL.stats[0] # psi8 = _GAUSS_KERNEL.psi(8) # psi12 = _GAUSS_KERNEL.psi(12) psi8 = 105 / (32 * sqrt(pi)) psi12 = 3465. / (512 * sqrt(pi)) g1 = self._get_g(k60, mu2, psi8, n, order=8) g2 = self._get_g(k100, mu2, psi12, n, order=12) for dim in range(d): s = sigmaA[dim] ax = ax1[dim] / s bx = bx1[dim] / s datan = A[dim] / s xa = np.linspace(ax, bx, inc) xn = np.linspace(0, bx - ax, inc) c = gridcount(datan, xa) psi6 = self._estimate_psi(c, xn, g1, n, order=6) psi10 = self._estimate_psi(c, xn, g2, n, order=10) g3 = self._get_g(k40, mu2, psi6, n, order=6) g4 = self._get_g(k80, mu2, psi10, n, order=10) psi4 = self._estimate_psi(c, xn, g3, n, order=4) psi8 = self._estimate_psi(c, xn, g4, n, order=8) const = ((441. / (64 * pi)) ** (1. / 18.) * (4 * pi) ** (-1. / 5.) * psi4 ** (-2. / 5.) * psi8 ** (-1. / 9.)) M = np.atleast_2d(datan) Y = (M - M.T).ravel() for i in range(steps): g = const * n ** (-23. / 45) * hvec[i] ** (-2) sig1 = sqrt(2 * hvec[i] ** 2 + 2 * g ** 2) sig2 = sqrt(hvec[i] ** 2 + 2 * g ** 2) sig3 = sqrt(2 * g ** 2) term2 = np.sum(_GAUSS_KERNEL(Y / sig1) / sig1 - 2 * _GAUSS_KERNEL(Y / sig2) / sig2 + _GAUSS_KERNEL(Y / sig3) / sig3) score[i] = 1. / (n * hvec[i] * 2. * sqrt(pi)) + term2 / n ** 2 idx = score.argmin() # Kernel other than Gaussian scale bandwidth h[dim] = hvec[idx] * (ste_constant / ste_constant2) ** (1 / 5) _assert_warn(0 < idx, "Optimum is probably lower than " "hs={0:g} for dim={1:d}".format(h[dim] * s, dim)) _assert_warn(idx < maxit - 1, "Optimum is probably higher than " "hs={0:g} for dim={1:d}".format(h[dim] * s, dim)) hvec = hvec * (ste_constant / ste_constant2) ** (1 / 5) if fulloutput: return h * sigmaA, score, hvec return h * sigmaA