#r #derivative
#r #производное
Вопрос:
У меня возникли две связанные проблемы с функцией Deriv() из пакета Deriv (из CRAN).
Проблема (1): Я считаю, что код в правиле для дифференцирования dbinom() w.r.t «prob» неверен. Доказательства этого (и мое предлагаемое исправление) приведены в следующем коде. Я бы предпочел прикрепить текстовые файлы, содержащие код, но, насколько я вижу, это невозможно сделать.
# # Script demo01.R. # library(Deriv) # Plot dbinom as a function of probabiity. plot(function(p){dbinom(3,8,p)},from=0,to=1,xlab="parameter "prob"", ylab="binomial probability",main="dbinom") abline(v=3/8,col="red") readline("Go? ") # Plot the derivative of dbinom, with respect to prob, calculated by # Deriv(), as a function of probability. Ddb lt;- Deriv(dbinom,"prob") plot(function(p){Ddb(3,8,p)},from=0,to=1,xlab="parameter "prob"", ylab="",main="derivative of dbinom") readline("Go? ") # Replace what I believe to be incorrect code for the rule for # differentiating dbinom() with what I believe to be correct code. # This rule should, strictly speaking, be placed in a new environment # rather than over-writing the existing rule, but this seems to # break down when second derivatives are taken. drule[["dbinom"]] lt;- alist(x=NULL,size=NULL,prob={ .e1 lt;- 1 - prob .e2 lt;- size - 1 if (x == 0) -(x * .e1^(x - 1)) else if (x == size) prob^.e2 * size else size*(dbinom(x-1,.e2,prob) - dbinom(x,.e2,prob)) * (if (log) dbinom(x, size, prob) else 1) }) # Plot the derivative of dbinom, with respect to prob, calculated by # the corrected version of Deriv(), as a function of probability. Ddb lt;- Deriv(dbinom,"prob") plot(function(p){Ddb(3,8,p)},from=0,to=1,xlab="parameter "prob"", ylab="",main="derivative of dbinom, corrected") abline(v=3/8,col="red") abline(h=0,col="blue")
Вы заметите, что производная от dbinom() должно быть положительным для вероятности lt; 3/8 и отрицательным для вероятности gt; 3/8. Моя исправленная версия обладает этим свойством, в то время как производная, полученная из исправленной версии, везде отрицательна.
Может ли кто-нибудь подтвердить, что я прав насчет того, что в пакете Deriv есть ошибка? (т. Е. что я не совершаю какую-то глупую ошибку?)
Проблема (2). Я «перепроверил» вычисления, выполняемые Deriv (), применив эту функцию к «собственной» версии dbinom (), для которой не требуется никаких специальных правил. Я также применил (исправленную версию) функции Deriv() к dbinom(). Код, который я использовал, выглядит следующим образом:
# # Script demo02. # library(Deriv) # Replace what I believe to be incorrect code for the rule for # differentiating dbinom() with what I believe to be correct code. # This rule should, strictly speaking, be placed in a new environment # rather than over-writing the existing rule, but this seems to # break down when second derivatives are taken. drule[["dbinom"]] lt;- alist(x=NULL,size=NULL,prob={ .e1 lt;- 1 - prob .e2 lt;- size - 1 if (x == 0) -(x * .e1^(x - 1)) else if (x == size) prob^.e2 * size else size*(dbinom(x-1,.e2,prob) - dbinom(x,.e2,prob)) * (if (log) dbinom(x, size, prob) else 1) },log=NULL) fooB1 lt;- function(x,prob,size) { dbinom(x,size,prob) } fooB2 lt;- function(x,prob,size) { choose(size,x)*prob^x*(1-prob)^(size-x) } dfooB1 lt;- Deriv(fooB1,"prob") dfooB2 lt;- Deriv(fooB2,"prob") d2fooB1 lt;- Deriv(fooB1,"prob",nderiv=2) d2fooB2 lt;- Deriv(fooB2,"prob",nderiv=2) vB1 lt;- fooB1(x=3,prob=0.6,size=8) vB2 lt;- fooB2(x=3,prob=0.6,size=8) dB1 lt;- dfooB1(x=3,prob=0.6,size=8) dB2 lt;- dfooB2(x=3,prob=0.6,size=8) d2B1 lt;- d2fooB1(x=3,prob=0.6,size=8) d2B2 lt;- d2fooB2(x=3,prob=0.6,size=8)
Если вы запустите этот код, вы увидите, что значения функций (vB1 и vB2) совпадают, оба имеют значение 0,123863. Аналогично, значения первой производной dB1 и dB2 совпадают: -0,9289728.
Однако вторые производные не согласны. Значение d2B1 равно 1,769472, тогда как значение d2B2 равно 2,064384. Я понятия не имею, какой из этих ответов (если таковой имеется) правильный.
Что-то (правило цепочки?) работает не так, как следовало бы.
Есть ли какие-либо действия, которые я могу предпринять, чтобы устранить это несоответствие?
Комментарии:
1. На самом деле я знаю, какой из d2B1 и d2B2 правильный. Да. Просто рассчитайте производные вручную. Получается значение d2B2, то есть 2,064384. Таким образом, похоже, что Deriv() ошибается в применении правила цепочки к dbinom(). Мне это кажется очень странным.
2. Строка Сообщений об ошибках в выходных
packageDescription("Deriv")
данных покажет вам, где вы можете указать проблемы с пакетом.3. Спасибо тебе, Габор. Я не знал об этом заведении. Очевидно, что это подходящий способ решения таких вопросов. Теперь я «поднял вопрос» на Github.