酒店数据集退订分析与预测
主要内容:
本文将主要从以下几个方面分析:1、背景 2、提出问题 3、理解数据 4、数据清洗 5、可视化分析 6、退订率预测 7、结论和建议
1、背景
酒店集数据中包括了两家酒店(城市&度假)在20150701-20170831期间的预订数据,主要包括预订时间,停留时间,成人/儿童/婴儿的数量以及餐食类型和可用停车位数量等信息‘
退订率高会对酒店造成损失,本文主要根据数据集内容,分析各类数据对退订率的影响并进行预测,从数据分析的结论给出相关建议
2、提出问题
(1)分析两家酒店总体退订率情况;
(2)从整体情况看,退订的用户普遍具有哪些特征;
(3)尝试找到合适的模型预测退订用户;
(4)针对性给出预防用户取消预订的建议;
3、理解数据
根据介绍,该数据集有32个字段,共119390条数据,每条记录包含了每个订单的基本信息,我们的目的就是发现其他特征和is_canceled之间的关系
3.1数据清洗
- 数据观察
导入数据集文件
import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
plt.rcParams['font.sans-serif'] = [u'SimHei']
plt.rcParams['axes.unicode_minus'] = False
from datetime import datetime
data_path=r'hotel_bookings.csv'
data=pd.read_csv(data_path)
查看数据集信息,查看数据集大小,并初步观察前10条的数据内容。
#数据清洗
#查看数据集大小
# 查看数据集大小
data.shape
# 运行结果:(119390, 32)
# 设置查看列不省略
pd.set_option('display.max_columns',None)
# 查看前10条数据
data.head(10)
- 缺失值处理
查看数据是否存在Null,
# Null计数
data.isnull().sum().sort_values(ascending=False)
out:
company 112593
agent 16340
country 488
children 4
lead_time 0
arrival_date_year 0
arrival_date_month 0
arrival_date_week_number 0
is_canceled 0
market_segment 0
arrival_date_day_of_month 0
stays_in_weekend_nights 0
stays_in_week_nights 0
adults 0
babies 0
meal 0
reservation_status_date 0
distribution_channel 0
reservation_status 0
is_repeated_guest 0
previous_cancellations 0
previous_bookings_not_canceled 0
reserved_room_type 0
assigned_room_type 0
booking_changes 0
deposit_type 0
days_in_waiting_list 0
customer_type 0
adr 0
required_car_parking_spaces 0
total_of_special_requests 0
hotel 0
dtype: int64
children,country,agent,company均有空值
children 为空值推测为无children,使用0填充
country 列使用众数填充
agent 无旅行社id标识,推测为个人客户,使用0填充
company 列缺失值较多,且对结果分析产生影响不大,进行删除
#缺失值处理
df = data.copy()
df.drop(['company'],axis=1,inplace=True)
df['children'].fillna(0,inplace=True)
df['agent'].fillna(0,inplace=True)
df['country'].fillna(value=df['country'].mode()[0],inplace=True)
- 验证数据合法性,去除异常值
# 查看每一列数据取值
for x in data.columns: #遍历数据集中所有的列
test=data.loc[:,x].value_counts()
print('{0} 的行数是:{1}'.format(x,test.sum()))
print('{0} 的数据类型是:{1}'.format(x,data[x].dtypes))
print('{0} 的内容是:\n{1}\n'.format(x,test))
df.describe()
从以上代码输出的数据,可以做出如下处理:
(1)删除总人数和总入住天数为0的异常数据
(2)删除预订总天数为0的异常数据(即’stays_in_weekend_nights’+‘stays_in_week_nights’)
#删除总人数和总入住天数为0的异常数据
df.reset_index()
zero_people=df[df[['adults', 'children', 'babies']].sum(axis=1)==0]
df.drop(zero_people.index,inplace=True)
zero_date=df[df[['stays_in_weekend_nights','stays_in_week_nights']].sum(axis=1)==0]
df.drop(zero_date.index,inplace=True)
- 数据去重
保证数据唯一性,因为酒店类数据可能会出现不同数据库导出重复数据的现象,这里数据由30+列数据组成,完全相同的概率较小,故而针对完全相同的列进行去重
df.drop_duplicates(inplace=True)
df.info()
out:
<class 'pandas.core.frame.DataFrame'>
Int64Index: 86719 entries, 2 to 119389
Data columns (total 31 columns):
# Column Non-Null Count Dtype
--- ------ -------------- -----
0 hotel 86719 non-null object
1 is_canceled 86719 non-null int64
2 lead_time 86719 non-null int64
3 arrival_date_year 86719 non-null int64
4 arrival_date_month 86719 non-null object
5 arrival_date_week_number 86719 non-null int64
6 arrival_date_day_of_month 86719 non-null int64
7 stays_in_weekend_nights 86719 non-null int64
8 stays_in_week_nights 86719 non-null int64
9 adults 86719 non-null int64
10 children 86719 non-null float64
11 babies 86719 non-null int64
12 meal 86719 non-null object
13 country 86719 non-null object
14 market_segment 86719 non-null object
15 distribution_channel 86719 non-null object
16 is_repeated_guest 86719 non-null int64
17 previous_cancellations 86719 non-null int64
18 previous_bookings_not_canceled 86719 non-null int64
19 reserved_room_type 86719 non-null object
20 assigned_room_type 86719 non-null object
21 booking_changes 86719 non-null int64
22 deposit_type 86719 non-null object
23 agent 86719 non-null float64
24 days_in_waiting_list 86719 non-null int64
25 customer_type 86719 non-null object
26 adr 86719 non-null float64
27 required_car_parking_spaces 86719 non-null int64
28 total_of_special_requests 86719 non-null int64
29 reservation_status 86719 non-null object
30 reservation_status_date 86719 non-null object
dtypes: float64(3), int64(16), object(12)
还剩下86719行数据,所有字段的数据类型均符合实际含义,数据清洗工作完成
4、可视化分析
4.1 两家酒店总体退订率情况
- 整体取消预订比例
#整体取消预订比例
df['is_canceled']=df['is_canceled'].astype('str').replace(['0','1'],['no','yes'])
plt.rcParams['figure.figsize']=6,6
plt.pie(df['is_canceled'].value_counts(),labels=df['is_canceled'].value_counts().index,autopct='%1.2f%%',explode=(0.1,0)) #每一块饼图距离中心的距离,默认值(0,0)就是不离开中心,explode = (0,0,0.1,0) 表示将第三块分离出来,而这里就表示将第一块分离出来
plt.title('is_canceled(Yes/No) Ratio')
plt.show()
不分酒店类型情况下,整体取消比例为27.69%,接下来我们比较看下城市和度假酒店两者退订率是否有明显差异
#city类型酒店取消预订比例
fig= p