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

Зачем тогда нам нужно использовать прогностические модели?

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

Поэтому в этом следующем блоге мы углубимся в тему и сравним четыре популярных алгоритма: логистическая регрессия, дерево решений, случайный лес и XGBoost. Наш анализ показывает, что Random Forest является наиболее эффективной моделью с точки зрения точности прогнозирования отмен отелей. Итак, давайте подробно рассмотрим эти алгоритмы и их производительность.

Чтобы помочь нам понять, давайте сначала рассмотрим несколько определений:

Логистическая регрессия

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

Дерево решений

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

Случайный лес

Случайный лес — это ансамблевый алгоритм обучения, который объединяет несколько деревьев решений для прогнозирования. Он решает проблему переобучения деревьев решений путем создания разнообразного набора деревьев за счет комбинации случайного выбора функций и агрегирования начальной загрузки (бэггинга). Случайный лес повышает точность прогнозов и уменьшает дисперсию за счет усреднения прогнозов отдельных деревьев. Он известен своей надежностью и способностью обрабатывать многомерные данные.

XGBoost

XGBoost (Extreme Gradient Boosting) — еще один популярный алгоритм обучения ансамбля, который превосходно справляется с задачами прогнозирования. Это оптимизированная реализация алгоритма Gradient Boosting, который последовательно объединяет слабых учеников, чтобы сформировать сильного ученика. XGBoost использует алгоритм градиентного спуска, чтобы минимизировать функцию потерь и повысить эффективность прогнозирования. Он предлагает лучшую скорость и эффективность по сравнению с традиционными алгоритмами Gradient Boosting.

Сравнительный анализ

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

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

Прогнозное моделирование набора данных бронирования отелей

Вы можете получить доступ к набору данных здесь… https://www.kaggle.com/datasets/ahsan81/hotel-reservations-classification-dataset

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

Сначала нужно загрузить набор данных, а затем импортировать все необходимые библиотеки.

df = pd.read_csv("/kaggle/input/hotel-reservations-classification-dataset/Hotel Reservations.csv")
from sklearn.datasets import make_classification
from matplotlib import pyplot as plt
from sklearn.linear_model import LogisticRegression
from sklearn.model_selection import train_test_split
from sklearn.metrics import confusion_matrix
import pandas as pd
import seaborn as sns
from sklearn.impute import SimpleImputer
from sklearn.pipeline import Pipeline
from sklearn.preprocessing import OrdinalEncoder,OneHotEncoder,LabelEncoder
from sklearn.compose import ColumnTransformer
from sklearn.ensemble import RandomForestClassifier
from sklearn.tree import DecisionTreeClassifier
from sklearn.model_selection import cross_val_score
from sklearn.model_selection import GridSearchCV
import xgboost as xgb
from pandas import DataFrame
import numpy as np

С нашей категориальной меткой необходим кодировщик меток.

df = df.rename(columns={'booking_status': 'is_canceled'})
df['is_canceled'].replace('Canceled', '1',inplace=True)
df['is_canceled'].replace('Not_Canceled', '0',inplace=True

Мы должны изменить тип данных закодированной переменной со строки на целое число:

df['is_canceled'] = df['is_canceled'].astype(int)
hotel_df=train_set.copy()

Какова корреляция между переменными?

Мы можем проанализировать это, используя график корреляции, подобный этому:

hotel_df_corr=hotel_df.corr()

corr_df= DataFrame(hotel_df_corr['is_canceled'].abs().sort_values(ascending=False))

sns.heatmap(hotel_df_corr)

Выбор функций
Нам нужно будет выбрать числовые и категориальные столбцы для нашей модели.

numeric_cols=['no_of_adults', 'no_of_children', 'no_of_weekend_nights',
       'no_of_week_nights', 'required_car_parking_space', 'lead_time',
       'arrival_year', 'arrival_month', 'arrival_date', 'repeated_guest',
       'no_of_previous_cancellations', 'no_of_previous_bookings_not_canceled',
       'avg_price_per_room', 'no_of_special_requests']

cat_cols=[ 'type_of_meal_plan', 'room_type_reserved',
       'market_segment_type']

Определите целевую переменную

hotel_df_actual=hotel_df[numeric_cols + cat_cols]
hotel_df_y=hotel_df['is_canceled']

Числовой конвейер

Измените значения в категориальных на числовые значения и заполните пропущенные значения как в числовых, так и в категориальных переменных.

num_transformer=SimpleImputer(strategy="constant",fill_value=0)

#num_transformer.fit_transform(hotel_df[numeric_cols])
cat_transformer=Pipeline([('imputer',SimpleImputer(strategy="constant")),('ordinal',OrdinalEncoder())])

#combine the two so we can use it for other data sets

col_trans=ColumnTransformer([("num",num_transformer,numeric_cols),("cat",cat_transformer,cat_cols)])
col_trans

Затем мы разделим данные на разделение «Обучение/Тестирование», а затем используем обучающий набор для обучения модели.

X_train,X_test,y_train,y_test=train_test_split(hotel_df_actual,hotel_df_y,test_size=0.2,random_state=42,stratify=hotel_df_y)

Модель логистической регрессии

model=LogisticRegression(random_state=42,n_jobs=-1)

model_steps=Pipeline([('col_trans',col_trans),('model',model)])

model_steps.fit(X_train,y_train)

y_pred=model_steps.predict(X_test)

model_steps.score(X_test,y_test)
0.7953135768435562

Перекрестная проверка

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

cv_results=cross_val_score(model_steps,X_train,y_train,cv=5,n_jobs=-1,scoring='accuracy')
cv_results
array([0.77971576, 0.80142149, 0.78785268, 0.7964678 , 0.78677579])
cv_results=[x for x in cv_results if str(x) !="nan"]
np.mean(cv_results)
0.7904467061915885

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

clf1=LogisticRegression(penalty='l2',C=0.001,random_state=42)
clf2=DecisionTreeClassifier(criterion='entropy',max_depth=4,random_state=42)
clf3=RandomForestClassifier(n_estimators=100,criterion='entropy',random_state=42)
clf4=xgb.XGBClassifier(n_estimators=100,learning_rate=0.01,max_depth=4,random_state=1,use_label_encoder=False)

models_name=['Logisstic Reg','Decision Tree','RandomForest','XGB']

for clf,name in zip([clf1,clf2,clf3,clf4],models_name):
  model_steps=Pipeline([('col_trans',col_trans),('model',clf)])
  scores=cross_val_score(model_steps,X_train,y_train,cv=4,n_jobs=-1,scoring="accuracy")
  scores=[x for x in scores if str(x) !="nan"]
  print('accuracy:{:.2f},{}'.format(np.mean(scores),name))
accuracy:0.78,Logisstic Reg
accuracy:0.82,Decision Tree
accuracy:0.90,RandomForest
accuracy:0.84,XGB

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

RF=RandomForestClassifier(n_estimators=100,criterion='entropy',random_state=42)

model=Pipeline([('col_trans',col_trans),('model',RF)])

model.fit(X_train,y_train)

model.get_params()
clf3=RandomForestClassifier(n_estimators=100,criterion='entropy',random_state=42)
model=Pipeline([('col_trans',col_trans),('model',clf3)])

param_range=[100,160]
#param_criterion=['gini','entropy']
param_grids=[{'model__n_estimators':param_range,'model__criterion':['entropy']}]
             #{'model__n_estimators':param_range,'model__criterion':['entropy'],'model__min_samples_split':param_min_samples_split}]

gs=GridSearchCV(estimator=model,param_grid=param_grids,scoring='accuracy',cv=10,refit=True,n_jobs=-1)

gs=gs.fit(X_train,y_train)

Оценили базовые гиперпараметры в проверочном наборе, чтобы получить эти показатели.

print(gs.best_score_)

print(gs.best_params_)
0.8981306321601703
{'model__criterion': 'entropy', 'model__n_estimators': 160}
clf3=RandomForestClassifier(n_estimators=160,max_features=0.4,min_samples_split=2,n_jobs=-1,random_state=42)
model_clf=Pipeline([('col_trans',col_trans),('model',clf3)])

cv_result_score=cross_val_score(model_clf,X_train,y_train,cv=5,scoring='accuracy',n_jobs=-1)
cv_result_score=[x for x in cv_result_score if str(x) !="nan"]

np.mean(cv_result_score)
0.8964936055369768

Показать конвейер

model_clf.fit(X_train,y_train)

Определение важности функции

num=model_clf.named_steps['col_trans'].transformers_[0][2]
cat=model_clf.named_steps['col_trans'].transformers_[1][2]
features=num+cat


feat=DataFrame(features)
weight=DataFrame(model_clf.steps[1][1].feature_importances_)
imp_df=pd.concat([feat,weight],axis=1,keys=['Feature','Weight'])
imp_df=imp_df.droplevel(1,axis=1)
imp_df.sort_values("Weight",ascending=False).head(10)

Матрица путаницы

X_valid=test_set[numeric_cols + cat_cols]
y_valid=test_set['is_canceled']


from sklearn.metrics import confusion_matrix
model_clf.fit(X_train,y_train)
ypred=model_clf.predict(X_valid)
confmat=confusion_matrix(y_valid,ypred)
print(confmat)



import seaborn as sns
fig,ax=plt.subplots(figsize=(5.5,5.5))
sns.heatmap(confmat,annot=True)
plt.xlabel('Predicted Label')
plt.ylabel('Actual Label')

[[4579  260]
 [ 443 1973]]

Оценка точности

from sklearn.metrics import auc,accuracy_score

model_clf.fit(X_train,y_train)
ypred=model_clf.predict(X_valid)
accuracy_score(y_valid,ypred)
0.9031013094417643

Заключение

В этом последующем блоге мы сравнили четыре популярных алгоритма машинного обучения — логистическую регрессию, дерево решений, случайный лес и XGBoost — для прогнозирования отмен отелей. Хотя у всех четырех алгоритмов есть свои преимущества, наш анализ показал, что Random Forest оказался наиболее эффективной моделью с точки зрения точности прогнозирования.

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

Спасибо, что дочитали до этого момента! Пожалуйста, поставьте лайк, если это поможет, и подписывайтесь на меня в LinkedIn здесь https://www.linkedin.com/in/lisa-asafo-adjei-377901196/

Этап 1… https://medium.com/@asafoadjeilisa/navigating-the-turbulent-waters-of-hotel-booking-cancellations-the-menace-solution-phase-1-9005c71cba23