Exemple #1
0
    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]
Exemple #2
0
    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
Exemple #3
0
    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)
Exemple #4
0
    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)
Exemple #5
0
    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)
Exemple #6
0
    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)
Exemple #7
0
    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
Exemple #8
0
    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
Exemple #9
0
    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
Exemple #10
0
    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
Exemple #11
0
    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