docs: def _predict_forest(model, X, joint_contribution=False):
      """
      For a given RandomForestRegressor, RandomForestClassifier,
      ExtraTreesRegressor, or ExtraTreesClassifier returns a triple of
      [prediction, bias and feature_contributions], such that prediction ≈ bias +
      feature_contributions.
      """
      biases = []
      contributions = []
      predictions = []
  
      
      if joint_contribution:
          
          for tree in model.estimators_:
              pred, bias, contribution = _predict_tree(tree, X, joint_contribution=joint_contribution)
  
              biases.append(bias)
              contributions.append(contribution)
              predictions.append(pred)
          
          
          total_contributions = []
          
          for i in range(len(X)):
              contr = {}
              for j, dct in enumerate(contributions):
                  for k in set(dct[i]).union(set(contr.keys())):
                      contr[k] = (contr.get(k, 0)*j + dct[i].get(k,0) ) / (j+1)
  
              total_contributions.append(contr)    
              
          for i, item in enumerate(contribution):
              total_contributions[i]
              sm = sum([v for v in contribution[i].values()])
                  
  
          
          return (np.mean(predictions, axis=0), np.mean(biases, axis=0),
              total_contributions)
      else:
          for tree in model.estimators_:
              pred, bias, contribution = _predict_tree(tree, X)
  
              biases.append(bias)
              contributions.append(contribution)
              predictions.append(pred)
          
          
          return (np.mean(predictions, axis=0), np.mean(biases, axis=0),
              np.mean(contributions, axis=0))