Нахождение кривой для сопоставления данных - PullRequest
10 голосов
/ 31 августа 2009

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

Я должен иметь возможность указать в виде строки тип выражения, которое я хочу разместить.

Примеры:

"A+B*x+C*x*x"
"(A+B*x+C*x*x)/(D*x+E*x*x)"
"sin(A+B*x)*exp(C+D*x)+E+F*x"

Из этого я получу хотя бы значения констант (A, B, C и т. Д.) И, надеюсь, статистику о пригодности матча.

Существуют коммерческие программы для этого, но я ожидал, что смогу найти что-то такое же общее, как вписывание нужного выражения в языковую библиотеку в наши дни. Я подозреваю, что оптимизация SciPy могла бы сделать это, но я не вижу, чтобы это позволило мне определить уравнение. Точно так же я не могу найти именно то, что хочу в R.

Это то, что я ищу там, или мне нужно свернуть свое? Ненавижу делать это, если оно есть, и мне просто трудно его найти.


Edit: я хочу сделать это для немного большего контроля над процессом, чем я получаю от LAB Fit. Интерфейс LAB Fit ужасен. Я также хотел бы иметь возможность разбить диапазон на несколько частей и иметь разные кривые, представляющие разные части диапазона. В конце концов, результат должен быть в состоянии (по скорости) превзойти LUT с линейной интерполяцией, или я не заинтересован.

В моем текущем наборе проблем у меня есть триггерные функции или exp (), и мне нужно выполнять их 352800 раз в секунду в режиме реального времени (и использовать только часть процессора). Поэтому я строю кривую и использую данные, чтобы привести в порядок установщик кривой, чтобы получить менее дорогие приближения. В старые времена, LUT были почти всегда решением, но в настоящее время пропуск поиска памяти и приближение иногда бывают быстрее.

Ответы [ 6 ]

8 голосов
/ 03 сентября 2009

Чтобы ответить на ваш вопрос в общем смысле (относительно оценки параметров в R) без учета специфики указанных вами уравнений, я думаю, что вы ищете nls () или optim () ... nls - это мое Первый выбор, так как он предоставляет оценки ошибок для каждого оцениваемого параметра, а в случае неудачи я использую «optim». Если у вас есть переменные x, y:

out <- tryCatch(nls( y ~ A+B*x+C*x*x, data = data.frame(x,y), 
                start = c(A=0,B=1,C=1) ) ,
                error=function(e) 
                optim( c(A=0,B=1,C=1), function(p,x,y)  
                      sum((y-with(as.list(p),A + B*x + C*x^2))^2), x=x, y=y) )

чтобы получить коэффициенты, что-то вроде

getcoef <- function(x) if(class(x)=="nls") coef(x) else x$par
getcoef(out)

Если вы хотите стандартные ошибки в случае 'nls',

summary(out)$parameters

Файлы справки и сообщения в списке рассылки r-help содержат множество обсуждений, касающихся конкретных алгоритмов минимизации, реализуемых каждым (по умолчанию используется в каждом приведенном выше примере), и их соответствия конкретной форме уравнения. Некоторые алгоритмы могут обрабатывать рамочные ограничения, а другая функция с именем constrOptim () будет обрабатывать набор линейных ограничений. Этот сайт также может помочь:

http://cran.r -project.org / веб / просмотров / Optimization.html

8 голосов
/ 31 августа 2009

Ваша первая модель на самом деле линейная по трем параметрам и может быть вписана в R, используя

 fit <- lm(y ~ x + I(x^2), data=X)

, который даст вам три параметра.

Вторая модель также может быть подобрана с использованием nls() в R с обычными оговорками необходимости предоставления начальных значений и т. Д. статистические проблемы в оптимизации не обязательно совпадают с числовыми значениями проблемы - вы не можете просто оптимизировать любую функциональную форму независимо от того, какой язык вы выберете.

1 голос
/ 01 сентября 2009

, если у вас есть ограничения на ваши коэффициенты, и вы знаете, что есть определенный тип функции, который вы хотели бы вписать в свои данные, и эта функция беспорядочная, где стандартные методы регрессии или другие методы подбора кривой не работа, вы рассматривали генетические алгоритмы?

это не мой первый выбор, но если вы пытаетесь найти коэффициенты второй функции, о которой вы упомянули, то, возможно, GA сработают, особенно если вы используете нестандартные метрики для оценки наилучшего соответствия. например, если вы хотите найти коэффициенты «(A + Bx + Cx ^ 2) / (Dx + Ex ^ 2)», чтобы сумма квадратических разностей между вашей функцией и данными была минимальной и если существует некоторое ограничение на длину дуги получаемой функции, то стохастический алгоритм может быть хорошим способом приблизиться к этому.

некоторые предостережения: 1) стохастические алгоритмы не гарантируют лучшее решение, но они часто будут очень близки. 2) нужно быть осторожным со стабильностью алгоритма.

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

1 голос
/ 31 августа 2009

В R это довольно просто.

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

Затем вы называете это как out = optim (1, err_fn)

где err_fn

err_fn = function(A) {
    diff = 0;
    for(i in 1:data_length){
      x = eckses[i];
      y = data[i];
      model_y = A*x;
      diff = diff + ( y - model_y )^2
    }
    return(diff);
}

Это просто предполагает, что у вас есть вектор значений x и y в eckses и data. Измените строку model_y по своему усмотрению, даже добавьте больше параметров.

Он работает на нелинейных просто отлично, я использую его для четырехмерных кривых е ^ х, и это очень быстро. Выходные данные включают в себя значение ошибки в конце подгонки, которое является мерой того, насколько хорошо оно подойдет, в виде суммы квадратов разностей (в моем err_fn).

EDIT: Если вам НУЖНО воспринимать модель как строку, вы можете настроить свой пользовательский интерфейс на создание всего процесса подбора модели в виде сценария R и загрузить его для запуска. R может брать текст из STDIN или из файла, так что не составит труда создать строковый эквивалент этой функции, и он будет автоматически запускаться при оптимизации.

1 голос
/ 31 августа 2009

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

Для вашего первого примера подойдет полином наименьших квадратов. (Вам решать, какую степень полинома использовать - квадратичную, кубическую, квартичную и т. Д.). Для рациональной функции, такой как ваш второй пример, вам, возможно, придется «свернуть свою», если вы не можете найти подходящую библиотеку. Кроме того, имейте в виду, что для аппроксимации вашей «реальной» функции можно использовать полином достаточно высокой степени, если вам не нужно экстраполировать за пределы набора данных, который вам подходит.

Как уже отмечали другие, существуют и другие, более обобщенные алгоритмы оценки параметров, которые также могут оказаться полезными. Но эти алгоритмы не совсем «подключи и работай»: они обычно требуют от вас написания некоторых вспомогательных процедур и предоставления списка начальных значений для параметров модели. Такие алгоритмы могут расходиться или застревать в локальном минимуме или максимуме для неудачного выбора начальных оценок параметров.

1 голос
/ 31 августа 2009

Проверьте GNU Octave - между его polyfit () и решателем нелинейных ограничений должно быть возможно создать что-то подходящее для вашей задачи.

...