---
title: "Introdução ao scikit-learn com Python — 2026"
url: "https://python.dev.br/blog/introducao-ao-scikit-learn/"
markdown_url: "https://python.dev.br/blog/introducao-ao-scikit-learn.MD"
description: "Aprenda scikit-learn do zero: treinar modelos de classificação e regressão, dividir dados, avaliar métricas, usar Pipeline e salvar modelos. Tutorial prático em português."
date: "2026-07-04"
author: "Equipe Python Brasil"
---

# Introdução ao scikit-learn com Python — 2026

Aprenda scikit-learn do zero: treinar modelos de classificação e regressão, dividir dados, avaliar métricas, usar Pipeline e salvar modelos. Tutorial prático em português.


O **scikit-learn** é a biblioteca de machine learning clássico mais usada em Python. Se você já domina [NumPy](/blog/introducao-ao-numpy/) e [Pandas](/blog/introducao-ao-pandas/), o scikit-learn é o próximo passo natural para transformar dados em previsões: classificar e-mails como spam, prever o preço de um imóvel, identificar clientes com risco de cancelamento ou agrupar produtos por similaridade.

Praticamente todo profissional brasileiro de [ciência de dados](/blog/python-para-ciencia-de-dados/) passa pelo scikit-learn. A biblioteca cobre regressão, classificação, agrupamento, redução de dimensionalidade e pré-processamento, tudo com uma API consistente e fácil de testar. Neste tutorial prático, você vai treinar modelos de verdade, avaliar resultados com métricas corretas e entender o fluxo que o mercado espera. Para uma definição mais conceitual do tema, confira nossa entrada sobre [machine learning](/glossario/machine-learning/) no glossário; aqui o foco é colocar a mão na massa com a biblioteca.

## Instalação e importação

Instale o scikit-learn com o `pip`:

```bash
pip install scikit-learn
```

Quem usa [gerenciadores de pacotes modernos](/blog/gerenciadores-de-pacotes-python/) como o **uv** pode rodar `uv add scikit-learn`, que resolve dependências com [NumPy](/blog/introducao-ao-numpy/) e SciPy de forma bem mais rápida.

O scikit-learn não se importa como um bloco só. A convenção é importar cada submódulo no momento de usar:

```python
from sklearn.datasets import load_iris
from sklearn.model_selection import train_test_split
from sklearn.ensemble import RandomForestClassifier
from sklearn.metrics import accuracy_score, classification_report
```

Essa prática mantém o código explícito e evita carregar funções que você não vai usar.

## A API do scikit-learn: fit, predict e transform

O segredo do scikit-learn é a API uniforme. Quase todo objeto é um **estimador** com três métodos centrais:

- `fit(X, y)` — ajusta o modelo aos dados de entrada `X` (features) e, no caso supervisionado, aos alvos `y`.
- `predict(X)` — gera previsões para novos dados.
- `transform(X)` — usado por etapas de pré-processamento, como normalizar ou codificar variáveis.

Isso vale para uma regressão linear, uma floresta aleatória ou um normalizador: a mesma interface. Por isso, aprender bem três métodos destrava dezenas de algoritmos.

## Dividindo os dados em treino e teste

Antes de treinar qualquer modelo, separe parte dos dados para avaliação. Treinar e testar no mesmo conjunto engana: o modelo pode só decorar as respostas. A função `train_test_split` faz isso de forma aleatória e controlada:

```python
from sklearn.model_selection import train_test_split

X = dados.drop(columns=["alvo"])  # features
y = dados["alvo"]                  # variável que queremos prever

X_train, X_test, y_train, y_test = train_test_split(
    X, y, test_size=0.2, random_state=42, stratify=y
)
```

Detalhes importantes:

- `test_size=0.2` reserva 20% dos dados para teste.
- `random_state=42` garante reprodutibilidade — sem ele, cada execução divide diferente.
- `stratify=y` mantém a proporção das classes nos dois conjuntos, essencial em dados desbalanceados.

A convenção `X` maiúsculo (matriz de features, normalmente um DataFrame ou array 2D) e `y` minúsculo (vetor de alvos) é padrão em tutoriais, documentação e provas técnicas.

## Primeiro modelo: classificação

Vamos classificar espécies de flores usando o dataset Iris, clássico e embutido na biblioteca:

```python
from sklearn.datasets import load_iris
from sklearn.model_selection import train_test_split
from sklearn.ensemble import RandomForestClassifier
from sklearn.metrics import accuracy_score, classification_report, confusion_matrix

iris = load_iris()
X_train, X_test, y_train, y_test = train_test_split(
    iris.data, iris.target, test_size=0.2, random_state=42, stratify=iris.target
)

modelo = RandomForestClassifier(random_state=42)
modelo.fit(X_train, y_train)

previsoes = modelo.predict(X_test)
print("Acurácia:", accuracy_score(y_test, previsoes))
```

Para entender não só a taxa de acerto, mas onde o modelo erra, use a matriz de confusão e o relatório de classificação:

```python
print(confusion_matrix(y_test, previsoes))
print(classification_report(y_test, previsoes, target_names=iris.target_names))
```

O `classification_report` traz **precisão**, **revocação** (recall) e **F1-score** por classe. Em problemas reais, acurácia sozinha engana: um modelo que acerta 95% pode ser péssimo se a classe importante aparece em só 5% dos dados. Revocação e F1 mostram esse viés.

## Regressão: prevendo números contínuos

Quando o alvo é um número contínuo (preço, temperatura, tempo), usamos regressão. As métricas mudam: em vez de acurácia, avaliamos erro médio quadrático (MSE) e o coeficiente de determinação (R²):

```python
from sklearn.linear_model import LinearRegression
from sklearn.metrics import mean_squared_error, r2_score
import numpy as np

# Exemplo sintético: área (m²) e preço (R$ mil) de imóveis
area = np.array([[35], [50], [62], [80], [100], [120], [45], [75], [90], [110]])
preco = np.array([180, 240, 310, 420, 520, 610, 220, 380, 470, 560])

X_train, X_test, y_train, y_test = train_test_split(
    area, preco, test_size=0.3, random_state=42
)

reg = LinearRegression()
reg.fit(X_train, y_train)
previsoes = reg.predict(X_test)

print("MSE:", mean_squared_error(y_test, previsoes))
print("R²:", r2_score(y_test, previsoes))
print("Preço por m²:", reg.coef_[0])
```

O R² varia de 0 a 1 e indica quanto da variação do alvo o modelo explica. Um R² de 0,90 significa que 90% da variação no preço é capturada pela área. Para relações mais complexas, troque `LinearRegression` por `RandomForestRegressor` ou `GradientBoostingRegressor`, sem mudar o restante do código.

## Pipeline: pré-processamento e modelo juntos

Em projetos reais, os dados precisam de ajustes antes do modelo: normalizar escalas, preencher valores faltantes, codificar categorias. Fazer isso manualmente vira bagunça e abre espaço para um erro grave chamado **vazamento de dados** (data leakage), quando informações do teste "vazam" para o treino.

A solução é o `Pipeline`, que encadeia etapas e ajusta tudo corretamente dentro da validação:

```python
from sklearn.pipeline import Pipeline
from sklearn.preprocessing import StandardScaler
from sklearn.linear_model import LogisticRegression

pipeline = Pipeline([
    ("scaler", StandardScaler()),
    ("modelo", LogisticRegression(max_iter=200, random_state=42)),
])

pipeline.fit(X_train, y_train)
print("Acurácia:", pipeline.score(X_test, y_test))
```

O `StandardScaler` normaliza as features para média zero e desvio-padrão um, o que ajuda algoritmos sensíveis à escala (regressão logística, SVM, KNN). Florestas aleatórias, por outro lado, lidam bem com escalas diferentes e costumam dispensar esse passo. Use o `Pipeline` mesmo em projetos pequenos: ele deixa o código limpo e evita erros difíceis de rastrear.

## Validação cruzada

Uma única divisão treino/teste depende do acaso. A **validação cruzada** (k-fold) divide os dados em `k` partes, treina em `k-1` e testa em 1, repetindo `k` vezes. A média das execuções dá uma estimativa mais confiável:

```python
from sklearn.model_selection import cross_val_score

notas = cross_val_score(pipeline, X, y, cv=5)
print("Notas por fold:", notas)
print("Média:", notas.mean())
```

Esse passo é indispensável antes de confiar em um número de desempenho, principalmente com poucos dados. Para uma discussão mais profunda de viés, variância e validação, leia nosso artigo de [machine learning para iniciantes](/blog/python-e-machine-learning-iniciantes/).

## Salvando e carregando modelos

Depois de treinar, você vai querer guardar o modelo para usá-lo em uma API, um dashboard ou um script de inferência. O padrão do ecossistema é o `joblib`, otimizado para arrays do NumPy:

```python
import joblib

joblib.dump(pipeline, "modelo.pkl")
modelo_carregado = joblib.load("modelo.pkl")
print(modelo_carregado.predict(X_test[:5]))
```

Salve sempre o `Pipeline` completo, não só o modelo final. Assim, o pré-processamento (escalas, codificações) acompanha o modelo e a inferência nova é tratada da mesma forma que o treino. Para colocar esse modelo no ar como serviço, veja o guia de [deploy de aplicação Python](/blog/deploy-aplicacao-python/) e o exemplo com [AWS Lambda](/blog/python-e-aws-lambda/).

## Mini-projeto: prever cancelamento de clientes

Vamos juntar tudo em um problema típico do mercado brasileiro: prever se um cliente vai cancelar o serviço (churn) com base no tempo de contrato, valor mensal e número de chamadas no suporte. Usamos dados sintéticos para o exemplo ser reproduzível:

```python
from sklearn.datasets import make_classification
from sklearn.model_selection import train_test_split, cross_val_score
from sklearn.pipeline import Pipeline
from sklearn.preprocessing import StandardScaler
from sklearn.ensemble import GradientBoostingClassifier
from sklearn.metrics import classification_report

# 1.000 clientes, 3 features, ~30% de churn
X, y = make_classification(
    n_samples=1000, n_features=3, n_informative=3, n_redundant=0,
    n_clusters_per_class=1, weights=[0.7, 0.3], random_state=42
)

X_train, X_test, y_train, y_test = train_test_split(
    X, y, test_size=0.2, random_state=42, stratify=y
)

pipeline = Pipeline([
    ("scaler", StandardScaler()),
    ("modelo", GradientBoostingClassifier(random_state=42)),
])

pipeline.fit(X_train, y_train)
print(classification_report(y_test, pipeline.predict(X_test)))

notas = cross_val_score(pipeline, X, y, cv=5, scoring="f1")
print("F1 médio (cross-val):", notas.mean())
```

Repare no uso do `scoring="f1"` na validação cruzada. Em churn, o F1 (e a revocação da classe positiva) costuma importar mais que a acurácia, porque identificar quem vai cancelar é o objetivo de negócio. Escolher a métrica certa para o problema é uma decisão que separa um tutorial de uma solução útil.

## scikit-learn no mercado brasileiro

O scikit-learn é exigência frequente em vagas de **analista de dados**, **cientista de dados** e **engenheiro de dados** com Python. Vale acompanhar os caminhos de carreira: confira o guia para virar [analista de dados com Python](/carreira/python-analista-de-dados/), a trilha de [engenheiro de dados](/carreira/python-engenheiro-de-dados/) e a faixa de [salários de Python no Brasil](/carreira/salarios-python-brasil/). Para acompanhar oportunidades em tempo real, acompanhe nossas [vagas de Python](/vagas/).

## Próximos passos

Para evoluir depois deste tutorial:

1. **Aplique em dados reais** — carregue um CSV com [Pandas](/blog/introducao-ao-pandas/), trate valores faltantes e treine um modelo de ponta a ponta.
2. **Domine pré-processamento** — `OneHotEncoder`, `SimpleImputer` e `StandardScaler` resolvem a maior parte dos problemas tabulares.
3. **Estude ajuste de hiperparâmetros** — `GridSearchCV` e `RandomizedSearchCV` procuram as melhores configurações de forma automatizada.

O scikit-learn é a porta de entrada mais sólida para machine learning com Python. Treine modelos, avalie com métricas honestas, use `Pipeline` e validação cruzada, e você terá uma base que sustenta desde projetos de portfólio até decisões reais de negócio. Quando os dados crescerem demais para a memória, vale conhecer o [Polars como alternativa ao Pandas](/blog/polars-alternativa-pandas-python/); e para visualizar resultados, o [Matplotlib](/blog/introducao-ao-matplotlib/) integra direto com os arrays que o scikit-learn produz.
