Skip to content

Commit

Permalink
🔨 update slides
Browse files Browse the repository at this point in the history
  • Loading branch information
karbartolome committed May 2, 2024
1 parent 2974527 commit fb69076
Show file tree
Hide file tree
Showing 5 changed files with 3,710 additions and 1,203 deletions.
4,385 changes: 3,327 additions & 1,058 deletions 01_ml/01_clasificacion/01_calibracion/01_calibration_slides.html

Large diffs are not rendered by default.

184 changes: 84 additions & 100 deletions 01_ml/01_clasificacion/01_calibracion/01_calibration_slides.qmd
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
title: "Calibración de probabilidades"
subtitle: "Estimación de default mediante modelos de machine learning"
author: Karina Bartolomé
institute: "Organizadora: Natalia Salaberry <br> CIMBAGE (IADCOM) - Facultad Ciencias Económicas (UBA)"
institute: "Lic. En economía (UNLP), Esp. Métodos Cuantitativos (UBA)<br><br>Organizadora: Natalia Salaberry <br> CIMBAGE (IADCOM) - Facultad Ciencias Económicas (UBA)"
date: 2024-05-13
format:
revealjs:
Expand Down Expand Up @@ -44,6 +44,8 @@ lang: es
%autoreload 2
```


::: {style="font-size: 50%;"}
## Consideraciones previas

- Se realizará una breve introducción a modelos de aprendizaje automático, pero se recomienda tener algún conocimiento previo para seguir el taller.
Expand Down Expand Up @@ -101,7 +103,6 @@ from custom_functions import (
import sklearn
sklearn.set_config(transform_output="pandas")
```
<br>

```{python}
#| echo: false
Expand Down Expand Up @@ -130,11 +131,45 @@ color_verde = "#255255"
color_verde_claro = "#BDCBCC"
```

:::


# Introducción a machine learning

## Machine Learning

En general al hablar de machine learning se hace referencia a diversos tipos de modelos. En esta presentación se analizará el caso particular de los modelos de clasificación, haciendo énfasis en la estimación de probabilidad.

```{mermaid}
flowchart LR
ml[Machine Learning]
supervised[Aprendizaje <br> supervisado]
unsupervised[Aprendizaje <br> no supervisado]
semisupervised[Aprendizaje <br> semi supervizado]
reinforce[Aprendizaje <br> por refuerzo]
ml_clf[Modelos de <br>clasificación]
ml_reg[Modelos de <br>regresión]
ml_clfclass[Predicción de<br>clase]
ml_clfprob[Predicción de <br>probabilidad]:::redclass
ml-->supervised
ml-->unsupervised
ml-->semisupervised
ml-->reinforce
supervised-->ml_clf
supervised-->ml_reg
ml_clf-->ml_clfclass
ml_clf-->ml_clfprob
classDef redclass fill:#255255,stroke:#333,stroke-width:2px,color:white;
classDef blueclass fill:#BDCBCC,stroke:#333,stroke-width:2px,color:white;
```


## ¿Qué es un modelo de clasificación binaria?
::: {style="font-size: 50%;"}
## ¿Qué es un modelo de clasificación?

Se busca predecir la [probabilidad de ocurrencia]{style="color: blue"} de un evento a partir de ciertas características observables:

Expand All @@ -148,10 +183,10 @@ Se busca predecir la [probabilidad de ocurrencia]{style="color: blue"} de un eve

▪️**Iris**: Clasificación de especies de plantas

▪️**Titanic**: Probabilidad de supervivencia
▪️**Titanic**: Clasificación de individuos en sobrevivientes y no sobrevivientes

::: {.fragment .highlight-red}
▪️**German Credit**: Probabilidad de default
▪️**German Credit**: Clasificación de individuos en riesgosos o no riesgosos
:::
:::
:::
Expand Down Expand Up @@ -254,8 +289,6 @@ $$
P(\text{Risk}=1) = f(\text{Credit amount}, \text{Age})
$$

<br>

::: columns
::: {.column width="50%"}
::: {.fragment .fade-in}
Expand Down Expand Up @@ -311,7 +344,7 @@ clf
#| label: fig-credit-tree
colors = [color_verde, 'red']
labels = ['No riesgoso','Riesgoso']
plt.figure(figsize=(6.5,6.5))
plt.figure(figsize=(6,6))
arbol = plot_tree(
clf,
filled=True,
Expand Down Expand Up @@ -466,85 +499,19 @@ display(GT(preproc.fit_transform(X_train).sample(2).round(2))
)
)
```

:::

::: {style="font-size: 50%;"}

## Modelado
::: {style="font-size: 50%;"}

Se ajustan distintos tipos de modelos reutilizando el mismo `pipeline` de preprocesamiento de datos:

::: {.nav-pills}
::: {.panel-tabset}
### Hist Gradient Boosting
```{python}
model = HistGradientBoostingClassifier(
random_state=42,
max_depth=4,
learning_rate=0.1,
class_weight={1:1,0:1}, # Sin pesos para las clases
max_iter=1000
)
pipe_hist = Pipeline([
('preproc', preproc),
('model', model)
])
pipe_hist.fit(X_train, y_train)
```

### Decision Tree
```{python}
pipe_tree = Pipeline([
('preproc', preproc),
('model', DecisionTreeClassifier(random_state=42))
])
pipe_tree.fit(X_train, y_train)
```

### SVC

```{python}
pipe_svc = Pipeline([
('preproc', preproc),
('model', SVC(random_state=42, probability=True))
])
pipe_svc.fit(X_train, y_train)
```

### LogisticRegression

```{python}
pipe_reglog = Pipeline([
('preproc', preproc),
('model', LogisticRegression(random_state=42, class_weight='balanced'))
])
pipe_reglog.fit(X_train, y_train)
```

### Hist Gradient Boosting (v2)

```{python}
model = HistGradientBoostingClassifier(
random_state=42,
max_depth=4,
learning_rate=0.01,
class_weight={1:1,0:1}, # Sin pesos para las clases
max_iter=1000
)
pipe_hist_v2 = Pipeline([
('preproc', preproc),
('model', model)
])
pipe_hist_v2.fit(X_train, y_train)
```

```{python}
deg gen_pipe(model):
def gen_pipe(model):
pipe = Pipeline([
('preproc', preproc),
('model':model)
('model',model)
])
return pipe
Expand All @@ -556,7 +523,7 @@ pipe_hist = gen_pipe(
random_state=42,
)
)
pipe_hist_v2 = gen_pipe(
pipe_hist_balanced = gen_pipe(
model = HistGradientBoostingClassifier(
max_depth=4,
learning_rate=0.1,
Expand All @@ -566,28 +533,40 @@ pipe_hist_v2 = gen_pipe(
)
)
pipe_tree = gen_pipe(model = DecisionTreeClassifier(random_state=42))
pipe_tree = gen_pipe(model = DecisionTreeClassifier(random_state=42))
pipe_reglog = gen_pipe(model = LogisticRegression(random_state=42))
pipe_tree = gen_pipe(
model = DecisionTreeClassifier(random_state=42)
)
pipe_tree = gen_pipe(
model = DecisionTreeClassifier(random_state=42)
)
pipe_reglog = gen_pipe(
model = LogisticRegression(random_state=42)
)
pipe_reglog_balanced = gen_pipe(
model = LogisticRegression(random_state=42, class_weight='balanced')
)
pipe_svc = gen_pipe(model = SVC(random_state=42, probability=True))
models_dict = {
'Hist gradient boosting': pipe_hist,
'Decision tree': pipe_tree,
'Logistc regression': pipe_reglog,
'SVC': pipe_svc,
'Hist gradient boosting v2': pipe_hist_v2
'Logistc regression (balanced)': pipe_reglog_balanced,
'Hist gradient boosting (balanced)': pipe_hist_balanced
}
```

::: {.nav-pills}
::: {.panel-tabset}
```{python}
# | output: asis
for i in models_dict.keys():
models_dict[i] = models_dict.get(i).fit(X_train, y_train)
display(Markdown(f"## {i}"))
models_dict.get(i).fit(X_train, y_train)
display(models_dict.get(i))
display(Markdown(f" "))
```

:::
:::
:::
Expand All @@ -598,15 +577,8 @@ for i in models_dict.keys():
Se calculan las métricas de cada uno de los modelos:

```{python}
models_dict = {
'Hist gradient boosting': pipe_hist,
'Decision tree': pipe_tree,
'Logistc regression': pipe_reglog,
'SVC': pipe_svc,
'Hist gradient boosting v2': pipe_hist_v2
}
#| tbl-cap: "Métricas de los modelos en la partición de evaluación"
#| label: tbl-metrics-uncalibrated
metrics_df = pd.DataFrame()
for i in models_dict.keys():
pipe = models_dict.get(i)
Expand Down Expand Up @@ -634,7 +606,7 @@ for i in models_dict.keys():

:::


::: {style="font-size: 50%;"}
## Problema

Planteo de problema organizacional
Expand All @@ -643,6 +615,7 @@ Planteo de problema organizacional
```

:::

# Calibración de probabilidades

Expand All @@ -657,15 +630,16 @@ Se busca encontrar una función que ajuste la relación entre los scores predich
>
> Siendo: $P(y_{i}=1)$ la probabilidad calibrada para el individuo $i$ y $z_{i}$ el output del modelo no calibrado (score)
<br>

Un clasificador binario bien calibrado debería clasificar de forma tal que para las observaciones que predice un score (predict_proba) = 0.8, se espera que un 80% de las observaciones correspondan a la clase positiva (1).

**Referencias:**

- [Calibración de probabilidades en {scikit-learn} 📦 ](https://scikit-learn.org/stable/modules/calibration.html)

<br>
:::

::: {style="font-size: 50%;"}
## Calibración de probabilidades (Cont.)

::: {.fragment .fade-in}
**Métodos de calibración**
Expand Down Expand Up @@ -757,6 +731,7 @@ for i in models_dict.keys():
y_pred_prob_calibrated='pred_sigmoid',
model_name=i
)
plt.title('Calibración')
plt.show()
display(Markdown(f" "))
Expand Down Expand Up @@ -943,6 +918,13 @@ Por ejemplo:

:::

::: {style="font-size: 50%;"}
## Referencias / Recursos

[Probability Calibration Workshop - PyData 2020](https://www.youtube.com/watch?v=A1NGGV3Z4m4&list=PLeVfk5xTWHYBw22D52etymvcpxey4QFIk&ab_channel=numeristical)

:::


## Contacto

Expand All @@ -953,3 +935,5 @@ Por ejemplo:
{{< fa brands github size=1x >}} [@karbartolome](http://github.com/karbartolome)

{{< fa link >}} [Blog](https://karbartolome-blog.netlify.com)


2 changes: 1 addition & 1 deletion 01_ml/01_clasificacion/01_calibracion/custom_functions.py
Original file line number Diff line number Diff line change
Expand Up @@ -115,7 +115,7 @@ def plot_calibration_models(
plt.text(0.8, 0.85, "Línea 45°", fontsize=10, rotation=45, c=color_verde)

plt.legend()
plt.title(f"Curvas de calibración {model_name}")
plt.title('Reliability diagram')
plt.xlabel("Probabilidad predicha promedio")
plt.ylabel("Fracción de positivos (clase positiva=1)")
plt.text(0.10, 0.70, "Subestimación", fontsize=10, rotation=45)
Expand Down
Loading

0 comments on commit fb69076

Please sign in to comment.