<jupyter_start><jupyter_text>**Bibliotecas**---<jupyter_code># Importação de todas as bibliotecas que serão utilizadas nesta etapa do notebook 
import pandas as pd
import numpy as np
from imblearn.over_sampling import SMOTE
from sklearn.model_selection import train_test_split

import spacy
from spacy.util import minibatch
import random

from sklearn.metrics import confusion_matrix
import matplotlib.pyplot as plt
import seaborn as sns<jupyter_output><empty_output><jupyter_text>**Aquisição de Dados**---<jupyter_code># Leitura dos dados que serão utilizados
df = pd.read_csv('../data/01_raw/products_dataset.csv') 
df.head()<jupyter_output><empty_output><jupyter_text>**Processando Dataset**---  Removendo valores nulos<jupyter_code># Salva em 'numericos' todos os nomes das colunas que não são do tipo object
numericos = df.select_dtypes(exclude='object').columns
numericos 
# Remove valores faltantes das variáveis que são só numéricas, substituindo por 0
df[numericos] = df[numericos].fillna(0)
# Salva em strings todos os nomes das colunas que são do tipo object 
strings = df.select_dtypes(include='object').columns
strings
# Remove valores faltantes das variáveis que não são numéricas e substitui por 0, como texto
df[strings] = df[strings].fillna('0')<jupyter_output><empty_output><jupyter_text>Separando em dados de treino e teste Antes da separação o dataset será ordenado pela data, assim as classificações serão feitas para os valores com a data mais atual. Com isso, será utilizado o parâmetro `shuffle` para que a divisão seja feita na ordem.<jupyter_code>df_ordenado = df.sort_values(by='creation_date', ignore_index=True)
df_ordenado.head(2)
# Divisão em treino e teste
label = df_ordenado["category"].copy()
feat_colunas = df_ordenado.columns.tolist()
feat_colunas.remove("category")
feats = df_ordenado[feat_colunas].copy()

X_train, X_test, y_train, y_test = train_test_split(feats, label, random_state=0, shuffle=False)
# Verifica o tamanho dos conjuntos de treino e teste
X_train.shape, X_test.shape, y_train.shape, y_test.shape
X_train.tail(2)
X_test.head(2)<jupyter_output><empty_output><jupyter_text>**Treinando o Modelo com NLP**--- Resolvemos usar o NLP para classificar o dataframe, pois gostaríamos de ver uma forma mais automática para classificação e ver como um IA se comportaria para classificar o dataframe, uma vez que o NLP é muito usado e recomendado para classificar palavras.<jupyter_code># Criando um modelo vazio em português
nlp = spacy.blank("pt")

# Criando um Categorizador de Texto com classe exclusiva e arquitetura "bow" 
textcat = nlp.create_pipe("textcat", config={"exclusive_classes": True, "architecture": "bow"})

# Adicioando o Categorizador de Texto para o modelo vazio
nlp.add_pipe(textcat)
# Exibição das categorias para colocar no TextCat, na célula abaixo
df.category.unique()
# Adicionando as Categorias nos Textcat que serão usados para categorizar os objetos
textcat.add_label("Lembrancinhas")
textcat.add_label("Decoração")
textcat.add_label("Bebê")
textcat.add_label("Papel e Cia")
textcat.add_label("Outros")
textcat.add_label("Bijuterias e Jóias")
# Criando o train text e o train label
train_texts = X_train['title'].values
train_labels = [{'cats': {'Lembrancinhas': label == 'Lembrancinhas',
                          'Decoração': label == 'Decoração',
                          'Bebê': label == 'Bebê',
                          'Papel e Cia': label == 'Papel e Cia',
                          'Outros': label == 'Outros',
                          'Bijuterias e Jóias': label == 'Bijuterias e Jóias'}} 
                for label in y_train]
# Criando o train_data e vendo como que o ML está classificando os train texts (data de treino)
train_data = list(zip(train_texts, train_labels))
train_data[:3]
# Configuramos as opções e otimizador para treinamento
spacy.util.fix_random_seed(1)
optimizer = nlp.begin_training()

# Criando o batch generator com batch size = 8
batches = minibatch(train_data, size=8)

# Fazendo iteração pelo minibatches
for batch in batches:
    # Cada batch é uma lista de (text, label) mas precisamos para
    # enviar listas separadas para texts e labels para atualizar().
    # Esse é um rápido modo de dividir a lista de tuplas em listas
    texts, labels = zip(*batch)
    nlp.update(texts, labels, sgd=optimizer)
# Configuramos as opções e otimizador para treinamento, realizando 10 épocas  
random.seed(0)
spacy.util.fix_random_seed(1)
optimizer = nlp.begin_training()

losses = {}
for epoch in range(10):
    random.shuffle(train_data)
    # Criando o batch generator com batch size = 8
    batches = minibatch(train_data, size=8)
    # Iteração pelo minibatches
    for batch in batches:
        # Cada batch é uma lista de (text, label) mas precisamos para
        # enviar listas separadas para texts e labels para update().
        # Esse é um rápido modo de dividir a lista de tuplas em listas
        texts, labels = zip(*batch)
        nlp.update(texts, labels, sgd=optimizer, losses=losses)
        
    print(losses)
# Separando os textos de teste e transformando em valores numéricos 
texts = X_test['title']
docs = [nlp.tokenizer(text) for text in texts]
    
# Usa o textcat para pegar os scores de cada doc
textcat = nlp.get_pipe('textcat')
scores, _ = textcat.predict(docs)

print(scores)
# Pelos scores, achou-se o label com os mais altos scores/probabilidades  
predicted_labels = scores.argmax(axis=1)
cat_prev = []
for label in predicted_labels: 
    cat_prev.append(textcat.labels[label])
cat_prev[:5]<jupyter_output><empty_output><jupyter_text>**Validando modelo**---<jupyter_code># Criando a Matriz de Confusão para verificar como ficou o treinamento do meu modelo
target_names = df.category.unique()
cm = confusion_matrix(y_test, cat_prev)

cmn = cm.astype('float') / cm.sum(axis=1)[:, np.newaxis]
fig, ax = plt.subplots(figsize=(6,6))
sns.heatmap(cmn, annot=True, fmt='.2f', xticklabels=target_names, yticklabels=target_names, square=True)
plt.ylabel('Atual')
plt.xlabel('Predito')
plt.show(block=False)<jupyter_output><empty_output>
{'fraction_non_alphanumeric': 0.09435829759155394, 'fraction_numerical': 0.004618937644341801, 'mean_word_length': 4.7414772727272725, 'pattern_counts': {'":': 2, '<': 25, '<?xml version=': 0, '>': 25, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'chain_length': '6', 'dir': 'jupyter-structured-clean-dedup', 'id': '233055', 'license': 'MIT', 'n_tokens_mistral': 2119, 'n_tokens_neox': 2087, 'n_words': 621, 'path': 'elo7/elo7_project/docs/Classification_parte2.ipynb', 'repo_name': 'Lucas-Buk/Data_Mining', 'size': '6062'}