Merge pull request 'kurmyza_pavel_lab_3 is ready' (#81) from kurmyza_pavel_lab_3 into main

Reviewed-on: http://student.git.athene.tech/Alexey/IIS_2023_1/pulls/81
This commit is contained in:
Alexey 2023-10-28 12:28:53 +04:00
commit bed476a27b
4 changed files with 119565 additions and 0 deletions

View File

@ -0,0 +1,55 @@
# Лабораторная работа №3
## ПИбд-41, Курмыза Павел
Датасет по варианту: https://www.kaggle.com/datasets/jessemostipak/hotel-booking-demand.
Данный набор данных содержит информацию о бронировании городской и курортной гостиниц и включает в себя такие
сведения, как время бронирования, продолжительность пребывания, количество взрослых, детей и/или младенцев, количество
свободных парковочных мест и т.д.
## Как запустить ЛР
- Запустить файл main.py
## Используемые технологии
- Язык программирования Python
- Библиотеки: sklearn, numpy, pandas, xgboost, matplotlib, seaborn
## Что делает программа
Программа решает задачу классификации на выбранном датасете: определение гостиничного класса отеля (городской отель или
курортный отель). Решение достигается в несколько этапов:
- Предобработка данных
- Балансировка данных
- Стандартизация данных и приведение их к виду, удобном для работы с моделями ML
- Использование нескольких моделей классификации
- Сравнение оценок и поиск наиболее подходящей модели
- Оценка специфичности наилучшей модели классификации
## Тестирование
Для решения задачи классификации были выбраны 3 модели: XGBClassifier, RandomForestClassifier, DecisionTreeClassifier.
Оценка точности моделей:
- XGBClassifier: 0.970565942395149
- RandomForestClassifier: 0.9901465386558869
- DecisionTreeClassifier: 0.9714502273875695
Оцека способности модели RandomForestClassifier предсказывать истинные положительные результаты (TP / (TP + FN)), также
известные как коэффициент чувствительности, и истинные отрицательные результаты (TN / (TN + FP)), также известный как
коэффициент специфичности через матрицу неточностей:
![Матрица неточностей](confusion_matrix.jpg)
Матрица неточностей подтверждает приведенную ранее оценку модели RandomForestClassifier. Кроме того, она указывает на
то, что помимо высокой точности, модель также имеет высокую специфичность.
## Вывод
По итогу тестирования было выявлено, что наилучше всего с задачей классификации данного набора данных справляется модель
RandomForestClassifier, так как имеет наивысшую оценку точности. Тем не менее, все из выбранных моделей показали высокие
результаты. Из этого следует, что задача классификации для данного набора решена.

Binary file not shown.

After

Width:  |  Height:  |  Size: 26 KiB

File diff suppressed because it is too large Load Diff

119
kurmyza_pavel_lab_3/main.py Normal file
View File

@ -0,0 +1,119 @@
import pandas as pd
from matplotlib import pyplot as plt
from sklearn.tree import DecisionTreeClassifier
from sklearn.ensemble import RandomForestClassifier
from sklearn.preprocessing import LabelEncoder
from sklearn.feature_selection import VarianceThreshold
from sklearn.model_selection import train_test_split
from sklearn.preprocessing import StandardScaler
from xgboost import XGBClassifier
from sklearn.metrics import confusion_matrix, classification_report
import seaborn as sns
# Считываем датасет
ds = pd.read_csv('hotel_bookings.csv')
# Удаляем из датасета строки с пропущенными значениями столбцов country, children.
# Выбраны именно данные столбцы, так как, по информации из kaggle, только они могут содержать пропущеные значения
ds.dropna(axis=0, subset=['country', 'children'], inplace=True)
# Усредняем значения столбца agent, чтобы убрать его влияние на результат, так как столбец содержит неважные данные
moa = ds['agent'].mean()
ds['agent'].fillna(value=moa, axis=0, inplace=True)
# Заполняем пропущенные значения ячеек, чтобы исключить незаполненные
ds.fillna(method='pad', inplace=True)
ds.dropna(inplace=True, subset=['company'])
# Переводим столбцы, содержащие текстовые данные в числовое представление
hotel = LabelEncoder()
meal = LabelEncoder()
country = LabelEncoder()
market_segment = LabelEncoder()
distribution_channel = LabelEncoder()
reserved_room_type = LabelEncoder()
assigned_room_type = LabelEncoder()
deposit_type = LabelEncoder()
customer_type = LabelEncoder()
reservation_status = LabelEncoder()
reservation_status_date = LabelEncoder()
ds['hotel_n'] = hotel.fit_transform(ds['hotel'])
ds['arrival_date_month_n'] = hotel.fit_transform(ds['arrival_date_month'])
ds['meal_n'] = hotel.fit_transform(ds['meal'])
ds['country_n'] = hotel.fit_transform(ds['country'])
ds['market_segment_n'] = hotel.fit_transform(ds['market_segment'])
ds['distribution_channel_n'] = hotel.fit_transform(ds['distribution_channel'])
ds['reserved_room_type_n'] = hotel.fit_transform(ds['reserved_room_type'])
ds['assigned_room_type_n'] = hotel.fit_transform(ds['assigned_room_type'])
ds['deposit_type_n'] = hotel.fit_transform(ds['deposit_type'])
ds['customer_type_n'] = hotel.fit_transform(ds['customer_type'])
ds['reservation_status_n'] = hotel.fit_transform(ds['reservation_status'])
ds['reservation_status_date_n'] = hotel.fit_transform(ds['reservation_status_date'])
# Удаляем приведенные к числовым данным столбцы, они больше не нужны
ds.drop(
['hotel', 'arrival_date_month', 'meal', 'country', 'market_segment', 'distribution_channel', 'reserved_room_type',
'assigned_room_type', 'deposit_type', 'customer_type', 'reservation_status', 'reservation_status_date'], axis=1,
inplace=True)
# Производим балансировку данных таким образом, чтобы было одинаковое количество отелей всех классов
ds_0 = ds[ds['hotel_n'] == 0]
ds_1 = ds[ds['hotel_n'] == 1]
ds_0 = ds_0.sample(ds_1.shape[0])
ds = ds_0._append(ds_1, ignore_index=True)
# Полдготовка данных для выполнения модели
x = ds.drop('hotel_n', axis=1)
y = ds['hotel_n']
threshold = VarianceThreshold()
x_train, x_test, y_train, y_test = train_test_split(x, y, test_size=0.2)
x_train = threshold.fit_transform(x_train)
x_test = threshold.transform(x_test)
# Производим стандартизацию данных и приводим их к виду, с которым работают модели классификации
scaler = StandardScaler()
x_train = scaler.fit_transform(x_train)
x_test = scaler.fit_transform(x_test)
y_train = y_train.to_numpy()
y_test = y_test.to_numpy()
# Использование моделей машинного обучения.
# Для сравнения точности были взяты модели XGBClassifier, RandomForestClassifier, DecisionTreeClassifier.
xg = XGBClassifier()
xg.fit(x_train, y_train)
rf = RandomForestClassifier()
rf.fit(x_train, y_train)
dt = DecisionTreeClassifier()
dt.fit(x_train, y_train)
# Оценка точности моделей классификации
xgb_accuracy = xg.score(x_test, y_test)
rf_accuracy = rf.score(x_test, y_test)
dt_accuracy = dt.score(x_test, y_test)
print(f"Оценка точности моделей:"
f"\n XGBClassifier: {xgb_accuracy}",
f"\n RandomForestClassifier: {rf_accuracy}",
f"\n DecisionTreeClassifier: {dt_accuracy}")
# Оценка коэффициента специфичности через матрицу неточностей
y_pred = rf.predict(x_test)
cm = confusion_matrix(y_test, y_pred)
plt.figure(figsize=(7, 5))
sns.heatmap(cm, annot=True)
plt.xlabel('Prediction')
plt.ylabel('Actual')
plt.show()
print(classification_report(y_test, y_pred))