<jupyter_start><jupyter_text>EspecificaçãoO objetivo deste projeto é construir um classificador de Spam usando o algoritmo de classificação Naive Bayes. O modelo de documento que usaremos aqui é um modelo de saco de palavras(bag of words). Usaremos o modelo bag of words:- Com base na frequência de palavras (frequência de ocorrência de palavra no documento, o que tornará os atributos de entrada contínuos)  Modelo Bag of WordsUm saco de palavras (bag of words) é uma representação de um texto como um agrupamento de palavras, sem qualquer consideração da sua estrutura gramatical ou da ordem das palavras. É simplesmente um histograma sobre as palavras da língua, e cada documento é representado como um vetor sobre estas palavras. As entradas neste vetor simplesmente correspondem à presença ou à ausência da palavra correspondente. A seguir criaremos uma função para ler o conjunto de dados, verificar a frequência de palavras e então ajustar o modelo.<jupyter_code>#Importando as bibliotecas
import os
import warnings
import numpy as np
import pandas as pd
import seaborn as sns
import matplotlib.pyplot as plt
from sklearn.metrics import confusion_matrix
from sklearn.naive_bayes import MultinomialNB
from sklearn.model_selection import cross_val_score
from sklearn.model_selection import train_test_split
from sklearn.feature_extraction.text import CountVectorizer
from sklearn.metrics import accuracy_score, precision_score
sns.set()
warnings.filterwarnings('ignore')<jupyter_output><empty_output><jupyter_text>Exemplo simples.<jupyter_code>#Cria uma matix cujas linhas são frases, alocadas em uma única coluna
documents = ['Hello, how are you!',
             'Win money, win from home.',
             'Call me now.',
             'Hello, Call hello you tomorrow?']<jupyter_output><empty_output><jupyter_text>Para obter a frequência de cada palavra em cada frase (linha), será utilizado a função CountVectorizer() do scikit learning.<jupyter_code>count_vector = CountVectorizer() #set the variable

count_vector.fit(documents) #fit the function
count_vector.get_feature_names() #get the outputs
doc_array = count_vector.transform(documents).toarray()
doc_array
frequency_matrix = pd.DataFrame(doc_array,
                                columns = count_vector.get_feature_names()
                               )
frequency_matrix<jupyter_output><empty_output><jupyter_text>PART 1: DATA PREPROCESSING  Preparando o conjunto de dados Temos que definir onde estão os diretórios do conjunto de treino e teste. Em seguida temos que ler todos os e mails e armazená-los em uma lista, será armazenado também em outra lista o valor do e mail (spam ou notspam) e senpertence ao conjunto de trino ou de teste.<jupyter_code>files_path='Dados\\train' # Local onde se encontram os dados
traintest=[]
documents=[]
my_label=[]
dirs = os.listdir(files_path)
for class_dir_name in dirs:
    print ("Processando datasset de teino {}. Aguarde...".format(class_dir_name))
    for f in os.listdir(os.path.join(files_path, class_dir_name)):
        document = os.path.join(files_path, class_dir_name, f)
        with open(document, 'r', encoding = "latin1") as file:
            words = file.read()
#             .split()
            documents.append(words)
            my_label.append(class_dir_name)
            traintest.append('train')
print ("O processo foi finalizado com sucesso ...")
files_path='Dados\\test' # Local onde se encontram os dados
dirs = os.listdir(files_path)
for class_dir_name in dirs:
    print ("Processando {}. Seja paciente e aguarde...".format(class_dir_name))
    for f in os.listdir(os.path.join(files_path, class_dir_name)):
        document = os.path.join(files_path, class_dir_name, f)
        with open(document, 'r', encoding = "latin1") as file:
            words = file.read()
#             .split()
            documents.append(words)
            my_label.append(class_dir_name)
            traintest.append('test')
print ("O processo foi finalizado com sucesso ...")<jupyter_output>Processando notspam. Seja paciente e aguarde...
Processando spam. Seja paciente e aguarde...
O processo foi finalizado com sucesso ...<jupyter_text>A seguir será criado um dataframe contendo a classificação na primera colulna e o e-mail na segunda. Iremos também substituir as strings notspam e spam por 0 e 1 respectivamente<jupyter_code>Dict = {'Dividir':traintest,'labels': my_label, 'mensagem': documents} 
df=pd.DataFrame(Dict)
df['labels'] = df.labels.map({'notspam':0, 'spam':1})
df.head()<jupyter_output><empty_output><jupyter_text>Preparando os dados com a função CountVectorizer<jupyter_code>count_vector = CountVectorizer() #set the variable
dataset_transformado = count_vector.fit_transform(documents)<jupyter_output><empty_output><jupyter_text>Dividindo o datasset em trinamento e teste.<jupyter_code># indices do datassest de traino e de teste
slice_indices=np.arange(df.shape[0])
slice_train=slice_indices[df.Dividir=='train']
slice_test=slice_indices[df.Dividir=='test']
X_train=dataset_transformado[slice_train,:]
X_test=dataset_transformado[slice_test,:]
y_train=df.labels[df.Dividir=='train']
y_test=df.labels[df.Dividir=='test']<jupyter_output><empty_output><jupyter_text>PART 2: AJUSTANDO O MODELO<jupyter_code>naive_bayes = MultinomialNB() #call the method
naive_bayes.fit(X_train, y_train) #train the classifier on the training set
predictions = naive_bayes.predict(X_train) #predic using the model on the testing set
print('accuracy score: {}'.format(accuracy_score(y_train,predictions)))
print('precision score: {}'.format(precision_score(y_train,predictions)))<jupyter_output>accuracy score: 0.9875283446712018
precision score: 0.9983122362869198<jupyter_text>PART 3: AVALIANDO O MODELO Para avaliar o modelo utilizaremos uma Validação cruzada k-Fold.<jupyter_code># Aplicando validação cruzada de 5 folds
mnb = MultinomialNB()
scores = cross_val_score(mnb, X_train, y_train, cv = 5, scoring='accuracy')

print('Cross-validation scores:{}'.format(scores))
cross_val_score?
# computar Pontuação média de validação cruzada

print('Pontuação média de validação cruzada: {:.4f}'.format(scores.mean()))<jupyter_output>Pontuação média de validação cruzada: 0.9377<jupyter_text>PART 4: FAZENDO PREVISÕES Com o modelo ajustado, é necessário testar sua capacidade de predizer valores de mensagens que ele ainda não tenha visto. Assim, ireos carregar o arquivo de teste e utilizar o modelo ajustado para predizer os valores dos e-mails. E então comparar com seu real valor.  Predizendo os valores dos dados de teste.<jupyter_code>predictions = naive_bayes.predict(X_test) #predic using the model on the testing set
print('accuracy score: {}'.format(accuracy_score(y_test,predictions)))
print('precision score: {}'.format(precision_score(y_test,predictions)))
#confusion_matrix
cnf_matrix = confusion_matrix(y_test,predictions)
p = sns.heatmap(pd.DataFrame(cnf_matrix), annot=True, cmap="YlGnBu" ,fmt='g',yticklabels=['notspam','spam'],xticklabels=['notspam','spam'])
plt.title('Confusion matrix', y=1.1)
plt.ylabel('True label')
plt.xlabel('Predicted label')
p=sns.heatmap(cnf_matrix/np.sum(cnf_matrix), annot=True, fmt='.2%', cmap="YlGnBu" ,yticklabels=['notspam','spam'],xticklabels=['notspam','spam'])
plt.title('Confusion matrix', y=1.1)
plt.ylabel('True label')
plt.xlabel('Predicted label')<jupyter_output><empty_output>
{'fraction_non_alphanumeric': 0.09485574305933588, 'fraction_numerical': 0.007893304300489928, 'mean_word_length': 5.446491228070175, 'pattern_counts': {'":': 0, '<': 38, '<?xml version=': 0, '>': 38, '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': '10', 'dir': 'jupyter-structured-clean-dedup', 'id': '429852', 'license': 'MIT', 'n_tokens_mistral': 2532, 'n_tokens_neox': 2442, 'n_words': 694, 'path': '.ipynb_checkpoints/Classificador_Completo-checkpoint.ipynb', 'repo_name': 'Cristiano2132/ClassificadorSpamNaiveBayes', 'size': '7348'}