As the question says, can one force a fit through the origin $(0,0)$, as one can when fitting a trendline to your data in Microsoft Excel? If so, how do you do that?
4 Answers
data = Table[{i, 3 i + RandomReal[2]}, {i, 10}]
line = Fit[data, {x}, x]
Show[ListPlot[data, PlotStyle -> Red], Plot[line, {x, 0, 10}], PlotLabel -> line]
-
12$\begingroup$ Also:
LinearModelFit[..., IncludeConstantBasis -> False]
. $\endgroup$ Sep 17, 2012 at 19:00 -
$\begingroup$ @OleksandrR. also
Minimize[Sum[(i[[2]] - a i[[1]])^2, {i, data}], a]
and zillions more :) $\endgroup$ Sep 17, 2012 at 19:08 -
1$\begingroup$ Yes, that surely fits the description of "force"! :) $\endgroup$ Sep 17, 2012 at 20:28
Another possibility, a bit more general :
data = Table[{i, 3 i + RandomReal[2]}, {i, 10}];
model[x_] = a Cos[x] + b x^2 + c;
sol = FindFit[data, {model[x]}, {a, b, c}, x];
One can add constraints on the parameters to the model :
sol2 = FindFit[data, {model[x], model[0] == 0}, {a, b, c}, x];
Show[ListPlot[data], Plot[{model[x] /. sol, model[x] /. sol2}, {x, 0, 10}]]
-
8$\begingroup$ Important consideration with this approach: the interior point method (which is used for all constrained fits unless
Method -> NMinimize
is specified) requires that the residual and any additional constraints be twice differentiable, preferably analytically. If not, it will usually have trouble converging. $\endgroup$ Sep 17, 2012 at 20:32 -
$\begingroup$ @OleksandrR. Good point, thanks, I was not aware of this - is it in the documentation ? $\endgroup$ Sep 18, 2012 at 11:15
-
$\begingroup$ Sort of--you can find it discussed in relation to
FindMinimum
here. $\endgroup$ Sep 18, 2012 at 11:26 -
-
$\begingroup$ Thank you all for answering. I really appreciate it. $\endgroup$ Sep 20, 2012 at 10:16
I have given a derivation of the needed formulae in this math.SE answer. As already mentioned by belisarius, the canonical method for finding the equation of the least-squares line constrained to pass through the origin in Mathematica would be either of
Fit[data, {x}, x]
which produces the explicit linear function, or
FindFit[data, m x, m, x]
which produces just the slope of the best-fit line as a replacement rule.
To handle the case of a least-squares line constrained to pass through an arbitrary point $(h,k)$, you can again use either of Fit[]
or FindFit[]
, but things are slightly trickier. (I'll leave the task of encapsulating that method in a Mathematica routine as an exercise.) For this answer, I'll present the explicit formula, as implemented in Mathematica:
fixedLine[data_?MatrixQ, pt : (_?VectorQ) : {0, 0}] := Module[{a, b, dat, sx, sy},
dat = If[Precision[data] === Infinity, N[data], data];
{sx, sy} = Transpose[dat] - pt;
b = sx.sy/sx.sx;
a = #2 - b #1 & @@ pt;
Function[\[FormalX], Evaluate[Chop[a + b \[FormalX]]]]]
This returns the best-fit line as a pure function. Here are a few examples, taken from Kolb's Curve Fitting for Programmable Calculators:
fixedLine[{{100, 140}, {200, 230}, {300, 310}, {400, 400}, {500, 480}}, {300, 310}]
Function[\[FormalX]$, 55. + 0.85 \[FormalX]$]
fixedLine[{{11, 15}, {17, 23}, {23, 31}, {29, 39}}]
Function[\[FormalX]$, 1.34831 \[FormalX]$]
-
$\begingroup$ Thank you J.M. for answering my question. $\endgroup$ Sep 20, 2012 at 10:16
belisarius gives the solution but forgot to tell why it is the solution.
The general equation for your linear regression line is
$y = a x + b$
which you write in the Fit
function as
line = Fit[data, {x, 1}, x]
The second parameter is a list of functions. Fit will find the best fit by making a weighted sum of these functions, i.e.
$ a_1 \cdot x + a_2 \cdot 1 $
If you want a line through the origin the constant term should be zero, and the Fit
becomes
line = Fit[data, {x}, x]
Example:
data = Table[{i, 10 + 3 i + RandomReal[2]}, {i, 10}];
line1 = Fit[data, {1, x}, x]
line2 = Fit[data, {x}, x]
Show[ListPlot[data, PlotStyle -> PointSize[0.02]],
Plot[{line1, line2}, {x, 0, 10}, PlotStyle -> Thick]]
gives us
11.673984 + 2.9005496 x 4.5682616 x
-
$\begingroup$ Thank you very much stevenh for the clarification. $\endgroup$ Sep 20, 2012 at 10:15