class_docstr: An approach that switches between two optimizers midway through.
  
  The two-stage greedy optimizer is a general purpose framework for combining 
  two optimizers by making the first :math:`n` selections out of :math:`k` 
  total selections using one optimizer, and then making the remainder using 
  the other. When the first optimizer is random selection and the second 
  approach is naive/lazy greedy, this becomes partial enumeration. By 
  default, the first algorithm is the naive greedy optimizer and the second 
  algorithm is the lazy greedy. This combination results in the same 
  selection as either optimizer individually but replaces the 
  computationally intensive first few steps for the priority queue, where 
  the algorithm may require scanning through almost the entire queue, with 
  the parallelizable naive greedy algorithm. While, in theory, the lazy 
  greedy algorithm will never perform more function calls than the naive 
  greedy algorithm, there are costs associated both with maintaining a 
  priority queue and with evaluating a single example instead of a batch 
  of examples.
  
  This optimizer, with the naive greedy optimizer first and the lazy greedy 
  optimizer second, is the default optimizer for apricot selectors.
  
  .. code::python
  
          from apricot import FeatureBasedSelection
  
          X = numpy.random.randint(10, size=(10000, 100))
  
          selector = FeatureBasedSelection(100, 'sqrt', optimizer='two-stage')
          selector.fit(X)
  
  Parameters
  ----------
  self.function : base.BaseSelection
          A submodular function that implements the `_calculate_gains` and
          `_select_next` methods. This is the function that will be
          optimized.
  
  self.n_first_selections : int
          The number of selections to perform using the naive greedy algorithm
          before populating the priority queue and using the lazy greedy
          algorithm.
  
  self.verbose : bool
          Whether to display a progress bar during the optimization process.
  
  
  Attributes
  ----------
  self.function : base.BaseSelection
          A submodular function that implements the `_calculate_gains` and
          `_select_next` methods. This is the function that will be
          optimized.
  
  self.verbose : bool
          Whether to display a progress bar during the optimization process.
class_docstr_tok: ["An","approach","that","switches","between","two","optimizers","midway","through",".","The","two-stage","greedy","optimizer","is","a","general","purpose","framework","for","combining","two","optimizers","by","making","the","first",":","math",":","`","n","`","selections","out","of",":","math",":","`","k","`","total","selections","using","one","optimizer",",","and","then","making","the","remainder","using","the","other",".","When","the","first","optimizer","is","random","selection","and","the","second","approach","is","naive\/lazy","greedy",",","this","becomes","partial","enumeration",".","By","default",",","the","first","algorithm","is","the","naive","greedy","optimizer","and","the","second","algorithm","is","the","lazy","greedy",".","This","combination","results","in","the","same","selection","as","either","optimizer","individually","but","replaces","the","computationally","intensive","first","few","steps","for","the","priority","queue",",","where","the","algorithm","may","require","scanning","through","almost","the","entire","queue",",","with","the","parallelizable","naive","greedy","algorithm",".","While",",","in","theory",",","the","lazy","greedy","algorithm","will","never","perform","more","function","calls","than","the","naive","greedy","algorithm",",","there","are","costs","associated","both","with","maintaining","a","priority","queue","and","with","evaluating","a","single","example","instead","of","a","batch","of","examples",".","This","optimizer",",","with","the","naive","greedy","optimizer","first","and","the","lazy","greedy","optimizer","second",",","is","the","default","optimizer","for","apricot","selectors",".","..","code",":",":python","from","apricot","import","FeatureBasedSelection","X","=","numpy.random.randint","(","10",",","size=","(","10000",",","100",")",")","selector","=","FeatureBasedSelection","(","100",",","'sqrt","'",",","optimizer='two-stage","'",")","selector.fit","(","X",")","Parameters","--","--","--","--","--","self.function",":","base.BaseSelection","A","submodular","function","that","implements","the","`","_calculate_gains","`","and","`","_select_next","`","methods",".","This","is","the","function","that","will","be","optimized",".","self.n_first_selections",":","int","The","number","of","selections","to","perform","using","the","naive","greedy","algorithm","before","populating","the","priority","queue","and","using","the","lazy","greedy","algorithm",".","self.verbose",":","bool","Whether","to","display","a","progress","bar","during","the","optimization","process",".","Attributes","--","--","--","--","--","self.function",":","base.BaseSelection","A","submodular","function","that","implements","the","`","_calculate_gains","`","and","`","_select_next","`","methods",".","This","is","the","function","that","will","be","optimized",".","self.verbose",":","bool","Whether","to","display","a","progress","bar","during","the","optimization","process","."]
code: def select(self, X, k, sample_cost=None):
      if isinstance(self.optimizer1, str):
          optimizer1 = OPTIMIZERS[self.optimizer1](
              function=self.function, verbose=self.verbose
          )
      elif not isinstance(self.optimizer1, BaseOptimizer):
          raise ValueError(
              "optimizer1 must be either a string or an "
              / "optimized object."
          )
      else:
          optimizer1 = self.optimizer1
  
      if isinstance(self.optimizer2, str):
          optimizer2 = OPTIMIZERS[self.optimizer2](
              function=self.function, verbose=self.verbose
          )
      elif not isinstance(self.optimizer2, BaseOptimizer):
          raise ValueError(
              "optimizer1 must be either a string or an "
              / "optimized object."
          )
      else:
          optimizer2 = self.optimizer2
  
      optimizer1.select(
          X, min(self.n_first_selections, k), sample_cost=sample_cost
      )
      if k > self.n_first_selections:
          m = k - self.n_first_selections
          optimizer2.select(X, m, sample_cost=sample_cost)
  
imports: import os
  import copy
  import numpy
  import scipy
  from tqdm import tqdm
  from .utils import PriorityQueue
  from .utils import check_random_state
  from .utils import _calculate_pairwise_distances
label_desc: Use image node_id 2 for calling the TwoStageGreedy obj's underlying member method code with example usage: obj.select(X, k, sample_cost) without return types