GOOGLE ADS

domingo, 1 de mayo de 2022

Por qué mi ajuste para una función logarítmica se ve tan mal

Estoy trazando este conjunto de datos y haciendo un ajuste logarítmico, pero, por alguna razón, el ajuste parece estar muy mal, en algún momento obtuve un ajuste lo suficientemente bueno, pero luego volví a trazar y hubo un mal ajuste. Al principio había un 0.0 0.0076pero lo cambié 0.001 0.0076para evitar la asíntota.

Estoy usando (no exactamente este para la imagen de arriba, pero ahora estoy probando con este y también hay un mal ajuste) esto para el ajuste

f(x) = a*log(k*x + b)
fit = fit f(x) 'R_B/R_B.txt' via a, k, b

Y la salida es esta

Además, a veces dice que hubo 7 iteraciones como en el caso que se muestra en la captura de pantalla anterior, otras solo 1, y cuando hizo el ajuste "correcto", hizo como 35 iteraciones o algo así y obtuvo un = 32 si no recuerdo mal.

Editar: aquí está nuevamente el bueno, la trama que obtuve es esta. Y de nuevo, vuelvo a tramar y obtengo ese ajuste extraño. Es curioso que si hay el 0.0 0.0076cuando está a punto de mostrarse el buen ajuste, gnuplot dice " Undefined value during function evaluation", pero no se muestra ese mensaje cuando me sale el mal.

¿Sabes por qué sigo recibiendo esta inconsistencia? Gracias por tu ayuda


Solución del problema

El problema aquí es que el algoritmo de ajuste comienza con aproximaciones "incorrectas" para los parámetros a, k y b, por lo que durante la minimización encuentra un mínimo local, no el global. Puede mejorar el resultado si proporciona al algoritmo valores iniciales que estén cerca de los óptimos. Por ejemplo, comencemos con los siguientes parámetros:

gnuplot> a=47.5087
gnuplot> k=0.226
gnuplot> b=1.0016
gnuplot> f(x)=a*log(k*x+b)
gnuplot> fit f(x) 'R_B.txt' via a,k,b
....
....
....
After 40 iterations the fit converged.
final sum of squares of residuals: 16.2185
rel. change during last iteration: -7.6943e-06
degrees of freedom (FIT_NDF) : 18
rms of residuals (FIT_STDFIT) = sqrt(WSSR/ndf): 0.949225
variance of residuals (reduced chisquare) = WSSR/ndf: 0.901027
Final set of parameters Asymptotic Standard Error
======================= ==========================
a = 35.0415 +/- 2.302 (6.57%)
k = 0.372381 +/- 0.0461 (12.38%)
b = 1.07012 +/- 0.02016 (1.884%)
correlation matrix of the fit parameters:
a k b
a 1.000
k -0.994 1.000
b 0.467 -0.531 1.000

La trama resultante es

aquí

Ahora la pregunta es ¿cómo puede encontrar aproximaciones iniciales "buenas" para sus parámetros? Bueno, empiezas con

ingrese la descripción de la imagen aquí

Si derivas esta ecuación obtienes

ingrese la descripción de la imagen aquí

o

ingrese la descripción de la imagen aquí

El lado izquierdo de esta ecuación es una constante 'C', por lo que la expresión del lado derecho también debería ser igual a esta constante:

ingrese la descripción de la imagen aquí

En otras palabras, el recíproco de la derivada de sus datos debe aproximarse mediante una función lineal. Entonces, a partir de sus datos x[i], y[i]puede construir las derivadas recíprocas y x[i]el (x[i+1]-x[i])/(y[i+1]-y[i])ajuste lineal de estos datos:

ingrese la descripción de la imagen aquí

El ajuste da los siguientes valores:

C*k = 0.0236179
C*b = 0.106268

Ahora, necesitamos encontrar los valores para a, y C. Digamos que queremos que el gráfico resultante pase cerca del punto inicial y final de nuestro conjunto de datos. Eso significa que queremos

a*log(k*x1 + b) = y1
a*log(k*xn + b) = yn

Por lo tanto,

a*log((C*k*x1 + C*b)/C) = a*log(C*k*x1 + C*b) - a*log(C) = y1
a*log((C*k*xn + C*b)/C) = a*log(C*k*xn + C*b) - a*log(C) = yn

Restando las ecuaciones obtenemos el valor de a:

a = (yn-y1)/log((C*k*xn + C*b)/(C*k*x1 + C*b)) = 47.51

Entonces,

log(k*x1+b) = y1/a
k*x1+b = exp(y1/a)
C*k*x1+C*b = C*exp(y1/a)

A partir de esto podemos calcular C:

C = (C*k*x1+C*b)/exp(y1/a)

y finalmente encontrar el ky b:

k=0.226
b=1.0016

Estos son los valores utilizados anteriormente para encontrar el mejor ajuste.

ACTUALIZAR

Puede automatizar el proceso descrito anteriormente con el siguiente script:

# Name of the file with the data
data='R_B.txt'
# The coordinates of the last data point
xn=NaN
yn=NaN
# The temporary coordinates of a data point used to calculate a derivative
x0=NaN
y0=NaN
linearFit(x)=Ck*x+Cb
fit linearFit(x) data using (xn=$1,dx=$1-x0,x0=$1,$1):(yn=$2,dy=$2-y0,y0=$2,dx/dy) via Ck, Cb
# The coordinates of the first data point
x1=NaN
y1=NaN
plot data using (x1=$1):(y1=$2) every::0::0
a=(yn-y1)/log((Ck*xn+Cb)/(Ck*x1+Cb))
C=(Ck*x1+Cb)/exp(y1/a)
k=Ck/C
b=Cb/C
f(x)=a*log(k*x+b)
fit f(x) data via a,k,b
plot data, f(x)
pause -1

No hay comentarios.:

Publicar un comentario

Flutter: error de rango al acceder a la respuesta JSON

Estoy accediendo a una respuesta JSON con la siguiente estructura. { "fullName": "FirstName LastName", "listings...