code: def _get_loess_predictor(xs_train, ys_train, span, seed, max_n):
      import statsmodels.api as sm
      from scipy.interpolate import interp1d
  
      if max_n is not None:
          np.random.seed(seed)
          indices = np.random.choice(
              range(xs_train.size), size=max_n, replace=False
          )
          xs_train = xs_train[indices]
          ys_train = ys_train[indices]
      lowess = sm.nonparametric.lowess(ys_train, xs_train, frac=span)
      lowess_x = list(zip(*lowess))[0]
      lowess_y = list(zip(*lowess))[1]
      model = interp1d(lowess_x, lowess_y, bounds_error=False)
  
      return lambda xs: np.array([model(x) for x in xs])
  
file_path: lets-plot/python-package/lets_plot/bistro/residual.py
imports: from ..plot.core import PlotSpec, aes
  from ..plot.geom import geom_hline
  from ..plot.label import ylab
  from ..plot.theme_ import *
  from ._plot2d_common import _get_bin_params_2d, _get_geom2d_layer, _get_marginal_layers
label_desc: Use image node_id 4 for calling a global function with example usage: _get_loess_predictor(xs_train, ys_train, span, seed, max_n) and returns: function