Skip to content

Commit 1f5fdb9

Browse files
committed
Merge branch 'feature/fix_qini_score' into dev
2 parents b965da5 + f656dcf commit 1f5fdb9

File tree

3 files changed

+46
-6
lines changed

3 files changed

+46
-6
lines changed

Readme.rst

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -238,6 +238,9 @@ Papers and materials
238238
9. Zhao, Yan & Fang, Xiao & Simchi-Levi, David. 2017.
239239
Uplift Modeling with Multiple Treatments and General Response Types. 10.1137/1.9781611974973.66.
240240

241+
10. Nicholas J Radcliffe. 2007
242+
Using control groups to target on predicted lift: Building and assessing uplift model. Direct Marketing Analytics Journal, (3):14–21, 2007.
243+
241244
===============
242245

243246
Tags

docs/index.rst

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -154,6 +154,9 @@ Papers and materials
154154
9. Zhao, Yan & Fang, Xiao & Simchi-Levi, David. 2017.
155155
Uplift Modeling with Multiple Treatments and General Response Types. 10.1137/1.9781611974973.66.
156156

157+
10. Nicholas J Radcliffe. 2007
158+
Using control groups to target on predicted lift: Building and assessing uplift model. Direct Marketing Analytics Journal, (3):14–21, 2007.
159+
157160
===============
158161

159162
Tags

sklift/metrics/metrics.py

Lines changed: 40 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@
77

88

99
def uplift_curve(y_true, uplift, treatment):
10-
"""Compute Uplift curve
10+
"""Compute Uplift curve.
1111
1212
This is a general function, given points on a curve. For computing the
1313
area under the Uplift Curve, see :func:`uplift_auc_score`.
@@ -153,20 +153,52 @@ def auuc(y_true, uplift, treatment):
153153
return uplift_auc_score(y_true, uplift, treatment)
154154

155155

156-
def qini_auc_score(y_true, uplift, treatment):
156+
def qini_auc_score(y_true, uplift, treatment, negative_effect=True):
157157
"""Compute Area Under the Qini Curve (aka Qini coefficient) from prediction scores.
158158
159+
For binary outcomes the ratio of the actual uplift gains curve above the diagonal to that of the optimum Qini Curve.
160+
159161
Args:
160162
y_true (1d array-like): Correct (true) target values.
161163
uplift (1d array-like): Predicted uplift, as returned by a model.
162164
treatment (1d array-like): Treatment labels.
165+
negative_effect (bool): If True, optimum Qini Curve contains the negative effects.
166+
Otherwise, optimum Qini Curve does not the negative effects.
167+
168+
.. versionadded:: 0.2.0
163169
164170
Returns:
165-
float: Area Under the Qini Curve.
171+
float: Qini coefficient.
172+
173+
References:
174+
Nicholas J Radcliffe. (2007). Using control groups to target on predicted lift:
175+
Building and assessing uplift model. Direct Marketing Analytics Journal, (3):14–21, 2007.
166176
"""
167-
# ToDO: Add normalization
168-
# ToDO: Add baseline
169-
return auc(*qini_curve(y_true, uplift, treatment))
177+
# ToDO: Add Continuous Outcomes
178+
check_consistent_length(y_true, uplift, treatment)
179+
180+
y_true, uplift, treatment = np.array(y_true), np.array(uplift), np.array(treatment)
181+
182+
if not isinstance(negative_effect, bool):
183+
raise TypeError(f'Negative_effects flag should be bool, got: {type(negative_effect)}')
184+
185+
ratio_random = (y_true[treatment == 1].sum() - len(y_true[treatment == 1]) *
186+
y_true[treatment == 0].sum() / len(y_true[treatment == 0])) / len(y_true)
187+
188+
x_baseline, y_baseline = np.array([0, len(y_true)]), np.array([0, ratio_random])
189+
auc_score_baseline = auc(x_baseline, y_baseline)
190+
191+
if negative_effect:
192+
x_perfect, y_perfect = qini_curve(
193+
y_true, y_true * treatment - y_true * (1 - treatment), treatment
194+
)
195+
else:
196+
x_perfect, y_perfect = np.array([0, ratio_random, len(y_true)]), np.array([0, ratio_random, ratio_random])
197+
198+
qini_auc_score_perfect = auc(x_perfect, y_perfect) - auc_score_baseline
199+
qini_auc_score_actual = auc(*qini_curve(y_true, uplift, treatment)) - auc_score_baseline
200+
201+
return qini_auc_score_actual / qini_auc_score_perfect
170202

171203

172204
# FIXME: remove in 0.2.0
@@ -213,6 +245,8 @@ def uplift_at_k(y_true, uplift, treatment, strategy, k=0.3):
213245
Separately calculates conversions in top k observations in each group (control and treatment)
214246
sorted by uplift predictions. Then the difference between these conversions is calculated
215247
248+
249+
216250
.. versionchanged:: 0.1.0
217251
218252
* Add supporting absolute values for ``k`` parameter

0 commit comments

Comments
 (0)