AutorÃa | Ultima modificación | Ver Log |
<?phpdeclare(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()/ (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];}}}}