Skip to content

Commit

Permalink
Merge pull request #2 from TailUFPB/nb-news-integration
Browse files Browse the repository at this point in the history
Nb news integration PR
  • Loading branch information
jonasgabriel18 authored Nov 3, 2023
2 parents a166897 + 22f060c commit 3f0d9ac
Show file tree
Hide file tree
Showing 8 changed files with 10,059 additions and 87 deletions.
9 changes: 7 additions & 2 deletions api/DataProcesser.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import pandas as pd
from NbNewsModel import NbNewsModel
from NbNewsModel import news_prediction
from NbEmotionsModel import make_prediction
from NbLinRegressionModel import make_prediction_nblin
import nltk
Expand All @@ -14,6 +14,7 @@ class DataProcesser():
input_column = ''
stopwordsenglish = nltk.corpus.stopwords.words('english')


def handle_classify(self, df, classifier):
if classifier == 'a':
return self.classify_emotions(df)
Expand Down Expand Up @@ -51,5 +52,9 @@ def lin_regression_model(self, df):
result_csv = df # converte o df pra csv
return result_csv

def nb_news_application(self):
self.df['coluna_classificada'] = self.df[self.input_column].apply(self.preprocess_text).apply(news_prediction)
result_csv = self.df
return result_csv

# TODO métodos com o processamento de classificação
##TODO métodos com o processamento de classificação
103 changes: 18 additions & 85 deletions api/NbNewsModel.py
Original file line number Diff line number Diff line change
@@ -1,86 +1,19 @@
import pandas as pd
import numpy as np
from sklearn.feature_extraction.text import CountVectorizer
from sklearn.feature_extraction.text import TfidfVectorizer
from sklearn.model_selection import train_test_split
from sklearn.naive_bayes import MultinomialNB
from sklearn.metrics import accuracy_score, classification_report
from sklearn.pipeline import make_pipeline
import seaborn as sns
import matplotlib.pyplot as plt
import nltk
import re
from collections import defaultdict
from nltk.tokenize import word_tokenize
nltk.download('punkt')
nltk.download('stopwords')

stopwords = nltk.corpus.stopwords.words('english')

class NbNewsModel():

def __init__(self, df):
self.df = df

def filter_and_classify(self):
# Encontrando a contagem de ocorrências de cada categoria
contagem_categorias = self.df['category'].value_counts()

# Criando uma lista das categorias que têm 500 ou mais ocorrências
categorias_com_500_ou_mais_ocorrencias = contagem_categorias[contagem_categorias >= 500].index.tolist()

# Filtrando o DataFrame original para incluir apenas as categorias com 500 ou mais ocorrências
self.df_filtrado = self.df[self.df['category'].isin(categorias_com_500_ou_mais_ocorrencias)]

# Agora, df_filtrado contém apenas as categorias com 500 ou mais ocorrências
# Aplicando o preprocessamento
self.df_filtrado['tokenizado'] = self.df_filtrado['short_description'].apply(self.tokenize)

# Inicializando um dicionário para contar as palavras por categoria
self.contagem_palavras_por_categoria = defaultdict(lambda: defaultdict(int))

# Iterando sobre cada linha do DataFrame e contando as palavras por categoria

for idx, row in self.df_filtrado.iterrows():
categoria = row['category']
lista_palavras = row['tokenizado']
for palavra in lista_palavras:
self.contagem_palavras_por_categoria[categoria][palavra] += 1

#self.contagem_palavras_por_categoria['STYLE']

self.num_palavras_por_categoria = defaultdict(int)
for idx, row in self.df_filtrado.iterrows():
categoria = row['category']
lista_palavras = row['tokenizado']
num_palavras = len(lista_palavras)
self.num_palavras_por_categoria[categoria] += num_palavras

self.df_filtrado['result'] = self.df_filtrado['short_description'].apply(self.classificando)
result = self.df_filtrado

return result

def tokenize(self, x):
texto = re.sub(r'\d+', '', x) #Removendo números
texto = re.sub(r'[^\w\s]', '', texto) #Removendo pontuação
tokens = word_tokenize(texto)
return [word for word in tokens if word not in stopwords] #Removendo stopwords

def classificando(self, frase):
proporcoes_por_categoria = {}
for categoria in self.contagem_palavras_por_categoria.keys():
resultado = 1.0 # Inicialize a resultado como 1.0
for palavra in frase:
probabilidade_categoria = self.num_palavras_por_categoria[categoria] / sum(self.num_palavras_por_categoria.values())# Probabilidade de ser da categoria
resultado *= probabilidade_categoria
# Verificando se a palavra está no dicionário de contagem de palavras por categoria
if palavra in self.contagem_palavras_por_categoria[categoria]:
resultado *= self.contagem_palavras_por_categoria[categoria][palavra] / self.num_palavras_por_categoria[categoria]
#Probabilidade da palavra dado que é dá categoria
else:
# Caso a palavra não esteja na categoria, você pode assumir um valor padrão (por exemplo, 1.0)
resultado *= 1/self.num_palavras_por_categoria[categoria] # Pode ajustar este valor conforme necessário
proporcoes_por_categoria[categoria] = resultado

return max(proporcoes_por_categoria, key=proporcoes_por_categoria.get)
import pickle

def news_prediction(texts):
model_file = "api/models/text_classification_pipeline.pkl"
try:
# Carregando o pipeline do arquivo .pkl
with open(model_file, 'rb') as model_file:
pipeline = pickle.load(model_file)

# Fazendo previsões para os textos
predictions = pipeline.predict(texts)

return predictions

except Exception as e:
return str(e)
# df = pd.read_csv("api/training_df/nb_news.csv")
# print(news_prediction(df['short_description']))
Binary file added api/__pycache__/DataProcesser.cpython-37.pyc
Binary file not shown.
Binary file added api/__pycache__/NbEmotionsModel.cpython-37.pyc
Binary file not shown.
Binary file added api/__pycache__/NbNewsModel.cpython-37.pyc
Binary file not shown.
25 changes: 25 additions & 0 deletions api/models/nb_news.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
import pandas as pd
import pickle
from sklearn.pipeline import make_pipeline
from sklearn.feature_extraction.text import CountVectorizer
from sklearn.feature_extraction.text import TfidfVectorizer
from sklearn.model_selection import train_test_split
from sklearn.naive_bayes import MultinomialNB

df = pd.read_csv("api/training_df/nb_news.csv")
# Dividindo os dados em um conjunto de treinamento e um conjunto de teste
x = df['short_description']
y = df['category']

X_train, X_test, y_train, y_test = train_test_split(x, y, test_size=0.2, random_state=42)
# Criando um pipeline que inclui o vetorizador TF-IDF e o modelo Naive Bayes

# Criando um pipeline com o vetorizador TF-IDF e o classificador Multinomial Naive Bayes
pipeline = make_pipeline(TfidfVectorizer(), MultinomialNB())

# Ajustando o modelo ao conjunto de treinamento
pipeline.fit(X_train, y_train)

# Salvando o pipeline em um arquivo .pkl
with open("text_classification_pipeline.pkl", "wb") as model_file:
pickle.dump(pipeline, model_file)
Binary file added api/models/text_classification_pipeline.pkl
Binary file not shown.
Loading

0 comments on commit 3f0d9ac

Please sign in to comment.