« Неискушенный прогнозист использует статистику, как пьяный человек использует фонарные столбы - для поддержки, а не для освещения . «- После Эндрю Лэнга

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

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

Здесь, в этом контексте, компания - это Walmart. Имени достаточно, чтобы быть услышанным !!!

Обзор проекта:

  • Часть 1: Определение проблемы Kaggle с оценочными метриками.
  • Часть 2: Исследовательский анализ данных (EDA) .
  • Часть 3. Предварительная обработка данных
  • Часть 4: Модели временных рядов.
  • Часть 5. Регрессионные модели машинного обучения.

Часть 1. Определение проблемы Kaggle с оценочными показателями:

Определение проблемы:

  • Walmart предоставил исторические данные о продажах для 45 магазинов Walmart, расположенных в разных регионах. В каждом магазине есть несколько отделов, и задача состоит в том, чтобы спрогнозировать объем продаж в каждом магазине.
  • Кроме того, в течение года Walmart проводит несколько рекламных мероприятий по уценке. Эти скидки предшествуют знаменательным праздникам, четырьмя крупнейшими из которых являются Суперкубок, День труда, День Благодарения и Рождество.
  • Недели, включающие эти праздничные дни, имеют в оценке в пять раз больший вес, чем недели, не являющиеся выходными. Частично проблема, связанная с этим соревнованием, заключается в моделировании эффектов уценки в эти праздничные недели при отсутствии полных / идеальных исторических данных.
  • Kaggle-ссылку на эту проблему можно найти здесь.

Метрика оценки:

  • Walmart предоставил метрику взвешенной средней абсолютной ошибки (WMAE), математическая функция которой показана ниже.

  • Эта метрика производительности отсутствует ни в одной из библиотек sklearn, поэтому задача состоит в том, чтобы написать математический сценарий для этой метрики оценки. Очевидно, что наша цель - максимально снизить этот рейтинг, а также прогнозировать еженедельные продажи. Мы будем использовать этот показатель производительности в регрессионных моделях.

Часть 2: Исследовательский анализ данных (EDA):

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

  • Давайте сначала импортируем набор библиотек.
import numpy as np
import pandas as pd
import scipy.stats as stats
import matplotlib.pyplot as plt
import seaborn as sns
from sklearn.model_selection import train_test_split
from sklearn.metrics import mean_squared_error, mean_absolute_error
from datetime import datetime
import math
# Importing the most popular regression libraries.
from sklearn.linear_model import LinearRegression, 
from sklearn.neighbors import KNeighborsRegressor,
from sklearn.linear_model import Ridge,
from sklearn.linear_model import Lasso,
from sklearn.tree import DecisionTreeRegressor,
from sklearn.ensemble import RandomForestRegressor,
from sklearn.ensemble import ExtraTreesRegressor,
from xgboost import XGBRegressor
  • Затем мы загружаем данные из файлов csv во фрейм данных pandas и проверяем его атрибуты.
#Loading the data from csv files.
train=pd.read_csv('train.csv')
features=pd.read_csv('features.csv')
stores = pd.read_csv('stores.csv')

  • Поскольку нам дали три отдельных файла, мы объединили тезисы и сформировали новый файл данных в виде данных.
data = train.merge(features, on=['Store', 'Date'], how='inner').merge(stores, on=['Store'], how='inner')
print(data.shape)

  • Всего существует 3 типа магазинов: Type A, Type Band Type C.
    Всего 45 магазинов. Более подробную информацию о типе продаж можно увидеть ниже.
sorted_type = stores.groupby('Type')
plt.style.use('ggplot')
labels=['A store','B store','C store']
sizes=sorted_type.describe()['Size'].round(1)
sizes=[(22/(17+6+22))*100,(17/(17+6+22))*100,(6/(17+6+22))*100] # convert to the proportion
fig, axes = plt.subplots(1,1, figsize=(10,10))
wprops={'edgecolor':'black',
      'linewidth':2}
tprops = {'fontsize':30}
axes.pie(sizes,
        labels=labels,
        explode=(0.0,0,0),
        autopct='%1.1f%%',
        pctdistance=0.6,
        labeldistance=1.2,
        wedgeprops=wprops,
        textprops=tprops,
        radius=0.8,
        center=(0.5,0.5))
plt.show()

  • Мы узнали, что у магазинов типа A их медианы выше, чем у любых других медиан в магазинах других типов, поэтому еженедельные продажи в магазинах типа A больше, чем в магазинах других типов.
  • Мы проверяли еженедельные распродажи в праздничные и не праздничные дни.
holiday = train_stores['Weekly_Sales'].loc[train_stores['IsHoliday']== True] # Weekly Sales in Holidays
non_holiday = train_stores['Weekly_Sales'].loc[train_stores['IsHoliday']== False] #Weekly Sales in Non-holidays.
sns.barplot(x='IsHoliday', y='Weekly_Sales', data=train_stores)

  • Мы построили коробчатую диаграмму еженедельных продаж по отделам и праздникам.
data_11= pd.concat([train_stores['Dept'], train_stores['Weekly_Sales'], train_stores['IsHoliday']], axis=1)
plt.figure(figsize=(20,6))
plt.title('Box Plot of Weekly Sales by Department and Holiday')
fig = sns.boxplot(x='Dept', y='Weekly_Sales', data=data_11, showfliers=False, hue="IsHoliday")

  • Визуализация еженедельных продаж по месяцам также выполняется следующим образом.
data_14 = pd.concat([train_stores['Month'], train_stores['Weekly_Sales'], train_stores['IsHoliday']], axis=1)
plt.figure(figsize=(20,6))
plt.title('Box Plot of Weekly Sales by Month and Holiday')
fig = sns.boxplot(x='Month', y='Weekly_Sales', data=data_14, showfliers=False, hue='IsHoliday')

Часть 3. Предварительная обработка данных:

  • Здесь мы сначала проверили наличие каких-либо нулевых значений в объединенных файлах данных и узнали, что в некоторых столбцах присутствуют нулевые значения. Мы заменили нулевые значения нулями.

data=data.fillna(0)
data.isna().sum()

  • Просматривая статистику фрейма данных, мы узнаем, что есть некоторые строки, для которых недельные продажи имеют отрицательные значения. Поскольку значения продаж не могут быть отрицательными, мы пропустили строки с отрицательными недельными продажами.
data = data[data['Weekly_Sales'] >= 0]
  • Мы построили корреляционную матрицу, чтобы увидеть, существует ли какая-либо корреляция между функциями. Мы выполнили этот шаг, потому что нет смысла использовать сильно коррелированные функции, поскольку коррелированные функции будут давать ту же информацию, когда помещены в модель для прогнозирования. Следовательно, лучше идентифицировать те и каскадировать коррелированные. Давайте разберемся с этим подробнее.

Матрица корреляции:

Корреляция - это двухвариантный анализ, который измеряет силу связи между двумя переменными и направление связи. Что касается силы взаимосвязи, значение коэффициента корреляции варьируется от +1 до -1.

Значение ± 1 указывает на идеальную степень связи между двумя переменными. Когда значение коэффициента корреляции приближается к 0, связь между двумя переменными будет слабее. Направление взаимосвязи обозначается знаком коэффициента; Знак + указывает на положительную взаимосвязь, а знак - на отрицательную взаимосвязь. Обычно в статистике мы измеряем четыре типа корреляций: корреляцию Пирсона, ранговую корреляцию Кендалла и корреляцию Спирмена. График ниже даст вам представление о корреляции.

Часть 4. Модели временных рядов:

  • Поскольку файл данных содержит поле даты, данный набор данных представляет собой набор данных временного ряда, в котором в соответствии с каждой датой указаны еженедельные продажи по магазинам и отделам.
  • Поэтому мы будем применять некоторые из популярных моделей прогнозирования временных рядов, а именно:
    1. Модель Auto ARIMA
    2. Модель Холта-Винтерса

1. Авто ARIMA (авторегрессивная интегрированная скользящая средняя):

ARIMA расшифровывается как модель авторегрессионного интегрированного скользящего среднего.

Одномерный (одномерный) ARIMA - это метод прогнозирования, который проецирует будущие значения ряда, полностью основываясь на его собственной инерции.

  • Шаги, необходимые для создания модели Auto ARIMA, приведены ниже.
    → Загрузите данные.
    → Своевременно визуализируйте доступные одномерные данные.
    → Посмотрите на параметр сезонной декомпозиции, чтобы проверить сезонность, имеется или нет тренд и т. д.
    → Выполните тест на стационарность, используя один из методов стационарности временных рядов.
    → Если временной ряд нестационарен, сделайте его стационарным.
    → Если временной ряд является стационарным, то нет необходимости делать его стационарным.
    → Разделите одномерные данные на тренировку и тест.
    → Самый важный шаг - найти подходящие значения триплета p, d, q , где p - количество авторегрессоров, d - интеграция или разность, а q - количество скользящих средних, построенных на графиках ACF и PACF.
    → После получения значений p, d, q подгоните модель ARIMA к данным поезда .
    → Прогноз значений тестовых данных и построение визуализации значений обучающих, тестовых и прогнозируемых тестовых данных на едином графике.
    → Вычислить корень m квадратичная ошибка (RMSE) для предсказанных значений.

Обратите внимание, что модели ARIMA или Holt-Winters учитывают одномерные данные. Следовательно, мы использовали столбец Weekly_Sales для анализа, так как нам нужно спрогнозировать его значения в ближайшем будущем. Ниже приводится общее представление о том, как обстоят дела с еженедельными продажами до сих пор.

data.Date = pd.to_datetime(data.Date,format='%Y-%m-%d')
data.index = data.Date
data = data.drop('Date', axis=1)
data = data.resample('MS').mean() # Resmapling the time series data with month starting first.
# Train-Test splitting of time series data
train_data = data[:int(0.7*(len(data)))]
test_data = data[int(0.7*(len(data))):]
# ARIMA takes univariate data.
train_data = train_data['Weekly_Sales']
test_data = test_data['Weekly_Sales']
# Plot of Weekly_Sales with respect to years in train and test.
train_data.plot(figsize=(20,8), title= 'Weekly_Sales', fontsize=14)
test_data.plot(figsize=(20,8), title= 'Weekly_Sales', fontsize=14)
plt.show()

  • Модели временных рядов предполагают, что данный набор данных временных рядов в стационарном смысле имеет постоянное среднее значение и постоянную дисперсию. Если набор данных нестационарный, мы не применяем модели временных рядов к набору данных как есть. Сначала мы делаем ряд стационарным, используя любой из методов стационарности, а затем применяем к нему модель временных рядов.
    Мы выполнили тест Дики Фуллера, чтобы проверить, является ли ряд стационарным или нет. Ниже представлена ​​его реализация.

Тест Дики Фуллера на стационарность:
Дики-Фуллер проверяет нулевую гипотезу о том, что единичный корень присутствует в данных временных рядов. Чтобы прояснить ситуацию, этот тест проверяет стационарность или нестационарность данных. Тест пытается отвергнуть нулевую гипотезу о существовании единичного корня и о нестационарности данных. Если нулевая гипотеза отклоняется, тогда альтернативная может считаться действительной (например, данные являются стационарными).
Когда мы запустим тест, мы получим значение ADF и p-значение. Число ADF должно быть отрицательным числом, а значение p должно быть ниже определенного порогового значения (например, 1% или 5% и т. Д.) Для уровня достоверности. Здесь мы будем использовать 5% (или 95% уровень достоверности), поэтому, если значение p больше 0,05, мы говорим, что не можем отклонить нулевую гипотезу, потому что данные имеют единичный корень и нестационарны. Если p-значение меньше или равно 0,05, мы можем сказать, что отвергаем нулевую гипотезу, потому что данные не имеют единичного корня и являются стационарными.

from statsmodels.tsa.stattools import adfuller
result = adfuller(data['Weekly_Sales'])
print('ADF Statistic: {}'.format(result[0]))
print('p-value: {}'.format(result[1]))
print('Critical Values:')
for key, value in result[4].items():
    print('\t{}: {}'.format(key, value))

  • Как мы видим, наше p-значение определенно меньше 0,5 и даже меньше 0,01, поэтому мы можем с довольно большой уверенностью сказать, что можем отклонить нуль (единичный корень, нестационарные данные) и можем предположить, что наши данные являются стационарными. . Кроме того, наш ADF намного меньше нашего 1% -ного значения достоверности -3,43, поэтому у нас есть еще одно подтверждение того, что мы можем отклонить нулевую гипотезу.
  • Теперь мы можем перейти к применению модели ARIMA, поскольку набор данных является стационарным.
  • Проверяли вручную, применяя модель ARIMA. Он работает очень хорошо, однако в нем были некоторые незначительные ограничения. Чтобы применить ARIMA, нам необходимо вычислить значение триплета, то есть (p, d, q). Значение p - это количество автоматических регрессоров, значение d - количество разностей, необходимых для стабилизации ряда, а q - количество скользящих средних. Для вычисления значений p, d, q нам необходимо построить графики автокоррелированной функции (ACF) и частичной автокоррелированной функции (PACF).
  • Чтобы избежать этого, мы использовали Auto-ARIMA вместо ARIMA, потому что в модели ARIMA мы должны найти подходящие значения числа авторегрессора (p), числа скользящего среднего (q) и интегрированного (разница, d), что утомительно и кропотливый. В Auto-ARIMA мы можем видеть значения тройки (p, q, d) автоматически на основе наименьших оценок AIC и BIC, которые, что более важно, лучше всего соответствуют модели.
  • Здесь следует отметить, что Auto ARIMA не присутствует в модели статистики, а фактически присутствует в пирамиде. Итак, мы установили пирамиду, а затем импортировали библиотеку auto arima. Ниже представлена ​​реализация Auto ARIMA для набора данных Walmart (Еженедельные продажи).
  • Здесь мы указываем диапазон триплета (p, q, d) от 0 до 10 каждый. Вы можете представить это как выполнение трех циклов for, начиная с p, затем q и, наконец, и вычисляя оценки AIC и BIC.
pip install pyramid-arima
# Applying auto_arima model on train data.
from pyramid.arima import auto_arima
model_auto_arima = auto_arima(train_data, trace=True, error_action='ignore', suppress_warnings=True)
model_auto_arima = auto_arima(train_data, trace=True,start_p=0, start_q=0, start_P=0, start_Q=0, max_p=10, max_q=10, max_P=10, max_Q=10, seasonal=True,stepwise=False, suppress_warnings=True, D=1, max_D=10,error_action='ignore',approximation = False)
model_auto_arima.fit(train_data)

  • Результат, который мы получили после применения Auto ARIMA, показан ниже. Модель автоматически выбрала значения p, d, q с наименьшими показателями AIC и BIC. Здесь в нашем случае мы получили p = 0, q = 0 и d = 2.

  • Здесь нам не нужно знать значения p, d, q. После того, как мы получим наиболее подходящую модель, мы продолжим и спрогнозируем тестовые значения и построим на одном графике поезда, тестовые и прогнозируемые значения, после чего мы найдем значения MSE, RMSE и MAD.
# Predicting the test values using predict function.
forecast = model_auto_arima.predict(n_periods=len(test_data))
forecast = pd.DataFrame(forecast,index = test_data.index,columns=['Prediction'])
plt.figure(figsize=(20,6))
plt.title('Prediction of Weekly Sales using Auto ARIMA model', fontsize=20)
plt.plot(train_data, label='Train')
plt.plot(test_data, label='Test')
plt.plot(forecast, label='Prediction using ARIMA Model')
plt.legend(loc='best')
plt.xlabel('Date', fontsize=14)
plt.ylabel('Weekly Sales', fontsize=14)
plt.show()

  • Ниже приведены показатели производительности для Auto ARIMA.
# Performance metric for ARIMA model -MSE/RMSE
print('Mean Squared Error (MSE) of ARIMA: ', mean_squared_error(test_data, forecast))
print('Root Mean Squared Error (RMSE) of ARIMA: ', math.sqrt(mean_squared_error(test_data, forecast)))
print('Mean Absolute Deviation (MAD) of ARIMA: ', mean_absolute_error(test_data, forecast))

2. Метод Холта-Винтерса:

Holt-Winters - это модель временных рядов, которая позволяет смоделировать три аспекта временных рядов: типичное значение (среднее), наклон (тренд) во времени и циклический повторяющийся образец (сезонность).

Холт-Винтерс использует экспоненциальное сглаживание, чтобы кодировать множество значений из прошлого и использовать их для прогнозирования «типичных» значений для настоящего и будущего.

  • Ниже приведены шаги, необходимые для выполнения метода Холта-Винтерса.
    → Загрузить данные.
    → Своевременно визуализировать доступные одномерные данные.
    → Подобрать модель с помощью метода Холта-Винтерса на поезде данные.
    → Предсказать значения с использованием тестовых данных.
    → Визуализировать данные обучения, тестовые данные и прогнозируемые данные на одном графике
    → Вычислить среднеквадратичную ошибку (RMSE) на основе прогнозируемых данных.

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

Это также называется алгоритмом тройного экспоненциального сглаживания, поскольку он экспоненциально сглаживает уровень, тренд и сезонность. Ниже представлена ​​реализация метода Холта-Винтерса.

  • Поскольку данные уже организованы в формате временных рядов, здесь нам просто нужно применить метод Холта-Винтерса. Ниже представлена ​​его реализация.
# Fitting the Holt-Winters method for Weekly Sales.
from statsmodels.tsa.api import ExponentialSmoothing
model_holt_winters = ExponentialSmoothing(train_data, seasonal_periods=7, trend='additive', seasonal='additive').fit() 
pred = model_holt_winters.forecast(len(test_data))# Predict the test data
#Visualize train, test and predicted data.
plt.figure(figsize=(20,6))
plt.title('Prediction of Weekly Sales using Holt-Winters model', fontsize=20)
plt.plot(train_data, label='Train')
plt.plot(test_data, label='Test')
plt.plot(pred, label='Prediction using Holt Winters Methods')
plt.legend(loc='best')
plt.xlabel('Date', fontsize=14)
plt.ylabel('Weekly Sales', fontsize=14)
plt.show()

Мы видим, что этот метод вполне правильно подошел к тестовым значениям. Ниже приведены показатели производительности для метода Холта-Винтерса.

print('Mean Squared Error (MSE) of Holt-Winters: ', mean_squared_error(test_data, pred))
print('Root Mean Squared Error (RMSE) of Holt-Winters: ', math.sqrt(mean_squared_error(test_data, pred)))
print('Mean Absolute Deviation (MAD) of Holt-Winters: ', mean_absolute_error(test_data, pred))

Часть 5. Модели регрессии машинного обучения.

  • До сих пор мы обсуждали прогнозирование недельных продаж с использованием методов временных рядов. Теперь мы перейдем к обычным алгоритмам регрессии для прогнозирования значений продаж.
  • Здесь мы будем использовать нижеприведенные модели регрессии для прогнозирования продаж на неделю.

1. Линейная регрессия

2. K Регрессия ближайших соседей

3. Регрессия гребня

4. Регрессия лассо

5. Регрессия дерева решений

6. Регрессия случайного леса

7. Регрессия ExtraTrees

8. Регрессия XGBoost

В каждой модели будут выполнены следующие шаги.

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

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

train_data = [train]
# Converting Categorical Variable 'Type' into Numerical Variables.
type_mapping = {"A": 1, "B": 2, "C": 3}
for dataset in train_data:
    dataset['Type'] = dataset['Type'].map(type_mapping)
# Converting Categorical Variable 'IsHoliday' into Numerical Variables.
type_mapping = {False: 0, True: 1}
for dataset in train_data:
    dataset['IsHoliday'] = dataset['IsHoliday'].map(type_mapping)
  • Чтобы усложнить прогноз, Walmart добавил новый набор праздников, а именно Суперкубок, День Благодарения, День труда и Рождество. Конкурс требует знать влияние этих праздников на параметр еженедельных продаж. Поэтому мы добавили эти функции в существующий IsHoliday и пометили их как 0 и 1 соответственно.
train['Super_Bowl'] = np.where(
(train['Date']==datetime(2010,2,10))|
(train['Date'] == datetime(2011,2,11))| 
(train['Date'] == datetime(2012,2,10))|
(train['Date'] == datetime(2013,2,8)), 1, 0)
train['Labor_day'] = np.where(
(train['Date'] == datetime(2010,9,10))|
(train['Date'] == datetime(2011,9,9))| 
(train['Date'] == datetime(2012,9,7))|
(train['Date'] == datetime(2013,9,6)), 1, 0)
train['Thanksgiving'] = np.where(
(train['Date']==datetime(2010, 11, 26)) | (train['Date']==datetime(2011, 11, 25)) | 
(train['Date']==datetime(2012, 11, 23)) | (train['Date']==datetime(2013, 11, 29)),1,0)
train['Christmas'] = np.where(
(train['Date']==datetime(2010, 12, 31))| (train['Date']==datetime(2011, 12, 30))| 
(train['Date']==datetime(2012, 12, 28))| (train['Date']==datetime(2013, 12, 27)),1,0)
  • Затем мы разделяем набор данных на тренировку, перекрестную проверку и тестирование, как показано ниже. Поскольку мы расположили даты в порядке возрастания, мы разделили данные в соотношении 70:30 каждый для train: test и train: cv.
train = train.sort_values(by='Date', ascending=True) # Sorting the data in increasing order of Date and then splitting.
y = train['Weekly_Sales']
X = train.drop(['Weekly_Sales'], axis=1)
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.3) # Train:Test = 70:30 splitting.
X_train, X_cv, y_train, y_cv = train_test_split(X_train, y_train, test_size=0.3) #Train:CV = 70:30 splitting.
  • Но прежде чем приступить к применению каких-либо регрессионных моделей, мы определили наиболее важную метрику, то есть средневзвешенную абсолютную ошибку. Обратите внимание на формулу, показанную ранее. Мы вычислили WMAE, используя приведенную ниже логику. Мы рассчитали потери WMAE для каждого из данных поезда, данных резюме и данных испытаний отдельно.
def wmae_train(test, pred): 
  weights = X_train['IsHoliday'].apply(lambda is_holiday:5 if   is_holiday else 1)
  error = np.sum(weights * np.abs(test - pred), axis=0) / np.sum(weights)
  return error
def wmae_cv(test, pred): # WMAE for CV
  weights = X_cv['IsHoliday'].apply(lambda is_holiday:5 if is_holiday else 1)
  error = np.sum(weights * np.abs(test - pred), axis=0) / np.sum(weights)
  return error
def wmae_test(test, pred): # WMAE for test
  weights = X_test['IsHoliday'].apply(lambda is_holiday:5 if is_holiday else 1)
  error = np.sum(weights * np.abs(test - pred), axis=0) / np.sum(weights)
  return error
  • Теперь мы применили упомянутые регрессионные модели и рассчитали оценку WMAE для каждой из них. Пора использовать стандартные алгоритмы машинного обучения…!
  • Мы показали лучшую модель, по которой получили лучший результат WMAE. Мы не использовали технику оптимизации GridSearch / RandomSearch, потому что функция потерь, предоставленная Kaggle, не попадает в библиотеку skleran (например, MSE, Accuracy, F1 score и т. Д.). Вместо этого мы выполнили простой цикл «for», чтобы получить наилучшие гиперпараметры для соответствующих моделей.
  • Процедура, применяемая здесь в лучшей модели, применяется ко всем другим методам регрессии.

Шаг 1. Примените регрессию случайного леса для настройки гиперпараметров (max_depth и n_estimators).

# Define the list of errors and list of hyper parameters.
error_cv_rf = []
error_train_rf = []
max_depth = [1,5,10,15,20,25,30,35]
n_estimators = [10,20,30,40,50,60,70,80]
rf_hyperparams = []
"""Calculating train and CV errors for maximum depth and number of estimators parameters."""
for i in max_depth: 
    for j in n_estimators: 
        rf = RandomForestRegressor(max_depth=i, n_estimators=j) 
        rf.fit(X_train, y_train) 
        y_pred_cv_rf = rf.predict(X_cv) 
        y_pred_train_rf = rf.predict(X_train) 
        error_cv_rf.append(wmae_cv(y_cv, y_pred_cv_rf)) 
        error_train_rf.append(wmae_train(y_train, y_pred_train_rf)) 
        rf_hyperparams.append({'Maximum Depth':i, 'No. of Estimators':j}) 

Шаг 2. Получите таблицу ошибок обучения и перекрестной проверки. Эта таблица сформирована, потому что нам нужно, чтобы эта таблица была предоставлена ​​во время создания тепловой карты.

rf_dataframe = pd.DataFrame(rf_hyperparams)
rf_dataframe['Train Error']=error_train_rf
rf_dataframe['CV Error']=error_cv_rf
rf_dataframe.sort_values(by=['CV Error'], ascending=True)
rf_dataframe.head()

Шаг 3. Создайте тепловую карту и определите соответствующие значения гиперпараметров.

sns.set(font_scale=1.0)
train_rf = pd.pivot_table(rf_dataframe,'Train Error','Maximum Depth','No. of Estimators') # Pivot table of Train data.
cv_rf = pd.pivot_table(rf_dataframe, 'CV Error','Maximum Depth','No. of Estimators') # Pivot table of CV data.
fig, ax = plt.subplots(1,2, figsize=(20,6))
ax_train = sns.heatmap(train_rf, annot=True, fmt='2g', ax=ax[0], linewidths=0.01)
ax_cv = sns.heatmap(cv_rf, annot=True, fmt='4g', ax=ax[1], linewidths=0.01)
bottom_train, top_train = ax_train.get_ylim()
ax_train.set_ylim(bottom_train + 0.5, top_train - 0.5)
bottom_cv, top_cv = ax_cv.get_ylim()
ax_cv.set_ylim(bottom_cv + 0.5, top_cv - 0.5)
ax[0].set_title('Training set')
ax[1].set_title('CV set')
plt.show()

Шаг 4. Прогнозируйте данные теста и рассчитайте оценку WMAE.

model_rf = RandomForestRegressor(max_depth= 35, n_estimators=80).fit(X_train, y_train) # Fit the model with best hyper parameter values.
y_pred = model_rf.predict(X_test) # Predict the test data.
print('Weighted Mean Absolute Error (WMAE) for Random Forest Regression:', wmae_test(y_test, y_pred)) # Get WMAE score.

  • Аналогичным образом мы рассчитали средневзвешенную абсолютную ошибку (WMAE) для остальных моделей и свели в таблицу оценки WMAE для каждой модели. Ниже приводится краткое описание эффективности каждой регрессионной модели.
models = pd.DataFrame({
'Model Name': 
['Linear Regression','KNN Regression','Ridge Regression','Lasso Regression','Decision Tree Regression','Random Forest Regression','ExtraTrees Regression','XGBoost Regession'],
    
'WMAE Score': 
['14904.66', '11887.99', '14824.52', '14810.89', '2134.17', '1785.20', '1986.29', '2765.22']
 })
Index = pd.Series([1, 2, 3, 4, 5, 6, 7, 8])
models.set_index(Index, inplace=True)
models

  • Мы заметили, что оценка WMAE меньше всего встречается для модели регрессии случайного леса, то есть 1785,20, поэтому лучше всего использовать регрессионную модель случайного леса. Мы используем эту модель для расчета еженедельных продаж на будущие даты, указанные в тестовом файле (test.csv). Еженедельные продажи прогнозируются ниже.

Результат (файл отправки):

  • Мы проделали ту же предварительную обработку для test.csv, что и для файла с объединенными данными поезда. Наконец, мы применили регрессию случайного леса с лучшими гиперпараметрами на test.csv. Здесь test_kaggle - это не что иное, как файл test.csv.
model_rf = RandomForestRegressor(max_deth= 35, n_estimators=80).fit(train) 
y_pred = model_rf.predict(test_kaggle) 
  • Наконец, CSV-файл с прогнозом продаж на неделю создается с использованием формата, предоставленного Kaggle в файле sampleSubmission.csv. Ниже представлена ​​его реализация.
submission = pd.DataFrame({
"Id": 
test_kaggle.Store.astype(str)+'_'+
test_kaggle.Dept.astype(str)+'_'+
test_kaggle.Date.astype(str), 
"Weekly_Sales": y_pred 
 })
submission.to_csv('Weekly Sales Prediction.csv', index=False) # Final submission.

  • Это полная история этого конкурса Kaggle, в котором были изучены и применены вещи.
  • К счастью, при загрузке файла прогнозируемых продаж в Kaggle он получил оценку WMAE 3202,24 с рейтингом 160 !!

GitHub ссылка на проект. Пожалуйста, проверьте мой профиль в LinkedIn.

Сфера машинного обучения - это изучение неизвестных вещей и экспериментирование с ними, применяя .. !!!

Если хотите, пожалуйста, оставьте несколько комментариев и предложений ниже. В конце концов, я надеюсь, что, прочитав эту статью, вы, возможно, узнали концепции, о которых не знали: D

Спасибо, что прочитали статью… !!