protected function runGradientDescent(array $samples, array $targets, \Closure $gradientFunc, bool $isBatch = false)
    {
        $class = $isBatch ? GD::class : StochasticGD::class;

        if (empty($this->optimizer)) {
            $this->optimizer = (new $class($this->featureCount))
                ->setLearningRate($this->learningRate)
                ->setMaxIterations($this->maxIterations)
                ->setChangeThreshold(1e-6)
                ->setEarlyStop($this->enableEarlyStop);
        }

        $this->weights = $this->optimizer->runOptimization($samples, $targets, $gradientFunc);
        $this->costValues = $this->optimizer->getCostValues();
    }