def METHOD_NAME(self,
          actual: np.array,
          predicted: np.array,
          sample_weight: typing.Optional[np.array] = None,
          labels: typing.Optional[np.array] = None,
          X: typing.Optional[dt.Frame] = None,
          **kwargs) -> float:
    logger = None
    #        if self._make_logger:
    # Example use of logger, with required import of:
    #  from h2oaicore.systemutils import make_experiment_logger, loggerinfo
    # Can use loggerwarning, loggererror, etc. for different levels
    #            if self.context and self.context.experiment_id:
    #                logger = make_experiment_logger(experiment_id=self.context.experiment_id, tmp_dir=self.context.tmp_dir,
    #                                                experiment_tmp_dir=self.context.experiment_tmp_dir)
    N = actual.shape[0]
    if sample_weight is None:
        sample_weight = np.ones(N)
    # label actual values as 1 or 0
    lb = LabelEncoder()
    labels = lb.fit_transform(labels)
    # create datatable with all data
    DT = dt.Frame(actual=lb.transform(actual),
                  predicted=np.minimum(1 - self.__class__._epsilon, np.maximum(self.__class__._epsilon, predicted)),
                  cost_fn=self.make_cost_values(self.__class__._fn_cost, X, N, 1.),
                  cost_tp=self.make_cost_values(self.__class__._tp_cost, X, N, 0.),
                  cost_tn=self.make_cost_values(self.__class__._tn_cost, X, N, 0.),
                  cost_fp=self.make_cost_values(self.__class__._fp_cost, X, N, 1.),
                  sample_weight=sample_weight)
    lloss = DT[:, f.sample_weight * (f.actual * (f.cost_fn * dt.log(f.predicted) +
                                                 f.cost_tp * dt.log(1 - f.predicted)) +
                                     (1 - f.actual) * (f.cost_fp * dt.log(1 - f.predicted) +
                                                       f.cost_tn * dt.log(f.predicted)))]
    lloss = lloss.sum()[0, 0] * -1.0 / np.sum(sample_weight)
    return lloss