class_docstr: A multi-output model that arranges classifiers into a chain.
  
  This will create one model per output. The prediction of the first output will be used as a
  feature in the second model. The prediction for the second output will be used as a feature
  for the third model, etc. This "chain model" is therefore capable of capturing dependencies
  between outputs.
  
  Parameters
  ----------
  model
      A classifier model used for each label.
  order
      A list with the targets order in which to construct the chain. If `None` then the order
      will be inferred from the order of the keys in the target.
  
  Examples
  --------
  
  >>> from river import feature_selection
  >>> from river import linear_model
  >>> from river import metrics
  >>> from river import multioutput
  >>> from river import preprocessing
  >>> from river import stream
  >>> from sklearn import datasets
  
  >>> dataset = stream.iter_sklearn_dataset(
  ...     dataset=datasets.fetch_openml('yeast', version=4, parser='auto', as_frame=False),
  ...     shuffle=True,
  ...     seed=42
  ... )
  
  >>> model = feature_selection.VarianceThreshold(threshold=0.01)
  >>> model |= preprocessing.StandardScaler()
  >>> model |= multioutput.ClassifierChain(
  ...     model=linear_model.LogisticRegression(),
  ...     order=list(range(14))
  ... )
  
  >>> metric = metrics.multioutput.MicroAverage(metrics.Jaccard())
  
  >>> for x, y in dataset:
  ...     # Convert y values to booleans
  ...     y = {i: yi == 'TRUE' for i, yi in y.items()}
  ...     y_pred = model.predict_one(x)
  ...     metric.update(y, y_pred)
  ...     model.learn_one(x, y)
  
  >>> metric
  MicroAverage(Jaccard): 41.81%
  
  References
  ----------
  [^1]: [Multi-Output Chain Models and their Application in Data Streams](https://jmread.github.io/talks/2019_03_08-Imperial_Stats_Seminar.pdf)
code: def learn_one(self, x, y, **kwargs):
      x = copy.copy(x)
      n_seen = 0
  
      for o in self.order:
          clf = self[o]
  
          # Make predictions before the model is updated to avoid leakage
          y_pred = clf.predict_proba_one(x, **kwargs)
  
          # We handle the case where an output has been seen in the past but is missing now
          try:
              y_o = y[o]
              n_seen += 1
              clf.learn_one(x, y_o, **kwargs)
          except KeyError:
              pass
  
          # The predictions are stored as features for the next label
          if clf._multiclass:
              for label, proba in y_pred.items():
                  x[f"{o}_{label}"] = proba
          else:
              x[o] = y_pred[True]
  
      # Now we check if there are any new outputs
      n_unseen = len(y) - n_seen
      if n_unseen:
          for o in y:
              if o not in self.order:
                  self.order.append(o)
  
imports: from __future__ import annotations
  import collections
  import copy
  import functools
  import random
  from river import base, linear_model
  from river.utils.math import minkowski_distance, prod
label_desc: Use image node_id 4 for calling the ClassifierChain obj's underlying member method code with example usage: obj.learn_one(x, y) without return types