See Release Notes
Long Term Support Release
<?php declare(strict_types=1); namespace Phpml\FeatureSelection\ScoringFunction; use Phpml\FeatureSelection\ScoringFunction; use Phpml\Math\Matrix; use Phpml\Math\Statistic\Mean; /** * Quick linear model for testing the effect of a single regressor, * sequentially for many regressors. * * This is done in 2 steps: * * 1. The cross correlation between each regressor and the target is computed, * that is, ((X[:, i] - mean(X[:, i])) * (y - mean_y)) / (std(X[:, i]) *std(y)). * 2. It is converted to an F score. * * Ported from scikit-learn f_regression function (http://scikit-learn.org/stable/modules/generated/sklearn.feature_selection.f_regression.html#sklearn.feature_selection.f_regression) */ final class UnivariateLinearRegression implements ScoringFunction { /** * @var bool */ private $center; /** * @param bool $center - if true samples and targets will be centered */ public function __construct(bool $center = true) { $this->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())> 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]; } } } }