Поиск кривой для сопоставления данных

Я ищу нелинейную процедуру подгонки кривой (вероятно, наиболее вероятно,можно найти в 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 (), и мне нужно выполняйте их 352,800 раз в секунду в режиме реального времени (и используйте только часть процессора). Поэтому я строю кривую и использую данные для приведения кривой в соответствие, чтобы получить менее дорогие аппроксимации. В старые времена лут почти всегда были решением, но в настоящее время пропускать поиск памяти и делать приближение иногда быстрее.

6 ответов


чтобы ответить на ваш вопрос в общем смысле (относительно оценки параметров в 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 содержат много обсуждений относительно конкретных алгоритмов минимизации, реализованных каждым (по умолчанию используется в каждом примере выше), и их уместности для конкретной формы уравнения. Некоторые алгоритмы могут обрабатывать ограничения box, а другая функция constrOptim () будет обрабатывать набор линейных ограничений. Этот веб-сайт также может помогите!--4-->

http://cran.r-project.org/web/views/Optimization.html


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

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

который получит вас ваши 3 параметра.

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


проверить GNU Octave - между его 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.


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

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

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


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

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

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

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