protected function split(Labeled $dataset) : Decision
    {
        $bestImpurity = INF;
        $bestColumn = $bestValue = null;
        $bestGroups = [];

        $max = $dataset->numRows() - 1;

        shuffle($this->columns);

        foreach (array_slice($this->columns, 0, $this->maxFeatures) as $column) {
            $sample = $dataset->row(rand(0, $max));

            $value = $sample[$column];

            $groups = $dataset->partition($column, $value);

            $impurity = $this->splitImpurity($groups);

            if ($impurity < $bestImpurity) {
                $bestColumn = $column;
                $bestValue = $value;
                $bestGroups = $groups;
                $bestImpurity = $impurity;
            }

            if ($impurity < $this->tolerance) {
                break 1;
            }
        }

        return new Decision($bestColumn, $bestValue, $bestGroups, $bestImpurity);
    }