samples = array_merge($this->samples, $samples); $this->targets = array_merge($this->targets, $targets); $this->computeCoefficients(); } /** * @return mixed */ public function predictSample(array $sample) { $result = $this->intercept; foreach ($this->coefficients as $index => $coefficient) { $result += $coefficient * $sample[$index]; } return $result; } public function getCoefficients() : array { return $this->coefficients; } public function getIntercept() : float { return $this->intercept; } /** * coefficient(b) = (X'X)-1X'Y. */ private function computeCoefficients(): void { $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. */ private function getSamplesMatrix() : Matrix { $samples = []; foreach ($this->samples as $sample) { array_unshift($sample, 1); $samples[] = $sample; } return new Matrix($samples); } private function getTargetsMatrix() : Matrix { if (is_array($this->targets[0])) { return new Matrix($this->targets); } return Matrix::fromFlatArray($this->targets); } }