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

Один из лучших способов прогнозирования продаж — использование методов машинного обучения Python. Взглянув на данные, собранные в продуктовом магазине в Эквадоре: Corporación Favorita Grocery, нам нужно будет использовать несколько методов прогнозирования временных рядов для прогнозирования продаж в магазине для эквадорского продуктового ритейлера Corporation Favorita. Даты, магазины, информация о продукте, был ли товар в продаже, а также статистика продаж включены в данные обучения. Отдельные файлы также снабжены дополнительной информацией, которая может быть полезна при разработке моделей.

Гипотеза

Продвижение положительно влияет на продажи.

NULL: нет значительного увеличения продаж, когда семейство продуктов находится на промо-акции.

АЛЬТЕРНАТИВНЫЙ ВАРИАНТ: когда товары проходят акцию, продажи значительно увеличиваются.

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

# Data handling
import pandas as pd
import numpy as np

#display all columns and rows 
pd.set_option('display.max_columns', None)

# Vizualisation (Matplotlib, Plotly, Seaborn, etc. )
import matplotlib.pyplot as plt
import seaborn as sns 

# EDA (pandas-profiling, etc. )
from pandas_profiling import ProfileReport
from datetime import date

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

Train_df = pd.read_csv('train.csv')
stores_df = pd.read_csv('stores.csv')
Transaction_df = pd.read_csv('transactions.csv')
oil_df = pd.read_csv('oil.csv')
submission_df = pd.read_csv('sample_submission.csv')
test_df = pd.read_csv('test.csv')
Holiday_df = pd.read_csv('holidays_events.csv')

Столбец даты был разбит на день, месяц и год для дальнейшего анализа.

Train_df["date"] = pd.to_datetime(Train_df["date"], format='%Y-%m-%d')
Transaction_df["date"] = pd.to_datetime(Transaction_df["date"], format='%Y-%m-%d')
oil_df["date"] = pd.to_datetime(oil_df["date"], format='%Y-%m-%d')
Holiday_df["date"] = pd.to_datetime(Holiday_df["date"], format='%Y-%m-%d')

Чтобы иметь 360-градусный обзор данных, наборы данных объединяются на основе отношений между ними, а столбец даты был установлен как индекс.

merged_df = pd.merge(Train_df, stores_df, on='store_nbr', how='left')
merged_df = pd.merge(merged_df,Transaction_df, on=['store_nbr','date'], how='left')
merged_df = pd.merge(merged_df,oil_df, on=['date'], how='left')
merged_df = pd.merge(merged_df,Holiday_df, on=['date'], how='left')

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

Вопрос 1. Полный ли набор данных о поездах?

Использование тепловой карты:

Проверка отсутствующих дат:

expected_dates = pd.date_range(start=merged_df['day'].min(), end=merged_df['day'].max())
missing_dates = expected_dates.difference(merged_df['day'])
missing_dates

Вывод:

DatetimeIndex(['2013–12–25', '2014–12–25', '2015–12–25', '2016–12–25'], dtype='datetime64[ns]', freq=None

В результате в наборе данных поезда отсутствуют 4 даты. Эти отсутствующие даты следуют последовательности. Во всех годах отсутствуют даты 25 декабря (12, 25). Эта дата также является праздником в Эквадоре. Таким образом, в этом анализе предполагается, что данные в этот день не собирались каждый год, поскольку магазины могут быть закрыты в этот день каждый год.

Вопрос 2. На какие даты приходится самый низкий и самый высокий объем продаж за каждый год?

Компания зафиксировала самые высокие продажи в 2016 году, затем в 2015 и 2014 годах. Самые низкие продажи были зарегистрированы в 2013 году, а затем в 2017 году. Однако данные за 2017 год были собраны только за 8 месяцев (2017/08/15), что может объяснить рейтинг. Поэтому мы ориентируемся на самые высокие (2016 г.) и самые низкие (2013 г.)

Вопрос 3. Повлияло ли землетрясение в апреле 2016 года на продажи?

Вопрос 4. Продают ли определенные группы магазинов больше товаров? (кластер, город, штат, тип)?

Магазин № 43 имеет самые высокие продажи

Семейство продуктов Бакалея I имело наибольшие продажи

Самые высокие продажи были сделаны в городе Кито

В штате Пичинча самое большое количество продаж.

Магазин типа А зафиксировал наибольшее количество продаж.

Вопрос 5. Влияют ли на продажи рекламные акции, цены на нефть и праздники?

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

Найдите ту золотую середину с точки зрения количества продуктов, которые могут максимизировать продажи. Как видно ниже, наличие около 250 товаров в продаже может оптимизировать и улучшить средние продажи.

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

Импорт библиотек:

from sklearn import preprocessing
from sklearn.ensemble import RandomForestClassifier,RandomForestRegressor,GradientBoostingRegressor
from sklearn.tree import DecisionTreeRegressor
from sklearn.metrics import mean_squared_error,mean_absolute_error,mean_squared_log_error

Использование модели линейной регрессии

# Import the linear regression model
from sklearn.linear_model import LinearRegression

# Initialize the linear regression model
reg = LinearRegression()

# Fit the linear regression model to the training data
reg.fit(X_train, y_train)

# Predict on the validation test data
y_pred_lg = reg.predict(X_validation_test)

# Calculate the RMSLE
rmsle_lg = np.sqrt(mean_squared_log_error(y_validation_test, y_pred))
#print("RMSLE: ", rmsle)

print('Mean Absolute Error for LinearRegression:', mean_absolute_error(y_validation_test, y_pred_lg))
print('Mean Squared Log Error for LinearRegression:', mean_squared_log_error(y_validation_test, y_pred_lg))
print('Mean Squared Error for LinearRegression:', mean_squared_error(y_validation_test, y_pred_lg))
print('Root Mean Squared Error for LinearRegression:', np.sqrt(mean_squared_error(y_validation_test, y_pred_lg)))
print('Root Mean Squared Log Error for LinearRegression:', np.sqrt(mean_squared_log_error(y_validation_test, y_pred_lg)))

Этот код подгоняет модель линейной регрессии из класса LinearRegression scikit-learn к обучающим данным, а затем использует подобранную модель для прогнозирования данных проверочного теста.

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

Эти показатели оценки рассчитываются с использованием функций mean_absolute_error, mean_squared_error, mean_squared_log_error и np.sqrt из модуля metrics scikit-learn.

Выход:

Mean Absolute Error for LinearRegression: 0.5478638617146765
Mean Squared Log Error for LinearRegression: 0.11376193571249157
Mean Squared Error for LinearRegression: 0.4442382787974733
Root Mean Squared Error for LinearRegression: 0.6665120244957875
Root Mean Squared Log Error for LinearRegression: 0.33728613329410917

Использование регрессионной модели случайного леса

#RandomForestClassifier()
#from sklearn.ensemble import RandomForestClassifier,RandomForestRegressor,GradientBoostingRegressor
rfm =RandomForestRegressor(n_estimators=100,max_depth=6,n_jobs=3, random_state=10)
rfm.fit(X_train, y_train)

# RandomForestRegressor Prediction
y_pred_Rf= rfm.predict(X_validation_test)

# Calculate the RMSLE
rmsle_RF = np.sqrt(mean_squared_log_error(y_validation_test, y_pred_Rf))

print('Mean Absolute Error for RandomForestRegressor:', mean_absolute_error(y_validation_test, y_pred_Rf))
print('Mean Squared Log Error for RandomForestRegressor:', mean_squared_log_error(y_validation_test, y_pred_Rf))
print('Mean Squared Error for RandomForestRegressor:', mean_squared_error(y_validation_test, y_pred_Rf))
print('Root Mean Squared Error for RandomForestRegressor:', np.sqrt(mean_squared_error(y_validation_test, y_pred_Rf)))
print('Root Mean Squared Log Error for RandomForestRegressor:', np.sqrt(mean_squared_log_error(y_validation_test, y_pred_Rf)))

Мы обучаем модель регрессии случайного леса из класса RandomForestRegressor scikit-learn на обучающих данных. RandomForestRegressor инициализируется со следующими параметрами:

  • n_estimators: Количество деревьев в лесу. Здесь установлено значение 100.
  • max_depth: Максимальная глубина дерева. Здесь установлено значение 6.
  • n_jobs: Количество параллельных заданий для запуска. Здесь установлено значение 3.
  • random_state: начальное число генератора случайных чисел, используемое при перетасовке данных. Здесь установлено значение 10.

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

Далее код делает прогнозы на основе данных проверочного теста, используя обученную модель регрессии случайного леса. Затем он вычисляет различные показатели оценки, такие как средняя абсолютная ошибка, среднеквадратическая ошибка, среднеквадратическая логарифмическая ошибка, среднеквадратическая ошибка и среднеквадратическая логарифмическая ошибка, чтобы оценить производительность модели на данных проверочного теста. Эти показатели оценки рассчитываются с использованием функций mean_absolute_error, mean_squared_error, mean_squared_log_error и np.sqrt из модуля metrics scikit-learn.

Выход:

Mean Absolute Error for RandomForestRegressor: 0.5181034077206986
Mean Squared Log Error for RandomForestRegressor: 0.0990607743260502
Mean Squared Error for RandomForestRegressor: 0.3962637344533816
Root Mean Squared Error for RandomForestRegressor: 0.6294948248026997
Root Mean Squared Log Error for RandomForestRegressor: 0.31473921637770247