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 |