mirror of
https://github.com/Llewellynvdm/php-ml.git
synced 2024-09-28 06:59:02 +00:00
79 lines
1.8 KiB
PHP
79 lines
1.8 KiB
PHP
|
<?php
|
||
|
|
||
|
declare(strict_types=1);
|
||
|
|
||
|
namespace Phpml\FeatureSelection;
|
||
|
|
||
|
use Phpml\Exception\InvalidArgumentException;
|
||
|
use Phpml\Exception\InvalidOperationException;
|
||
|
use Phpml\FeatureSelection\ScoringFunction\ANOVAFValue;
|
||
|
use Phpml\Transformer;
|
||
|
|
||
|
final class SelectKBest implements Transformer
|
||
|
{
|
||
|
/**
|
||
|
* @var ScoringFunction
|
||
|
*/
|
||
|
private $scoringFunction;
|
||
|
|
||
|
/**
|
||
|
* @var int
|
||
|
*/
|
||
|
private $k;
|
||
|
|
||
|
/**
|
||
|
* @var array|null
|
||
|
*/
|
||
|
private $scores = null;
|
||
|
|
||
|
/**
|
||
|
* @var array|null
|
||
|
*/
|
||
|
private $keepColumns = null;
|
||
|
|
||
|
public function __construct(?ScoringFunction $scoringFunction = null, int $k = 10)
|
||
|
{
|
||
|
if ($scoringFunction === null) {
|
||
|
$scoringFunction = new ANOVAFValue();
|
||
|
}
|
||
|
|
||
|
$this->scoringFunction = $scoringFunction;
|
||
|
$this->k = $k;
|
||
|
}
|
||
|
|
||
|
public function fit(array $samples, ?array $targets = null): void
|
||
|
{
|
||
|
if ($targets === null || empty($targets)) {
|
||
|
throw InvalidArgumentException::arrayCantBeEmpty();
|
||
|
}
|
||
|
|
||
|
$this->scores = $sorted = $this->scoringFunction->score($samples, $targets);
|
||
|
if ($this->k >= count($sorted)) {
|
||
|
return;
|
||
|
}
|
||
|
|
||
|
arsort($sorted);
|
||
|
$this->keepColumns = array_slice($sorted, 0, $this->k, true);
|
||
|
}
|
||
|
|
||
|
public function transform(array &$samples): void
|
||
|
{
|
||
|
if ($this->keepColumns === null) {
|
||
|
return;
|
||
|
}
|
||
|
|
||
|
foreach ($samples as &$sample) {
|
||
|
$sample = array_values(array_intersect_key($sample, $this->keepColumns));
|
||
|
}
|
||
|
}
|
||
|
|
||
|
public function scores(): array
|
||
|
{
|
||
|
if ($this->scores === null) {
|
||
|
throw new InvalidOperationException('SelectKBest require to fit first to get scores');
|
||
|
}
|
||
|
|
||
|
return $this->scores;
|
||
|
}
|
||
|
}
|