A empresa Amazon deseja obter um sistema inteligente para processar os comentários de seus clientes sobre os seus produtos, podendo classificar tais comentários dentre as categorias: positivo ou negativo. Para isso ela disponibiliza três bases de dados com sentenças rotuladas.
Os dados estão organizados em sentença e rótulo, sendo 0 negativo e 1 positivo As bases são provenientes dos seguintes sites: imdb.com amazon.com yelp.com
In [20]:
import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
In [21]:
X_1 = pd.read_csv('amazon_cells_labelled.txt', sep="\t", usecols=[0], header=None)
Y_1 = pd.read_csv('amazon_cells_labelled.txt', sep="\t", usecols=[1], header=None)
X_2 = pd.read_csv('imdb_labelled.txt', sep="\t", usecols=[0], header=None)
Y_2 = pd.read_csv('imdb_labelled.txt', sep="\t", usecols=[1], header=None)
X_3 = pd.read_csv('yelp_labelled.txt', sep="\t", usecols=[0], header=None)
Y_3 = pd.read_csv('yelp_labelled.txt', sep="\t", usecols=[1], header=None)
X = np.concatenate((X_1.values[:,0], X_2.values[:,0]), axis=0)
Y = np.concatenate((Y_1.values[:,0], Y_2.values[:,0]), axis=0)
X = np.concatenate((X, X_3.values[:,0]), axis=0)
Y = np.concatenate((Y, Y_3.values[:,0]), axis=0)
In [22]:
# Treating Sentences
allSentences = []
charsSplit = "\\`*_{}[]()>#+-.!$,:&?"
charsRemove = ".,-_;\"\'"
for x in X :
for c in charsSplit:
x = x.replace(c, ' '+ c +' ')
for c in charsRemove:
x = x.replace(c, '')
allSentences.append(x.lower() )
In [23]:
allWords = []
for x in allSentences :
allWords.extend(x.split(" "))
allWords = list(set(allWords))
allWords.sort()
In [24]:
positiveCount = [0] * len(allWords)
negativeCount = [0] * len(allWords)
sentenceNumber = 0
for sentenceNumber, sentence in enumerate(allSentences) :
for word in sentence.split(" "):
wordIndex = allWords.index(word)
if (Y[sentenceNumber] == 1):
positiveCount[wordIndex] = positiveCount[wordIndex] + 1
else:
negativeCount[wordIndex] = negativeCount[wordIndex] + 1
allCount = np.array(positiveCount) + np.array(negativeCount)
probPositive = np.divide(positiveCount, allCount)
len(allWords)
allWordsFiltered = np.array(allWords)
len(allWordsFiltered)
index_to_remove = []
for index, prob in enumerate(probPositive):
if not((prob <= 0.48) or (prob >= 0.52)):
index_to_remove.append(index)
a = 1
allWordsFiltered = np.delete(allWordsFiltered, index_to_remove)
Cria-se um vetor para cada sentença utilizando o dicionário elaborado como base.
Este vetor dependerá das palavras contidas em cada uma das sentenças. Cada ocorrência de palavra acarretará em igualarmos o índice associado a 1 (testou-se também incrementando esse valor, mas não foi viável).
In [25]:
allWords = np.array(allWordsFiltered).tolist()
X = []
for x in allSentences :
sentenceV = [0] * len(allWords)
words = x.split(" ")
for w in words :
try:
index = allWords.index(w)
sentenceV[index] = 1 #sentenceV[index] + 1
except ValueError:
pass
X.append(sentenceV)
In [34]:
from sklearn.cross_validation import cross_val_score
cross_val_k = 10
from sklearn.naive_bayes import MultinomialNB
clf1 = MultinomialNB()
from sklearn.neighbors import KNeighborsClassifier
clf2 = KNeighborsClassifier(n_neighbors=5)
from sklearn.linear_model import LogisticRegression
clf3 = LogisticRegression(penalty='l2', C=1.0)
from sklearn.ensemble import VotingClassifier
eclf = VotingClassifier(estimators=[('mnb', clf1), ('knn', clf2), ('lr', clf3)], voting='soft', weights=[3,2,2])
accuracy = cross_val_score(eclf, X, Y, cv=cross_val_k, scoring='accuracy').mean()
print('Precisão: ', accuracy)
A melhor classificação obtida consistituiu de utilizar três classificadores para decidir o resultado. Isso foi feito a partir de um esquema de votação, em que cada um deles possui um peso na decisão. Foi usado portanto um método de Ensemble.
| Método | Peso |
|---|---|
| MultinomialNB | 3 |
| KNeighborsClassifier | 2 |
| LogisticRegression | 2 |
Precisão: 0.852974803574
Avaliando cada um desses métodos isoladamente, foram obtidos os seguintes resultados:
| Método | Precisão |
|---|---|
| MultinomialNB | 0.833680803593 |
| KNeighborsClassifier | 0.673224700191 |
| LogisticRegression | 0.828600463537 |