code: def _cv_estimate(
      model: RegressorMixin,
      train_data: pd.DataFrame,
      features: List[str],
      y: str,
      n_splits: int,
  ) -> Tuple[pd.Series, List[RegressorMixin]]:
      cv = KFold(n_splits=n_splits)
      models = []
      cv_pred = pd.Series(np.nan, index=train_data.index)
  
      for train, test in cv.split(train_data):
          m = clone(model, safe=False).fit(
              train_data[features].iloc[train],
              train_data[y].iloc[train],
          )
          cv_pred.iloc[test] = m.predict(
              train_data[features].iloc[test]
          )
          models += [m]
  
      return cv_pred, models
  
file_path: fklearn/src/fklearn/causal/cate_learning/double_machine_learning.py
imports: from typing import List, Tuple
  import numpy
  import pandas
  from sklearn import __version__
  from sklearn.base import RegressorMixin
  from sklearn.model_selection import KFold
  from sklearn.ensemble import GradientBoostingRegressor
  from sklearn.base import clone
  from toolz import curry
  from typing import Union
  from fklearn.common_docstrings import learner_pred_fn_docstring, learner_return_docstring
  from fklearn.training.utils import log_learner_time, expand_features_encoded
  from fklearn.types import LearnerReturnType
label_desc: Use image node_id 1 for calling a global function with example usage: _cv_estimate(model, train_data, features, y, n_splits) and returns: cv_pred,  models