As sequências são melhores que o original?

May 09 2023
Por: Justin Cheigh e Daisuke Yamada Resumo: Neste artigo procuramos responder à questão de saber se as sequências são melhores que o original. Para fazer isso, realizamos análises de sentimento em resenhas de determinadas séries de filmes.

Por: Justin Cheigh e Daisuke Yamada

Resumo: Neste artigo buscamos responder a questão de saber se as sequências são melhores que o original. Para fazer isso, realizamos análises de sentimento em resenhas de determinadas séries de filmes. Embora tenhamos treinado em um conjunto de dados kaggle contendo 50.000 resenhas de filmes, também coletaremos resenhas de filmes do IMDb usando a biblioteca de selênio do Python . Confira nosso repositório do GitHub e obrigado pela leitura!

Uma série que veremos

Motivação

Você já se perguntou se as sequências são realmente melhores que o original? Sim… todos nós já estivemos lá. Na verdade, a resposta a essa pergunta secular nos perseguiu por toda a minha vida. Nós vasculhamos e vasculhamos em busca de respostas. A teoria padrão do cinema não dava respostas concretas. A linguística e a teoria literária não se encaixavam direito. A filosofia apenas aumentou a confusão. Então, recorremos ao último recurso possível: ciência de dados. Depois de uma rápida maratona de Kung Fu Panda, começamos a trabalhar.

Nosso plano era treinar um modelo de análise de sentimento usando dados rotulados. Com este modelo pudemos determinar o sentimento das resenhas de filmes de diferentes séries. A partir daqui poderíamos desenvolver algumas heurísticas para medir a popularidade de cada filme, permitindo-nos comparar as sequências e o original.

Raspagem de dados e pré-processamento

Para começar, precisávamos de dados. Encontramos um conjunto de dados IMDb no kaggle contendo 50.000 resenhas de filmes, cada uma rotulada como positiva ou negativa . Esse conjunto de dados era perfeito para treinar um modelo de análise de sentimento binário, mas também precisávamos de dados sobre resenhas de filmes de várias séries.

Escolhemos trabalhar com 4 séries diferentes: Harry Potter, Star Wars, Kung Fu Panda e Carros. Depois de encontrar críticas/classificações de filmes no IMDb para cada filme de cada série, extraímos os dados usando o selênio. Salvamos esses dados como uma pasta de arquivos CSV (/reviews/original), cada um contendo (pelo menos) resenhas de filmes e classificações por estrelas associadas. Daqui em diante, nos referiremos a essas classificações por estrelas como classificações críticas ou apenas classificações.

Ao contrário de nosso conjunto de dados de treinamento, que tinha valores de sentimento rotulados ( sentimento positivo ou negativo ), essas avaliações tinham classificações reais determinadas pelo crítico ( 1–10 , sendo 1 o pior e 10 o melhor). Reconheceremos essa discrepância durante nossa análise mais adiante.

Exemplo de dados copiados - Kung Fu Panda 2

Modelo de Análise de Sentimento

Depois disso, partimos para treinar nosso modelo de análise de sentimento. A primeira etapa é codificar a revisão em algum vetor numérico. O método ingênuo é simplesmente codificar as palavras. No entanto, isso leva a um enorme vetor de entrada que carece de qualquer compreensão semântica das palavras (por exemplo, trata EUA e América como completamente diferentes).

Assim, optamos por usar uma camada de incorporação de palavras. As incorporações de palavras representam palavras como vetores numéricos de uma forma que leva em consideração a similaridade semântica . Por exemplo, sinônimos podem estar “próximos” um do outro no espaço vetorial, e você também pode aprender relações semânticas como a seguir:

Exemplo de benefício de incorporações do Word (de developers.google.com)

Especificamente, usamos uma incorporação de palavra GloVe pré-treinada para definir uma camada de incorporação em nosso modelo. Depois de definir essa camada de incorporação, passamos a definir nosso modelo. Para nosso modelo subjacente, optamos por usar um LSTM bidirecional (Long Short-Term Memory). LSTMs são um tipo de rede neural recorrente (RNN) projetada para lidar com dependências de longo prazo.

Em RNNs tradicionais, geralmente obtemos o problema do gradiente desaparecendo (ou explodindo), pois exigimos retropropagação ao longo do tempo . Os LSTMs corrigem isso tendo uma célula de memória que pode controlar o fluxo de informações. Ou seja, existem 3 portões: o portão de entrada (novas informações entrando na célula), o portão de esquecimento (quanta informação da célula atual é esquecida) e o portão de saída (quanto do estado da célula é usado para produzir a saída do LSTM ). Esses portões, representados por ativações sigmoides, permitem dependências de longo prazo. Abaixo você pode ver a arquitetura de um LSTM:

Arquitetura LSTM

Um LSTM bidirecional se baseia nessa estrutura usando 2 LSTMs, permitindo o fluxo de informações em ambas as direções. Em outras palavras, LSTM preservam informações apenas do passado, mas LSTMs bidirecionais preservam informações do passado e do futuro. Isso permite que a rede tenha um contexto de palavras ao redor, e uma imagem de sua arquitetura é mostrada abaixo:

Arquitetura LSTM Bidirecional

Implementamos nosso LSTM bidirecional da seguinte forma:

# define pre-trained embedding layer
pre_emb = Embedding(
  input_dim=len(word_index)+1, 
  output_dim=seqlen, 
  weights=[embedding_matrix], # from GloVe embedding
  input_length=seqlen, 
  trainable=True
  )

with tf.device(device):
    # define bidirectional LSTM
    model = Sequential([
        pre_emb, # embedding layer
        Bidirectional(LSTM(128, return_sequences=True)), 
        Dropout(0.2),
        Bidirectional(LSTM(64)),
        Dropout(0.2),
        Dense(128, activation='relu'),
        Dropout(0.2),
        Dense(1, activation="sigmoid") # binary classification
    ])

    # compile
    model.compile(
        loss=BinaryCrossentropy(from_logits=True),
        optimizer='adam',
        metrics=['accuracy']
    )

Depois de treinado, esse modelo obteve 86,9% de precisão no conjunto de teste, em comparação com uma linha de base de 50%! Agora que temos esse modelo treinado, podemos usá-lo nas resenhas de filmes copiadas. Então pegamos nossos arquivos CSV copiados e adicionamos uma coluna “Sentiment” , que continha 0 (negativo) ou 1 (positivo) com base na previsão de sentimento do nosso modelo sobre a avaliação. Esses arquivos CSV foram salvos em /reviews/annotated.

Resultados e Análise

Ótimo! Portanto, para cada crítica de cada filme em cada série, temos duas informações: a previsão de sentimento do nosso modelo (0 ou 1) e a avaliação real dos críticos (1–10). Vamos definir alguma notação. Corrija uma revisão r . Seja M(r) a previsão de sentimento binário do nosso modelo para a resenha e C(r) a avaliação real da crítica do filme ao qual a resenha pertence.

Qual é a relação entre M(r) e C(r) ? Bem, resenhas com boas avaliações devem intuitivamente ter um sentimento positivo, o que implica que queremos uma correlação positiva entre M(r) e C(r). De fato, o caso ideal absoluto é a seguinte relação (assumindo que C(r) reflita o nível absoluto ou objetivo de satisfação):

Caso Ideal para Relação M(r)/C(r)

Então, qual é a relação real?

Relação entre M(r) e C(r)

Vamos quebrar essas parcelas. Cada coluna representa um filme de alguma série. Trabalharemos com a coluna mais à esquerda, representando o primeiro filme de Harry Potter, como exemplo. Seja R o conjunto de críticas raspadas para este filme. Então podemos interpretar o enredo da seguinte forma:

  • O número superior (7,7) é a avaliação crítica média; significa formalmente (C(R)).
  • O número em vermelho é a classificação crítica média para revisões que nosso modelo previu como positivas; formalmente significa({C(r) | r em R e M(r) = 1}).
  • O número em azul é a classificação crítica média para revisões que nosso modelo previu como negativas; significa formalmente ({C(r) | r em R e M(r) = 0}).

Depois de ver isso, decidimos explorar mais a distribuição de C(r) agrupada por M(r). Obtemos as seguintes parcelas:

Distribuição de M(r) dado C(r) para Star Wars/Harry Potter

Por exemplo, o enredo Positivo de Harry Potter mostra a distribuição de classificações críticas para resenhas de filmes de Harry Potter que nosso modelo classificou como contendo sentimento positivo. Como esperaríamos ou esperamos que esses enredos se pareçam? Voltemos à nossa equação ideal para a relação entre M(r) e C(r). Esperamos que as parcelas Positivas tenham apenas avaliações com classificação > 5, enquanto as parcelas Negativas tenham apenas avaliações com classificação ≤ 5.

No mínimo, desejaríamos algum aumento no número de avaliações à medida que a classificação aumenta para Positivo e vice-versa para Negativo. Isso parece verdadeiro para os gráficos Positivos, indicando que nosso modelo pode classificar bem as avaliações avaliadas positivamente. No entanto, isso não é verdade para Negativo; nosso modelo não consegue classificar bem as avaliações negativas.

Isso é curioso. Uma possível explicação é que as críticas positivas são mais explícitas; eles dizem coisas como “Este filme foi ótimo!”. Por outro lado, as avaliações negativas podem ser um pouco mais difíceis de decifrar. Considere a seguinte crítica (falsa): “Embora alguns possam adorar o CGI e as animações deste filme, eu não era fã”. Este é um caso extremamente difícil para uma rede neural. Existem palavras como “amor” ou “fã” que são comumente associadas a sentimentos positivos, mas é preciso entender verdadeiramente o contexto para saber que esta é uma crítica negativa.

Esta é apenas uma hipótese potencial. Para ter uma ideia melhor, criamos nuvens de palavras para cada filme ao agrupar por sentimento positivo/negativo:

Wordclouds for Harry Potter Reviews (esquerda é Positivo, direita é Negativo)

Notamos algumas coisas importantes aqui. A primeira é que palavras muito previsíveis como “Harry Potter”, “livro”, “filme”, “cena”, “filme” e muito mais são muito prevalentes. Uma razão específica é que nossa incorporação GloVe usou um corpus fixo. Pode ter sido benéfico usar uma camada de incorporação de palavras específica para nosso corpus específico. Embora tenhamos tentado explicar isso tornando a camada de incorporação treinável, talvez também pudéssemos ter tentado um método diferente, diferente do GloVe.

Também vemos palavras como “bom” nas nuvens de palavras positivas e negativas, o que reafirma nosso problema com a classificação de críticas negativas. Ótimo! Agora que fizemos algumas visualizações de dados e entendemos melhor nosso conjunto de dados, queremos definir uma heurística H(m) que recebe um filme de entrada m e gera um valor proporcional ao quanto as pessoas gostam do filme.

Heurística e Análise Adicional

Queríamos que H(m) considerasse tanto a previsão de nosso modelo quanto a avaliação crítica real. Definimos H(m) como segue:

Primeiro ponderamos o número de avaliações positivas pela avaliação crítica média das avaliações positivas. Em seguida, pegamos isso e subtraímos o número de avaliações negativas ponderadas pela avaliação crítica média das avaliações negativas. Essa é uma boa heurística, mas precisamos lembrar que nosso modelo não é o melhor para classificar avaliações negativas. Assim, não nos importamos com a classificação média das críticas negativas, o que reduz nossa heurística ao seguinte:

Então, usando essa heurística, quais são nossos resultados? Para cada uma das quatro séries decidimos criar dois enredos. A primeira é a avaliação crítica média vs. movie , e a segunda é nossa heurística vs. movie:

Tramas de Harry Potter
Planos de Guerra nas Estrelas
Planos de Kung Fu Panda
Loteamentos de Carros

Observe que, ao agrupar por série, o gráfico de classificação média não muda muito , indicando que todos os filmes em cada série são vistos aproximadamente em um nível semelhante pelos críticos. Isso pode ser apenas um indicativo dos indivíduos que realmente postam avaliações neste site e sua disposição de dar pontuações diferentes.

O enredo certo parece bastante aleatório para cada série. Observe que o número real no eixo y é bastante irrelevante, pois a classificação relativa é realmente o que importa. Não há nenhuma tendência óbvia em H(m) aumentando ou diminuindo à medida que a série progride. Parece que os originais tendem a ser um pouco mais populares do que a sequência , embora haja definitivamente exceções a isso (Guerra nas Estrelas).

Outra observação interessante é que, além de Harry Potter, o filme final é o menos ou o mais popular de acordo com nossa heurística. Isso intuitivamente faz sentido, já que a série interrompe a produção devido à falta de popularidade ou termina com uma nota alta. Além disso, isso não se aplica a Harry Potter, pois eles acabaram quando os livros terminaram.

Conclusão e trabalho futuro

Ótimo! Não encontramos tendências definitivas sobre as sequências serem piores ou melhores que os originais, mas tivemos a chance de mergulhar nesse assunto. Conseguimos usar adequadamente as incorporações de palavras GloVe e implementar um LSTM bidirecional. Além disso, fomos capazes de coletar dados com sucesso e produzir algumas análises.

No futuro, provavelmente exploraríamos modelos NLP mais complicados, como transformadores. No entanto, nosso maior problema era definir uma boa heurística H(m). É difícil determinar com certeza se nossa heurística foi boa ou não, mas há razões para sugerir que ela pode estar falhando.

Por exemplo, suponha que a_p seja constante nos filmes de algumas séries. Vimos em nossos gráficos que essa não é uma grande suposição. Então nossa heurística se reduz a H(m) = C * r_p -r_n , onde C = a_p é constante. Isso significa que as críticas mal são consideradas em nossa heurística, o que é problemático, pois já sabemos que nosso modelo não é o melhor para classificar críticas negativas.

Apesar desses contratempos, este foi, no geral, um projeto muito divertido! Obrigado por ler!