Proyectos de Subversion Moodle

Rev

| Ultima modificación | Ver Log |

Rev Autor Línea Nro. Línea
1 efrain 1
<?php
2
 
3
declare(strict_types=1);
4
 
5
namespace Phpml\FeatureSelection;
6
 
7
use Phpml\Exception\InvalidArgumentException;
8
use Phpml\Exception\InvalidOperationException;
9
use Phpml\FeatureSelection\ScoringFunction\ANOVAFValue;
10
use Phpml\Transformer;
11
 
12
final class SelectKBest implements Transformer
13
{
14
    /**
15
     * @var ScoringFunction
16
     */
17
    private $scoringFunction;
18
 
19
    /**
20
     * @var int
21
     */
22
    private $k;
23
 
24
    /**
25
     * @var array|null
26
     */
27
    private $scores = null;
28
 
29
    /**
30
     * @var array|null
31
     */
32
    private $keepColumns = null;
33
 
34
    public function __construct(int $k = 10, ?ScoringFunction $scoringFunction = null)
35
    {
36
        if ($scoringFunction === null) {
37
            $scoringFunction = new ANOVAFValue();
38
        }
39
 
40
        $this->scoringFunction = $scoringFunction;
41
        $this->k = $k;
42
    }
43
 
44
    public function fit(array $samples, ?array $targets = null): void
45
    {
46
        if ($targets === null || count($targets) === 0) {
47
            throw new InvalidArgumentException('The array has zero elements');
48
        }
49
 
50
        $this->scores = $sorted = $this->scoringFunction->score($samples, $targets);
51
        if ($this->k >= count($sorted)) {
52
            return;
53
        }
54
 
55
        arsort($sorted);
56
        $this->keepColumns = array_slice($sorted, 0, $this->k, true);
57
    }
58
 
59
    public function transform(array &$samples, ?array &$targets = null): void
60
    {
61
        if ($this->keepColumns === null) {
62
            return;
63
        }
64
 
65
        foreach ($samples as &$sample) {
66
            $sample = array_values(array_intersect_key($sample, $this->keepColumns));
67
        }
68
    }
69
 
70
    public function scores(): array
71
    {
72
        if ($this->scores === null) {
73
            throw new InvalidOperationException('SelectKBest require to fit first to get scores');
74
        }
75
 
76
        return $this->scores;
77
    }
78
}