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.0076
pero lo cambié 0.001 0.0076
para 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.0076
cuando 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
Ahora la pregunta es ¿cómo puede encontrar aproximaciones iniciales "buenas" para sus parámetros? Bueno, empiezas con
Si derivas esta ecuación obtienes
o
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:
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:
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 k
y 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