10 zmiennych, które przetrwają kryzys. Jak nie dać się złapać w pułapkę overfittingu
W 2022 roku jeden z polskich banków musiał wycofać model scoringowy po zaledwie 8 miesiącach. Powód? 52 zmienne, które świetnie działały na danych historyczn…
W 2022 roku jeden z polskich banków musiał wycofać model scoringowy po zaledwie 8 miesiącach. Powód? 52 zmienne, które świetnie działały na danych historycznych, kompletnie zawiodły po zmianie stóp procentowych. Koszt? 2,3 mln PLN stracone na wdrożenie i utrzymanie – bez żadnej poprawy wskaźnika AUC [2].
Dlaczego modele scoringowe z 50+ zmiennymi zawodzą w praktyce?
Pułapka nadmiaru: polski bank i 30% wyższe koszty
W 2021 roku średni model scoringowy w Europie Środkowej zawierał 22 zmienne. Tylko 15% z tych modeli pozostało stabilnych po roku [2]. W Polsce problem jest jeszcze dotkliwszy – dynamiczne zmiany rynkowe sprawiają, że modele tracą skuteczność szybciej niż na Zachodzie. Przykład? Bank, który wdrożył model z 52 zmiennymi, musiał go wycofać po 8 miesiącach. Koszt wdrożenia i utrzymania: 2,3 mln PLN – bez żadnej poprawy AUC [2].
Dlaczego tak się dzieje? Overfitting to tylko część problemu. Główna przyczyna leży w niestabilności zmiennych. Zmienne behawioralne, które świetnie sprawdzają się w stabilnych warunkach, tracą sens po zmianie trendu – np. po podwyżce stóp procentowych czy pandemii. W takich sytuacjach modele z mniejszą liczbą zmiennych radzą sobie lepiej, bo są łatwiejsze do interpretacji i aktualizacji.
Badanie McKinsey: 70% modeli ma za dużo zmiennych
Raport McKinsey pokazuje, że 70% modeli scoringowych wdrażanych w Europie Środkowej ma ponad 20 zmiennych. Problem? Tylko 15% z nich pozostaje stabilnych po roku [2]. Reszta wymaga kosztownych aktualizacji lub – jak w przypadku polskiego banku – zostaje wycofana.
Dlaczego firmy wciąż pakują się w tę pułapkę? Bo łatwiej dodać kolejną zmienną niż sprawdzić, czy rzeczywiście poprawia ona stabilność modelu. Tymczasem każda dodatkowa zmienna to:
- wyższe koszty utrzymania (o 20-30% dla modeli z 50+ zmiennymi) [2],
- dłuższy czas wdrożenia,
- większe ryzyko błędów w interpretacji.
Scoring behawioralny: dlaczego modele tracą skuteczność po zmianie trendu?
Zmienne behawioralne – np. częstotliwość zakupów czy średnia wartość transakcji – są szczególnie podatne na zmiany rynkowe. W 2020 roku Allegro zauważyło, że modele oparte na danych demograficznych kompletnie zawiodły podczas pandemii. Dlaczego? Bo zachowania klientów zmieniły się z dnia na dzień, a dane demograficzne nie nadążały za tymi zmianami [4].
Rozwiązanie? Allegro przeszło na zmienne oparte na historii transakcji. Efekt? Model z 30% mniejszą liczbą zmiennych okazał się bardziej stabilny i łatwiejszy w utrzymaniu [4]. To pokazuje, że kluczowa nie jest liczba zmiennych, ale ich jakość i odporność na zmiany.
Jakie cechy powinna mieć zmienna, żeby przetrwać test czasu?
Stabilność vs. predykcyjność: dlaczego wysokie IV nie wystarczy?
Information Value (IV) to popularna metryka do oceny siły predykcyjnej zmiennych. Problem? Wysokie IV nie gwarantuje stabilności. Przykład: zmienna "liczba zakupów w ostatnim miesiącu" może mieć wysokie IV w stabilnych warunkach, ale kompletnie zawieść po zmianie trendu rynkowego.
Dlatego kluczowa jest stabilność populacji – mierzy ją Population Stability Index (PSI). PSI poniżej 0,1 oznacza stabilność, powyżej 0,25 – poważne ryzyko degradacji modelu [1]. W Polsce, gdzie zmiany rynkowe są częstsze niż na Zachodzie, PSI powinien być monitorowany co najmniej raz na kwartał.
Case study Allegro: historia transakcji vs. demografia
Podczas pandemii Allegro testowało dwa podejścia do scoringu klientów:
- Zmienne demograficzne (wiek, lokalizacja, płeć).
- Zmienne behawioralne (historia transakcji, średnia wartość koszyka).
Wynik? Zmienne demograficzne straciły skuteczność w ciągu 3 miesięcy. Zmienne behawioralne pozostały stabilne – PSI poniżej 0,1 przez cały okres [4]. Co więcej, Allegro zredukowało liczbę zmiennych o 30%, co poprawiło interpretowalność modelu i obniżyło koszty utrzymania.
Jak liczyć i interpretować PSI?
Population Stability Index (PSI) mierzy, jak bardzo rozkład zmiennej zmienił się między dwoma okresami. Wzór:
PSI = Σ [(aktualny % - bazowy %) * ln(aktualny % / bazowy %)]
Gdzie:
- aktualny % – odsetek populacji w danym przedziale w aktualnym okresie,
- bazowy % – odsetek populacji w danym przedziale w okresie bazowym.
Interpretacja:
- PSI < 0,1 – stabilna zmienna,
- 0,1 ≤ PSI < 0,25 – umiarkowana zmiana, wymaga monitorowania,
- PSI ≥ 0,25 – poważna zmiana, zmienna może być niestabilna.
W Polsce, gdzie zmiany rynkowe są częste, warto ustawić alerty na PSI powyżej 0,15. Przykład: mBank zautomatyzował monitorowanie PSI, co pozwoliło na redukcję kosztów utrzymania modeli o 25% [3].
Krok po kroku: jak wyselekcjonować zmienne do modelu scoringowego?
Faza 1: Wstępna selekcja – eliminacja redundancji
Pierwszy krok to usunięcie zmiennych, które niczego nie wnoszą. Jak to zrobić?
- Analiza korelacji – usuń zmienne silnie skorelowane (|r| > 0,7). Przykład: jeśli "liczba zakupów" i "wartość zakupów" są silnie skorelowane, zostaw jedną z nich.
- Variance Inflation Factor (VIF) – usuń zmienne z VIF > 5 (oznacza to wysoką multikolinearność). W Pythonie możesz użyć biblioteki
statsmodels:
```python
from statsmodels.stats.outliers_influence import variance_inflation_factor
vif = [variance_inflation_factor(X.values, i) for i in range(X.shape[1])]
```
- Niska wariancja – usuń zmienne, które mają wariancję bliską zeru (np. < 0,01). W
feature_enginemożesz to zrobić za pomocąDropConstantFeatures[6].
Przykład: PKO BP użyło tych metod, aby zredukować liczbę zmiennych w modelach ryzyka kredytowego o 20%, co obniżyło koszty utrzymania o 15% [3].
Faza 2: Testowanie stabilności – symulacja zmian rynkowych
Nawet po wstępnej selekcji zmienne mogą okazać się niestabilne. Jak to sprawdzić?
- Bootstrapping – losuj podzbiory danych i sprawdzaj, jak zmienia się rozkład zmiennych. Jeśli PSI między podzbiorami jest wysokie, zmienna jest niestabilna.
- Symulacja scenariuszy – np. "co się stanie, jeśli stopy procentowe wzrosną o 2%?". Zmienne, które tracą skuteczność w takich scenariuszach, należy usunąć.
- Testowanie na danych z różnych okresów – np. porównaj rozkład zmiennych z 2022 i 2023 roku. Jeśli PSI jest wysokie, zmienna może nie przetrwać kolejnej zmiany trendu.
Przykład: Allegro testowało zmienne na danych z okresu pandemii i po jej zakończeniu. Tylko 60% zmiennych przeszło ten test [4].
Faza 3: Walidacja biznesowa – rozmowa z product ownerem
Statystyka to nie wszystko. Ostateczna decyzja o wyborze zmiennych powinna być konsultowana z biznesem. Dlaczego?
- Interpretowalność – modele z mniejszą liczbą zmiennych są łatwiejsze do wyjaśnienia. Przykład: OLX zredukowało liczbę zmiennych o 40%, co poprawiło interpretowalność modelu i ułatwiło komunikację z zarządem [5].
- Dostępność danych – niektóre zmienne mogą być trudne do pozyskania w przyszłości. Przykład: zmienna "liczba wizyt w sklepie stacjonarnym" może stracić sens, jeśli firma przejdzie na model online-only.
- Koszty utrzymania – każda zmienna to dodatkowy koszt. Przykład: mBank oszacował, że każda dodatkowa zmienna zwiększa koszty utrzymania modelu o 5-10% [3].
Jakie narzędzia i biblioteki ułatwiają selekcję zmiennych w Pythonie i R?
Porównanie bibliotek: feature_engine vs. scikit-learn vs. caret
| Biblioteka | Zalety | Wady | Najlepsza do |
|---|---|---|---|
feature_engine | Gotowe implementacje PSI, VIF, usuwania zmiennych o niskiej wariancji [6] | Mniej popularna niż scikit-learn | Automatyzacji selekcji zmiennych w modelach scoringowych |
scikit-learn | Szerokie wsparcie, integracja z innymi narzędziami ML | Brak gotowych implementacji PSI, wymaga ręcznego kodowania | Ogólnego przeznaczenia, gdy potrzebujesz elastyczności |
caret (R) | Wsparcie dla wielu metod selekcji zmiennych | Wolniejsza niż Python, mniej intuicyjna składnia | Analitycy pracujący w R, którzy potrzebują kompleksowych rozwiązań |
Przykład użycia feature_engine do usuwania zmiennych o niskiej wariancji:
from feature_engine.selection import DropConstantFeatures # Usuń zmienne o wariancji < 0.01 selector = DropConstantFeatures(tol=0.01) X_transformed = selector.fit_transform(X)
Automatyzacja PSI w Pythonie
Monitorowanie PSI można zautomatyzować za pomocą prostego pipeline'u. Przykład:
import numpy as np
import pandas as pd
def calculate_psi(expected, actual, buckets=10):
breakpoints = np.linspace(min(expected), max(expected), buckets + 1)
expected_perc = np.histogram(expected, breakpoints)[0] / len(expected)
actual_perc = np.histogram(actual, breakpoints)[0] / len(actual)
psi = np.sum((actual_perc - expected_perc) * np.log(actual_perc / expected_perc))
return psi
# Przykład użycia
expected = df_train['zmienna']
actual = df_test['zmienna']
psi = calculate_psi(expected, actual)
print(f"PSI: {psi:.3f}")
PKO BP zautomatyzowało monitorowanie PSI w swoich modelach ryzyka kredytowego, co pozwoliło na redukcję kosztów o 15% [3].
Case study: Jak PKO BP zautomatyzowało selekcję zmiennych?
PKO BP wdrożyło pipeline do automatycznej selekcji zmiennych, który obejmuje:
- Usuwanie zmiennych o niskiej wariancji (za pomocą
feature_engine). - Analizę korelacji i VIF (za pomocą
statsmodels). - Monitorowanie PSI (automatyczne alerty przy PSI > 0,15).
Efekt? Redukcja liczby zmiennych o 20% i obniżenie kosztów utrzymania modeli o 15% [3].
Jak przekonać biznes do modelu z mniejszą liczbą zmiennych?
Argumenty liczbowe: ROI modelu z 10 vs. 50 zmiennymi
Biznes często myśli w kategoriach kosztów i zysków. Jak pokazać, że mniejsza liczba zmiennych się opłaca?
- Koszty wdrożenia – model z 50 zmiennymi kosztuje średnio 30% więcej niż model z 10 zmiennymi [2].
- Koszty utrzymania – każda dodatkowa zmienna zwiększa koszty utrzymania o 5-10% [3].
- Stabilność – modele z mniejszą liczbą zmiennych są stabilniejsze (15% vs. 70% niestabilnych modeli) [2].
Przykład: OLX oszacowało, że redukcja liczby zmiennych o 40% pozwoliła zaoszczędzić 1,2 mln PLN rocznie na kosztach utrzymania [5].
Prezentacja dla zarządu: jak wizualizować stabilność modelu?
Zarząd nie ma czasu na techniczne szczegóły. Kluczowe są proste wizualizacje:
- Wykres PSI over time – pokazuje, jak stabilne są zmienne w czasie.
```
PSI (Population Stability Index)
0.3 | *
0.2 |
0.1 |
---------------------
Q1 Q2 Q3 Q4
```
- AUC over time – pokazuje, jak skuteczność modelu zmienia się w czasie.
```
AUC
0.9 | *
0.8 |
0.7 |
---------------------
Q1 Q2 Q3 Q4
```
- Porównanie kosztów – tabela pokazująca koszty wdrożenia i utrzymania dla modeli z różną liczbą zmiennych.
Przykład: OLX użyło takich wizualizacji, aby przekonać zarząd do redukcji liczby zmiennych. Efekt? Zgodę na wdrożenie modelu z 30 zmiennymi zamiast 50 [5].
Case study: Jak OLX zmniejszyło liczbę zmiennych o 40%?
OLX stanęło przed problemem: modele scoringowe były zbyt skomplikowane i trudne do utrzymania. Rozwiązanie?
- Analiza stabilności – usunięto zmienne z PSI > 0,2.
- Redukcja redundancji – usunięto zmienne silnie skorelowane.
- Walidacja biznesowa – konsultacje z product ownerami, aby upewnić się, że zmienne są interpretowalne.
Efekt?
- Redukcja liczby zmiennych o 40% (z 50 do 30).
- Poprawa interpretowalności modelu.
- Obniżenie kosztów utrzymania o 1,2 mln PLN rocznie [5].
Jak monitorować i aktualizować zmienne w modelu scoringowym?
Dlaczego modele w Polsce wymagają częstszych aktualizacji?
W Polsce zmiany rynkowe są częstsze niż na Zachodzie. Przykłady:
- Zmiany stóp procentowych – wpływają na zachowania klientów banków.
- Pandemia – zmieniła nawyki zakupowe klientów e-commerce.
- Inflacja – wpływa na siłę nabywczą i zachowania konsumenckie.
Dlatego modele scoringowe w Polsce wymagają częstszych aktualizacji – co najmniej raz na kwartał [3].
Automatyczne alerty PSI: jak skonfigurować system wczesnego ostrzegania?
Monitorowanie PSI można zautomatyzować za pomocą prostego systemu alertów. Przykład w Pythonie:
def monitor_psi(df_train, df_test, threshold=0.15):
psi_results = {}
for column in df_train.columns:
psi = calculate_psi(df_train[column], df_test[column])
psi_results[column] = psi
if psi > threshold:
print(f"ALERT: PSI dla {column} wynosi {psi:.3f} (próg: {threshold})")
return psi_results
# Przykład użycia
psi_results = monitor_psi(df_train, df_test)
mBank wdrożył taki system, co pozwoliło na redukcję kosztów utrzymania modeli o 25% [3].
Case study: Jak mBank zredukował koszty utrzymania modeli o 25%?
mBank postawił na ciągłe monitorowanie zmiennych. Kluczowe kroki:
- Automatyczne alerty PSI – system wysyła powiadomienia, gdy PSI przekracza 0,15.
- Kwartalne przeglądy modeli – analitycy sprawdzają, które zmienne straciły stabilność.
- Szybka reakcja – niestabilne zmienne są usuwane lub zastępowane.
Efekt? Redukcja kosztów utrzymania modeli o 25% i poprawa stabilności [3].
Next step: Jak zacząć od dziś?
- Przeanalizuj swoje modele – sprawdź, ile zmiennych mają Twoje modele scoringowe. Jeśli jest ich więcej niż 20, rozważ redukcję.
- Oblicz PSI – użyj kodu z tego artykułu, aby sprawdzić stabilność zmiennych. Ustaw alerty na PSI > 0,15.
- Porozmawiaj z biznesem – pokaż zarządowi, jak redukcja liczby zmiennych może obniżyć koszty i poprawić stabilność.
- Zautomatyzuj monitorowanie – wdroż system alertów PSI, aby szybko reagować na zmiany.
Pamiętaj: kluczowa nie jest liczba zmiennych, ale ich jakość i stabilność. Lepiej mieć 10 zmiennych, które przetrwają kryzys, niż 50, które zawiodą przy pierwszej zmianie trendu.
Źródła
[1] How to Select Variables Robustly in a Scoring Model — https://towardsdatascience.com/how-to-select-variables-robustly-in-a-scoring-model/
[2] How to Build AI Models That Stand the Test of Time — https://www.mckinsey.com/capabilities/quantumblack/our-insights/how-to-build-ai-models-that-stand-the-test-of-time
[3] Jak banki w Polsce wykorzystują AI w ocenie ryzyka kredytowego? — https://www.bankier.pl/wiadomosc/Jak-banki-w-Polsce-wykorzystuja-AI-w-ocenie-ryzyka-kredytowego-8234560.html
[4] Jak Allegro wykorzystuje dane do ulepszania doświadczeń klientów? — https://www.allegro.pl/blog/tech/jak-allegro-wykorzystuje-dane-do-ulepszania-doświadczeń-klientów/
[5] Jak OLX wykorzystuje AI do zwiększenia efektywności? — https://www.olxgroup.com/pl/insights/jak-olx-wykorzystuje-ai-do-zwiekszenia-efektywnosci/
[6] Feature-engine: A Python Library for Feature Selection and Engineering — https://www.feature-engine.com/