22
$\begingroup$

In the past, I used to solve a lot of my regression analysis (curve fitting) problems with a program called DataFit which runs on Windows. It has hundreds of regression models which it runs through in in order to get the best fit. - Now this is extremely convenient for the lazy engineer with little time at hand.

However, I shifted OS and I now got my beloved Mathematica which has a lot of curve fitting functions who all require a great deal of manual tinkering and guessing.

So the question is: Are there any functions/packages that automatically run through an abundance of models and return the one with best fit? Or do I have to write it myself?

EDIT: Here is an example of a rather clean set of data I often encounter:

data = {{0, 0}, {1.5, 10.47}, {4.8, 16.31}, {9, 20.75}, {14.1, 
   23.81}, {22.6, 26.28}, {32.1, 27.96}, {41.3, 29.94}, {53.8, 
   34.68}, {64.8, 40.22}, {75, 47.04}, {82, 53.48}, {87.8, 
   60.15}, {91.8, 67.75}, {95.1, 76.09}, {97, 83.97}, {98, 90}, {99, 
   100}}

And some interpolating function would be suitable for this, but the problem remains how to extract the interpolating functions and use them in other programs.

$\endgroup$
4
  • 2
    $\begingroup$ What is the point to find a fit with a random function that is not theoretically meaningful? If you just need a smooth line you can use a BSplineFunction or a LowpassFilter. $\endgroup$
    – rhermans
    Nov 15, 2014 at 11:51
  • $\begingroup$ @rhermans That sounds reasonable, but for me, the theoretical background of the data it is not always known beforehand. Do the functions you mentioned return models that can be intered in other programs? $\endgroup$
    – MathLind
    Nov 15, 2014 at 12:08
  • 2
    $\begingroup$ Well the data is the best model of itself, if the theory behind is unknown. Probably what you are after is to have a sparse representation of your data? i.e any function as long as it has with the minimum number of parameters? Hard to do without defining (implicit or explicitly) what is signal and what is noise. Can you give examples of your data and of good and bad fits? Its not clear to me what you really need. $\endgroup$
    – rhermans
    Nov 15, 2014 at 12:15
  • $\begingroup$ @rhermans Thanks for your comment. I added some simple data above. $\endgroup$
    – MathLind
    Nov 15, 2014 at 12:42

2 Answers 2

26
$\begingroup$
vars = {w, x, y, z};
terms = MonomialList[(Plus @@ vars)^3] /. _Integer x_ :> x;
cols = Join @@ {vars, terms} 
(* {w,x,y,z,w^3,w^2 x,w^2 y,w^2 z,w x^2,w x y,w x z,w y^2,
    w y z,w z^2,x^3,x^2 y,x^2 z,x y^2,x y z,x z^2,y^3,y^2 z,y z^2,z^3} *)

For the data

dt = Table[Join[RandomInteger[10, 4], {RandomReal[]}], {100}];

evaluate all models with up to three covariates from the set cols and get the goodness-of-fit-measures "AIC", "BIC", "AdjustedRSquared", "AICc", "RSquared" for each model:

models = Table[Join[{j}, LinearModelFit[dt, j, vars][{"AIC", "BIC", 
                               "AdjustedRSquared", "AICc", "RSquared"}]],
               {j, Subsets[cols, 3]}];
Length@models
(* 2325 *)

Display the top 10:

Grid[{{"Model", "BestFit", "AIC", "BIC", "AdjustedRSquared", "AICc", 
  "RSquared"}, ## & @@ SortBy[models, #[[3]] &][[;; 10]]}, 
   Dividers -> All]

enter image description here

See also: LogitFitModel >> Scope >> Properties >> Goodness-of-Fit Measures for a great example.

Update: A single function combining the necessary steps:

modelsF = Table[Join[{j}, LinearModelFit[#, j, #2][{"BestFit", "AIC", 
  "BIC", "AdjustedRSquared", "AICc", "RSquared"}]], {j, Subsets[#3, #4]}] &;

and another function for showing the results:

resultsF = Grid[{{"BestFit", "Model", "AIC", "BIC", 
  "AdjustedRSquared", "AICc", "RSquared"},
   ## & @@ SortBy[#, #[[3]] &][[;; #2]]}, Dividers -> All] &;

Using the OP's example data to find the best 10 models with 3 covariates:

data = {{0, 0}, {1.5, 10.47}, {4.8, 16.31}, {9, 20.75}, {14.1, 23.81}, {22.6, 26.28},
        {32.1, 27.96}, {41.3, 29.94}, {53.8, 34.68}, {64.8, 40.22}, 
        {75, 47.04}, {82, 53.48}, {87.8, 60.15}, {91.8, 67.75}, {95.1, 76.09},
        {97, 83.97}, {98, 90}, {99, 100}};
cols = {1, x, x^2, x^3, x^4, Sin[x], Cos[x], 1/(.001 + x), 1/(.001 + x^2),
        1/(.001 + x^3), IntegerPart[x], PrimePi[Round[x]]};

models = modelsF[data, {x}, cols, {3}];
resultsF[models, 10]

enter image description here

Note: a better way to generate a richer set of covariates would be

cols = MonomialList[(1 + Plus @@ vars)^3] /. _Integer x_ :> x; (*thanks: @BobHanlon *)

Another note: All the above is essentially a brute-force approach. More rigorous and and smarter methods must exist for model selection.

$\endgroup$
7
  • 1
    $\begingroup$ Awesome and pedagogical answer: My heart jump with joy. Is this the level of knowledge that awaits me after a few more years with Mathematica. $\endgroup$
    – MathLind
    Nov 15, 2014 at 12:58
  • $\begingroup$ @MathLind, great to know this made you so happy:) $\endgroup$
    – kglr
    Nov 15, 2014 at 12:59
  • 1
    $\begingroup$ You will get more models and a better fit with cols = MonomialList[(1 + Plus @@ vars)^3] /. _Integer x_ :> x; $\endgroup$
    – Bob Hanlon
    Nov 15, 2014 at 15:50
  • $\begingroup$ @Bob, good point. I just wanted to get some list of covariates for illustration assuming that the user knows the specific covariates he would like to use. $\endgroup$
    – kglr
    Nov 15, 2014 at 16:06
  • 1
    $\begingroup$ @MathLind, thank you for the accept. Re "many others," great to know that there are quite a few of us "lazy engineers":) $\endgroup$
    – kglr
    Nov 17, 2014 at 11:28
6
$\begingroup$

In version 10.2 there is a new experimental function which might be what you are looking for: FindFormula.

I suspect that a genetic programming algorithm (symbolic regression) is behind this new feature.

See also my question here: What is behind experimental function: FindFormula?

$\endgroup$
2
  • $\begingroup$ Thanks, I will look in to that after moving to 10.2. $\endgroup$
    – MathLind
    Jul 17, 2015 at 17:13
  • 1
    $\begingroup$ Installed and tested. This has the potential of being truly useful. $\endgroup$
    – MathLind
    Jul 17, 2015 at 19:34

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

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