2013-05-07 3 views
0

Я пытаюсь установить данные точек с помощью полиномиальных функций в программе R и хочу, чтобы какой порядок был наилучшим образом подходит. Я использую модель нелинейной регрессии nls(function, data, start), функция y~a*(x+c)^b.Проблемы вычисления nls() в R

Что я хочу сделать, так это рассчитать площадь поперечного сечения заполнения долины. По этой причине мне нужно смоделировать, как может выглядеть базовая долина. У меня уже есть линейный сценарий, и теперь я хочу попробовать несколько полиномиальных сценариев.

Мой набор данных представляет собой профиль долины и выглядит следующим образом (с x_combsl быть расстояние и y_combsl высота):

x_combsl y_combsl  
1 0.0000000 120.9095 
2 0.9904867 120.5066 
3 1.9809735 120.0947 
4 2.9714602 119.6811 
5 3.9619470 119.2492 
6 4.9524337 118.8483 
7 5.9429204 118.4866 
8 6.9334072 118.1120 
9 7.9238939 117.7750 
10 8.9143806 117.2833 
11 9.9048674 116.7698 
12 10.8953541 116.2841 
13 11.8858409 115.8285 
14 12.8763276 115.2949 
15 13.8668143 114.6750 
16 14.8573011 114.1301 
17 15.8477878 113.6537 
18 16.8382746 113.2016 
19 17.8287613 112.8163 
20 18.8192480 112.4945 
21 19.8097348 112.0304 
22 20.8002215 111.2370 
23 21.7907082 110.7463 
24 22.7811950 110.2954 
25 23.7716817 109.6715 
26 24.7621685 109.1829 
27 44.5719032 109.0435 
28 45.5623900 109.4721 
29 46.5528767 110.0491 
30 47.5433634 110.4394 
31 48.5338502 110.6832 
32 49.5243369 111.0763 
33 50.5148237 111.8376 
34 51.5053104 112.6162 
35 52.4957971 113.2467 
36 53.4862839 113.8065 
37 54.4767706 114.4694 
38 55.4672573 114.9547 
39 56.4577441 115.4724 
40 57.4482308 116.0013 
41 58.4387176 116.4606 
42 59.4292043 117.0797 
43 60.4196910 117.7074 
44 61.4101778 118.2127  
45 62.4006645 118.7544 
46 63.3911512 119.3134 
47 64.3816380 119.9159 
48 65.3721247 120.5462 
49 66.3626115 121.0418 
50 67.3530982 121.5350 
51 68.3435849 122.0184 
52 69.3340717 122.5490 
53 70.3245584 123.1162 
54 71.3150452 123.6437 

При попытке создания модели я получаю следующее сообщение об ошибке:

data<-data.frame(x_combsl, y_combsl) 

fit_nls<-nls(y_combsl~a*(x_combsl + c)^b, data=data, start=list(a=1, b=2, c=35)) 
Error in numericDeriv(form[[3]], names(ind), env) : 
    Missing value or an Infinity produced when evaluating the model 

Любые идеи, которые могут вызвать проблему? Пик полинома, скорее всего, будет около c = 35, поэтому параметры запуска, похоже, не вызывают проблем. Может ли это быть очень линейное выравнивание точек? Я попробовал это с меньшим количеством точек данных [24:31], но я получил то же сообщение об ошибке.

Я не очень опытен в программировании с R, поэтому конкретные ответы были бы замечательными.

+0

Вы должны, вероятно, дать оценки по параметрам оценки (см '' lower' и upper' аргументы, описанные в 'nls'?). Вероятно, у вас также будет лучшее преобразование результатов и установка 'log (y) = log (a) + b log (x + c)'. – Gregor

+0

После построения ваших данных я не думаю, что ваша модель хорошо подходит для данных. Вы можете попробовать использовать алгоритм Левенберга-Марквардта ('nlsLM' из пакета minpack.lm), который часто сходится лучше, чем у Гаусса-Ньютона, но я сомневаюсь, что вы получите хорошую форму. PS: Читайте '? Dput', чтобы узнать, как лучше делиться своими данными. – Roland

ответ

1

Несколько пунктов:

  • кривая примерно симметрично относительно примерно 35 таким образом, начиная c должна быть равна -35, а не +35.
  • При условии, что симметрия b должна быть четной, 2, 4, 6, ....
  • модель нуждается в гибкости для смещения вверх и вниз, поэтому добавьте параметр для этого
  • с последней точкой у нас есть два линейных параметра, поэтому используйте algorithm="plinear", чтобы избежать появления стартовых значений для них. Также мы фиксируем b, поэтому теперь у нас есть только c, чтобы дать начальное значение, и мы уже определили, что для этого будем использовать -35.

Таким образом, попробуйте следующий и, возможно, дополнительные прогоны с Ь = 2 и Ь = 6, а также:

nls(y_combsl ~ cbind(1, (x_combsl + c)^4), data, alg = "plinear", start = list(c = -35)) 

Из courese мы действительно теперь до полиномом таким образом, мы могли бы изменить модель к полный полином и использовать lm:

lm(y_combsl ~ poly(x_combsl, 4), data) 
Смежные вопросы