Разделение на основе модели с «двухуровневым взаимодействием» (сегментированные модели)

Я пытаюсь построить дерево на основе моделей с типом «двухуровневого взаимодействия», где модели в узлах дерева снова сегментируются.

Я использую функцию mob() для этой цели, но мне не удалось заставить аргумент для функции fit работать с функцией lmtree().

В следующем примере a является функцией b, а взаимосвязь между a и b зависит от d и от b | d.

library("partykit")
set.seed(321)

b <- runif (200)
d <- sample(1:2, 200, replace = TRUE)
a <- jitter(ifelse(d == 1, 2 * b - 1, 4 * b - 1.2), amount = .1)
a[b < .5 & d == 1] <- jitter(rep(0, length(a[b < .5 & d == 1])))
a[b < .3 & d == 2] <- jitter(rep(0, length(a[b < .3 & d == 2])))

fit <- function(y, x, start = NULL, weights = NULL, offset = NULL, ..., estfun = FALSE, object = FALSE)
{   
  x <- x[, 2]
  l <- lmtree(y ~ x | b)
  return(l)
}   

m <- mob(a ~ b | d, fit = fit) # not working

Конечно, с помощью этого простого примера я мог бы использовать lmtree(a ~ b | d + b) для поиска каждого взаимодействия, но есть ли способ использовать в качестве функции fitmob()lmtree()?

Стоит ли изучать PHP в 2026-2027 годах?
Стоит ли изучать PHP в 2026-2027 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
1
0
210
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Нет, но да ;-)

Нет, lmtree() не может быть легко использован в качестве установщика для mob().

  1. Размер внутреннего дерева (lmtree()) не фиксирован, то есть вы можете получить дерево без какого-либо раздела или со многими подгруппами, и это может сбить с толку внешнее дерево (mob()).

  2. Даже если бы кто-то обошел проблему размерности или исправил ее, всегда заставляя один разрыв, потребовалось бы больше работы, чтобы настроить правильный вектор коэффициентов, матрицу оценочных функций и т. д. Это также непросто, потому что скорость сходимости (и, следовательно, вывод) отличается, если заданы точки останова (например, для двоичного фактора) или должны быть оценены (например, для ваших числовых переменных b).

  3. Как вы настроили функцию fit(), внутренний lmtree() не знает, где найти b. Все, что у него есть, это числовой вектор y и числовая матрица x, но не исходные данные.

Но да, я думаю, что все эти проблемы можно решить, изменив представление с подгонки «двухслойного» дерева к подгонке «сегментированной» модели внутри дерева. У меня сложилось впечатление, что вы хотите соответствовать модели y ~ x (или a ~ b в вашем примере), где в x используется кусочно-линейная функция с дополнительной точкой останова. Если в x предполагается, что кусочно-линейная функция является непрерывной, то можно легко использовать пакет segmented. Если нет, то можно использовать strucchange. Предполагая, что вы хотите первое (поскольку вы смоделировали свои данные таким образом), я включаю рабочий пример segmented ниже (а также немного изменил ваш вопрос, чтобы отразить это).

Немного изменив имена и код, ваши данные d имеют сегментированную кусочно-линейную зависимость y ~ x с коэффициентами, зависящими от групповой переменной g.

set.seed(321)
d <- data.frame(
  x = runif (200),
  g = factor(sample(1:2, 200, replace = TRUE))
)
d$y <- jitter(ifelse(d$g == "1",
  pmax(0, 2 * d$x - 1),
  pmax(0, 4 * d$x - 1.2)
), amount = 0.1)

Затем в каждый узел дерева я могу поместить модель segmented(lm(y ~ x)), которая поставляется с подходящими экстракторами для coef(), logLik(), estfun() и т. д. Таким образом, функция мафиози проста:

segfit <- function(y, x, start = NULL, weights = NULL, offset = NULL, ...)
{
  x <- as.numeric(x[, 2])
  segmented::segmented(lm(y ~ x))
}

(Примечание: я не пробовал, будет ли segmented() также поддерживать объекты lm() с weights и offset.)

Таким образом, мы можем получить полное дерево, которое просто разбивается на g в этом базовом примере:

library("partykit")
segtree <- mob(y ~ x | g, data = d, fit = segfit)
plot(segtree, terminal_panel = node_bivplot, tnex = 2)

segtree

Практическое введение в segmented доступно в: Muggeo VMR (2008). «сегментированный: пакет R для соответствия моделям регрессии с ломаной связью». Новости R, 8 (1), 20-25. https://CRAN.R-project.org/doc/Rnews/

Для базовой методологической основы см .: Muggeo VMR (2003). «Оценка регрессионных моделей с неизвестными точками разрыва». Статистика в медицине, 22 (19), 3055-3071. DOI: 10.1002 / sim.1545

Спасибо :-) Я был удивлен, насколько легко это было собрать! Но segmented Вито был достаточно дружелюбным, чтобы поставляться со всеми необходимыми нам строительными блоками. Теперь мне любопытно посмотреть, насколько хорошо это работает с реальными данными ...

Achim Zeileis 09.04.2018 15:52

Спасибо @AchimZeileis. Собственно, поначалу я использовал именно такой подход (сегментированная функция для подгонки). Но я отказался от своих реальных данных, так как это занимает несколько дней ... В любом случае еще раз спасибо за помощь.

MassCorr 09.04.2018 16:58

@MassCorr Сильно ли отличается проблема синхронизации для mob(y ~ x | ..., fit = segtree) от lmtree(y ~ x | ...)? Если последнее также занимает очень много времени, может потребоваться огрубление некоторых регрессоров или факторов, чтобы облегчить поиск точки разделения, увеличить минимальный размер сегмента, ограничить глубину дерева и т. д.

Achim Zeileis 09.04.2018 22:22

@AchimZeileis mob + segmented занимает гораздо больше времени, чем lmtree

MassCorr 10.04.2018 16:16

Хорошо, я вижу. Насколько приблизительно? Возможно, можно поиграться со стартовыми значениями и т. д., Возможно, возможно некоторое ускорение. Спросить Вито тоже может быть полезно ...

Achim Zeileis 10.04.2018 20:00

@AchimZeileis Ну даже для самой простой модели с выборкой данных >> 100 x. Я думаю (но вы это знаете лучше меня), что мафии сложно сходиться с такой регрессией (особенно с зашумленными данными)

MassCorr 13.04.2018 12:38

Кроме того, у самой сегментированной функции иногда возникают трудности с конвергенцией.

MassCorr 13.04.2018 12:45

Вероятно, значительная часть этого времени уходит на обработку формул и / или проблемы сходимости. Это может помочь связать с seg.lm.fit(...), а не с segmented(lm(...)), а затем вручную установить лучшие начальные значения (например, используя информацию от материнского узла), ослабить критерии сходимости и т. д.

Achim Zeileis 13.04.2018 14:19

Это очень хорошая идея использовать информацию от материнского узла! Я могу попробовать это

MassCorr 13.04.2018 14:25

В mob_control() для этого есть параметр restart. Затем функция fit получает параметры от материнского узла через аргумент start. Однако при его использовании необходимо соблюдать осторожность. Мой опыт показывает, что иногда это приводит к ускорению, а иногда нет ... или даже приводит к проблемам сходимости. Таким образом, функция fit должна обратить на это внимание.

Achim Zeileis 13.04.2018 22:12

Хорошо, расскажу, как это происходит

MassCorr 14.04.2018 13:36

Другие вопросы по теме