Exploração dos dados
Descrição da base de dados e código de exploração
O câncer de mama é o tipo de câncer mais comum entre mulheres em todo o mundo, responsável por aproximadamente 25% de todos os casos e afetando milhões de pessoas todos os anos. Ele se desenvolve quando células da mama começam a crescer de forma descontrolada, formando tumores que podem ser identificados por exames de imagem (raios-X) ou detectados como nódulos.
O principal desafio no diagnóstico é diferenciar corretamente os tumores malignos (cancerosos) dos benignos (não cancerosos). O objetivo deste projeto é desenvolver um modelo de classificação supervisionada capaz de prever, com base em atributos numéricos das células, se um tumor é maligno ou benigno.
Sobre o Dataset
Total de registros: 569 amostras
Variável alvo: diagnosis (M = maligno, B = benigno)
Número de variáveis preditoras: 30 atributos numéricos relacionados ao tamanho, textura, formato e concavidade das células.
| id | diagnosis | radius_mean | texture_mean | perimeter_mean | area_mean | smoothness_mean | compactness_mean | concavity_mean | concave points_mean | symmetry_mean | fractal_dimension_mean | radius_se | texture_se | perimeter_se | area_se | smoothness_se | compactness_se | concavity_se | concave points_se | symmetry_se | fractal_dimension_se | radius_worst | texture_worst | perimeter_worst | area_worst | smoothness_worst | compactness_worst | concavity_worst | concave points_worst | symmetry_worst | fractal_dimension_worst |
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| 87930 | B | 12.47 | 18.6 | 81.09 | 481.9 | 0.09965 | 0.1058 | 0.08005 | 0.03821 | 0.1925 | 0.06373 | 0.3961 | 1.044 | 2.497 | 30.29 | 0.006953 | 0.01911 | 0.02701 | 0.01037 | 0.01782 | 0.003586 | 14.97 | 24.64 | 96.05 | 677.9 | 0.1426 | 0.2378 | 0.2671 | 0.1015 | 0.3014 | 0.0875 |
| 859575 | M | 18.94 | 21.31 | 123.6 | 1130 | 0.09009 | 0.1029 | 0.108 | 0.07951 | 0.1582 | 0.05461 | 0.7888 | 0.7975 | 5.486 | 96.05 | 0.004444 | 0.01652 | 0.02269 | 0.0137 | 0.01386 | 0.001698 | 24.86 | 26.58 | 165.9 | 1866 | 0.1193 | 0.2336 | 0.2687 | 0.1789 | 0.2551 | 0.06589 |
| 8670 | M | 15.46 | 19.48 | 101.7 | 748.9 | 0.1092 | 0.1223 | 0.1466 | 0.08087 | 0.1931 | 0.05796 | 0.4743 | 0.7859 | 3.094 | 48.31 | 0.00624 | 0.01484 | 0.02813 | 0.01093 | 0.01397 | 0.002461 | 19.26 | 26 | 124.9 | 1156 | 0.1546 | 0.2394 | 0.3791 | 0.1514 | 0.2837 | 0.08019 |
| 907915 | B | 12.4 | 17.68 | 81.47 | 467.8 | 0.1054 | 0.1316 | 0.07741 | 0.02799 | 0.1811 | 0.07102 | 0.1767 | 1.46 | 2.204 | 15.43 | 0.01 | 0.03295 | 0.04861 | 0.01167 | 0.02187 | 0.006005 | 12.88 | 22.91 | 89.61 | 515.8 | 0.145 | 0.2629 | 0.2403 | 0.0737 | 0.2556 | 0.09359 |
| 921385 | B | 11.54 | 14.44 | 74.65 | 402.9 | 0.09984 | 0.112 | 0.06737 | 0.02594 | 0.1818 | 0.06782 | 0.2784 | 1.768 | 1.628 | 20.86 | 0.01215 | 0.04112 | 0.05553 | 0.01494 | 0.0184 | 0.005512 | 12.26 | 19.68 | 78.78 | 457.8 | 0.1345 | 0.2118 | 0.1797 | 0.06918 | 0.2329 | 0.08134 |
| 927241 | M | 20.6 | 29.33 | 140.1 | 1265 | 0.1178 | 0.277 | 0.3514 | 0.152 | 0.2397 | 0.07016 | 0.726 | 1.595 | 5.772 | 86.22 | 0.006522 | 0.06158 | 0.07117 | 0.01664 | 0.02324 | 0.006185 | 25.74 | 39.42 | 184.6 | 1821 | 0.165 | 0.8681 | 0.9387 | 0.265 | 0.4087 | 0.124 |
| 9012000 | M | 22.01 | 21.9 | 147.2 | 1482 | 0.1063 | 0.1954 | 0.2448 | 0.1501 | 0.1824 | 0.0614 | 1.008 | 0.6999 | 7.561 | 130.2 | 0.003978 | 0.02821 | 0.03576 | 0.01471 | 0.01518 | 0.003796 | 27.66 | 25.8 | 195 | 2227 | 0.1294 | 0.3885 | 0.4756 | 0.2432 | 0.2741 | 0.08574 |
| 853201 | M | 17.57 | 15.05 | 115 | 955.1 | 0.09847 | 0.1157 | 0.09875 | 0.07953 | 0.1739 | 0.06149 | 0.6003 | 0.8225 | 4.655 | 61.1 | 0.005627 | 0.03033 | 0.03407 | 0.01354 | 0.01925 | 0.003742 | 20.01 | 19.52 | 134.9 | 1227 | 0.1255 | 0.2812 | 0.2489 | 0.1456 | 0.2756 | 0.07919 |
| 8611161 | B | 13.34 | 15.86 | 86.49 | 520 | 0.1078 | 0.1535 | 0.1169 | 0.06987 | 0.1942 | 0.06902 | 0.286 | 1.016 | 1.535 | 12.96 | 0.006794 | 0.03575 | 0.0398 | 0.01383 | 0.02134 | 0.004603 | 15.53 | 23.19 | 96.66 | 614.9 | 0.1536 | 0.4791 | 0.4858 | 0.1708 | 0.3527 | 0.1016 |
| 911673 | B | 13.9 | 16.62 | 88.97 | 599.4 | 0.06828 | 0.05319 | 0.02224 | 0.01339 | 0.1813 | 0.05536 | 0.1555 | 0.5762 | 1.392 | 14.03 | 0.003308 | 0.01315 | 0.009904 | 0.004832 | 0.01316 | 0.002095 | 15.14 | 21.8 | 101.2 | 718.9 | 0.09384 | 0.2006 | 0.1384 | 0.06222 | 0.2679 | 0.07698 |
Pré - processamento
Antes do treinamento do modelo, foi realizado um pré-processamento para garantir a qualidade e consistência dos dados:
Remoção de colunas irrelevantes – A coluna id foi descartada, pois não contribui para o aprendizado do modelo.
Tratamento de valores ausentes – Foram encontrados valores faltantes em algumas variáveis (concavity_worst e concave points_worst). Esses valores foram preenchidos utilizando a mediana, por ser uma técnica robusta contra outliers.
Codificação de variáveis categóricas – A variável alvo diagnosis foi transformada em valores numéricos por meio de Label Encoding (M = 1, B = 0), permitindo sua utilização pelo algoritmo de aprendizado.
import matplotlib.pyplot as plt
import pandas as pd
from io import StringIO
from sklearn import tree
from sklearn.model_selection import train_test_split
from sklearn.preprocessing import LabelEncoder
from sklearn.metrics import accuracy_score
#carregamento da base
df = pd.read_csv('https://raw.githubusercontent.com/MariaLuizazz/MACHINE-LEARNING-PESSOAL/refs/heads/main/dados/breast-cancer.csv')
#pré processamento
#remoção da coluna id pois é irrelevante para o modelo
df = df.drop(columns=['id'])
#conversão de letra para número
label_encoder = LabelEncoder()
df['diagnosis'] = label_encoder.fit_transform(df['diagnosis'])
#features escolhidas, todas menos diagnosis e id
x = df.drop(columns=['diagnosis'])
y = df['diagnosis']
#imputação com mediana de valores ausentes nas features concavity_worts e concavity points_worst
df['concavity_mean'].fillna(df['concavity_mean'].median(), inplace=True)
df['concave points_mean'].fillna(df['concave points_mean'].median(), inplace=True)
print(df.to_markdown(index=False))
Divisão de Dados e Treinamneto do Modelo(SVM + PCA)
O código separa o conjunto de dados em dois grupos: um para treinar o modelo (x_train, y_train) e outro para avaliar seu desempenho (x_test, y_test). A divisão usa 70% dos dados para treino e 30% para teste.
A opção stratify=y garante que a proporção entre as classes (benigno/maligno) seja mantida igual nos dois conjutos. Isso evita que o modelo treine com mais exemplos de uma classe do que outra.
O parâmetro random_state=42 apenas fixa a semente aleatória, garantindo que a mesma divisão sempre seja reproduzida.
# Divisão treino/teste
x_train, x_test, y_train, y_test = train_test_split(
x, y, test_size=0.3, random_state=42, stratify=y)
Aplicação do PCA :
O PCA (Principal Component Analysis) reduz a dimensionalidade dos dados de entrada para 2 componentes principais.
Aqui é que o PCA é ajustado apenas no conjunto de treino, usando: x_train_pca = pca.fit_transform(x_train)
Isso significa que o PCA aprende sua transformação apenas com os dados que o modelo pode ver durante o treinamento — evitando vazamento de informação do teste.
Depois disso, o mesmo PCA transformado é aplicado ao conjunto de teste, sem novo ajuste: x_test_pca = pca.transform(x_test)
# PCA treinado APENAS no conjunto de treino
pca = PCA(n_components=2)
x_train_pca = pca.fit_transform(x_train)
x_test_pca = pca.transform(x_test)
Avaliação do Modelo
| Kernel | Acurácia |
|---|---|
| linear | 0.9240 |
| sigmoid | 0.8889 |
| poly | 0.8480 |
| rbf | 0.9123 |
Representação :
-
Foram avaliadas quatro variantes do SVM, cada uma utilizando um kernel diferente: linear, sigmoid, polynomial (poly) e rbf.
-
Kernel Linear (0.9240) — Melhor desempenho A alta acurácia indica que, após o PCA, os dados tornam-se essencialmente separáveis por uma fronteira linear. Isso sugere que a estrutura do problema é relativamente simples no espaço reduzido.
-
Kernel RBF (0.9123) — Segundo melhor Mesmo sendo mais flexível, o RBF não superou o kernel linear, mostrando que a complexidade extra não traz ganho real neste cenário.
-
Kernel Sigmoid (0.8889) — Desempenho intermediário O kernel sigmoid tende a ser menos estável e frequentemente oferece resultados inferiores em comparação a kernels mais robustos.
-
Kernel Poly (0.8480) — Pior desempenho A fronteira polinomial acaba gerando uma complexidade que não reflete bem a estrutura dos dados, prejudicando a generalização.
Relatório Final
Os experimentos mostraram que:
O PCA cumpriu sua função ao comprimir a variância dos 30 atributos para duas dimensões, permitindo uma separação clara entre as classes.
O SVM com kernel linear mostrou-se o mais adequado para o problema, fornecendo a melhor acurácia e generalização.
Kernels mais complexos, como RBF e Poly, não superaram o modelo linear, reforçando que a separação dos dados no espaço PCA é simples.
Possíveis Melhorias:
-
Avaliação de SVM sem PCA, para comparar o impacto da redução dimensional.
-
Aplicação de normalização (StandardScaler) antes do PCA e do SVM.
-
Ajuste de hiperparâmetros via GridSearchCV.
-
Teste de outras métricas além da acurácia: F1-score, recall, matriz de confusão.
-
Uso de métodos mais robustos a ruído, como Random Forest ou Gradient Boosting.
