Учимся анализировать — полный цикл +4


Всем привет!

Контент будет ориентирован на новичков в анализе данных, ниже мы с Вами рассмотрим дата сет интернет-магазина, поставим цели и проверим гипотезы.

Язык программирования: Python

Весь код указан с пояснениями, но если у Вас возникли вопросы - отвечу в комментариях.

Начнем!!!

Интернет-магазин компьютерных игр

Цель проекта:

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

Ход исследования:

  1. Откройте файл с данными и изучите общую информацию

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

    2.1. Замените названия столбцов;

    2.2. Преобразуйте данные в нужные типы. Опишите, в каких столбцах заменили тип данных и почему;

    2.3. Обработайте пропуски при необходимости:

    2.3.1. Объясните, почему заполнили пропуски определённым образом или почему не стали это делать;

    2.3.2. Опишите причины, которые могли привести к пропускам;

    2.3.3. Обратите внимание на аббревиатуру 'tbd' в столбцах с рейтингом. Отдельно разберите это значение и опишите, как его обработать;

  3. Исследовательский анализ данных

    3.1. Посмотрите, сколько игр выпускалось в разные годы. Важны ли данные за все периоды?

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

    3.3. Возьмите данные за соответствующий актуальный период. Актуальный период определите самостоятельно в результате исследования предыдущих вопросов. Основной фактор — эти данные помогут построить прогноз на 2017 год.

    3.4. Какие платформы лидируют по продажам, растут или падают? Выберите несколько потенциально прибыльных платформ;

    3.5. Постройте график «ящик с усами» по глобальным продажам игр в разбивке по платформам. Опишите результат;

    3.6. Посмотрите, как влияют на продажи внутри одной популярной платформы отзывы пользователей и критиков. Постройте диаграмму рассеяния и посчитайте корреляцию между отзывами и продажами. Сформулируйте выводы;

  4. Составление портрета пользователя каждого региона, Определите для пользователя каждого региона (NA, EU, JP):

    4.1. Самые популярные платформы (топ-5). Опишите различия в долях продаж.

    4.2. Самые популярные жанры (топ-5). Поясните разницу.

    4.3. Влияет ли рейтинг ESRB на продажи в отдельном регионе?

  5. Проверка гипотез

    5.1. Средние пользовательские рейтинги платформ Xbox One и PC одинаковые;

    5.2. Средние пользовательские рейтинги жанров Action (англ. «действие», экшен-игры) и Sports (англ. «спортивные соревнования») разные;

    5.3. Как вы сформулировали нулевую и альтернативную гипотезы;

    5.4. Какой критерий применили для проверки гипотез и почему;

  6. Общий вывод

Опишем значения столбцов в данных для удобства в работе:

  • Name — название игры

  • Platform — платформа

  • Year_of_Release — год выпуска

  • Genre — жанр игры

  • NA_sales — продажи в Северной Америке (миллионы проданных копий)

  • EU_sales — продажи в Европе (миллионы проданных копий)

  • JP_sales — продажи в Японии (миллионы проданных копий)

  • Other_sales — продажи в других странах (миллионы проданных копий)

  • Critic_Score — оценка критиков (максимум 100)

  • User_Score — оценка пользователей (максимум 10)

  • Rating — рейтинг от организации ESRB (англ. Entertainment Software Rating Board).

    Эта ассоциация определяет рейтинг компьютерных игр и присваивает им подходящую возрастную категорию.


1. Открываем файл с данными и изучаем общую информацию

# импортируем необходимые нам библиотеки
import pandas as pd
import matplotlib.pyplot as plt
import seaborn as sns
import numpy as np
from scipy import stats as st
import warnings
warnings.filterwarnings('ignore')
читаем файл с данными и сохраненяем в переменную data
data = pd.read_csv('/datasets/games.csv')
получаем первые 10 строк таблицы
display(data.head(10))
# проверяем тип данных в столбцах таблицы
data.info()

Изучая типы данных, с использование выгрузки из таблицы выше, можно заметить, что в столбце Year_of_Release вместо значения int стоит float. Так же в столбце User_Score необходимо изменить значение на float.

# выгружаем наименования стобцов для проверки корректного отображения
data.columns

Нам необходимо поработать с заголовками столбцов, а именно привести их к единому малому регистру. Делать мы это будем уже на следующем этапе "Подготовке данных".

# проверяем уникальные значения в столбцах, важно пробежаться по каждому столбцу и проверить
data['Name'].unique()

Вывод

Подведем промежуточный итог. Мы выгрузили таблицу и присвоили переменной data, и импортировали все необходимые библиотеки, которые будут нужны для дальнейшей работы. Далее мы с помощью метода info() проверили какие типы данные в каждом столбце и выяснили, что необходимо изменить тип данных в двух столбцах: Year_of_Release, User_Score.

  • тип данных в столбце Year_of_Release необходимо изменить с float на int

  • тип данных в столбце User_Score необходимо изменить с object на float

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

  • столбец Year_of_Release - значение NaN

  • столбец Genre - значение NaN

  • столбец Critic_Score - значение NaN

  • столбец User_Score - значения NaN и tbd

  • столбец Rating - значения NaN и K-A

Все указанные корректировки мы внесем и обоснуем на следующем этапе диагностики.


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

Заменяем названия столбцов

# изменяем регистр с помощью метода str.lower()
data.columns = data.columns.str.lower()
проверяем внесенные изменения
data.columns

Index(['name', 'platform', 'year_of_release', 'genre', 'na_sales', 'eu_sales', 'jp_sales', 'other_sales', 'critic_score', 'user_score', 'rating'], dtype='object')

Еще раз просмотри ячейки, с которыми нам необходимо работать. Напомним, что некорректные, для анализа, ячейки находятся в столбцах year_of_release, genre, critic_score, user_score, rating.

# изменяем регистр zxttr столбца genre с помощью метода str.lower()
data['genre'] = data['genre'].str.lower()
выведем содержимое столбцов
display(data['year_of_release'].unique())
display(data['genre'].unique())
display(data['critic_score'].unique())
display(data['user_score'].unique())
display(data['rating'].unique())

array([2006., 1985., 2008., 2009., 1996., 1989., 1984., 2005., 1999.,
2007., 2010., 2013., 2004., 1990., 1988., 2002., 2001., 2011.,
1998., 2015., 2012., 2014., 1992., 1997., 1993., 1994., 1982.,
2016., 2003., 1986., 2000., nan, 1995., 1991., 1981., 1987.,
1980., 1983.])

array(['sports', 'platform', 'racing', 'role-playing', 'puzzle', 'misc',
'shooter', 'simulation', 'action', 'fighting', 'adventure',
'strategy', nan], dtype=object)

array([76., nan, 82., 80., 89., 58., 87., 91., 61., 97., 95., 77., 88.,
83., 94., 93., 85., 86., 98., 96., 90., 84., 73., 74., 78., 92.,
71., 72., 68., 62., 49., 67., 81., 66., 56., 79., 70., 59., 64.,
75., 60., 63., 69., 50., 25., 42., 44., 55., 48., 57., 29., 47.,
65., 54., 20., 53., 37., 38., 33., 52., 30., 32., 43., 45., 51.,
40., 46., 39., 34., 35., 41., 36., 28., 31., 27., 26., 19., 23.,
24., 21., 17., 22., 13.])

array(['8', nan, '8.3', '8.5', '6.6', '8.4', '8.6', '7.7', '6.3', '7.4',
'8.2', '9', '7.9', '8.1', '8.7', '7.1', '3.4', '5.3', '4.8', '3.2',
'8.9', '6.4', '7.8', '7.5', '2.6', '7.2', '9.2', '7', '7.3', '4.3',
'7.6', '5.7', '5', '9.1', '6.5', 'tbd', '8.8', '6.9', '9.4', '6.8',
'6.1', '6.7', '5.4', '4', '4.9', '4.5', '9.3', '6.2', '4.2', '6',
'3.7', '4.1', '5.8', '5.6', '5.5', '4.4', '4.6', '5.9', '3.9',
'3.1', '2.9', '5.2', '3.3', '4.7', '5.1', '3.5', '2.5', '1.9', '3',
'2.7', '2.2', '2', '9.5', '2.1', '3.6', '2.8', '1.8', '3.8', '0',
'1.6', '9.6', '2.4', '1.7', '1.1', '0.3', '1.5', '0.7', '1.2',
'2.3', '0.5', '1.3', '0.2', '0.6', '1.4', '0.9', '1', '9.7'],
dtype=object)

array(['E', nan, 'M', 'T', 'E10+', 'K-A', 'AO', 'EC', 'RP'], dtype=object)

В столбце user_score выделим значение tbd. Выше мы воспользовались методом info() и обратили внимание, что формат ячейки object. Хотя судя по общему содержанию, а так же по описанию столбца (оценка пользователей (максимум 10)) тип данных должен быть float. Поэтому предлагаю считать данное значение (tbd) пустым и изменить на NaN.

# Функция для замены значения 'tbd' на NaN
def replace_wrong_user_scores(wrong_user_scores, correct_user_score):
data['user_score'] = data['user_score'].replace(wrong_user_scores, correct_user_score)
replace_wrong_user_scores('tbd', np.NaN)
проверяем уникальные значения в столбце после применения функции
data['user_score'].unique()

array(['8', nan, '8.3', '8.5', '6.6', '8.4', '8.6', '7.7', '6.3', '7.4', '8.2', '9', '7.9', '8.1', '8.7', '7.1', '3.4', '5.3', '4.8', '3.2', '8.9', '6.4', '7.8', '7.5', '2.6', '7.2', '9.2', '7', '7.3', '4.3', '7.6', '5.7', '5', '9.1', '6.5', '8.8', '6.9', '9.4', '6.8', '6.1', '6.7', '5.4', '4', '4.9', '4.5', '9.3', '6.2', '4.2', '6', '3.7', '4.1', '5.8', '5.6', '5.5', '4.4', '4.6', '5.9', '3.9', '3.1', '2.9', '5.2', '3.3', '4.7', '5.1', '3.5', '2.5', '1.9', '3', '2.7', '2.2', '2', '9.5', '2.1', '3.6', '2.8', '1.8', '3.8', '0', '1.6', '9.6', '2.4', '1.7', '1.1', '0.3', '1.5', '0.7', '1.2', '2.3', '0.5', '1.3', '0.2', '0.6', '1.4', '0.9', '1', '9.7'], dtype=object)

Значение в столбце user_score скорректировано и далее уже будем работать со значением NaN.

В столбце rating есть два значения 'K-A' и 'E10+' - это два значения носящие один и тот же смысл (первоначально "K-A" ("Kids to Adults"), потом было переименовано на E10+), поэтому предлагаю переименовать 'K-A' в 'E10+' для удобного и более точного анализа в дальнейшем.

# Функция для замены значения 'K-A' на 'E10+'
def replace_wrong_ratings(wrong_ratings, correct_rating):
data['rating'] = data['rating'].replace(wrong_ratings, correct_rating)
replace_wrong_ratings('K-A', 'E10+')
data['rating'].value_counts()

E 3990
T 2961
M 1563
E10+ 1423
EC 8
RP 3
AO 1
Name: rating, dtype: int64

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

# Функция для замены значения аббревиатур на полное название бля понимание, что это за игровая платформа.
def replace_wrong_platforms(wrong_platforms, correct_platform):
data['platform'] = data['platform'].replace(wrong_platforms, correct_platform)
replace_wrong_platforms('2600', 'Atari 2600')
replace_wrong_platforms('Wii', 'Nintendo Wii')
replace_wrong_platforms('NES', 'Nintendo NES')
replace_wrong_platforms('GB', 'GB-60')
replace_wrong_platforms('DS', 'Nintendo DS')
replace_wrong_platforms('X360', 'Xbox 360')
replace_wrong_platforms('SNES', 'Nintendo SNES')
replace_wrong_platforms('GBA', 'Game Boy Advance')
replace_wrong_platforms('3DS', 'Nintendo 3DS')
replace_wrong_platforms('N64', 'Nintendo 64')
replace_wrong_platforms('XB', 'Xbox')
replace_wrong_platforms('XOne', 'Xbox One')
replace_wrong_platforms('WiiU', 'Nintendo Wii U')
replace_wrong_platforms('GC', 'Nintendo GameCube')
replace_wrong_platforms('GEN', 'SEGA Retro Genesis')
replace_wrong_platforms('DC', 'Dendy Classic')
replace_wrong_platforms('PSV', 'PS Vita')
replace_wrong_platforms('SAT', 'Sega Saturn')
replace_wrong_platforms('WS', 'WonderSwan')
replace_wrong_platforms('TG16', 'NEC TurboGrafx')
replace_wrong_platforms('3DO', 'Panasonic 3DO')
replace_wrong_platforms('GG', 'Game Gear')
replace_wrong_platforms('PCFX', 'NEC PC-FX')
проверяем уникальные значения в столбце
display(data['platform'].unique())

array(['Nintendo Wii', 'Nintendo NES', 'GB-60', 'Nintendo DS', 'Xbox 360', 'PS3', 'PS2', 'Nintendo SNES', 'Game Boy Advance', 'PS4', 'Nintendo 3DS', 'Nintendo 64', 'PS', 'Xbox', 'PC', 'Atari 2600', 'PSP', 'Xbox One', 'Nintendo Wii U', 'Nintendo GameCube', 'SEGA Retro Genesis', 'Dendy Classic', 'PS Vita', 'Sega Saturn', 'SCD', 'WonderSwan', 'NG', 'NEC TurboGrafx', 'Panasonic 3DO', 'Game Gear', 'NEC PC-FX'], dtype=object)

Обрабатываем пропущенные значения

Вначале c помощью методов .isna().sum() смотрим в каких столбцах есть пропуска, далее нам нужно понять удалять эти строки или заполнить по среднему значению или медиане.

data.isna().sum()

name 2
platform 0
year_of_release 269
genre 2
na_sales 0
eu_sales 0
jp_sales 0
other_sales 0
critic_score 8578
user_score 9125
rating 6766
dtype: int64

В 6 столбцах есть пустые ячейки. Приступим к изучению.

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

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

  • со столбцом year_of_release есть названия игр с указанием года выпуска и в итоге будет выглядеть не совсем логично (на примере ИД16373 игра с названием 'PDC World Championship Darts 2008' и год не указан.) Поэтому предлагаю удалить пропуска, чтобы не было нелогичного установления года выпуска. Пропуск в данном столбце мог возникнуть из-за того, что при заполнении данных об игре забыли указать или точная дата выхода игры точно не определена.

  • столбец genre так же сложно подвести к какому-либо значению, т.к. необходимо знать конкретную игру. Так же удаляем строки с пустыми значениями. Пропуск в данном столбце мог возникнуть из-за того, что при заполнении данных об игре его забыли указать или не определились к какому именно жанру относится видеоигра.

  • столбец rating так же подлежит удалению, т.к. мы не сможем понять возрастное ограничение, если не будем знать это точно.

# удаляем строки с пустыми значениями в столбцах
data.dropna(subset = ['name', 'year_of_release', 'genre'], inplace = True)
Функция для присвоения пропущенных значениям в столбце 'rating' на значение 'неопределенные'
def replace_wrong_user_scores(wrong_user_scores, correct_user_score):
data['rating'] = data['rating'].replace(wrong_user_scores, correct_user_score)
replace_wrong_user_scores(np.NaN, 'неопределенный')

Изменим тип данных в столбцах year_of_release и user_score.

# после удаления пропусков и корректировки неверных значений ячеек в столбцах необходимо перевести значения в корректный формат
data['year_of_release'] = data['year_of_release'].astype(int)
data['user_score'] = data['user_score'].astype(float)
проверяем изменение типов
data.info()

<class 'pandas.core.frame.DataFrame'>
Int64Index: 16444 entries, 0 to 16714
Data columns (total 11 columns):
name 16444 non-null object
platform 16444 non-null object
year_of_release 16444 non-null int64
genre 16444 non-null object
na_sales 16444 non-null float64
eu_sales 16444 non-null float64
jp_sales 16444 non-null float64
other_sales 16444 non-null float64
critic_score 7983 non-null float64
user_score 7463 non-null float64
rating 16444 non-null object
dtypes: float64(6), int64(1), object(4)
memory usage: 1.5+ MB

# заполняем столбцы critic_score, user_score медианой по платформе
data.loc[data['critic_score'].isna(), 'critic_score'] = -1
data.loc[data['user_score'].isna(), 'user_score'] = -1
проверяем количество пропусков после удаления
data.isna().sum()

name 0
platform 0
year_of_release 0
genre 0
na_sales 0
eu_sales 0
jp_sales 0
other_sales 0
critic_score 0
user_score 0
rating 0
dtype: int64

Отлично! С пропусками мы разобрались.
Теперь типы данных корректные. Таблица готова к дальнейшей диагностике.

Посчитаем суммарные продажи во всех регионах

Необходимо посчитать сумму продаж во всех регионах. Для этого суммируем значения нескольких столбцов (na_sales, eu_sales, jp_sales, other_sales) и полученные значения присвоить столбцу sum_sales_game.

# создадим отдельную таблицу для проведения общих расчетов, в дальнейшем она нам понадобится
data_all = data
посчитаем суммарные продажи во всех регионах
data['sum_sales_game'] =  data[['na_sales','eu_sales','jp_sales', 'other_sales']].sum(axis = 1)
проверим
data.head(10)

Вывод

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

Далее нам необходимо проверить уже известные нам столбцы (year_of_release, genre, critic_score, user_score, rating) на наличие некорректных значений в ячейка. Помимо пустых ячеек NaN мы видим и другие значения. В столбце user_score выделим значение tbd. Выше мы воспользовались методом info() и обратили внимание, что формат ячейки object. Хотя судя по общему содержанию, а так же по описанию столбца (оценка пользователей (максимум 10)) тип данных должен быть float. Поэтому предлагаю считать данное значение (tbd) пустым и изменить на NaN. Значение в столбце user_score скорректировано и далее уже будем работать со значением NaN. В столбце rating есть два значения 'K-A' и 'E10+' - это два значения носящие один и тот же смысл (первоначально "K-A" ("Kids to Adults"), потом было переименовано на E10+), поэтому предлагаю переименовать 'K-A' в 'E10+' для удобного и более точного анализа в дальнейшем.

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

Следующей стадией будет обработка пропусков. Выяснить какие именно значения у нас пропущены и какое количество поможет метод isna().sum()

В 6 столбцах есть пустые ячейки. Приступим к изучению.

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

  • в столбцах critic_scoreuser_score довольно много значений и поэтому мы рассчитаем присвоили значение -1 по пустым показателям, т.к. пропуски могут повлиять на дальнейшую аналитику. Причиной отсутствия рейтинга может быть просто отсутствие оценок (неоцененные игры) или же игры были недавнего вышедшие и еще не получили свои оценки.

  • со столбцом year_of_release есть названия игр с указанием года выпуска и в итоге будет выглядеть не совсем логично (на примере ИД16373 игра с названием 'PDC World Championship Darts 2008' и год не указан.) Поэтому предлагаю удалить пропуска, чтобы не было нелогичного установления года выпуска. Пропуск в данном столбце мог возникнуть из-за того, что при заполнении данных об игре забыли указать или точная дата выхода игры точно не определена.

  • столбец genre так же сложно подвести к какому-либо значению, т.к. необходимо знать конкретную игру. Так же удаляем строки с пустыми значениями. Пропуск в данном столбце мог возникнуть из-за того, что при заполнении данных об игре его забыли указать или не определились к какому именно жанру относится видеоигра.

  • пустые значения столбца rating были заполнены значением "неопределенный"

После удаления пропусков мы приступим к изменению типа ячеек в столбцах year_of_release и user_score, как описывалось выше.

И напоследок выведем отдельный столбец с суммарным количеством продаж по всем регионам.


3. Исследовательский анализ данных

Посчитаем сколько игр вышло в разные года по разным платформам. Для этого сделаем 2 выгрузки: - первая выгрузка покажет нам сумму игр в группировке по игровой платформе и годам. - вторая выгрузка - общее количество игр по годам.

# первая выгрузка
count_games_1 = data.groupby(['platform', 'year_of_release'])['name'].count()
count_games_1

platform year_of_release
Atari 2600 1980 9
1981 46
1982 36
1983 11
1984 1
..
Xbox 360 2016 13
Xbox One 2013 19
2014 61
2015 80
2016 87
Name: name, Length: 238, dtype: int64

Теперь посчитаем сколько игр вышло в разные года по всем платформам.

# вторая выгрузка
count_games_2 = data.groupby('year_of_release')['name'].count()
count_games_2

year_of_release
1980 9
1981 46
1982 36
1983 17
1984 14
1985 14
1986 21
1987 16
1988 15
1989 17
1990 16
1991 41
1992 43
1993 60
1994 121
1995 219
1996 263
1997 289
1998 379
1999 338
2000 350
2001 482
2002 829
2003 775
2004 762
2005 939
2006 1006
2007 1197
2008 1427
2009 1426
2010 1255
2011 1136
2012 653
2013 544
2014 581
2015 606
2016 502
Name: name, dtype: int64

Для дальнейшей диагностики выделим года, по которым будет оптимально анализировать динамику продаж. Берем 2015 и 2016 года.

# оставим в выгрузке только нужные года
data = data.query("2015 <= year_of_release <= 2016")
построим график распределения по годам
data.pivot_table(index='year_of_release', columns = 'platform', values='sum_sales_game', aggfunc='sum').plot(grid=True, figsize=(15, 7))
plt.show()

Посмотрим, как менялись продажи по платформам.

На графике мы можем заметить, что продажи в течении года стремительно уменьшались и из всех платформ в выборке остались только две, по которым показатели значительно положительные. Это платформы Xbox One, PS4. По остальным платформам показатель близится к 0.
Далее выведем таблицу с подсчетом общих продаж.

# суммируем столбцы продаж и добавим результат в столбец sum_sales_game
data.groupby(['platform'])['na_sales', 'eu_sales', 'jp_sales', 'other_sales', 'sum_sales_game'].sum()

Из данной выгрузки мы можем выделить две игровые платформы с наибольшими суммарными продажами. Выделим от 40 млн продаж - это платформы: Xbox One, PS4, тем самым мы отсеиваем мало продаваемые позиции и устаревшие.

# обновим выгрузку и оставим только интересующие нас платформы
data = data.query("platform == ['Xbox One', 'PS4']")
data

На графике выше мы видим самые продаваемые позиции за период с 2015 по 2016 года. Обратим внимание, что все платформы, кроме Xbox One, PS4 к 2016 году приравниваются к 0 продаж.

За какой характерный срок появляются новые и исчезают старые платформы?

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

Исчезновение старых моделей так же было постепенно, относительно их появления, за исключением платформ Nintendo. Хоть они и появились в разные периоды, но эпоха Nintendo закончила в один год.

Возьмем данные за актуальный период, которые определим самостоятельно.

Актуальные период для прогноза на 2017 возьмем с 2015 по 2016 года. Данный период выбран в связи с тем, чтобы мы могли посмотреть какие платформы в принципе не будут продаваться. Если сделать период меньше, то часть данных будет урезана.

# Построим график распределения по годам с 2015 по 2016 (актуальный период)
data = data.query("platform == ['Xbox One', 'PS4'] and year_of_release == ['2015', '2016']")
data.pivot_table(index='year_of_release', columns = 'platform', values='sum_sales_game', aggfunc='sum').plot(grid=True, figsize=(15, 7))
# меняем наименование горизонтальной линии ('X')
plt.xlabel('Год и месяц реализации')
# меняем наименование вертикальной линии ('Y')
plt.ylabel('Продажи экземпляров (млн.)')
plt.show()

В данном обсуждении мы будем отталкиваться от актуального периода (2015-2016 года).
Если отталкивать от нашего графика, то можно сделать следующий вывод - потенциально прибыльной платформой можно считать PS4 и Xbox One. Именно эта платформа дольше всего "на плаву". Xbox One так же имеет продажи, но значительно меньше. Но так как продажи более 20 млн. - так же в рассмотрении.

Постройте график «ящик с усами» по глобальным продажам игр в разбивке по платформам. Опишите результат.

data.groupby('platform')['sum_sales_game'].describe()
# построим общую диаграмму размаха
data.boxplot(column='sum_sales_game', by='platform')
plt.show()

Просмотрев общую диаграмму размаха мы видели частые выбросы и редкие. Данные выбросы предлагаю оставить, т.к. есть игры, которые могли "стрельнуть" большими продажами.

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

Для диагностики возьмем платформу PS4, т.к. у этой платформы значительные продажи в 2016 году.

# выведем таблицу рассеивания по платформе PS3, отобразив отзывы пользователей
data[data['platform']=='PS4'].plot(x='user_score', y='sum_sales_game', kind='scatter', alpha=0.3, figsize=(8,8), grid=True)
plt.show()
# выведем таблицу рассеивания по платформе PS3, отобразив отзывы критиков
data[data['platform']=='PS4'].plot(x='critic_score', y='sum_sales_game', kind='scatter', alpha=0.3, figsize=(8,8), grid=True)
plt.show()
# вычислим корреляционную матрицу, диапазон элементов которой равен [-1, 1], по умолчанию она использует коэффициент корреляции Пирсона. sns.heatmap -это просто способ показать с помощью цветов, насколько сильны корреляции, где зеленый цвет в данном случае предполагает положительную корреляцию, близкую к 1 .
data_ps4 = data[data['platform']=='PS4']
data_ps4_cor = data_ps4['user_score'].corr(data_ps4['sum_sales_game'])
display('Корреляция слабо положительная: {}'.format(data_ps4_cor))

'Корреляция слабо положительная: 0.07810659085915489'

# вычислим корреляционную матрицу, диапазон элементов которой равен [-1, 1], по умолчанию она использует коэффициент корреляции Пирсона. sns.heatmap -это просто способ показать с помощью цветов, насколько сильны корреляции, где зеленый цвет в данном случае предполагает положительную корреляцию, близкую к 1 .
#data_ps4_1 = data[data['platform']=='PS4']
создаем выгрузку без заглушек
data_without_user = data_ps4[data_ps4['user_score'] != -1]
data_without_user_cor = data_without_user['user_score'].corr(data_without_user['sum_sales_game'])
display('Корреляция слабо отрицательная: {}'.format(data_without_user_cor))

'Корреляция слабо отрицательная: -0.05973845712638215'

	# вычислим корреляционную матрицу, диапазон элементов которой равен [-1, 1], по умолчанию она использует коэффициент корреляции Пирсона. sns.heatmap -это просто способ показать с помощью цветов, насколько сильны корреляции, где зеленый цвет в данном случае предполагает положительную корреляцию, близкую к 1 .
#data_ps4_1 = data[data['platform']=='PS4']
data_ps4_cor = data_ps4['critic_score'].corr(data_ps4['sum_sales_game'])
display('Корреляция слабо положительная: {}'.format(data_ps4_cor))

'Корреляция слабо положительная: 0.18098000145868295'

# создаем выгрузку без заглушек
data_without_critic = data_ps4[data_ps4['critic_score'] != -1]
data_without_critic_cor = data_without_critic['critic_score'].corr(data_without_critic['sum_sales_game'])
display('Корреляция слабо положительная: {}'.format(data_without_critic_cor))

'Корреляция слабо положительная: 0.3928485555130601'

Перед подведение итогов еще раз посмотрим на продажи PS4

# Построим график распределения по годам с 2015 по 2016 (актуальный период)
ps3 = data.query("platform == ['PS4'] and year_of_release == ['2015', '2016']")
ps3.pivot_table(index='year_of_release', columns = 'platform', values='sum_sales_game', aggfunc='sum').plot(grid=True, figsize=(15, 7))
plt.show()

Сделаем небольшой вывод:
Просмотрев соотношение отзывов покупателе и критиков можно сказать, что большую часть составляют высокие оценки. Мы выяснили, что по данным из диаграммы рассеивания у нас:- слабо отрицательная корреляция -0.05973845712638215 по отзывам покупателей- слабо положительная корреляция 0.3928485555130601 по отзывам критиков

Сравним выводы с продажами игр на других платформах.

# воспользуемся переменной data_all со всеми платформами
data_all.groupby('platform')['sum_sales_game'].describe()

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

# выводим диаграмму размаха общего плана
data_all.boxplot(column='sum_sales_game', by='platform', figsize=(25,7))
plt.show()

В представленной диаграмме мы видим, что есть очень редкие выбросы с продажами в 80 млн (видимо эта игра была очень популярная игра), так же редкие, в отличии от других, выбросы есть в диапазоне от 20 до 40 млн. Уберем эти выбросы и еще раз посмотрим на диаграмму размаха.

# теперь сужаем диапазон до 20 млн продаж
data_all.boxplot(column='sum_sales_game', by='platform', figsize=(25,7))
# подгоняем данные по стороне 'Y'
plt.ylim(0, 20)
plt.show()

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

# сужаем диапазон до 5 млн продаж
data_all.boxplot(column='sum_sales_game', by='platform', figsize=(25,7))
# подгоняем данные по стороне 'Y'
plt.ylim(0, 5)
plt.show()

В диаграмме размаха выше можно было бы оставить этот вариант, но я предлагаю еще сузить диапазон до 3.9 млн

# сужаем диапазон до 3.9 млн продаж
data_all.boxplot(column='sum_sales_game', by='platform', figsize=(25,7))
# подгоняем данные по стороне 'Y'
plt.ylim(0, 3.9)
plt.show()

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

Если сравнить продажи платформ из нашей выборки с теми, которые не попали в нее, то после просмотра диаграмм размаха с разными диапазонами можем подвести небольшой ИТОГ.

Можем выделить несколько платформ, которые выделяются: PS и PS4 и Xbox One. Границы этих платформ высокие, но при всем при этом медиана у всех платформ, кроме PS и PS3, не выходит за рамки 0.5 млн продаж, т.к. медиана и размах примерно на одном уровне, можно сказать, что у наших платформ, в отличии от тех, которые не попали в выборку есть намного больше игр, которые покупались намного чаще.

Предположим, потому что каждые из платформ из выборки были с нововведением:

Nintendo DS - платформа с 2 дисплееями, что то новое;
Nintendo Wii - платформа с дистанционной игрой;
PS2 - габариты данной платформы могли вызвать ажиотаж в покупке;
PS3 - появления функционала с дистанционной игрой, а так жсе платформа с возможностью выхода в интернет;
Xbox 360 - аналогия PS3 c иными джостиками.

Остальным приставки, были или такими же по функционалу и просто усовершенственной версией или такие платформы как Dendy Classic или Game Boy Advance были доступны не всем сегментам людей.

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

Посмотрим на общее распределение игр по жанрам.

# посмотрим популярность жанров на всех платформах за все время
(
    data_all.pivot_table(index='genre', values='sum_sales_game', aggfunc='median')
    .boxplot(column='sum_sales_game', by='genre', figsize=(25,7))
)
plt.show()
(
data_all.pivot_table(index='genre', values='sum_sales_game', aggfunc='median')
.plot(grid=True, figsize=(12, 5))
)
plt.show()

В круговой диаграмме мы можем выделить ТОП-5 жанров:
1. Platform
2. Shooter
3. Sports
4. Fighting
5. Action

ТОП-5 самых непопулярных жанров:
1. Adventure
2. Puzzle
3. Strategy
4. Simulation
5. Misc

Теперь посмотрим какие будут результаты согласно нашей выборке. Будут ли они отличаться?

Посмотрим на распределение игр по жанрам в нашей выгрузке на 2016 год.

# смотрим популярность жанров исходя из нашей выборки
(
data.pivot_table(index='genre', values='sum_sales_game', aggfunc='median')
.boxplot(column='sum_sales_game', by='genre', figsize=(25,7))
)
plt.show()
(
data.pivot_table(index='genre', values='sum_sales_game', aggfunc='median')
.plot(grid=True, figsize=(12, 5))
)
plt.show()

В круговой диаграмме мы можем выделить ТОП-5 жанров:
1. Shooter
2. Sports
3. Role-Playing
4. Fighting
5. Platform

ТОП-5 самых непопулярных жанров:
1. Puzzle
2. Adventure
3. Misc
4. Strategy
5. Racing

Вывод

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

Далее мы посчитаем суммарное количество продаж по каждой платформе в рамках выше указанных годов. По изучению суммарных показателей мы можем выделить самые продаваемые платформы с продажами 40 млн и более. У нас вышли следующие платформы (PS4 и Xbox One). Корректируем нашу выгрузку и оставляем в ней только эти позиции.

Теперь займемся построением графиков распределения.

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

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

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

Можно выделить лидирующую платформу - PS4.

Далее мы оставляем все выбросы, т.к. они нам важны для дальнейшей аналитики.

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

  • по оценкам покупателей корреляция слабо отрицательная: -0.0652804641386599

  • по оценкам критиков корреляция слабо положительная: 0.3914585293351539Далее мы решили сравнить показатели со всеми платформами которые выпускали и после вывода финальной диаграммы подвели итоги. Так как все подробно расписано дублировать здесь не будем, можете ознакомиться выше по проекту.

И последнее, что мы сделаем в анализе данных, это сравним показатели по жанрам и выясним отличаются топовые жанры нашей выгрузки от топовых жанров всех платформ.

Выяснилось следующее:

  • Жанры Fighting, Shooter, Sports занимают с первого по третье место как в общей выборке, так и в нашей финальной таблице, а вот 4 и 5 места разнятся (в нашей выгрузки это Simulation и Role-Playing)

  • ТОП-5 самых непопулярных жанров содержит одинаковые жанры, что в общей выгрузке, что в нашей.

В круговой диаграмме мы можем выделить ТОП-5 жанров:

  1. Platform

  2. Shooter

  3. Sports

  4. Fighting

  5. Action

    ТОП-5 самых непопулярных жанров:

  6. Shooter

  7. Sports

  8. Role-Playing

  9. Fighting

  10. Platform


4. Составление портрета пользователя каждого региона

Определим для пользователя каждого региона:

  • самые популярные платформы (топ-5)

  • самые популярные жанры (топ-5)

ТОП-5 самых популярных платформ в Северной Америке

# ТОП-5 самых популярных платформ в Северной Америке по общей таблице
группируем по платформе
platform_na_all = data_all.groupby('platform')['na_sales'].sum().sort_values(ascending=False).head(5)
построим гистограмму
platform_na_all.plot(x = 'platform', y = 'na_sales', kind = 'bar', figsize=(20,8), grid=True, title = 'ТОП-5 самых популярных платформ в Северной Америке')
меняем наименование горизонтальной линии ('X')
plt.xlabel('Платформа')
меняем наименование вертикальной линии ('Y')
plt.ylabel('Продажи экземпляров (млн.)')
plt.show()
# ТОП-5 самых популярных платформ в Северной Америке по нашей таблице
группируем по платформе
platform_na = data.groupby('platform')['na_sales'].sum()
построим гистограмму
platform_na.plot(x = 'platform', y = 'na_sales', kind = 'bar', figsize=(20,8), grid=True, title = 'ТОП-5 самых популярных платформ в Северной Америке по нашей таблице')
меняем наименование горизонтальной линии ('X')
plt.xlabel('Платформа')
меняем наименование вертикальной линии ('Y')
plt.ylabel('Продажи экземпляров (млн.)')
plt.show()
# считаем долю продаж в Северной Америке по нашей таблице
переменной platform_count_full присваиваем сумму общих продаж по всем платформам
platform_count_full = data.groupby('platform')['sum_sales_game'].sum()
вычисляем процентное соотношение
percent_na = platform_na / platform_count_full * 100
display('Доля продаж в Северной Америке:')
display(percent_na.sort_values(ascending=False))

'Доля продаж в Северной Америке:'
platform
Xbox One 58.291807
PS4 33.941005
dtype: float64

Общая выгрузка носит ознакомительный характер.
Так как мы взяли данные для анализа за 2015-2016 года - вот ТОП-5.

ТОП-5 самых популярных платформ в Северной Америке по нашей таблице:
1. Xbox One
2. PS4

ТОП-5 самых популярных платформ в Европе

# ТОП-5 самых популярных платформ в Европе по общей таблице
группируем по платформе
platform_eu_all = data_all.groupby('platform')['eu_sales'].sum().sort_values(ascending=False).head(5)
построим гистограмму
platform_eu_all.plot(x = 'platform', y = 'eu_sales', kind = 'bar', figsize=(20,8), grid=True, title = 'ТОП-5 самых популярных платформ в Европе')
меняем наименование горизонтальной линии ('X')
plt.xlabel('Платформа')
меняем наименование вертикальной линии ('Y')
plt.ylabel('Продажи экземпляров (млн.)')
plt.show()
# ТОП-5 самых популярных платформ в Европе по нашей таблице
группируем по платформе
platform_eu = data.groupby('platform')['eu_sales'].sum()
построим гистограмму
platform_eu.plot(x = 'platform', y = 'eu_sales', kind = 'bar', figsize=(20,8), grid=True, title = 'ТОП-5 самых популярных платформ в Европе по нашей таблице')
меняем наименование горизонтальной линии ('X')
plt.xlabel('Платформа')
меняем наименование вертикальной линии ('Y')
plt.ylabel('Продажи экземпляров (млн.)')
plt.show()
# считаем долю продаж в Европе по нашей таблице
вычисляем процентное соотношение
percent_eu = platform_eu / platform_count_full * 100
display('Доля продаж в Европе:')
display(percent_eu.sort_values(ascending=False))

'Доля продаж в Европе:'
platform
PS4 44.400744
Xbox One 32.564608
dtype: float64

ТОП-5 самых популярных платформ в Европе по нашей таблице:
1. PS4
2. Xbox One

ТОП-5 самых популярных платформ в Японии

# ТОП-5 самых популярных платформ в Японии по общей таблице
группируем по платформе
platform_jp_all = data_all.groupby('platform')['jp_sales'].sum().sort_values(ascending=False).head(5)
построим гистограмму
platform_jp_all.plot(x = 'platform', y = 'jp_sales', kind = 'bar', figsize=(20,8), grid=True, title = 'ТОП-5 самых популярных платформ в Японии')
меняем наименование горизонтальной линии ('X')
plt.xlabel('Платформа')
меняем наименование вертикальной линии ('Y')
plt.ylabel('Продажи экземпляров (млн.)')
plt.show()
# ТОП-5 самых популярных платформ в Японии по нашей таблице
группируем по платформе
platform_jp = data.groupby('platform')['jp_sales'].sum()
построим гистограмму
platform_jp.plot(x = 'platform', y = 'jp_sales', kind = 'bar', figsize=(20,8), grid=True, title = 'ТОП-5 самых популярных платформ в Японии по нашей таблице')
меняем наименование горизонтальной линии ('X')
plt.xlabel('Платформа')
меняем наименование вертикальной линии ('Y')
plt.ylabel('Продажи экземпляров (млн.)')
plt.show()
# считаем долю продаж в Японии по нашей таблице
вычисляем процентное соотношение
percent_jp = platform_jp / platform_count_full * 100
display('Доля продаж в Японии:')
display(percent_jp.sort_values(ascending=False))

'Доля продаж в Японии:'
platform
PS4 6.404465
Xbox One 0.208599
dtype: float64

ТОП-5 самых популярных платформ в Японии по нашей таблице:
1. PS4
2. Xbox One

ТОП-5 самых популярных платформ в остальных регионах

# ТОП-5 самых популярных платформ в остальных регионах по общей таблице
группируем по платформе
platform_other_all = data_all.groupby('platform')['other_sales'].sum().sort_values(ascending=False).head(5)
построим гистограмму
platform_other_all.plot(x = 'platform', y = 'other_sales', kind = 'bar', figsize=(20,8), grid=True, title = 'ТОП-5 самых популярных платформ в остальных регионах')
меняем наименование горизонтальной линии ('X')
plt.xlabel('Платформа')
меняем наименование вертикальной линии ('Y')
plt.ylabel('Продажи экземпляров (млн.)')
plt.show()
# ТОП-5 самых популярных платформ в остальных регионах по нашей таблице
группируем по платформе
platform_other = data.groupby('platform')['other_sales'].sum()
построим гистограмму
platform_other.plot(x = 'platform', y = 'other_sales', kind = 'bar', figsize=(20,8), grid=True, title = 'ТОП-5 самых популярных платформ в остальных регионах по нашей таблице')
меняем наименование горизонтальной линии ('X')
plt.xlabel('Платформа')
меняем наименование вертикальной линии ('Y')
plt.ylabel('Продажи экземпляров (млн.)')
plt.show()
# считаем долю продаж в остальных регионах по нашей таблице
вычисляем процентное соотношение
percent_other = platform_other / platform_count_full * 100
display('Доля продаж в остальных регионах:')
display(percent_other.sort_values(ascending=False))

'Доля продаж в остальных регионах:'
platform
PS4 15.253787
Xbox One 8.934987
dtype: float64

ТОП-5 самых популярных платформ в остальных регионах по нашей таблице:
1. PS4
2. Xbox One

Самые популярные жанры (топ-5)

ТОП-5 самых популярных жанров в Северной Америке

# ТОП-5 самых популярных жанров в Северной Америке по общей таблице
переменной genre_count_full присваиваем сумму общих продаж по всем жанрам
genre_count_full = data.groupby('genre')['sum_sales_game'].sum()
группируем по жанрам
genre_na = data.groupby('genre')['na_sales'].sum().sort_values(ascending=False).head(5)
построим гистограмму
genre_na.plot(x = 'genre', y = 'na_sales', kind = 'bar', figsize=(20,8), grid=True, title = 'ТОП-5 самых популярных жанров в Северной Америке')
меняем наименование горизонтальной линии ('X')
plt.xlabel('Жанр')
меняем наименование вертикальной линии ('Y')
plt.ylabel('Продажи экземпляров (млн.)')
plt.show()
# ТОП-5 самых популярных жанров в Северной Америке по нашей таблице
группируем по жанрам
genre_na = data.groupby('genre')['na_sales'].sum().sort_values(ascending=False).head(5)
построим гистограмму
genre_na.plot(x = 'genre', y = 'na_sales', kind = 'bar', figsize=(20,8), grid=True, title = 'ТОП-5 самых популярных жанров в Северной Америке по нашей таблице')
меняем наименование горизонтальной линии ('X')
plt.xlabel('Жанр')
меняем наименование вертикальной линии ('Y')
plt.ylabel('Продажи экземпляров (млн.)')
plt.show()
# считаем долю продаж в Северной Америке по нашей таблице
вычисляем процентное соотношение
genre_percent_na = genre_na / genre_count_full * 100
display('Доля продаж в Северной Америке:')
display(genre_percent_na.sort_values(ascending=False).head(5))

'Доля продаж в Северной Америке:'
genre
fighting 46.611910
shooter 46.340412
sports 40.804598
role-playing 39.038760
action 38.612903
dtype: float64

ТОП-5 самых популярных жанров в Северной Америке по нашей таблице:
1. Fighting
2. Shooter
3. Sports
4. Role-Playing
5. Action

ТОП-5 самых популярных жанров в Европе

# ТОП-5 самых популярных жанров в Европе по общей таблице
группируем по жанрам
genre_eu = data.groupby('genre')['eu_sales'].sum().sort_values(ascending=False).head(5)
построим гистограмму
genre_eu.plot(x = 'genre', y = 'eu_sales', kind = 'bar', figsize=(20,8), grid=True, title = 'ТОП-5 самых популярных жанров в Европе')
меняем наименование горизонтальной линии ('X')
plt.xlabel('Жанр')
меняем наименование вертикальной линии ('Y')
plt.ylabel('Продажи экземпляров (млн.)')
plt.show()
# ТОП-5 самых популярных жанров в Европе по нашей таблице
группируем по жанрам
genre_eu = data.groupby('genre')['eu_sales'].sum().sort_values(ascending=False).head(5)
построим гистограмму
genre_eu.plot(x = 'genre', y = 'eu_sales', kind = 'bar', figsize=(20,8), grid=True, title = 'ТОП-5 самых популярных жанров в Европе по нашей таблице')
меняем наименование горизонтальной линии ('X')
plt.xlabel('Жанр')
меняем наименование вертикальной линии ('Y')
plt.ylabel('Продажи экземпляров (млн.)')
plt.show()
# считаем долю продаж в Европе по нашей таблице
вычисляем процентное соотношение
genre_percent_eu = genre_eu / genre_count_full * 100
display('Доля продаж в Европе:')
display(genre_percent_eu.sort_values(ascending=False).head(5))

'Доля продаж в Европе:'
genre
racing 59.209257
sports 44.094332
action 41.096774
role-playing 38.201550
shooter 38.104991
dtype: float64

ТОП-5 самых популярных жанров в Европе по нашей таблице:
1. Shooter
2. Sports
3. Action
4. Adventure
5. Role-Playing

ТОП-5 самых популярных жанров в Японии

# ТОП-5 самых популярных жанров в Японии по общей таблице
группируем по жанрам
genre_jp = data.groupby('genre')['jp_sales'].sum().sort_values(ascending=False).head(5)
построим гистограмму
genre_jp.plot(x = 'genre', y = 'jp_sales', kind = 'bar', figsize=(20,8), grid=True, title = 'ТОП-5 самых популярных жанров в Японии')
меняем наименование горизонтальной линии ('X')
plt.xlabel('Жанр')
меняем наименование вертикальной линии ('Y')
plt.ylabel('Продажи экземпляров (млн.)')
plt.show()
# ТОП-5 самых популярных жанров в Японии по нашей таблице
группируем по жанрам
genre_jp = data.groupby('genre')['jp_sales'].sum().sort_values(ascending=False).head(5)
построим гистограмму
genre_jp.plot(x = 'genre', y = 'jp_sales', kind = 'bar', figsize=(20,8), grid=True, title = 'ТОП-5 самых популярных жанров в Японии по нашей таблице')
меняем наименование горизонтальной линии ('X')
plt.xlabel('Жанр')
меняем наименование вертикальной линии ('Y')
plt.ylabel('Продажи экземпляров (млн.)')
plt.show()
# считаем долю продаж в Японии по нашей таблице
вычисляем процентное соотношение
genre_percent_jp = genre_jp / genre_count_full * 100
display('Доля продаж в Японии:')
display(genre_percent_jp.sort_values(ascending=False).head(5))

'Доля продаж в Японии:'
genre
role-playing 10.046512
fighting 7.392197
action 6.790323
shooter 2.263663
sports 1.367420
dtype: float64

ТОП-5 самых популярных жанров в Японии по нашей таблице:
1. Role-Playing
2. Fighting
3. Action
4. Shooter
5. Sports

ТОП-5 самых популярных жанров в других странах

# ТОП-5 самых популярных жанров в других странах по общей таблице
группируем по жанрам
genre_other = data.groupby('genre')['other_sales'].sum().sort_values(ascending=False).head(5)
построим гистограмму
genre_other.plot(x = 'genre', y = 'other_sales', kind = 'bar', figsize=(20,8), grid=True, title = 'ТОП-5 самых популярных жанров в других странах')
меняем наименование горизонтальной линии ('X')
plt.xlabel('Жанр')
меняем наименование вертикальной линии ('Y')
plt.ylabel('Продажи экземпляров (млн.)')
plt.show()
# ТОП-5 самых популярных жанров в других странах по нашей таблице
группируем по жанрам
genre_other = data.groupby('genre')['other_sales'].sum().sort_values(ascending=False).head(5)
построим гистограмму
genre_other.plot(x = 'genre', y = 'other_sales', kind = 'bar', figsize=(20,8), grid=True, title = 'ТОП-5 самых популярных жанров в других странах по нашей таблице')
меняем наименование горизонтальной линии ('X')
plt.xlabel('Жанр')
меняем наименование вертикальной линии ('Y')
plt.ylabel('Продажи экземпляров (млн.)')
plt.show()
# считаем долю продаж в других странах по нашей таблице
вычисляем процентное соотношение
genre_percent_other = genre_other / genre_count_full * 100
display('Доля продаж в других странах:')
display(genre_percent_other.sort_values(ascending=False).head(5))

'Доля продаж в других странах:'
genre
fighting 14.065708
sports 13.733650
action 13.500000
shooter 13.290935
role-playing 12.713178
dtype: float64

ТОП-5 самых популярных жанров в других странах по нашей таблице:
1. Shooter
2. Sports
3. Action
4. Role-Playing
5. Adventure

Выясним влияет ли рейтинг ESRB на продажи в отдельном регионе по нашей выгрузке?

#  Рейтинг от организации ESRB в Северной Америке
группируем по жанрам
rating_na = data.groupby('rating')['na_sales'].sum().sort_values(ascending=False)
построим гистограмму
rating_na.plot(x = 'rating', y = 'na_sales', kind = 'bar', figsize=(20,8), grid=True, title = 'Рейтинг от организации ESRB в Северной Америке')
меняем наименование горизонтальной линии ('X')
plt.xlabel('Рейтинг')
меняем наименование вертикальной линии ('Y')
plt.ylabel('Продажи экземпляров (млн.)')
plt.show()

В Северной Америке самые высокие рейтинги у жанра M («Для взрослых»: Материалы игры не подходят для подростков младше 17 лет.), далее по популярности игры, в которых жанры неопределенны. Остальные жанры менее популярные.

# Рейтинг от организации ESRB в Европе
группируем по жанрам
rating_eu = data.groupby('rating')['eu_sales'].sum().sort_values(ascending=False)
построим гистограмму
rating_eu.plot(x = 'rating', y = 'eu_sales', kind = 'bar', figsize=(20,8), grid=True, title = 'Рейтинг от организации ESRB в Европе')
меняем наименование горизонтальной линии ('X')
plt.xlabel('Рейтинг')
меняем наименование вертикальной линии ('Y')
plt.ylabel('Продажи экземпляров (млн.)')
plt.show()

В Европе самые высокие рейтинги у жанра M («Для взрослых»: Материалы игры не подходят для подростков младше 17 лет.), далее по популярности игры, в которых жанры неопределенны. Остальные жанры менее популярные.

# Рейтинг от организации ESRB в Японии
группируем по жанрам
rating_jp = data.groupby('rating')['jp_sales'].sum().sort_values(ascending=False)
построим гистограмму
rating_jp.plot(x = 'rating', y = 'jp_sales', kind = 'bar', figsize=(20,8), grid=True, title = 'Рейтинг от организации ESRB в Японии')
меняем наименование горизонтальной линии ('X')
plt.xlabel('Рейтинг')
меняем наименование вертикальной линии ('Y')
plt.ylabel('Продажи экземпляров (млн.)')
plt.show()

В Японии самые высокие рейтинги у игр, в которых жанры неопределенны, далее по популярности жанр M («Для взрослых»: Материалы игры не подходят для подростков младше 17 лет). Остальные жанры менее популярные.

# Рейтинг от организации ESRB в других странах
группируем по жанрам
rating_other = data.groupby('rating')['other_sales'].sum().sort_values(ascending=False)
построим гистограмму
rating_other.plot(x = 'rating', y = 'other_sales', kind = 'bar', figsize=(20,8), grid=True, title = 'Рейтинг от организации ESRB в других странах')
меняем наименование горизонтальной линии ('X')
plt.xlabel('Рейтинг')
меняем наименование вертикальной линии ('Y')
plt.ylabel('Продажи экземпляров (млн.)')
plt.show()

В других странах самые высокие рейтинги у жанра M («Для взрослых»: Материалы игры не подходят для подростков младше 17 лет.), далее по популярности игры, в которых жанры неопределенны. Остальные жанры менее популярные.

Вывод

В этой части выделим ТОП-5 самых популярных и непопулярных платформ и жанров.
Можем выделить, что каждый регион отличается топовыми позициями. Для примера разберем первые места.

По нашей таблице:

Рейтинг по платформам:
в Северной Америке - Xbox One
в Европе - PS4
в Японии - PS4
в других странах - PS4

Рейтинг по жанрам:
в Северной Америке - Fighting
в Европе - Shooter
в Японии - Role-Playing
в других странах - Shooter

Рейтинг от организации ESRB:
в Северной Америке - M
в Европе - M
в Японии - жанр неопределён
в других странах - M

Более подробно расписано в процессе выгрузок.


5. Проверка гипотез

В финальной части нам необходимо проверить две гипотезы:

  • cредние пользовательские рейтинги платформ Xbox One и PC одинаковые

  • cредние пользовательские рейтинги жанров Action и Sports разные

Так как платформы Xbox One и PC не попали в нашу выборку в связи с тем, что суммарные продажи менее 300 млн. Сделаем выгрузку из общей таблицы и по ней рассчитаем среднее значение по глобальным продажам.

Гипотеза: средние пользовательские рейтинги платформ Xbox One и PC одинаковые.

Для проверки гипотезы "средние пользовательские рейтинги платформ Xbox One и PC одинаковые" в качестве нулевой и альтернативной гипотезы мы взяли следующее:
H0: средние рейтинги по платформам одинаковые
H1: средние рейтинги по платформам разные

# убираем значения, которые были пропусками
data_all = data_all[data_all['user_score'] != -1]
вывелb две выборки по необходимым платформам
data_xbox = data_all[data_all['platform'] == 'Xbox One']
data_pc = data_all[data_all['platform'] == 'PC']
обозначили две выборки конкретных столбцов с пользовательскими рейтингами.
xbox_1 = data_xbox['user_score']
pc_1 = data_pc['user_score']
alpha = .05 # критический уровень статистической значимости
если p-value окажется меньше него - отвергнем гипотезу
results = st.ttest_ind(
xbox_1,
pc_1)
print('p-значение:', results.pvalue)
if (results.pvalue < alpha):
print("Отвергаем нулевую гипотезу")
else:
print("Не получилось отвергнуть нулевую гипотезу")

p-значение: 1.3037979620149106e-05
Отвергаем нулевую гипотезу

data_all.info()

<class 'pandas.core.frame.DataFrame'>
Int64Index: 7463 entries, 0 to 16705
Data columns (total 12 columns):
name 7463 non-null object
platform 7463 non-null object
year_of_release 7463 non-null int64
genre 7463 non-null object
na_sales 7463 non-null float64
eu_sales 7463 non-null float64
jp_sales 7463 non-null float64
other_sales 7463 non-null float64
critic_score 7463 non-null float64
user_score 7463 non-null float64
rating 7463 non-null object
sum_sales_game 7463 non-null float64
dtypes: float64(7), int64(1), object(4)
memory usage: 758.0+ KB

# Приведены два датасета: сумма покупок, совершённых за месяц посетителями ...
sample_1 = [3071, 3636, 3454, 3151, 2185, 3259, 1727, 2263, 2015,
2582, 4815, 633, 3186, 887, 2028, 3589, 2564, 1422, 1785,
3180, 1770, 2716, 2546, 1848, 4644, 3134, 475, 2686,
1838, 3352]
sample_2 = [1211, 1228, 2157, 3699, 600, 1898, 1688, 1420, 5048, 3007,
509, 3777, 5583, 3949, 121, 1674, 4300, 1338, 3066,
3562, 1010, 2311, 462, 863, 2021, 528, 1849, 255,
1740, 2596]
alpha = .05 # критический уровень статистической значимости
если p-value окажется меньше него - отвергнем гипотезу
results = st.ttest_ind(
sample_1,
sample_2)
print('p-значение:', results.pvalue)
if (results.pvalue < alpha):
print("Отвергаем нулевую гипотезу")
else:
print("Не получилось отвергнуть нулевую гипотезу")

p-значение: 0.1912450522572209
Не получилось отвергнуть нулевую гипотезу

Результат говорит о том, что нулевая гипотеза отвергается.

Гипотеза: средние пользовательские рейтинги жанров Action и Sports разные.

Рейтинг жанров мы уже будем делать по нашей выборке

Для проверки гипотезы "средние пользовательские рейтинги жанров Action и Sports разные" в качестве нулевой и альтернативной гипотезы мы взяли следующее:
H0: средние рейтинги по жанрам одинаковые
H1: средние рейтинги по жанрам разные

# убираем значения, котрые были пропусками
data = data[data['user_score'] != -1]
data_action = data[data['genre'] == 'action']
data_sports = data[data['genre'] == 'sports']
action_1 = data_action['user_score']
sports_1 = data_sports['user_score']
alpha = .05 # критический уровень статистической значимости
если p-value окажется меньше него - отвегнем гипотезу
results = st.ttest_ind(
action_1,
sports_1)
print('p-значение: ', results.pvalue)
if results.pvalue < alpha:
print("Отвергаем нулевую гипотезу")
else:
print("Не получилось отвергнуть нулевую гипотезу") 

p-значение: 6.222342604166548e-06
Отвергаем нулевую гипотезу

Результат говорит о том, что нулевая гипотеза отвергается.

Вывод

В первой гипотезе:
Результат говорит о том, что нулевая гипотеза отвергается.
p-значение: 1.3037979620149106e-05
Во второй гипотезе:
Результат говорит о том, что нулевая гипотеза отвергается.
p-значение: 6.222342604166548e-06


6. Общий вывод

Мы сделали колоссальную работу в которой из нескольких таблиц мы подготовили и сделали выгрузку. Подробно о каждом этапе есть вывод, можете с ними ознакомиться. В конце проекта нам необходимо было проверить две гипотезы: "средние пользовательские рейтинги платформ Xbox One и PC одинаковые" и "средние пользовательские рейтинги жанров Action и Sports разные". Итог можно сделать следующий: средние пользовательские рейтинги платформ разные, и средние пользовательские рейтинги по жанрам разные.

По итогам можно сделать прогноз на 2017 год в игровой индустрии.

Был анализирован период с 2015-2016 года, и в этот период для диагностики у нас были выбраны 2 платформы: PS4 и Xbox One, которые на этот момент обладали самыми большими продажами и были в тренде.

Самыми популярными платформами на рынке в мире являются - PS4, т.к. из из всех стран, только Северная Америка склоняется к Xbox One.

Жанры игр страны предпочитают разные, но большинство склоняется к жанру Shooter. Также в ТОП жанров попали такие как: Fighting (в Северной Америке), Role-Playing (в Японии).

А вот ТОП рейтинг от организации ESRB можно твердо считать категорию M («Для взрослых»: Материалы игры не подходят для подростков младше 17 лет).

На следующий год ставку можно делать на платформу PS4, т.к. она популярна в большинстве стран мира. В жанрах ТОП Shooter, но предлагаю не забывать про остальные два жанра, т.к. они захватываю две большие страны. Возрастная категория M пользуется большим спросом на рынке.




Комментарии (2):

  1. Vindicar
    /#24491628 / +2

    Где данные-то?

    • Siciliez88
      /#24491996 / -1

      Первый опыт на Хабре, поэтому не вкладывал csv. На будущее обязательно учту.