Искусственный интеллект и машинное обучение проникли во все отрасли, принося значительную прибыль тем, кто в них вложился. По мере того, как технологии машинного обучения становятся все более мощными и распространяются, компании считают своим долгом внедрить эти технологии, чтобы получить конкурентное преимущество. В то время как машинное обучение включает в себя обучение компьютеров выполнению задач без явных инструкций, объединение согласованных данных для успешного обучения модели ML само по себе является проблемой. Сбор, очистка и проектирование данных — самая трудоемкая часть процесса машинного обучения.

Все алгоритмы машинного обучения используют данные в качестве входных данных для калибровки и генерации выходных данных. Данные изначально находятся в самой грубой форме, требующей улучшения, прежде чем передать их алгоритму. Эти входные данные содержат функции, которые являются измеримыми свойствами процесса, часто представляемыми в виде структурированных столбцов. Процесс извлечения соответствующих признаков из данных для обучения алгоритмов машинного обучения называется проектированием признаков. Разработка функций жизненно важна для науки о данных, поскольку она дает надежные и точные данные, а алгоритмы хороши настолько, насколько хороши данные, которые им передаются.

Что такое функциональная инженерия?

Что такое функция?

В машинном обучении особенность — это отдельное свойство или характеристика изучаемого процесса. Для эффективного обучения и калибровки алгоритмов важным шагом является выбор подходящих функций.

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

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

Итак, что такое функциональная инженерия?

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

Функции также называются «переменными» или «атрибутами», поскольку они влияют на результат процесса.

Разработка признаков включает в себя несколько процессов. Выбор признаков, построение, преобразование и извлечение — вот некоторые ключевые аспекты разработки признаков. Давайте разберемся, что включает в себя каждый процесс:

  • Выбор функций включает в себя выбор набора функций из большой коллекции. Выбор важных функций и уменьшение размера набора функций делает вычисления в алгоритмах машинного обучения и анализа данных более осуществимыми. Выбор признаков также улучшает качество выходных данных, полученных с помощью алгоритмов.
  • Преобразование объектов включает в себя создание объектов с использованием существующих данных с помощью математических операций. Например, для определения типа телосложения человека необходима характеристика, называемая ИМТ (индекс массы тела). Если набор данных отражает вес и рост человека, ИМТ можно рассчитать с помощью математической формулы.
  • Конструирование признаков — это процесс разработки новых признаков помимо тех, которые были созданы при преобразовании признаков, которые являются соответствующими переменными изучаемого процесса.
  • Извлечение признаков – это процесс уменьшения размерности набора данных. Извлечение признаков включает в себя объединение существующих признаков в новые, тем самым уменьшая количество признаков в наборе данных. Это уменьшает объем данных до управляемых размеров для обработки алгоритмами, не искажая исходные отношения или соответствующую информацию.

Почему требуется функциональная инженерия?

Намерение разработки признаков состоит в том, чтобы достичь двух основных целей:

  1. Подготовка набора входных данных, который совместим с алгоритмом машинного обучения и наилучшим образом соответствует ему.
  2. Повышение производительности моделей машинного обучения

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

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

Используемые методы проектирования общих элементов

  • Вменение

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

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

  • Горячее кодирование

Это один из распространенных методов кодирования, используемых в разработке признаков. Горячее кодирование — это метод присвоения двоичных значений (0 и 1) значениям в столбцах. В этом методе все значения выше порога преобразуются в 1, а все значения, равные или ниже порога, преобразуются в 0. Это изменяет значения признаков на числовой формат, который алгоритмам намного легче понять без ущерба для значения информация и взаимосвязь между переменными и функцией.

  • Операции группировки

В алгоритмах машинного обучения переменная или экземпляр представлены в строках, а функции представлены в столбцах. Многие наборы данных редко вписываются в упрощенное расположение строк и столбцов, поскольку каждый столбец содержит несколько строк экземпляра. Для обработки таких случаев данные группируются таким образом, что каждая переменная представлена ​​только одной строкой. Цель операций группировки — получить агрегацию, которая устанавливает наиболее жизнеспособную связь с функциями.

  • Преобразование журнала

Мера асимметрии в наборе данных известна как асимметрия, которая определяется как степень, в которой данное распределение данных отличается от нормального распределения. Асимметрия данных влияет на модели прогнозирования в алгоритмах ML. Чтобы решить эту проблему, преобразования журнала используются для уменьшения асимметрии данных. Чем менее асимметричны распределения, тем лучше алгоритмы способны интерпретировать закономерности.

  • Мешок слов

Bag of Words (BoW) — это алгоритм подсчета, который оценивает количество повторений слова в документе. Этот алгоритм полезен для выявления сходств и различий в документах для таких приложений, как поиск и классификация документов.

  • Хэширование функций

Хеширование признаков — важный метод, используемый для масштабирования алгоритмов машинного обучения путем векторизации признаков. Техника хеширования признаков обычно используется при классификации документов и анализе настроений, когда токены преобразуются в целые числа. Хэш-значения получаются путем применения хэш-функций к объектам, которые используются в качестве индексов для сопоставления данных.

Автоматизированная разработка функций

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

Вывод

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

Инжиниринг признаков — важный процесс в науке о данных, позволяющий извлечь максимальную выгоду из доступных данных. Различные методы разработки признаков направлены на получение согласованного набора данных, которые понятны и просты в обработке для алгоритмов машинного обучения для получения точных и надежных результатов.

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

Если вы хотите узнать больше об этой теме, свяжитесь с одним из наших экспертов по искусственному интеллекту и науке о данных для индивидуальной консультации.

Проблема под рукой

Файлы данных Bollywood.csv и Bollywood — 2 .csv содержат сбор кассовых сборов и информацию о продвижении в социальных сетях фильмов, выпущенных в период 2013–2015 годов.

Ниже приведена информация о столбцах (названия могут различаться):

  • Серийный номер фильма
  • Дата выхода фильма
  • Время выхода таких фильмов, как «Долгие выходные» (3), «Праздничный сезон» (1), «Праздничный сезон» (2) и «Обычный» (4)
  • Жанр фильма: романтика, триллер, боевик, комедия и т. д.
  • Бюджет фильма в крорах
  • Кассовые сборы фильма в крорах
  • Просмотры трейлеров фильмов на YouTube
  • Ютуб лайкает трейлеры к фильмам
  • YouTube не любит трейлеры фильмов
import pandas as pd
from pandas import DataFrame as df
import matplotlib.pyplot as plt
import seaborn as sns
%matplotlib inline
import numpy as np
import warnings
warnings.filterwarnings("ignore")

Импорт набора данных Болливуда и просмотр данных:

bollywood = pd.read_csv("bollywood.csv")

bollywood.head()

Импорт набора данных bollywood2 и просмотр данных:

bollywood2 = pd.read_csv("bollywood - 2.csv")

bollywood2.head()

Глядя на оба набора данных, мы видим, что имена столбцов разные, хотя они означают одно и то же. Переименование столбцов в обоих наборах данных, чтобы они совпадали, чтобы их можно было анализировать и использовать вместе.

bollywood.columns
Index(['No', 'RelDate', 'MovieName', 'ReleaseTime', 'Genre', 'Budget',
       'BoxOfficeCollection', 'YoutubeViews', 'YoutubeLikes',
       'YoutubeDislikes', 'YoutubeLikeDislikes'],
      dtype='object')
bollywood2.columns = ['No', 'RelDate', 'MovieName', 'ReleaseTime', 'Genre', 'Budget',
       'BoxOfficeCollection', 'YoutubeViews', 'YoutubeLikes',
       'YoutubeDislikes']

bollywood2.head()

Теперь эти наборы данных имеют одинаковые столбцы. Понимание элементов каждого из наборов данных:

bollywood.isnull().sum()
No                     0
RelDate                0
MovieName              0
ReleaseTime            0
Genre                  0
Budget                 0
BoxOfficeCollection    0
YoutubeViews           0
YoutubeLikes           1
YoutubeDislikes        3
YoutubeLikeDislikes    0
dtype: int64

Мы видим, что в YoutubeDislikes и YoutubeLikes есть нулевые значения.

bollywood2.isnull().sum()
No                     0
RelDate                0
MovieName              0
ReleaseTime            0
Genre                  0
Budget                 0
BoxOfficeCollection    0
YoutubeViews           0
YoutubeLikes           0
YoutubeDislikes        0
dtype: int64

В bollywood2 нет нулевых значений. Поэтому никаких дополнительных проверок не требуется.

bollywood.dtypes
No                       int64
RelDate                 object
MovieName               object
ReleaseTime              int64
Genre                   object
Budget                  object
BoxOfficeCollection     object
YoutubeViews             int64
YoutubeLikes           float64
YoutubeDislikes        float64
YoutubeLikeDislikes      int64
dtype: object
bollywood2.dtypes
No                       int64
RelDate                 object
MovieName               object
ReleaseTime             object
Genre                   object
Budget                   int64
BoxOfficeCollection    float64
YoutubeViews             int64
YoutubeLikes             int64
YoutubeDislikes          int64
dtype: object

Изменение столбцов на соответствующие типы данных в обоих наборах данных

В идеале: 1. RelDate должен быть полем даты. 2. MovieName, Genre являются строковыми значениями. 3. Бюджет, BoxOfficeCollection — это числа с плавающей запятой. 4. YoutubeViews, YoutubeLikes, YoutubeDislikes и YoutubeLikeDislikes — все целые числа. 5. ReleaseTime — это своего рода эннумератор

Работа с каждым из полей, чтобы понять, есть ли какие-либо проблемы:

Работа с полем даты выпуска:

Попытка преобразовать поле даты в стандартные значения.

Выполнение приведенного ниже кода приводит к исключению.

#bollywood['FormattedRelDate'] = pd.to_datetime(bollywood['RelDate'])

Делая это, мы сталкиваемся с исключением, как показано выше. Это указывает на неправильное форматирование строки в предоставленном наборе данных. Это должно быть исправлено для всех элементов в наборе данных.

Примечание. Код намеренно закомментирован, чтобы можно было запустить все ячейки.

Дальнейшее понимание данных путем разделения дат на год, месяц и даты.

bollywood['MonthOfRel'] = bollywood['RelDate'].str[:3]
bollywood['DateOfRel'] = bollywood['RelDate'].str[4:6]
bollywood['YearOfRel'] = bollywood['RelDate'].str[-4:]
bollywood.groupby(['DateOfRel'])['No'].count()
DateOfRel
09    1
1-    2
10    1
11    3
12    1
13    1
14    2
15    4
18    6
19    2
2-    2
20    1
21    2
22    2
23    1
24    2
25    2
27    1
28    1
30    1
4-    3
6-    2
7-    3
8-    4
9-    1
Name: No, dtype: int64

Проверяя даты, они не содержат недопустимых символов. Они не нуждаются в дополнительной фильтрации.

bollywood.groupby(['YearOfRel'])['No'].count()
YearOfRel
-204     1
2013    19
2014    31
Name: No, dtype: int64

Глядя на приведенный выше набор данных, мы видим следующие неверно введенные данные за годы: 1. 204 Это должен был быть 2014 год, поскольку данные относятся к 2013–2015 годам. Идентификация конкретного образца:

bollywood[bollywood.YearOfRel.isin(['-204'])]

Исправление набора данных путем замены значения правильным значением.

bollywood.RelDate = bollywood.RelDate.replace(to_replace=r'204', value='2014', regex=True)
bollywood.groupby(['MonthOfRel'])['No'].count()
MonthOfRel
Apr     1
Aug     1
Feb     9
Jan    10
Jul     6
Jum     1
Jun     3
Mar     7
May     5
Nov     2
Oct     2
Sep     2
Sqp     1
juu     1
Name: No, dtype: int64

Глядя на приведенный выше набор данных, мы видим следующие неверно введенные месяцы данных: 1. Jum 2. Sqp 3. juu

Есть два способа решить эту проблему с данными: 1. Предполагать наличие опечаток на основе последовательности символов и неправильно размещенного символа. Например: Jum — это Jun, в котором вместо «n» введено «m». Точно так же Sqp — 2 сентября. Однако мы не можем прийти к выводу, что juu — это июнь или 3 июля. В качестве альтернативы мы можем просмотреть детали фильма, чтобы получить точную информацию для заполнения, поскольку этот набор данных общедоступен.

Поскольку Sqp и Jum можно исправить с помощью (1), мы можем использовать это. Для (2) я использую Интернет в качестве ссылки для заполнения элемента данных.

bollywood[bollywood.MonthOfRel.isin(['juu'])]

Это подтверждает, фильм выпущен в июне месяце. Внесение соответствующих исправлений в набор данных Болливуда.

bollywood[bollywood.MonthOfRel.isin(['Jum'])]

bollywood[bollywood.MonthOfRel.isin(['Sqp'])]

bollywood.RelDate = bollywood.RelDate.replace(to_replace=r'juu', value='Jun', regex=True)
bollywood.RelDate = bollywood.RelDate.replace(to_replace=r'Jum', value='Jun', regex=True)
bollywood.RelDate = bollywood.RelDate.replace(to_replace=r'Sqp', value='Sep', regex=True)
#bollywood.RelDate = bollywood.RelDate.replace("Sqp-19-2014", "Sep-19-2014")
#bollywood.head()

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

bollywood['FormattedRelDate'] = pd.to_datetime(bollywood['RelDate'])
bollywood.head()

Удаление столбцов, созданных для проверки

bollywood = bollywood.drop(['MonthOfRel', 'DateOfRel', 'YearOfRel'], axis = 1)
bollywood.head(1)

Применение тех же проверок к набору данных bollywood2:

Попытка отформатировать поле данных напрямую, чтобы перейти к стандартному формату:

bollywood2['FormattedRelDate'] = pd.to_datetime(bollywood2['RelDate'])
bollywood2.head(1)

Мы видим, что форматирование прошло успешно и проблем здесь нет.

Работа с жанровым полем:

Глядя на распределение, сгруппировав их по жанрам

bollywood.groupby(['Genre'])['No'].count()
Genre
 Drama           1
 DramaGenre     11
Action           1
ActionGenre      9
ComedyGenre     12
RomanceGenre     9
Thriller         5
Thriller         3
Name: No, dtype: int64
bollywood2.groupby(['Genre'])['No'].count()
Genre
 Drama      23
Action      14
Comedy      24
Romance     17
Thriller    21
Name: No, dtype: int64

Ниже приведены проблемы, которые мы видим: 1. Драма имеет пробел перед текстом в обоих наборах данных 2. Триллер и боевик имеют конечный пробел в конце текста в наборе данных Болливуда 3. ActionGenre, ComedyGenre и RomanceGenre имеют «Жанр». ' добавлено в конце. 4. DramaGenre имеет начальный пробел, а «Жанр» добавляется в конце. Устранение этих неровностей.

bollywood.Genre = bollywood.Genre.str.strip()
bollywood.Genre = bollywood.Genre.replace("ActionGenre", "Action")
bollywood.Genre = bollywood.Genre.replace("ComedyGenre", "Comedy")
bollywood.Genre = bollywood.Genre.replace("RomanceGenre", "Romance")
bollywood.Genre = bollywood.Genre.replace("DramaGenre", "Drama")
bollywood2.Genre = bollywood2.Genre.str.strip()

Подтверждая, что это устранило нарушения:

bollywood.groupby(['Genre'])['No'].count()
Genre
Action      10
Comedy      12
Drama       12
Romance      9
Thriller     8
Name: No, dtype: int64
bollywood2.groupby(['Genre'])['No'].count()
Genre
Action      14
Comedy      24
Drama       23
Romance     17
Thriller    21
Name: No, dtype: int64

Глядя на Budget и BoxOfficeCollection:

#bollywood.groupby(['Budget'])['No'].count() #uncomment and run this.
#bollywood2.groupby(['Budget'])['No'].count() #uncomment and run this.

Глядя на бюджет, мы видим следующие проблемы:

  1. Столбец бюджета в bollywood2 не имеет проблем, но все значения представлены целыми числами. Это должно быть преобразовано в поплавки.
  2. Изменение набора данных Болливуда, чтобы он соответствовал этому набору результатов.
bollywood2['Budget'] = pd.to_numeric(bollywood2['Budget'], downcast='float')
bollywood['Budget'] = bollywood['Budget'].replace(to_replace=r'Cr', value='', regex=True)
bollywood['Budget'] = pd.to_numeric(bollywood['Budget'], downcast='float')
#bollywood.groupby(['Budget'])['No'].count() #uncomment and run this.
#bollywood.groupby(['BoxOfficeCollection'])['No'].count() #uncomment and run this.
#bollywood2.groupby(['BoxOfficeCollection'])['No'].count()#uncomment and run this.

С BoxOfficeCollection в основном есть две проблемы: 1. Тип данных несовместим. BoxOfficeCollection на bollywood2 следует преобразовать в число с плавающей запятой. 2. В некоторых случаях к набору данных Болливуда добавлено «cr», что приводит к тому, что данные не имеют стандартного формата.

bollywood2['BoxOfficeCollection'] = pd.to_numeric(bollywood2['BoxOfficeCollection'], downcast='float')
bollywood['BoxOfficeCollection'] = bollywood['BoxOfficeCollection'].replace(to_replace=r'Cr', value='', regex=True)
bollywood['BoxOfficeCollection'] = pd.to_numeric(bollywood['BoxOfficeCollection'], downcast='float')

Работа с YoutubeLikes и YoutubeDislikes:

Ютублайки:

  1. Мы знаем, что в YoutubeLikes есть нулевое значение только в наборе данных Болливуда. Другой набор данных в порядке.
  2. Получение строки, в которой существует нулевое значение:
bollywood[bollywood.YoutubeLikes.isin([np.nan])]

LikesDislikes содержит сумму лайков и дизлайков для строки. Таким образом, значение NaN в лайках на Youtube можно получить из YoutubeLikeDislikes — YoutubeDislikes.

bollywood['YoutubeLikes'] = bollywood['YoutubeLikes'].fillna(bollywood['YoutubeLikeDislikes']- bollywood['YoutubeDislikes'])
#confirming the null value in YoutubeLikes is replaced
bollywood.isnull().sum()
No                     0
RelDate                0
MovieName              0
ReleaseTime            0
Genre                  0
Budget                 0
BoxOfficeCollection    0
YoutubeViews           0
YoutubeLikes           0
YoutubeDislikes        3
YoutubeLikeDislikes    0
FormattedRelDate       0
dtype: int64

Youtube Dislikes: 1. Мы знаем, что в наборе данных Bollywood в Youtube Dislikes есть 3 нулевых значения.

Идентификация строк, в которых есть нулевые значения:

bollywood[bollywood.YoutubeDislikes.isin([np.nan])]

bollywood['YoutubeDislikes'] = bollywood['YoutubeDislikes'].fillna(bollywood['YoutubeLikeDislikes']- bollywood['YoutubeLikes'])
#confirming the null value in YoutubeLikes is replaced
bollywood.isnull().sum()
No                     0
RelDate                0
MovieName              0
ReleaseTime            0
Genre                  0
Budget                 0
BoxOfficeCollection    0
YoutubeViews           0
YoutubeLikes           0
YoutubeDislikes        0
YoutubeLikeDislikes    0
FormattedRelDate       0
dtype: int64

Выявление любых других проблем с наборами данных:

bollywood.describe()

bollywood2.describe()

Мы видим, что YoutubeLikeDislikes отсутствует в наборе данных bollywood2. Добавление этого столбца:

bollywood2['YoutubeLikeDislikes'] = bollywood2['YoutubeDislikes']+ bollywood2['YoutubeLikes']

Работа с временем выпуска:

bollywood.groupby(['ReleaseTime'])['No'].count()
ReleaseTime
1      3
2     10
3      4
4     33
44     1
Name: No, dtype: int64
bollywood2.groupby(['ReleaseTime'])['No'].count()
ReleaseTime
FS    14
HS     8
LW    11
N     66
Name: No, dtype: int64

По сути, здесь есть две проблемы: 1. Неверное значение в наборе данных Болливуда, для которого ReleaseTime имеет значение 44. 2. Значения ReleaseTime различаются в случае обоих наборов данных.

bollywood.ReleaseTime = bollywood.ReleaseTime.replace(44,4)
#Replacing 44 with 4
bollywood.groupby(['ReleaseTime'])['No'].count()
ReleaseTime
1     3
2    10
3     4
4    34
Name: No, dtype: int64

Из Постановки о проблеме мы понимаем, что: 1. Время выхода фильма, такого как «Долгие выходные» (3), «Праздничный сезон» (1), «Праздничный сезон» (2) и «Обычный» (4) 2. Сравнивая это со строками с элементами данных в bollywood2, мы можем сделать вывод, что LW = длинные выходные, FS = праздничный сезон, HS = праздничный сезон и N = нормальный 3. Теперь данные преобразуются в заданные типы ReleaseTimes, как описано в (1)

Замена элементов данных в bollywood2 на элементы bollywood.

bollywood.ReleaseTime = bollywood.ReleaseTime.replace(1,"Festive Season")
bollywood.ReleaseTime = bollywood.ReleaseTime.replace(2,"Holiday Season")
bollywood.ReleaseTime = bollywood.ReleaseTime.replace(3,"Long Weekend")
bollywood.ReleaseTime = bollywood.ReleaseTime.replace(4,"Normal")
bollywood2.ReleaseTime = bollywood2.ReleaseTime.replace('FS',"Festive Season")
bollywood2.ReleaseTime = bollywood2.ReleaseTime.replace('HS',"Holiday Season")
bollywood2.ReleaseTime = bollywood2.ReleaseTime.replace('LW',"Long Weekend")
bollywood2.ReleaseTime = bollywood2.ReleaseTime.replace('N',"Normal")
bollywood2.groupby(['ReleaseTime'])['No'].count()
#Confirming that both the datasets have the same value sets for ReleaseTime
ReleaseTime
Festive Season    14
Holiday Season     8
Long Weekend      11
Normal            66
Name: No, dtype: int64

Глядя на просмотры на Youtube:

#bollywood.groupby(['YoutubeViews'])['No'].count() #Uncomment this to run this code, commented to reduce the size of notebook
#bollywood2.groupby(['YoutubeViews'])['No'].count() #Uncomment this to run this code, ommented to reduce the size of notebook

Глядя на просмотры Youtube для обоих наборов данных, мы видим, что в наборе данных нет проблем с качеством данных.

Объединение двух наборов данных:

merged_bollywood = [bollywood, bollywood2]
dataset = pd.concat(merged_bollywood)
dataset.shape
(150, 12)

Проверка данных в объединенном наборе данных путем поиска нулей:

dataset.isnull().sum()
No                     0
RelDate                0
MovieName              0
ReleaseTime            0
Genre                  0
Budget                 0
BoxOfficeCollection    0
YoutubeViews           0
YoutubeLikes           0
YoutubeDislikes        0
YoutubeLikeDislikes    0
FormattedRelDate       0
dtype: int64

Нулевых значений нет. Также мы видим, что есть 150 строк.

Проверка повторяющихся значений в наборе данных

Названия фильмов не могут быть точными копиями

dataset.shape
(150, 12)

Группировка фильмов по названию:

distinct_movies = dataset.groupby(['MovieName'])['Budget'].count().reset_index().rename(columns={"Budget":"Occurrences"})
distinct_movies.shape
(149, 2)

Мы видим, что есть разница в единицу, это будет означать, что есть одно такое значение, которое является дубликатом. Сортировка приведенного выше по убыванию и определение дублирующейся записи.

distinct_movies.sort_values(by=['Occurrences'], inplace=True, ascending=False)
distinct_movies.head(1)

Мы видим, что в названиях фильмов есть повторяющаяся запись. Изучение других других атрибутов этого фильма.

dataset[dataset.MovieName.isin(['Lekar Hum Deewana Dil'])]

Мы видим, что все остальные атрибуты совпадают, таким образом удаляя одно из вхождений.

dataset = dataset.drop_duplicates(subset=['MovieName'])

Резюме проблем:

Ниже перечислены проблемы, которые были выявлены и подтверждены в процессе подготовки данных: 1. Проблемы с датой выпуска: a. Есть три даты с неправильными названиями месяцев. Они заменяются правильными именами. б. Неправильно введен год. Это также исправляется заменой на правильное значение. в. Также создается столбец форматированного поля даты для различных аналитических целей. Исходное поле, если оно опущено с изменением. 2. Проблемы с полем «Жанр»: a. Драма имеет пробел перед текстом в обоих наборах данных b. Триллер и боевик имеют пробел в конце текста в наборе данных Болливуда c. В ActionGenre, ComedyGenre и RomanceGenre в конце добавляется «Жанр». д. DramaGenre имеет начальный пробел, а «Жанр» добавляется в конце. Начальные и конечные пробелы были удалены, и везде, где в конец добавляется слово «Жанр», оно удаляется. 3. Проблемы с полем бюджета: a. Тип данных не соответствует наборам данных. б. В некоторых случаях к набору данных Болливуда добавлено «cr», что приводит к тому, что данные не имеют стандартного формата. 4. Проблемы с полем BoxOfficeColleciton: a. Тип данных не соответствует наборам данных. б. В некоторых случаях к набору данных Болливуда добавлено «cr», что приводит к тому, что данные не имеют стандартного формата. 5. Проблемы с ReleaseTime: a. Значение неверно введено в набор данных Болливуда. Это исправлено вручную, так как это только одно значение. б. Значения не согласуются между двумя наборами данных. Они были заменены стандартными значениями из Постановки задачи о назначении. 6. Проблемы с полем YoutubeLikes: a. Одно нулевое значение в YoutubeLikes в наборе данных Болливуда. б. Это было исправлено за счет использования дополнительного столбца YoutubeLikeDislikes. Этот столбец содержит сумму лайков и антипатий. Используя эту информацию, мы заменили нулевое значение в YoutubeLikes на значение, равное YoutubeLikeDislikes — YoutubeDislikes из этой конкретной строки. 7. Проблемы с полем YoutubeDislikes: a. В наборе данных bollywood в YoutubeDislikes есть три нулевых значения. б. Эти значения также могут быть получены как разница между YoutubeLikeDislikes и YoutubeLikes. 8. После очистки данных как в наборах данных, так и в наборах данных мы видим, что есть фильм с повторяющимися записями. Один из них удален.

Метаинформация набора данных

dataset.info()#MetaInfo
<class 'pandas.core.frame.DataFrame'>
Int64Index: 149 entries, 0 to 98
Data columns (total 12 columns):
 #   Column               Non-Null Count  Dtype         
---  ------               --------------  -----         
 0   No                   149 non-null    int64         
 1   RelDate              149 non-null    object        
 2   MovieName            149 non-null    object        
 3   ReleaseTime          149 non-null    object        
 4   Genre                149 non-null    object        
 5   Budget               149 non-null    float32       
 6   BoxOfficeCollection  149 non-null    float32       
 7   YoutubeViews         149 non-null    int64         
 8   YoutubeLikes         149 non-null    float64       
 9   YoutubeDislikes      149 non-null    float64       
 10  YoutubeLikeDislikes  149 non-null    int64         
 11  FormattedRelDate     149 non-null    datetime64[ns]
dtypes: datetime64[ns](1), float32(2), float64(2), int64(3), object(4)
memory usage: 14.0+ KB

Всего в наборе данных 149 записей.

Фильмов в каждом жанре за время выпуска

Genre_ReleaseTime = dataset.groupby(['Genre','ReleaseTime'])['Budget'].count().reset_index().rename(columns={"Budget":"Occurrences"})
Genre_ReleaseTime.sort_values(by=['Genre'], inplace=True, ascending=False)
#Genre_ReleaseTime
pivot = Genre_ReleaseTime.pivot_table(index=['Genre'], columns = 'ReleaseTime', values=['Occurrences'], aggfunc='sum')
pivot

Выше приведено распределение фильмов, выпущенных в каждом жанре для каждого из ReleaseTime.

Месяц года, когда просматривается максимальное количество кинорелизов

dataset['yearOfRelease'], dataset['monthOfRelease'] = dataset['FormattedRelDate'].dt.year,dataset['FormattedRelDate'].dt.month
Month_Year = dataset.groupby(['yearOfRelease','monthOfRelease'])['Budget'].count().reset_index().rename(columns={"Budget":"Occurrences"})
Month_Year_max = Month_Year.loc[Month_Year.groupby(["yearOfRelease"])["Occurrences"].idxmax()]
Month_Year_max.sort_values(by=['Occurrences'], inplace=True, ascending=False)
Month_Year_max

Мы видим, что 2014 год и месяц 5 (май) имеют наибольшее количество выпусков, за ними следуют июль 2013 года с 9 выпусками и январь 2015 года с 5 выпусками.

Месяц года, когда мы смотрим высокобюджетные фильмы

Фильмы с высоким бюджетом – это фильмы с бюджетом более 25 крс. Создание столбца, содержащего это значение.

dataset['HighBudgetMovies'] = np.where((dataset['Budget'] >= 25), 'High Budget', 'Low Budget')

dataset.head(1)

Понимание общего распределения высокобюджетных фильмов за все годы.

Month_Year_Budget = dataset.groupby(['yearOfRelease','monthOfRelease','HighBudgetMovies'])['Budget'].count().reset_index().rename(columns={"Budget":"Occurrences"})
Month_Year_Budget_HighBudget = Month_Year_Budget[Month_Year_Budget.HighBudgetMovies.isin(['High Budget'])]
Month_Year_Budget_HighBudget.sort_values(by=['yearOfRelease','Occurrences'], inplace=True, ascending=False)
Month_Year_Budget_HighBudget['ConcatVal'] = Month_Year_Budget_HighBudget["yearOfRelease"].astype(str)+":"+Month_Year_Budget_HighBudget["Occurrences"].astype(str)

Month_Year_Budget_HighBudget

Мы видим, что в 2014 году есть три месяца с одинаковыми результатами. Сохранение всех результатов:

Month_Year_Budget_HighBudget_max = Month_Year_Budget_HighBudget.loc[Month_Year_Budget_HighBudget.groupby(["yearOfRelease"])["Occurrences"].idxmax()]
Month_Year_Budget_HighBudget_max.sort_values(by=['Occurrences'], inplace=True, ascending=False)
Summarized_Budget = Month_Year_Budget_HighBudget_max[['yearOfRelease','Occurrences']]
Summarized_Budget['ConcatVal'] = Summarized_Budget["yearOfRelease"].astype(str)+":"+Summarized_Budget["Occurrences"].astype(str)
Summarized_Budget
budget_result = pd.merge(Summarized_Budget, Month_Year_Budget_HighBudget, on=['ConcatVal'])
budget_result[['yearOfRelease_x','monthOfRelease','Occurrences_y']]

Мы видим, что 2013 год и 7-й месяц (июль) имеют наибольшее количество высокобюджетных релизов: 5, за которыми следуют февраль, матч и апрель 2014 года с 4 релизами и январь 2015 года с 3 релизами.

Топ-10 фильмов с максимальным ROI:

Расчет рентабельности инвестиций:

ROI = (кассовые сборы — бюджет)/бюджет

dataset['ROI'] = (dataset['BoxOfficeCollection'] - dataset['Budget'])/dataset['Budget']

dataset.head(1)

HighROI  = dataset[['MovieName','FormattedRelDate','ROI']]
HighROI.sort_values(by=['ROI'], inplace=True, ascending=False)
HighROI.head(10)

Ссылку на файлы можно найти здесь.