Code Coverage |
||||||||||
Classes and Traits |
Functions and Methods |
Lines |
||||||||
| Total | |
100.00% |
1 / 1 |
|
100.00% |
7 / 7 |
CRAP | |
100.00% |
25 / 25 |
| LeastSquares | |
100.00% |
1 / 1 |
|
100.00% |
7 / 7 |
10 | |
100.00% |
25 / 25 |
| train | |
100.00% |
1 / 1 |
1 | |
100.00% |
4 / 4 |
|||
| predictSample | |
100.00% |
1 / 1 |
2 | |
100.00% |
4 / 4 |
|||
| getCoefficients | |
100.00% |
1 / 1 |
1 | |
100.00% |
1 / 1 |
|||
| getIntercept | |
100.00% |
1 / 1 |
1 | |
100.00% |
1 / 1 |
|||
| computeCoefficients | |
100.00% |
1 / 1 |
1 | |
100.00% |
7 / 7 |
|||
| getSamplesMatrix | |
100.00% |
1 / 1 |
2 | |
100.00% |
5 / 5 |
|||
| getTargetsMatrix | |
100.00% |
1 / 1 |
2 | |
100.00% |
3 / 3 |
|||
| <?php | |
| declare (strict_types = 1); | |
| namespace Phpml\Regression; | |
| use Phpml\Helper\Predictable; | |
| use Phpml\Math\Matrix; | |
| class LeastSquares implements Regression | |
| { | |
| use Predictable; | |
| /** | |
| * @var array | |
| */ | |
| private $samples; | |
| /** | |
| * @var array | |
| */ | |
| private $targets; | |
| /** | |
| * @var float | |
| */ | |
| private $intercept; | |
| /** | |
| * @var array | |
| */ | |
| private $coefficients; | |
| /** | |
| * @param array $samples | |
| * @param array $targets | |
| */ | |
| public function train(array $samples, array $targets) | |
| { | |
| $this->samples = $samples; | |
| $this->targets = $targets; | |
| $this->computeCoefficients(); | |
| } | |
| /** | |
| * @param array $sample | |
| * | |
| * @return mixed | |
| */ | |
| public function predictSample(array $sample) | |
| { | |
| $result = $this->intercept; | |
| foreach ($this->coefficients as $index => $coefficient) { | |
| $result += $coefficient * $sample[$index]; | |
| } | |
| return $result; | |
| } | |
| /** | |
| * @return array | |
| */ | |
| public function getCoefficients() | |
| { | |
| return $this->coefficients; | |
| } | |
| /** | |
| * @return float | |
| */ | |
| public function getIntercept() | |
| { | |
| return $this->intercept; | |
| } | |
| /** | |
| * coefficient(b) = (X'X)-1X'Y. | |
| */ | |
| private function computeCoefficients() | |
| { | |
| $samplesMatrix = $this->getSamplesMatrix(); | |
| $targetsMatrix = $this->getTargetsMatrix(); | |
| $ts = $samplesMatrix->transpose()->multiply($samplesMatrix)->inverse(); | |
| $tf = $samplesMatrix->transpose()->multiply($targetsMatrix); | |
| $this->coefficients = $ts->multiply($tf)->getColumnValues(0); | |
| $this->intercept = array_shift($this->coefficients); | |
| } | |
| /** | |
| * Add one dimension for intercept calculation. | |
| * | |
| * @return Matrix | |
| */ | |
| private function getSamplesMatrix() | |
| { | |
| $samples = []; | |
| foreach ($this->samples as $sample) { | |
| array_unshift($sample, 1); | |
| $samples[] = $sample; | |
| } | |
| return new Matrix($samples); | |
| } | |
| /** | |
| * @return Matrix | |
| */ | |
| private function getTargetsMatrix() | |
| { | |
| if (is_array($this->targets[0])) { | |
| return new Matrix($this->targets); | |
| } | |
| return Matrix::fromFlatArray($this->targets); | |
| } | |
| } |