Разница между KDE и частотой гистограммы из sns.distplot

#statistics #seaborn

#Статистика #seaborn

Вопрос:

Результат, который я наблюдал на графике плотности sns, довольно запутанный.

результат для :

 sns.distplot(subset['difference_ratio'], kde = True, label =label ,hist=False).set(xlim=(0,1))
  

ниже:

введите описание изображения здесь

И результат для :

 sns.distplot(subset['difference_ratio'], kde = False, label =label ,hist=True).set(xlim=(0,1))
  

ниже:

введите описание изображения здесь

Как эти графики можно объяснить как подобное поведение?

Ответ №1:

Ось y гистограммы по умолчанию показывает количество выборок в каждой ячейке. По оси y графика kdeplot все нормализовано таким образом, что общая площадь под кривой равна единице. Настройка norm_hist=True делает что-то похожее на ось y: все значения масштабируются таким образом, что площади столбцов будут равны единице.

Гистограмма, помещающая все выборки между границами каждой ячейки, попадет в ячейку. Не имеет значения, находится ли значение слева, справа или в центре ячейки.

График kde, с другой стороны, принимает каждое отдельное значение выборки и рисует над ним небольшую гауссову колоколообразную кривую. Затем все колоколообразные кривые суммируются вместе, чтобы сформировать конечную кривую. Колоколообразная кривая имеет некоторую ширину, что делает кривую kde немного шире гистограммы. В общем, kdeplot предполагает, что базовое распределение довольно плавное и медленно стремится к нулю вблизи краев.

На следующем графике сравниваются гистограмма и график kdeplot для типичной выборки. Выборки показаны красным цветом с их положением на оси x и случайным значением y (чтобы избежать слишком большого перекрытия).

 from matplotlib import pyplot as plt
import numpy as np
import seaborn as sns

samples = np.clip(0.5   np.random.uniform(-.2, .2, (10, 10)).cumsum(axis=0).ravel(), 0, 1)

ax = sns.distplot(samples)

x, y = ax.lines[-1].get_data() # get the coordinates of the kde curve
ax.scatter(samples, [np.random.uniform(0, np.interp(samp, x, y)) for samp in samples], color='crimson')
plt.show()
  

пример графика

Обратите внимание, что кривая kde сглаживает ситуацию намного больше, чем гистограмма, и что кривая kde не стремится резко к нулю.

PS: Чтобы точно выровнять ячейки для двух (или более) дистрибутивов, обратите внимание, что количество ячеек рассчитывается исходя из количества выборок. И что границы взяты из выборочных данных. Если вы уверены, что оба набора выборок имеют одинаковый максимум и минимум, вы можете просто установить bins= одинаковое число.

Но, в целом, экстремумы различны для непрерывных распределений. В этом случае вы могли бы явно вычислить ячейки:

 xmin = min(min(samples['Detractor']), min(samples['Promoter']))
xmax = max(max(samples['Detractor']), max(samples['Promoter']))
bins = np.linspace(xmin, xmax, 10)
  

Ответ №2:

Различное поведение, наблюдаемое для одних и тех же данных, связано с тем, что общее количество ячеек отличается на графике sns (seaborn) kde и графике sns histogram. Для вычисления ячеек по умолчанию в seaborn distplot используется правило Фридмана-Диакониса, следовательно, из-за разницы в размере ячеек изменились формы графика, чтобы они выглядели иначе.

Теперь, если я использую:

  sns.distplot(subset['difference_ratio'],bins=10, kde = False, label =label ,hist=True).set(xlim=(0,1))
  

Выходной график такой же, как и график kde:

введите описание изображения здесь

Комментарии:

1. Итак, ваш настоящий вопрос заключался в том, почему ячейки не выровнены и как их выровнять? Обратите внимание, что в общем случае недостаточно просто поставить bins=10 в обоих случаях. Начало и конец вычисляются из выборок. В этом случае кажется, что оба набора образцов содержат 0 и 1. Но в случае, если экстремальные значения будут отсутствовать, вам необходимо явно рассчитать границы ячеек.