Installs into .claude/skills of the current project.
Are you the author of Ml Pipeline?
Add the live security badge to your README. It updates with every re-scan.
[](https://www.skillsdirectory.com/skills/labdaps-ml-pipeline)
---
name: ml-pipeline
description: Pipeline padrao de ML para projetos de saude. Data loading, preprocessing, train, eval com metricas clinicas. Triggers on /ml-pipeline.
---
# Skill: ml-pipeline
Cria ou modifica pipeline de Machine Learning para projetos de saude.
**Esta skill implementa, nao decide.** As decisoes de metodo (separacao, faltantes, sentinelas, encoding, balanceamento, modelos, metrica, ponto de corte, calibracao) sao da skill `ml-checkpoints`, que e a norma do laboratorio, e ficam registradas no `pipeline-decisions.md` do projeto. O porque de cada regra esta em `docs/aprendizados-pipeline-agentes.md`, no ai-lab-hub. Sem `pipeline-decisions.md`, rode a `ml-checkpoints` antes de escrever o pipeline. Se o codigo pedir uma decisao que nao esta registrada, pare e decida pela `ml-checkpoints`, em vez de escolher um padrao aqui.
## Estrutura padrao
```
data/
raw/ # dados brutos
processed/ # dados processados
src/
data/ # loading e preprocessing
features/ # feature engineering
models/ # treinamento e avaliacao
utils/ # helpers
notebooks/ # exploracaao e analise
configs/ # hiperparametros
```
## Passos
### 1. Data Loading
- Identificar fonte (CSV, Parquet, DataSUS, API)
- Carregar com dtypes corretos: codigo (municipio, CID, categoria do DataSUS) entra como texto ou categoria, nunca como quantidade
- Documentar shape, colunas, tipos
### 2. Separacao, antes de qualquer ajuste
Separe treino e teste antes de ajustar qualquer coisa, inclusive a busca de hiperparametros, pelo esquema do CP2 da `ml-checkpoints`: por grupo (StratifiedGroupKFold) quando um identificador repete, temporal quando a pergunta e se o modelo envelhece. Tudo o que aprende com o dado (imputacao, encoding, escalonamento, selecao, balanceamento, tuning) vive dentro do fold de treino, num `Pipeline` do sklearn ou do imblearn.
### 3. Preprocessing
Aplique o que o `pipeline-decisions.md` registrou no CP3 e no CP4 da `ml-checkpoints`:
- Missing: estrategia coluna a coluna, com indicador quando o CP3 pedir
- Sentinelas: por variavel, a partir do dicionario da base, antes de codificar e imputar. Nunca a mesma lista de valores no dado inteiro
- Encoding fixo: mapa de categorias tirado do dicionario, categorica mantida como categoria ate o pipeline e encoder ajustado no fold. Nada de `pd.Categorical(col).codes`, que numera o que aparece na amostra
- Scaling: conforme a familia de modelo (CP4 e CP6)
### 4. Feature Engineering
- Criar features clinicamente relevantes, todas disponiveis no momento da predicao (CP1)
- Selecao de features dentro do fold, pelo criterio do CP7
- Documentar cada feature criada e justificativa clinica
### 5. Treinamento
Os candidatos saem do CP6, sempre com a baseline (logistica ou escore clinico) na mesma particao. Algoritmos que o lab costuma usar:
1. LightGBM
2. XGBoost
3. CatBoost
4. Random Forest
5. Logistic Regression (baseline)
6. TabPFN (datasets pequenos < 10K)
Cross-validation: o esquema registrado no CP2 (StratifiedGroupKFold quando o identificador repete; StratifiedKFold so sem repeticao)
Balanceamento: nenhum, por padrao (CP5). `class_weight` so com a calibracao medida antes e depois (Brier e slope). Reamostragem (SMOTE) raramente, sempre dentro do fold de treino, nunca antes do split, e com recalibracao obrigatoria (CP9)
### 6. Avaliacao
Siga a skill `ml-eval-report`: a metrica principal do CP8, escolhida antes de rodar e reportada com IC, calibracao (CP9), ponto de corte fixado no treino pelo custo clinico e SHAP com direcao (CP10).
### 7. Salvar
- Modelo: joblib/pickle com versao, junto com o encoder e o mapa de categorias
- Metricas: JSON ou CSV
- Graficos: PNG em results/
## Convencoes do LABDAPS (lab-ai-prediction)
O app de referencia do laboratorio e o [lab-ai-prediction](https://github.com/fabianofilho/lab-ai-prediction). O datasus-ai-prediction e o fork labdaps/datasus-ai-prediction sao linhagens arquivadas: nao escreva codigo contra elas. Ao escrever codigo que vai conviver com o app, use a API abaixo; as decisoes de metodo continuam vindo da `ml-checkpoints`. Aqui fica so a assinatura minima: na duvida, o codigo do app e a fonte.
### Modulos
- `core/outcomes/` - cada desfecho e uma subclasse de `OutcomeConfig` (ver skill `datasus-outcome`).
- `core/features/cohort.py` - `CohortBuilder(outcome).build(raw) -> cohort`, depois `.get_Xy(cohort) -> (X, y)` e `.split(...)`.
- `core/models/pipeline.py` - separacao, busca de hiperparametros, treino e calibracao.
- `core/models/evaluation.py` - graficos Plotly (ver skill `ml-eval-report`).
- `core/data/` - downloaders por sistema (SIH, SIM, SINASC, SINAN_*) e `linker.py` para record linkage.
### Treino (assinatura real)
```python
from core.models.pipeline import (
split_train_test, optimize_hyperparams, build_pipeline, train_cv, calibrate_model,
)
# Holdout ou corte temporal: separe antes da busca de hiperparametros
X_tr, X_te, y_tr, y_te = split_train_test(X, y, "holdout", holdout_size=0.2)
# ou split_train_test(X, y, "temporal", dates=datas, cutoff="AAAA-MM-DD")
params = optimize_hyperparams(X_tr, y_tr, algorithm="lgbm", seed=42) # a busca so ve o treino
pipe = build_pipeline(X_tr, "lgbm", params, balancing="none").fit(X_tr, y_tr)
# Validacao cruzada com probabilidades out-of-fold
res = train_cv(
X, y,
algorithm="lgbm", # lgbm | xgb | catboost | rf | logreg | mlp (tabpfn, se instalado)
params=params_fixos, # hiperparametro buscado na mesma coorte aqui exige CV aninhada
n_folds=5, # StratifiedKFold(shuffle=True, random_state=42), sem grupo
balancing="none", # none | class_weight | smote_over | smote_under
)
# res traz: fold_metrics, mean_metrics, oof_probs, feature_importances, model, X_columns, algorithm
```
Pontos-chave do padrao do lab:
- **Out-of-fold probs**: metricas e graficos usam `oof_probs` (predicao de cada fold no seu hold-out), nao predicao no treino. Evita vazamento e da estimativa honesta.
- **Sem grupo no `train_cv`**: ele usa StratifiedKFold por linha. Com identificador que repete, faca a separacao por grupo fora dele (CP2).
- **Metricas no corte 0,5**: sensibilidade, especificidade e F1 de `fold_metrics` e `mean_metrics` saem no corte 0,5. Para o relatorio, recalcule no corte do CP8 (ver `ml-eval-report`).
- **Balanceamento**: `balancing="none"` e o padrao (CP5). Qualquer outro valor roda so no treino de cada fold e exige a calibracao medida antes e depois. `class_weight` nao tem efeito em `xgb` nem em `mlp`.
- **Sentinelas**: o `SentinelReplacer` do app troca a mesma lista de valores em todas as colunas, o que contraria o CP3 (sentinela e por variavel). Deixe `null_sentinels` vazio e trate o ignorado coluna a coluna no preprocess do desfecho, a partir do dicionario.
### Calibracao (CP9)
```python
cal = calibrate_model(model, X, y, method="sigmoid") # sigmoid (Platt) | isotonic
# re-treina o modelo em 50%, ajusta o calibrador em 25% e mede o Brier nos 25% restantes
# cal traz: cal_model, method, raw_probs, cal_probs, y_eval, brier_before, brier_after, brier_delta
```
Modelo de risco clinico precisa de probabilidade calibrada, nao so de bom AUROC. Reporte o Brier antes e depois. Se a particao estratificada falhar (desfecho rarissimo), a funcao cai para um modo que mede o Brier na propria fracao de calibracao, e o antes e depois deixa de ser held-out: diga isso no relatorio.
### Janelas temporais
Todo desfecho define `observation_window_days` (look-back das features) e `prediction_window_days` (look-ahead do desfecho). Garanta que nenhuma feature use informacao posterior ao fim da janela de observacao (sem leakage temporal).