Projeto requisitado na disciplina de Tópicos Avançados em Eng. de Software 1 - Universidade de Pernambuco Campus Garanhuns - Bacharelado em Engenharia de Software - 7º período
1 - Preparação do ambiente:
- Google Colab (para construir o notebook e realizar a análise utilizando as bibliotecas já existentes na linguagem Python);
- Dataset (base de dados que pode ser encontrada aqui que possui um conjunto de transações anonimizadas com operações fraudulentas e genuínas em operações com cartão de crédito.
Vamos lá!!! Crie um projeto em branco em colab.research.google.com e vamos começar!!!
2 - Importando as bibliotecas necessárias:
# Para manipulação do dataset e visualização de dados
import pandas as pd
import matplotlib.pyplot as plt
import seaborn as sns
from sklearn.model_selection import train_test_split
# Para classificação dos dados
from sklearn import model_selection
from sklearn.metrics import classification_report
from sklearn.tree import DecisionTreeClassifier
from sklearn.naive_bayes import GaussianNB
from sklearn.linear_model import LogisticRegression
from xgboost import XGBClassifier
from imblearn.under_sampling import NearMiss
from sklearn import tree
3 - Importando e atribuindo o dataset a uma variável:
# Use o Dropbox, Github ou até a importação
# direta do Colab para ter acesso aos dados
file_path = "https://www.dropbox.com/s/b44o3t3ehmnx2b7/creditcard.csv?dl=1"
df = pd.read_csv(file_path)
4 - Vamos verificar o tamanho do dataset e já vamos separar 15% dos dados para testes:
df.shape
# (284807, 31) quase 300k transações e 31 colunas
# separando 15% dos dados para os testes
test = df.sample(frac=0.15, random_state=0)
# removendo do dataset principal
# as transações selecionadas para teste
df = df.drop(test.index)
test.shape
# (42721, 31) cerca de 43k transações para testes
df.shape
# (242086, 31) agora cerca de 243k
# transações no dataset principal
5 - Apresentado as 5 primeiras entradas do dataset e o resumo estatístico:
# 5 primeiras entradas
df.head()
# Resumo estatístico
df.describe()
Conseguimos perceber que as colunas com o prefixo V estão anonimizadas, então são provavelmente referentes a informações sensíveis das transações. Porém as colunas de Time, Amount e Class estão presentes sem anonimização. Confira a descrição do dataset no Kaggle para ter mais informações sobre essas colunas.
6 - Verificando a porcentagem de valores ausentes:
percent_missing = df.isnull().sum() * 100 / len(df)
missing_values = pd.DataFrame({'Coluna': df.columns, '% de valores ausentes': percent_missing})
missing_values
Coisa boa!! nenhum valor ausente. Um passo a menos a realizar, pois caso a base estivesse com valores ausentes deveria ser analisado uma estratégia para preencher ou remover esses dados.
7 - Apresentando gráfico de barras da coluna de Class (que é a coluna que identifica se a transação é fraudulenta ou não):
sns.countplot(x="Class", data=df)
Conseguimos perceber que o dataset está bastante desbalanceado porquê a quantidade de fraudes é muitíssimo baixa em comparação com as transações verídicas. Existem bibliotecas de balanceamento com o SMOTE e NearMiss. Nesse cenário específico não consegui balancear o dataset usando o SMOTE. Mas obtive êxito ao balancear usando NearMiss que será aplicado mais a frente.
8 - Apresentando histogramas para as colunas de Time e Amount nos cenários de fraude (Class = 1) e não fraude (Class = 0):
# Histograma da variável Time no caso de não fraude
df.Time[df.Class == 0].hist(figsize=(10,5))
# Histograma da variável Time no caso de fraude
df.Time[df.Class == 1].hist(figsize=(10,5))
# Histograma da variável Amount no caso de não fraude
df.Amount[df.Class == 0].hist(figsize=(10,5))
# Histograma da variável Amount no caso de fraude
df.Amount[df.Class == 1].hist(figsize=(10,5))
- Histograma da variável Time no caso de não fraude
- Histograma da variável Time no caso de fraude
- Histograma da variável Amount no caso de não fraude
- Histograma da variável Amount no caso de fraude
Conseguimos perceber através desses gráficos que o valor das transações fraudulentas são valores baixos que possivelmente visam não levantar suspeita. Ademais, o intervalo entre a primeira transação e as transções fraudulentas são muitos menores em comparação dessa diferença com as transações verídicas.
9 - Apresentando gráfico de Box Plot para a variável Amount no caso de fraude:
fig = plt.figure(figsize=(10, 7))
plt.boxplot(df.Amount[df.Class == 1])
plt.show()
Também confirma que as transações fraudulentas se concentram em valores baixos.
10 - Removendo outliers da variável Amount (dados no intervalo do 3º quartil):
df = df.loc[(df['Amount'] < 1500)]
11- Apresentando Box Plot novamente sem os outliers da variável Amount:
12 - Apresentando Matriz de Correlação:
fig, ax = plt.subplots(figsize=(30, 20))
sns.heatmap(df.corr(), annot=True, linewidths=.3)
plt.show()
Percebe-se uma correlação muito baixa entre as variáveis nesse dataset em questão.
13 - Apresentando gráficos de densidade para as variáveis Amount e Time:
df['Amount'].plot(kind = 'density')
print(df['Time'].plot(kind = 'density'))
Vamos para classificação!!! Hora de testar o desempenho dos algoritmos.
14 - Preparando os dados para classificação:
X = test.drop('Class', axis=1)
y = test['Class']
#Balanceando os dados
nm = NearMiss()
X_res, y_res = nm.fit_resample(X,y)
X_train, X_validation, y_train, y_validation = train_test_split(X_res,y_res)
15 - Treinando os classificadores:
classifiers = [
["Logistic Regr.", LogisticRegression(max_iter=1000)],
["Decision Tree ", DecisionTreeClassifier(random_state=10)],
["Gaussian NB ", GaussianNB()],
["XG Boost ", XGBClassifier(n_estimators = 100, learning_rate = 0.05)]
]
for alg in classifiers:
alg[1].fit(X_train, y_train)
Y_pred = alg[1].predict(X_validation)
report = classification_report(y_validation, Y_pred)
print("{} - Report: \n{}".format(alg[0], report))
- Resultado dos algoritmos:
Considerações sobre os resultados:
Em uma primeira análise sem balancear os dados o XG Boost apresentou os melhores resultados em relação aos demais. Porém agora balanceando os dados com a biblioteca NearMiss todos os 4 algoritmos testados obtiveram resultados melhores e o Gaussian NB foi o melhor que o Xg Boost.
Segue o link do colab com o código completo: https://colab.research.google.com/drive/14gC9gg678_qgOwf0PtIItvDXOu_wVrF7?usp=sharing
No Colab existe um exemplo adicional demostrando graficamente como ficaria estruturada a árvore de decisão para os dados balanceados e não balanceados.
Feedbacks são bem-vindos. Obrigado e até mais!!!
Latest comments (0)