Ускорьте итерации кусочных регрессий с помощью сегментированной функции в R - PullRequest
0 голосов
/ 05 июля 2018

Я пытаюсь разместить около 300 кусочных регрессий с помощью функции segmented из пакета segmented в R. Это занимает много времени (~ 4 дня) из-за функции segmented. Я уже использую все ядра своего компьютера, но я не программист, и я думаю, что этот код, вероятно, не оптимален. Могу ли я улучшить приведенный ниже код, чтобы он работал быстрее? Как?

Вот воспроизводимый пример. df - это моделируемый фрейм данных, который соответствует одному из 300 наборов данных, которые я хочу проанализировать. Каждый набор данных составляет один день, и в течение каждого дня я измеряю температуру каждые 5 минут, x - это температура, а y - время дня. На рисунке ниже показано, как выглядят мои данные. Картина очень специфична и повторяется в течение нескольких дней, и каждое изменение наклона соответствует хорошо понятным биологическим механизмам. Вот почему я могу угадать все значения psi (например, время восхода и захода солнца).

Конечно, реальные данные более изменчивы, и я использую много итераций (около 200, здесь я сократил до 10 для примера), чтобы увеличить свои шансы на успешное соответствие.

library(segmented)
y<-seq(1,288,1)
x<-c(seq(0,-30,-1),seq(-30,-54,-2),seq(-54,30,1),seq(30,10,-1),seq(10,90,1),seq(90,34,-1))
df<-data.frame(x,y)
head(df)

plot(x~y)
t1=31
t2=44
t3=129
t4=150
t5=231

iterations<-10
for (j in 1:iterations) {           
  res <- lm(formula=x~y,data=df)      
  try(result <- segmented(
       res, seg.Z=~y, psi=c(t1,t2,t3,t4,t5),
       control=seg.control(it.max=200, display=F, K=4, h=0.1, n.boot=100, random=T)))          
}

result

Temperature ~ time of the day

Вывод lm из цикла не приводит к значительному улучшению скорости цикла.

1 Ответ

0 голосов
/ 13 июля 2018

Одна вещь, которая должна помочь, - это выйти из итераций, как только будет найден результат. В большинстве случаев он должен найти что-то на первой итерации, и это позволит избежать 200 ненужных итераций.

rm(result)
for (j in 1:iterations) {           
  res <- lm(formula=x~y,data=df)
  try(result <- segmented(
       res, seg.Z=~y, psi=c(t1,t2,t3,t4,t5),
       control=seg.control(it.max=200, display=F, K=4, h=0.1, n.boot=100, random=T)))
  if (exists("result")) break
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...