%matplotlib inline
import matplotlib.pyplot as plt
import pandas as pd
import seaborn as sns
import nltk
from nltk.corpus import stopwords 
from nltk.tokenize import RegexpTokenizer
from sklearn.model_selection import train_test_split
from sklearn.neural_network import MLPClassifier
from sklearn.metrics import classification_report,confusion_matrix
"""
# Carregando os dados
"""
df = pd.read_csv("../input/olist_classified_public_dataset.csv")
df.head(6)
"""
# Analise Exploratória dos dados
"""
#Quantidade de linhas e colunas do DataFrame
df.shape
# 3584 linhas e 34 colunas
"""
Primeiro vamos analisar as categorias dos produtos e retirar algumas estatisticas
"""
df["product_category_name"].describe()
#Todas as categorias de produtos
valueCategoria = df["product_category_name"].value_counts()
valueCategoria
print(valueCategoria[0:6])
print("Somatorio: %s" % valueCategoria[0:6].sum())
valueCategoria[0:6].sum()/valueCategoria.sum()
"""
Podemos notar que 10% das categorias são responsaveis por 46.24% da nossa base. Sendo elas:

* cama_mesa_banho
* moveis_decoracao
* beleza_saude
* esporte_lazer
* informatica_acessorios
* utilidades_domesticas
"""
MEAN = df["review_score"].mean()
print("Média da população %s" % MEAN)
std = df["review_score"].std()
print("Desvio Padrão da população: %s" % std)
"""
A média de score é 3.5228 e o desvio padrão é igual a 1.65, com isso em mente vamos analisar as principais categorias de produtos.
"""
df.groupby(['product_category_name'])["review_score"].describe().sort_values(['count'], ascending=False)
"""
Se analisarmos as seis primeiras categoria, podemos notar que a media de todos os dados (3.5228) não difere tanto da media por categoria, mas o desvio padrão esta um valor alto. Como essas categorias representam 46.24% da nossa base. Poderia ser feito um estudo mais aprofundado para tentar elevar a media dos scores e diminuir a variância (quadrado do desvio padrão). Diminuir essa variância seria importante, pois se o cliente não teve uma boa experiencia com compras online, ele pode não voltar a comprar na mesma.
"""
dfFiltrado = df[(df.product_category_name == "cama_mesa_banho") | 
                (df.product_category_name == "moveis_decoracao")|
                (df.product_category_name == "beleza_saude")|
                (df.product_category_name == "esporte_lazer")|
                (df.product_category_name == "informatica_acessorios")|
                (df.product_category_name == "utilidades_domesticas")]


dfFiltrado.groupby(['product_category_name'])["most_voted_class"].value_counts(normalize=True)
"""
Normalizando os nosso dados, podemos notar que proporcionalmente a categoria com o maior numero de clientes satisfeitos é beleza_saude, enquanto a categoria com maior proporção de clientes com problemas na entrega foi informatica_acessorios e a categoria com maior proporção de problemas de qualidade tambem foi informatica acessorios. Como informatica_acessorios é a categoria proporcionalmente com o maior numero de reclamação, caberia uma medida especifica para a mesma. Principalmente levando em conta que o mercado de informática tem uma grande volatilidade, então uma boa experiencia do cliente poderia ocasionar novas compras em um futuro próximo.
"""
"""
## Categoria: informatica_acessorios
"""
dfInformatica = df[df["product_category_name"] == "informatica_acessorios"]
dfInformatica.head(2)
## Pegando as categorias problemas_de_entrega e problemas_de_qualidade

dfInformatica[(dfInformatica["most_voted_class"] == "problemas_de_entrega") |
              (dfInformatica["most_voted_class"] == "problemas_de_qualidade")]["most_voted_subclass"].value_counts()
"""
O maior problema para a categoria de informática é o atrasado, uma solução seria uma melhoria do algoritmo de calculo do prazo de entrega ou a criação de alguns indicadores e medidas de prevenção, um exemplo seria um indicador que acompanha o rastreamento do pedido, quando o indicador notar que vai ocorrer um atraso, poderia levantar uma flag para que o operacional possa entrar em contato com o cliente, para explicar os motivos do atraso e contornar o problema da melhor maneira possível. 
"""
print(df[df["most_voted_class"]== "satisfeito_com_pedido"]["product_photos_qty"].describe())
print(dfInformatica[(dfInformatica["most_voted_class"] == "problemas_de_qualidade") | (dfInformatica["most_voted_class"] == "diferente_do_anunciado")]["product_photos_qty"].describe())
"""
Analisando o problema de qualidade e diferente do anunciado, podemos notar que esses produtos tem uma média de fotos (1.976744) no anunciante abaixo da média da classe "satisfeito_com_pedido"(2.217347), o que poderia ter alguma correlação, dado que com mais fotos, o cliente tem mais informação sobre o produto.
"""
"""
## Matriz de correlação
"""
df.corr()
df[["review_score", "product_photos_qty", "product_description_lenght", "order_products_value", "order_freight_value", "order_items_qty"]].corr()
"""
Fazendo algum testes de correlação, não obtivemos nenhuma correlação significativa.
"""
"""
# Most_voted_class

Analisaremos agora a categoria Most_voted_class, utilizando toda a nossa base de dados.
"""
# Classificações e suas frequencias
freqClass = df["most_voted_class"].value_counts()
freqClass
print("%s" % ((1983 / freqClass.sum())* 100))
print("%s" % ((950 / freqClass.sum())* 100))
print("%s" % ((480 / freqClass.sum())* 100))
"""
Podemos notar que na nossa base, a classe dominante é satisfeito_com_pedido, com 58.10%, seguido de problemas na entrega com 27.83% e por ultimo problemas de qualidade com 14.06%.
"""
## Plotando as frequencias
sns.barplot(freqClass.index, freqClass.values)
plt.show()
"""
## Subclass: problemas_de_qualidade
"""
# Criando um novo data frame apenas com os problemas de qualidade
dfQuali = df[df["most_voted_class"] == "problemas_de_qualidade"]
freqSubClassQual = dfQuali["most_voted_subclass"].value_counts()
freqSubClassQual
"""
Podemos notar um volume muito grande de problemas com o produto diferente do anunciado, algumas medidas podem ser tomadas, como uma melhor descrição do produto, utilização de videos para demonstrar o produto, entre outras.
"""
"""
### NLP da categoria Problemas_de_qualidade
"""
"""
Temos 480 reviews, vamos criar Bigramas para cada subcategoria
"""
plt.figure()
subcategorias = ["diferente_do_anunciado", "baixa_qualidade", "devolucao", "outro_pedido"]
for subcategoria in subcategorias:
    dfGenerico = dfQuali[dfQuali["most_voted_subclass"] == subcategoria]
    review = (" ".join(dfGenerico["review_comment_message"])).lower().replace("produtoq", "produto")
    review
    # Removendo a pontuação e Tokenizando o texto
    tokenizer = RegexpTokenizer(r'\w+')
    cleanText = tokenizer.tokenize(review)

    # Removendo as StopWords
    stopWords = stopwords.words('portuguese')
    stopWords.remove("não")
    filtered_words = [word for word in cleanText if word not in stopWords]

    # Criando Bigramas
    filtered_words = nltk.ngrams(filtered_words, 2)

    filtered_words

    freq = nltk.FreqDist(filtered_words)
    plt.figure(figsize=(10, 5))
    plt.title(subcategoria)
    freq.plot(30)
"""
Analisando o gráfico de bigramas, podemos notar que na categoria diferente_do_anunciado teve uma grande reclamação sobre a cor do produto que veio errado. Enquanto na categoria baixa_qualidade temos reclamação por causa da qualidade, ou afirmações como "o produto não é oque eu esperava" ou que "não vale o preço". A classe de devolução parece ter uma grande reclamação com a categoria roupas, como por exemplo o tamanho da camisa foi errada.
"""
"""
## Subclass: problemas_de_entrega
"""
# Criando um novo data frame apenas com os problemas de entrega
dfEntrega = df[df["most_voted_class"] == "problemas_de_entrega"]
freqSubClassEntre = dfEntrega["most_voted_subclass"].value_counts()
freqSubClassEntre
"""
Podemos notar que atraso foi a subcategoria que mais causou transtornos. Vamos analisar os estados que mais tiveram problemas com essa subcategoria.
"""
# Frequencia dos estados que mais tiveram problemas com a entrega
freqAtraso = dfEntrega[dfEntrega["most_voted_subclass"] == "atrasado"]["customer_state"].value_counts()
freqAtraso
print((134/freqAtraso.sum()) * 100)
print((108/freqAtraso.sum()) * 100)
print(((134/freqAtraso.sum()) * 100) + ((108/freqAtraso.sum()) * 100))
"""
O estado de São Paulo e Rio de Janeiro somam juntas 55% dos problemas atrasos, 30.87% e 23.88% respectativamente.
Como demonstrado na tabela abaixo, a cidade de São Paulo possui a maioria dos atrasos. Por se tratar de uma grande cidade, algumas outras medidas podem ser tomadas, alem das já debatidas nesta analise. Como por exemplo, uma parceria com outras empresas de transportes.
"""
# Cidades de São Paulo com o maior numero de atrasos
dfEntrega[dfEntrega["customer_state"] == "SP"]["customer_city"].value_counts()
"""
# Rede Neural
"""
"""
Vamos criar uma rede neural para tentar predizer o score do produto baseado no preço do produto e seu frete.
"""
X = df[["order_products_value", "order_freight_value"]]
y = df["review_score"]
# Separando a nossa base em validação e treinamento
X_train, X_test, y_train, y_test = train_test_split(X, y)
mlp = MLPClassifier(hidden_layer_sizes=(13),max_iter=5000)
mlp.fit(X_train,y_train)
MLPClassifier()
predictions = mlp.predict(X_test)
# Criando a matriz de confusão
print(confusion_matrix(y_test,predictions))
print(classification_report(y_test,predictions))
"""
Como o esperado, a nossa precisão foi de apenas, 0.35. Isso ocorreu pois não houve um tratamento das variáveis, uma escolha dos melhores parâmetros de teste e uma otimização dos parâmetros da rede neural.
O objetivo maior era demonstrar que podemos criar um modelo de predição baseado na nossa base, que com um pouco de trabalho, pode dar ótimos resultados.
"""
"""
# Conclusão
"""
"""
O objetivo desta analise é demonstrar algumas possibilidades de trabalhos mais estruturados que podem ser feitos com a utilização desta base, como a utilização de outras abordagens do NLP (Neuro-Linguistic Programming), testes estatísticos e criação de modelos preditivos.
"""