R скрипт - NLS не работает - PullRequest
       30

R скрипт - NLS не работает

3 голосов
/ 20 августа 2011

У меня есть 5 (x, y) точек данных, и я пытаюсь найти наиболее подходящее решение, состоящее из двух линий, которые пересекаются в точке (x0, y0) и которые соответствуют следующим уравнениям:

y1 = (m1)(x1 - x0) + y0
y2 = (m2)(x2 - x0) + y0

В частности, я требую, чтобы пересечение происходило между x = 2 и x = 3. Посмотрите на код:

#Initialize x1, y1, x2, y2
x1 <- c(1,2)
y1 <- c(10,10)

x2 <- c(3,4,5)
y2 <- c(20,30,40)

g <- c(TRUE, TRUE, FALSE, FALSE, FALSE)

q <- nls(c(y1, y2) ~ ifelse(g == TRUE, m1 * (x1 - x0) + y0, m2 * (x2 - x0) + y0), start = c(m1 = -1, m2 = 1, y0 = 0, x0 = 2), algorithm = "port", lower = c(m1 = -Inf, m2 = -Inf, y0 = -Inf, x0 = 2), upper = c(m1 = Inf, m2 = Inf, y0 = Inf, x0 = 3))
coef <- coef(q)
m1 <- coef[1]
m2 <- coef[2]
y0 <- coef[3]
x0 <- coef[4]

#Plot the original x1, y1, and x2, y2
plot(x1,y1,xlim=c(1,5),ylim=c(0,50))
points(x2,y2)

#Plot the fits
x1 <- c(1,2,3,4,5)
fit1 <- m1 * (x1 - x0) + y0
lines(x1, fit1, col="red")

x2   <- c(1,2,3,4,5)
fit2 <- m2 * (x2 - x0) + y0
lines(x2, fit2, col="blue")

Итак, вы можете видеть перечисленные там точки данных. Затем я запускаю его через мои nls, получаю мои параметры m1, m2, x0, y0 (уклоны и точки пересечения).

Но взгляните на решение: enter image description here

Очевидно, что красная линия (которая должна основываться только на первых 2 точках) не является лучшей линией соответствия для первых 2 точек. Это тот же случай с синей линией (2-е совпадение), которая, как предполагается, зависит от последних 3-х точек). Что здесь не так?

Ответы [ 2 ]

3 голосов
/ 20 августа 2011

Это сегментированная регрессия:

# input data

x1 <- c(1,2); y1 <- c(10,10); x2 <- c(3,4,5);  y2 <- c(20,30,40) 
x  <- c(x1, x2); y <- c(y1, y2)

# segmented regression

library(segmented)
fm <- segmented.lm(lm(y ~ x), ~ x, NA, seg.control(stop.if.error = FALSE, K = 2))
summary(fm)

# plot

plot(fm)
points(y ~ x)

См. ?lm, ?segmented.lm и ?seg.control для получения дополнительной информации.

2 голосов
/ 20 августа 2011

Я не совсем уверен, что не так, но я могу заставить его работать, немного переставив вещи. Обратите внимание на комментарий в ?nls о " Не используйте use nls 'для искусственных данных с нулевым остатком. "; Я добавил немного шума.

## Initialize x1, y1, x2, y2
x1 <- c(1,2)
y1 <- c(10,10)

x2 <- c(3,4,5)
y2 <- c(20,30,40)

## make single x, y vector
x <- c(x1,x2)
set.seed(1001)
## (add a bit of noise to avoid zero-residual artificiality)
y <- c(y1,y2)+rnorm(5,sd=0.01)

g <- c(TRUE,TRUE,FALSE,FALSE,FALSE) ## specify identities of points

## particular changes:
##   * you have lower=upper=2 for x0.  Did you want 2<x0<3?
##   * specified data argument explicitly (allows use of predict() etc.)
##   * changed name from 'q' to 'fit1' (avoid R built-in function)
fit1 <- nls(y ~ ifelse(g,m1,m1+delta_m)*(x - x0) + y0,
         start = c(m1 = -1, delta_m = 2, y0 = 0, x0 = 2),
         algorithm = "port",
         lower = c(m1 = -Inf, delta_m = 0, y0 = -Inf, x0 = 2),
         upper = c(m1 = Inf, delta_m = Inf, y0 = Inf, x0 = 3),
         data=data.frame(x,y))

#Plot the original 'data'
plot(x,y,col=rep(c("red","blue"),c(2,3)),
           xlim=c(1,5),ylim=c(0,50))

## add predicted values
xvec <- seq(1,5,length.out=101)
lines(xvec,predict(fit1,newdata=data.frame(x=xvec)))

edit : основано на ifelse предложении на точечной идентичности, а не на позиции x

edit : изменен, чтобы требовать, чтобы второй уклон был> первым уклоном

С другой стороны, я думаю, что проблема выше - , вероятно из-за использования отдельных векторов для x1 и x2 выше, а не одного вектора x: я подозреваю, что эти был воспроизведен R, чтобы соответствовать вектору g, что могло бы испортить ситуацию. Например, этот урезанный пример:

g <- c(TRUE, TRUE, FALSE, FALSE, FALSE)
ifelse(g,x1,x2)
## [1] 1 2 5 3 4

показывает, что x2 расширяется до (3 4 5 3 4) перед использованием в предложении ifelse. Самое страшное то, что обычно выдается предупреждение, например:

> x2 + 1:5
[1] 4 6 8 7 9
Warning message:
In x2 + 1:5 :
  longer object length is not a multiple of shorter object length

но в этом случае предупреждения нет ...

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...