数据分析:基于随机森林(RFC)对酒店预订分析预测
数据分析:基于随机森林(RFC)对酒店预订分析预测
文章目录
- 数据分析:基于随机森林(RFC)对酒店预订分析预测
- 1、前言
- 2、数据探索
- 3、数据可视化分析
- 3.1酒店预订量和取消量
- 3.2酒店各月份预定量
- 3.3客源地与预订取消率
- 3.4客户类型
- 3.5酒店预订途径
- 3.6各类旅客日均开销
- 3.7新老客数量与取消预订率
- 3.8押金方式与预定取消率
- 3.9房间类型与预定取消量
- 4.数据预处理
- 4.1处理分类型变量
- 4.2处理连续型变量
- 4.3各变量的相关性系数
- 5.建模预测
- 5.1随机森林
- 分析总结
1、前言
数据准备
2、数据探索
1.导入所需模块
import numpy as np # linear algebra
import pandas as pd # data processing, CSV file I/O (e.g. pd.read_csv)
import matplotlib.pyplot as plt
import seaborn as sns
import warnings
warnings.filterwarnings('ignore')
%matplotlib inline
import os
for dirname, _, filenames in os.walk('/home/mw/input/'):for filename in filenames:print(os.path.join(dirname, filename))
2.导入数据
df=pd.read_csv('/home/mw/input/1119442/hotel_bookings.csv')
df.head()
3.查看每列空值占比
df.isnull().mean()
4.查看数据基本信息
df.info()
5.使用describe()函数,计算数据集中每列的总数、均值、标准差、最小值、25%、50%、75%分位数以及最大值并转置。
df.describe([0.01,0.05,0.1,0.25,0.5,0.75,0.99]).T
3、数据可视化分析
3.1酒店预订量和取消量
plt.figure(figsize=(15,8))
sns.countplot(x='hotel',data=df,hue='is_canceled',palette=sns.color_palette('Set2',2))
hotel_cancel=(df.loc[df['is_canceled']==1]['hotel'].value_counts()/df['hotel'].value_counts()).sort_values(ascending=False)
print('酒店取消率'.center(20),hotel_cancel,sep='\n')
City Hotel的预定量与取消量都高于Resort Hotel,但Resort Hotel取消率为27.8%,而City Hotel的取消率达到了41.7%
3.2酒店各月份预定量
city_hotel=df[(df['hotel']=='City Hotel') & (df['is_canceled']==0)]
resort_hotel=df[(df['hotel']=='Resort Hotel') & (df['is_canceled']==0)]
for i in [city_hotel,resort_hotel]:i.index=range(i.shape[0])
city_month=city_hotel['arrival_date_month'].value_counts()
resort_month=resort_hotel['arrival_date_month'].value_counts()
name=resort_month.index
x=list(range(len(city_month.index)))
y=city_month.values
x1=[i+0.3 for i in x]
y1=resort_month.values
width=0.3
plt.figure(figsize=(15,8),dpi=80)
plt.plot(x,y,label='City Hotel',color='lightsalmon')
plt.plot(x1,y1,label='Resort Hotel',color='lightseagreen')
plt.xticks(x,name)
plt.legend()
plt.xlabel('Month')
plt.ylabel('Count')
plt.title('Month Book')
for x,y in zip(x,y):plt.text(x,y+0.1,'%d' % y,ha = 'center',va = 'bottom')for x,y in zip(x1,y1):plt.text(x,y+0.1,'%d' % y,ha = 'center',va = 'bottom')
3.3客源地与预订取消率
country_book=df['country'].value_counts()[:10]
country_cancel=df[(df.country.isin (country_book.index)) & (df.is_canceled==1)]['country'].value_counts()
plt.figure(figsize=(15,8))
sns.countplot(x='country',data=df[df.country.isin (country_book.index)],hue='is_canceled',palette=sns.color_palette('Set2',2))
plt.title('Main Source of Guests')
country_cancel_rate=(country_cancel/country_book).sort_values(ascending=False)
print('各国客户取消率'.center(10),country_cancel_rate,sep='\n')
Resort hotel和City hotel的旺季均为夏季7、8月份,且客源主要为欧洲国家,符合欧洲游客偏爱夏季出游的特点,需要重点关注来自葡萄牙(PRT)和英国(BRT)等取消率高的主要客源
3.4客户类型
city_customer=city_hotel.customer_type.value_counts()
resort_customer=resort_hotel.customer_type.value_counts()
plt.figure(figsize=(21,12),dpi=80)
plt.subplot(1,2,1)
plt.pie(city_customer,labels=city_customer.index,autopct='%.2f%%')
plt.legend(loc=1)
plt.title('City Hotel Customer Type')
plt.subplot(1,2,2)
plt.pie(resort_customer,labels=resort_customer.index,autopct='%.2f%%')
plt.title('Resort Hotel Customer Type')
plt.legend()
plt.show()
酒店的主要客户类型都是散客(Transient),占比均为70%左右
3.5酒店预订途径
city_segment=city_hotel.market_segment.value_counts()
resort_segment=resort_hotel.market_segment.value_counts()
plt.figure(figsize=(21,12),dpi=80)
plt.subplot(1,2,1)
plt.pie(city_segment,labels=city_segment.index,autopct='%.2f%%')
plt.legend()
plt.title('City Hotel Market Segment')
plt.subplot(1,2,2)
plt.pie(resort_segment,labels=resort_segment.index,autopct='%.2f%%')
plt.title('Resort Hotel Market Segment')
plt.legend()
plt.show()
两间酒店的客源主要来自线上旅游机构,其在City Hotel的占比甚至超过5成;线下旅游机构的比重次之,均为20%左右
3.6各类旅客日均开销
plt.figure(figsize=(15,8))
sns.boxplot(x='customer_type',y='adr',hue='hotel',data=df[df.is_canceled==0],palette=sns.color_palette('Set2',2))
plt.title('Average Daily Rate of Different Customer Type')
City Hotel各类客户的日均开销均高于Resort Hotel;在四种类型的客户中,散客(Transient)的消费最高,团体客(Group)最低
3.7新老客数量与取消预订率
plt.figure(figsize=(15,8))
sns.countplot(x='is_repeated_guest',data=df,hue='is_canceled',palette=sns.color_palette('Set2',2))
plt.title('New/Repeated Guest Amount')
plt.xticks(range(2),['no','yes'])
guest_cancel=(df.loc[df['is_canceled']==1]['is_repeated_guest'].value_counts()/df['is_repeated_guest'].value_counts()).sort_values(ascending=False)
guest_cancel.index=['New Guest', 'Repeated Guest']
print('新老客取消率'.center(15),guest_cancel,sep='\n')
老客的取消率为14.4%,而新客的取消率则达到了37.8%,高出老客24个百分点
3.8押金方式与预定取消率
print('三种押金方式预定量'.center(15),df['deposit_type'].value_counts(),sep='\n')
deposit_cancel=(df.loc[df['is_canceled']==1]['deposit_type'].value_counts()/df['deposit_type'].value_counts()).sort_values(ascending=False)
plt.figure(figsize=(8,5))
x=range(len(deposit_cancel.index))
y=deposit_cancel.values
plt.bar(x,y,label='Cancel_Rate',color=['orangered','lightsalmon','lightseagreen'],width=0.4)
plt.xticks(x,deposit_cancel.index)
plt.legend()
plt.title('Cancel Rate of Deposite Type')
for x,y in zip(x,y):plt.text(x,y,'%.2f' % y,ha = 'center',va = 'bottom')
无需押金(‘No Deposit’)是预定量最高的方式,且取消率较低,而不退押金(Non Refund)这一类型的取消预订率高达99%,可以减少这一类型的押金方式以减少客户取消率
3.9房间类型与预定取消量
plt.figure(figsize=(15,8))
sns.countplot(x='assigned_room_type',data=df,hue='is_canceled',palette=sns.color_palette('Set2',2))
plt.title('Book & Cancel Amount of Room Type')
room_cancel=df.loc[df['is_canceled']==1]['assigned_room_type'].value_counts()[:7]/df['assigned_room_type'].value_counts()[:7]
print('不同房型取消率'.center(5),room_cancel.sort_values(ascending=False),sep='\n')
在预定量前7的房型中,A、G房型的取消率均高于其他房型,A房型的取消率更是高达44.5%
4.数据预处理
建模的目的是为了预测旅客是否会取消酒店的预订,后续需要将’is_canceled’设为标签y,其余为特征x。日期特征’is_cance’reservation_status_date’不会直接影响标签,所以删除
df1=df.drop(labels=['reservation_status_date'],axis=1)
4.1处理分类型变量
cate=df1.columns[df1.dtypes == "object"].tolist()
#用数字表现的分类型变量
num_cate=['agent','company','is_repeated_guest']
cate=cate+num_cate
results={}
for i in ['agent','company']:result=np.sort(df1[i].unique())results[i]=result
results
agent和company列空值占比较多且无0值,所以用0填补
df1[['agent','company']]=df1[['agent','company']].fillna(0,axis=0)
df1.loc[:,cate].isnull().mean()
创造新变量in_company和in_agent对旅客分类,company和agent为0的设为NO,非0的为YES
df1.loc[df1['company'] == 0,'in_company']='NO'
df1.loc[df1['company'] != 0,'in_company']='YES'
df1.loc[df1['agent'] == 0,'in_agent']='NO'
df1.loc[df1['agent'] != 0,'in_agent']='YES'
创造新特征same_assignment,若预订的房间类型和分配的类型一致则为yes,反之为no
df1.loc[df1['reserved_room_type'] == df1['assigned_room_type'],'same_assignment']='Yes'
df1.loc[df1['reserved_room_type'] != df1['assigned_room_type'],'same_assignment']='No'
删除’reserved_room_type’,‘assigned_room_type’,‘agent’,'company’四个特征
df1=df1.drop(labels=['reserved_room_type','assigned_room_type','agent','company'],axis=1)
重新设置’is_repeated_guest’,常客标为YES,非常客为NO
df1['is_repeated_guest'][df1['is_repeated_guest']==0]='NO'
df1['is_repeated_guest'][df1['is_repeated_guest']==1]='YES'
df1['country']=df1['country'].fillna(df1['country'].mode()[0])
for i in ['in_company','in_agent','same_assignment']:cate.append(i)for i in ['reserved_room_type','assigned_room_type','agent','company']:cate.remove(i)
cate
对分类型特征进行编码
from sklearn.preprocessing import OrdinalEncoder
oe = OrdinalEncoder()
oe = oe.fit(df1.loc[:,cate])
df1.loc[:,cate] = oe.transform(df1.loc[:,cate])
4.2处理连续型变量
筛选出连续型变量,需要先删除’is_canceled’这一标签
col=df1.columns.tolist()
col.remove('is_canceled')
for i in cate:col.remove(i)
col
统计空值
df1[col].isnull().sum()
使用众数填补xtrain children列的空值
df1['children']=df1['children'].fillna(df1['children'].mode()[0])
连续型变量进行无量纲化
from sklearn.preprocessing import StandardScaler
ss = StandardScaler()
ss = ss.fit(df1.loc[:,col])
df1.loc[:,col] = ss.transform(df1.loc[:,col])
4.3各变量的相关性系数
cor=df1.corr()
cor=abs(cor['is_canceled']).sort_values()
cor
plt.figure(figsize=(8,15))
x=range(len(cor.index))
name=cor.index
y=abs(cor.values)
plt.barh(x,y,color='salmon')
plt.yticks(x,name)
for x,y in zip(x,y):plt.text(y,x-0.1,'%.2f' % y,ha = 'center',va = 'bottom')
plt.xlabel('Corrleation')
plt.ylabel('Varriance')
plt.show()
预订状态(‘reservation_status’)与是否取消预订的相关性最高,达到了0.92,但考虑到后续可能会导致模型过拟合,所以删除;押金类型(‘deposit_type’)则达到了0.47,创造的特征预订和分配房型是否一致(‘same_assignment’)也有0.25的相关性
5.建模预测
划分特征x和标签y
df2=df1.drop('reservation_status',axis=1)
x=df2.loc[:,df2.columns != 'is_canceled' ]
y=df2.loc[:,'is_canceled']
from sklearn.model_selection import train_test_split as tts
xtrain,xtest,ytrain,ytest=tts(x,y,test_size=0.3,random_state=90)
for i in [xtrain,xtest,ytrain,ytest]:i.index=range(i.shape[0])
5.1随机森林
from sklearn.ensemble import RandomForestClassifier
from sklearn.model_selection import cross_val_score as cvs,KFold
from sklearn.metrics import accuracy_score
rfc=RandomForestClassifier(n_estimators=100,random_state=90)
cv=KFold(n_splits=10, shuffle = True, random_state=90)
rfc_score=cvs(rfc,xtrain,ytrain,cv=cv).mean()
rfc.fit(xtrain,ytrain)
y_score=rfc.predict_proba(xtest)[:,1]
rfc_pred=rfc.predict(xtest)
from sklearn.metrics import roc_curve
from sklearn.metrics import roc_auc_score as AUC
FPR, recall, thresholds = roc_curve(ytest,y_score, pos_label=1)
rfc_auc = AUC(ytest,y_score)
绘制ROC曲线
plt.figure(figsize=(8,8))
plt.plot(FPR, recall, color='red',label='ROC curve (area = %0.2f)' % rfc_auc)
plt.plot([0, 1], [0, 1], color='black', linestyle='--')
plt.xlim([-0.05, 1.05])
plt.ylim([-0.05, 1.05])
plt.xlabel('False Positive Rate')
plt.ylabel('Recall')
plt.title('Random Forest Classifier ROC Curve')
plt.legend(loc="lower right")
plt.show()
查看模型classification_report
from sklearn.metrics import classification_report as CR
print('随机森林'.center(50), CR(ytest,rfc_pred),sep='\n')
score={'Model_score':[rfc_score],'Auc_area':[rfc_auc]}
score_com=pd.DataFrame(data=score,index=['RandomForest'])
score_com.sort_values(by=['Model_score'],ascending=False)
随机森林的准确度达到了88.8%,AUC面积也有0.95,可以通过调参来继续提升模型的效果
分析总结
1.City Hotel的预定量和取消率都远高于Resort Hotel,该酒店应对客户展开调研,深入了解导致客户最终放弃预订的因素从而降低客户的取消率
2.酒店应利用好每年7、 8月的旅游旺季,可以在保证服务质量的同时适当提高价格获取更多利润,在淡季(冬季)的时候进行优惠活动,如圣诞大促和新年活动,减少酒店空房率
3.酒店需分析来自葡萄牙、英国等主要客源国的客户画像,了解这些客户的属性标签、偏好与消费特征,推出专属服务从而降低客户的取消率
4.由于散客是酒店的主要客户群且消费水平较高,酒店可以通过线上和线下旅游机构的途径,加大对自由行的宣传营销,从而吸引更多该类型的游客
5.新客的取消率比老客高24%,因此,酒店应重点关注新客的预订与入住体验,为新客提供更多指引与优惠,如为首次入住的客户提供折扣,调研新客对入住满意与不满意的反馈以提升日后服务,同时维护好老客
6.不退押金(Non Refund)这一类型的取消预订率高达99%,酒店应优化这种方式,如返还50%的押金,或者可以直接取消这一种方式,从而提高入住率
7.A、G房型的取消率远高于其他房型,酒店方应在客户在预订的时候跟客户仔细确认房间信息,让客户对房间情况有充分了解,避免认知错误,同时可以对房间设施进行优化并提高服务水平
转:https://blog.csdn.net/AOAIYI/article/details/129381319
数据分析:基于随机森林(RFC)对酒店预订分析预测相关推荐
- 机器学习:基于随机森林(RFC)对酒店预订分析预测
机器学习:基于随机森林(RFC)对酒店预订分析预测 作者:i阿极 作者简介:Python领域新星作者.多项比赛获奖者:博主个人首页
- 基于随机森林模型的葡萄酒品质分析
视频:南京大学 用Python玩转数据 https://www.icourse163.org/course/NJU-1001571005 背景:UCI葡萄酒数据集中有12个属性,分别是: 1 - fi ...
- 大数据分析案例-基于随机森林模型对北京房价进行预测
目录 1.项目背景 2.项目简介 2.1数据说明 2.2技术工具 3.算法原理 4.项目实施步骤 4.1理解数据 4.2数据预处理 4.2.1缺失值处理 4.2.2重复值处理 4.2.3异常值处理 4 ...
- 基于随机森林模型的红酒品质分析
看了南京大学的<用python玩转数据视频>,Python非常强大.代码做了些注释. https://scipy.org/ # url: https://archive.ics.uci.e ...
- 动手实操丨基于随机森林算法进行硬盘故障预测
摘要:业界期望使用机器学习技术来构建硬盘故障预测的模型,更准确地提前感知硬盘故障,降低运维成本,提升业务体验.本案例将使用随机森林算法来训练一个硬盘故障预测模型. 本文分享自华为云社区<基于随机 ...
- 基于随机森林算法进行硬盘故障预测
摘要:本案例将带大家使用一份开源的S.M.A.R.T.数据集和机器学习中的随机森林算法,来训练一个硬盘故障预测模型,并测试效果. 本文分享自华为云社区<基于随机森林算法进行硬盘故障预测>, ...
- 【项目实战】基于随机森林算法的房屋价格预测模型
[博客地址]:https://blog.csdn.net/sunyaowu315 [博客大纲地址]:https://blog.csdn.net/sunyaowu315/article/details/ ...
- 基于随机森林算法的贷款违约预测模型研究(Give me some credit)
本文实验代码github:https://github.com/dengsiying/give-me-some-credit/tree/master 参考链接:从决策树到随机森林 http://www ...
- 【python3】基于随机森林的气温预测
前言 这个项目实战系列主要是跟着网络上的教程来做的,主要参考<跟着迪哥学习机器学习>中的思路和具体实现代码,但是书中使用到的应该是python2的版本,有一些代码也有问题,有的是省略了一些 ...
最新文章
- 【转】高性能前端3-高性能javascript
- 一个改变世界的“箱子”
- 大数据传输,文件传输的专业解决方案!
- aix 安装oracle9,IBM P570 小型机AIX5.3系统安装ORACLE9i
- linux下被遗忘的gpio_keys按键驱动
- adb avd install 失败_Android 模拟器(emulator-5554...)出现错误解决办法
- PS滤镜插件工具箱Mac版:Nik Collection 4
- cartographer探秘第二章之论文解析
- 传奇脚本显示服务器开区时间代码,GOM引擎该地图只限新区开放方法,传奇开区时设置老区不能进脚本...
- 处理各种压力(情绪、家庭)时,需要注意什么!
- 优秀网页设计的七条基本准则
- JavaFx界面设计【SceneBuilder版】适合初学者
- java何时new_何时使用lambda,何时使用Proc.new?
- 群辉服务器如何清理缓存和文件,群晖的硬盘缓存到底肿么清理
- Alamps学习设计模式之备忘录模式(笑话:劫个色OR抢个鸡蛋版)
- HDMI接口与HDMI协议
- 在浏览器进行大文件分片上传(java服务端实现)
- keras-gpu安装
- 【Mark Schmidt课件】线性代数
- java 生成mysql dto_如何根据动态SQL代码自动生成DTO
热门文章
- java基础-CAS、synchronized和AQS的理解
- 数据库设计时设计标识字段的一些思考[mysql]
- 计算机无法识别手机咋解决,我电脑不能识别手机USB端口。怎么办?
- python投资分析实验报告_Python的实验报告怎么写?
- MASM32编程访问结构体成员要注意的一点
- docker启动指定udp端口
- IP地址最简单的解释
- 搜狗上市总市值53亿美元;微信发布数据报告,9月份日活用户9亿丨价值早报
- 一步一个台阶,两个台阶,三个台阶,直到 m个台阶,有多少种方法爬到n阶楼顶
- 【CSS】栅格(Grid)布局