2009-08-31 29 views
10

Estoy buscando una rutina de ajuste de curva no lineal (probablemente más probable que se encuentre en R o Python, pero estoy abierto a otros idiomas) que tomaría datos x, y adaptarse a una curva.Encontrar una curva para hacer coincidir los datos

Debería ser capaz de especificar como una cadena el tipo de expresión que quiero encajar.

Ejemplos:

"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" 

Lo que iba a salir de esto es, al menos, los valores de las constantes (A, B, C, etc.) y es de esperar las estadísticas sobre la idoneidad del partido.

Existen programas comerciales para hacer esto, pero esperaba poder encontrar algo tan común como ajustarse a una expresión deseada en una biblioteca de idiomas hoy en día. Sospecho que la optimización de SciPy podría hacer esto, pero no veo que me permita definir una ecuación. Del mismo modo, no puedo encontrar exactamente lo que quiero en R.

¿Es lo que estoy buscando por ahí, o tengo que hacer el mío? Odio hacerlo si está allí y solo tengo problemas para encontrarlo.


Editar: Quiero hacer esto para tener un poco más de control sobre el proceso que el que obtengo de LAB Fit. La UI de ajuste de LAB es espantosa. También me gustaría poder dividir el rango en múltiples piezas y tener diferentes curvas para representar las diferentes piezas de la gama. Al final, el resultado tiene que ser capaz (en velocidad) de vencer a una LUT con interpolación lineal o no estoy interesado.

En mi conjunto actual de problemas, tengo funciones trigonométricas o exp() y necesito ejecutarlas 352,800 veces por segundo en tiempo real (y usar solo una fracción de la CPU). Así que trazado la curva y uso los datos para conducir al instalador de curvas a obtener aproximaciones menos costosas. En los viejos tiempos, los LUT casi siempre eran la solución, pero hoy en día omitir las búsquedas de memoria y hacer una aproximación a veces es más rápido.

+0

¿Se da cuenta de que esto es realmente una mala idea, estadísticamente hablando? Si solo desea un ajuste flexible a sus datos, utilice un modelo flexible como loess, splines o modelos aditivos generalizados. – hadley

+0

Incluso dividir el rango en rangos más pequeños es un costo con el que debo tener cuidado. Tengo acceso a todo tipo de interpoladores geniales para datos de audio, pero generalmente son demasiado intensivos en computación para mí. Generalmente, una vez que tengo que comenzar a romper el rango en pedazos, estoy mejor con un LUT. Las aproximaciones de las curvas siguen siendo bastante útiles en las aplicaciones DSP. – Nosredna

Respuesta

8

Para responder a su pregunta en un sentido general (con respecto a la estimación de parámetros en R) sin considerar los detalles de las ecuaciones que ha señalado, creo que está buscando nls() o optim() ...'nls' es mi primera opción, ya que proporciona estimaciones de errores para cada parámetro estimado y cuando falla, uso 'optim'. Si usted tiene sus x, y las variables:

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)) 

para obtener los coeficientes, algo así como

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

Si desea que los errores estándar en el caso de ÑLS ',

summary(out)$parameters 

Los archivos de ayuda y las publicaciones de la lista de correo de r-help contienen muchas discusiones sobre los algoritmos de minimización específicos implementados por cada uno (el predeterminado usado en cada ejemplo de caso anterior) y su adecuación para el f específico orma de la ecuación en cuestión. Ciertos algoritmos pueden manejar restricciones de caja, y otra función llamada constrOptim() manejará un conjunto de restricciones lineales. Este sitio web también puede ayudar:

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

+0

¿Puedo alimentar la fórmula como cadenas? – Nosredna

+1

sí - algo así como as.formula (pegar ("y", "A + B * x + C * x^2", sep = "~")) debería hacerlo. – hatmatrix

+0

que estaba en el caso nls, en optim algo parecido a eval (parse (text = sprintf ("suma ((y-% s)^2)", "A + B * x + C * x^2"))) debería funcionar (se muestra la construcción de sprintf para que pueda insertar la fórmula que desee). – hatmatrix

1

Echa un vistazo GNU Octave - entre su polyfit() y el solucionador de restricciones no lineales debería ser posible construir algo adecuado para su problema.

+0

De hecho, uso Octave algunas veces. Veré lo que puedo descubrir. – Nosredna

8

Su primer modelo es en realidad lineal en los tres parámetros y puede estar en forma en I usando

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

que te llevará sus tres parámetros. No se puede simplemente -

El segundo modelo también puede estar en forma usando nls() en R con las advertencias habituales de tener que proporcionar valores a partir etc. Las estadísticas cuestiones de optimización no son necesariamente los mismos que los numéricos cuestiones optimice cualquier forma funcional sin importar el idioma que elija.

+3

Aunque estaría mejor con 'y ~ poly (x, 2)' o 'y ~ ns (x, 2)' – hadley

1

Probablemente no va a encontrar una sola rutina con la flexibilidad implícita en sus ejemplos (polinomios y funciones racionales usando la misma rutina), y mucho menos una que analizará una cadena para descubrir qué tipo de ecuación encajar .

Un polinomio de mínimos cuadrados sería apropiado para su primer ejemplo. (Depende de usted qué grado de polinomio usar: cuadrádico, cúbico, cuártico, etc.). Para una función racional como su segundo ejemplo, es posible que deba "rodar la suya" si no puede encontrar una biblioteca adecuada.Además, tenga en cuenta que se puede usar un polinomio de alto grado para aproximar su función "real", siempre y cuando no necesite extrapolar más allá de los límites del conjunto de datos que le corresponde.

Como han notado otros, existen otros algoritmos de estimación de parámetros más generalizados que también podrían ser útiles. Pero esos algoritmos no son del todo "plug and play": generalmente requieren que escriba algunas rutinas auxiliares y proporcione una lista de valores iniciales para los parámetros del modelo. Es posible que estos tipos de algoritmos diverjan o se estanquen en un mínimo o máximo local para una mala elección de los parámetros iniciales estimados.

+0

Cuando uso los productos comerciales, normalmente tengo _no idea_ qué funcionará mejor. LAB Fit probará varios cientos de ecuaciones para ver qué se ajusta mejor a los datos en el rango que especifico. – Nosredna

+0

No había considerado ese caso de uso: si está en las primeras etapas de intentar caracterizar un conjunto de datos, tiene sentido probar varias familias de funciones (lineal, polinomial, de poder, periódica ...) para ver cómo se vería un buen ajuste Voy a editar mi respuesta en consecuencia. –

+0

"Es posible que este tipo de algoritmos diverjan ..." Sí, supongo que los programas comerciales simplemente rescatan cuando esto sucede durante la verificación de todas las opciones. Te permiten jugar con los valores iniciales cuando eliges una expresión a la vez. – Nosredna

1

En R, esto es bastante fácil.

El método incorporado se llama optim(). Toma como argumentos un vector inicial de parámetros potenciales, luego una función. Tienes que construir tu propia función de error, pero eso es realmente simple.

A continuación, llamar así a cabo Optim = (1, err_fn)

donde err_fn es

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); 
} 

Esto se supone que tiene un vector de valores X e Y en eckses y datos. Cambie la línea model_y como mejor le parezca, incluso agregue más parámetros.

Funciona de forma no lineal muy bien, lo uso para cuatro dimensiones e^x curvas y es muy rápido. Los datos de salida incluyen el valor de error al final del ajuste, que es una medida de qué tan bien encaja, dado como una suma de diferencias al cuadrado (en mi err_fn).

EDIT: Si NECESITA tomar en el modelo como una cadena, puede hacer que su interfaz de usuario construya todo el proceso de ajuste del modelo como un guión R y lo cargue para ejecutarlo. R puede tomar texto de STDIN o de un archivo, por lo que no debería ser demasiado difícil crear el equivalente de cadena de esta función y hacer que funcione de manera óptima.

+0

Pero, ¿por qué no usar nls() en R? –

+0

No uso nls por dos razones, primero, me gusta poder crear manualmente la función de error para optimizarla, y segundo, en realidad no soy tan experimentado con R. Así que nls() hace justo lo que escribí allí. ? Ordenado. – Karl

+0

Mi objetivo final es entregarle una lista de cadenas y tener el código probarlas todas para encontrar la mejor opción. – Nosredna

1

si tiene restricciones en sus coeficientes, y sabe que hay un tipo específico de función que le gustaría ajustar a sus datos y esa función es desordenada donde los métodos de regresión estándar u otros métodos de ajuste de curvas ganaron ' t trabajo, ¿ha considerado los algoritmos genéticos?

no son mi primera opción, pero si está tratando de encontrar los coeficientes de la segunda función que mencionó, entonces tal vez las GA funcionarían, especialmente si está utilizando métricas no estándar para evaluar el mejor ajuste. por ejemplo, si quiere encontrar los coeficientes de "(A + Bx + Cx^2)/(Dx + Ex^2)" de modo que la suma de las diferencias cuadradas entre su función y los datos sea mínima y que haya alguna restricción en la longitud de arco de la función resultante, entonces un algoritmo estocástico podría ser una buena forma de abordar esto.

algunas advertencias: 1) los algoritmos estocásticos no garantizan la mejor solución , pero a menudo estarán muy cerca. 2) debes tener cuidado con la estabilidad del algoritmo.

en una nota más larga, si se encuentra en la etapa en la que desea encontrar una función desde un espacio de funciones que mejor se ajusta a sus datos (por ejemplo, no va a imponer, por ejemplo, el segundo modelo en sus datos), entonces las técnicas de programación genética también pueden ayudar.

+0

Esa es una idea interesante. Pensaré sobre eso. Obviamente, sería lento. Los programas comerciales se ejecutan a través de cientos de formas de ecuaciones en segundos. – Nosredna

+0

sí, otro inconveniente es que los algoritmos estocásticos pueden ser lentos. sin embargo, al alza, es posible obtener una forma de ecuación fuera del conjunto que atraviesan los programas comerciales. al permitir que un programa genético busque a través de * clases * de funciones (con operaciones en esas funciones) tales como, funciones de potencia, exponenciales, logaritmos, funciones trigonométricas, pdfs/cdfs, etc., es posible encontrar una solución no dada por un sistema fijo conjunto de formas de ecuaciones. pero una vez más a la baja, esto requiere un esfuerzo razonable de codificación inicial que puede no valer la pena. –

+0

Siempre estoy preparado para una aventura Quijotesca. – Nosredna

Cuestiones relacionadas