center = $center; } public function score(array $samples, array $targets): array { if ($this->center) { $this->centerTargets($targets); $this->centerSamples($samples); } $correlations = []; foreach (array_keys($samples[0]) as $index) { $featureColumn = array_column($samples, $index); $correlations[$index] = Matrix::dot($targets, $featureColumn)[0] / (new Matrix($featureColumn, false))->transpose()->frobeniusNorm() / (new Matrix($targets, false))->frobeniusNorm(); } $degreesOfFreedom = count($targets) - ($this->center ? 2 : 1); return array_map(function (float $correlation) use ($degreesOfFreedom): float { return $correlation ** 2 / (1 - $correlation ** 2) * $degreesOfFreedom; }, $correlations); } private function centerTargets(array &$targets): void { $mean = Mean::arithmetic($targets); array_walk($targets, function (&$target) use ($mean): void { $target -= $mean; }); } private function centerSamples(array &$samples): void { $means = []; foreach ($samples[0] as $index => $feature) { $means[$index] = Mean::arithmetic(array_column($samples, $index)); } foreach ($samples as &$sample) { foreach ($sample as $index => &$feature) { $feature -= $means[$index]; } } } }