机器学习运用-民宿价格

项目简介

随着旅游业的蓬勃发展,民宿市场迎来了前所未有的增长机遇。正好最近在参加拓尔思数据挖掘公益实习活动,我的项目将应用机器学习技术开发一个价格预测模型。可以达到更好地理解和预测民宿价格的目的,该模型综合考虑了从容纳人数、便利设施数量到房主回复率等一系列关键数据,目的在于评估并预测不同民宿的潜在价格。

通过分析包括民宿的物理属性(床铺、卧室与洗手间的数量等)、位置数据(维度、经度和邮编等)、客户互动指标(评论个数和房主回复率等)以及提供的便利服务和条件(互联网接入、厨房设施和其他基础设施等),模型旨在捕捉影响价格的各种因素。此外,模型还将探讨民宿的类型、所在城市、清洁费用及即时预订支持等对价格可能产生的影响。最后,通过考察房主的在线呈现,如是否有个人资料图片及身份验证,进一步完善模型预测的准确性。

项目采用CatBoost对数据进行分析,CatBoost(Categorical Boosting)是由 Yandex 开发的一个开源机器学习库,基于梯度提升决策树(Gradient Boosted Decision Trees, GBDT)算法的一种实现,专为处理分类(Categorical)数据而设计,同时也可以完成一些回归任务。CatBoost 可以提供高性能、可扩展性和精确度,尤其运用在是在具有很多类别特征的数据集上表现突出。


数据总览

文件包括"train.csv"和"test.csv"两个文件,下面是"trian.csv"的大致含有的特征内容:

在这里插入图片描述


代码分析

导入相关python库和数据

# 导入相关库

import pandas as pd
from sklearn.preprocessing import RobustScaler
from sklearn.preprocessing import LabelEncoder
from sklearn.preprocessing import MinMaxScaler
from sklearn.preprocessing import StandardScaler
from sklearn.model_selection import train_test_split
from catboost import CatBoostRegressor, Pool
from sklearn.metrics import mean_squared_error,r2_score
import warnings

# options

warnings.filterwarnings('ignore')#这行命令将会忽略python警告信息,使得输出结果更加清晰,不被警告打扰。
pd.set_option('display.max_rows', None)
pd.set_option('display.max_columns', None)#用来确保在输出DataFrame时能显示所有的行和列。

# 加载数据集

train = pd.read_csv('./train_data.csv')
test = pd.read_csv('./test_data.csv')

# 数据探索
train.info()
train.head()

train.info(),会显示关于DataFrame的一些基本信息,如:列名、非空值数量、每列的数据类型。

train.head(),会显示DataFrame的前几行数据,默认情况下是前5行。这对于快速查看数据集的样本数据以及确保数据被正确加载也是很有用的。

特征工程处理

#添加新特征:便利设施数量

train['便利设施_num'] = train['便利设施'].str.split(',')
int_equipments = []
for item in train['便利设施_num']:
    num = len(item)
    int_equipments.append(num)
train['便利设施_num'] = int_equipments

test['便利设施_num'] = test['便利设施'].str.split(',')
int_equipments_test = []
for item in test['便利设施_num']:
    num = len(item)
    int_equipments_test.append(num)
test['便利设施_num'] = int_equipments_test


# 分割'便利设施'

for key_words in ['Internet', 'Kitchen', 'Pets', 'Air', 'Washer', 'Aid', 'Heating', 'Dryer', 'Essentials', 'Hangers','TV','parking', '24-hour']:
    train[key_words] = train['便利设施'].str.contains(key_words).astype('str')
    test[key_words] = test['便利设施'].str.contains(key_words).astype('str')

    
# '民宿周边'特征

train['民宿周边'] = train['民宿周边'].fillna(-999) #将NaN填充指定值
test['民宿周边'] = test['民宿周边'].fillna(-999)

surround_train = []
for value in train['民宿周边']:
    if value == -999:
        new_value = 0
    else:
        new_value = 1
    surround_train.append(new_value)
train['民宿周边'] = surround_train

surround_test = []
for value in test['民宿周边']:
    if value == -999:
        new_value = 0
    else:
        new_value = 1
    surround_test.append(new_value)
test['民宿周边'] = surround_test


#'房主是否有个人资料图片'和'房主身份是否验证'特征

train['房主是否有个人资料图片'] = train['房主是否有个人资料图片'].fillna('f')
test['房主是否有个人资料图片'] = test['房主是否有个人资料图片'].fillna('f')
train['房主身份是否验证'] = train['房主身份是否验证'].fillna('f')
test['房主身份是否验证'] = test['房主身份是否验证'].fillna('f')

str_cols = ['Internet', 'Kitchen', '房主是否有个人资料图片', '房主身份是否验证', 'Air', 'Pets', 'Washer', 'Aid',
            'Heating', 'Dryer','Essentials', 'Hangers', 'TV', 'parking', '24-hour']
le = LabelEncoder()
for col in str_cols:
    train[col] = le.fit_transform(train[col])
    test[col] = le.fit_transform(test[col])

    
# '房主回收率'特征

train['房主回复率'] = train['房主回复率'].fillna('20%')
test['房主回复率'] = test['房主回复率'].fillna('20%')
train['房主回复率'] = train['房主回复率'].str[:-1]
#去除数据中的‘%’
test['房主回复率'] = test['房主回复率'].str[:-1]


# '首次评论日期'特征
train['首次评论日期'] = train['首次评论日期'].fillna('2019-1-1')
test['首次评论日期'] = test['首次评论日期'].fillna('2019-1-1')
train['最近评论日期'] = train['最近评论日期'].fillna('2019-1-1')
test['最近评论日期'] = test['最近评论日期'].fillna('2019-1-1')

time_cols = ['首次评论日期', '最近评论日期', '何时成为房主']
for col in time_cols:
    train[col] = pd.to_datetime(train[col])
    test[col] = pd.to_datetime(test[col])

    
# '邮编'特征
train['邮编'] = train['邮编'].fillna(0)
test['邮编'] = test['邮编'].fillna(0)
train['邮编'] = train['邮编'].astype('str')
test['邮编'] = test['邮编'].astype('str')


# 特征处理:将特征分为连续变量和分类变量,分别处理

cols = train.columns
cont_cols = ['容纳人数', '便利设施_num', '床的数量', '卧室数量', '洗手间数量', '维度', '经度', '评论个数', '民宿评分','房主回复率']
cate_cols=['邮编','Internet','Kitchen','Air','Pets','Washer','Aid','Heating','Dryer','Essentials','Hangers',"TV",'parking',
           '24-hour','床的类型','民宿周边','取消条款','所在城市','清洁费','是否支持随即预订','房产类型','房型','房主是否有个人资料图片', '房主身份是否验证']
#定义了两个列表,分别包含了连续型特征列和分类型特征列的列名


#其他离散型特征的处理
features = cont_cols + cate_cols

train[cate_cols] = train[cate_cols].astype('category')
test[cate_cols] = test[cate_cols].astype('category')
#将训练集和测试集中的分类型特征列的数据类型转换为 'category' 类型。

for col in cate_cols:
    train[col]=train[col].fillna(train[col].mode())
    test[col] = test[col].fillna(test[col].mode())
#对分类型特征列中的缺失值进行填充,填充的值为该列的众数(mode)。

for col in ['洗手间数量','床的数量','卧室数量','民宿评分']:
    train[col]=train[col].fillna(train[col].median())
    test[col] = test[col].fillna(test[col].median())
#对指定的连续型特征列中的缺失值进行填充,填充的值为该列的中位数(median)。
train=train.dropna().reset_index()


#特征缩放:其他连续型特征的处理
X_train=train[features]
scaler=RobustScaler()
scaler.fit(X_train[cont_cols])
#使用训练集中的连续型特征列来拟合RobustScaler对象。
X_train[cont_cols]=scaler.transform(X_train[cont_cols])

X_test=test[features]
X_test[cont_cols]=scaler.transform(X_test[cont_cols])
y_train=train['价格'].astype('int')

DateFrame[colum].str.contains(key_words)

方法在列colum中查找是否包含特定关键词 key_words,返回一个布尔类型的 Series。

astype(‘str’)

将项目中上一步生成的布尔类型的 Series 转换为字符串类型,将 True 和 False 分别转换为 ‘True’ 和 ‘False’ 字符串。

LabelEncoder()

LabelEncoder()是sklearn的内容,le = LabelEncoder(),实例化一个LabelEncoder对象,用于对分类特征进行编码

fit_transform()

fit_transform() 方法会先对指定的列数据进行拟合,然后进行实际的转换操作。在这个过程中,LabelEncoder 会根据指定列的值建立编码规则,并将分类特征转换为数值编码。

to_datetime()

Pandas中的函数,将DataFrame中的当前列col中的日期时间字符串转换为 Pandas datetime 类型。

dropna()

删除训练集中的所有包含缺失值的行

reset_index()

重置 DataFrame 的索引。

RobustScaler()

scaler=RobustScaler(),这行代码实例化了一个 RobustScaler 对象,用于后续的特征缩放。RobustScaler 是一种对异常值有鲁棒性的缩放器,它使用中位数和四分位数范围来缩放特征。

模型训练和拟合

#划分数据集
X_train,X_valid,y_train,y_valid=train_test_split(X_train,y_train,random_state=1025,test_size=0.2)

train_pool=Pool(X_train,y_train,cat_features=cate_cols)
eval_pool=Pool(X_valid,y_valid,cat_features=cate_cols)
#两行代码创建了两个CatBoost数据池,一个用于训练,一个用于评估。

model=CatBoostRegressor()
#实例化CatBoostRegressor对象,用于后续的模型训练。

model.fit(train_pool,eval_set=eval_pool)
#使用训练数据池进行模型训练,并设置了评估数据集。

y_pred_valid=model.predict(X_valid)
#使用训练好的模型对验证集进行预测,将结果存储在y_pred_valid中

print(y_pred_valid)

result_df=X_valid.copy()
result_df['价格']=y_valid
result_df['预测价格']=y_pred_valid
#创建一个新的DataFrame,将实际值、预测值和特征重新集合

result_df.head()

模型评价

mse=mean_squared_error(y_valid,y_pred_valid)  #均方误差
r2=r2_score(y_valid,y_pred_valid)             #r2系数
print('mse的值为:',mse)
print('r2的值为:',r2)

模型使用

predictions=model.predict(X_test)
#使用训练好的模型对测试集进行预测
new_results_df=X_test.copy()
new_results_df['预测价格']=predictions
new_results_df.head()
#同训练集,构建出测试集DataFrame

结果展示

在这里插入图片描述

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/570874.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

【Java】文件操作(一)

文章目录 ✍一、文件的基本认识1.文件是什么?2.文本文件和二进制文件3.文件权限4.相对路径和绝对路径1.1绝对路径1.2相对路径 ✍二、文件的基本操作1.FIle的属性2.File的构造方法3.File类的方法3.1File类的获取操作3.2File类的判断操作3.3文件创建和删除3.4其他的常…

this指向

调用方式示例 函数中this的指向通过new调用new method()新对象直接调用method()全局对象通过对象调用obj.method()前面的对象call、apply、bindmethod.call(ctx)第一个参数 我们说的this指向是一个函数里边的this指向,如果这个this不在函数里边,那th…

C. Inhabitant of the Deep Sea

本题链接:Problem - C - Codeforces 题目: 样例: 输入 6 4 5 1 2 4 3 4 6 1 2 4 3 5 20 2 7 1 8 2 2 2 3 2 2 15 1 5 2 7 5 2输出 2 3 5 0 2 2 思路: 数学模拟。 根据题意,一前一后的攻击,攻击k次后&…

PotPlayer详细安装教程

安装步骤 进入官网: https://potplayer.tv/ 根据自己电脑的windows系统选择对应的版本安装 选择合适的字体 下载完成 优化设置 刚下好的potplayer仅限于能用,所有设置均为默认状态,我们需要进行优化 首先打开potplayer 右击选择选项 在…

三、CPU基础-缓存

计算机中缓存一般分为两个部分 1.内存 2.CPU Cache 一、CPU Cache分级 CPU Cache 通常分为大小不等的三级缓存,分别是 L1 Cache、L2 Cache 和 L3 Cache。 L1 Cache 和 L2 Cache 都是每个 CPU 核心独有的(通常会分为「数据缓存」和「指令缓存」&#…

Git--原理与使用

目录 一、课程目标二、初始Git三、安装Git3.1 Linux-centos 四、Git的基本操作4.1 创建Git本地仓库 五、配置Git六、认识工作区、暂存区、版本库七、添加文件八、查看.git九、修改文件十、版本回退十一、撤销修改11.1 情况一:对于工作区的代码,还有add11…

海康NVR接入视频监控平台部分视频浏览失败,显示503错误的解决办法

目录 一、问题概述 二、问题排查 (一)排查思路介绍 (二)平台排查 1、确定排查的思路 2、信令控制模块的排查 3、媒体转发模块的排查 (三)客户设备排查 1.观察正常视频的设置 2. 调查问题原因 三…

B端设计实战:基于角色属性的权限设计

编辑导读:“权限控制”是中后台的基础能力,用于管控操作人员在平台内可做的事项内容。即通过权限控制,可以决定哪些人在平台内可以做哪些事。本文作者围绕角色&属性的权限设计展开分析,希望对你有帮助。 Hello,我是一名交互设计师。 随着3月暖春的即将到来,苏州的疫…

足球场体育馆三维可视化:颠覆传统观赛体验,开启视觉新纪元

在数字化浪潮席卷全球的今天,三维可视化技术正以其独特的魅力引领着体育场馆建设的革新潮流。这一技术的出现,不仅为观众带来了前所未有的视觉享受,更在体育产业的发展中,开启了一扇通往未来的大门。 足球场体育馆三维可视化&…

YOLOV1学习笔记

1. 前置知识简介 1.1 方向梯度直方图(HOG, Histogram of Oriented Gradient) 在计算机视觉以及数字图像处理中方向梯度直方图是一种能对物体进行检测的基于形状边缘特征的描述算子(用于量化图像局部特征的算法工具,它将图像中的…

string 类以及模拟实现

𝙉𝙞𝙘𝙚!!👏🏻‧✧̣̥̇‧✦👏🏻‧✧̣̥̇‧✦ 👏🏻‧✧̣̥̇:Solitary_walk ⸝⋆ ━━━┓ - 个性标签 - :来于“云”的“羽球人”。…

Flutter 中优雅切换应用主题的组件

Flutter 中优雅切换应用主题的组件 视频 https://youtu.be/L–XLpc452I https://www.bilibili.com/video/BV1wD421n75p/ 前言 原文 https://ducafecat.com/blog/flutter-app-theme-switch Adaptive Theme 这个组件通过包裹 MaterialApp 的方式整体管理 theme 主题&#xff0…

Java冲突

本身 父类 接口(多) 如果出现同样名字的方法,就会出现冲突 * 情况描述1: * 当一个类,继承了父类,实现了某接口,父类中的成员方法和接口中的方法重名 * 解决方法: * 子类就近选择父类成员方法 亲爹优先原则 * *使用格式: * 父类:super.方法名 * 父接口:父接口名.super.方…

QT——其他方式实现HelloWrold

QT——其他方式实现HelloWrold 使用输入框实现使用代码实现 通过按钮实现信号槽代码方式实现 我们之前对QT实现HelloWorld有了一些基本的了解,用了一些简单的方法实现了HelloWorld,如果对QT还不怎么了解的,可以点击这里: https://…

算法提高 第一期 KMP扩展算法

1## 具体思路: 和KMP算法的是想类似,充分利用已经比较字符性质来减少冗余的字符比较次数。KMP的思想是充分的利用模式串中所有前缀字串(以模式串为开头的字串)的真前缀和真后缀(指子串的开始字符与子串的最后字符相等的…

【C 数据结构】二叉树

文章目录 【 1. 基本原理 】1.1 二叉树的性质1.2 满二叉树1.3 完全二叉树 【 2. 二叉树的顺序存储结构 】2.1 完全二叉树的顺序存储2.2 普通二叉树的顺序存储2.3 完全二叉树的还原 【 3. 二叉树的链式存储结构 】【 4. 二叉树的先序遍历 】4.1 递归实现4.2 非递归实现 【 5. 二…

MongoDB磁盘空间占满,导致数据库被锁定,如何清理数据和磁盘空间

一、问题 1、我在实际项目中,遇到一个问题,随着数据每天的不断增加,导致mongodb的磁盘空间站满了,数据库被锁了,无法使用。 2、故障表现 部署的应用程序突然无法将数据写入数据库,但是可以正常读取数据。…

栈和队列详解

目录 栈栈的概念及结构栈的实现数组栈的实现数组栈功能的实现栈的初始化void STInit(ST* pst)初始化情况一初始化情况二 代码栈的插入void STPush(ST* pst, STDataType x)代码 栈的删除void STPop(ST* pst)代码 栈获取数据STDataType STTop(ST* pst)代码 判断栈是否为空bool ST…

裸金属服务器是什么

自推出裸金属服务器以来,它一直断断续续地出现在我们面前。最近,关于裸金属服务器、什么是裸金属服务器、裸金属服务器可以做什么、数据托架共享的讨论越来越多: 裸金属服务器(bare metal server,BMS)的官…

如何在OpenWRT上配置SFTP远程文件传输

如何在OpenWRT上配置SFTP远程文件传输 OpenWRT 是一款广泛使用的开源路由器固件,它能够让普通的家用路由器具备高级路由功能,提供更多自定义和优化选项。本文将介绍如何在OpenWRT上配置SFTP(SSH文件传输协议)服务,以便…