PostgreSQL 9.1
Деловая ситуация
Каждый месяц появляется новая партия учетных записей, предоставляемых конкретному процессу. Каждая партия может быть описана по месяцам, количеству счетов и суммарному балансу счетов. Цель этого процесса - вернуть часть баланса клиентам. Каждая партия отслеживается отдельно на ежемесячной основе (сумма, полученная по каждому месяцу с момента передачи партии в процесс).
Цель
Моя цель - предсказать, какая сумма будет восстановлена в будущем.
Определение данных
create table vintage_data (
granularity date, /* Month when account entered process*/
distance_in_months integer, /* Distance in months from date when accounts entered process*/
entry_accounts integer, /* Number of accounts that entered process in a given month*/
entry_amount numeric, /* Total amount for account that entered process in a given month*/
recovery_amount numeric /* Amount recovered in Nth month on accounts that entered process in a given month */
);
Примеры данных
insert into vintage_data values('2012-01-31',1,200,100000,1000);
insert into vintage_data values('2012-01-31',2,200,100000,2000);
insert into vintage_data values('2012-01-31',3,200,100000,3000);
insert into vintage_data values('2012-01-31',4,200,100000,3500);
insert into vintage_data values('2012-01-31',5,200,100000,3400);
insert into vintage_data values('2012-01-31',6,200,100000,3300);
insert into vintage_data values('2012-02-28',1,250,150000,1200);
insert into vintage_data values('2012-02-28',2,250,150000,1600);
insert into vintage_data values('2012-02-28',3,250,150000,1800);
insert into vintage_data values('2012-02-28',4,250,150000,1200);
insert into vintage_data values('2012-02-28',5,250,150000,1600);
insert into vintage_data values('2012-03-31',1,200,90000,1300);
insert into vintage_data values('2012-03-31',2,200,90000,1200);
insert into vintage_data values('2012-03-31',3,200,90000,1400);
insert into vintage_data values('2012-03-31',4,200,90000,1000);
insert into vintage_data values('2012-04-30',1,300,180000,1600);
insert into vintage_data values('2012-04-30',2,300,180000,1500);
insert into vintage_data values('2012-04-30',3,300,180000,4000);
insert into vintage_data values('2012-05-31',1,400,225000,2200);
insert into vintage_data values('2012-05-31',2,400,225000,6000);
insert into vintage_data values('2012-06-30',1,100,60000,1000);
Процесс расчета
Вы можете представить данные как треугольную матрицу (значения X должны быть предсказаны):
distance_in_months 1 2 3 4 5 6
granularity entry_accounts entry_amount
2012-01-31 200 100000 1000 2000 3000 3500 3400 3300
2012-02-28 250 150000 1200 1600 1800 1200 1600 (X-1)
2012-03-31 200 90000 1300 1200 1400 1000 (X0) (X4)
2012-04-30 300 180000 1600 1500 4000 (X1) (X5) (X8)
2012-05-31 400 225000 2200 6000 (X2) (X6) (X9) (X11)
2012-06-30 100 60000 1000 (X3) (X7) (X10) (X12 (X13)
Алгоритм
Цель состоит в том, чтобы прогнозировать все недостающие пункты (будущее). Чтобы проиллюстрировать этот процесс, это вычисление для точки X1
1) Получите итоговые значения строк за предыдущие три месяца, используя расстояние до 4:
2012-01-31 1000+2000+3000+3500=9500 (d4m3)
2012-02-28 1200+1600+1800+1200=5800 (d4m2)
2012-03-31 1300+1200+1400+1000=4900 (d4m1)
2) Получить итоговые итоги за предыдущие три месяца, используя расстояние до 3:
2012-01-31 1000+2000+3000=6000 (d3m3)
2012-02-28 1200+1600+1800=4600 (d3m2)
2012-03-31 1300+1200+1400=3800 (d3m1)
3) Вычислить средневзвешенную скорость работы для расстояния 3 и расстояния 4 (взвешенное по entry_amount):
(d4m3+d4m2+d4m1)/(100000+150000+90000) = (9500+5800+4900)/(100000+150000+90000) = 20200/340000 = 0.0594
(d3m3+d3m2+d3m1)/(100000+150000+90000) = (6000+4600+3800)/(100000+150000+90000) = 14400/340000 = 0.0424
4) Рассчитайте изменение между расстоянием 3 и расстоянием 4
((d4m3+d4m2+d4m1)/(100000+150000+90000))/((d3m3+d3m2+d3m1)/(100000+150000+90000)) =
= (20200/340000)/(14400/340000) =
= 0.0594/0.0424 = 1.403 (PredictionRateForX1)
5) Рассчитать итоговые суммы строк для прогнозируемого месяца с использованием расстояния до 3:
2012-04-30 1600+1500+4000=7100
6) Рассчитать скорость, используя entry_amount для прогнозируемого месяца
7100/180000 = 0.0394
7) Рассчитать скорость, прогнозируемую для X1
0.0394 * PredictionRateForX1 = 0.05534
8) Рассчитать количество для X1
(0.05534-0.0394)*180000 = 2869.2
Проблема
Проблема заключается в том, как вычислить остальную часть матрицы (от x-1 до x13) с помощью оператора SQL. Очевидно, что для этого потребуется какой-то рекурсивный алгоритм.