Os algoritmos são o ‘core’ da Ciência de Dados, e a técnica de amostragem é uma das etapas críticas que pode impactar o desempenho de um projeto. É importante aprender sobre os métodos mais usados para amostragem, dessa forma podemos escolher a melhor abordagem para os nossos dados. Nesse post, vamos apresentar os 5 métodos de amostragem mais conhecidos e exemplos de implementação em Python.

 

Amostragem Aleatória Simples

Vamos considerar que é necessário selecionar um subconjunto de uma população onde cada elemento tem uma probabilidade igual de ser selecionado.

Por exemplo, dado um conjunto de dados carregados em certo dataframe (df), podemos selecionar 100 amostras aleatórias do conjunto:

sample_df = df.sample(100)

Amostragem Estratificada

 

Amostragem-Estratificada

 

Imagine que precisamos estimar a média de votos para cada candidato em uma eleição estadual. Suponha que temos um estado com 3 cidades:

A cidade A tem 1 milhão de funcionários de fábrica;

A cidade B tem 2 milhões de funcionários;

A cidade C tem 3 milhões de aposentados.

Podemos escolher ter uma amostragem aleatória de tamanho 60 sobre a população inteira, mas existe uma chance de que a amostragem não resulte balanceada para cidades e por consequência teremos um viés que pode causar um erro significante na análise.

Como alternativa, se selecionarmos uma amostra aleatória de 10, 20 e 30 da cidade A, B e C respectivamente, podemos ter uma estimativa com erro menor para o mesmo tamanho de amostra. Em Python, podemos implementar essa abordagem de forma simples usando funções da livraria sklearn:

from sklearn.model_selection import train_test_split

X_train, X_test, y_train, y_test = train_test_split(X, y, stratify=y, test_size=0.25)

 

Amostragem “Reservoir”

 

Amostragem “Reservoir”Amostragem “Reservoir”

 

Vamos supor que temos um fluxo de elementos de tamanho grande e desconhecido e só conseguimos repetir elementos uma vez na amostragem. A tarefa é criar um algoritmo que selecione um elemento para o fluxo de forma que cada elemento seja escolhido com mesma probabilidade.

Como podemos fazer isso?

Para simplificar, considere que devemos amostrar 5 elementos a partir de um fluxo infinito e cada elemento tem a mesma probabilidade de ser selecionado. Abaixo, temos uma implementação da amostragem reservoir para o caso:

import random

def generator(max):

number = 1

while number < max:

number += 1

yield number

 

# Criar um gerador do fluxo

stream = generator(10000)

 

# Fazendo amostragem ‘Reservoir’ a partir do fluxo

k=5

reservoir = []

for i, element in enumerate(stream):

if i+1<= k:

reservoir.append(element)

else:

probability = k/(i+1)

if random.random() < probability:

# Selecionar elemento no fluxo e remover e retirar um dos k elementos já selecionados

reservoir[random.choice(range(0,k))] = element

 

print(reservoir)

————————————

[1369, 4108, 9986, 828, 5589]

 

Matematicamente pode se demonstrar que na amostra cada elemento tem a mesma probabilidade de ser selecionado no fluxo. Como?

Vamos pensar em um problemas mais simples: 

Imagine que temos só 3 elementos e temos que manter 2.

Vemos o primeiro elemento e o mantemos na lista dado que nosso reservoir tem espaço. Vemos o segundo e também o mantemos na lista dado que o reservoir ainda tem espaço.

Agora vemos o terceiro elemento. Selecionamos o terceiro para pertencer na lista com probabilidade ⅔. 

Agora vamos ver a probabilidade do primeiro item ser selecionado:

A probabilidade de retirar o primeiro elemento é a probabilidade do terceiro ser selecionado multiplicado pela probabilidade do primeiro ser selecionado de forma aleatória para ser substituído no reservoir de 2 elementos. A probabilidade é:

⅔ * ½ = ⅓ 

Assim, a probabilidade do primeiro elemento ser selecionado é:

1-⅓ = ⅔ 

Exatamente a mesma probabilidade do terceiro ser selecionado. Usando o mesmo argumento para o segundo elemento e pode-se estender para muitos. Assim, cada elemento tem a mesma probabilidade de ser selecionado: ⅔ ou em geral k/n.

 

Undersampling e Oversampling Aleatórios

 

Undersampling-Oversampling-aleatórios

 

 

É muito comum encontrar um conjunto de dados desbalanceado. Uma técnica muito usada para tratar estes casos é conhecida como re-amostragem. Consiste em remover amostrar da classe maioria (undersampling) e/ou adicionar mais amostras da classe minoria (oversampling).

Vamos criar primeiro um exemplo de conjunto desbalanceado:

import pandas as pd

from sklearn.datasets import make_classification

X, y = make_classification(

n_classes=2, class_sep=1.5, weights=[0.9, 0.1],

n_informative=3, n_redundant=1, flip_y=0,

n_features=20, n_clusters_per_class=1,

n_samples=100, random_state=10

)

 

X = pd.DataFrame(X)

X[‘target’] = y

 

Agora, podemos fazer undersampling e oversampling aleatório usando:

 

num_0 = len(X[X[‘target’]==0])

num_1 = len(X[X[‘target’]==1])

print(num_0,num_1)

 

# undersampling aleatório

undersampled_data = pd.concat([ X[X[‘target’]==0].sample(num_1) , X[X[‘target’]==1] ])

print(len(undersampled_data))

 

# oversampling aleatório

oversampled_data = pd.concat([ X[X[‘target’]==0] , X[X[‘target’]==1].sample(num_0, replace=True) ])

print(len(oversampled_data))

 

————————————————————

SAÍDA:

90 10

20

180

 

Undersampling e Oversampling usando imbalanced-learn

A livraria python imbalanced-learn (imblearn) é uma ferramenta auxiliar para conjunto de dados desbalanceados. Esta fornece uma variedade de métodos para fazer undersampling e oversampling.

  1. Undersampling usando Tomek Links:

Um dos métodos é conhecido como Tomek Links. Tomek links são duplas de exemplos com classes opostas numa vizinhança próxima.

Nesse algoritmo temos a remoção de elementos maioria no Tomek link que fornece uma melhor fronteira de decisão para um classificador:

from imblearn.under_sampling import TomekLinks

tl = TomekLinks(return_indices=True, ratio=’majority’)

X_tl, y_tl, id_tl = tl.fit_sample(X, y)

 

Oversampling-usando-SMOTE

  1. Oversampling usando SMOTE:

No SMOTE (Synthetic Minority Oversampling Technique), dados sintéticos são criados para a classe minoria na vizinhança dos elementos existentes:

from imblearn.over_sampling import SMOTE

smote = SMOTE(ratio=’minority’)

X_sm, y_sm = smote.fit_sample(X, y)

Existem outros tipos de métodos na livraria imblearn tanto para undersampling (Cluster Centroids, NearMiss, etc. ) e oversampling (ADASYN, SMOTE, etc).

Conclusão

Amostragem é um assunto importante em ciência de dados, assunto este que não se abordamos tanto quanto deveríamos.

Uma boa estratégia de amostragem as vezes pode levar um projeto à frente. Uma estratégia deficiente pode levar a resultados incorretos. Assim, devemos ser cuidadosos na hora selecionarmos uma estratégia de amostragem.

Share This