Як обчислити перекриття між емпіричними щільністю ймовірності?


14

Я шукаю метод обчислення площі перекриття між двома оцінками щільності ядра в R, як міру подібності між двома вибірками. Щоб уточнити, у наступному прикладі мені потрібно було б кількісно визначити область пурпурної області, що перекривається:

library(ggplot2)
set.seed(1234)
d <- data.frame(variable=c(rep("a", 50), rep("b", 30)), value=c(rnorm(50), runif(30, 0, 3)))
ggplot(d, aes(value, fill=variable)) + geom_density(alpha=.4, color=NA)

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

Подібне питання обговорювалося тут , різниця в тому, що мені потрібно це зробити для довільних емпіричних даних, а не заздалегідь визначених нормальних розподілів. У overlapпакеті розглядає це питання, але , мабуть , тільки для даних тимчасової мітки, яка не працює для мене. Індекс Брей-Кертіса (як реалізований у функції veganпакету vegdist(method="bray")) також здається релевантним, але знову ж таки для дещо інших даних.

Мене цікавлять і теоретичний підхід, і функції R, які я міг би використати для його реалізації.


2
"кількісна оцінка фіолетової області" є проблемою в оцінці, а не в тестуванні гіпотез, тому ви не можете сподіватися "досягти цього за допомогою стандартного статистичного тесту, що можна визначити ". Ви суперечите собі. Поясніть, будь ласка, що ви насправді хочете. Якщо все, що вам потрібно, - це оцінка площі перекриття двох KDE, це простий розрахунок.
Glen_b -Встановіть Моніку

@Glen_b дякую за коментар, допоміг з’ясувати моє нестатистичне мислення. Я вважаю, що область перекриття між KDE - це дійсно те, що я шукаю - я відредагував питання, щоб це відобразити.
mmk

2
Мене б дуже турбував ризик свавілля в цьому методі. Залежно від пропускної здатності ядра, обчислене перекриття між будь-якими двома наборами даних може бути зроблене рівним будь-якому обраному значенню в інтервалі . Ширини смуги за замовчуванням не оптимізовані для цієї мети, і, можливо, це може дати дивовижні, довільні або непослідовні результати. Набори даних із природними межами (такими як негативні дані чи пропорції тощо) надалі надаватимуть небажані наслідки. Що робити замість цього? Почніть з причини цього розрахунку: що означає «подібність»? (0,1)
whuber

Це ж питання з’явилося через кілька місяців, але воно стосувалося точок перетину, проте були деякі дійсні примітки, які можна було б врахувати. У наведеному питанні йдеться про два емпіричні розподіли. Я додаю посилання, оскільки ця публікація відповідає лише на це за допомогою оцінки щільності ядра та для звичайних розподілів. Посилання нижче, я думаю, поширюється на питання про пари емпіричних розподілів. stats.stackexchange.com/questions/122857/… - Barnaby 7 годин тому
Barnaby

Відповіді:


9

Площа накладання двох оцінок щільності ядра може бути наближена до будь-якої бажаної ступеня точності.

min(K1(x),K2(x))

Якщо вони знаходяться в різних сітках і їх неможливо легко перерахувати в одній сітці, може бути використана інтерполяція.

2) Ви можете знайти точку (або точки) перетину та інтегрувати нижню з двох KDE у кожен інтервал, де кожен нижній. У діаграмі вище ви інтегруєте синю криву ліворуч від перехрестя та рожеву - праворуч будь-якими способами, які вам подобаються / мають. Це можна зробити по суті точно, розглядаючи область під кожним компонентом ядра1hK(xxih)

Однак коментарі Уубера повинні бути чітко враховані - це не обов'язково дуже важливо робити.


Як ви обчислюєте помилку, пов’язану з методом перший та методом 2?
olliepower

У звичайних обставинах і те, і інше буде мізерно порівняно з помилкою в оцінці щільності ядра, тому я б не переживав занадто сильно. Межі помилок можна обчислити за допомогою трапецієподібних методів та іншої чисельної інтеграції, звичайно - такі розрахунки є досить стандартними - але безглуздо хвилюватися, враховуючи, що KDE мають великі невизначеності. Метод 2 буде точним до накопиченої помилки округлення обчислень.
Glen_b -Встановіть Моніку

1
Ці методичні пропозиції мають сенс, дуже дякую за вашу відповідь. Я працюю над тим, щоб це реалізувати в R, але, як новачок, мені були б цікаві пропозиції, як це чітко кодувати.
mmk

10

Для повноти, ось як я закінчив це робити в R:

# simulate two samples
a <- rnorm(100)
b <- rnorm(100, 2)

# define limits of a common grid, adding a buffer so that tails aren't cut off
lower <- min(c(a, b)) - 1 
upper <- max(c(a, b)) + 1

# generate kernel densities
da <- density(a, from=lower, to=upper)
db <- density(b, from=lower, to=upper)
d <- data.frame(x=da$x, a=da$y, b=db$y)

# calculate intersection densities
d$w <- pmin(d$a, d$b)

# integrate areas under curves
library(sfsmisc)
total <- integrate.xy(d$x, d$a) + integrate.xy(d$x, d$b)
intersection <- integrate.xy(d$x, d$w)

# compute overlap coefficient
overlap <- 2 * intersection / total

Як зазначалося, притаманна генерація KDE, а також інтеграція притаманні невизначеності та суб'єктивності.


2
Зараз на CRAN існує пакет, який називається, overlappingякий оцінює площу перекриття 2 (або більше) емпіричних розподілів. Ознайомтеся з документацією тут: rdocumentation.org/packages/overlapping/versions/1.5.0/topics/…
Стефан Аві

x,dx,dx,d

@mmk ви можете це зробити для 2D щільності?
Переповнення поліції

4

По-перше, я можу помилитися, але я думаю, що ваше рішення не буде працювати в тому випадку, коли є кілька крапок, коли оцінки щільності ядра (KDE) перетинаються. По-друге, хоча overlapпакет був створений для використання з даними часових позначок, ви все одно можете використовувати його для оцінки площі накладання будь-яких двох KDE. Вам просто потрібно змінити масштаб даних, щоб вони становили від 0 до 2π.
Для прикладу:

# simulate two sample    
 a <- rnorm(100)
 b <- rnorm(100, 2)

# To use overplapTrue(){overlap} the scale must be in radian (i.e. 0 to 2pi)
# To keep the *relative* value of a and b the same, combine a and b in the
# same dataframe before rescaling. You'll need to load the ‘scales‘ library.
# But first add a "Source" column to be able to distinguish between a and b
# after they are combined.
 a = data.frame( value = a, Source = "a" )
 b = data.frame( value = b, Source = "b" )
 d = rbind(a, b)
 library(scales) 
 d$value <- rescale( d$value, to = c(0,2*pi) )

# Now you can created the rescaled a and b vectors
 a <- d[d$Source == "a", 1]
 b <- d[d$Source == "b", 1]

# You can then calculate the area of overlap as you did previously.
# It should give almost exactly the same answers.
# Or you can use either the overlapTrue() and overlapEst() function 
# provided with the overlap packages. 
# Note that with these function the KDE are fitted using von Mises kernel.
 library(overlap)
  # Using overlapTrue():
   # define limits of a common grid, adding a buffer so that tails aren't cut off
     lower <- min(d$value)-1 
     upper <- max(d$value)+1
   # generate kernel densities
     da <- density(a, from=lower, to=upper, adjust = 1)
     db <- density(b, from=lower, to=upper, adjust = 1)
   # Compute overlap coefficient
     overlapTrue(da$y,db$y)


  # Using overlapEst():            
    overlapEst(a, b, kmax = 3, adjust=c(0.8, 1, 4), n.grid = 500)

# You can also plot the two KDEs and the region of overlap using overlapPlot()
# but sadly I haven't found a way of changing the x scale so that the scale 
# range correspond to the initial x value and not the rescaled value.
# You can only change the maximum value of the scale using the xscale argument 
# (i.e. it always range from 0 to n, where n is set with xscale = n).
# So if some of your data take negative value, you're probably better off with
# a different plotting method. You can change the x label with the xlab
# argument.  
  overlapPlot(a, b, xscale = 10, xlab= "x metrics", rug=T)
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.