Qualificação da interação dos clientes por meio das redes sociais - Análise Produto vs Marca

Qualificação da interação dos clientes por meio das redes sociais - Análise Produto vs Marca

Este notebook trata-se de uma análise simples para classificação de texto, onde o objetivo é tentar diferenciar tópicos relacionados a produtos do banco com tópicos relacionados a marca somente utilizando dados do tweeter.

import pandas as pd
import numpy as np
import re
import string
import unidecode
import nltk
import os

data = pd.read_csv("produto_marca_classificado.txt", sep='\t')
print(data.shape)
print(data.columns)
(1640, 2)
Index(['conteudo', 'CLASSIFICAÇÃO'], dtype='object')

Vamos normalizar o conteúdo dos tweets e a categoria.

data = data.applymap(lambda x: x.lower())

Vamos retirar os tweets classificados como inconclusivos e deixar somente aqueles com classificação Produto e Marca.

train_data = data[data.CLASSIFICAÇÃO!='inconclusivo']
print("Shape: {}".format(train_data.shape))
(train_data['CLASSIFICAÇÃO'].value_counts()/train_data['CLASSIFICAÇÃO'].count())*100
Shape: (973, 2)





marca      65.981501
produto    34.018499
Name: CLASSIFICAÇÃO, dtype: float64

Nos sobraram então 973 tweets relacionados ao problema, sendo que temos uma proporção 65% para marca, e 34% para produto. Sendo que este será então nosso baseline.

X = train_data['conteudo']
y = train_data['CLASSIFICAÇÃO']

from sklearn.model_selection import train_test_split

X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.33)
X_train.shape, X_test.shape
((651,), (322,))
from capstone import preprocess_text

raw_train = preprocess_text(X_train)
raw_test = preprocess_text(X_test)
base_treino = pd.concat([raw_train, y_train], axis = 1).reset_index()
base_teste = pd.concat([raw_test, y_test], axis = 1).reset_index()
base_treino.to_csv('base_treino.csv', encoding = 'utf-8', index=False)
base_teste.to_csv('base_teste.csv', encoding = 'utf-8', index=False)
from sklearn.feature_extraction.text import TfidfVectorizer

tfidf_model = TfidfVectorizer().fit(raw_train.values.astype('U'))
X = tfidf_model.transform(raw_train.values.astype('U'))
y = train_data['CLASSIFICAÇÃO'].apply(lambda x: str(x))
C:\Users\VictorVT\Anaconda3\lib\site-packages\sklearn\feature_extraction\text.py:1059: FutureWarning: Conversion of the second argument of issubdtype from `float` to `np.floating` is deprecated. In future, it will be treated as `np.float64 == np.dtype(float).type`.
  if hasattr(X, 'dtype') and np.issubdtype(X.dtype, np.float):
print(X.shape,y.shape)
(973, 2013) (973,)

Vamos separar 30% dos dados para teste.

Por fim, salvamos o conteúdo para aplicarmos os modelos.

base_treino = pd.concat([X_train, y_train], axis = 1).reset_index()
base_teste = pd.concat([X_test, y_test], axis = 1).reset_index()
base_treino.to_csv('train_data.csv', encoding = 'utf-8', index=False)
base_teste.to_csv('test_data.csv', encoding = 'utf-8', index=False)
---------------------------------------------------------------------------

TypeError                                 Traceback (most recent call last)

<ipython-input-23-04058a053cf0> in <module>()
----> 1 base_treino = pd.concat([X_train, y_train], axis = 1).reset_index()
      2 base_teste = pd.concat([X_test, y_test], axis = 1).reset_index()
      3 base_treino.to_csv('train_data.csv', encoding = 'utf-8', index=False)
      4 base_teste.to_csv('test_data.csv', encoding = 'utf-8', index=False)


C:\Users\VictorVT\Anaconda3\lib\site-packages\pandas\tools\merge.py in concat(objs, axis, join, join_axes, ignore_index, keys, levels, names, verify_integrity, copy)
   1449                        keys=keys, levels=levels, names=names,
   1450                        verify_integrity=verify_integrity,
-> 1451                        copy=copy)
   1452     return op.get_result()
   1453 


C:\Users\VictorVT\Anaconda3\lib\site-packages\pandas\tools\merge.py in __init__(self, objs, axis, join, join_axes, keys, levels, names, ignore_index, verify_integrity, copy)
   1506         for obj in objs:
   1507             if not isinstance(obj, NDFrame):
-> 1508                 raise TypeError("cannot concatenate a non-NDFrame object")
   1509 
   1510             # consolidate


TypeError: cannot concatenate a non-NDFrame object
from sklearn.naive_bayes import MultinomialNB
clf = MultinomialNB()
clf.fit(X_train, y_train)
# Here, alpha is the Laplacian Smoothing
y_pred = clf.predict(X_test)
from sklearn.metrics import precision_recall_fscore_support, accuracy_score
def scores(y_true, y_pred):
    avg_train_scores = precision_recall_fscore_support(y_true, y_pred, 
                                average = 'macro', 
                                labels = ['produto', 'marca'])
    return pd.DataFrame(list(avg_train_scores), 
             columns = ['scores'],
             index = ['precision', 'recall', 'fscore', 'distribution'])
scores(y_test, y_pred)
scores
precision 0.790244
recall 0.638695
fscore 0.654655
distribution NaN

Vamos aplicar o modelo diversas vezes e calcular a média e o desvio padrão dos scores, importante para sabermos o quando o modelo varia dependendo de como ocorre o split no database.

from sklearn.model_selection import cross_val_score

clf = MultinomialNB()
scores = cross_val_score(clf, X, y, cv = 3) # calcula a acurácia em 5 splits diferentes
pd.DataFrame({'acuracia':scores})
acuracia
0 0.686154
1 0.753086
2 0.746914
scores_ = precision_recall_fscore_support(y_test, y_pred, 
                                average = None, 
                                labels = ['marca', 'produto'])

pd.DataFrame(list(scores_), 
             columns = ['marca', 'produto'],
             index = ['precision', 'recall', 'fscore', 'distribution'])
marca produto
precision 0.780488 0.800000
recall 0.969697 0.307692
fscore 0.864865 0.444444
distribution 231.000000 91.000000