Мне нужно рассчитать площадь, где две функции перекрываются. Я использую обычные дистрибутивы в этом упрощенном примере, но мне нужна более общая процедура, которая также адаптируется к другим функциям.Рассчитайте площадь перекрытия двух функций
См изображение ниже, чтобы получить представление о том, что я имею в виду, где красная зона, что я после:
Это MWE у меня до сих пор:
import matplotlib.pyplot as plt
import numpy as np
from scipy import stats
# Generate random data uniformly distributed.
a = np.random.normal(1., 0.1, 1000)
b = np.random.normal(1., 0.1, 1000)
# Obtain KDE estimates foe each set of data.
xmin, xmax = -1., 2.
x_pts = np.mgrid[xmin:xmax:1000j]
# Kernels.
ker_a = stats.gaussian_kde(a)
ker_b = stats.gaussian_kde(b)
# KDEs for plotting.
kde_a = np.reshape(ker_a(x_pts).T, x_pts.shape)
kde_b = np.reshape(ker_b(x_pts).T, x_pts.shape)
# Random sample from a KDE distribution.
sample = ker_a.resample(size=1000)
# Compute the points below which to integrate.
iso = ker_b(sample)
# Filter the sample.
insample = ker_a(sample) < iso
# As per Monte Carlo, the integral is equivalent to the
# probability of drawing a point that gets through the
# filter.
integral = insample.sum()/float(insample.shape[0])
print integral
plt.xlim(0.4,1.9)
plt.plot(x_pts, kde_a)
plt.plot(x_pts, kde_b)
plt.show()
, где я применяю Monte Carlo
для получения интеграла.
Проблема этого метода состоит в том, что, когда я оценить выборку точек в любом распределении с ker_b(sample)
(или ker_a(sample)
), я получаю значения размещены непосредственно над линию KDE. Из-за этого даже четко перекрывающиеся распределения, которые должны возвращать общее/перекрываемое значение области, очень близкое к 1. возвращают вместо этого небольшие значения (общая площадь любой кривой равна 1., так как они являются оценками плотности вероятности).
Как я могу исправить этот код, чтобы дать ожидаемые результаты?
Это, как я применил ответ Жени
# Calculate overlap between the two KDEs.
def y_pts(pt):
y_pt = min(ker_a(pt), ker_b(pt))
return y_pt
# Store overlap value.
overlap = quad(y_pts, -1., 2.)
http://stackoverflow.com/questions/15361125/calculate-area-between-two-curves-that-are-normal-distributions/15361352#15361352 –
Я собираюсь над вашим ответом в вопросе, который вы связали, и, похоже, он применим и здесь, хотя первоначально предполагал, что он будет работать только для нормальных распределений. Не могли бы вы опубликовать свой комментарий в форме ответа? Таким образом, если он работает, я могу отметить его как принятый. Спасибо. – Gabriel
Этот ответ использует квадратуру - это вариант здесь? Если необходимо использовать Монте-Карло, тогда код выше нуждается в нескольких изменениях. Хотелось бы, чтобы я понял ваши окончательные комментарии - предложение, начинающееся с «Я получаю значения, размещенные непосредственно над KDE ...», является для меня штопором. –