5.数据预处理
经过4的数据分析环节,我们得出了一些和目标特征‘price’关联度比较高的特征,现在将这些特征列进行提取
df.head(5)
# 筛选对应的数据列
rs_df = df[['price','comment','sight_comment_score','level','city','address']]
# 判断是否有缺失值
rs_df.isnull().sum()
# 评论这一列有景区没有,将缺失值填充为0
rs_df['comment'] = rs_df['comment'].fillna(0)
再次查看
rs_df.isnull().sum()
# 将city,address进行One-Hot编码
ca_df = pd.get_dummies(rs_df[['city','address']],dtype='int')
ca_df.head(5)
One-Hot编码目的:计算机本质上只能处理数值型数据,对字符串的处理也是基于一定的转换算法进行编译后处理的,把字符串类型的‘city’和‘address’也就是景点坐落的城市和地址转换成稀疏的数字串可以提高机器学习算法的训练效率
pd.get_dummies():Pandas提供的get_dummies函数用于自动对分类变量进行One-Hot编码。
作用是将一个DataFrame中的分类数据转换为“哑变量”(dummy variables),也称为“指示变量”。哑变量是用于表示分类数据的二进制(0或1)变量。
1.pd.get_dummies(): 这是pandas库中的一个函数,用于将分类变量转换为哑变量。这个函数会为每个类别创建一个新的列,如果某个观测属于该类别,则在新列中标记为1,否则为0。最后某一条数据在机器学习过程中将以一串由0和1组成的数字串来表示热编码后的特征。(one-hot编码处理)
2.rs_df[['city','address']]: 这部分代码从名为rs_df的DataFrame中选择city和address这两列。rs_df可能是一个包含房地产信息的DataFrame,其中city列代表城市,address列代表地址。
3.dtype='int': 这个参数指定了新创建的哑变量列的数据类型为整数(int)。这是因为哑变量只包含0和1,所以使用整数类型是合适的。
4.ca_df =: 这将get_dummies函数的输出赋值给变量ca_df。ca_df是一个新创建的DataFrame,包含了原始city和address列转换后的哑变量。
大多数模型只能处理数值输入,而不能直接处理文本或分类数据。
应用one-hot编码处理后的数据
# 将ca_df和rs_df进行合并
rs_df1 = pd.merge(rs_df,ca_df,left_index=True,right_index=True)
rs_df1.head(5)
# 删除city和address列
rs_df1.drop(['city','address'],axis=1,inplace=True)
rs_df1.head(5)
6.机器学习建模
6.1决策树
6.1.1决策树算法概述
决策树是属于有监督机器学习的一种,起源非常早,符合直觉并且非常直观,模仿人类做决策的过程,早期人工智能模型中有很多应用,现在更多的是使用基于决策树的一些集成学习的算法。这章我们把决策树算法理解透彻非常有利于后面去学习集成学习。
特点
1.可以处理非线性的问题
2.可解释性强 没有θ
3.模型简单,模型预测效率高if else
4.不容易显示的使用函数表达,不可微 XGBoost
数据不断分裂的递归过程,每一次分裂,尽可能让类别一样的数据在树的一边,当树的叶子节点的数据都是一类的时候,则停止分裂。
6.1.2模型调用
# 引入模块
from sklearn.model_selection import train_test_split # 划分数据集
from sklearn.ensemble import RandomForestRegressor # 使用随机森林
from sklearn.metrics import mean_squared_error,mean_absolute_error # 引入模型评价指标
处理后的数据集:rs_df1
# 准备样本数据
# 获取除了price之外的所有列 price是目标特征
columns = rs_df1.columns.difference(['price'])
# 获取特征值
x = rs_df1[columns].values
x
# 获取标签
y = rs_df1['price'].values
y
划分训练数据、测试数据
# 数据的拆分7:3
# x特征值 y标签 train训练集 test测试集
x_train,x_test,y_train,y_test=train_test_split(x,y,test_size=0.3,random_state=42)
# 查看划分结果
x_train.shape,x_test.shape,y_train.shape,y_test.shape
# 数据的训练
# 随机森林回归
# n_estimators:森林中树的数量
# max_depth:树的最大深度
# 调整n_estimators和max_depth的值,可以提高模型的准确率
rf_model_1 = RandomForestRegressor(n_estimators=20,max_depth=7)
# 模型的训练
rf_model_1.fit(x_train,y_train)
# 模型的预测
pred_1 = rf_model_1.predict(x_test)
pred_1
6.1.3模型评估
# 模型的评估
# 均方误差, 值 越小越好
print('均方误差:',mean_squared_error(y_test,pred_1))
# 平均绝对误差 值 越小越好
print('平均绝对误差:',mean_absolute_error(y_test,pred_1))
# 调整n_estimators和max_depth的值,可以提高模型的准确率
rf_model_2 = RandomForestRegressor(n_estimators=30,max_depth=10)
# 模型的训练
rf_model_2.fit(x_train,y_train)
# 模型的预测
pred_2 = rf_model_2.predict(x_test)
pred_2
# 模型的评估
# 均方误差, 值 越小越好
print('均方误差:',mean_squared_error(y_test,pred_2))
# 平均绝对误差 值 越小越好
print('平均绝对误差:',mean_absolute_error(y_test,pred_2))
6.2随机森林(集成学习)
6.2.1随机森林算法概述
并行地去训练一定数量规模的预测器,然后众人拾柴火焰高
随机森林
1、随机选择样本(放回抽样);
2、随机选择特征;
3、构建决策树;
4、随机森林投票(平均)
优点:
1.表现良好
2.可以处理高维度数据(维度随机选择)
3.辅助进行特征选择
4.得益于bagging 可以进行并行训练
缺点:
对于噪声过大的数据容易过拟合
6.2.2模型使用
from sklearn.tree import DecisionTreeRegressor
from sklearn.metrics import mean_squared_error
from sklearn.model_selection import GridSearchCV
from sklearn.preprocessing import StandardScaler
from sklearn.pipeline import Pipeline
# 创建决策树回归模型
dtr_model = DecisionTreeRegressor(random_state=42)
# 创建管道,包括标准化和决策树回归
pipeline = Pipeline([
('scaler', StandardScaler()), # 数据标准化
('dtr', dtr_model)
])
pipeline:流水线地形式使用机器学习算法
# 使用网格搜索来寻找最佳的参数
param_grid = {
'dtr__max_depth': [3, 5, 10, None], # 决策树的最大深度
'dtr__min_samples_split': [2, 5, 10], # 分割内部节点所需的最小样本数
'dtr__min_samples_leaf': [1, 2, 5] # 叶子节点所需的最小样本数
}
grid_search = GridSearchCV(pipeline, param_grid, cv=5, scoring='neg_mean_squared_error')
# 训练模型
grid_search.fit(x_train, y_train)
# 最佳参数和模型
best_params = grid_search.best_params_
best_model = grid_search.best_estimator_
best_params
best_model
6.2.3模型评估
# 使用找到的best_model预测测试集
y_pred = best_model.predict(x_test)
y_pred
# 计算均方误差
mse = mean_squared_error(y_test, y_pred)
print(f'均方误差: {mse}')
# 平均绝对误差 值 越小越好
print('平均绝对误差:',mean_absolute_error(y_test,y_pred))
# 打印最佳参数
print(f'最佳参数: {best_params}')
6.3梯度提升树
6.3.1梯度提升树算法概述
GBDT应用于回归问题时
6.3.2模型使用
from sklearn.ensemble import GradientBoostingRegressor
from sklearn.metrics import mean_squared_error# 创建梯度提升树回归模型
gbr_model = GradientBoostingRegressor(random_state=42)
# 训练模型
gbr_model.fit(x_train, y_train)
# 预测测试集
y_pred_1 = gbr_model.predict(x_test)
6.3.3模型评估
# 计算均方误差
mse = mean_squared_error(y_test, y_pred_1)
print(f'均方误差: {mse}')
# 平均绝对误差 值 越小越好
print('平均绝对误差:',mean_absolute_error(y_test,y_pred_1))
7.总结
- 城市旅游发展与景区等级:城市经济和基础设施的完善程度对景区的吸引力和等级评定有显著影响。
- 游客体验与景区评价:高评论数的景区往往能提供更好的游客体验,这与景区的服务质量和设施完善度密切相关。
- 5A级景区的示范效应:5A级景区作为旅游业的标杆,其成功经验可以为其他景区提供借鉴,推动整个行业的服务水平提升。
7.1任务说明
1.划分好的训练集用于训练模型,然后用测试集来预测结果y
2.将y_pred于真实值y进行比较
3.通过均方误差和平均绝对误差来评价模型
7.2算法评价
1.决策树
均方误差: 224771.53121922252
平均绝对误差: 155.2390348610850
2.随机森林
均方误差: 278754.27231324726
平均绝对误差: 165.6377770520820
3.梯度提升树
均方误差: 224771.53121922252
平均绝对误差: 155.2390348610850661
7.3总结与评价
在本次旅游景点票价预测项目中,我们比较了三种不同的机器学习模型:决策树、随机森林和梯度提升树。
1.决策树
决策树模型在本项目中表现良好,均方误差和平均绝对误差相对较低,表明模型能够较好地拟合数据并预测票价。
决策树的优点是模型简单,易于理解和解释。但是,它容易过拟合,对于复杂的数据集可能不够强大。
2.随机森林
随机森林模型在本项目中的均方误差和平均绝对误差都高于决策树,表明其预测性能不如决策树。
随机森林通过集成多个决策树来提高预测性能,通常能够提供更稳定的预测结果。然而,在本项目中,它的表现没有达到预期,可能是由于参数设置不当或数据预处理不足。
3.梯度提升树
梯度提升树模型在本项目中的性能与决策树相当,均方误差和平均绝对误差都较低。
梯度提升树是一种强大的集成学习方法,通过逐步添加树来改进模型性能。它通常能够处理更复杂的数据关系,但在本项目中,其性能并没有显著优于决策树。
8.反思
1. 数据收集的难点
- 难点:获取全面且准确的旅游景点数据可能具有挑战性,因为对于旅游景点的数据会分散在不同的来源(app、当地的信息检索服务资源),且更新频率不一。
- 解决方法:通过整合多个数据源,包括官方网站、旅游论坛和社交媒体,来确保数据的全面性。同时,定期更新数据以保持其时效性。最重要的是自定义一个框架来规范对景点进行分析的特征维度。
2. 数据清洗和预处理的难点
- 难点:收集到的这份数据包含缺失值、异常值和不一致的格式,这些都会影响分析的准确性。比如有些景点是没有评级、没有评论数或者地理位置的格式比较特殊。
- 解决方法:使用Pandas库进行数据清洗,包括处理缺失值(如填充或删除)、识别并处理异常值,以及标准化数据格式。
3. 特征选择的难点
- 难点:从众多特征中选择与票价预测最相关的特征可能较为困难,因为这需要对数据有深入的理解。加之不同景点所坐落的地理位置还受到气候、经济、政治和人文等多方面因素的影响,这些方面都会影响游客的选择。
- 解决方法:通过探索性数据分析(EDA)来识别关键特征,如景区等级、评论数和评星等。此外,可以使用相关性分析和特征重要性评估来辅助特征选择。
4. 数据转换的难点
- 难点:将非数值型数据转换为数值型数据,以便机器学习模型能够处理。进行one-hot编码对非数值型的数据转换为数字串的格式来代表类别需要划分好区间,这对与景点的具体坐落位置信息提取挑战较大。
- 解决方法:应用One-Hot编码对分类变量进行转换,如城市和地址字段。对于有序数据,如景区等级,可以直接转换为数值型。
5. 数据分析的难点
- 难点:在分析过程中,难以发现数据中的潜在模式和关联,毕竟特征维度较多,且很多特征间其实明显没有太直接的关联性。
- 解决方法:利用可视化工具(如matplotlib和seaborn)来探索数据分布和关系。通过绘制图表,如条形图、直方图和热力图,可以更直观地理解数据。
6. 数据价值提炼的难点
- 难点:从大量数据中提炼出高价值信息,以支持决策和预测,需要深入的分析和洞察,从数据的体量上来看这也是个不小的挑战。
- 解决方法:结合业务知识和数据分析结果,识别关键指标和趋势。例如,通过分析评论数与票价的关系,可以提炼出影响票价的关键因素。
7. 数据分析过程中的反思
- 难点:在分析过程中,遇到预期之外的数据特性或分析结果,印象深刻的是在分析评论数前10的5A景点得到的结果:个别5A景点的好评度不是很高,由此扩展分析了所有的景点的评论数前10以求能找到更合理的解释。
- 解决方法:保持灵活性和开放性,对分析过程中的意外发现进行深入探究。例如,如果发现某个特征与预期的影响相反,应进一步分析其原因,并考虑是否需要调整模型或引入新的特征。
综合考虑,决策树和梯度提升树在本项目中表现相似,均优于随机森林。这可能是因为随机森林的参数设置不够优化,或者是因为数据预处理步骤未能充分提取出对票价预测有用的特征。未来的工作将集中在进一步优化模型参数和改进数据预处理步骤,以提高模型的预测准确性。同时,还应该尝试其他机器学习算法,如支持向量机或神经网络,以探索是否有更适合本项目的模型。