Модель классификации с использованием набора данных по моему выбору.

Я нашел интересный набор данных о телерекламе в Хранилище машинного обучения UCI. Набор данных состоит из аудио- и визуальных характеристик видеоклипов, взятых из новостных телепередач. Сами видеоклипы были созданы путем сегментации 30-минутных записей с использованием однородности распределения цветов. Все это часть предварительно обработанного набора данных из UCI.

Видеоданные, которые я использовал, были получены как от BBC, так и от CNN (подмножество данных, представленных в полном репозитории UCI TV). Набор данных содержит тонну объектов. Для моего подмножества данных было 231 функция, большинство из которых относятся к корзинам звуковых слов, которые были заполнены создателями набора данных. Каждая запись классифицируется либо как реклама, либо как выпуск новостей — идеальная задача бинарной классификации.

Вопрос/проблема. Можно ли использовать функции видеоклипа, чтобы определить, является ли видео коммерческим или новостным?

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

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

Используемая метрика — точность. Точность = истинные положительные результаты/прогнозированные положительные результаты. При использовании этого показателя для оптимизации модель стремится уменьшить количество ложных срабатываний. Что такое ложный положительный результат? Что ж, в контексте этих данных ложноположительный результат – это выпуск телевизионных новостей (отрицательный), который случайно был классифицирован как телевизионная реклама (положительный).

Так зачем же точность?… Хотя зритель хочет пропустить рекламу, он НЕ не хочет случайно пропустить просматриваемую программу. Следовательно, непреднамеренно пропустить содержание программы раздражает больше, чем не пропустить рекламный ролик. Ложноположительный результат считается хуже, чем ложноотрицательный. Это не конец света, если вы застряли на одном рекламном ролике — если, конечно, этот конкретный рекламный ролик не является одной из тех раздражающих рекламных роликов о страховании или сайтах знакомств. Если да, то вам позволено проклясть этот показатель и решить для себя, что важнее всего в жизни.

Процесс. Из-за большой размерности этих данных я поставил перед собой подцель сокращения количества признаков до менее чем 20, сохраняя при этом приемлемый уровень точности и точность.

Я определил различные подмножества функций в наборе данных, которые я хотел смоделировать на основе анализа kbest, тепловых карт корреляции и построения кривых распределения для коммерческих/новостных тегов для каждой функции. Я включаю изображение тепловой карты полного набора данных только для того, чтобы обеспечить визуальное представление количества функций. В основном бесполезно пытаться увидеть детали корреляции на этом графике, не удаляя или не фокусируясь на определенных функциях.

Какое красивое произведение современного искусства! Я думаю, что мне следует подумать о продаже шаблонов стеганых одеял, которые используют тепловые карты различных наборов данных для дизайна шаблона. :)

Чтобы получить базовое представление о том, насколько хорошо классификатор может работать с этим набором данных, я использовал случайный лес, опорный вектор и экстремальный градиент. Расширьте классификаторы до всех функций набора данных. — результаты: Точность, Точность, Отзыв и F1Scores — все в диапазоне 93–95%. Прохладный!

Теперь приступим к моделированию подмножеств признаков (и преобразованных признаков). Я начал только с необработанных функций аудио и видео, таких как спектральный поток, коэффициент пересечения нуля, распределение разности кадров и т. д. а затем использовали итеративный процесс, чтобы подогнать каждый тип классификатора к набору данных и добавить/удалить определенные функции.

Я использовал функцию sklearn GridSearchCV для тестирования различных наборов параметров для классификаторов. Предпринятые шаги представлены ниже.

Процесс:

  1. В начале было выполнено разбиение обучающего теста с 15% данных, зарезервированных для проверки.
  2. Подбирайте модели к каждому варианту набора данных, используя поиск по сетке и перекрестную проверку обучающих данных.
  3. Сохраненные модели и статистика моделей в списке результатов (каждый результат представляет собой словарь).
  4. Применял модели к набору тестовых данных и сохранял результаты.
  5. Посмотрел результаты, изменил некоторые параметры gridsearch, изменил некоторые функции в наборах данных… повторять, повторять и т. д., пока не счастлив.
  6. Выберите лучшую модель и выполните перекрестную проверку всего набора данных (обучающие и тестовые данные вместе).

Основные варианты протестированного набора данных:

  • Все функции,
  • Только функции аудио-видео
  • Только неколлинеарные функции аудио-видео
  • Неколлинеарные функции аудио-видео, функции преобразования текстовой области Prinicpal Component, выбранные функции набора слов.
  • Неколлинеарные функции аудио-видео и выбранные функции текстовой области.
  • Все аудио-видео столбцы и выбранные функции текстовой области и набора слов.
#MODEL TYPES and GRIDSEARCHCV PARAMETERS - repeatedly tweaked and used other versions as well.

#Random Forest
rf_clf = RandomForestClassifier(max_features=’auto’)
param_grid_rf = [{‘criterion’: [‘gini,’entropy’],
 ‘max_depth’: [5,6,7,8],
 ‘n_estimators’: [50,100] }]
#XGBoost
xgb_clf = xgb.XGBClassifier()
param_grid_xgb = [{‘max_depth’: [3,4,5],
 ‘n_estimators’: [50, 100],
 ‘learning_rate’: [0.1, 0.2],
 ‘gamma’: [0, 1] }]
#Support Vector
svc_clf = SVC()
param_grid_svc = [{‘C’: [1, 10],
 ‘gamma’: [‘auto’] }]

Некоторые интересные результаты заключались в том, что классификатор Random Forest почти всегда переопределял данные, если не был установлен параметр max_depth (по умолчанию он не имеет максимального значения). Опорный вектор, как правило, превосходил данные, когда в подходящих данных присутствовало много-много функций. Модели XGBoost перекроют данные, если max_depth будет задано слишком большое значение (по умолчанию 3). Support Vector, безусловно, занимает больше всего времени, чтобы соответствовать.

Я определил функцию, которая соответствует модели gridsearch, вычисляет точность и показатели точности, а затем возвращает словарь, содержащий саму модель, используемые параметры и результаты производительности. Это упростило выполнение нескольких итераций подбора модели для разных наборов признаков. Последней моделью, которую я выбрал, была модель XGBoost, которая смогла поддерживать около 90% точности и правильности всего с 11 функциями из исходных 231.

Я предоставил функцию, которую использовал для подбора модели, в конце этого сообщения в блоге. В общем, мне очень нравится помещать любые результаты процесса в формат словаря, так как это упрощает последующую проверку. В основном блоке кода вы можете заполнить список словарей результатов и получить доступ к каждому элементу (в данном случае к модели) или просмотреть результаты в формате pandas DataFrame — список словарей преобразуется в DataFrame с легкостью: pd.DataFrame(results_list).

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

def fit_model(clf,
              train_test_data,
              param_grid,
              scoring=’precision’,
              cv=5):
“””
This function will use sklearn GridSearchCV to fit a model using the classifier and parameter grid provided. It will return a dictionary containing the model and train/test results.
 
INPUTS:
clf             = The classifier being fit.
train_test_data = Tuple containing train and test data in the format
                  (X_train,X_test,y_train,y_test)
param_grid      = The parameters to use for gridsearch fitting of 
                  the classifier.
scoring         = The scoring method to be used by gridsearch.
cv              = The number of cross validations.
 
RETURNS:
Dictionary object with the following keys:
model           = The best model from gridsearch.
model_params    = The best model parameters used.
accuracy_train  = The accuracy of the model on the training data.
accuracy_test   = The accuracy of the model on the test data.
precision_train = The precision of the model on the training data.
precision_test  = The precision of the model on the test data.
“””
result = {}
(X_train,X_test,y_train,y_test) = train_test_data
grid_clf = GridSearchCV(estimator=clf, 
                        param_grid=param_grid, 
                        cv=cv, 
                        scoring=scoring)
grid_clf.fit(X_train,y_train)
y_pred_train = grid_clf.predict(X_train)
y_pred_test  = grid_clf.predict(X_test)
result[‘model’] = grid_clf.best_estimator_
result[‘model_params’] = grid_clf.best_params_
result[‘accuracy_train’] = accuracy_score(y_train,y_pred_train)
result[‘accuracy_test’] = accuracy_score(y_test,y_pred_test)
result[‘precision_train’] = precision_score(y_train,y_pred_train)
result[‘precision_test’] = precision_score(y_test,y_pred_test)

return result