'Performs the distributed estimation using the corresponding
DistributedModel
Parameters
data_generator : generator
A generator that produces a sequence of tuples where the first
element in the tuple corresponds to an endog array and the
element corresponds to an exog array.
fit_kwds : dict-like or None
Keywords needed for the model fitting.
parallel_method : str
type of distributed estimation to be used, currently
"sequential", "joblib" and "dask" are supported.
parallel_backend : None or joblib parallel_backend object
used to allow support for more complicated backends,
ex: dask.distributed
init_kwds_generator : generator or None
Additional keyword generator that produces model init_kwds
that may vary based on data partition.  The current usecase
is for WLS and GLS
Returns
join_method result.  For the default, _join_debiased, it returns a
p length array.'

def fit(self, data_generator, fit_kwds=None, parallel_method='sequential', parallel_backend=None, init_kwds_generator=None):

    if (fit_kwds is None):
        fit_kwds = {}
    if (parallel_method == 'sequential'):
        results_l = self.fit_sequential(data_generator, fit_kwds, init_kwds_generator)
    elif (parallel_method == 'joblib'):
        results_l = self.fit_joblib(data_generator, fit_kwds, parallel_backend, init_kwds_generator)
    else:
        raise ValueError(('parallel_method:    %s    is    currently    not    supported' % parallel_method))
    params = self.join_method(results_l, **self.join_kwds)
    res_mod = self.model_class([0], [0], **self.init_kwds)
    return self.results_class(res_mod, params, **self.results_kwds)
