# Sampling from a KDE object

**URL:** https://discourse.julialang.org/t/sampling-from-a-kde-object/121604
**Category:** Statistics
**Tags:** kernel
**Created:** [October 22, 2024, 5:40pm UTC](https://discourse.julialang.org/t/sampling-from-a-kde-object/121604 "2024-10-22T17:40:11Z")
**Posts on this page:** 5
**Page:** 1

<div class="post-metadata">

### Author: ![miguelborrero](https://avatars.discourse-cdn.com/v4/letter/m/eb9ed0/32.png) [@miguelborrero](https://discourse.julialang.org/u/miguelborrero)
#### Post date: [October 22, 2024, 5:40pm UTC](https://discourse.julialang.org/t/sampling-from-a-kde-object/121604/1 "2024-10-22T17:40:11Z")

</div>

Hi there,

I estimated the density for a variable of interest using the `kde()` function from `KernelDensity.jl` package. Is there not a built-in/efficient function that samples from this estimated density?

Thanks a lot!

---

<div class="post-metadata">

### Author: ![sethaxen](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/sethaxen/32/35604_2.png) [@sethaxen](https://discourse.julialang.org/u/sethaxen)
#### Post date: [October 22, 2024, 6:20pm UTC](https://discourse.julialang.org/t/sampling-from-a-kde-object/121604/2 "2024-10-22T18:20:20Z")

</div>

This is really straightforward to do if one has a copy of the data, the bandwidth, and the kernel, since a KDE is just a uniformly weighted mixture whose components are the kernel centered on each data point, but the object returned by `kde` stores none of these. See e.g. [Make KDE a distribution and implement other Distributions method · Issue #58 · JuliaStats/KernelDensity.jl · GitHub](https://github.com/JuliaStats/KernelDensity.jl/issues/58)

---

<div class="post-metadata">

### Author: ![miguelborrero](https://avatars.discourse-cdn.com/v4/letter/m/eb9ed0/32.png) [@miguelborrero](https://discourse.julialang.org/u/miguelborrero)
#### Post date: [October 22, 2024, 6:31pm UTC](https://discourse.julialang.org/t/sampling-from-a-kde-object/121604/3 "2024-10-22T18:31:55Z")

</div>

Thanks for the reply. I’ve been through the comments but I still do not see how this is really straightforward. Maybe its just that I am very unexperienced.

---

<div class="post-metadata">

### Author: ![sethaxen](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/sethaxen/32/35604_2.png) [@sethaxen](https://discourse.julialang.org/u/sethaxen)
#### Post date: [October 22, 2024, 7:04pm UTC](https://discourse.julialang.org/t/sampling-from-a-kde-object/121604/4 "2024-10-22T19:04:27Z")

</div>

Here’s a minimal demo:

```julia
using Distributions: Distributions
using KernelDensity: KernelDensity

# Like KernelDensity.UnivariateKDE, but store also the data and (kernel) distribution we need to build a Distributions-like object.
struct UnivariateKDE{
    D<:AbstractVector{<:Real},
    R<:KernelDensity.UnivariateKDE,
    K<:Distributions.UnivariateDistribution,
}
    data::D
    dist::K
    kde::R
end

function kde(
    data::AbstractVector{<:Real};
    bandwidth=KernelDensity.default_bandwidth(data),
    kernel=Normal,
    kwargs...
)
    dist = KernelDensity.kernel_dist(kernel, bandwidth)
    k = KernelDensity.kde(data, dist; kwargs...)
    return UnivariateKDE(data, dist, k)
end

# A KDE is just a uniform mixture of the kernel shifted to each data point
function Base.convert(::Type{<:Distributions.Distribution}, kde::UnivariateKDE)
    components = map(kde.data) do x
        return x + kde.dist
    end
    return Distributions.MixtureModel(components)
end

using Distributions, StatsPlots

dist = MixtureModel([Normal(0, 1), Normal(3, 3)])
data = rand(dist, 1_000)
k = kde(data)
kde_dist = convert(Distributions.Distribution, k)
p = plot(dist; components=false, label="true dist", lw=2)
plot!(k.kde; label="KDE.jl dist", lw=2)
plot!(kde_dist; components=false, label="KDE mixture", lw=1)
density!(rand(kde_dist, 100_000), lw=2, label="KDE mixture rand")

```

 ![image](https://global.discourse-cdn.com/julialang/original/3X/8/5/85950d6babd34e4f130dba5951496dc283f253df.png)

---

<div class="post-metadata">

### Author: ![miguelborrero](https://avatars.discourse-cdn.com/v4/letter/m/eb9ed0/32.png) [@miguelborrero](https://discourse.julialang.org/u/miguelborrero)
#### Post date: [October 23, 2024, 8:54pm UTC](https://discourse.julialang.org/t/sampling-from-a-kde-object/121604/5 "2024-10-23T20:54:06Z")

</div>

Thanks a lot!
