import pandas as pd
import re
from datetime import datetime
import string
from nltk.tokenize import word_tokenize
import nltk
import matplotlib.pyplot as plt
nltk.download('punkt')
nltk.download('stopwords')
stopwords = nltk.corpus.stopwords.words('portuguese')
[nltk_data] Downloading package punkt to /root/nltk_data... [nltk_data] Package punkt is already up-to-date! [nltk_data] Downloading package stopwords to /root/nltk_data... [nltk_data] Package stopwords is already up-to-date!
dados = pd.read_csv('/content/drive/MyDrive/DATA/pedidos-recursos-features-process.csv')
def clear_values_regex(df):
df = df.replace(r'\r\n\r\n',' ', regex=True)
df = df.replace(r'\r\n',' ', regex=True)
df = df.replace(r'\r \r',' ', regex=True)
return df
dados = clear_values_regex(dados)
dados['conteudo_resposta'] = dados['conteudo_resposta'].fillna('')
dados = dados[dados['atendimento_resposta'] != 'Não Classificado']
Essa função denominamos de padrão em NLP, algumas funções estabelecidas são:
Transformação para caracter minúsculos
Antes: Tiver problemas ao acessar o gov.br no dia 14/05/2016.
Depôs: tiver problemas ao acessar o gov.br no dia 14/05/2016.
Remoção de pontuação.
Antes: Tiver problemas ao acessar o gov.br no dia 14/05/2016.
Depôs: tiver problemas ao acessar o gov.br no dia 14/05/2016
Remoção de stopword.
Antes: Tiver problemas ao acessar o gov.br no dia 14/05/2016
Depôs: problemas acessar o gov.br dia 14/05/2016
Essas funções padrão são aplicadas com o intuito de reduzir algumas informações que não seriam necessária para o modelo.
def limpando_texto(mensagem):
# Diminuindo os caracteres
mensagem = mensagem.lower()
# remove pontuação
table = str.maketrans('', '', string.punctuation)
stripped = [palavra.translate(table) for palavra in mensagem.split()]
mensagem = ' '.join(stripped).strip()
# remove stopword
mensagem_tokens = word_tokenize(mensagem)
mensagem = [word for word in mensagem_tokens if not word in stopwords]
mensagem = " ".join(mensagem)
return mensagem
Após esse processo retomando o que sabemos em relação aos dados estava muito comum a presença de URL e Data nos pedidos, uma alternativa é padronizar no texto substituindo um URL pela tag SITE e uma data pela tag DATA isso ajuda ao modelo considerando que ambas as informações podem assumir infinitos valores, mas antes de definir essa atividade iremos observar a presenta dessas informações nos dados.
def get_site(mensagem):
regex_url = r"(?i)\b((?:https?://|www\d{0,3}[.]|[a-z0-9.\-]+[.][a-z]{2,4}/)(?:[^\s()<>]+|\(([^\s()<>]+|(\([^\s()<>]+\)))*\))+(?:\(([^\s()<>]+|(\([^\s()<>]+\)))*\)|[^\s`!()\[\]{};:'\".,<>?«»“”‘’]))"
busca = re.compile(regex_url)
condicional = busca.search(mensagem) != None
if condicional:
return 'sim'
else:
return 'não'
def get_data(mensagem):
regex_data = r'\d{2}.\d{2}.\d{4}'
busca = re.compile(regex_data)
condicional = busca.search(mensagem) != None
if condicional:
return 'sim'
else:
return 'não'
dados['url_pedido'] = dados['conteudo_pedido'].apply(get_site)
dados['url_resposta'] = dados['conteudo_resposta'].apply(get_site)
dados['data_pedido'] = dados['conteudo_pedido'].apply(get_data)
dados['data_resposta'] = dados['conteudo_resposta'].apply(get_data)
dados.groupby(['url_pedido', 'atendimento_resposta']).size().unstack(level=1).plot(kind = 'barh',
title='Distribuição de URL nos Pedidos',figsize=(12, 7))
<matplotlib.axes._subplots.AxesSubplot at 0x7f3639b080d0>
Observamos ser pouco o número de pedidos que possuem alguma (URL) de site para a solicitação.
dados.groupby(['url_resposta', 'atendimento_resposta']).size().unstack(level=1).plot(kind = 'barh',
title='Distribuição de URL nas Resposta',figsize=(12, 7))
<matplotlib.axes._subplots.AxesSubplot at 0x7f3639b09650>
Já para as respostas observamos que temos um aumento significativo de URL presentes.
dados.groupby(['data_pedido', 'atendimento_resposta']).size().unstack(level=1).plot(kind = 'barh',
title='Distribuição da presença de Data nos Pedidos',figsize=(12, 7))
<matplotlib.axes._subplots.AxesSubplot at 0x7f3639b3a790>
Datas está mais presente nos pedidos que as (URL).
dados.groupby(['data_resposta', 'atendimento_resposta']).size().unstack(level=1).plot(kind = 'barh',
title='Distribuição da presença de Data nas Respostas',figsize=(12, 7))
<matplotlib.axes._subplots.AxesSubplot at 0x7f3639586090>
Observamos um aumento significativo de presença de Data nas respostas dos órgãos.
Considerando as análises acima podemos considerar como uma tentativa a substituição de data e url por suas respectivas tags, portanto teríamos algo como:
Substituição de determinada URL pela tag SITE.
Antes: Tiver problemas ao acessar o gov.br no dia 14/05/2016
Depôs: problemas acessar o site dia 14/05/2016
Substituição de determinada data pela tag DATA.
Antes: Tiver problemas ao acessar o gov.br no dia 14/05/2016
Depôs: problemas acessar o site dia data
Portanto, nossa função de limpeza de texto preliminar fica sendo:
def limpando_texto(mensagem):
# Diminuindo os caracteres
mensagem = mensagem.lower()
# url
regex_url = r"(?i)\b((?:https?://|www\d{0,3}[.]|[a-z0-9.\-]+[.][a-z]{2,4}/)(?:[^\s()<>]+|\(([^\s()<>]+|(\([^\s()<>]+\)))*\))+(?:\(([^\s()<>]+|(\([^\s()<>]+\)))*\)|[^\s`!()\[\]{};:'\".,<>?«»“”‘’]))"
mensagem = re.sub(regex_url,'site',mensagem)
# data replace
mensagem = re.sub(r'\d{2}.\d{2}.\d{4}','data',mensagem)
# remove pontuação
table = str.maketrans('', '', string.punctuation)
stripped = [palavra.translate(table) for palavra in mensagem.split()]
mensagem = ' '.join(stripped).strip()
# remove stopword
mensagem_tokens = word_tokenize(mensagem)
mensagem = [word for word in mensagem_tokens if not word in stopwords]
mensagem = " ".join(mensagem)
return mensagem
Consideramos como função preliminar porque iremos analisar o comportamento dela em relação aos modelos gerados, portanto, podo ocorrer substituição.