Librerías

library(tidyverse)   # Manipulación de datos
library(syuzhet)     # Análisis de sentimientos y emociones
library(tm)          # Minería de texto
library(wordcloud)   # Nube de palabras

Carga y Preparación de Datos

datos <- read.csv("movie_reviews.csv", stringsAsFactors = FALSE)

# Filtrar solo género Acción
accion <- datos %>%
  filter(first_genre == "Action") %>%
  select(movie_name, review_text, year)

cat("Total de reseñas de acción:", nrow(accion), "\n")
## Total de reseñas de acción: 3944
cat("Películas únicas:", n_distinct(accion$movie_name), "\n")
## Películas únicas: 429

Análisis de Sentimientos y Emociones

# Calcular sentimiento de cada reseña
accion$sentimiento <- get_sentiment(accion$review_text, method = "syuzhet")

# Promedio por película (mínimo 10 reseñas para mayor confiabilidad)
sentimiento_peliculas <- accion %>%
  group_by(movie_name) %>%
  summarise(
    sentimiento_promedio = mean(sentimiento, na.rm = TRUE),
    n_resenas = n()
  ) %>%
  filter(n_resenas >= 10) %>%
  arrange(desc(sentimiento_promedio))

# Top 5 Mejores
mejores <- head(sentimiento_peliculas, 5)
cat("Top 5 Mejores Películas de Acción:\n")
## Top 5 Mejores Películas de Acción:
print(mejores)
## # A tibble: 5 × 3
##   movie_name       sentimiento_promedio n_resenas
##   <chr>                           <dbl>     <int>
## 1 Star Wars                        13.2        22
## 2 Charlie's Angels                 12.5        18
## 3 Space Cowboys                    12.0        16
## 4 Rush Hour                        11.6        34
## 5 X-Men                            11.6        25
# Top 5 Peores
peores <- tail(sentimiento_peliculas, 5)
cat("\nTop 5 Peores Películas de Acción:\n")
## 
## Top 5 Peores Películas de Acción:
print(peores)
## # A tibble: 5 × 3
##   movie_name           sentimiento_promedio n_resenas
##   <chr>                               <dbl>     <int>
## 1 Con Air                             -1.89        29
## 2 Alien³                              -2.20        11
## 3 Battlefield Earth                   -3.65        24
## 4 Ghosts of Mars                      -3.90        10
## 5 Natural Born Killers                -4.00        22

Análisis de Emociones

# Muestra pequeña para que corra rápido
set.seed(123)
muestra <- accion %>% sample_n(min(50, nrow(accion)))
palabras_muestra <- get_tokens(muestra$review_text)
emociones <- get_nrc_sentiment(palabras_muestra, language = "english")

# 8 emociones básicas
barplot(colSums(prop.table(emociones[, 1:8])))

Nube de Palabras

Nube de Palabras — Mejores Películas

mejores_nombres <- mejores$movie_name

textos_mejores <- accion %>%
  filter(movie_name %in% mejores_nombres) %>%
  pull(review_text) %>%
  paste(collapse = " ")

palabras_mejores <- get_tokens(textos_mejores)
palabras_mejores <- removeWords(
  palabras_mejores,
  c(stopwords("english"),
    "film", "movie", "one", "like", "just", "even", "get", "can",
    "will", "much", "also", "well", "made", "make", "way", "good",
    "still", "really", "see", "come", "back", "two", "first", "reviews", "review", "movies", "rec", "chan", "ascci", "html")
)

set.seed(42)
wordcloud(
  words        = palabras_mejores,
  min.freq     = 3,
  max.words    = 80,
  rot.per      = 0.1,
  random.order = FALSE,
  colors       = brewer.pal(8, "Blues"),
  scale        = c(4, 0.5)
)
title(main = "Palabras en Reseñas — Mejores Películas de Acción", cex.main = 1)

Nube de Palabras — Peores Películas

peores_nombres <- peores$movie_name

textos_peores <- accion %>%
  filter(movie_name %in% peores_nombres) %>%
  pull(review_text) %>%
  paste(collapse = " ")

palabras_peores <- get_tokens(textos_peores)
palabras_peores <- removeWords(
  palabras_peores,
  c(stopwords("english"),
    "film", "movie", "one", "like", "just", "even", "get", "can",
    "will", "much", "also", "well", "made", "make", "way", "good",
    "still", "really", "see", "come", "back", "two", "first", "reviews", "review", "movies", "rec", "chan", "ascci", "html")
)

set.seed(42)
wordcloud(
  words        = palabras_peores,
  min.freq     = 3,
  max.words    = 80,
  rot.per      = 0.1,
  random.order = FALSE,
  colors       = brewer.pal(8, "Reds"),
  scale        = c(4, 0.5)
)
title(main = "Palabras en Reseñas — Peores Películas de Acción", cex.main = 1)

Películas Destacadas

Mejores Películas de Acción

The Matrix (1999)

Men in Black (1997)

Gladiator (2000)

Peores Películas de Acción

Batman & Robin (1997)

Godzilla (1998)

Alien: Resurrection (1997)

Conclusiones

  • Las películas de acción con mejores reseñas son aquellas que equilibran la acción con una historia sólida y personajes bien desarrollados. El vocabulario positivo en sus reseñas está centrado en la narrativa y las actuaciones, no en los efectos visuales.

  • Las películas de acción con peores reseñas generan respuestas emocionales de ira y decepción, reflejando que el público se siente defraudado cuando se priorizan el espectáculo visual sobre el contenido.

  • La emoción de anticipación es la más prevalente en el género, lo que sugiere que el público de acción llega altamente motivado. Esto hace que las decepciones sean especialmente pronunciadas en este género.

LS0tDQp0aXRsZTogIk1pbmVyw61hIGRlIFRleHRvOiBNZWpvcmVzIHkgUGVvcmVzIFBlbMOtY3VsYXMgZGUgQWNjacOzbiINCmF1dGhvcjogIiINCmRhdGU6ICJgciBTeXMuRGF0ZSgpYCINCm91dHB1dDoNCiAgaHRtbF9kb2N1bWVudDoNCiAgICB0b2M6IFRSVUUNCiAgICB0b2NfZmxvYXQ6IFRSVUUNCiAgICBjb2RlX2Rvd25sb2FkOiBUUlVFDQogICAgdGhlbWU6IGNvc21vDQotLS0NCg0KPGNlbnRlcj4NCiFbXShodHRwczovL3d3dy5kZ2NzLnVuYW0ubXgvYm9sZXRpbi9iZGJvbGV0aW4vbXVsdGltZWRpYS9XQVYyNDAyMDEvMDk0KDEpLmpwZykNCjwvY2VudGVyPg0KDQoNCiMgTGlicmVyw61hcw0KDQpgYGB7ciBtZXNzYWdlPUZBTFNFLCB3YXJuaW5nPUZBTFNFfQ0KbGlicmFyeSh0aWR5dmVyc2UpICAgIyBNYW5pcHVsYWNpw7NuIGRlIGRhdG9zDQpsaWJyYXJ5KHN5dXpoZXQpICAgICAjIEFuw6FsaXNpcyBkZSBzZW50aW1pZW50b3MgeSBlbW9jaW9uZXMNCmxpYnJhcnkodG0pICAgICAgICAgICMgTWluZXLDrWEgZGUgdGV4dG8NCmxpYnJhcnkod29yZGNsb3VkKSAgICMgTnViZSBkZSBwYWxhYnJhcw0KYGBgDQoNCiMgQ2FyZ2EgeSBQcmVwYXJhY2nDs24gZGUgRGF0b3MNCg0KYGBge3IgbWVzc2FnZT1GQUxTRSwgd2FybmluZz1GQUxTRX0NCmRhdG9zIDwtIHJlYWQuY3N2KCJtb3ZpZV9yZXZpZXdzLmNzdiIsIHN0cmluZ3NBc0ZhY3RvcnMgPSBGQUxTRSkNCg0KIyBGaWx0cmFyIHNvbG8gZ8OpbmVybyBBY2Npw7NuDQphY2Npb24gPC0gZGF0b3MgJT4lDQogIGZpbHRlcihmaXJzdF9nZW5yZSA9PSAiQWN0aW9uIikgJT4lDQogIHNlbGVjdChtb3ZpZV9uYW1lLCByZXZpZXdfdGV4dCwgeWVhcikNCg0KY2F0KCJUb3RhbCBkZSByZXNlw7FhcyBkZSBhY2Npw7NuOiIsIG5yb3coYWNjaW9uKSwgIlxuIikNCmNhdCgiUGVsw61jdWxhcyDDum5pY2FzOiIsIG5fZGlzdGluY3QoYWNjaW9uJG1vdmllX25hbWUpLCAiXG4iKQ0KYGBgDQoNCiMgQW7DoWxpc2lzIGRlIFNlbnRpbWllbnRvcyB5IEVtb2Npb25lcw0KDQpgYGB7ciBtZXNzYWdlPUZBTFNFLCB3YXJuaW5nPUZBTFNFfQ0KIyBDYWxjdWxhciBzZW50aW1pZW50byBkZSBjYWRhIHJlc2XDsWENCmFjY2lvbiRzZW50aW1pZW50byA8LSBnZXRfc2VudGltZW50KGFjY2lvbiRyZXZpZXdfdGV4dCwgbWV0aG9kID0gInN5dXpoZXQiKQ0KDQojIFByb21lZGlvIHBvciBwZWzDrWN1bGEgKG3DrW5pbW8gMTAgcmVzZcOxYXMgcGFyYSBtYXlvciBjb25maWFiaWxpZGFkKQ0Kc2VudGltaWVudG9fcGVsaWN1bGFzIDwtIGFjY2lvbiAlPiUNCiAgZ3JvdXBfYnkobW92aWVfbmFtZSkgJT4lDQogIHN1bW1hcmlzZSgNCiAgICBzZW50aW1pZW50b19wcm9tZWRpbyA9IG1lYW4oc2VudGltaWVudG8sIG5hLnJtID0gVFJVRSksDQogICAgbl9yZXNlbmFzID0gbigpDQogICkgJT4lDQogIGZpbHRlcihuX3Jlc2VuYXMgPj0gMTApICU+JQ0KICBhcnJhbmdlKGRlc2Moc2VudGltaWVudG9fcHJvbWVkaW8pKQ0KDQojIFRvcCA1IE1lam9yZXMNCm1lam9yZXMgPC0gaGVhZChzZW50aW1pZW50b19wZWxpY3VsYXMsIDUpDQpjYXQoIlRvcCA1IE1lam9yZXMgUGVsw61jdWxhcyBkZSBBY2Npw7NuOlxuIikNCnByaW50KG1lam9yZXMpDQoNCiMgVG9wIDUgUGVvcmVzDQpwZW9yZXMgPC0gdGFpbChzZW50aW1pZW50b19wZWxpY3VsYXMsIDUpDQpjYXQoIlxuVG9wIDUgUGVvcmVzIFBlbMOtY3VsYXMgZGUgQWNjacOzbjpcbiIpDQpwcmludChwZW9yZXMpDQpgYGANCg0KDQojIyBBbsOhbGlzaXMgZGUgRW1vY2lvbmVzDQoNCmBgYHtyIG1lc3NhZ2U9RkFMU0UsIHdhcm5pbmc9RkFMU0UsIGNhY2hlPVRSVUV9DQojIE11ZXN0cmEgcGVxdWXDsWEgcGFyYSBxdWUgY29ycmEgcsOhcGlkbw0Kc2V0LnNlZWQoMTIzKQ0KbXVlc3RyYSA8LSBhY2Npb24gJT4lIHNhbXBsZV9uKG1pbig1MCwgbnJvdyhhY2Npb24pKSkNCnBhbGFicmFzX211ZXN0cmEgPC0gZ2V0X3Rva2VucyhtdWVzdHJhJHJldmlld190ZXh0KQ0KZW1vY2lvbmVzIDwtIGdldF9ucmNfc2VudGltZW50KHBhbGFicmFzX211ZXN0cmEsIGxhbmd1YWdlID0gImVuZ2xpc2giKQ0KDQojIDggZW1vY2lvbmVzIGLDoXNpY2FzDQpiYXJwbG90KGNvbFN1bXMocHJvcC50YWJsZShlbW9jaW9uZXNbLCAxOjhdKSkpDQpgYGANCg0KIyBOdWJlIGRlIFBhbGFicmFzDQoNCiMjIE51YmUgZGUgUGFsYWJyYXMg4oCUIE1lam9yZXMgUGVsw61jdWxhcw0KDQpgYGB7ciBtZXNzYWdlPUZBTFNFLCB3YXJuaW5nPUZBTFNFfQ0KbWVqb3Jlc19ub21icmVzIDwtIG1lam9yZXMkbW92aWVfbmFtZQ0KDQp0ZXh0b3NfbWVqb3JlcyA8LSBhY2Npb24gJT4lDQogIGZpbHRlcihtb3ZpZV9uYW1lICVpbiUgbWVqb3Jlc19ub21icmVzKSAlPiUNCiAgcHVsbChyZXZpZXdfdGV4dCkgJT4lDQogIHBhc3RlKGNvbGxhcHNlID0gIiAiKQ0KDQpwYWxhYnJhc19tZWpvcmVzIDwtIGdldF90b2tlbnModGV4dG9zX21lam9yZXMpDQpwYWxhYnJhc19tZWpvcmVzIDwtIHJlbW92ZVdvcmRzKA0KICBwYWxhYnJhc19tZWpvcmVzLA0KICBjKHN0b3B3b3JkcygiZW5nbGlzaCIpLA0KICAgICJmaWxtIiwgIm1vdmllIiwgIm9uZSIsICJsaWtlIiwgImp1c3QiLCAiZXZlbiIsICJnZXQiLCAiY2FuIiwNCiAgICAid2lsbCIsICJtdWNoIiwgImFsc28iLCAid2VsbCIsICJtYWRlIiwgIm1ha2UiLCAid2F5IiwgImdvb2QiLA0KICAgICJzdGlsbCIsICJyZWFsbHkiLCAic2VlIiwgImNvbWUiLCAiYmFjayIsICJ0d28iLCAiZmlyc3QiLCAicmV2aWV3cyIsICJyZXZpZXciLCAibW92aWVzIiwgInJlYyIsICJjaGFuIiwgImFzY2NpIiwgImh0bWwiKQ0KKQ0KDQpzZXQuc2VlZCg0MikNCndvcmRjbG91ZCgNCiAgd29yZHMgICAgICAgID0gcGFsYWJyYXNfbWVqb3JlcywNCiAgbWluLmZyZXEgICAgID0gMywNCiAgbWF4LndvcmRzICAgID0gODAsDQogIHJvdC5wZXIgICAgICA9IDAuMSwNCiAgcmFuZG9tLm9yZGVyID0gRkFMU0UsDQogIGNvbG9ycyAgICAgICA9IGJyZXdlci5wYWwoOCwgIkJsdWVzIiksDQogIHNjYWxlICAgICAgICA9IGMoNCwgMC41KQ0KKQ0KdGl0bGUobWFpbiA9ICJQYWxhYnJhcyBlbiBSZXNlw7FhcyDigJQgTWVqb3JlcyBQZWzDrWN1bGFzIGRlIEFjY2nDs24iLCBjZXgubWFpbiA9IDEpDQpgYGANCg0KIyMgTnViZSBkZSBQYWxhYnJhcyDigJQgUGVvcmVzIFBlbMOtY3VsYXMNCg0KYGBge3IgbWVzc2FnZT1GQUxTRSwgd2FybmluZz1GQUxTRX0NCnBlb3Jlc19ub21icmVzIDwtIHBlb3JlcyRtb3ZpZV9uYW1lDQoNCnRleHRvc19wZW9yZXMgPC0gYWNjaW9uICU+JQ0KICBmaWx0ZXIobW92aWVfbmFtZSAlaW4lIHBlb3Jlc19ub21icmVzKSAlPiUNCiAgcHVsbChyZXZpZXdfdGV4dCkgJT4lDQogIHBhc3RlKGNvbGxhcHNlID0gIiAiKQ0KDQpwYWxhYnJhc19wZW9yZXMgPC0gZ2V0X3Rva2Vucyh0ZXh0b3NfcGVvcmVzKQ0KcGFsYWJyYXNfcGVvcmVzIDwtIHJlbW92ZVdvcmRzKA0KICBwYWxhYnJhc19wZW9yZXMsDQogIGMoc3RvcHdvcmRzKCJlbmdsaXNoIiksDQogICAgImZpbG0iLCAibW92aWUiLCAib25lIiwgImxpa2UiLCAianVzdCIsICJldmVuIiwgImdldCIsICJjYW4iLA0KICAgICJ3aWxsIiwgIm11Y2giLCAiYWxzbyIsICJ3ZWxsIiwgIm1hZGUiLCAibWFrZSIsICJ3YXkiLCAiZ29vZCIsDQogICAgInN0aWxsIiwgInJlYWxseSIsICJzZWUiLCAiY29tZSIsICJiYWNrIiwgInR3byIsICJmaXJzdCIsICJyZXZpZXdzIiwgInJldmlldyIsICJtb3ZpZXMiLCAicmVjIiwgImNoYW4iLCAiYXNjY2kiLCAiaHRtbCIpDQopDQoNCnNldC5zZWVkKDQyKQ0Kd29yZGNsb3VkKA0KICB3b3JkcyAgICAgICAgPSBwYWxhYnJhc19wZW9yZXMsDQogIG1pbi5mcmVxICAgICA9IDMsDQogIG1heC53b3JkcyAgICA9IDgwLA0KICByb3QucGVyICAgICAgPSAwLjEsDQogIHJhbmRvbS5vcmRlciA9IEZBTFNFLA0KICBjb2xvcnMgICAgICAgPSBicmV3ZXIucGFsKDgsICJSZWRzIiksDQogIHNjYWxlICAgICAgICA9IGMoNCwgMC41KQ0KKQ0KdGl0bGUobWFpbiA9ICJQYWxhYnJhcyBlbiBSZXNlw7FhcyDigJQgUGVvcmVzIFBlbMOtY3VsYXMgZGUgQWNjacOzbiIsIGNleC5tYWluID0gMSkNCmBgYA0KDQojIFBlbMOtY3VsYXMgRGVzdGFjYWRhcw0KDQojIyBNZWpvcmVzIFBlbMOtY3VsYXMgZGUgQWNjacOzbg0KDQojIyMgVGhlIE1hdHJpeCAoMTk5OSkNCg0KIyMjIE1lbiBpbiBCbGFjayAoMTk5NykNCg0KIyMjIEdsYWRpYXRvciAoMjAwMCkNCg0KIyMgUGVvcmVzIFBlbMOtY3VsYXMgZGUgQWNjacOzbg0KDQojIyMgQmF0bWFuICYgUm9iaW4gKDE5OTcpDQoNCiMjIyBHb2R6aWxsYSAoMTk5OCkNCg0KIyMjIEFsaWVuOiBSZXN1cnJlY3Rpb24gKDE5OTcpDQoNCiMgQ29uY2x1c2lvbmVzDQoNCi0gTGFzIHBlbMOtY3VsYXMgZGUgYWNjacOzbiBjb24gKiptZWpvcmVzIHJlc2XDsWFzKiogc29uIGFxdWVsbGFzIHF1ZSBlcXVpbGlicmFuIGxhIGFjY2nDs24gY29uIHVuYSAqKmhpc3RvcmlhIHPDs2xpZGEgeSBwZXJzb25hamVzIGJpZW4gZGVzYXJyb2xsYWRvcyoqLiBFbCB2b2NhYnVsYXJpbyBwb3NpdGl2byBlbiBzdXMgcmVzZcOxYXMgZXN0w6EgY2VudHJhZG8gZW4gbGEgbmFycmF0aXZhIHkgbGFzIGFjdHVhY2lvbmVzLCBubyBlbiBsb3MgZWZlY3RvcyB2aXN1YWxlcy4NCg0KLSBMYXMgcGVsw61jdWxhcyBkZSBhY2Npw7NuIGNvbiAqKnBlb3JlcyByZXNlw7FhcyoqIGdlbmVyYW4gcmVzcHVlc3RhcyBlbW9jaW9uYWxlcyBkZSAqKmlyYSB5IGRlY2VwY2nDs24qKiwgcmVmbGVqYW5kbyBxdWUgZWwgcMO6YmxpY28gc2Ugc2llbnRlIGRlZnJhdWRhZG8gY3VhbmRvIHNlIHByaW9yaXphbiBlbCBlc3BlY3TDoWN1bG8gdmlzdWFsIHNvYnJlIGVsIGNvbnRlbmlkby4NCg0KLSBMYSBlbW9jacOzbiBkZSAqKmFudGljaXBhY2nDs24qKiBlcyBsYSBtw6FzIHByZXZhbGVudGUgZW4gZWwgZ8OpbmVybywgbG8gcXVlIHN1Z2llcmUgcXVlIGVsIHDDumJsaWNvIGRlIGFjY2nDs24gbGxlZ2EgYWx0YW1lbnRlIG1vdGl2YWRvLiBFc3RvIGhhY2UgcXVlIGxhcyBkZWNlcGNpb25lcyBzZWFuIGVzcGVjaWFsbWVudGUgcHJvbnVuY2lhZGFzIGVuIGVzdGUgZ8OpbmVyby4NCg0K