Considere o seguinte código:
import pandas as pd
from sklearn.model_selection import train_test_split
# step 1
ids = list(range(1000))
label = 500 * [1.0] + 500 * [0.0]
df = pd.DataFrame({"id": ids, "label": label})
# step 2
train_p = 0.8
val_p = 0.1
test_p = 0.1
# step 3
n_train = int(len(df) * train_p)
n_val = int(len(df) * val_p)
n_test = len(df) - n_train - n_val
print("* Step 3")
print("train:", n_train)
print("val:", n_val)
print("test:", n_test)
print()
# step 4
train_ids, test_ids = train_test_split(df["id"], stratify=df.label, test_size=n_test, random_state=42)
# step 5
print("* Step 5. First split")
print( df.loc[df.id.isin(train_ids), "label"].value_counts() )
print( df.loc[df.id.isin(test_ids), "label"].value_counts() )
print()
# step 6
train_ids, val_ids = train_test_split(train_ids, stratify=df.loc[df.id.isin(train_ids), "label"], test_size=n_val, random_state=42)
# step 7
train_df = df[df["id"].isin(train_ids)]
val_df = df[df["id"].isin(val_ids)]
test_df = df[df["id"].isin(test_ids)]
# step 8
print("* Step 8. Final split")
print("train:", train_df["label"].value_counts())
print("val:", val_df["label"].value_counts())
print("test:", test_df["label"].value_counts())
com saída:
* Step 3
train: 800
val: 100
test: 100
* Step 5. First split
label
1.0 450
0.0 450
Name: count, dtype: int64
label
1.0 50
0.0 50
Name: count, dtype: int64
* Step 8. Final split
train: label
0.0 404
1.0 396
Name: count, dtype: int64
val: label
1.0 54
0.0 46
Name: count, dtype: int64
test: label
1.0 50
0.0 50
Name: count, dtype: int64
- Crie um Dataframe com 1000 elementos perfeitamente balanceados entre classe 1 e 0 (positiva e negativa);
- Defina a proporção de exemplos que devem ser incluídos nas partições de treinamento, validação e teste. Gostaria de 800 exemplos na divisão de treinamento e 100 exemplos em cada uma das outras duas.
- Calcule os tamanhos das três partições e imprima seus valores.
- Execute a primeira divisão para obter o conjunto de teste, estratificado em
label
. - Imprima as estatísticas de rótulo da primeira divisão. As duas partições ainda estão balanceadas.
- Execute a segunda divisão em treinamento e validação, estratificada em
label
. - Selecione exemplos
- Estatísticas de etiquetas de impressão.
Como você pode ver, a segunda divisão na etapa 6 não produz uma divisão balanceada (estatísticas impressas na etapa 8). Após a primeira divisão, os exemplos (saída na etapa 5) ainda estão balanceados e seria possível realizar uma segunda divisão mantendo um equilíbrio de classes perfeito.
O que estou fazendo errado?