code: def normalize_estimator(est):
      """Normalize an estimator.
  
      Note: Since scikit-learn requires duck-typing, but not sub-typing from
      ``BaseEstimator``, we sometimes need to call this function directly.
      """
      base = [type(est).__name__, normalize_token(est.get_params())]
      # fitted attributes: https://github.com/dask/dask-ml/issues/658
      attrs = [
          x
          for x in dir(est)
          if x.endswith("_") and not x.startswith("_")
      ]
      exclude = {
          "cv_results_",
          "model_history_",
          "history_",
          "refit_time_",
      }
  
      with warnings.catch_warnings():
          warnings.simplefilter("ignore", FutureWarning)
          for attr in attrs:
              if attr in exclude:
                  continue
              try:
                  val = getattr(est, attr)
              except (
                  sklearn.exceptions.NotFittedError,
                  AttributeError,
              ):
                  continue
              base.append(val)
      return tuple(base)
  
file_path: dask-ml/dask_ml/model_selection/_normalize.py
imports: from __future__ import absolute_import, division, print_function
  import warnings
  import numpy
  import sklearn.exceptions
  from dask.base import normalize_token
  from sklearn.base import BaseEstimator
  from sklearn.model_selection._split import BaseShuffleSplit, LeaveOneGroupOut, LeaveOneOut, LeavePGroupsOut, LeavePOut, PredefinedSplit, _BaseKFold, _CVIterableWrapper
label_desc: Use image node_id 1 for calling a global function with example usage: normalize_estimator(est) and returns: tuple