Я спросил этот вопрос некоторое время назад. Я не уверен, должен ли я опубликовать это как ответ или новый вопрос. У меня нет ответа, но я "решил" проблему, применив алгоритм Левенберга-Марквардта, используя nls.lm
в R, и когда решение находится на границе, я запускаю алгоритм рефлексии в области доверия (TRR, реализованный в R), чтобы отойти от него. Теперь у меня есть новые вопросы.
Из моего опыта, таким образом, программа достигает оптимальной и не очень чувствительна к стартовым значениям. Но это всего лишь практический метод, чтобы отвлечься от проблем, с которыми я столкнулся, используя nls.lm
, а также другие функции оптимизации в R. Я хотел бы знать, почему nls.lm
ведет себя таким образом для задач оптимизации с граничными ограничениями и как обрабатывать граничных ограничений при использовании nls.lm
на практике.
Далее я привел пример, иллюстрирующий два вопроса, используя nls.lm
.
- Он чувствителен к стартовым значениям.
- Он останавливается, когда какой-то параметр достигает границы.
Воспроизводимый пример: Фокусный набор D
library(devtools)
install_github("KineticEval","zhenglei-gao")
library(KineticEval)
data(FOCUS2006D)
km <- mkinmod.full(parent=list(type="SFO",M0 = list(ini = 0.1,fixed = 0,lower = 0.0,upper =Inf),to="m1"),m1=list(type="SFO"),data=FOCUS2006D)
system.time(Fit.TRR <- KinEval(km,evalMethod = 'NLLS',optimMethod = 'TRR'))
system.time(Fit.LM <- KinEval(km,evalMethod = 'NLLS',optimMethod = 'LM',ctr=kingui.control(runTRR=FALSE)))
compare_multi_kinmod(km,rbind(Fit.TRR$par,Fit.LM$par))
dev.print(jpeg,"LMvsTRR.jpeg",width=480)
Дифференциальные уравнения, описывающие модель/систему:
"d_parent = - k_parent * parent"
"d_m1 = - k_m1 * m1 + k_parent * f_parent_to_m1 * parent"
В графе слева находится модель с начальными значениями, а в середине - модель с использованием "TRR" (аналогичная алгоритму в функции Matlab lsqnonlin
), справа - установленная модель с использованием "LM" с nls.lm
. Изучив установленные параметры (Fit.LM$par
), вы обнаружите, что один установленный параметр (f_parent_to_m1
) находится на границе 1
. Если я изменил начальное значение для одного параметра M0_parent
от 0,1 до 100, то я получил те же результаты, используя nls.lm
и lsqnonlin
. У меня много таких случаев.
newpars <- rbind(Fit.TRR$par,Fit.LM$par)
rownames(newpars)<- c("TRR(lsqnonlin)","LM(nls.lm)")
newpars
M0_parent k_parent k_m1 f_parent_to_m1
TRR(lsqnonlin) 99.59848 0.09869773 0.005260654 0.514476
LM(nls.lm) 84.79150 0.06352110 0.014783294 1.000000
За исключением вышеперечисленных проблем, часто бывает, что гессиан, возвращаемый nls.lm
, не является инвертируемым (особенно когда некоторые параметры находятся на границе), поэтому я не могу получить оценку ковариационной матрицы. С другой стороны, алгоритм "TRR" (в Matlab) почти всегда дает оценку, вычисляя якобиан в точке решения. Я думаю, что это полезно, но я также уверен, что алгоритмы оптимизации R (те, которые я пробовал) не сделали этого по какой-то причине. Я хотел бы знать, ошибаюсь ли я, используя метод Matlab для вычисления матрицы ковариации, чтобы получить стандартную ошибку для оценок параметров.
Последнее замечание, которое я утверждал в предыдущем сообщении