Я спросил этот вопрос некоторое время назад. Я не уверен, должен ли я опубликовать это как ответ или новый вопрос. У меня нет ответа, но я "решил" проблему, применив алгоритм Левенберга-Марквардта, используя 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 для вычисления матрицы ковариации, чтобы получить стандартную ошибку для оценок параметров.
Последнее замечание, которое я утверждал в предыдущем сообщении