Подгонка и построение графика нелинейной регрессии в R

Я пытаюсь подогнать нелинейную функцию к заданному набору данных (x и y во фрагменте кода), функция определяется как

f(x) = a/((sin((x-b)/2))^4)
x <- c(0, 5, -5, 10, -10, 15, -15, 20, -20, 25, -25, 30, -30)
y <- c(4.21, 3.73, 2.08, 1.1, 0.61, 0.42, 0.13, 0.1, 0.04, 0.036667, 0.016667, 0.007778, 0.007778)
plot(x,y, log="y")

Вот так выглядит исходный график, на который я должен уместить ранее упомянутую функцию.

Исходный график

Но когда я пытаюсь подобрать с помощью nls и построить кривую, график выглядит не совсем правильно

f <- function(x,a,b) { a/((sin((x-b)/2))^4) }
fitmodel <- nls (y ~ f(x,a,b), start=list(a=1,b=1))
lines(x, predict(fitmodel))

Вот что я вижу:

Построенная кривая

Я почти уверен, что делаю что-то не так, и буду признателен за любую помощь от вас.


person Honj25    schedule 03.11.2016    source источник
comment
@ZheyuanLi прав - посмотрите, например, на plot(x,y, log="y", type="l"), чтобы понять, почему это происходит. А потом сравните plot(x[order(x)],y[order(x)], log="y", type="l")   -  person thelatemail    schedule 04.11.2016
comment
Я думаю, сначала закажите y, затем x, т.е. y <- y[order(x)]; x[order(x)]   -  person Berry Boessenkool    schedule 04.11.2016
comment
Встроенное исправление: lines(sort(x), predict(fitmodel)[order(x)])   -  person alistaire    schedule 04.11.2016
comment
Спасибо за помощь, по крайней мере, график выглядит определенно лучше. К сожалению, функция была дана мне, поэтому я ничего не мог с этим поделать.   -  person Honj25    schedule 04.11.2016


Ответы (1)


Интерпретатор R сделал именно то, что вы ему сказали.

x - несортированный массив.

Поэтому predict(fitmodel) делайте прогнозы для этих несортированных точек.

lines(x, predict(fitmodel)) соединяет точки в заданном порядке. Он соединяет (x[1], Predict(FitModel)[1]) с (x[2], Predict(FitModel)[2]) с (x[3], Predict(FitModel)[3]) и т. д. Поскольку точки не отсортированы по x, вы видите картинку на графике.

Вы можете сделать ind <- order(x); x <- x[ind]; y <- y[ind] в соответствии с предложением Zheyuan Li'd.

Кроме того, ваша модель не имеет смысла.

f <- function(x,a,b) { a/((sin((x-b)/2))^4) }
fitmodel <- nls (y ~ f(x,a,b), start=list(a=1,b=1))

Для любых a и b f будет периодической функцией с периодом 2π, в то время как ваш x изменится от -30 до 30 на шаге 5. Вы не можете разумно приблизить свои точки с помощью такой функции.

person user31264    schedule 03.11.2016