Ты провел отличную работу над ошибками! Уверен, ты обязательно достигнешь своей цели! Успехов в дальнейшем обучении! 🙂
Антон, привет! Меня зовут Ефимов Денис и сегодня я буду делать ревью твоего проекта!
В Практикуме принято общаться на "ты", однако если это неудобно - дай знать, и можем перейти на более официальное общение.
Ниже ты найдешь мои комментарии - пожалуйста, не перемещай, не изменяй и не удаляй их. Я буду использовать цветовую разметку:
Давай работать над проектом в диалоге: если ты что-то меняешь в проекте или отвечаешь на мои комментарии — пиши об этом. Мне будет легче отследить изменения, если ты выделишь свои комментарии: Например так:
Или можешь использовать эту галочку ✔ в моих комментариях, если писать особо нечего.
- Ты проделал огромную работу:)
- У меня есть несколько замечаний, исправив которые ты сделаешь проект еще лучше.
- Пробегись по моим комментариям, исправь недочёты и всё будет отлично :)
Анализ игровых платформ и игровых продуктов в разрезе продаж¶
Описание проекта¶
Вы работаете в интернет-магазине «Стримчик», который продаёт по всему миру компьютерные игры. Из открытых источников доступны исторические данные о продажах игр, оценки пользователей и экспертов, жанры и платформы (например, Xbox или PlayStation). Вам нужно выявить определяющие успешность игры закономерности. Это позволит сделать ставку на потенциально популярный продукт и спланировать рекламные кампании. Перед вами данные до 2016 года. Представим, что сейчас декабрь 2016 г., и вы планируете кампанию на 2017-й. Нужно отработать принцип работы с данными. Неважно, прогнозируете ли вы продажи на 2017 год по данным 2016-го или же 2027-й — по данным 2026 года. В наборе данных попадается аббревиатура ESRB (Entertainment Software Rating Board) — это ассоциация, определяющая возрастной рейтинг компьютерных игр. ESRB оценивает игровой контент и присваивает ему подходящую возрастную категорию, например, «Для взрослых», «Для детей младшего возраста» или «Для подростков».
Проекту нужно и название. Также стоит задуматься, как еще его можно дополнить, чтобы сделать более ценным для читателя. Все инструкции по оформлению проекта есть на платформе в разделе "Полезные инструкции для учебы"
Также советую тебе взглянуть на работы профессиональных аналитиков, чтобы оценить, как другие люди оформляют и проводят исследования.
Вопрос: после возвращения проекта с ревью Jupiter постоянно выдает ошибку "Операция сохранения прошла успешно, но блокнот, похоже, недействителен. Ошибка проверки:" . Что это?? И как с этим бороться??
Очень мешала работе, кажды 2 минуты при автосохранении вылазила.
Откроем датасет:¶
import pandas as pd
import seaborn as sns
import matplotlib.pyplot as plt
import numpy as np
from scipy import stats as st
df = pd.read_csv('/datasets/games.csv')
display(df.head(30))
| Name | Platform | Year_of_Release | Genre | NA_sales | EU_sales | JP_sales | Other_sales | Critic_Score | User_Score | Rating | |
|---|---|---|---|---|---|---|---|---|---|---|---|
| 0 | Wii Sports | Wii | 2006.0 | Sports | 41.36 | 28.96 | 3.77 | 8.45 | 76.0 | 8 | E |
| 1 | Super Mario Bros. | NES | 1985.0 | Platform | 29.08 | 3.58 | 6.81 | 0.77 | NaN | NaN | NaN |
| 2 | Mario Kart Wii | Wii | 2008.0 | Racing | 15.68 | 12.76 | 3.79 | 3.29 | 82.0 | 8.3 | E |
| 3 | Wii Sports Resort | Wii | 2009.0 | Sports | 15.61 | 10.93 | 3.28 | 2.95 | 80.0 | 8 | E |
| 4 | Pokemon Red/Pokemon Blue | GB | 1996.0 | Role-Playing | 11.27 | 8.89 | 10.22 | 1.00 | NaN | NaN | NaN |
| 5 | Tetris | GB | 1989.0 | Puzzle | 23.20 | 2.26 | 4.22 | 0.58 | NaN | NaN | NaN |
| 6 | New Super Mario Bros. | DS | 2006.0 | Platform | 11.28 | 9.14 | 6.50 | 2.88 | 89.0 | 8.5 | E |
| 7 | Wii Play | Wii | 2006.0 | Misc | 13.96 | 9.18 | 2.93 | 2.84 | 58.0 | 6.6 | E |
| 8 | New Super Mario Bros. Wii | Wii | 2009.0 | Platform | 14.44 | 6.94 | 4.70 | 2.24 | 87.0 | 8.4 | E |
| 9 | Duck Hunt | NES | 1984.0 | Shooter | 26.93 | 0.63 | 0.28 | 0.47 | NaN | NaN | NaN |
| 10 | Nintendogs | DS | 2005.0 | Simulation | 9.05 | 10.95 | 1.93 | 2.74 | NaN | NaN | NaN |
| 11 | Mario Kart DS | DS | 2005.0 | Racing | 9.71 | 7.47 | 4.13 | 1.90 | 91.0 | 8.6 | E |
| 12 | Pokemon Gold/Pokemon Silver | GB | 1999.0 | Role-Playing | 9.00 | 6.18 | 7.20 | 0.71 | NaN | NaN | NaN |
| 13 | Wii Fit | Wii | 2007.0 | Sports | 8.92 | 8.03 | 3.60 | 2.15 | 80.0 | 7.7 | E |
| 14 | Kinect Adventures! | X360 | 2010.0 | Misc | 15.00 | 4.89 | 0.24 | 1.69 | 61.0 | 6.3 | E |
| 15 | Wii Fit Plus | Wii | 2009.0 | Sports | 9.01 | 8.49 | 2.53 | 1.77 | 80.0 | 7.4 | E |
| 16 | Grand Theft Auto V | PS3 | 2013.0 | Action | 7.02 | 9.09 | 0.98 | 3.96 | 97.0 | 8.2 | M |
| 17 | Grand Theft Auto: San Andreas | PS2 | 2004.0 | Action | 9.43 | 0.40 | 0.41 | 10.57 | 95.0 | 9 | M |
| 18 | Super Mario World | SNES | 1990.0 | Platform | 12.78 | 3.75 | 3.54 | 0.55 | NaN | NaN | NaN |
| 19 | Brain Age: Train Your Brain in Minutes a Day | DS | 2005.0 | Misc | 4.74 | 9.20 | 4.16 | 2.04 | 77.0 | 7.9 | E |
| 20 | Pokemon Diamond/Pokemon Pearl | DS | 2006.0 | Role-Playing | 6.38 | 4.46 | 6.04 | 1.36 | NaN | NaN | NaN |
| 21 | Super Mario Land | GB | 1989.0 | Platform | 10.83 | 2.71 | 4.18 | 0.42 | NaN | NaN | NaN |
| 22 | Super Mario Bros. 3 | NES | 1988.0 | Platform | 9.54 | 3.44 | 3.84 | 0.46 | NaN | NaN | NaN |
| 23 | Grand Theft Auto V | X360 | 2013.0 | Action | 9.66 | 5.14 | 0.06 | 1.41 | 97.0 | 8.1 | M |
| 24 | Grand Theft Auto: Vice City | PS2 | 2002.0 | Action | 8.41 | 5.49 | 0.47 | 1.78 | 95.0 | 8.7 | M |
| 25 | Pokemon Ruby/Pokemon Sapphire | GBA | 2002.0 | Role-Playing | 6.06 | 3.90 | 5.38 | 0.50 | NaN | NaN | NaN |
| 26 | Brain Age 2: More Training in Minutes a Day | DS | 2005.0 | Puzzle | 3.43 | 5.35 | 5.32 | 1.18 | 77.0 | 7.1 | E |
| 27 | Pokemon Black/Pokemon White | DS | 2010.0 | Role-Playing | 5.51 | 3.17 | 5.65 | 0.80 | NaN | NaN | NaN |
| 28 | Gran Turismo 3: A-Spec | PS2 | 2001.0 | Racing | 6.85 | 5.09 | 1.87 | 1.16 | 95.0 | 8.4 | E |
| 29 | Call of Duty: Modern Warfare 3 | X360 | 2011.0 | Shooter | 9.04 | 4.24 | 0.13 | 1.32 | 88.0 | 3.4 | M |
df.info()
<class 'pandas.core.frame.DataFrame'> RangeIndex: 16715 entries, 0 to 16714 Data columns (total 11 columns): # Column Non-Null Count Dtype --- ------ -------------- ----- 0 Name 16713 non-null object 1 Platform 16715 non-null object 2 Year_of_Release 16446 non-null float64 3 Genre 16713 non-null object 4 NA_sales 16715 non-null float64 5 EU_sales 16715 non-null float64 6 JP_sales 16715 non-null float64 7 Other_sales 16715 non-null float64 8 Critic_Score 8137 non-null float64 9 User_Score 10014 non-null object 10 Rating 9949 non-null object dtypes: float64(6), object(5) memory usage: 1.4+ MB
1)Колонки Name, Platform, Year_of_Release, Genre, NA_sales, EU_sales, JP_sales, Other_sales, Critic_Score, User_Score, Rating.
- Количество срок 16715, с учетом колонок дает нам размер датасета в 1.4 MB
3)Основные недостатки проблемы: присутствование разного регистра, пропуски в данных, не соответствование данных в колонках их типу (year_of_releasу, critic_score, user_score)
Каждому пункту нужен вывод.
Что мы можем сказать о данных после первичного знакомства с ними?
Преобразование:¶
df = df.rename(columns = {'Name':'name','Platform':'platform','Year_of_Release':'year_of_release',
'Genre':'genre','NA_sales':'na_sales','EU_sales':'eu_sales','JP_sales':'jp_sales',
'Other_sales':'other_sales','Critic_Score':'critic_score','User_Score':'user_score',
'Rating':'rating'})
df['name'] = df['name'].str.lower()
df['platform'] = df['platform'].str.lower()
df['genre'] = df['genre'].str.lower()
df['rating'] = df['rating'].str.lower()
df.head()
| name | platform | year_of_release | genre | na_sales | eu_sales | jp_sales | other_sales | critic_score | user_score | rating | |
|---|---|---|---|---|---|---|---|---|---|---|---|
| 0 | wii sports | wii | 2006.0 | sports | 41.36 | 28.96 | 3.77 | 8.45 | 76.0 | 8 | e |
| 1 | super mario bros. | nes | 1985.0 | platform | 29.08 | 3.58 | 6.81 | 0.77 | NaN | NaN | NaN |
| 2 | mario kart wii | wii | 2008.0 | racing | 15.68 | 12.76 | 3.79 | 3.29 | 82.0 | 8.3 | e |
| 3 | wii sports resort | wii | 2009.0 | sports | 15.61 | 10.93 | 3.28 | 2.95 | 80.0 | 8 | e |
| 4 | pokemon red/pokemon blue | gb | 1996.0 | role-playing | 11.27 | 8.89 | 10.22 | 1.00 | NaN | NaN | NaN |
Также названия столбцов можно привести в нижнему регистру, если к df.columns применить метод str.lower
df.columns = df.columns.str.lower()
Предобработка данных¶
print('Кол-во явных дубликатов', df.duplicated().sum(),'\n \n')
print('Кол-во пропусков \n',df.isna().sum())
Кол-во явных дубликатов 0 Кол-во пропусков 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 6701 rating 6766 dtype: int64
2)Есть пропуски в данных, требуется обработка
Пропущенные значения¶
df.dropna(subset = ['name'], axis=0, inplace = True)
df.dropna(subset = ['year_of_release'], axis=0, inplace = True)
df = df.reset_index(drop=True)
df['year_of_release']= df['year_of_release'].astype('int')
#df['critic_score']=df['critic_score'].fillna(NaN)
df['critic_score']= df['critic_score'].astype('float')
#df['user_score']=df['user_score'].fillna(NaN)
df['rating']=df['rating'].fillna('not_defined')
df.info()
<class 'pandas.core.frame.DataFrame'> RangeIndex: 16444 entries, 0 to 16443 Data columns (total 11 columns): # Column Non-Null Count Dtype --- ------ -------------- ----- 0 name 16444 non-null object 1 platform 16444 non-null object 2 year_of_release 16444 non-null int64 3 genre 16444 non-null object 4 na_sales 16444 non-null float64 5 eu_sales 16444 non-null float64 6 jp_sales 16444 non-null float64 7 other_sales 16444 non-null float64 8 critic_score 7983 non-null float64 9 user_score 9839 non-null object 10 rating 16444 non-null object dtypes: float64(5), int64(1), object(5) memory usage: 1.4+ MB
|
- В колонке ' rating' пропущенные значения меняем на "not_defined". Более информативно и удобней работать с данными.
|
3)Значения в колонке 'year_of_release' целочисленны. Привидем их в соответствие. Данные по году выпуска игры содержат только год, поэтому не стоит приводить эти данные к типу date.
|
- Пропущенные значения в колонках "name" и "year_of_release" удаляем построчно, восстановлению не подлежат
|
- Данные в колонке 'critic_score' приводим к типу float.
А зачем мы заполняем пропуски в оценках нулями? Вдруг среди имеющихся значений уже есть нулевые? Вообще, любые заполнения вызывают искажения при расчете статистик, все основные методы pandas по-умолчанию убирают пропуски при расчетах (среднее, медиана, корреляция и тд). Поэтому их можно не заполнять, чтобы не делать лишних действий и избежать ошибок.
Обработка неявных дубликатов¶
list_platform = df['platform'].unique()
for i in df['platform'].unique():
list_du = df.loc[df['platform'] == i].groupby('name')['name'].count()
if 2 in list_du.values:
print(i,list_du[list_du >1])
x360 name need for speed: most wanted 2 Name: name, dtype: int64 ps3 name madden nfl 13 2 Name: name, dtype: int64 pc name need for speed: most wanted 2 Name: name, dtype: int64
display(df.loc[(df['platform'] == 'x360') &
(df['name'] == 'need for speed: most wanted')])
display(df.loc[(df['platform'] == 'ps3') &
(df['name'] == 'madden nfl 13')])
display(df.loc[(df['platform'] == 'ps3') &
(df['name'] == 'sonic the hedgehog')])
display(df.loc[(df['platform'] == 'pc') &
(df['name'] == 'need for speed: most wanted')])
| name | platform | year_of_release | genre | na_sales | eu_sales | jp_sales | other_sales | critic_score | user_score | rating | |
|---|---|---|---|---|---|---|---|---|---|---|---|
| 1177 | need for speed: most wanted | x360 | 2012 | racing | 0.62 | 0.78 | 0.01 | 0.15 | 83.0 | 8.5 | t |
| 1574 | need for speed: most wanted | x360 | 2005 | racing | 1.00 | 0.13 | 0.02 | 0.10 | 83.0 | 8.5 | t |
| name | platform | year_of_release | genre | na_sales | eu_sales | jp_sales | other_sales | critic_score | user_score | rating | |
|---|---|---|---|---|---|---|---|---|---|---|---|
| 600 | madden nfl 13 | ps3 | 2012 | sports | 2.11 | 0.22 | 0.0 | 0.23 | 83.0 | 5.5 | e |
| 15969 | madden nfl 13 | ps3 | 2012 | sports | 0.00 | 0.01 | 0.0 | 0.00 | 83.0 | 5.5 | e |
| name | platform | year_of_release | genre | na_sales | eu_sales | jp_sales | other_sales | critic_score | user_score | rating | |
|---|---|---|---|---|---|---|---|---|---|---|---|
| 1725 | sonic the hedgehog | ps3 | 2006 | platform | 0.41 | 0.06 | 0.04 | 0.66 | 43.0 | 4.1 | e10+ |
| name | platform | year_of_release | genre | na_sales | eu_sales | jp_sales | other_sales | critic_score | user_score | rating | |
|---|---|---|---|---|---|---|---|---|---|---|---|
| 5883 | need for speed: most wanted | pc | 2005 | racing | 0.02 | 0.23 | 0.0 | 0.04 | 82.0 | 8.5 | t |
| 11534 | need for speed: most wanted | pc | 2012 | racing | 0.00 | 0.06 | 0.0 | 0.02 | 82.0 | 8.5 | t |
df.loc[(df['name'] == 'need for speed: most wanted') &
(df['year_of_release'] == 2012),'name'] = 'need for speed: most wanted 2012'
df.drop([16228,4126], axis = 0, inplace =True)
df.reset_index(drop =True)
| name | platform | year_of_release | genre | na_sales | eu_sales | jp_sales | other_sales | critic_score | user_score | rating | |
|---|---|---|---|---|---|---|---|---|---|---|---|
| 0 | wii sports | wii | 2006 | sports | 41.36 | 28.96 | 3.77 | 8.45 | 76.0 | 8 | e |
| 1 | super mario bros. | nes | 1985 | platform | 29.08 | 3.58 | 6.81 | 0.77 | NaN | NaN | not_defined |
| 2 | mario kart wii | wii | 2008 | racing | 15.68 | 12.76 | 3.79 | 3.29 | 82.0 | 8.3 | e |
| 3 | wii sports resort | wii | 2009 | sports | 15.61 | 10.93 | 3.28 | 2.95 | 80.0 | 8 | e |
| 4 | pokemon red/pokemon blue | gb | 1996 | role-playing | 11.27 | 8.89 | 10.22 | 1.00 | NaN | NaN | not_defined |
| ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... |
| 16437 | samurai warriors: sanada maru | ps3 | 2016 | action | 0.00 | 0.00 | 0.01 | 0.00 | NaN | NaN | not_defined |
| 16438 | lma manager 2007 | x360 | 2006 | sports | 0.00 | 0.01 | 0.00 | 0.00 | NaN | NaN | not_defined |
| 16439 | haitaka no psychedelica | psv | 2016 | adventure | 0.00 | 0.00 | 0.01 | 0.00 | NaN | NaN | not_defined |
| 16440 | spirits & spells | gba | 2003 | platform | 0.01 | 0.00 | 0.00 | 0.00 | NaN | NaN | not_defined |
| 16441 | winning post 8 2016 | psv | 2016 | simulation | 0.00 | 0.00 | 0.01 | 0.00 | NaN | NaN | not_defined |
16442 rows × 11 columns
1)Нашли повторяющиеся игры по платформам, затем вывели их чтобы обработать.
2)Игра 'need for speed: most wanted' была выпущенна в 2005г., но в 2012 вышла игра под таким-же названием. Устраним путанницу, заменим значения 'need for speed: most wanted' на 'need for speed: most wanted 2012' убедившись что в колонке ['year_of_release'] указан 2012г.
3)Игры 'madden nfl 13' и 'sonic the hedgehog' на 'ps3' имеют по две записи, изучив данные в строках приходим к выводу, что это одни и те-же игры. Удалим записи с наибольшим количеством пропущенных или 0 данных.
Молодец, что сделал такую проверку!
А для чего мы меняем название игры 'need for speed: most wanted', если она выходила под одним названием в разные годы? К тому же углубляться в исследовании до анализа конкретных игр мы не будем.
df['sum_sales'] = df['eu_sales'] + df['jp_sales'] + df['na_sales'] + df['other_sales']# добавим колонку с суммарными продажами.
#df.head()
Тут можно использовать метод DataFrame.sum с аргументом axis=1
df['total_sum'] = df[['value_1', 'value_2', 'value_3', 'value_4']].sum(axis=1)
Обработка оценок 'tbd'¶
print('Суммарные продажи только с оценкой "tbd":',df.loc[df['user_score'] == 'tbd']['sum_sales'].sum())
print('Суммарные продажи без оценки "tbd":',df.loc[df['user_score'] !='tbd']['sum_sales'].sum())
display(df.loc[df['user_score'] == 'tbd'].sort_values(['sum_sales'], ascending = False).head(10))
Суммарные продажи только с оценкой "tbd": 446.45 Суммарные продажи без оценки "tbd": 8367.44
| name | platform | year_of_release | genre | na_sales | eu_sales | jp_sales | other_sales | critic_score | user_score | rating | sum_sales | |
|---|---|---|---|---|---|---|---|---|---|---|---|---|
| 119 | zumba fitness | wii | 2010 | sports | 3.45 | 2.59 | 0.00 | 0.66 | NaN | tbd | e | 6.70 |
| 300 | namco museum: 50th anniversary | ps2 | 2005 | misc | 2.08 | 1.35 | 0.00 | 0.54 | 61.0 | tbd | e10+ | 3.97 |
| 516 | zumba fitness 2 | wii | 2011 | sports | 1.51 | 1.03 | 0.00 | 0.27 | NaN | tbd | t | 2.81 |
| 639 | udraw studio | wii | 2010 | misc | 1.65 | 0.57 | 0.00 | 0.20 | 71.0 | tbd | e | 2.42 |
| 709 | just dance kids | wii | 2010 | misc | 1.52 | 0.54 | 0.00 | 0.18 | NaN | tbd | e | 2.24 |
| 716 | dance dance revolution x2 | ps2 | 2009 | simulation | 1.09 | 0.85 | 0.00 | 0.28 | NaN | tbd | e10+ | 2.22 |
| 810 | the incredibles | gba | 2004 | action | 1.15 | 0.77 | 0.04 | 0.10 | 55.0 | tbd | e | 2.06 |
| 870 | who wants to be a millionaire | pc | 1999 | misc | 1.94 | 0.00 | 0.00 | 0.00 | NaN | tbd | e | 1.94 |
| 1037 | imagine: teacher | ds | 2008 | simulation | 0.70 | 0.82 | 0.00 | 0.19 | NaN | tbd | e | 1.71 |
| 1036 | tetris worlds | gba | 2001 | puzzle | 1.25 | 0.39 | 0.00 | 0.06 | 65.0 | tbd | e | 1.70 |
df['user_score'] = df['user_score'].replace ( 'tbd' , np.nan )
df['user_score']= df['user_score'].astype('float')
df.info()
<class 'pandas.core.frame.DataFrame'> Int64Index: 16442 entries, 0 to 16443 Data columns (total 12 columns): # Column Non-Null Count Dtype --- ------ -------------- ----- 0 name 16442 non-null object 1 platform 16442 non-null object 2 year_of_release 16442 non-null int64 3 genre 16442 non-null object 4 na_sales 16442 non-null float64 5 eu_sales 16442 non-null float64 6 jp_sales 16442 non-null float64 7 other_sales 16442 non-null float64 8 critic_score 7983 non-null float64 9 user_score 7463 non-null float64 10 rating 16442 non-null object 11 sum_sales 16442 non-null float64 dtypes: float64(7), int64(1), object(4) memory usage: 1.6+ MB
'TBD' это означает что оценка еще только будет присвоена. Но возможно этой оценки уже не появиться, т.к. количество продаж по этим продуктам очень мало. На основании этого (малых продаж) рейтинг и отсутствует. Все продажи по таким играм составляют ~1/19 или ~5.26%.
Для проведения дальнейшего анализа ДФ заменили значения 'tbd' на NaN
Удалять эти строки не нужно. По этой же логике мы должны были удалить строки и с пропусками в оценках. А если игра только недавно вышла и не успела набрать необходимого количества оценок? Либо на это есть еще какие-то причины. Так мы теряем данные и это может повлиять на результаты исследования, поэтому значения 'tbd' лучше просто заменить на пропуски. В качестве пропуска можно взять numpy.nan из библиотеки numpy
Пропущенные значения могли появиться из-за случайных ошибок (восстановить невозможно) или ошибок внесения данных в ДФ.
Пропуски в колонках "critic_score", "user_score" это следствие малых продаж продукта, а если продажи малы то невозможно составить рейтинг. Абревиатура "TBD" на это нам явно и указывает, рейтинг только ожидается. Значения 'tbd' в колонке 'yser_score' заменили на NaN. Это позволит нам в дальнейшем работать с данными этой колонки как сединым целым.
Исследовательский анализ¶
Посмотрите, сколько игр выпускалось в разные годы. Важны ли данные за все периоды?¶
Посмотрим кол-во производимых игр по годам.
game_year = df.loc[df['year_of_release'] !=0].pivot_table(index='year_of_release', values =['name'], aggfunc ='count').reset_index()
plt.title('Количество производимых игр по годам', color ='brown', fontsize =15)
plt.xlabel('Годы релиза')
plt.ylabel('Количество игр')
plt.grid(True)
plt.plot(game_year['year_of_release'], game_year['name'] )
plt.show()
Количество выпускаемых игр расло с 1980г по 2008г. После 2008г. идет спад. Для далнейшего анализа нам понадобятся данные за последних 2 года. Мы будем строить прогноз на 2017г. и надо отталкиваться от сложившихся реалей именно последнего времени. Граффик в указанный малый интервал не имеет выбросов и отражает тенденцию к снижению числа производства.
Посмотрите, как менялись продажи по платформам. Выберите платформы с наибольшими суммарными продажами и постройте распределение по годам. За какой характерный срок появляются новые и исчезают старые платформы?¶
Создадим сводные таблицы для дальнейшей визуализации и анализа. Группируем по платформам и году, а значения берем продажи
platform_sales ={}
for i in list_platform:
platform_sales[i] = df.loc[df['platform'] == i]['sum_sales'].sum()
platform_sales_df = pd.DataFrame(pd.DataFrame(list(platform_sales.items()),
columns=['platform', 'sales']))
platform_sales_df = platform_sales_df.sort_values('sales', ascending = False).reset_index()
display('Суммарные продажи по платформам:',platform_sales_df.head(10))
df_pivot_platform = df.pivot_table(index=['platform','year_of_release'],
values ='sum_sales', aggfunc ='sum').reset_index()
# Хотел обойтись без pivot_table. Получилось, но больше так не хочу)
df_pivot_platform =df_pivot_platform.loc[df_pivot_platform['year_of_release'] !=0].reset_index(drop = True)
display('Сводная таблица, сгруппирована по платформам и годам',df_pivot_platform.head(10))
'Суммарные продажи по платформам:'
| index | platform | sales | |
|---|---|---|---|
| 0 | 6 | ps2 | 1233.56 |
| 1 | 4 | x360 | 961.24 |
| 2 | 5 | ps3 | 931.33 |
| 3 | 0 | wii | 891.18 |
| 4 | 3 | ds | 802.78 |
| 5 | 12 | ps | 727.58 |
| 6 | 9 | ps4 | 314.14 |
| 7 | 8 | gba | 312.88 |
| 8 | 16 | psp | 289.53 |
| 9 | 10 | 3ds | 257.81 |
'Сводная таблица, сгруппирована по платформам и годам'
| platform | year_of_release | sum_sales | |
|---|---|---|---|
| 0 | 2600 | 1980 | 11.38 |
| 1 | 2600 | 1981 | 35.68 |
| 2 | 2600 | 1982 | 28.88 |
| 3 | 2600 | 1983 | 5.84 |
| 4 | 2600 | 1984 | 0.27 |
| 5 | 2600 | 1985 | 0.45 |
| 6 | 2600 | 1986 | 0.67 |
| 7 | 2600 | 1987 | 1.94 |
| 8 | 2600 | 1988 | 0.74 |
| 9 | 2600 | 1989 | 0.63 |
Можно обойтись без pivot_table, если использовать метод groupby)) Он немного проще. Пример написал ниже.
# код ревьюера
(df.groupby('platform', as_index=False).agg({'sum_sales' : 'sum'})
.sort_values(by='sum_sales', ascending = False)
.head(10)
)
| platform | sum_sales | |
|---|---|---|
| 16 | ps2 | 1233.56 |
| 28 | x360 | 961.24 |
| 17 | ps3 | 931.33 |
| 25 | wii | 891.18 |
| 4 | ds | 802.78 |
| 15 | ps | 727.58 |
| 18 | ps4 | 314.14 |
| 6 | gba | 312.88 |
| 19 | psp | 289.53 |
| 2 | 3ds | 257.81 |
Визуализируем и проанализируем данные по нашим сводным таблицам
#df_pivot_platform.loc[df_pivot_platform['platform'] == 'ps2']
list_platform = platform_sales_df.loc[:19,['platform']]
k = 'продажи по годам для : '
for i in list_platform['platform']:
df_pivot_platform.loc[(df_pivot_platform['platform'] == i) ].plot(x='year_of_release', kind ='bar',
y = 'sum_sales',title = k+i,
xlabel='Годы',
ylabel = 'Суммарное кол-во продаж',
figsize=(10,4),
grid= True)
Молодец ,что используешь цикл! Нам в принципе было бы достаточно рассмотреть продажи топ-6 платформ
Построили графики для топ 20 платформ исходя из количества продаж. Для всех платформ характерна одна черта, продажи падают с течением времени, , большинство платформ практически не продается. За исключением Xbox One, PS4, 3DS. Средний срок жизни платформ 6-7 лет и им на смену приходят новые, время перехода составляет 1 год.
Отдельно стоит выделить PC. Это платформа отличается от всех остальных. Консоли они конечны, не модернизируются не именяются. Им только приходят на смену другие. А PC изменчивая платформа во времени, на данный момент по графику 1992-2016г, 24года существования. Поэтому данные можно проверять и сравнивать с другими платформами только за короткие промежутки времени .
Для дальнейшего анализа исходя из граффиков выбираем период 2014-2016 годы. Приоритетные платформы для анализа PS4, Xbox One, 3DS так как они лидируют по прадажам.
Прежде чем переходить к следующему пункту, нам нужно выделить актуальный период (вижу ты сделал это ниже, но 2014 год все-таки лучше оставить) и ответить на пару вопросов из задания:
Какие платформы лидируют по продажам, растут или падают? Выберите несколько потенциально прибыльных платформ.
Постройте график «ящик с усами» по глобальным продажам игр в разбивке по платформам. Опишите результат.¶
Построим два boxplota. 1-ый по всему датасету, а 2-ой для найшей выборки 2014-2016. Дадим оценки по продажам
df_new = df.query('year_of_release > 2013') # Сделали выборку по актуальному периоду для дальнейшей работы
df_pivot_platform = df_pivot_platform.query('year_of_release > 2013')
plt.figure(figsize=(20,10))
plt.ylim(0,4)
sns.boxplot(data = df, x ='platform',y='sum_sales')
plt.show()
plt.figure(figsize=(12,10))
plt.ylim(0,4)
sns.boxplot(data = df_new, x ='platform',y='sum_sales')
plt.show()
print('Платформа PS4 \n',df[df['platform'] == 'ps4']['sum_sales'].describe())
print('Платформа 3DS \n',df[df['platform'] == '3ds']['sum_sales'].describe())
print('Платформа xone \n',df[df['platform'] == 'xone']['sum_sales'].describe())
Платформа PS4 count 392.000000 mean 0.801378 std 1.609456 min 0.010000 25% 0.060000 50% 0.200000 75% 0.730000 max 14.630000 Name: sum_sales, dtype: float64 Платформа 3DS count 512.000000 mean 0.503535 std 1.441271 min 0.010000 25% 0.050000 50% 0.120000 75% 0.332500 max 14.600000 Name: sum_sales, dtype: float64 Платформа xone count 247.000000 mean 0.645020 std 1.036139 min 0.010000 25% 0.060000 50% 0.220000 75% 0.685000 max 7.390000 Name: sum_sales, dtype: float64
На данном графике выделяются 3 платформы по количеству продаж это: PS4, Xbox One, 3DS.
Датасеты PS4 и Xbox One имеют максимальные средние и медианные значения из всего ДФ.
И последняя платформа 3DS. Уровень продаж довольно высок, медиана > 20 млн. и заслуживает внимание.
Из всего выше указанного выберем наиболее перспективные платформы : 3DS, PS4, Xbox One.
Выбросы есть практически по всем платформам. Однако интересующие нас платформы имеют не такое большое количество выбросов как к примеру PS3 или DS. Межквартильный размах наших платформ сопоставим с количеством значений лежащих выше 75%. Сами коробки относительно не высокие. Это говорит в пользу более однородных данных-большенство продуктов на данных платформах имеет успех. Если взять к примеру платформу DS, то мы увидим что МКР очень большой данные не однородны и следовательно далеко не все продукты так хорошо покупаются.
Последнюю особенность которую хочется отметить это то, что датасеты по выбранным платформам скошены вправо, а это значит что среднее больше медианы.
Все верно
Давай, пожалуйста, перед началом каждого подпункта писать комментарии, чтобы читатель был в курсе что сейчас будет происходить и для чего)
Зависимость продаж от оценок¶
Для PS4 посчитаем коэфициенты корреляции продажи-оценки. Визуализируем на диаграмме рассеяния оценки-продажи.
print('Корреляция оценка критика \ суммарные продажи :',df_new.query('critic_score > 0 & platform == "ps4"')
['critic_score'].corr(df.query('critic_score > 0 & platform == "ps4"')['sum_sales']))
print('Корреляция оценка пользователя \ суммарные продажи :',df_new.query('user_score > 0 & platform == "ps4"')
['user_score'].corr(df.query('user_score > 0 & platform == "ps4"')['sum_sales']))
df_ps4 = df_new.query('platform == "ps4" & user_score > 0')
plt.title('Оценка пользователей от кол-ва продаж', color ='brown')
plt.ylabel('Продажи')
#plt.ylim(0,0.5)
plt.xlabel('Рейтинг')
plt.scatter(data = df_ps4, y='sum_sales', x ='user_score')
plt.show()
plt.title('Оценка критиков от кол-ва продаж', color ='brown')
plt.ylabel('Продажи')
plt.xlabel('Рейтинг')
plt.scatter(data = df_ps4, y='sum_sales', x ='critic_score', color= 'green')
plt.show()
Корреляция оценка критика \ суммарные продажи : 0.402661410681041 Корреляция оценка пользователя \ суммарные продажи : -0.040131589472697356
Корреляция critic_score и sum_sales = 0.40 слабая
Корреляция user_score и sum_sales = -0.04 слабая-отрицательная
Для Xbox One посчитаем коэфициенты корреляции продажи-оценки. Визуализируем на диаграмме рассеяния оценки-продажи.
print('Корреляция оценка критика \ суммарные продажи :',df_new.query('critic_score > 0 & platform == "xone"')
['critic_score'].corr(df.query('critic_score > 0 & platform == "xone"')['sum_sales']))
print('Корреляция оценка пользователя \ суммарные продажи :',df_new.query('user_score > 0 & platform == "xone"')
['user_score'].corr(df.query('user_score > 0 & platform == "xone"')['sum_sales']))
df_xone = df_new.query('platform == "xone" & user_score > 0')
plt.title('Оценка пользователей от кол-ва продаж', color ='brown')
plt.ylabel('Продажи')
#plt.ylim(0,0.5)
plt.xlabel('Рейтинг')
plt.scatter(data = df_xone, y='sum_sales', x ='user_score')
plt.show()
plt.title('Оценка критиков от кол-ва продаж', color ='brown')
plt.ylabel('Продажи')
plt.xlabel('Рейтинг')
plt.scatter(data = df_xone, y='sum_sales', x ='critic_score', color= 'green')
plt.show()
Корреляция оценка критика \ суммарные продажи : 0.42867694370333226 Корреляция оценка пользователя \ суммарные продажи : -0.0703839280647581
Для 3DS посчитаем коэфициенты корреляции продажи-оценки. Визуализируем на диаграмме рассеяния оценки-продажи.
print('Корреляция оценка критика \ суммарные продажи :',df_new.query('critic_score > 0 & platform == "3ds"')
['critic_score'].corr(df.query('critic_score > 0 & platform == "3ds"')['sum_sales']))
print('Корреляция оценка пользователя \ суммарные продажи :',df_new.query('user_score > 0 & platform == "3ds"')
['user_score'].corr(df.query('user_score > 0 & platform == "3ds"')['sum_sales']))
df_3ds = df_new.query('platform == "xone" & user_score > 0')
plt.title('Оценка пользователей от кол-ва продаж', color ='brown')
plt.ylabel('Продажи')
#plt.ylim(0,0.5)
plt.xlabel('Рейтинг')
plt.scatter(data = df_3ds, y='sum_sales', x ='user_score')
plt.show()
plt.title('Оценка критиков от кол-ва продаж', color ='brown')
plt.ylabel('Продажи')
plt.xlabel('Рейтинг')
plt.scatter(data = df_3ds, y='sum_sales', x ='critic_score', color= 'green')
plt.show()
Корреляция оценка критика \ суммарные продажи : 0.314117492869051 Корреляция оценка пользователя \ суммарные продажи : 0.2151932718527027
3DS_corr_critic = 0.31
3DS_corr_user = 0.22
xone_corr_critic = 0.43
xone_corr_user = -0.07
Интересное наблюдение: у платформы 3DS коэфициенты корреляции положительны и не так сильно разнесены друг от друга, по сравнению с другими популярными платформами.
После анализа зависимости продаж от оценок по одной из популярных платформ нужно соотнести выводы с продажами на других платформах
Посмотрите на общее распределение игр по жанрам. Что можно сказать о самых прибыльных жанрах? Выделяются ли жанры с высокими и низкими продажами?¶
Рассмотрим два варианта анализа и выберем правильный. 1) проссумируем продажи 2)Вычислим медианы
df_pivot_genre = df_new.pivot_table(index=['genre'],
values ='sum_sales', aggfunc ='sum').reset_index()
df_pivot_genre.plot(x='genre', kind ='bar',
y = 'sum_sales',title = 'Продажи по жанрам',
xlabel='Жанры',
ylabel = 'Суммарное кол-во продаж',
figsize=(10,4),
grid= True)
plt.show()
plt.figure(figsize=(12,12))
plt.ylim(0,4)
sns.boxplot(data = df_new, x ='genre',y='sum_sales')
plt.show()
print(df_new.pivot_table(index=['genre'],
values ='sum_sales', aggfunc ='median').reset_index().sort_values(by='sum_sales', ascending =False))
genre sum_sales 8 shooter 0.515 10 sports 0.180 4 platform 0.140 2 fighting 0.130 7 role-playing 0.110 9 simulation 0.100 0 action 0.090 3 misc 0.090 6 racing 0.090 11 strategy 0.060 5 puzzle 0.045 1 adventure 0.030
Если попытаться выявить популярные жанры суммированием, то выбросы перекрывают реальную картину.
Ищем популярные жанры по медиане, используем boxplot.
Из последнего графика отчетливо видно лидирующие и аутсайдерские позиции жанров. Топ в порядке убывания: shooter, sports, platform, fighting, role-playing, simulation . Топ аутсайдов в порядке возрастания: adventure, puzzle, strategy, racing, misc, action.
Молодец, что рассматривал именно медианные продажи, это наиболее объективный показатель прибыльности, так как они не подвержены влиянию выбросов (которых в игровой индустрии достаточно много за счет продаж хитовых и популярных игр).
Определили временные рамки для анализа: 2015-2016г. Этот промежуток отражает сложившуюся тендецию, график по выпущенным играм не имеет резких изломов.
Определили ведующи платформы это: PS4, Xbox One и как дополнительный вариант 3DS (медиана 0.14е+6, не велика но продажи идут).
Линейной зависимости количество продаж в зависимости от отзывов не выявленно. Корреляция между количеством продаж и оценкой критика ~0.4, это слабая связь. И нельзя сказать, что одно зависит от другого. Что касается продаж в зависимости от отзывов пользователей, то здесь корреляция составила ~ -0,06, а это отрицательная слабая связь. Можно даже утверждать что линейной зависимости нет.
Определили самые популярные жанры и их антогонисты : Топ в порядке убывания: shooter, sports, role-playing, simulation и platform. Топ аутсайдов в порядке возрастания: adventure, strategy,puzzle, racing, misc, action.
Круто, что не забываешь писать промежуточные выводы!
Портрет пользователя каждого региона¶
Продажи по регионам в зависимости от платформы
print(df_new.pivot_table(index ='platform' , values = 'na_sales',
aggfunc= 'sum').sort_values(by ='na_sales', ascending =False).head(),'\n')
print(df_new.pivot_table(index ='platform' , values = 'eu_sales',
aggfunc= 'sum').sort_values(by ='eu_sales', ascending =False).head(),'\n')
print(df_new.pivot_table(index ='platform' , values = 'jp_sales',
aggfunc= 'sum').sort_values(by ='jp_sales', ascending =False).head(),'\n')
na_sales
platform
ps4 98.61
xone 81.27
x360 28.30
3ds 22.64
ps3 22.05
eu_sales
platform
ps4 130.04
xone 46.25
ps3 25.54
pc 17.97
3ds 16.12
jp_sales
platform
3ds 44.24
ps4 15.02
psv 14.54
ps3 11.21
wiiu 7.31
Визуализируем данные
plt.title('Рейтинг платформ по продажам NA региона', color='brown')
sns.barplot(data = df_new.pivot_table(index ='platform' , values = 'na_sales',
aggfunc= 'sum').sort_values(by ='na_sales', ascending =False).reset_index(), x='platform',y='na_sales')
plt.show()
plt.title('Рейтинг платформ по продажам EU региона', color='brown')
sns.barplot(data = df_new.pivot_table(index ='platform', values = 'eu_sales',
aggfunc= 'sum').sort_values(by ='eu_sales', ascending =False).reset_index(), x='platform',y='eu_sales' )
plt.show()
plt.title('Рейтинг платформ по продажам JP региона', color='brown')
sns.barplot(data = df_new.pivot_table(index ='platform', values = 'jp_sales',
aggfunc= 'sum').sort_values(by ='jp_sales', ascending =False).reset_index(), x='platform',y='jp_sales' )
<AxesSubplot:title={'center':'Рейтинг платформ по продажам JP региона'}, xlabel='platform', ylabel='jp_sales'>
NA Популярные платформы в порядке убывания: PS4, Xbox One,Xbox x360, 3DS,PS3
EU Популярные платформы в порядке убывания: PS4, Xbox One, PS3, PC, 3DS
JP Популярные платформы в порядке убывания: 3DS, PS4,PSV,PS3, WIIU
Во всех регионах PS4 занимает если не первое место то второе, это очень популярная платформа. Платформа 3DS и Xbox One хорошо представленны в EU и JP. Суммарные продажи высоки. Также везде присутствует PS3, но ее мы в дальнейшем не рассматриваем т.к. она уже устарела.
Продажи по регионам в зависимости от жанра.
print(df_new.pivot_table(index ='genre' , values = 'na_sales',
aggfunc= 'sum').sort_values(by ='na_sales', ascending =False).head(),'\n')
print(df_new.pivot_table(index ='genre' , values = 'eu_sales',
aggfunc= 'sum').sort_values(by ='eu_sales', ascending =False).head(),'\n')
print(df_new.pivot_table(index ='genre' , values = 'jp_sales',
aggfunc= 'sum').sort_values(by ='jp_sales', ascending =False).head(),'\n')
na_sales
genre
shooter 79.02
action 72.53
sports 46.13
role-playing 33.47
misc 15.05
eu_sales
genre
action 74.68
shooter 65.52
sports 45.73
role-playing 28.17
racing 14.13
jp_sales
genre
role-playing 31.16
action 29.58
fighting 6.36
misc 5.61
shooter 4.87
Визуализируем данные
plt.figure(figsize=(10,4))
plt.title('Рейтинг жанров по продажам NA региона', color='brown')
sns.barplot(data = df_new.pivot_table(index ='genre' , values = 'na_sales',
aggfunc= 'sum').sort_values(by ='na_sales', ascending =False).reset_index(), x='genre',y='na_sales')
plt.show()
plt.figure(figsize=(10,4))
plt.title('Рейтинг жанров по продажам EU региона', color='brown')
sns.barplot(data = df_new.pivot_table(index ='genre', values = 'eu_sales',
aggfunc= 'sum').sort_values(by ='eu_sales', ascending =False).reset_index(), x='genre',y='eu_sales' )
plt.show()
plt.figure(figsize=(10,4))
plt.title('Рейтинг жанров по продажам JP региона', color='brown')
sns.barplot(data = df_new.pivot_table(index ='genre', values = 'jp_sales',
aggfunc= 'sum').sort_values(by ='jp_sales', ascending =False).reset_index(), x='genre',y='jp_sales' )
<AxesSubplot:title={'center':'Рейтинг жанров по продажам JP региона'}, xlabel='genre', ylabel='jp_sales'>
NA Популярные жанры в порядке убывания: Shooter, Action, Sports, Role_playing, Misc
EU Популярные жанры в порядке убывания: Action, Shooter, Sports, Role-playing, Racing
JP Популярные жанры в порядке убывания: Role-playing, Action, Fighthing, Misc, Shooter
Наиболее популярные жанры по всем локациям это : Shooter, Action, Role-playing. Самый популярный это Action везде высокие продажи на фоне других жанров (учитывая регионы)
Давай визуализируем результаты группировки продаж по жанрам и платформам (ну и по рейтингам), так информация будет гораздо нагляднее, ведь мы делаем исследование для отдела маркетинга. Тем более это у тебя отлично получается:)
Тут подойдет barplot или piechart
Продажи по регионам в зависимости от рэйтинга
print(df_new.pivot_table(index ='rating' , values = 'na_sales',
aggfunc= 'sum').sort_values(by ='na_sales', ascending =False),'\n')
print(df_new.pivot_table(index ='rating' , values = 'eu_sales',
aggfunc= 'sum').sort_values(by ='eu_sales', ascending =False),'\n')
print(df_new.pivot_table(index ='rating' , values = 'jp_sales',
aggfunc= 'sum').sort_values(by ='jp_sales', ascending =False),'\n')
na_sales
rating
m 96.42
not_defined 64.72
e 50.74
t 38.95
e10+ 33.23
eu_sales
rating
m 93.44
not_defined 58.95
e 58.06
t 34.07
e10+ 26.16
jp_sales
rating
not_defined 56.89
t 14.78
e 8.94
m 8.01
e10+ 4.46
NA Самый популярный ценз игры с отметкой "m", следом идут игры которым не был присвоен ценз, далее без ограничений, подростки и 10+
EU положение такое же как и в NA регионе
JP Здесь лидирующую позицию заняли игры чей ценз не определен, далее идут подростки, для взрослых, без ограничений и замыкает все 10+. Но в отличии от других регионов в JP четко виден перевес в одну категорию "not_defined".
Рейтинг ESRB оказывает влияние на отдельные регионы.
Как ты думаешь, почему в Японии большинство игр не имеют рейтинга ESRB?
Проверка гипотез¶
Перед проверкой нужно обязательно формулировать как нулевую, так и альтернативную гипотезы.
Все библиотеки лучше импортировать в самом начале проекта, в отдельной ячейке. Если в процессе работы появилась необходимость добавить библиотеку, то ее можно дописать в эту ячейку и исполнить.
Средние пользовательские рейтинги платформ Xbox One и PC одинаковые;¶
H0 : Средние пользовательские рейтинги платформ Xbox One и PC одинаковые(средние двух генеральных совокупностей равны между собой)
H1 : Средние пользовательские рейтинги платформ Xbox One и PC неравны.
df_new.query('user_score != 0 ')['user_score'].hist(bins =30)# убедимся что у нас нормальное распределение
plt.show()
#df.query('user_score != 0 & genre == "action"')['user_score'].hist(bins =30) посмотрел по отдельности каждую выборку.
#Распределение нормальное
alpha = .05 # критический уровень статистической значимости
# если p-value окажется меньше него - отвергнем гипотезу
results = st.ttest_ind(
df_new.query(' platform == "pc" & user_score !=0 & user_score == user_score')['user_score'],
df_new.query(' platform == "xone" & user_score !=0 & user_score == user_score')['user_score'])
print('p-значение:', results.pvalue)
if results.pvalue < alpha:
print("Отвергаем нулевую гипотезу")
else:
print("Не получилось отвергнуть нулевую гипотезу")
p-значение: 0.10450507919348415 Не получилось отвергнуть нулевую гипотезу
H0 : Средние пользовательские рейтинги платформ Xbox One и PC одинаковые(средние двух генеральных совокупностей равны между собой) H1 : Средние пользовательские рейтинги платформ Xbox One и PC неравны.
Вывод: При уровне значимости 0.05 мы не можем отвергнуть нулевую гипотезу, так как в 10 случаях из 100 мы можем получить равенство двух генеральных совокупностей. Уровень значимости выбран такой поскольку гипотеза двусторонняя.
Выборки должны быть без 0 значений.
Средние пользовательские рейтинги жанров Action (англ. «действие», экшен-игры) и Sports (англ. «спортивные соревнования») разные.¶
H0 : Cредние двух генеральных совокупностей равны между собой, пользовательские рейтинги жанров Action и Sports.
H1 : пользовательские рейтинги жанров не равны между собой Action и Sports.
alpha = 0.05 # критический уровень статистической значимости
# если p-value окажется меньше него - отвергнем гипотезу
results = st.ttest_ind(
df_new.query(' genre == "action" & user_score !=0 & user_score == user_score ')['user_score'],
df_new.query(' genre == "sports" & user_score !=0 & user_score == user_score')['user_score'])
print('p-значение:', results.pvalue)
if results.pvalue < alpha:
print("Отвергаем нулевую гипотезу")
else:
print("Не получилось отвергнуть нулевую гипотезу")
p-значение: 2.8711147985105864e-19 Отвергаем нулевую гипотезу
H0 : Cредние двух генеральных совокупностей равны между собой, пользовательские рейтинги жанров Action и Sports.
H1 : пользовательские рейтинги жанров не равны между собой Action и Sports.
Вывод: Отвергаем нулевую гипотезу о равенстве т.к. alpha > 2.87e-13 . Alpha равен 0.05 т.к гипотеза двустороняя.
Общий вывод:¶
Проведя работу над датасетом и поставленной задачей можно сделать следующие выводы-тезисы:
- Лучшими платформами для решения наших задач это: 1. PS4 2. Xboxe One 3. 3DS можно рассматривать как дополнительную альтернативу, медиана продаж находится на уровне 140 000. Платформы Xbox One и PS4 имеют пропорциональный boxplot и данные скошены в право(положительно). Это говорит нам о том что данные однородны(близки)-> практически все продукты покупаются хорошо и среднии продажи выше медианных.
- Продажи по всем платформам падают и количество выпускаемых продуктов уменьшается.
- Продажи линейно не зависят от рейтинга-отзыва пользователей и критиков, что нам и показала корреляция этих данных
- Лидирующие и аутсайдерские позиции жанров. Топ в порядке убывания: shooter, sports, platform, fighting, role-playing, simulation. Топ аутсайдов в порядке возрастания: adventure, strategy,puzzle, racing, misc, action.
- Лидирующие и аутсайдерские позиции жанров. Топ в порядке убывания: shooter, sports, role-playing, simulation и platform. Топ аутсайдов в порядке возрастания: adventure, puzzle, strategy, racing, misc, action.
- Период для анализа был выбран с 2015-2016. По нашему предположению и анализу этот отрезок времени характерезует сложившуюся обстановку на рынке платформ и программных продуктов к ним.
- При планировании рекламных компаний стоит использовать таргетированную рекламу по регионам продаж, т.к. они различаются в следующих моментах:
1) Популярность жанров по регионам:
- NA Популярные платформы в порядке убывания: PS4, Xbox One,Xbox x360, 3DS,PS3
- EU Популярные платформы в порядке убывания: PS4, Xbox One, PS3, PC, 3DS
- JP Популярные платформы в порядке убывания: 3DS, PS4,PSV,PS3, WIIU
Во всех регионах PS4 занимает если не первое место то второе, это очень популярная платформа. Платформа 3DS
и Xbox One хорошо представленны в EU и JP. Суммарные продажи высоки.
Также везде присутствует PS3, но ее мы в дальнейшем не рассматриваем т.к. она уже устарела.
2) NA Популярные платформы в порядке убывания: PS4, Xbox One,Xbox x360, PS3
EU Популярные платформы в порядке убывания: PS4, Xbox One, PS3, PC, 3DS
JP Популярные платформы в порядке убывания: 3DS, PS4,PSV,PS3, WIIU
Во всех регионах PS4 занимает если не первое место то второе, это очень популярная платформа.
Платформа 3DS и Xbox One хорошо представленны в EU и JP. Суммарные продажи высоки.
3)Рейтинг и продажи:
- NA Самый популярный ценз игры с отметкой "m", следом идут игры которым не был присвоен ценз, далее без
ограничений, подростки и 10+
- EU положение такое же как и в NA регионе
- JP Здесь лидирующую позицию заняли игры чей ценз не определен, далее идут подростки, для взрослых, без
ограничений и замыкает все 10+. Но в отличии от других регионов в JP четко виден перевес в одну категорию
"not_defined".
Рейтинг ESRB оказывает влияние на отдельные регионы.
- Были выдвинуты две гипотезы: 1)Средние пользовательские рейтинги платформ Xbox One и PC одинаковые. Гипотезу не можем отвергнуть.
2)Cредние двух генеральных совокупностей равны между собой, пользовательские рейтинги жанров Action и Sports.
Гипотеза отвергнута.
Хороший резюмирующий вывод! Молодец, что не забыл дать рекомендации на 2017 год.
В целом проект получился очень даже хорошим. Ты уверенно обращаешься с данными, отлично их анализируешь и строишь прекрасные визуализации! Нужно только подправить несколько замечаний и будет супер!
Хочу обратить твое внимание на то, что после исправления замечаний в некоторых пунктах исследования могут измениться результаты, поэтому нужно будет подкорректировать выводы.