1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61
| def uplift_curve(y_true, uplift, treatment): """Compute Uplift curve.
For computing the area under the Uplift Curve, see :func:`.uplift_auc_score`.
Args: y_true (1d array-like): Correct (true) binary target values. uplift (1d array-like): Predicted uplift, as returned by a model. treatment (1d array-like): Treatment labels.
Returns: array (shape = [>2]), array (shape = [>2]): Points on a curve.
See also: :func:`.uplift_auc_score`: Compute normalized Area Under the Uplift curve from prediction scores.
:func:`.perfect_uplift_curve`: Compute the perfect Uplift curve.
:func:`.plot_uplift_curve`: Plot Uplift curves from predictions.
:func:`.qini_curve`: Compute Qini curve.
References: Devriendt, F., Guns, T., & Verbeke, W. (2020). Learning to rank for uplift modeling. ArXiv, abs/2002.05897. """
check_consistent_length(y_true, uplift, treatment) check_is_binary(treatment) check_is_binary(y_true)
y_true, uplift, treatment = np.array(y_true), np.array(uplift), np.array(treatment)
desc_score_indices = np.argsort(uplift, kind="mergesort")[::-1] y_true, uplift, treatment = y_true[desc_score_indices], uplift[desc_score_indices], treatment[desc_score_indices]
y_true_ctrl, y_true_trmnt = y_true.copy(), y_true.copy()
y_true_ctrl[treatment == 1] = 0 y_true_trmnt[treatment == 0] = 0
distinct_value_indices = np.where(np.diff(uplift))[0] threshold_indices = np.r_[distinct_value_indices, uplift.size - 1]
num_trmnt = stable_cumsum(treatment)[threshold_indices] y_trmnt = stable_cumsum(y_true_trmnt)[threshold_indices]
num_all = threshold_indices + 1
num_ctrl = num_all - num_trmnt y_ctrl = stable_cumsum(y_true_ctrl)[threshold_indices]
curve_values = (np.divide(y_trmnt, num_trmnt, out=np.zeros_like(y_trmnt), where=num_trmnt != 0) - np.divide(y_ctrl, num_ctrl, out=np.zeros_like(y_ctrl), where=num_ctrl != 0)) * num_all
if num_all.size == 0 or curve_values[0] != 0 or num_all[0] != 0: num_all = np.r_[0, num_all] curve_values = np.r_[0, curve_values]
return num_all, curve_values
|