The following sentence popped into my head this weekend, "a regression is the combination of a model and a method".
I was thinking we could create "Models" as objects. Models are functions, but more. A model would necessarily have an evaluateModel() method.
// y=mx+b
trait LinearModel;
{
function evaluateModel(...$params)
{
$x = $params[0];
$m = $params[1];
$b = $params[2];
return $m * $x + $b;
}
// It can also include other "model specific" functions.
public function getModelEquation(...$params): string
{
$x = $params[0];
$m = $params[1];
$b = $params[2];
return sprintf('y = %fx + %f', $m, $b);
}
// Include other stuff as desired. partial derivatives would be handy for Jacobians.
function partialDerivatives($x, $m, $b, $parameter)
{
switch($parameter){
case 1 : return $m;
break;
case 2 : return $x;
break;
case 3 : return 1;
break;
}
}
}
class Regression {
// An array of our regression parameters. Use this instead of $this->m and $this->b.
protected $params
// We can then move the evaluate and getEquation code up to the parent.
// The specific details on how to do this are a little fuzzy, arrays, list of parameters...
public function evaluate($x)
{
// Params is an array of parameters, if the chosen method produces parameters
$fitted_params = $this->params
return evaluateModel($x, $fitted_params);
}
public function getEquation($x)
{
// Params is an array of parameters, if the chosen method produces parameters
$fitted_params = $this->params
return getModelEquation($x, $fitted_params);
}
}
// The Linear class then combines a Linear Model with a Least Squares method.
// We could alternatively combine a Logarithm model with LeastSquares, or Exponential with Interpolation.
class Linear extends Regression
{
use LinearModel;
use LeastSquares;
function calculate($ys, $xs)
{
// Prepare the data for the chosen method.
}
// If we have a non-parametric regression, we will but evaluate code here.
// LOESS or interpolation would be two examples.
function evaluate($x)
{
}
}
We have the existing LeastSquares trait as a method, but we could also use weighted least squares, or non-linear, or LOESS, or whatever.
The job of the regression class is to provide common functions which link a regression method and a model, such as to allow us to arbitrarily evaluate the model at defined points. I'm not saying that the job is to find any sort of universal parameters, because non-parametric regression has no universal parameters. The classes which extend the Regression class are where the model and the method are chosen. Data is prepared for the analysis, and, in the case of non-parametric regressions, functions (like evaluate) may have to be overridden.
I guess "Regression" could be extended to ParametricRegression, and NonParametricRegression...