Corporación Favorita — эквадорский конгломерат магазинов самообслуживания, инвестиций в недвижимость, производства электроэнергии, продуктов питания и предметов первой необходимости, торговли и оборудования. Компания присутствует в Эквадоре, Перу, Парагвае и Панаме. Супермаркеты La Favorita CA были основаны 26 ноября 1957 года. Это был первый супермаркет самообслуживания в Эквадоре.
В этом проекте мы будем использовать прогнозирование временных рядов для прогнозирования продаж магазинов на основе данных от Corporación Favorita для тысяч семейств продуктов, продаваемых в магазинах Favorita. Данные обучения включают даты, информацию о магазине и продукте, информацию о том, рекламировался ли этот товар, а также количество продаж.
Для продуктовых магазинов более точное прогнозирование может уменьшить количество пищевых отходов, связанных с затовариванием, и повысить удовлетворенность покупателей.
Мы используем этот набор данных от Kaggle.
Источник набора данных: https://www.kaggle.com/competitions/store-sales-time-series-forecasting
Как запустить код
Это руководство представляет собой исполняемый блокнот Jupyter, размещенный на Jovian. Вы можете запустить это руководство и поэкспериментировать с примерами кода двумя способами: используя бесплатные онлайн-ресурсы (рекомендуется) или на своем компьютере.
Вариант 1. Использование бесплатных онлайн-ресурсов (рекомендуется в один клик)
Самый простой способ начать выполнение кода — нажать кнопку «Выполнить» в верхней части этой страницы и выбрать «Выполнить на Binder». Вы также можете выбрать «Запустить на Colab» или «Запустить на Kaggle», но для использования этих платформ вам потребуется создать учетную запись в Google Colab или Kaggle.
Вариант 2. Запуск на локальном компьютере
Чтобы запустить код на вашем компьютере локально, вам нужно настроить Python, загрузить блокнот и установить необходимые библиотеки. Мы рекомендуем использовать дистрибутив Python Conda. Нажмите кнопку «Выполнить» в верхней части этой страницы, выберите параметр «Выполнить локально» и следуйте инструкциям.
Описание набора данных
Описания файлов и информация о полях данных
- train.csv
- store_nbr: определяет магазин, в котором продаются товары.
- семейство: определяет тип продаваемого продукта.
- продажи: дает общий объем продаж для семейства продуктов в конкретном магазине на заданную дату. Дробные значения возможны, так как продукты могут продаваться в дробных единицах (например, 1,5 кг сыра вместо 1 пакета чипсов).
- onpromotion: показывает общее количество товаров в семействе продуктов, которые рекламировались в магазине на указанную дату.
- test.csv
- Тестовые данные, имеющие те же характеристики, что и обучающие данные. Мы будем прогнозировать целевые продажи для дат в этом файле.
- Даты в тестовых данных относятся к 15 дням после последней даты в обучающих данных.
- sample_submission.csv
- Образец файла отправки в правильном формате.
- stores.csv
- Храните метаданные, включая город, штат, тип и кластер.
- кластер — это группа похожих магазинов.
- oil.csv
- Ежедневная цена на нефть. Включает значения как во время обучения, так и во время тестовых данных. (Эквадор — страна, зависящая от нефти, и ее экономическое здоровье очень уязвимо к скачкам цен на нефть.)
- holidays_events.csv
- Праздники и события с метаданными
- ПРИМЕЧАНИЕ. Обратите особое внимание на переданную колонку. Перенесенный праздник официально приходится на этот календарный день, но правительство перенесло его на другую дату. Перенесенный день больше похож на обычный день, чем на праздник. Чтобы найти день его празднования, найдите соответствующую строку, где тип — «Перенос». Например, праздник Independencia de Guayaquil был перенесен с 2012–10–09 на 2012–10–12, что означает, что он отмечался 2012–10–12. Дни типа «Мост» — это дополнительные дни, которые добавляются к празднику (например, чтобы продлить перерыв на длинные выходные). Они часто состоят из типа «Рабочий день», который обычно не запланирован для работы (например, суббота), который предназначен для окупаемости Моста.
- Дополнительные праздники — это дни, добавленные к обычному календарному празднику, например, как это обычно бывает на Рождество (что делает Сочельник выходным днем).
- Дополнительные примечания Заработная плата в бюджетной сфере выплачивается каждые две недели 15 числа и в последний день месяца. Это может повлиять на продажи в супермаркетах. Землетрясение магнитудой 7,8 произошло в Эквадоре 16 апреля 2016 года. Люди объединились для оказания помощи, пожертвовав воду и другие предметы первой необходимости, что сильно повлияло на продажи в супермаркетах в течение нескольких недель после землетрясения.
Выявление проблемы
Продажи — это помеченная непрерывная числовая характеристика. Следовательно, это приложение Supervised ML, в частности, это проблема регрессии.
Метрика оценки
Показателем оценки для этого соревнования является среднеквадратическая логарифмическая ошибка.
RMSLE рассчитывается как:
$$RMSLE = \sqrt{ \frac{1}{n} \sum_{i=1}^n \left(\log (1 + \hat{y}_i) — \log (1 + y_i)\right)²}$$
где:
$n$ — общее количество экземпляров,
$\hat{y}_i$ — прогнозируемое значение цели для экземпляра (i),
${y}_i$ — фактическое значение цели, например (i)
$log$ — натуральный логарифм.
Скачать набор данных
Установите и импортируйте необходимые библиотеки
!pip install --upgrade pandas "dask[complete]" --quiet
[2K [90m━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━[0m [32m12.3/12.3 MB[0m [31m75.2 MB/s[0m eta [36m0:00:00[0m [2K [90m━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━[0m [32m1.2/1.2 MB[0m [31m61.5 MB/s[0m eta [36m0:00:00[0m [2K [90m━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━[0m [32m341.8/341.8 kB[0m [31m31.7 MB/s[0m eta [36m0:00:00[0m [2K [90m━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━[0m [32m1.3/1.3 MB[0m [31m73.7 MB/s[0m eta [36m0:00:00[0m [2K [90m━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━[0m [32m980.4/980.4 kB[0m [31m42.7 MB/s[0m eta [36m0:00:00[0m [?25h[31mERROR: pip's dependency resolver does not currently take into account all the packages that are installed. This behaviour is the source of the following dependency conflicts. google-colab 1.0.0 requires pandas==1.5.3, but you have pandas 2.0.3 which is incompatible.[0m[31m [0m
!pip install opendatasets seaborn matplotlib plotly scikit-learn xgboost lightgbm --upgrade --quiet
[2K [90m━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━[0m [32m11.6/11.6 MB[0m [31m33.9 MB/s[0m eta [36m0:00:00[0m [2K [90m━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━[0m [32m15.5/15.5 MB[0m [31m23.3 MB/s[0m eta [36m0:00:00[0m [2K [90m━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━[0m [32m10.8/10.8 MB[0m [31m30.5 MB/s[0m eta [36m0:00:00[0m [2K [90m━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━[0m [32m98.3/98.3 kB[0m [31m11.1 MB/s[0m eta [36m0:00:00[0m [?25h
# Import library to download data from Kaggle import opendatasets as od import os import random import pandas as pd # data processing, CSV file I/O (e.g. pd.read_csv) import numpy as np # linear algebra import warnings warnings.filterwarnings('ignore')
# Visualisation libraries import matplotlib import matplotlib.pyplot as plt import seaborn as sns import plotly.graph_objects as go from plotly.subplots import make_subplots import plotly.express as px %matplotlib inline # Configuring styles sns.set_style("darkgrid") plt.rcParams['font.size'] = 14 plt.rcParams['figure.figsize'] = (15, 6) plt.rcParams['figure.facecolor'] = '#00000000'
#Models Packages from sklearn import metrics from sklearn.metrics import mean_squared_log_error from sklearn import feature_selection from sklearn.model_selection import train_test_split from sklearn import preprocessing from sklearn.preprocessing import MinMaxScaler from sklearn.preprocessing import OneHotEncoder import random pd.options.display.float_format = '{:,.2f}'.format from sklearn.linear_model import LinearRegression, Ridge, SGDRegressor from sklearn.tree import DecisionTreeRegressor from sklearn.ensemble import RandomForestRegressor import xgboost as xgb from xgboost import XGBRegressor import lightgbm as lgb from lightgbm import LGBMRegressor
Загрузка данных
dataset_url = 'https://www.kaggle.com/competitions/store-sales-time-series-forecasting'
od.download(dataset_url)
Downloading store-sales-time-series-forecasting.zip to ./store-sales-time-series-forecasting 100%|██████████| 21.4M/21.4M [00:00<00:00, 34.8MB/s] Extracting archive ./store-sales-time-series-forecasting/store-sales-time-series-forecasting.zip to ./store-sales-time-series-forecasting
data_dir = "store-sales-time-series-forecasting"
Просмотр файлов набора данных
os.listdir(data_dir)
['train.csv', 'test.csv', 'oil.csv', 'transactions.csv', 'stores.csv', 'sample_submission.csv', 'holidays_events.csv']
train_df = pd.read_csv(data_dir+'/train.csv') test_df = pd.read_csv(data_dir+'/test.csv') transactions_df = pd.read_csv(data_dir+'/transactions.csv') stores_df = pd.read_csv(data_dir+'/stores.csv') oil_df = pd.read_csv(data_dir+'/oil.csv') holidays_df = pd.read_csv(data_dir+'/holidays_events.csv')
print('Training dataset length:', len(train_df)) print('Test dataset length:', len(test_df)) print('Transactions dataset length:', len(transactions_df)) print('Stores dataset length:', len(stores_df)) print('Oil dataset length:', len(oil_df)) print('Holidays events dataset length:', len(holidays_df))
Training dataset length: 3000888 Test dataset length: 28512 Transactions dataset length: 83488 Stores dataset length: 54 Oil dataset length: 1218 Holidays events dataset length: 350
print('Training dataset Shape:', (train_df.shape)) print('Test dataset Shape:', (test_df.shape)) print('Transactions dataset Shape:', (transactions_df.shape)) print('Stores dataset Shape:', (stores_df.shape)) print('Oil dataset Shape:', (oil_df.shape)) print('Holidays events dataset Shape:', (holidays_df.shape))
Training dataset Shape: (3000888, 6) Test dataset Shape: (28512, 5) Transactions dataset Shape: (83488, 3) Stores dataset Shape: (54, 5) Oil dataset Shape: (1218, 2) Holidays events dataset Shape: (350, 6)
train_df.head()
test_df.head()
Набор данных содержит более 3 миллионов строк и 6 столбцов в обучающих данных и более 28 тысяч строк и 5 столбцов в тестовых данных.
Мы будем использовать только 1% обучающих данных для обучения модели.
sample_fraction = 0.1
def skip_row(row_idx):
if row_idx == 0:
return False
return random.random() > sample_fraction
# Loading the data with skip rows
random.seed(42)
train_df = pd.read_csv(data_dir+'/train.csv',
skiprows=skip_row)
Исследуйте набор данных
train_df.info()
<class 'pandas.core.frame.DataFrame'> RangeIndex: 300730 entries, 0 to 300729 Data columns (total 6 columns): # Column Non-Null Count Dtype --- ------ -------------- ----- 0 id 300730 non-null int64 1 date 300730 non-null object 2 store_nbr 300730 non-null int64 3 family 300730 non-null object 4 sales 300730 non-null float64 5 onpromotion 300730 non-null int64 dtypes: float64(1), int64(3), object(2) memory usage: 13.8+ MB
train_df.describe()
test_df.info()
<class 'pandas.core.frame.DataFrame'> RangeIndex: 28512 entries, 0 to 28511 Data columns (total 5 columns): # Column Non-Null Count Dtype --- ------ -------------- ----- 0 id 28512 non-null int64 1 date 28512 non-null object 2 store_nbr 28512 non-null int64 3 family 28512 non-null object 4 onpromotion 28512 non-null int64 dtypes: int64(3), object(2) memory usage: 1.1+ MB
stores_df.info()
<class 'pandas.core.frame.DataFrame'> RangeIndex: 54 entries, 0 to 53 Data columns (total 5 columns): # Column Non-Null Count Dtype --- ------ -------------- ----- 0 store_nbr 54 non-null int64 1 city 54 non-null object 2 state 54 non-null object 3 type 54 non-null object 4 cluster 54 non-null int64 dtypes: int64(2), object(3) memory usage: 2.2+ KB
transactions_df.info()
<class 'pandas.core.frame.DataFrame'> RangeIndex: 83488 entries, 0 to 83487 Data columns (total 3 columns): # Column Non-Null Count Dtype --- ------ -------------- ----- 0 date 83488 non-null object 1 store_nbr 83488 non-null int64 2 transactions 83488 non-null int64 dtypes: int64(2), object(1) memory usage: 1.9+ MB
transactions_df.describe()
oil_df.info()
<class 'pandas.core.frame.DataFrame'> RangeIndex: 1218 entries, 0 to 1217 Data columns (total 2 columns): # Column Non-Null Count Dtype --- ------ -------------- ----- 0 date 1218 non-null object 1 dcoilwtico 1175 non-null float64 dtypes: float64(1), object(1) memory usage: 19.2+ KB
oil_df.describe()
holidays_df.info()
<class 'pandas.core.frame.DataFrame'> RangeIndex: 350 entries, 0 to 349 Data columns (total 6 columns): # Column Non-Null Count Dtype --- ------ -------------- ----- 0 date 350 non-null object 1 type 350 non-null object 2 locale 350 non-null object 3 locale_name 350 non-null object 4 description 350 non-null object 5 transferred 350 non-null bool dtypes: bool(1), object(5) memory usage: 14.1+ KB
train_df.family.nunique(), train_df.family.unique()
(33, array(['BABY CARE', 'CLEANING', 'DELI', 'GROCERY I', 'LADIESWEAR', 'PET SUPPLIES', 'PLAYERS AND ELECTRONICS', 'DAIRY', 'FROZEN FOODS', 'LIQUOR,WINE,BEER', 'MAGAZINES', 'POULTRY', 'PERSONAL CARE', 'SEAFOOD', 'BEAUTY', 'BOOKS', 'AUTOMOTIVE', 'HOME CARE', 'LINGERIE', 'BREAD/BAKERY', 'SCHOOL AND OFFICE SUPPLIES', 'EGGS', 'CELEBRATION', 'GROCERY II', 'HOME AND KITCHEN I', 'HARDWARE', 'MEATS', 'PREPARED FOODS', 'HOME AND KITCHEN II', 'HOME APPLIANCES', 'BEVERAGES', 'PRODUCE', 'LAWN AND GARDEN'], dtype=object))
train_df.store_nbr.nunique()
54
stores_df[['city','state','type','cluster']].nunique(), stores_df.type.unique()
(city 22 state 16 type 5 cluster 17 dtype: int64, array(['D', 'B', 'C', 'E', 'A'], dtype=object))
Мы выяснили, что в 54 магазинах в 22 городах, расположенных в 16 штатах, продается 33 товарных семейства. Магазины делятся на 5 типов: «А», «В», «С», «D» и «Е». Также есть 17 кластеров, т.е. группировка похожих магазинов.
Заполнение отсутствующих значений в oil_df
def fill_nan_with_mean(df, column_name): values = df[column_name].values is_nan = np.isnan(values) filled_values = values.copy() for i in range(1, len(filled_values)-1): if np.isnan(filled_values[i]): prev_val = filled_values[i-1] next_val = filled_values[i+1] if not np.isnan(prev_val) and not np.isnan(next_val): filled_values[i] = (prev_val + next_val) / 2 df[column_name] = filled_values return df
fill_nan_with_mean(oil_df, 'dcoilwtico')
oil_df[oil_df.dcoilwtico.isna()]
Тем не менее у нас есть 3 nan(s), заполняя их вручную
oil_df.dcoilwtico[0] = 93.14 # filling the first value similar to second value
print(oil_df.loc[1173])
date 2017-06-30 dcoilwtico 46.02 Name: 1173, dtype: object
# filling these two similar to the previous value oil_df.dcoilwtico[1174]=46.02 oil_df.dcoilwtico[1175]=46.02
oil_df.isna().sum()
date 0 dcoilwtico 0 dtype: int64
Манипуляции с данными и очистка
Преобразуем даты в datetime
train_df["date"] = pd.to_datetime(train_df["date"])
test_df['date'] = pd.to_datetime(test_df['date'])
transactions_df['date'] = pd.to_datetime(transactions_df['date'])
oil_df['date'] = pd.to_datetime(oil_df['date'])
holidays_df['date'] = pd.to_datetime(holidays_df['date'])
Мы объединим train_df и test_df с store_df, oil_df и holiday_df. В holiday_df «locale_name» — это город, поэтому мы должны переименовать столбец как город. В магазинах и праздниках столбец «тип» одинаков, поэтому мы должны переименовать их как store_type и day_type. В oil_df «dcoilwtico» — это цена на нефть, поэтому мы также переименуем этот столбец. Нам не нужно описание праздников, поэтому мы опустим этот столбец.
stores_df.rename(columns = {'type':'store_type'}, inplace=True)
oil_df.rename(columns = {'dcoilwtico':'oil_price'}, inplace=True)
holidays_df.rename(columns = {'locale_name':'city', 'type': 'day_type'}, inplace=True)
holidays_df.drop('description', axis=1, inplace=True)
Теперь объединяем разные наборы данных
merged_train_df = train_df.merge(stores_df, how='left', on='store_nbr') merged_test_df = test_df.merge(stores_df, how='left', on='store_nbr') merged_train_df = pd.merge(merged_train_df, oil_df, how='left', on='date') merged_test_df = pd.merge(merged_test_df, oil_df, how='left', on='date') merged_train_df = pd.merge(merged_train_df, holidays_df, how='left', on=['date', 'city']) merged_test_df = pd.merge(merged_test_df, holidays_df, how='left', on=['date', 'city'])
merged_train_df
merged_test_df
Заполнение значений nan в объединенном наборе данных
# Filling the nan(s) with the value before nan because oil prices don't change very much every other day
merged_train_df['oil_price'].fillna(method = 'ffill', inplace=True)
merged_test_df['oil_price'].fillna(method = 'ffill', inplace=True)
# 'day_type' is filled with holidays, so all nan(s) are working days
merged_train_df['day_type'].fillna('working_day',inplace=True)
merged_test_df['day_type'].fillna('working_day',inplace=True)
# All the NaN value in 'locale' column are working days hence it is National
merged_train_df['locale'].fillna('National', inplace=True)
merged_test_df['locale'].fillna('National', inplace=True)
# All the NaN values are working days hence not tranferred
merged_train_df['transferred'].fillna(False, inplace=True)
merged_test_df['transferred'].fillna(False, inplace=True)
изменение типов данных столбцов
merged_train_df['store_nbr']= merged_train_df['store_nbr'].astype('uint8')
merged_train_df['sales']= merged_train_df['sales'].astype('float64')
merged_train_df['onpromotion']=merged_train_df['onpromotion'].astype('uint16')
merged_train_df['cluster']= merged_train_df['cluster'].astype('uint8')
merged_train_df['oil_price']= merged_train_df['oil_price'].astype('float64')
merged_train_df['transferred'] = merged_train_df['transferred'].astype('uint8')
merged_test_df['store_nbr']= merged_test_df['store_nbr'].astype('uint8')
merged_test_df['onpromotion']= merged_test_df['onpromotion'].astype('uint16')
merged_test_df['cluster']= merged_test_df['cluster'].astype('uint8')
merged_test_df['oil_price']= merged_test_df['oil_price'].astype('float64')
merged_test_df['transferred'] = merged_test_df['transferred'].astype('uint8')
Замена значений «семейства» добавлением «подчеркивания» в «пробел», потому что это приводит к ошибке во время обучения легкой модели GBM.
def replace_fam_vals(df): df.replace('HOME APPLIANCES','HOME_APPLIANCES',inplace=True) df.replace('BABY CARE','BABY_CARE',inplace=True) df.replace('BREAD/BAKERY','BREAD_BAKERY',inplace=True) df.replace('FROZEN FOODS','FROZEN_FOODS',inplace=True) df.replace('GROCERY I','GROCERY_I',inplace=True) df.replace('GROCERY II','GROCERY_II',inplace=True) df.replace('HOME AND KITCHEN I','HOME_AND_KITCHEN_I',inplace=True) df.replace('HOME AND KITCHEN II','HOME_AND_KITCHEN_II',inplace=True) df.replace('HOME CARE','HOME_CARE',inplace=True) df.replace('LAWN AND GARDEN','LAWN_AND_GARDEN',inplace=True) df.replace('LIQUOR,WINE,BEER','LIQUOR_WINE_BEER',inplace=True) df.replace('PERSONAL CARE','PERSONAL_CARE',inplace=True) df.replace('PET SUPPLIES','PET_SUPPLIES',inplace=True) df.replace('PLAYERS AND ELECTRONICS','PLAYERS_AND_ELECTRONICS',inplace=True) df.replace('PREPARED FOODS','PREPARED_FOODS',inplace=True) df.replace('SCHOOL AND OFFICE SUPPLIES','SCHOOL_AND_OFFICE_SUPPLIES',inplace=True) return df
replace_fam_vals(merged_train_df.family) replace_fam_vals(merged_test_df.family)
0 AUTOMOTIVE 1 BABY_CARE 2 BEAUTY 3 BEVERAGES 4 BOOKS ... 28507 POULTRY 28508 PREPARED_FOODS 28509 PRODUCE 28510 SCHOOL_AND_OFFICE_SUPPLIES 28511 SEAFOOD Name: family, Length: 28512, dtype: object
merged_train_df.info()
<class 'pandas.core.frame.DataFrame'> RangeIndex: 300754 entries, 0 to 300753 Data columns (total 14 columns): # Column Non-Null Count Dtype --- ------ -------------- ----- 0 id 300754 non-null int64 1 date 300754 non-null datetime64[ns] 2 store_nbr 300754 non-null uint8 3 family 300754 non-null object 4 sales 300754 non-null float64 5 onpromotion 300754 non-null uint16 6 city 300754 non-null object 7 state 300754 non-null object 8 store_type 300754 non-null object 9 cluster 300754 non-null uint8 10 oil_price 300754 non-null float64 11 day_type 300754 non-null object 12 locale 300754 non-null object 13 transferred 300754 non-null uint8 dtypes: datetime64[ns](1), float64(2), int64(1), object(6), uint16(1), uint8(3) memory usage: 24.4+ MB
merged_train_df.describe()
Проверка дубликатов
merged_train_df.duplicated().sum()
0
Проверка даты начала и окончания данных
merged_train_df.date.min(), merged_train_df.date.max()
(Timestamp('2013-01-01 00:00:00'), Timestamp('2017-08-15 00:00:00'))
merged_test_df.date.min(), merged_test_df.date.max()
(Timestamp('2017-08-16 00:00:00'), Timestamp('2017-08-31 00:00:00'))
Данные обучения с 1 января 2013 г. по 15 августа 2017 г.
Данные испытаний с 16 августа 2017 г. по 31 августа 2017 г.
Разработка функций
Создание новых столбцов с использованием столбца даты
merged_train_df['year'] = merged_train_df['date'].dt.year
merged_train_df['month'] = merged_train_df['date'].dt.month
merged_train_df['week'] = merged_train_df['date'].dt.isocalendar().week
merged_train_df['quarter'] = merged_train_df['date'].dt.quarter
merged_train_df['day_of_week'] = merged_train_df['date'].dt.dayofweek
merged_test_df['year'] = merged_test_df['date'].dt.year
merged_test_df['month'] = merged_test_df['date'].dt.month
merged_test_df['week'] = merged_test_df['date'].dt.isocalendar().week
merged_test_df['quarter'] = merged_test_df['date'].dt.quarter
merged_test_df['day_of_week'] = merged_test_df['date'].dt.dayofweek
Изменение типов данных столбцов
merged_train_df['month'] = merged_train_df['month'].astype('uint8')
merged_train_df['year'] = merged_train_df['year'].astype('uint16')
merged_train_df['week'] = merged_train_df['week'].astype('uint8')
merged_train_df['quarter'] = merged_train_df['quarter'].astype('uint8')
merged_train_df['day_of_week'] = merged_train_df['day_of_week'].astype('uint16')
merged_test_df['month'] = merged_test_df['month'].astype('uint8')
merged_test_df['year'] = merged_test_df['year'].astype('uint16')
merged_test_df['week'] = merged_test_df['week'].astype('uint8')
merged_test_df['quarter'] = merged_test_df['quarter'].astype('uint8')
merged_test_df['day_of_week'] = merged_test_df['day_of_week'].astype('uint16')
Исследовательский анализ данных
1. Цена на нефть
date_oil_price = merged_train_df.groupby('date')[['oil_price']].mean() year_oil_price = merged_train_df.groupby('year')[['oil_price']].mean()
# plotting daily and yearly oil price fig, axes = plt.subplots(1,2, figsize=(12,5)) date_oil_price.plot(ax=axes[0]) year_oil_price.plot(ax=axes[1]) axes[0].set_title("Daily oil price") axes[1].set_title("Yearly oil price");
Информация
- Цены на нефть были максимальными в 2013 году, но в 2015 году наблюдается резкое снижение цен, а в 2016 году цены были минимальными.
2. Продажи в день
date_sales = merged_train_df.groupby('date')[['sales']].sum().reset_index()
# plotting The date vs sales line plot w.r.t to year px.line(date_sales, x ='date',y ='sales', title='line plot of date vs. sales')