Цель: сформулировать рекомендацию руководству компании о том, на каких играх стоит сосредоточиться в будущем году.
Задачи: проанализировать накопленные данные о продажах в разные года, определить тренды и проверить гипотезы.
# Необходимые библиотеки
import pandas as pd
import matplotlib.pyplot as plt
import numpy as np
from scipy import stats as st
%matplotlib inline
# Загрузка данных
games_data = pd.read_csv('games_data.csv')
ratind_data = pd.read_csv('rating.csv') # данные о возрастном рейтинге ESRB
Описание данных
games_data.head()
games_data.info()
# Проверка на дубликаты
games_data.duplicated().sum()
print('В столбце с оценкой пользователей содержится', len(games_data[games_data['user_score'] == 'tbd']), 'строк, содержащих tbd')
# Общее количество продаж: сумма онлайн и оффлайн покупок
games_data['revenue'] = games_data['online'] + games_data['offline']
Промежуточные выводы
Замена типа данных необходима для упрощения дальнейших расчетов.
# Замена tbd в столбце с оценкой пользователей
games_data.loc[games_data['user_score'] == 'tbd', 'user_score'] = np.nan
# Изменение типов данных
games_data['sales_year'] = games_data['sales_year'].astype('int')
games_data['online'] = games_data['online'].astype('int')
games_data['offline'] = games_data['offline'].astype('int')
games_data['revenue'] = games_data['revenue'].astype('int')
games_data['user_score'] = games_data['user_score'].astype('float')
# Проверка
games_data.info()
Постройте распределение по годам продажи для игр с отзывом и без отзыва
# Создаем таблицу для подсчета
years_bt_review = (
pd.DataFrame(games_data[(games_data['critic_score'].notnull()) & (games_data['user_score'].notnull())] \
.groupby('sales_year')['sales_year'].count())
.join(
pd.DataFrame(games_data[(games_data['critic_score'].isnull()) | (games_data['user_score'].isnull())]\
.groupby('sales_year')['sales_year'].count()), lsuffix='_nan', rsuffix='_not_nan'
)
)
years_bt_review.columns = ['Нет оценок', 'Есть хотя бы одна оценка']
years_bt_review.plot(kind='bar', alpha=0.5)
plt.title('Распределение количества игр по годам продажи относительно наличия оценок'+ "\n")
plt.xlabel('Год')
plt.ylabel('Количество')
plt.show()
years_bt_review['Доля без оценок'] = years_bt_review['Нет оценок'] / (years_bt_review['Нет оценок'] \
+ years_bt_review['Есть хотя бы одна оценка']) * 100
years_bt_review['Доля с оценкой'] = 100 - years_bt_review['Доля без оценок']
years_bt_review
Вывод
Количество и доля реализуемых игр с оценками на протяжении всего исследуемого периода всегда больше, чем у игр без оценок. Не смотря на высокие показатели в 2017 году, максимальная доля проданных игр с оценкой отмечена в 2015 году. Наиболее удачный год для реализации игр без оценок - 2018. Стоит проанализировать стратегию продаж в 2015 и в 2018 годах для увеличения показателей.
Постройте ящик с усами по общим продажам, опишите полученный результат
games_data['revenue'].plot(kind='box', ylim=(-10,200))
plt.title('Распределение выручки за все года')
games_data.boxplot(column='revenue', by='sales_year').set_title("\n")
plt.show()
games_data['revenue'].describe()
# Сколько игр не получили денег с продажи с неуказанным рейтингом
len((games_data[(games_data['revenue'] == 0) &
(games_data['critic_score'].isnull()) &
(games_data['user_score'].isnull())
]
))
Выводы
# Проверка зависимости года и рейтинга
games_data.boxplot(by='sales_year', column='user_score').set_title("")
plt.title('Распределение рейтинга зрителей по годам'+ '\n\n')
games_data.boxplot(by='sales_year', column='critic_score').set_title("")
plt.title('Распределение рейтинга критиков по годам' + '\n\n')
plt.show()
Выводы
def get_top_5(group, type_sale):
"""
Функция для определения портрета пользователя в зависимости от канала продаж.
"""
top_5 = games_data.groupby(group)[type_sale].sum().reset_index()
top_5['rate'] = 100 * top_5[type_sale] / top_5[type_sale].sum()
return top_5.sort_values(by=type_sale, ascending=False).head()
Топ-5 предпочтительных жанров
# Топ для онлайн-продаж
get_top_5('genre', 'online')
# Топ для онлайн-продаж
get_top_5('genre', 'offline')
Вывод
Клиентв обоих каналов дистрибьюции игр одинаковые предпочтения к тематическим игровым направлениям. Что примечательно, процентное соотношение интересов пользователей почти не отличается между интернет и оффлайн продажами.
В какие года пользователи были наиболее активны (больше всего покупали игры)
# Активность по годам в интернет-продажах
get_top_5('sales_year', 'online')
# Активность по годам в оффлайн-продажах
get_top_5('sales_year', 'offline')
Вывод
Больше всего клиенты интернет-магазина и сети розничных магазинов покупали игры в 2017 году. Стоит отметить, что выручка обоих каналов продаж распределена равномерно. Возможно, необходимо усилить рекламные кампании для интернет-магазина, т.к. в целом в последние года пользователи все чаще делают покупки в интернет-магазинах, чем в оффлайн.
Какой рейтинг ESRB встречается чаще всего (наиболее частотная категория)
# Рейтинг ESRB для интернет-покупок
get_top_5('rating', 'online').merge(ratind_data,left_on='rating', right_on='rating_type')
# Рейтинг ESRB для оффлайн-магазина
get_top_5('rating', 'offline').merge(ratind_data,left_on='rating', right_on='rating_type')
Вывод
В обоих каналах продаж лидируют игры с рейтингом "От 17 лет" и "Для всех" - более 65% от всех проданных игр. Стоит отметить, что игры для детей младшего возраста выбирают чаще всего клиенты интернет-магазина. Вероятно, это связано с нехваткой времени для покупок в розничных магазинах. Можно подробнее рассмотреть этот инсайд для корректировки стратегии продвижения игр в интернет-магазинах.
Средний пользовательский рейтинг платформ PS4 и PS3 одинаковый
Н0 - cредний пользовательский рейтинг платформ PS4 и PS3 одинаковый, т.е. средние значения выборок равны.
Н1 - cредний пользовательский рейтинг платформ PS4 и PS3 разный, т.е. средние значения выборок не равны.
Для проверки гипотезы будет использоваться критерий p-value.
results = st.ttest_ind(games_data[(games_data['platform'] == "PS4") & (games_data['user_score'].notna())]['user_score'], \
games_data[(games_data['platform'] == "PS3") & (games_data['user_score'].notna())]['user_score'])
alpha = 0.05
print('p-значение: ', results.pvalue)
if results.pvalue < alpha:
print('Принимаем альтернативную гипотезу')
else:
print('Опровергнуть нулевую гипотезу нельзя')
Вывод
Полученное значение p-value говорит о том, что средний пользовательский рейтинг платформ PS4 и PS3 отличается, но с вероятностью в почти 26% такое различие можно получить случайно. Это слишком высокая вероятность для того, чтобы делать выводы о значимом различии между средними значениями рейтинга.
Средний пользовательский рейтинг жанров Action и Sports различается
Н0 - средний пользовательский рейтинг жанров Action и Sports одинаковый, т.е. средние значения выборок раввны.
Н1 - средний пользовательский рейтинг жанров Action и Sports разный, т.е. средние значения выборок не равны.
Для проверки гипотезы будет использоваться критерий p-value.
results = st.ttest_ind(games_data[(games_data['genre'] == "Action") & (games_data['user_score'].notna())]['user_score'], \
games_data[(games_data['genre'] == "Sports")& (games_data['user_score'].notna())]['user_score'])
alpha = 0.05
print('p-значение: ', results.pvalue)
if results.pvalue < alpha:
print('Принимаем альтернативную гипотезу')
else:
print('Опровергнуть нулевую гипотезу нельзя')
Вывод
p-значение достаточно мало, что дает основание отвергнуть предположение об отсутствии различий между рейтингами жанров Action и Sports, т.е. маловероятна случайность результатов теста гипотезы.