Коэффициенты для экстраполяции прогнозов компонент CLTV на 5 лет

Эта статья описывает, как из прогнозов ряда ML-моделей получить ценность клиента с горизонтом в 5 лет. Напомним, что показатель CLTV представляет из себя композицию прогнозов ее компонент (подробнее в статье). В нашей реализации максимальный период прогнозирования моделей — 24 месяца. Важно отметить, что чем выше горизонт прогнозирования, тем менее точный прогноз способна сделать модель. А показатель CLTV интересен бизнесу на более длинном горизонте, в нашем случае — пять лет. Как же из прогнозов на два года получить прогноз на пять лет? Ответ прост: экстраполировать прогнозы.

Основная идея продления (экстраполяции) прогнозов — это разбиение пользователей на несколько групп, а в каждой группе единообразно продлить ряд прогноза. 

Далее мы обсудим:

  • подходы к экстраполяции ряда, их достоинства и проблемы

  • как выбирать группы и подготовить данные для экстраполяции

  • достоинства выбранного подхода к продлению прогнозов на 5 лет, трудности и пути их решения.

1. Подходы к экстраполяции

Итак, давайте разберемся, что же нам нужно экстраполировать и как это можно сделать. Нам доступны помесячные прогнозы каждой из компонент CLTV на 24 месяца. Конечная цель — вывести некоторые коэффициенты, при помощи которых мы, имея прогноз на 24 месяцев, можем получить прогноз на 25, 26, 27, … 60 месяц. Для этого необходимо экстраполировать или продлить ряд прогнозов.

Для построения коэффициентов нам доступны исторические и прогнозные данные.

На наш взгляд, расчет коэффициентов на исторических данных (факте) имеет много недостатков, поскольку на их изменение влияет множество внешних факторов (изменение стоимости тарифных планов, кризисы, действия конкурентов), влияние которых мы хотим избежать и изучать отдельно в рамках экспериментов и тестов.  Кроме того, для 5-ти летних коэффициентов экстраполяции пришлось бы использовать очень старые исторические данные, что привело бы к неактуальным значениям коэффициентов. Например, поведение абонентов (в частности, выживаемость) в последний год отличается от их поведения 3 года назад. По этой же причине ML модели не предсказывают выручку и затраты на 5-ти летнем горизонте. К достоинствам этого подхода можно отнести доступность информации о фактических колебаниях сервисной маржи на длинных горизонтах. В результате применения такого подхода, если база с каждым годом улучшается, мы получим заниженные оценки коэффициентов. Исторические данные нами использовались только для валидации.

По причинам описанным выше для построения коэффициентов были использованы прогнозные значения. Для экстраполяции мы строили регрессии, имея более-менее монотонно убывающие/возрастающие ряды прогнозов. Однако не всегда можно увидеть такую зависимость в ряде данных,   в таком случае можно посмотреть на ряд прогнозов, посчитанных с накопительным итогом и так прийти к монотонности. 

Пример: есть ряд наблюдений за 2 года для базы пользователей, активных в декабре 2021 года (зафиксировали группу пользователей). Наблюдение = сумма выручки, которые мы спрогнозировали на 1, 2, 3 … 24 месяцев вперед. Описанный ряд изобразим синей линией, на графике, где ось абсцисс — месяц прогноза, ось ординат — выручка. Видим, что синяя линия поначалу убывает, а потом колеблется вокруг нуля. Оранжевым изображен ряд, посчитанный накопительным итогом — в нем видна явная логарифмическия зависимость между накопленным прогнозом выручки и месяцем прогноза.

_scroll_external/attachments/image2023-8-25_18-55-53-a02ef4e6dcadff743789675522ca0919c39918b4cf212c152bf1589666e3e16f.pngДанные для графика

Факт маржи

Накопленный факт

Прогноз

период

2020–01–01

6666

6666

7000

1

2020–02–01

4199,3599479678

10865,3599479678

10612,3599479678

2

2020–03–01

2683,0951086681

13548,4550566359

12725,4550566359

3

2020–04–01

1245,2648392996

14793,7198959355

14224,7198959355

4

2020–05–01

1263,9201560967

16057,6400520322

15387,6400520322

5

2020–06–01

949,1749525715

17006,8150046037

16337,8150046037

6

2020–07–01

658,3614755674

17665,1764801711

17141,1764801711

7

2020–08–01

423,9033637322

18089,0798439033

17837,0798439033

8

2020–09–01

781,8302693686

18870,9101132719

18450,9101132719

9

2020–10–01

15,0898867281

18886

19000

10

2020–11–01

1090,7122218988

19976,7122218988

19496,7122218988

11

2020–12–01

619,4627306726

20596,1749525714

19950,1749525714

12

2021–01–01

784,1452751107

21380,3202276821

20367,3202276821

13

2021–02–01

547,2162004568

21927,5364281389

20753,5364281389

14

2021–03–01

221,5586805293

22149,0951086682

21113,0951086682

15

2021–04–01

194,3446832028

22343,439791871

21449,439791871

16

2021–05–01

-22,0527353318

22321,3870565392

21765,3870565392

17

2021–06–01

582,8830047005

22904,2700612397

22063,2700612397

18

2021–07–01

-275,2268498057

22629,043211434

22345,043211434

19

2021–08–01

131,3167365338

22760,3599479678

22612,3599479678

20

2021–09–01

-318,7284111608

22441,631536807

22866,631536807

21

2021–10–01

426,4406330595

22868,0721698665

23109,0721698665

22

2021–11–01

21,6618623446

22889,7340322111

23340,7340322111

23

2021–12–01

389,8008683282

23279,5349005393

23562,5349005393

24

2022–01–01

-77,2547964748

23202,2801040645

23775,2801040645

25

2022–02–01

605,4000715853

23807,6801756498

23979,6801756498

26

2022–03–01

517,6849942581

24325,3651699079

24176,3651699079

27

2022–04–01

513,5312061987

24838,8963761066

24365,8963761066

28

2022–05–01

82,8795986809

24921,7759747875

24548,7759747875

29

2022–06–01

572,6790818484

25494,4550566359

24725,4550566359

30

2022–07–01

657,8852693753

26152,3403260112

24896,3403260112

31

2022–08–01

-7,5405861723

26144,7997398389

25061,7997398389

32

2022–09–01

-77,6324613042

26067,1672785347

25222,1672785347

33

2022–10–01

92,5797259724

26159,7470045071

25377,7470045071

34

2022–11–01

693,0695276963

26852,8165322034

25528,8165322034

35

2022–12–01

-74,1865229959

26778,6300092075

25675,6300092075

36

2023–01–01

579,7906795964

27358,4206888039

25818,4206888039

37

2023–02–01

735,9824705978

28094,4031594017

25957,4031594017

38

2023–03–01

-29,6278750837

28064,775284318

26092,775284318

39

2023–04–01

-180,0553883825

27884,7198959355

26224,7198959355

40

2023–05–01

-339,3136152986

27545,4062806369

26353,4062806369

41

2023–06–01

154,5852041379

27699,9914847748

26478,9914847748

42

2023–07–01

621,6299821803

28321,6214669551

26601,6214669551

43

2023–08–01

497,8106508792

28819,4321178343

26721,4321178343

44

2023–09–01

460,1180474698

29279,5501653041

26838,5501653041

45

2023–10–01

93,5438148747

29373,0939801788

26953,0939801788

46

2023–11–01

361,0803150498

29734,1742952286

27065,1742952286

47

2023–12–01

-450,2794467215

29283,8948485071

27174,8948485071

48

2. Подготовка данных

Если посмотреть на ряды прогнозов одной и той же метрики для разных абонентов, мы увидели, что для одних абонентов эти ряды растут сильнее, для других — слабее, для третьих — убывают. Тогда если мы экстраполируем все ряды одинаковыми коэффициентами, получим на одних абонентах завышенные показатели, на других — заниженные, но в среднем на всех — хорошие. При этом, если мы будем строить отдельно коэффициенты для каждого абонента, то не сможем гарантировать такую правильную форму кривой ряда, какую мы увидели на совокупности абонентов. Середина между двумя крайностями — делить базу на крупные сегменты. Мы делим абонентскую базу на сегменты, поведение абонентов (выживаемость, выручка, затраты) в которых существенно различаются между собой, но имеют схожую динамику изменений внутри сегмента. При таком подходе при увеличении того или иного сегмента общий показатель лучше подстраивается под изменения. Сегменты могут быть выбраны экспертно или на основании кластерного анализа.

В билайн для определения сегментов использовались комбинации:

  1. стаж клиента в компании (lifetime). У себя мы выделяем 0–3 месяцев, 4–12 месяцев, 13+ месяцев

  2. соцдем-характеристики клиента 

  3. географическая принадлежность клиента

  4. активность клиента за последние год/полгода/месяц и прочее

Обозначим каждую группу характеристик номером как в списке. Пусть признак 1 принимает К1 = 5 значений, фича 2  К2 = 6, К3 = 8. В итоге получается К1*K2*K3 = 5×6*8×10 = 240 сегментов. Пример такого сегмента — абоненты с lifetime от года из северных регионов и активные на конец периода.

Далее возникает вопрос, за какой период брать выборку для расчета коэффициентов. Мы пробовали 2 подхода:  10% сэмпл базы за несколько лет и всю базу за последние полгода. Победил 2 вариант, так как сокращение периода сбора предсказаний позволяет уловить актуальное поведение абонентов. 

Итак, мы сформировали некоторую выборку клиентов за последние 6 месяцев, подтянули к ним их характеристики, позволяющие понять, к какому сегменту относится каждый абонент. Далее подтягиваем к этой таблице доступные нам на данный момент помесячные прогнозы некоторой компоненты CLTV. В случае компоненты SM Mobile, получаем таблицу следующего вида:

ID клиента

Отчетная дата

Х-ка 1

Х-ка 2

Сегмент

Прогноз маржи на 1 месяц вперед 

Прогноз маржи на 2 месяца вперед 

Прогноз маржи на 24 месяца вперед 

123456

2023–02–01

1

South

1_South

110

100

80

123456

2023–03–01

1

South

1_South

100

98

78

234567

2023–03–01

0

West

0_West

3

0

-20

Далее внутри отчетной даты и сегмента вертикализируем ряд прогнозом на 1–24 месяц для удобства, получаем 24 строки вместо 24 столбов с прогнозами ранее с рядами y1,  y2,  y3,  y4, … y24  для каждого сегмента.

Отчетная дата

Х-ка 1

Х-ка 2

Сегмент

Сумма прогнозов маржи на k-тый месяц вперед 

Месяц прогноза (месяц k, где к от 1 до 24)

Количество клиентов в сегменте в отчетный месяц

2023–02–01

1

South

1_South

100 000 000

1

1 000 000

2023–03–01

1

South

1_South

100 020 000

2

1 000 200

2023–03–01

0

West

0_West

30 000 000

22

500 000

3. Экстраполяция

На графике ниже приведена динамика факта и прогноза для некоторой когорты клиентов (например, активных в декабре 2019 года с lifetime от года из северных регионов). Видим, что средний факт и прогноз маржи убывают с ростом периода из-за фактора выживаемости. Прирост с ростом периода становится все меньше и меньше стремится к определенному значению, не пересекая 0 значение, так как большинство прогнозируемых метрик не могут принимать отрицательные значения (гб, минуты, доход). Также можно отметить выпуклость кривой вниз. Запросим от нашего уравнения эти свойства: монотонное убывание, выпуклость вниз, непересечение оси абсцисс (не для всех компонент верно  это условие, в некоторых случаях ряд стремится к некоторому отрицательному значению и пересекает ось абсцисс. В таком случае константа будет отрицательной). Заявленным условиям удовлетворяет 

_scroll_external/other/fulstech-4896239083230047802-7296ac8606b61a79c331a4c816c1215c47225b036787ff4960012bed041101f2.png

где y = прогноз на месяц n, где n натуральное.  

_scroll_external/attachments/image2023-8-25_18-56-57-4f0541f3fae107ae1fe5909e102d33924998496ac27a648726a1844e0cc3ff14.png

Для каждого сегмента строим по модели, которая будет описывать зависимость компоненты CLTV  от месяца предсказания  уравнением 

_scroll_external/other/fulstech-7960089748646050564-969d4c42b2d97048e50dbb0934f4308ccc860d876dadda0bbd0d0bf051b44a0e.png

(можно сделать это в цикле, строить парную регрессию для каждого сегмента, а можно добавить в уравнение переменную, отвечающую за сегмент и домножить ее на x). Для расчета коэффициентов используем последние 6 месяцев прогноза — 6 поколений (где поколение = группа абонентов, для которых доступен прогноз на 24 месяца вперед на рассматриваемый месяц). Таким образом, исходная таблица — это список абонентов за последние 6 месяцев, их прогнозы на каждый из 6 месяцев на 2 года вперед и ряд характеристик абонентов, которые позволяют определить, к какому сегменту относится абонент. 

Будем строить парную регрессию для каждого сегмента в цикле.

Итак, в каждом сегменте для каждой когорты у нас есть ряд прогнозов на 1,2,3,…12,…24 месяцев вперед, экстраполируем его методом наименьших квадратов (мы использовали  statsmodels). Спецификацию (формулу, как зависит у от х, логарифмически, линейно, экспоненциально …) уравнения выбираем на основании вида ряда предиктов и ряда фактов. Для выбора наиболее подходящей спецификации можно использовать тест Рамсея и другие тесты на спецификацию.

Код ниже помогает создать список коэффициентов продления для выбранного сегмента сегмента segm, строит саммари и график модели для данного сегмента, можно удобно посмотреть основные статистики модели.

import numpy as np
import math
import pandas as pd
import statsmodels.api as sm
import statsmodels.formula.api as smf
 
# df - таблица с рядами суммарных прогнозов по сегментам
SEGM = '...' # выбранный сегмент для расчета
df_segm = df[df['segment'] == SEGM]
 
form_reg = '(service_margin) ~ 1 + np.log(period_key)'
model = smf.ols(formula=form_reg, data=df_segm)
result = model.fit()
# вынимаем a и b из y = a + b(ln(x))
a = result.params[0]
b = result.params[1]
# смотрим саммари
print(result.summary())
 
N_PRED_HORIZON = 24
y_fact = list(df_segm['service_margin'])
y_pred = []
for period in range(1,25):
    y_pred+=[a+b*np.log(period)]
for period in range(25,61):
    y_fact+=[a+b*np.log(period)]
    y_pred+=[a+b*np.log(period)]
 
segment_coeffs = y_pred[N_PRED_HORIZON:]/y_pred[N_PRED_HORIZON-1]
 
# строим прогноз и факт на 1 графике
print(segm)
plt.plot(y_fact, label="y_fact")
plt.plot(y_pred, label="y_pred")
plt.legend(loc="upper right")
plt.show()

На этом этапе контролируются коэффициенты детерминации ( 

_scroll_external/other/fulstech-8537423189573453613-f55c7b0e49892cab405496c1a54531b1cdcd2fdadb0b3cb9c5ac7587e676ecfa.png

 ) и адекватность коэффициентов построенных моделей. Далее подставляем для каждого сегмента и периода с 25 по 60, получаем предсказанный 

_scroll_external/other/fulstech-1302856825071434225-f7db71697be3507f0b03645809784c1aaea4a4883bc0e5be4a23b08edf708fd0.png

 и делим его на 

_scroll_external/other/fulstech-54189012749753108-336fdf1e31305c98804fb857967ac48cfedbfd4c782645213056652ac5cf7088.png

  , получаем коэффициент перевода прогноза на 24 месяц в прогноз на выбранный период как в коде выше.

Пример: на сегменте ХХХ после применения МНК получили уравнение  

_scroll_external/other/fulstech-297792654594175137-c15cbd3bf1615f39217276f87365fb98a0bad8680c1bed2fd50f9b74d966ce20.png

 ,  подставляем в уравнение

_scroll_external/other/fulstech-3008674404522182856-c53ae5329995ae54739e3b1b459e846b0ae105a99d6952b3ed12c2188cd22880.png

 , получаем 

_scroll_external/other/fulstech-3914314157009950102-ea4ded92d2f4f47723409bcfa5ae6d1b2f3b94b480fac0fd7ea482bceb4ababb.png

 , делим на прогноз на 24 период 

_scroll_external/other/fulstech-4440423510409728893-e61b9ab62711c5729b085eeaededfde05a8881d421a2f2d8afd75b0dcc0eacca.png

  и получаем коэффициент  

_scroll_external/other/fulstech-45789608123358050-acae6dc149f30b2943e5a9f9209e66e2cc26a0f8f072636ace2f92a0b4d73ce6.png

Вместо построения по модели для каждого сегмента можно добавить в уравнение по переменной, отвечающей за каждый сегмент и домножить ее на период. При 240 сегментах уравнение будет выглядеть примерно так 

_scroll_external/other/fulstech-4571578926784683398-d83cc2e4902a84a233768c782601ed121a20959c1b5cc4fa9aa7f1f78c934230.png

 , где s1,  s2,… — активные переменные сегментов, принимают значения 0 и 1. Для каждого сегмента только одна переменная s будет равна 1, остальные занулятся, таким образом задача сведется к той же парной регрессии, как мы построили в предыдущем варианте.

4. Проблемы и подходы к их решению

  1. Не учтены важные переменные. (эндогенность) Эта проблема может возникнуть, если наша компонента CLTV сильно зависит от какого-то параметра. В нашем случае этим параметром является количество дней в месяце, от которого зависит в величина месячного платежа в тарифах с подневной оплатой. Отсюда получаем проблему, случайная ошибка больше не случайна, а зависит от количества дней в месяце прогноза, поэтому оценки коэффициентов не состоятельные. В этом случае можно поделить нашу целевую переменную на количество дней в месяце и строить модели для средненевной компоненты.

  2. Временной ряд скоров не повторяет особенности ряда фактов. Эта проблема может возникнуть, если модель в среднем работает хорошо, но в отдельных сегментах завышает прогноз, на других — занижает. Например, на графике ниже ряд прогнозов убывает, ряд фактов — растет. В подобном случае мы продлевали скользящим средним.

_scroll_external/attachments/image2023-11-10_17-25-0-af311577cc6fb0aa5bfa5171c5d85d7d4c9d6617e44acec906efdc18333500c8.pngHidden text

x

y_fact

y_pred

1

37

70

2

91

4

3

78

58

4

47

83

5

37

52

6

47

33

7

115

40

8

81

-3

9

115

38

10

62

0

11

35

63

12

41

-14

13

47

4

14

129

48

15

62

10

16

135

21

17

68

-6

18

72

-21

19

81

21

20

98

-53

21

157

-41

22

150

-27

23

107

7

24

164

-64

25

140

-67

26

176

-64

27

93

-62

28

154

-14

29

114

-7

30

139

-85

31

158

-51

32

143

-38

33

120

-54

34

118

-62

35

148

-60

36

157

-8

37

160

-63

38

200

-53

39

148

-38

40

181

-102

41

208

-114

42

143

-76

43

167

-100

44

140

-80

45

221

-54

46

145

-117

47

197

-84

48

229

-95

49

202

-74

50

247

-75

51

201

-119

52

160

-151

53

241

-132

54

250

-102

55

230

-98

56

191

-163

57

250

-106

58

270

-146

59

258

-102

60

254

-115

3. Первые 1–3 месяца прогноза «скачут» или имеют другой характер кривой. (выпуклая вверх). Такая проблема возникает для свежих и неактивных абонентов, потому что модели отрабатывают на них  хуже. В этом случае можно экстраполировать ряд начиная с 4–5 месяца прогноза или рассчитывалось скользящее среднее с окном в 3 месяца и на нем уже строить статистические модели.

_scroll_external/attachments/image2023-11-14_12-25-20-f24a9f78c91b4624818db28532a787976ac9332e3d145e26034ea79d8b3b66b8.pngHidden text

y

y_regression

1

160

500

2

450

430,6853

3

440

390,1388

4

438

361,3706

5

350

339,0562

6

330

320,8241

7

345

305,409

8

348

292,0558

9

287,2775

280,2775

10

262,7415

269,7415

11

258,2105

260,2105

12

248,5093

251,5093

13

247,5051

243,5051

14

227,0943

236,0943

15

232,195

229,195

16

225,7411

222,7411

17

207,6787

216,6787

18

217,9628

210,9628

19

195,5561

205,5561

20

207,4268

200,4268

21

200,5478

195,5478

22

186,8958

190,8958

23

188,4506

186,4506

24

183,1946

182,1946

25

172,1124

178,1124

26

173,1903

174,1903

27

173,4163

170,4163

28

175,7795

166,7795

29

153,2704

163,2704

30

165,8803

159,8803

31

146,6013

156,6013

32

144,4264

153,4264

33

148,3492

150,3492

34

151,3639

147,3639

35

137,4652

144,4652

36

138,6481

141,6481

37

148,9082

138,9082

38

136,2414

136,2414

39

133,6438

133,6438

40

128,1121

131,1121

41

130,6428

128,6428

42

117,233

126,233

43

122,88

123,88

44

128,581

121,581

45

123,3338

119,3338

46

112,1359

117,1359

47

109,9852

114,9852

48

114,8799

112,8799

49

107,818

110,818

50

99,7977

108,7977

51

106,8174

106,8174

52

106,8756

104,8756

53

100,9708

102,9708

54

95,1016

101,1016

55

105,2667

99,26668

56

99,46483

97,46483

57

102,6949

95,69487

58

83,9557

93,9557

59

93,24626

92,24626

60

85,56554

90,56554

Итак, мы обсудили, какие подходы к экстраполяции могут быть использованы для продления прогнозов до 5-летнего горизонта. О том, что с этими показателями дальше делать, а также об особенностях прогнозирования компонент CLTV расскажут ребята из команды CLTV билайна совсем скоро в следующих статьях.

© Habrahabr.ru