Объединение кластеризации k-средних с деревом решений по данным IMDb

Задний план

Вы когда-нибудь задумывались, насколько великим будет фильм до его выхода? Недавно данные IMDb о более чем 5000 фильмах были скопированы с помощью Python и опубликованы на Kaggle.com Чуаном Саном. Набор данных доступен здесь.

Цель

Наша цель - выяснить, какие факторы могут способствовать созданию отличных фильмов.

Подход

1… Примените кластеризацию k-средних, чтобы разделить фильмы на 5 классов.

Сначала нам нужно определить, что такое великие фильмы. Один простой способ - использовать оценки IMDb; однако подход, который мы здесь используем, заключается в объединении оценок с кассовыми сборами (валовыми), чтобы получить более сбалансированный показатель того, насколько хороши фильмы. Фильмы делятся на 5 категорий, как показано ниже. Мы видим, что большинство фильмов находится в кластере 3, который генерировал низкие кассовые сборы и большие различия в оценках IMDb; тогда как фильмы в кластере 1 имеют относительно более высокие общие и более высокие оценки по сравнению с другими кластерами.

2… Постройте дерево решений для классификации фильмов на основе различных переменных.

Затем мы введем различные факторы и посмотрим, какие факторы помогают классифицировать фильмы на 5 кластеров, создаваемых больше всего, путем построения дерева решений. Согласно результатам, количество проголосовавших пользователей, бюджет фильма, контент с рейтингом R и количество отзывов критиков влияют на величие фильмов.

Допустим, мы хотим знать, будет ли фильм отличным (кластер 1 в зеленом), мы должны будем следовать по пути, созданному сверху вниз в дереве решений:

  1. Количество проголосовавших пользователей должно быть не менее 43 000.
  2. Бюджет фильма должен превышать 36 миллионов долларов США.
  3. Фильму нельзя присвоить рейтинг R.
  4. Фактическое количество проголосовавших пользователей должно быть не менее 519 000

Выполнив указанные выше условия, мы будем иметь почти 70% шанс узнать, что фильм будет отличным, еще до его выпуска!

Подготовка данных

1… В файле отсутствуют некоторые критические значения, поэтому строки удаляются.

2… фиктивные переменные, созданные для категориальных переменных (язык, страна)

3… Набор для обучения и набор для тестирования создаются с соотношением 4: 1.

Результаты

На основе матрицы неточностей общая точность составляет 0,6572 для 5 кластеров (с точностью кластера 1, близкой к 0,70).

Чтобы повысить общую точность, мы можем захотеть включить больше переменных из файла, поскольку мы не включили жанры (действие, рекламные ролики, триллер и т. Д.), Название фильма (может потребоваться обработка естественного языка) и ключевые слова в сюжеты ( может потребоваться интеллектуальный анализ текста).

Кроме того, мы можем продолжить изучение возможности увеличения количества кластеров. Давайте сначала посмотрим на производительность на 6 кластерах. Замечено, что производительность упала на 5% с точки зрения точности.

Далее мы рассмотрим производительность всего с 4 кластерами.

Результат со 100% точностью! Это имеет смысл, потому что по мере того, как мы уменьшаем кластеры результатов, модели дерева решений становится легче прогнозировать. Например, если есть только один кластер результатов, мы также всегда будем иметь 100% точность.

Полный код в R приведен ниже.

library(ggplot2)
library(rpart)
library(rattle)
library(rpart.plot)
library(RColorBrewer)
library(caret)
setwd("~/Desktop/imdb")
mydata <- read.csv("movie_label.csv")
set.seed(123)
#Generate movie clusters and plot
mydataCluster <- kmeans(mydata[, 9:10], 5, nstart = 20)
mydata$cluster <- as.factor(mydataCluster$cluster)
ggplot(mydata, aes(gross, imdb_score, color = mydata$cluster)) + geom_point()+scale_colour_manual(values=c("green", "blue","orange","purple","red")) + xlab("Gross") + ylab("IMDB Score")
#Create dummy variables for categorial variables
for(level in unique(mydata$language)){
  mydata[paste("dummy", level, sep = "_")] <- ifelse(mydata$language == level, 1, 0)
}
for(level in unique(mydata$country)){
  mydata[paste("dummy", level, sep = "_")] <- ifelse(mydata$country == level, 1, 0)
}
for(level in unique(mydata$content_rating)){
  mydata[paste("dummy", level, sep = "_")] <- ifelse(mydata$content_rating == level, 1, 0)
}
for(level in unique(mydata$title_year)){
  mydata[paste("dummy", level, sep = "_")] <- ifelse(mydata$title_year == level, 1, 0)
}
for(level in unique(mydata$aspect_ratio)){
  mydata[paste("dummy", level, sep = "_")] <- ifelse(mydata$aspect_ratio == level, 1, 0)
}
#Remove unwanted variables for decision tree
mydata$id <- NULL
mydata$gross <- NULL
mydata$imdb_score <- NULL
mydata$genres <- NULL
mydata$language <- NULL
mydata$country <- NULL
mydata$content_rating <- NULL
mydata$title_year <- NULL
mydata$aspect_ratio <- NULL
#Create training and testing datasets
training_size <- floor(0.80 * nrow(mydata))
train_ind <- sample(seq_len(nrow(mydata)), size = training_size)
training <- mydata[train_ind, ]
testing <- mydata[-train_ind, ]
#Construct decision tree
fit <- rpart(cluster ~.,method="class",data=training)
fancyRpartPlot(fit)
#Evaluate decision tree performance
Prediction <- predict(fit, testing, type = "class")
confusionMatrix(Prediction, testing$cluster)

Вопросы, комментарии или проблемы?
[email protected]