数据获取
我们利用scrapy爬虫框架对去哪儿网对景点数据进行抓取,部分数据如下:
加载数据
import pandas as pd import numpy as np import matplotlib.pyplot as plt %matplotlib inline #加载数据 df = pd.read_csv("data.csv") df.head()
数据预处理
处理景区等级,只保留数字,且对没有等级的用0填充
df['level'] = df['level'].fillna(0) df['level'] = df['level'].apply(lambda x:0 if x==0 else int(x[0])) df.head(10)
处理热度,只保留数值,且小数点保留两位数字
df['hot'] = df['hot'].apply(lambda x:float("%.2f"%float(x.split(" ")[-1]))) df.head(10)
地区处理,将area拆分为省,市,区,并新增这三列数据,最后删除area这一列
df['province'] = df['area'].apply(lambda x:x.split("·")[0] ) df['city'] = df['area'].apply(lambda x:x.split("·")[1] ) df['mini_city'] = df['area'].apply(lambda x:x.split("·")[-1] ) del df['area'] df.head()
统计分析
统计销量最多的前10个景点
# 统计销量最多的前10个景点 num_top = df.sort_values(by='num',axis=0,ascending=False) num_top = num_top.reset_index(drop=True) plt.rcParams['font.sans-serif']=['Microsfot YaHei'] plt.rcParams['axes.unicode_minus']=False import seaborn as sns sns.set(font="SimHei") sns.set_context("talk") fig = plt.figure() sns.barplot(num_top['name'][:10],num_top['num'][:10]) plt.xticks(rotation=90) fig.show()
景区评级和省份的关系
#景区评级和省份的关系 df['level_sum']=1 var = df.groupby(['province','level']).level_sum.sum() var.unstack().plot(kind="bar",figsize=(35,10),stacked=False,color=['red','blue','green','black'])
统计人最多的前10个5A景区
#统计人最多的前10个5A景区 top_5A = df[df['level']==5].sort_values(by="num",axis=0,ascending=False).reset_index(drop=True) # top_5A.head() fit = plt.figure(figsize=(35,15)) # plt.pie(top_5A["num"][:10],labels=top_5A["name"][:10],autopct='%1.2f%%') sns.barplot(top_5A["name"][:10],top_5A["num"][:10]) plt.title("人数最多的10个5A景区") plt.xticks(rotation=90) plt.show()
统计人最少的前10个5A景区
#统计人最少的前10个5A景区 top_5A = df[df['level']==5].sort_values(by="num",axis=0,ascending=True).reset_index(drop=True) # top_5A.head() fit = plt.figure(figsize=(35,15)) # plt.pie(top_5A["num"][:10],labels=top_5A["name"][:10],autopct='%1.2f%%') sns.barplot(top_5A["name"][:10],top_5A["num"][:10]) plt.title("人数最多的10个5A景区") plt.xticks(rotation=90) plt.show()
数据的分布分析
景区等级分布
#景区等级分布 plt.figure(figsize=(20,1)) sns.countplot(y='level',data=df)
热度分布
# 热度分布 sns.distplot(df['hot']) plt.xticks(rotation=25)
价格分布
#价格分布 sns.distplot(df['price']) plt.xticks(rotation=25)
销量分析
#销量分析 sns.distplot(df['num']) plt.xticks(rotation=25)
将num进行分组并可视化
df['num_cut'] = pd.cut(df['num'],10) plt.figure() sns.countplot(y='num_cut',data=df)
建模
df =df[['name','level','hot','price','num','province','city','mini_city']] one_hot_df = pd.get_dummies(df[['province','city','mini_city']]) one_hot_df.head()
合并数据
df = df[['level','hot','price','num']] df = pd.merge(df,one_hot_df,left_index=True,right_index=True) df.head()
导包
from sklearn.model_selection import train_test_split from sklearn.ensemble import RandomForestRegressor from sklearn.metrics import mean_squared_error,mean_absolute_error
数据准备
X = df[df.columns.difference(['price'])].values Y = df['price'].values
划分数据集并训练模型
x_train,x_test,y_train,y_test = train_test_split(X,Y,test_size=0.3,random_state=6) rf = RandomForestRegressor(n_estimators=20,max_depth=7) rf.fit(x_train,y_train) pred = rf.predict(x_test) print(mean_squared_error(y_test,pred)) print(mean_absolute_error(y_test,pred))
模型结果预测
result_df = pd.DataFrame(np.concatenate((y_test.reshape(-1,1),pred.reshape(-1,1)),axis=1),columns=['y_test','y_pred']) result_df.head()