class_docstr: Recursive pipelines are Spark NLP specific pipelines that allow a Spark
  ML Pipeline to know about itself on every Pipeline Stage task.
  
  This allows annotators to utilize this same pipeline against external
  resources to process them in the same way the user decides.
  
  Only some of the annotators take advantage of this. RecursivePipeline
  behaves exactly the same as normal Spark ML pipelines, so they can be used
  with the same intention.
  
  Examples
  --------
  >>> from sparknlp.annotator import *
  >>> from sparknlp.base import *
  >>> recursivePipeline = RecursivePipeline(stages=[
  ...     documentAssembler,
  ...     sentenceDetector,
  ...     tokenizer,
  ...     lemmatizer,
  ...     finisher
  ... ])
class_docstr_tok: ["Recursive","pipelines","are","Spark","NLP","specific","pipelines","that","allow","a","Spark","ML","Pipeline","to","know","about","itself","on","every","Pipeline","Stage","task",".","This","allows","annotators","to","utilize","this","same","pipeline","against","external","resources","to","process","them","in","the","same","way","the","user","decides",".","Only","some","of","the","annotators","take","advantage","of","this",".","RecursivePipeline","behaves","exactly","the","same","as","normal","Spark","ML","pipelines",",","so","they","can","be","used","with","the","same","intention",".","Examples","--","--","--","--",">",">",">","from","sparknlp.annotator","import","*",">",">",">","from","sparknlp.base","import","*",">",">",">","recursivePipeline","=","RecursivePipeline","(","stages=","[","...","documentAssembler",",","...","sentenceDetector",",","...","tokenizer",",","...","lemmatizer",",","...","finisher","...","]",")"]
code: def _fit(self, dataset):
      stages = self.getStages()
      for stage in stages:
          if not (
              isinstance(stage, Estimator)
              or isinstance(stage, Transformer)
          ):
              raise TypeError(
                  "Cannot recognize a pipeline stage of type %s."
                  % type(stage)
              )
      indexOfLastEstimator = -1
      for i, stage in enumerate(stages):
          if isinstance(stage, Estimator):
              indexOfLastEstimator = i
      transformers = []
      for i, stage in enumerate(stages):
          if i <= indexOfLastEstimator:
              if isinstance(stage, Transformer):
                  transformers.append(stage)
                  dataset = stage.transform(dataset)
              elif isinstance(stage, RecursiveEstimator):
                  model = stage.fit(
                      dataset, pipeline=PipelineModel(transformers)
                  )
                  transformers.append(model)
                  if i < indexOfLastEstimator:
                      dataset = model.transform(dataset)
              else:
                  model = stage.fit(dataset)
                  transformers.append(model)
                  if i < indexOfLastEstimator:
                      dataset = model.transform(dataset)
          else:
              transformers.append(stage)
      return PipelineModel(transformers)
  
file_path: spark-nlp/python/sparknlp/base/recursive_pipeline.py
imports: from pyspark import keyword_only
  from pyspark.ml import PipelineModel, Estimator, Pipeline, Transformer
  from pyspark.ml.wrapper import JavaEstimator
  from sparknlp.common import AnnotatorProperties
  from sparknlp.internal import RecursiveEstimator
  from sparknlp.base import HasRecursiveTransform
label_desc: Use image node_id 2 for calling the RecursivePipeline obj's underlying member method code with example usage: obj._fit(dataset) and returns: PipelineModel