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:
commit
bed476a27b
55
kurmyza_pavel_lab_3/README.md
Normal file
55
kurmyza_pavel_lab_3/README.md
Normal 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, так как имеет наивысшую оценку точности. Тем не менее, все из выбранных моделей показали высокие
|
||||
результаты. Из этого следует, что задача классификации для данного набора решена.
|
BIN
kurmyza_pavel_lab_3/confusion_matrix.jpg
Normal file
BIN
kurmyza_pavel_lab_3/confusion_matrix.jpg
Normal file
Binary file not shown.
After Width: | Height: | Size: 26 KiB |
119391
kurmyza_pavel_lab_3/hotel_bookings.csv
Normal file
119391
kurmyza_pavel_lab_3/hotel_bookings.csv
Normal file
File diff suppressed because it is too large
Load Diff
119
kurmyza_pavel_lab_3/main.py
Normal file
119
kurmyza_pavel_lab_3/main.py
Normal 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))
|
Loading…
Reference in New Issue
Block a user