0
$\begingroup$

I'm trying to fit a function to data using FindFit, but I can't find a way to replace norm function RMSE with a RMSE in log space: Total[(Log10[a] - Log10[b])^2]

I tried:

logNorm [x_, y_] = Total[(Log10[x + 1] - Log10[y + 1])^2];
nlm = FindFit[data, x*a+b, {a, b}, x, NormFunction -> (logNorm[#] &)]

But I get an error:

The function value logNorm[<long list>] is not a real number at {a,b} = {1.,1.}.

$\endgroup$
  • 3
    $\begingroup$ NormFunction operates on the list of residuals, which are already formed and provided to this function. You seem to want it to represent the log-distance to the point. Sorry, but it cannot do this; you should use FindMinimum instead with a suitable objective function. FindFit just calls FindMinimum internally, if that makes you feel better. $\endgroup$ – Oleksandr R. Dec 20 '15 at 22:46
  • $\begingroup$ But, perhaps I misunderstood your question. Is Norm[Log10[## + 1], 2] & what you want? I am not sure I understand what your x and y arguments to logNorm are supposed to represent. $\endgroup$ – Oleksandr R. Dec 20 '15 at 22:54
  • $\begingroup$ Thanks. I wanted to replace RMSE with LRMSE. If residuals are already formed, then it's not possible and I'd have to use FindMinimum. In logNorm, x corresponds to observed value and y to fitted value provided by a model. In other words I wanted to replace current residuals calculated as "x-y" with "Log10[x+1]-Log10[y+1]". $\endgroup$ – Krzysztof Narkowicz Dec 21 '15 at 9:31
  • $\begingroup$ @Krzysztof Narkowicz, I guess the norm-function should be represented as f[Delta=observed-calculated], so you should transform your logarithmic expression to this form instead of your f[observed,calculated]. $\endgroup$ – Rom38 Dec 21 '15 at 10:50
3
$\begingroup$

You can pass your data to the NormFunction:

myNorm[residuals_, data_] := 
   Total[(Log[data[[All, 2]] + 1] - 
          Log[data[[All, 2]] + residuals + 1])^2];
data = {#, 2 # + 10 + # RandomReal[{0, 2}]} & /@ Range[100];
fit = x*a + b /. 
    FindFit[data, x*a + b, {a, b}, x, 
         NormFunction -> (myNorm[#, data] &)] 

10.3158 + 2.86435 x

Show[{ListPlot[data], Plot[fit, {x, 0, 100}]}]

enter image description here

or even do this: NormFunction -> (logNorm[data[[All, 2]] + #, data[[All, 2]]] &) and your function as originally defined will work.

| improve this answer | |
$\endgroup$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.