leonaascimento / great-meal

A sentiment analysis algorithm for restaurant reviews
MIT License
0 stars 0 forks source link

Usar o SentiWordNet para classificar opinões #2

Closed leonaascimento closed 5 years ago

leonaascimento commented 5 years ago

Apesar do artigo apresentar que o SentiWordNet apenas possui definição para unigramas, ainda não temos nem essa etapa pronta. Precisaríamos ter isto pronto para poder evoluir usando a estratégia com bigramas.

leonaascimento commented 5 years ago

Entendendo este artigo sobre análise de sentimentos é possível resolver esse problema e talvez o descito em #3 .

tsuzukayama commented 5 years ago

Neste artigo parece que ele usa um classificador com unigrama, um com bigrama, e um com os dois. A idéia seria construir o último? (unigrama + bigrama)

gmurayama commented 5 years ago

Depois de muito apanhar pro Python, consegui adaptar o que temos pra usar o sentiword de acordo com o artigo. Fiz um arquivo de teste dessa maneira:

import re

import nltk
import numpy as np
import pandas as pd
from nltk.corpus import stopwords
from nltk.corpus import sentiwordnet as swn
from nltk.corpus import wordnet as wn
from nltk.stem import WordNetLemmatizer
from sklearn.feature_extraction.text import CountVectorizer
from sklearn.metrics import accuracy_score, confusion_matrix
from sklearn.model_selection import train_test_split
from sklearn.naive_bayes import GaussianNB

dataset = pd.read_csv('assets/Restaurant_Reviews.tsv',
                      delimiter='\t', quoting=3)
dataset.head()

lemmatizer = WordNetLemmatizer()

def predict(new_review):
    new_review = re.sub('[^a-zA-Z]', ' ', new_review)
    new_review = new_review.lower().split()
    new_review = [lemmatizer.lemmatize(word) for word in new_review if word not in set(
        stopwords.words('english'))]

    tokens_count = 0
    sentiment = 0.0

    for word in new_review:
        synsets = wn.synsets(word)
        synset = synsets[0]
        swn_synset = swn.senti_synset(synset.name())
        sentiment += swn_synset.pos_score() - swn_synset.neg_score()
        tokens_count += 1

    if not tokens_count:
        return 0

    # sum greater than 0 => positive sentiment
    if sentiment >= 0:
        return 1

    # negative sentiment
    return 0

new_review = input('Add a review: ')
while new_review != '':
    feedback = predict(new_review)
    print('This review is: ', feedback)
    new_review = input('Add a review: ')

Ele está "funcionando", mas vou tentar implementar o restante do artigo com o bigrams e os mark_negation

gmurayama commented 5 years ago

No commit leonaascimento@ee02ebe0efb4ab035621a0af475be6750aee1e00 fiz uma implementação do sentiword de acordo com o artigo e obtive um resultado por volta de 60%