Prepend this dataset with another dataset.

@param \Rubix\ML\Datasets\Dataset $dataset
@return \Rubix\ML\Datasets\Dataset
518590
public function prepend(Dataset $dataset) : Dataset
    {
        return self::quick(array_merge($dataset->samples(), $this->samples));
    }
657902
public static function terminate(Dataset $dataset, int $depth) : self
    {
        $depth += self::c($dataset->numRows()) - 1.;

        return new self($depth);
    }
1006364
public static function toNQuads($dataset) {
    $quads = array();
    foreach($dataset as $graph_name => $triples) {
      foreach($triples as $triple) {
        if($graph_name === '@default') {
          $graph_name = null;
        }
        $quads[] = self::toNQuad($triple, $graph_name);
      }
    }
    sort($quads);
    return implode($quads);
  }
135859
public function bind($dataset)
    {
        if ($dataset === null) {
            return $this;
        }

        if ($dataset instanceof \Traversable) {
            $dataset = iterator_to_array($dataset);
        } elseif (is_object($dataset)) {
            $dataset = [$dataset];
        } elseif (!is_array($dataset)) {
            throw new \InvalidArgumentException('Need an array or object');
        }

        foreach ($dataset as $k => $data) {
            $this[$k] = $data;
        }

        return $this;
    }
1172807
public function fit(Dataset $dataset) : void
    {
        $columns = $dataset->columnsByType(DataType::CONTINUOUS);

        $this->medians = $this->mads = [];

        foreach ($columns as $column => $values) {
            [$median, $mad] = Stats::medMad($values);

            $this->medians[$column] = $median;
            $this->mads[$column] = $mad ?: EPSILON;
        }
    }
1239152
public function train(Dataset $dataset) : void
    {
        if (!$dataset instanceof Labeled) {
            throw new InvalidArgumentException('This estimator requires a'
                . ' labeled training set.');
        }

        DatasetIsCompatibleWithEstimator::check($dataset, $this);

        $samples = $dataset->samples();
        $labels = $dataset->labels();

        $biases = Matrix::ones($dataset->numRows(), 1);

        $x = Matrix::build($samples)->augmentLeft($biases);
        $y = Vector::build($labels);

        $alphas = array_fill(0, $x->n() - 1, $this->alpha);

        $penalty = Matrix::diagonal(array_merge([0.], $alphas));

        $xT = $x->transpose();

        $coefficients = $xT->matmul($x)
            ->add($penalty)
            ->inverse()
            ->dot($xT->dot($y))
            ->asArray();

        $this->bias = (float) array_shift($coefficients);
        $this->weights = Vector::quick($coefficients);
    }
662742
protected function preparePriceDataKeysCache(DataSetInterface $dataSet): void
    {
        if ($this->isDataKeysCachePrepared) {
            return;
        }
        foreach ($dataSet as $key => $value) {
            if (!$this->isPriceDataKey($key)) {
                continue;
            }
            $this->priceDataKeysCache[$key] = $this->getPriceDataKey($key);
        }
        $this->isDataKeysCachePrepared = true;
    }
967256
public function partial(Dataset $dataset) : void
    {
        if (!$this->r or !$this->histograms or !$this->n) {
            $this->train($dataset);

            return;
        }

        DatasetIsCompatibleWithEstimator::check($dataset, $this);

        $this->n += $dataset->numRows();

        $z = Matrix::quick($dataset->samples())
            ->matmul($this->r)
            ->transpose();

        foreach ($z as $i => $values) {
            [$edges, $counts, $densities] = $this->histograms[$i];

            $interior = array_slice($edges, 1, $this->bins);

            foreach ($values as $value) {
                foreach ($interior as $k => $edge) {
                    if ($value < $edge) {
                        $counts[$k]++;

                        continue 2;
                    }
                }

                $counts[$this->bins]++;
            }

            foreach ($counts as $j => $count) {
                $densities[$j] = $count > 0
                    ? -log($count / $this->n)
                    : -LOG_EPSILON;
            }

            $this->histograms[$i] = [$edges, $counts, $densities];
        }
    }
374013
public function proba(Dataset $dataset) : array
    {
        if ($this->bare()) {
            throw new RuntimeException('The learner has not'
                . ' been trained.');
        }

        DatasetIsCompatibleWithEstimator::check($dataset, $this);

        $template = array_fill_keys($this->classes, 0.);

        $probabilities = [];

        foreach ($dataset as $sample) {
            $node = $this->search($sample);

            $probabilities[] = $node instanceof Outcome
                ? array_replace($template, $node->probabilities())
                : null;
        }

        return $probabilities;
    }
898529
public function train(Dataset $dataset) : void
    {
        if (!$dataset instanceof Labeled) {
            throw new InvalidArgumentException('This estimator requires a'
                . ' labeled training set.');
        }
        
        $k = (int) round($this->ratio * $dataset->numRows());

        $this->forest = [];

        Loop::run(function () use ($dataset, $k) {
            $pool = new DefaultPool($this->workers);

            $coroutines = [];

            for ($i = 0; $i < $this->estimators; $i++) {
                $estimator = clone $this->base;

                $subset = $dataset->randomSubsetWithReplacement($k);

                $task = new CallableTask(
                    [$this, '_train'],
                    [$estimator, $subset]
                );

                $coroutines[] = call(function () use ($pool, $task) {
                    return yield $pool->enqueue($task);
                });
            }

            $this->forest = yield all($coroutines);
            
            return yield $pool->shutdown();
        });

        $this->classes = $dataset->possibleOutcomes();
        $this->featureCount = $dataset->numColumns();
    }
674420
public function predict(Dataset $dataset) : array
    {
        if (!$this->model) {
            throw new RuntimeException('Estimator has not been trained.');
        }

        DatasetIsCompatibleWithEstimator::check($dataset, $this);

        return array_map([$this->model, 'predict'], $dataset->samples());
    }
418536
public function grow(Dataset $dataset) : void
    {
        $depth = 1;

        $this->root = Isolator::split($dataset);

        $stack = [[$this->root, $depth]];

        while ($stack) {
            [$current, $depth] = array_pop($stack) ?? [];

            [$left, $right] = $current->groups();

            $depth++;

            if ($depth >= $this->maxDepth) {
                $current->attachLeft(Cell::terminate($left, $depth));
                $current->attachRight(Cell::terminate($right, $depth));
    
                continue 1;
            }
    
            if ($left->numRows() > $this->maxLeafSize) {
                $node = Isolator::split($left);
    
                $current->attachLeft($node);
    
                $stack[] = [$node, $depth];
            } else {
                $current->attachLeft(Cell::terminate($left, $depth));
            }
    
            if ($right->numRows() > $this->maxLeafSize) {
                $node = Isolator::split($right);
    
                $current->attachRight($node);
    
                $stack[] = [$node, $depth];
            } else {
                $current->attachRight(Cell::terminate($right, $depth));
            }

            $current->cleanup();
        }
    }
1119999
public function partial(Dataset $dataset) : void
    {
        if (!$this->network) {
            $this->train($dataset);

            return;
        }

        if (!$dataset instanceof Labeled) {
            throw new InvalidArgumentException('This estimator requires a'
                . ' labeled training set.');
        }

        DatasetIsCompatibleWithEstimator::check($dataset, $this);

        if ($this->logger) {
            $this->logger->info('Learner init ' . Params::stringify([
                'batch_size' => $this->batchSize,
                'optimizer' => $this->optimizer,
                'alpha' => $this->alpha,
                'epochs' => $this->epochs,
                'min_change' => $this->minChange,
                'cost_fn' => $this->costFn,
            ]));
        }
        
        $n = $dataset->numRows();

        $randomize = $n > $this->batchSize ? true : false;

        $previous = INF;

        for ($epoch = 1; $epoch <= $this->epochs; $epoch++) {
            if ($randomize) {
                $dataset->randomize();
            }

            $batches = $dataset->batch($this->batchSize);

            $loss = 0.;

            foreach ($batches as $batch) {
                $loss += $this->network->roundtrip($batch);
            }

            $loss /= $n;

            $this->steps[] = $loss;

            if ($this->logger) {
                $this->logger->info("Epoch $epoch complete, loss=$loss");
            }

            if (is_nan($loss)) {
                break 1;
            }

            if (abs($previous - $loss) < $this->minChange) {
                break 1;
            }

            $previous = $loss;
        }

        if ($this->logger) {
            $this->logger->info('Training complete');
        }
    }
1344603
public static function split(Labeled $dataset) : self
    {
        $columns = $dataset->columns();

        $variances = array_map([Stats::class, 'variance'], $columns);

        $column = argmax($variances);

        $value = Stats::median($columns[$column]);

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

        $min = $max = [];

        foreach ($columns as $values) {
            $min[] = min($values);
            $max[] = max($values);
        }

        return new self($column, $value, $groups, $min, $max);
    }
1366403
public function partial(Dataset $dataset) : void
    {
        if (empty($this->weights) or empty($this->means) or empty($this->variances)) {
            $this->train($dataset);

            return;
        }

        if (!$dataset instanceof Labeled) {
            throw new InvalidArgumentException('This Estimator requires a'
                . ' Labeled training set.');
        }

        DatasetIsCompatibleWithEstimator::check($dataset, $this);

        foreach ($dataset->stratify() as $class => $stratum) {
            $means = $this->means[$class];
            $variances = $this->variances[$class];

            $oldWeight = $this->weights[$class];
            $oldMeans = $this->means[$class];
            $oldVariances = $this->variances[$class];

            $n = $stratum->numRows();

            foreach ($stratum->columns() as $column => $values) {
                [$mean, $variance] = Stats::meanVar($values);

                $means[$column] = (($n * $mean)
                    + ($oldWeight * $oldMeans[$column]))
                    / ($oldWeight + $n);

                $vHat = ($oldWeight
                    * $oldVariances[$column] + ($n * $variance)
                    + ($oldWeight / ($n * ($oldWeight + $n)))
                    * ($n * $oldMeans[$column] - $n * $mean) ** 2)
                    / ($oldWeight + $n);

                $variances[$column] = $vHat ?: EPSILON;
            }

            $this->means[$class] = $means;
            $this->variances[$class] = $variances;
            
            $this->weights[$class] += $n;
        }

        if ($this->fitPriors) {
            $total = array_sum($this->weights) ?: EPSILON;

            foreach ($this->weights as $class => $weight) {
                $this->priors[$class] = log($weight / $total);
            }
        }
    }
698003
public function fit(Dataset $dataset) : void
    {
        $this->intervals = [];

        $columns = $dataset->columnsByType(DataType::CONTINUOUS);

        foreach ($columns as $column => $values) {
            $min = min($values);
            $max = max($values);

            $edges = Vector::linspace($min, $max, $this->bins + 1)->asArray();

            array_shift($edges);

            $this->intervals[$column] = $edges;
        }
    }
833812
public function fit(Dataset $dataset) : void
    {
        if (!$dataset->homogeneous() or $dataset->columnType(0) !== DataType::CONTINUOUS) {
            throw new InvalidArgumentException('This transformer only works'
                . ' with continuous features.');
        }

        $columns = $dataset->numColumns();

        $p = count(static::DISTRIBUTION) - 1;

        $r = [];

        for ($i = 0; $i < $columns; $i++) {
            $row = [];

            for ($j = 0; $j < $this->dimensions; $j++) {
                $row[] = static::DISTRIBUTION[rand(0, $p)];
            }

            $r[] = $row;
        }

        $this->r = Matrix::quick($r);
    }