Очень зависит от задач конкретной баннерокрутилки: это большая рекламная сеть, внутренний ротатор, и т.п.
Общий принцип такой:
# берем список баннеров, которые могут таргетироваться на этого пользователя
banners = get_banners(session)
# большую часть показов (например, 90%) нужно откручивать тем пользователям, для которых ожидаемая полезность максимальна
if random.randint(0,100) > 10:
# предсказываем потенциальную прибыль
banners = {x : predict(x) for x in banners}
# находим баннер с максимальной прогнозной прибылью
banner = max(banners, key=lambda k: banners[k])
show(banner)
# остальные показы случайные, чтобы модель могла обучаться
else:
show(random.choice(banners))
Самое интересное — по какой модели предсказывать прибыль. И тут все зависит от особенностей задачи. В самом простом варианте обычно считается eCPM, но рационально использовать комбинированные модели, использующие машинное обучение и всякие бизнес-ограничения вроде количества показов на пользователя.