class_docstr: Base class that is inherited by the majority of classes in River.
  
  This base class allows us to handle the following tasks in a uniform manner:
  
  - Getting and setting parameters
  - Displaying information
  - Mutating/cloning
docstr: Return a fresh estimator with the same parameters.
  
  The clone has the same parameters but has not been updated with any data.
  
  This works by looking at the parameters from the class signature. Each parameter is either
  
  - recursively cloned if its a class.
  - deep-copied via `copy.deepcopy` if not.
  
  If the calling object is stochastic (i.e. it accepts a seed parameter) and has not been
  seeded, then the clone will not be idempotent. Indeed, this method's purpose if simply to
  return a new instance with the same input parameters.
  
  Parameters
  ----------
  new_params
  include_attributes
      Whether attributes that are not present in the class' signature should also be cloned
      or not.
  
  Examples
  --------
  
  >>> from river import linear_model
  >>> from river import optim
  
  >>> model = linear_model.LinearRegression(
  ...     optimizer=optim.SGD(lr=0.042),
  ... )
  
  >>> new_params = {
  ...     'optimizer': optim.SGD(.001)
  ... }
  
  >>> model.clone(new_params)
  LinearRegression (
    optimizer=SGD (
      lr=Constant (
        learning_rate=0.001
      )
    )
    loss=Squared ()
    l2=0.
    l1=0.
    intercept_init=0.
    intercept_lr=Constant (
      learning_rate=0.01
    )
    clip_gradient=1e+12
    initializer=Zeros ()
  )
  
  The algorithm is recursively called down `Pipeline`s and `TransformerUnion`s.
  
  >>> from river import compose
  >>> from river import preprocessing
  
  >>> model = compose.Pipeline(
  ...     preprocessing.StandardScaler(),
  ...     linear_model.LinearRegression(
  ...         optimizer=optim.SGD(0.042),
  ...     )
  ... )
  
  >>> new_params = {
  ...     'LinearRegression': {
  ...         'optimizer': optim.SGD(0.03)
  ...     }
  ... }
  
  >>> model.clone(new_params)
  Pipeline (
    StandardScaler (
      with_std=True
    ),
    LinearRegression (
      optimizer=SGD (
        lr=Constant (
          learning_rate=0.03
        )
      )
      loss=Squared ()
      l2=0.
      l1=0.
      intercept_init=0.
      intercept_lr=Constant (
        learning_rate=0.01
      )
      clip_gradient=1e+12
      initializer=Zeros ()
    )
  )
docstr_tok: ["Return","a","fresh","estimator","with","the","same","parameters",".","The","clone","has","the","same","parameters","but","has","not","been","updated","with","any","data",".","This","works","by","looking","at","the","parameters","from","the","class","signature",".","Each","parameter","is","either","-","recursively","cloned","if","its","a","class",".","-","deep-copied","via","`","copy.deepcopy","`","if","not",".","If","the","calling","object","is","stochastic","(","i.e",".","it","accepts","a","seed","parameter",")","and","has","not","been","seeded",",","then","the","clone","will","not","be","idempotent",".","Indeed",",","this","method","'s","purpose","if","simply","to","return","a","new","instance","with","the","same","input","parameters",".","Parameters","--","--","--","--","--","new_params","include_attributes","Whether","attributes","that","are","not","present","in","the","class","'","signature","should","also","be","cloned","or","not",".","Examples","--","--","--","--",">",">",">","from","river","import","linear_model",">",">",">","from","river","import","optim",">",">",">","model","=","linear_model.LinearRegression","(","...","optimizer=optim.SGD","(","lr=0.042",")",",","...",")",">",">",">","new_params","=","{","...","'optimizer","'",":","optim.SGD","(",".001",")","...","}",">",">",">","model.clone","(","new_params",")","LinearRegression","(","optimizer=SGD","(","lr=Constant","(","learning_rate=0.001",")",")","loss=Squared","(",")","l2=0",".","l1=0",".","intercept_init=0",".","intercept_lr=Constant","(","learning_rate=0.01",")","clip_gradient=1e+12","initializer=Zeros","(",")",")","The","algorithm","is","recursively","called","down","`","Pipeline","`","s","and","`","TransformerUnion","`","s",".",">",">",">","from","river","import","compose",">",">",">","from","river","import","preprocessing",">",">",">","model","=","compose.Pipeline","(","...","preprocessing.StandardScaler","(",")",",","...","linear_model.LinearRegression","(","...","optimizer=optim.SGD","(","0.042",")",",","...",")","...",")",">",">",">","new_params","=","{","...","'LinearRegression","'",":","{","...","'optimizer","'",":","optim.SGD","(","0.03",")","...","}","...","}",">",">",">","model.clone","(","new_params",")","Pipeline","(","StandardScaler","(","with_std=True",")",",","LinearRegression","(","optimizer=SGD","(","lr=Constant","(","learning_rate=0.03",")",")","loss=Squared","(",")","l2=0",".","l1=0",".","intercept_init=0",".","intercept_lr=Constant","(","learning_rate=0.01",")","clip_gradient=1e+12","initializer=Zeros","(",")",")",")"]
code: def clone(
      self, new_params: dict | None = None, include_attributes=False
  ):
      """Return a fresh estimator with the same parameters.
  
      The clone has the same parameters but has not been updated with any data.
  
      This works by looking at the parameters from the class signature. Each parameter is either
  
      - recursively cloned if its a class.
      - deep-copied via `copy.deepcopy` if not.
  
      If the calling object is stochastic (i.e. it accepts a seed parameter) and has not been
      seeded, then the clone will not be idempotent. Indeed, this method's purpose if simply to
      return a new instance with the same input parameters.
  
      Parameters
      ----------
      new_params
      include_attributes
          Whether attributes that are not present in the class' signature should also be cloned
          or not.
  
      Examples
      --------
  
      >>> from river import linear_model
      >>> from river import optim
  
      >>> model = linear_model.LinearRegression(
      ...     optimizer=optim.SGD(lr=0.042),
      ... )
  
      >>> new_params = {
      ...     'optimizer': optim.SGD(.001)
      ... }
  
      >>> model.clone(new_params)
      LinearRegression (
        optimizer=SGD (
          lr=Constant (
            learning_rate=0.001
          )
        )
        loss=Squared ()
        l2=0.
        l1=0.
        intercept_init=0.
        intercept_lr=Constant (
          learning_rate=0.01
        )
        clip_gradient=1e+12
        initializer=Zeros ()
      )
  
      The algorithm is recursively called down `Pipeline`s and `TransformerUnion`s.
  
      >>> from river import compose
      >>> from river import preprocessing
  
      >>> model = compose.Pipeline(
      ...     preprocessing.StandardScaler(),
      ...     linear_model.LinearRegression(
      ...         optimizer=optim.SGD(0.042),
      ...     )
      ... )
  
      >>> new_params = {
      ...     'LinearRegression': {
      ...         'optimizer': optim.SGD(0.03)
      ...     }
      ... }
  
      >>> model.clone(new_params)
      Pipeline (
        StandardScaler (
          with_std=True
        ),
        LinearRegression (
          optimizer=SGD (
            lr=Constant (
              learning_rate=0.03
            )
          )
          loss=Squared ()
          l2=0.
          l1=0.
          intercept_init=0.
          intercept_lr=Constant (
            learning_rate=0.01
          )
          clip_gradient=1e+12
          initializer=Zeros ()
        )
      )
  
      """
  
      def is_class_param(param):
          # See expand_param_grid to understand why this is necessary
          return (
              isinstance(param, tuple)
              and inspect.isclass(param[0])
              and isinstance(param[1], dict)
          )
  
      # Override the default parameters with the new ones
      params = self._get_params()
      params.update(new_params or {})
  
      # Clone by recursing
      clone = self.__class__(
          *(params.get("_POSITIONAL_ARGS", [])),
          **{
              name: (
                  getattr(self, name).clone(param[1])
                  if is_class_param(param)
                  else copy.deepcopy(param)
              )
              for name, param in params.items()
              if name != "_POSITIONAL_ARGS"
          },
      )
  
      if not include_attributes:
          return clone
  
      for attr, value in self.__dict__.items():
          if attr not in params:
              setattr(clone, attr, copy.deepcopy(value))
      return clone
  
imports: from __future__ import annotations
  import collections
  import contextlib
  import copy
  import inspect
  import itertools
  import logging
  import sys
  import types
  import typing
label_desc: Use image node_id 5 for calling the Base obj's underlying member method code with example usage: obj.clone(new_params, include_attributes) and returns: clone, unknown, clone