code: def set_params(self, **params):
          
          if not params:
              # Simple optimisation to gain speed (inspect is slow)
              return self
          valid_params = self.get_params(deep=True)
          for key, value in six.iteritems(params):
              split = key.split('__', 1)
              if len(split) > 1:
                  # nested objects case
                  name, sub_name = split
                  if not name in valid_params:
                      raise ValueError('Invalid parameter %s for estimator %s' %
                                       (name, self))
                  sub_object = valid_params[name]
                  sub_object.set_params(**{sub_name: value})
              else:
                  # simple objects case
                  if not key in valid_params:
                      raise ValueError('Invalid parameter %s ' 'for estimator %s'
                                       % (key, self.__class__.__name__))
                  setattr(self, key, value)
          return self
docs: Set the parameters of this estimator.
  
          The method works on simple estimators as well as on nested objects
          (such as pipelines). The former have parameters of the form
          ``<component>__<parameter>`` so that it's possible to update each
          component of a nested object.
  
          Returns
          -------
          self