一、选题背景
随着我国经济、科技的不断发展和人民生活水平的不断提高,旅游逐渐成为社会的主要经济部门。旅游这项活动在伴随着经济社会的发展同时应运而生,它本质上是一种社会文化生态环境现象,对于我国来说,旅游影响着很多城市在许多方面发展。在旅游热中,城市成为支撑现代旅游的旅游目的地和现代旅游的支撑点,而旅游城市就是城市和旅游业发展到相当阶段水平的产物。旅游业前景更加开放,但同时也将导致更激烈的竞争,而竞争的本质就是制定价格的竞争。因此,对一个城市的旅游业来说,研究和调价对于保持市场竞争力特别重要,越来越多人意识到,它有可能决定一个景区乃至一个旅游城市的繁荣与否。现在的大环境,人人都有智能机,人人都会上网,人们开始习惯使用网络代替进行一切不方便的操作,当然旅游时也倾向选择更加便捷的在线预订方式,若是不继续完善网上预订平台的定价,势必将被愈渐激烈的市场遗忘甚至淘汰。
如今,各大在线预订平台例如携程、飞猪、去哪儿旅行、美团等使用度非常高,用户范围也非常广。如果能通过网站的信息对旅游景点价格实现预测,那么,各旅游景点便可以根据预测信息实时调整自己的策略,在一定程度上提高客户的预订率和旅游业市场占有率。
二、大数据分析设计方案
1.数据采集的概念和方法,本设计对去哪儿旅行网站中丽江、南京、临沧、南昌等旅游城市的全部景点信息爬取。
2.数据预处理技术,本设计中爬行数据的预处理过程。
3.对预处理后的变量自身分布和变量之间的关系进行可视化分析。
三、数据分析步骤
1.数据源 https://piao.qunar.com
本报告所选取的目标数据是去哪儿旅行网站中旅游城市,通过搜索关键字确定所对应的数据页进行采集。
2.数据清洗
此次方案使用通过爬虫爬取技术采集到的数据。在数据收集阶段已经得到“data.xls”并且保存起来。
导入库
导入了数据处理、需要的库:Pandas库、NumPy库、Matplotlib库。matplotlib是可以和numpy一起使用的图片库。Seaborn是基于matplotlib的图形可视化中使用的Python包。
读取数据集
在导入预处理需要的库之后,读取“data.xls”数据集,为了数据显示界面整洁,删除“id”这一列再输出。数据属性包括景点的名称、星级、评分、销售量、省市区、坐标、介绍、是否免费、地址等
部分数据
3.数据预处理
在所有列中,除了景点名称、id、地址,其他属性都存在或多或少的数据缺失,缺失程度不一。
由于讨论的是价格与其他因素的关系,所以先清洗价格,针对数值型变量的缺失值,采用将删除缺失值所在行的方式。
4.数据可视化
景点价格分布
直方图看到在所有数据中,景点价格主要集中在0-250这一区间,还存在极少部分500以上的数据。整个分布大致上呈现出正偏态分布。
偏度和峰度分别为42.183834和2137.223113。通过计算峰度值和偏度值,对数据进行分析对该变量的分布情况掌握更加精确。
对数变换后的价格分布直方图
景区门票销量直方图
景点门票价格与门票销量线性关系
选择使用散点图来分析价格与销售量之间的线性关系,散点图直接显示了两个变量之间是否存在相关性以及相关程度。这里我们将“price”作x轴,“sale”作y轴。
通过前面的描述性统计已经得知“price”的0值数量还是有挺多的,绘制结果图更加直观的佐证了这一点,通过观察可以发现数据多集中在图像中间部分。除此之外可以看出销售量与景点价格没有非常明显的线性相关关系,但并不能说明两者毫无关系。
景点门票价格与景点评分线性关系
“评分”这一变量删除缺失值后作x轴,价格作y轴,制作散点图,绘制结果可以直观看出景点的价格与评分之间存在一定的关系。散点图以直观醒目的优点反映出变量与变量之间的相关关系,缺点是还不够精确。
成对散点图
对角线上是分布直方图,它显示了每个属性的数据分布;其余的是不同属性之间的散点图,显示了两个属性之间的相关性。通过观察散点图可以发现,景区的得分与景区的销量和价格之间存在一定程度的正相关关系。
相关系数热力图
sns.heatmap热图是用来绘制热图的函数。热图是相关系数的可视化。利用不同的颜色值来区分不同的数字范围,达到可视化的目的。
热图中所有对角线的颜色是相同的,相关系数是1,因为对角线显示了变量本身和变量本身的关系,这是确定的。因为相关系数矩阵是对称的,所以热图的颜色值也是对称的。观察非对角线的颜色值,可以发现销售量与价格的相关系数大于0,但接近0,属于弱相关。另外,得分与销量的相关系数在0.3-5之间,属于中等相关。经纬度与得分的相关系数小于0,为负相关。销量与维度的相关系数大于0,但接近0,相关性较弱。经纬度呈正相关和中相关。通过观察价格与其他数值变量的相关系数,可以发现价格与其他变量的相关性较弱。
5.完整代码
import numpy as np
import pandas as pd
import os
import matplotlib.pyplot as plt
plt.style.use('ggplot')
import seaborn as sns
sns.set_style('whitegrid')
import warnings
warnings.filterwarnings('ignore')
os.chdir('D://')
os.getcwd()
data = pd.read_excel("D:\py\data.xlsx")
data=data.drop(["id"],axis=1)
data.head() #根据位置返回对象的前5行。
data.info()#显示所有信息
#data.isnull().sum()
#data
data1= data[data['price'] != 0.00]
#data1= data[data['score'] != 0.00]
#data1
data1.describe()
#
import numpy as np
import pandas as pd
import os
import matplotlib.pyplot as plt
plt.style.use('ggplot')
import seaborn as sns
sns.set_style('whitegrid')
import warnings
plt.figure(figsize=(18, 9))
sns.set()
sns.set_context("notebook", font_scale=1,
rc={"lines.linewidth":2 })
sdisplot_loan = sns.distplot(data1['price'])
plt.xticks(rotation=90)
plt.rcParams['font.sans-serif']=['SimHei']
plt.rcParams['axes.unicode_minus'] = False#解决图例中文乱码以及坐标负号显示
plt.xlabel('景区价格')
plt.title('景区价格分布情况')
sdisplot_loan.figure.savefig("价格分布直方图")#将当前图表保存到文件
plt.show()
#价格分布的峰度与偏度
print("Skewness:%f "% data1['price'].skew())
print("Kurtosis:%f "% data1['price'].kurt())
import numpy as np
import pandas as pd
import os
import matplotlib.pyplot as plt
plt.style.use('ggplot')
import seaborn as sns
sns.set_style('whitegrid')
import warnings
plt.figure(figsize=(18, 9))
sns.set()
sns.set_context("notebook", font_scale=1,
rc={"lines.linewidth":2 })
sdisplot_loan = sns.distplot(np.log2(data1['price']))
plt.xticks(rotation=90)
plt.rcParams['font.sans-serif']=['SimHei']
plt.rcParams['axes.unicode_minus'] = False
plt.xlabel('景区价格')
plt.title('景区价格分布情况')
sdisplot_loan.figure.savefig("对数变换后的价格分布直方图")
plt.show()
import numpy as np
import pandas as pd
import os
import matplotlib.pyplot as plt
plt.style.use('ggplot')
import seaborn as sns
sns.set_style('whitegrid')
import warnings
plt.figure(figsize=(18, 9))
sns.set()
sns.set_context("notebook", font_scale=1,
rc={"lines.linewidth":2 })
sdisplot_loan = sns.distplot(np.log2(data1['sale']))
plt.xticks(rotation=90)
plt.rcParams['font.sans-serif']=['SimHei']
plt.rcParams['axes.unicode_minus'] = False
plt.xlabel('景区门票销量')
plt.title('景区门票销量分布情况')
sdisplot_loan.figure.savefig("销量分布直方图")
plt.show()
data2 = pd.read_excel("D:\py\data4.xlsx")
import numpy as np
import pandas as pd
import os
import matplotlib.pyplot as plt
plt.style.use('ggplot')
import seaborn as sns
sns.set_style('whitegrid')
import warnings
#数据转换
price = np.log2(data2['price'])
sale = np.log2(data2['sale'])
# 散点图
plt.scatter(price, sale)
plt.ylabel("sale")
plt.xlabel("price")
plt.savefig('销量与价格的关系散点图.png')
# 展示图标
plt.show()
#data2
import numpy as np
import pandas as pd
import os
import matplotlib.pyplot as plt
plt.style.use('ggplot')
import seaborn as sns
sns.set_style('whitegrid')
import warnings
price = np.log2(data2['price'])
score = data2['score']
# 散点图
plt.scatter(price, score)
plt.ylabel("price")
plt.xlabel("score")
plt.savefig('评分与价格的关系散点图.png')
# 展示图标
plt.show()
sns.set()
cols = ['score', 'price', 'sale','category']
sns.pairplot(data2[cols])
plt.show()
plt.savefig('成对散点图.png')
data3=data2.drop(["Unnamed: 0","free","id","price1","sale1"],axis=1)
corrmat=data3.corr()
f,ax=plt.subplots(figsize=(12,9))
sns.heatmap(corrmat,vmax=1.15,square=True)#绘制热力图
plt.show()
plt.savefig('热力图.png')
# 特征选择,经纬度的选择
jing = []
wei = []
for item in data2['point']:
jing.append(float(item.split("\t")[0]))
wei.append(float(item.split("\t")[1]))
data2['jing'] = jing
data2['wei'] = wei
data2['sale1'] = np.log2(data2['sale'])
data2['price1'] = np.log2(data2['price'])
full_X = data2[['score','sale1','jing','wei','category']]
full_X.head()
#原始数据集:特征
source_X = full_X
feature = pd.get_dummies(full_X)
source_X = feature
#原始数据集:标签
source_y = data2.loc[:,'price1']
#print(source_X)
#print(source_y)
source_X.head()
import numpy as np
import pandas as pd
from matplotlib import pyplot as plt
from sklearn import tree, linear_model
from sklearn.model_selection import train_test_split, cross_val_score
from sklearn.metrics import r2_score, mean_squared_error
from sklearn.utils import shuffle
from sklearn.linear_model import LinearRegression
#建立模型用的训练数据集和测试数据集
train_X, test_X, train_y, test_y = train_test_split(source_X, source_y, train_size=0.9)
model = LinearRegression()
model.fit(train_X , train_y)
LinearRegression(copy_X=True, fit_intercept=True, n_jobs=None, normalize=False)
#训练集准确度
train_ACC = model.score(train_X, train_y)
#print(train_ACC)
#准确度
test_ACC = model.score(test_X, test_y)
print(test_ACC)
import numpy as np
import pandas as pd
from matplotlib import pyplot as plt
from sklearn import tree, linear_model
from sklearn.model_selection import train_test_split, cross_val_score
from sklearn.metrics import r2_score, mean_squared_error
from sklearn.utils import shuffle
train_X, test_X, train_y, test_y = train_test_split(source_X, source_y, train_size=.9, random_state=200)
from sklearn.metrics import make_scorer
#计算平方根
def rmsle(y, y_pred):
return np.sqrt((((np.log1p(y_pred)-np.log1p(y)))**2).mean())
#均方误差
scorer = make_scorer(mean_squared_error)
#进行交叉验证
def rmse_cv(model, X, y):
return (cross_val_score(model, X, y, scoring = scorer)).mean()
# 建立Lasso进行alpha选择的范围
# 形成10为底的指数函数
# 10**(-10) -10**(-2)
alpha_range = np.logspace(-10,-2,200,base=10)
#print(alpha_range)
from sklearn.linear_model import LassoCV
lasso_ = LassoCV(alphas=alpha_range,cv=5).fit(train_X, train_y)
# 查看最佳正则化系数
best_alpha = lasso_.alpha_
print(best_alpha)
#变量重要性
#拟合Lasso模型
model_lasso = linear_model.Lasso(alpha = 0.001, max_iter = 5000).fit(train_X, train_y)
coef = pd.Series(model_lasso.coef_, index = train_X.columns).sort_values()#系数排序
imp_coef = pd.concat([coef.head(5), coef.tail(5)])
imp_coef.plot(kind = 'barh')
plt.rcParams['font.sans-serif']=['SimHei']
plt.rcParams['axes.unicode_minus'] = False
plt.title('coefficient in the model')
plt.show()
plt.savefig('变量重要性')
#计算均方根对数误差
p_pred = np.expm1(model_lasso.predict(test_X)) #测试集的预测值
# -*- coding: utf-8 -*-
os.getcwd()
import requests
import os
import random
import time
import requests
import pandas as pd
PLACE_EXCEL_PATH = '丽江.xlsx'
def path_spider_place(keyword):
'''
批量爬取去哪儿景点
:param keyword: 搜索关键字
:return:
'''
# 写入数据前先清空之前数据
if os.path.exists(PLACE_EXCEL_PATH):
os.remove(PLACE_EXCEL_PATH)
for i in range(1, 2): # 发现有39页,或者可以判断爬取数据返回值
print(f'正在爬取{keyword} 第{i}页')
spider_qunaer(keyword, i)
# 设置一个时间间隔
time.sleep(random.randint(2, 5))
print('爬取完成')
def spider_qunaer(keyword, i):
url = f'http://piao.qunar.com/ticket/list.json?keyword={keyword}&page={i}'
kv = {
'Accept': 'application/json, text/javascript, */*; q=0.01',
'Accept-Encoding': 'gzip, deflate',
'Accept-Language': 'zh-CN,zh;q=0.9',
'Connection': 'keep-alive',
'Cookie': 'QN1=000030002eb41a2c64507881; QN300=organic; QN205=organic; QN277=organic; csrfToken=guhvJ2UJ1S4JkRAEVVNKXqbexa4jr5lt; QN57=15696544141780.5581713141626528; _i=ueHd8gCnQ4-Xw7_X4lIWdXKBeRXX; _vi=XP2sC7e0MzBdRRW7FdRZOsOPXwsELGnAOhxlvjUk0axSb0VgxK5ed_tCVXy7Do_Hs18hUDMbEp0KJlk3szcH4x4NMsCp8FOa-NNtb_5lNw863q5BUECid5aLk0CTpYlYxknlalntWSAeee7jg11ixyFGiBhcBJQEVtrTCt757OCe; QN269=8BC04422E1BE11E9BCEAFA163E89CFE1; Hm_lvt_15577700f8ecddb1a927813c81166ade=1569654418; fid=10739e17-bb75-4c11-ba8d-2ab6b55fa9e8; QN63=%E5%9B%BD%E5%BA%86%E6%97%85%E6%B8%B8%E6%99%AF%E7%82%B9%7C%E5%9B%BD%E5%BA%86%E5%8E%BB%E5%93%AA%E5%84%BF; JSESSIONID=A946FF2222DB69A818A7AE88D0919C70; QN267=07847690024d33702e; QN58=1569654414177%7C1569654475972%7C4; Hm_lpvt_15577700f8ecddb1a927813c81166ade=1569654476; QN271=6211ab7c-59f8-442d-9234-ef456f77452b',
'Host': 'piao.qunar.com',
'Referer': 'http://piao.qunar.com/ticket/list.htm?keyword=%E5%9B%BD%E5%BA%86%E6%97%85%E6%B8%B8%E6%99%AF%E7%82%B9&page=2',
'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/77.0.3865.90 Safari/537.36',
'X-Requested-With': 'XMLHttpRequest'}
try:
result = requests.get(url, headers=kv)
result.raise_for_status()
place_list = get_place_info(result.json())
save_excel(place_list)
except Exception as e:
print(e)
def get_place_info(response_json):
'''
解析json,获取想要的字段
:param response_json:
:return:
'''
place_list = [] # 定义一个列表,等会将景点等信息都存到列表中
sight_list = response_json['data']['sightList']
for sight in sight_list:
goods = {
'id': sight['sightId'], # 景点id
'name': sight['sightName'], # 景点名称
'star': sight.get('star', None), # 星级,使用get获取,防止触发keyerror
'score': sight.get('score', 0), # 评分
'price': sight.get('qunarPrice', 0), # 价格
'sale': sight.get('saleCount', 0), # 销量
'districts': sight.get('districts', None), # 省,市,区
'point': sight.get('point', None), # 坐标
'intro': sight.get('intro', None), # 简介
'free': sight.get('free', True), # 是否免费
'address': sight.get('address', None) # 具体地址
}
print(type(goods))
place_list.append(goods)
return place_list
def save_excel(place_list):
'''
将json数据存储为excel文件
:param place_list:
:return:
'''
# pandas没有对excel追加模式,只能先读后写
if os.path.exists(PLACE_EXCEL_PATH):
df = pd.read_excel(PLACE_EXCEL_PATH)
df = df.append(place_list)
else:
df = pd.DataFrame(place_list)
writer = pd.ExcelWriter(PLACE_EXCEL_PATH)
df.to_excel(excel_writer=writer,
columns=['id', 'name', 'star', 'score', 'price', 'sale',
'districts', 'point', 'intro', 'free', 'address'],
encoding='utf-8', sheet_name='去哪儿热门景点')
writer.save()
writer.close()
if __name__ == '__main__':
path_spider_place('丽江')
四、总结
随着经济和信息技术的发展,交通越来越方便了。因此,人们的需求不仅仅在日常生活中发生了变化,而且在娱乐业中也发生了变化,旅游业就是很典型的代表。随着开发和改进主要互联网站的在线预订平台,越来越多的人希望选择最合适的在线预订方法,然而在这一系列变化的背后,针对在线预订平台中的景点价格的分析与预测却相对来说比较匮乏。基于此背景,对景区价格预测进行研究,根据网站页面上的信息实现景区价格预测:使用网络爬虫技术获取了去哪儿旅行网中旅游城市的所有景点的真实数据,包括景点名称、景点价格、景点点评、评分等。分析了这些数据的分布及之间的关系以及景区定价的主要特点。经过一系列的可视化分析,了解数据的基本情况。本文基于去哪儿旅行网站中旅游城市的景点信息研究了景点价格的预测问题,取得了一些成果,但仍然存在很多不足之处。对于影响景点价格高低的因素有很多,获取的却不多,只从评分销量等影响因素来讨论过于局限。
标签:数据分析,plt,score,price,train,景点,import From: https://www.cnblogs.com/zzl-328/p/17001290.html