Thursday, September 29, 2022

Simple 1D Kernel Density Estimation

 Оценка плотности проходит грань между неконтролируемым обучением, проектированием признаков и моделированием данных. Некоторыми из наиболее популярных и полезных методов оценки плотности являются смешанные модели, такие как гауссовские смеси (GaussianMixture), и подходы на основе соседей, такие как оценка плотности ядра (KernelDensity). Гауссовские смеси более подробно обсуждаются в контексте кластеризации, потому что этот метод также полезен в качестве неконтролируемой схемы кластеризации. Хотя в приведенном выше примере для простоты используется одномерный набор данных, оценка плотности ядра может выполняться в любом количестве измерений, хотя на практике проклятие размерности приводит к ухудшению производительности в больших измерениях.

Пример где класс KernelDensity используется для демонстрации принципов оценки плотности ядра в одном измерении.

На первом плоте показана одна из проблем использования гистограмм для визуализации плотности точек в 1D. Интуитивно гистограмму можно представить как схему, в которой единичный «блок» расположен над каждой точкой регулярной сетки. Однако, как показывают две верхние панели, выбор сетки для этих блоков может привести к совершенно разным представлениям об основной форме распределения плотности. Если вместо этого мы центрируем каждый блок по точке, которую он представляет, мы получаем оценку, показанную на нижней левой панели. Это оценка плотности ядра с ядром «цилиндр». 

Scikit-learn реализует эффективную оценку плотности ядра с использованием структуры Ball Tree или KD Tree с помощью оценщика KernelDensity. Все доступные ядра показаны на втором плоте.На третьем плоте сравниваются оценки плотности ядра для распределения 100 выборок в 1 измерении. Хотя в этом примере используются одномерные распределения, оценка плотности ядра также легко и эффективно расширяется до более высоких измерений.

(.env) boris@UbuntuLTS:~/PARZEN$ cat plottingKDE1D.py

import numpy as np

import matplotlib.pyplot as plt

from scipy.stats import norm

from sklearn.neighbors import KernelDensity

# Plot the progression of histograms to kernels

np.random.seed(1)

N = 20

X = np.concatenate(

    (np.random.normal(0, 1, int(0.3 * N)), np.random.normal(5, 1, int(0.7 * N)))

)[:, np.newaxis]

X_plot = np.linspace(-5, 10, 1000)[:, np.newaxis]

bins = np.linspace(-5, 10, 10)

fig, ax = plt.subplots(2, 2, sharex=True, sharey=True)

fig.subplots_adjust(hspace=0.05, wspace=0.05)

# histogram 1

ax[0, 0].hist(X[:, 0], bins=bins, fc="#AAAAFF", density=True)

ax[0, 0].text(-3.5, 0.31, "Histogram")

# histogram 2

ax[0, 1].hist(X[:, 0], bins=bins + 0.75, fc="#AAAAFF", density=True)

ax[0, 1].text(-3.5, 0.31, "Histogram, bins shifted")

# tophat KDE

kde = KernelDensity(kernel="tophat", bandwidth=0.75).fit(X)

log_dens = kde.score_samples(X_plot)

ax[1, 0].fill(X_plot[:, 0], np.exp(log_dens), fc="#AAAAFF")

ax[1, 0].text(-3.5, 0.31, "Tophat Kernel Density")

# Gaussian KDE

kde = KernelDensity(kernel="gaussian", bandwidth=0.75).fit(X)

log_dens = kde.score_samples(X_plot)

ax[1, 1].fill(X_plot[:, 0], np.exp(log_dens), fc="#AAAAFF")

ax[1, 1].text(-3.5, 0.31, "Gaussian Kernel Density")

for axi in ax.ravel():

    axi.plot(X[:, 0], np.full(X.shape[0], -0.01), "+k")

    axi.set_xlim(-4, 9)

    axi.set_ylim(-0.02, 0.34)

for axi in ax[:, 0]:

    axi.set_ylabel("Normalized Density")

for axi in ax[1, :]:

    axi.set_xlabel("x")

# Plot all available kernels

X_plot = np.linspace(-6, 6, 1000)[:, None]

X_src = np.zeros((1, 1))

fig, ax = plt.subplots(2, 3, sharex=True, sharey=True)

fig.subplots_adjust(left=0.05, right=0.95, hspace=0.05, wspace=0.05)

def format_func(x, loc):

    if x == 0:

        return "0"

    elif x == 1:

        return "h"

    elif x == -1:

        return "-h"

    else:

        return "%ih" % x

for i, kernel in enumerate(

    ["gaussian", "tophat", "epanechnikov", "exponential", "linear", "cosine"]

):

    axi = ax.ravel()[i]

    log_dens = KernelDensity(kernel=kernel).fit(X_src).score_samples(X_plot)

    axi.fill(X_plot[:, 0], np.exp(log_dens), "-k", fc="#AAAAFF")

    axi.text(-2.6, 0.95, kernel)

    axi.xaxis.set_major_formatter(plt.FuncFormatter(format_func))

    axi.xaxis.set_major_locator(plt.MultipleLocator(1))

    axi.yaxis.set_major_locator(plt.NullLocator())

    axi.set_ylim(0, 1.05)

    axi.set_xlim(-2.9, 2.9)

ax[0, 1].set_title("Available Kernels")


# Plot a 1D density example

N = 100

np.random.seed(1)

X = np.concatenate(

    (np.random.normal(0, 1, int(0.3 * N)), np.random.normal(5, 1, int(0.7 * N)))

)[:, np.newaxis]

X_plot = np.linspace(-5, 10, 1000)[:, np.newaxis]

true_dens = 0.3 * norm(0, 1).pdf(X_plot[:, 0]) + 0.7 * norm(5, 1).pdf(X_plot[:, 0])

fig, ax = plt.subplots()

ax.fill(X_plot[:, 0], true_dens, fc="black", alpha=0.2, label="input distribution")

colors = ["navy", "cornflowerblue", "darkorange"]

kernels = ["gaussian", "tophat", "epanechnikov"]

lw = 2

for color, kernel in zip(colors, kernels):

    kde = KernelDensity(kernel=kernel, bandwidth=0.5).fit(X)

    log_dens = kde.score_samples(X_plot)

    ax.plot(

        X_plot[:, 0],

        np.exp(log_dens),

        color=color,

        lw=lw,

        linestyle="-",

        label="kernel = '{0}'".format(kernel),

    )

ax.text(6, 0.38, "N={0} points".format(N))

ax.legend(loc="upper left")

ax.plot(X[:, 0], -0.005 - 0.01 * np.random.random(X.shape[0]), "+k")

ax.set_xlim(-4, 9)

ax.set_ylim(-0.02, 0.4)

plt.show()

Histograms and Density Plots in Python

==============================

Гистограмма — это графическое представление, которое упорядочивает группу точек данных в указанном диапазоне. Создание гистограммы обеспечивает визуальное представление распределения данных. Используя гистограмму, мы можем представить большой объем данных и их частоту.

График плотности — это непрерывная и сглаженная версия гистограммы, рассчитанная по данным. Это оценивается с помощью оценки плотности ядра.

В этом методе ядро ​​(непрерывная кривая) рисуется в каждой отдельной точке данных, а затем все эти кривые складываются вместе, чтобы получить единую сглаженную оценку плотности. Гистограмма терпит неудачу, когда мы хотим сравнить распределение данных одной переменной по нескольким категориям в то время, когда график плотности полезен для визуализации данных.

Подход:

Импортируйте необходимые библиотеки.

Создайте или импортируйте набор данных из морской библиотеки.

Выберите столбец, для которого мы должны сделать график.

Для построения графика мы используем функцию distplot(), предоставляемую библиотекой seaborn, для совместного построения гистограммы и графика плотности, в которую мы должны передать столбец набора данных.

Мы также можем сделать гистограмму и график плотности по отдельности, используя функцию distplot() в соответствии с нашими потребностями.

Для индивидуального создания гистограммы мы должны передать hist=False в качестве параметра функции distplot().

Для индивидуального создания графика плотности мы должны передать kde=False в качестве параметра функции distplot().

Теперь, после создания графика, мы должны его визуализировать, поэтому для визуализации мы должны использовать функцию show(), предоставляемую библиотекой matplotlib.pyplot.

Для совместного построения графиков гистограммы и плотности мы используем набор данных алмазов и радужной оболочки, предоставленный библиотекой Seaborn.


(.env) boris@UbuntuLTS:~/KDE3D$ cat plotHistKDE.py

# importing libraries

import seaborn as sns

import matplotlib.pyplot as plt

import warnings

warnings.filterwarnings('ignore')

# importing diamond dataset from the library

df = sns.load_dataset('diamonds')

# plotting histogram and density plot

# for carat using distplot() by setting color

sns.distplot(a=df.carat, bins=40, color='purple',

             hist_kws={"edgecolor": 'black'})

 

# visualizing plot using matplotlib.pyplot library

plt.show()

# importing libraries

import seaborn as sns

import matplotlib.pyplot as plt

# importing iris dataset from the library

df2 = sns.load_dataset('iris')

# plotting histogram and density plot for

# petal length using distplot() by setting color

sns.distplot(a=df2.petal_length, color='green',

             hist_kws={"edgecolor": 'black'})

# visualizing plot using matplotlib.pyplot library

plt.show()

















No comments:

Post a Comment