liveBook · Manning

Kernel density estimate

As explained in Machine Learning Algorithms in Depth

A nonparametric technique that estimates a probability density by combining localized kernel functions centered on observations.

A kernel density estimate (KDE) models a probability density by placing one localized kernel at every observed data point and averaging their contributions. With a Gaussian kernel, the estimate averages Gaussians centered on the observations; a general kernel κ(x) provides the broader formulation. section 9.2.1

Use KDE when choosing a parametric density model or mixture count is undesirable:

  • Avoid model fitting apart from fine-tuning the bandwidth parameter h. section 9.2.1
  • Avoid selecting the number of mixture components K, because every observation supplies a cluster center. section 9.2.1 section 9.8
  • Trade memory and evaluation speed for accuracy, making KDE most suitable for relatively small datasets. section 9.2.1
  • Adjust smoothing through the bandwidth; the resulting density can be compared with a histogram, whose smoothing depends on bin size. section 9.2.1 section 9.6

RNA-seq promoter-flux estimation

Estimate the flux of a T7 promoter from RNA-seq data, then compare a histogram-based density estimate with a Gaussian KDE. The Gaussian estimate appears smoother, while its smoothing can be further tuned through the bandwidth. section 9.2.1

Listing 9.2 Kernel density estimate
import numpy as np
import matplotlib.pyplot as plt

class KDE():

    def __init__(self):
        #Histogram and Gaussian Kernel Estimator used to
        #analyze RNA-seq data for flux estimation of a T7 promoter
        self.G = 1e9     #1
        self.C = 1e3     #2
        self.L = 100     #3
        self.N = 1e6     #4
        self.M = 1e4    #5
        self.LN = 1000     #6
        self.FDR = 0.05     #7

        #uniform sampling (poisson model)
        self.lmbda = (self.N * self.L) / self.G     #8
        self.C_est = self.M/(1-np.exp(-self.lmbda))     #9
        self.C_cvrg = self.G - self.G * 
         np.exp(-self.lmbda)     #10
        self.N_gaps = self.N * np.exp(-self.lmbda)    #11

        #gamma prior sampling (negative binomial model)
        #X = "number of failures before rth success"
        self.k = 0.5     #12
        self.p = self.lmbda/(self.lmbda + 1/self.k)     #13
        self.r = 1/self.k     #14

        #RNAP binding data (RNA-seq)
        self.data = np.random.negative_binomial(self.r, self.p, size=self.LN)

    def histogram(self):
        self.bin_delta = 1     #15
        self.bin_range = np.arange(1, np.max(self.data), self.bin_delta)
        self.bin_counts, _ = np.histogram(self.data, bins=self.bin_range)

        #histogram density estimation 
        #P = integral_R p(x) dx, where X is in R^3
        #p(x) = K/(NxV), where K=number of points in region R
        #N=total number of points, V=volume of region R

        rnap_density_est = self.bin_counts/(sum(self.bin_counts) * 
         self.bin_delta)
        return rnap_density_est

    def kernel(self):
        #Gaussian kernel density estimator with smoothing parameter h
        #sum N Guassians centered at each data point, parameterized by 
         common std dev h

        x_dim = 1     #16
        h = 10     #17

        rnap_density_support = np.arange(np.max(self.data))
        rnap_density_est = 0
        for i in range(np.sum(self.bin_counts)):
            rnap_density_est += (1/(2*np.pi*h**2)**(x_dim/2.0))*np.exp(-
             (rnap_density_support - self.data[i])**2 / (2.0*h**2))
        #end for

        rnap_density_est = rnap_density_est / np.sum(rnap_density_est)
        return rnap_density_est

if __name__ == "__main__":

    kde = KDE()
    est1 = kde.histogram()
    est2 = kde.kernel()

    plt.figure()
    plt.plot(est1, c='b', label='histogram')
    plt.plot(est2, c='r', label='gaussian kernel')
    plt.title("RNA-seq density estimate based on negative binomial sampling 
     model")
    plt.xlabel("read length, [base pairs]"); plt.ylabel("density"); 
     plt.legend()
    plt.show()

A Python implementation defines a KDE class and sets computational and probabilistic parameters for the RNA-seq analysis, including a Poisson sampling model and a negative binomial model. section 9.2.1

How Machine Learning Algorithms in Depth covers it

How deep it goes
Explains Gaussian and general kernels, bandwidth smoothing, trade-offs, and implementation, but defers efficient tree-based evaluation.
Examples
Applies Gaussian KDE to RNA-seq data for estimating T7 promoter flux and compares it with a histogram.
What you can do after
Apply KDE to estimate and compare data densities, tune bandwidth smoothing, and recognize memory and evaluation costs.
How it connects
Connects kernel smoothing with mixture models, histograms, negative binomial models, and ball tree or KD tree evaluation.

Also explained in

Compare how 2 books explain kernel density estimate →

Related concepts

This explainer was generated by Manning's knowledge graph from the text of Machine Learning Algorithms in Depth. The section links point to the parts of the book it draws on.