вычислить подгонку кривой Гаусса к списку

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

mylist<- structure(list(A = structure(list(breaks = c(-10, -9, 
-8, -7, -6, -5, -4, -3, -2, -1, 0, 1, 2, 3, 4), counts = c(1L, 
0L, 1L, 5L, 9L, 38L, 56L, 105L, 529L, 2858L, 17L, 2L, 0L, 2L), 
    density = c(0.000276014352746343, 0, 0.000276014352746343, 
    0.00138007176373171, 0.00248412917471709, 0.010488545404361, 
    0.0154568037537952, 0.028981507038366, 0.146011592602815, 
    0.788849020149048, 0.00469224399668783, 0.000552028705492686, 
    0, 0.000552028705492686), mids = c(-9.5, -8.5, -7.5, -6.5, 
    -5.5, -4.5, -3.5, -2.5, -1.5, -0.5, 0.5, 1.5, 2.5, 3.5), 
    xname = "x", equidist = TRUE), .Names = c("breaks", "counts", 
"density", "mids", "xname", "equidist"), class = "histogram"), 
    B = structure(list(breaks = c(-7, -6, -5, 
    -4, -3, -2, -1, 0), counts = c(2L, 0L, 6L, 2L, 2L, 1L, 3L
    ), density = c(0.125, 0, 0.375, 0.125, 0.125, 0.0625, 0.1875
    ), mids = c(-6.5, -5.5, -4.5, -3.5, -2.5, -1.5, -0.5), xname = "x", 
        equidist = TRUE), .Names = c("breaks", "counts", "density", 
    "mids", "xname", "equidist"), class = "histogram"), C = structure(list(
        breaks = c(-7, -6, -5, -4, -3, -2, -1, 0, 1), counts = c(2L, 
        2L, 4L, 5L, 14L, 22L, 110L, 3L), density = c(0.0123456790123457, 
        0.0123456790123457, 0.0246913580246914, 0.0308641975308642, 
        0.0864197530864197, 0.135802469135802, 0.679012345679012, 
        0.0185185185185185), mids = c(-6.5, -5.5, -4.5, -3.5, 
        -2.5, -1.5, -0.5, 0.5), xname = "x", equidist = TRUE), .Names = c("breaks", 
    "counts", "density", "mids", "xname", "equidist"), class = "histogram")), .Names = c("A", 
"B", "C"))

Я прочитал этот Подгонка кривой плотности к гистограмме в R но вот как подогнать кривую к гистограмме. то, что я хочу, - это наиболее подходящие ценности "

"Среднее" "SD"

Если я использую PRISM для этого, я должен получить следующие результаты для A

Mids   Counts
-9.5    1
-8.5    0
-7.5    1
-6.5    5
-5.5    9
-4.5    38
-3.5    56
-2.5    105
-1.5    529
-0.5    2858
0.5     17
1.5     2
2.5     0
3.5     2

выполняя нелинейную регрессию подгонки кривой Гаусса, я получаю

"Best-fit values"   
"     Amplitude"    3537
"     Mean"       -0.751
"     SD"         0.3842

для второго набора B

Mids   Counts
-6.5    2
-5.5    0
-4.5    6
-3.5    2
-2.5    2
-1.5    1
-0.5    3



"Best-fit values"   
"     Amplitude"    7.672
"     Mean"         -4.2
"     SD"          0.4275

а для третьего

Mids   Counts
-6.5    2
-5.5    2
-4.5    4
-3.5    5
-2.5    14
-1.5    22
-0.5    110
0.5      3

Я понял это

"Best-fit values"   
"     Amplitude"    120.7
"     Mean"       -0.6893
"     SD"        0.4397

person nik    schedule 28.06.2016    source источник
comment
Если вы ищете расчетное среднее значение и стандартное отклонение / дисперсию, я думаю, что это можно сделать с помощью процедуры максимального правдоподобия. В базовом R есть функция mle, а также пакет maxLik. В этом случае вы должны использовать необработанные данные, а не средние значения и счетчики. Первый пример в mle должен быть аналогом того, что вы хотите.   -  person lmo    schedule 28.06.2016
comment
Я не могу смотреть видео сейчас, но посмотрю через пару часов, когда смогу. Похоже, что оценка на основе данных с разбивкой теряет полезную информацию. Это особенно беспокоит, учитывая, что у вас такой небольшой размер выборки: 16, я думаю.   -  person lmo    schedule 28.06.2016
comment
@lmo Отлично, на самом деле размер выборки намного больше, чем 1000. Так что в этом случае не будет проблемой, я думаю   -  person nik    schedule 28.06.2016
comment
У вас есть доступ к исходным данным? Если это так, то, вероятно, лучше всего подойдут указанные выше функции. Я посмотрю видео, когда у меня будет возможность.   -  person lmo    schedule 28.06.2016
comment
@lmo Да, хорошо, я буду ждать тебя   -  person nik    schedule 28.06.2016


Ответы (1)


Чтобы преобразовать гистограмму обратно в оценку среднего и стандартного отклонения. Сначала преобразуйте результаты подсчета бункеров, умноженные на размер бункера. Это будет приблизительная оценка исходных данных.

Основываясь на вашем примере выше:

#extract the mid points and create list of simulated data
simdata<-lapply(mylist, function(x){rep(x$mids, x$counts)})
#if the original data were integers then this may give a better estimate
#simdata<-lapply(mylist, function(x){rep(x$breaks[-1], x$counts)})

#find the mean and sd of simulated data
means<-lapply(simdata, mean)
sds<-lapply(simdata, sd)
#or use sapply in the above 2 lines depending on future process needs

Если ваши данные были целыми числами, то использование разрывов в качестве ячеек даст лучшую оценку. В зависимости от функции для гистограммы (т.е. вправо = ИСТИНА / ЛОЖЬ) результаты могут сдвигаться на единицу.

Редактировать

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

mids<-seq(-7, 7)
counts<-c(7, 1, 2, 2, 2, 5, 217, 70, 18, 0, 2, 1, 2, 0, 1)
simdata<-rep(mids, counts)

Результаты видео: среднее значение = -0,7359 и стандартное отклонение = 0,4571. Решение, которое я нашел, дало наиболее близкие результаты, используя пакет fitdistrplus:

fitdist(simdata, "norm", "mge")

Использование максимальной оценки согласия привело к среднему значению = -0,7597280 и sd = 0,8320465.
На этом этапе описанный выше метод дает точную оценку, но не совсем соответствует. Я не знаю, какой метод был использован для расчета подгонки по видео.

Редактировать # 2

Вышеупомянутые решения включали воссоздание исходных данных и их подгонку с использованием либо mean / sd, либо пакета fitdistrplus. Эта попытка представляет собой попытку выполнить аппроксимацию методом наименьших квадратов с использованием распределения Гаусса.

simdata<-lapply(mylist, function(x){rep(x$mids, x$counts)})
means<-sapply(simdata, mean)
sds<-sapply(simdata, sd)

#Data from video
#mids<-seq(-7, 7)
#counts<-c(7, 1, 2, 2, 2, 5, 217, 70, 18, 0, 2, 1, 2, 0, 1)

#make list of the bins and distribution in each bin
mids<-lapply(mylist, function(x){x$mids})
dis<-lapply(mylist, function(x) {x$counts/sum(x$counts)})

#function to perform the least square fit
nnorm<-function(values, mids, dis) {
  means<-values[1]
  sds<-values[2]
  #print(paste(means, sds))
  #calculate out the Gaussian distribution for each bin
  modeld<-dnorm(mids, means, sds)  
  #sum of the squares
  diff<-sum( (modeld-dis)^2)
  diff
}

#use optim function with the mean and sd as initial guesses
#find the mininium with the mean and SD as fit parameters
lapply(1:3, function(i) {optim(c(means[[i]], sds[[i]]), nnorm, mids=mids[[i]], dis=dis[[i]])})

Это решение дает более точный ответ на результаты PRISM, но все же не то же самое. Вот сравнение всех 4 решений. введите описание изображения здесь

Из таблицы наиболее близкое приближение дает метод наименьших квадратов (приведенный выше). Возможно, вам может помочь настройка функции dnorm средних точек. Но данные случая B далеки от нормального распределения, но программное обеспечение PRISM по-прежнему генерирует небольшое стандартное отклонение, в то время как другие методы аналогичны. Возможно, программное обеспечение PRISM выполняет некоторый тип фильтрации данных, чтобы удалить выбросы до подбора.

person Dave2e    schedule 28.06.2016
comment
вы уверены, что, делая это, можно применить нелинейную регрессию подгонку кривой Гаусса ??? - person nik; 28.06.2016
comment
Привет, я проверил приведенные выше данные и использовал PRISM для построения аппроксимации кривой Гаусса нелинейной регрессии и получил среднее и стандартное отклонение. Не могли бы вы посмотреть, то же ли это? - person nik; 29.06.2016
comment
Значения не совпадают. Я не знаю, как программа PRISM справляется с этой задачей. Это может быть стрижка или сглаживание хвоста по фигуре. Ваш случай B не совсем нормальный, но PRISM генерирует стандартное отклонение ‹0,5. - person Dave2e; 29.06.2016
comment
Я делаю то же самое, что и vedio, но, похоже, вы не делаете никаких регрессов, чтобы найти лучшее; например, вы объединяете их и получаете случайные значения simdata ‹-rep (mids, counts). Я привел пример X и Y выше, можно ли сделать то же самое с ними? - person nik; 29.06.2016
comment
Третья и последняя попытка - person Dave2e; 30.06.2016
comment
Я принимаю ваш ответ, и он мне нравится. Вы потратили на это так много времени, и я очень ценю вашу помощь. В общем, мне интересно, почему мы должны делать частотное распределение, а затем подходить по методу наименьших квадратов ?? ты знаешь причину этого? также вы видели что они добавили 1.96 в sd + значит, у вас причина для этого? - person nik; 30.06.2016
comment
Я не совсем уверен в причинах, по которым вычисляют нормальное распределение, а затем подходят к функции. Это может быть связано с простотой фильтрации выбросов? Среднее + 1,96 * sd - это статистическая отсечка. Если распределение действительно гауссово, то 97,5% данных будут ниже этого значения. - person Dave2e; 30.06.2016