Advertisement
alien_555

Qini Curve

Jun 23rd, 2025
94
0
29 days
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Python 4.01 KB | None | 0 0
  1. import pandas as pd
  2. import numpy as np
  3. from sklearn.metrics import auc
  4. import matplotlib.pyplot as plt
  5.  
  6. # генерация данных для 100 пользователей
  7. np.random.seed(42)
  8. n = 100
  9. treatment = np.array([1]*50 + [0]*50)
  10. outcome = np.concatenate([np.random.choice([1, 0], p=[0.2, 0.8], size=50),
  11.                           np.random.choice([1, 0], p=[0.1, 0.9], size=50)])
  12. uplift_prediction = np.random.rand(n)
  13.  
  14. # создание DataFrame
  15. data = {
  16.     'user_id': range(1, n+1),
  17.     'treatment': treatment,
  18.     'outcome': outcome,
  19.     'uplift_prediction': uplift_prediction
  20. }
  21.  
  22. df = pd.DataFrame(data)
  23.  
  24. # сортировка данных по uplift_prediction
  25. df = df.sort_values(by='uplift_prediction', ascending=False).reset_index(drop=True)
  26.  
  27. # инициализация переменных
  28. nt = 0  # количество пользователей в группе лечения
  29. nt_1 = 0  # количество успешных исходов в группе лечения
  30. nc = 0  # количество пользователей в контрольной группе
  31. nc_1 = 0  # количество успешных исходов в контрольной группе
  32. cgain = []  # кумулятивный прирост
  33. random_curve = []  # случайная кривая
  34. optimum_curve = []  # оптимальная кривая
  35.  
  36. # Расчет общего количества успешных исходов
  37. total_outcome = df['outcome'].sum()
  38. # Расчёт конверсий
  39. conversion_treatment_total = df[(df['treatment']==1)].shape[0] / df[(df['treatment']==1) & (df['outcome']==1)].shape[0]
  40. conversion_control_total = df[(df['treatment']==0)].shape[0] / df[(df['treatment']==0) & (df['outcome']==0)].shape[0]
  41.  
  42. # Расчет CGain, Random и Optimum
  43. for i, row in df.iterrows():
  44.     if row['treatment'] == 1:  # если пользователь в группе воздействия
  45.         nt += 1
  46.         if row['outcome'] == 1:
  47.             nt_1 += 1
  48.     else:  # если пользователь в контрольной группе
  49.         nc += 1
  50.         if row['outcome'] == 0:
  51.             nc_1 += 1
  52.  
  53.     # Корректный расчет CGain (кумулятивный прирост)
  54.     conversion_treatment = nt / df[(df['treatment']==1) & (df['outcome']==1)].shape[0]
  55.     conversion_control = nc / df[(df['treatment']==0) & (df['outcome']==0)].shape[0]
  56.     cgain.append(conversion_treatment - conversion_control)  # Разница между конверсией в treatment и control
  57.  
  58.     # Расчет случайной кривой
  59.     random_curve.append(total_outcome * (i + 1) / len(df))
  60.        
  61.     # Расчет оптимальной кривой
  62.     optimum_curve.append(min(total_outcome, (i + 1)))
  63.    
  64. # Нормализация кривых
  65. cgain = [val / (conversion_treatment_total - conversion_control_total) for val in cgain] # Нормализуем CGain
  66. max_incremental_purchases = total_outcome if total_outcome > 0 else 1  # Защита от деления на ноль
  67. random_curve = [val / max_incremental_purchases for val in random_curve]
  68. optimum_curve = [val / max_incremental_purchases for val in optimum_curve]
  69.  
  70. # расчёт площади под кривыми
  71. qini_auc = auc(range(1, len(cgain) + 1), cgain)
  72. random_auc = auc(range(1, len(random) + 1), random)
  73.  
  74. # расчёт Qini Score
  75. qini_score = qini_auc - random_auc
  76.  
  77. # вывод Qini Score
  78. print(f'Qini Score: {qini_score}')
  79.  
  80. # построение графиков
  81. plt.figure(figsize=(10, 6))
  82. plt.plot(range(1, len(cgain) + 1), cgain, label='Model', color='blue')
  83. plt.plot(range(1, len(random_curve) + 1), random_curve, label='Random', color='red', linestyle='--')
  84. plt.plot(range(1, len(optimum_curve) + 1), optimum_curve, label='Optimum', color='green', linestyle='--')
  85. plt.xlabel('Number of users targeted')
  86. plt.ylabel('Number of Incremental Purchases')
  87. plt.title('Gains Chart for Uplift (Qini Curve) with Random')
  88. plt.legend()
  89. plt.grid(True)
  90. plt.show()
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement