Вопрос

Я ищу процедуру нелинейной подгонки кривой (вероятно, наиболее вероятно, что ее можно найти в 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.

Это то, что я ищу, или мне нужно сделать что-то свое?Я ненавижу это делать, если оно там есть, и у меня просто возникают проблемы с его поиском.


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

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

Это было полезно?

Решение

Чтобы ответить на ваш вопрос в общем смысле (относительно оценки параметров в R), не учитывая специфику указанных вами уравнений, я думаю, вы ищете nls() или optim()...«nls» — мой первый выбор, поскольку он предоставляет оценки ошибок для каждого оцениваемого параметра, а в случае неудачи я использую «оптимум».Если у вас есть переменные 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/web/views/Optimization.html

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

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

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

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

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

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

В 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 и данных.Измените строку model_y по своему усмотрению, даже добавьте больше параметров.

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

РЕДАКТИРОВАТЬ:Если вам НУЖНО принять модель в виде строки, вы можете создать в своем пользовательском интерфейсе весь процесс подгонки модели в виде сценария R и загрузить его для запуска.R может брать текст из STDIN или из файла, поэтому не должно быть слишком сложно создать строковый эквивалент этой функции и автоматически запустить ее optim.

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

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

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

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

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

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

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

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top