网络爬虫与机器学习算法在城市分析中的应用(python)


互联网的发展使得搜索引擎成为了人们获知信息的重要渠道之一,而如何从网上的海量数据中探寻到我们需要的数据成为了一个重要的技能,最近对于即将毕业的大学生来说正是需要考虑选择定居城市的时期,成都市地处西南经济中心,人口聚集度高,是关注的重点城市,所以我便利用爬虫技术爬取成都市的相关信息,进行美食数据可视化,并用监督学习算法(线性回归,KNN)和非监督学习算法(神经网络)进行租房价格的预测。


成都美食数据分析

1.1美食数据获取

爬虫过程
网络爬虫是一种按照一定的规则,自动地抓取网页上的信息的程序或者脚本,成都的美食信息我们采用从美团网上爬虫获取,因为美团网是动态网页,需要通过解析接口或用Selenium爬取,所以这里我使用通过解析接口的方法来爬取数据。

我们定义了三个python程序来爬取成都美团的店铺信息:

①run.py
爬虫运行的主要启动程序,调用spider.py里面的MeituanSpider类进行爬虫。

②settings.py
爬虫全局变量设置的程序,设置爬虫的 HTTP请求标头,这里我设置了两个请求头,避免其中一个失效,设置请求头的目的是为了防止美团网站发现爬虫而封掉ip,导致爬虫失败。爬虫完毕后数据存储在meituan_ChengDu_Restaurants2文件里。

③spider.py
利用parse函数发送get请求,用网页真实的URL,得到HTML页面,然后用关键词搜索进行网页信息的抓取,得到如’店铺名称’,'页面id’等我们所需的信息。其中利用__init__的函数接受参数保存数据的格式,并将爬虫获取到的数据保存为为csv的格式。最后使用run函数来启动爬虫,开始爬取商家信息,设置爬取的时间间隔,因为如果爬取数据的操作过于频繁的话,会被网页认为是爬虫而被禁掉。为了让代码看起来更加的简洁,上述的函数采用封装编码思想,都封装在一个类中,类名为 MeituanSpider,实现了代码的复用。

爬虫完成后获得了4448个店铺信息,数据如下图所示:
在这里插入图片描述
补充内容:爬虫程序,这里最重要的一步是要爬取网页的真实url(http://api.meituan.com/group/v4/deal/select/city/59/cate/1 sort=solds&hasGroup=true&mpt_cate1=1&offset={0}&limit={1})
参数:59—城市id(59代表成都)
limit:每页的店铺数量(我自定义的是30)
offset:翻页参数

1.2美食数据处理

爬虫得到29个属性,但我们探寻数据信息不需要这么多属性,所以我们选择其中几个属性并查看选择后的数据信息:
在这里插入图片描述
在这里插入图片描述
虽然有些属性有缺失值,但对我们后续数据可视化处理影响不大,不做处理。
后续为了查看各区美食数量排名添加新属性(区)

df['区'] = df['详细地址'].str.findall('(.*?区)').str.get(0)

在这里插入图片描述

1.3 美食数据可视化

店铺名称词云图

通过Python中的Jieba模块来实现分析过程中对词频和关键词的统计。Jieba分词是一个中文分词组件,将“店铺名称”属性利用jieba.analyse.extract_tags函数提取关键词的文本,并返回每个关键词出现的权重,分析出各种词出现的频率后使wordcloud 模块绘制词云图。可以看出,火锅、自助等出现的概率大,说明成都地区的饮食习惯偏爱辛辣的食物。这对于爱吃辣的我来说是个吸引点,选择饮食习惯相同的地区可以增加定居者的幸福感。
在这里插入图片描述
图1-1 关键词占比图
在这里插入图片描述

图1-2 店铺信息词云图

美食种类占比图
统计”类别“中不同餐厅的食物种类的数量,画出美食种类的占比的直方图,从图中可见四川火锅店铺数量是最多的,多达1253家店铺与火锅有关,符合成都这个城市的特点——爱吃火锅,而排名前十的食物中有4个就与自助相关的,看来自助餐还是很受广大成都百姓的欢迎的。
在这里插入图片描述
图1-3 美食种类直方图

地区餐厅直方图

画出不同区中的餐厅数量占比渐变值方图,从图可知武侯区和锦江区餐厅最多,新津区的最少,之后选择租房的地区可以优先选择武侯区,尽量避开数量排名靠后的几个区。
在这里插入图片描述
图1-4 地区餐厅数量直方图

地区人均价格折线图

新津区的人均价格最高,且餐厅数量较少,所以租房区域先排除新津区,武侯区虽然餐厅数量多,但人均价格也高,所以还需考虑一下,温江区虽然餐厅数量少但人均价格较低,纳入租房选择区域名单。
在这里插入图片描述
图1-5 地区人均价格折线图

成都美食据集地图

pyecharts 模块中的 Geo 地理坐标系组件用于地图的绘制,支持在地理坐标系上绘制散点图,利用geo 函数画出将上述的餐厅数量在成都地图上的分布,可见大部分餐厅都集中在成都的中心区域,而周围区域的餐厅数量较少,且很分散。
在这里插入图片描述

成都租房数据分析

2.1租房数据获取

利用八爪鱼进行租房数据的获取得到的数据很干净,不似爬虫那样在爬取数据的前期就需要考虑数据的清洗,八爪鱼获取的数据标准、规范,唯一的缺点是爬取速度过慢,这里我爬取了1420条链家出租房的数据,花了5个多小时。数据存储在“链家租房房源信息采集爬虫.csv”文件中。

2.2 租房数据预处理

缺失值处理

读取“链家租房房源信息采集爬虫.csv”文件中的数据后,打印出各属性的缺失值的个数,发现除了“地铁”属性外其他属性缺失值都很少,“地铁”属性缺失值较多,所以首先去除“地铁”属性,然后寻找各属性缺失值进行删除,还余1418个数据,说明只有两个数据有缺失值,将这两个缺失值数据删除。
核心代码:

jieba.analyse.extract_tags
data=pd.read_csv('C:/Users/easterding/Desktop/租房价格预测/链家租房房源信息采集爬虫.csv',encoding='gbk')
data.isnull().sum()

在这里插入图片描述
图2-1 各属性的缺失值

#指定删除某列的缺失值
df2 = df.dropna(subset=['价格','租赁方式','房型','面积','朝向','位置'])
df2.isnull().sum()

在这里插入图片描述

图2-2 缺失值处理后各属性的缺失值

数据格式规范化
我们得到的数据还是糙数据,为了方便将数据带入模型中进行训练,还需要经过繁杂的数据预处理过程,将数据转化为标准的数字数据。我们主要考虑’价格’,‘租赁方式’,‘房型’,‘面积’,‘朝向’,'位置’这几个属性对租金的影响,所以要对这几个数据进行清洗。

  • “面积”属性
    “面积”属性的原数据里有m²,而需要的只有面积的数字信息,所以剔除m²,并将数据转换成整数型数据。
df2['面积'] = df2['面积'].str.replace('㎡', '').astype(dtype='int')
  • “房型”属性
    “房型”属性数据格式是xx室xx厅xx卫,它里面包含着室、厅、卫三个重要的数据属性,我们将这三个属性提取出来作为新属性。
df2[['室','厅','卫']] = df2['房型'].str.extract(r'(\d+)室(\d+)厅(\d+)卫')
df2['室'] = df2['室'].astype(float)
df2['厅'] = df2['厅'].astype(float)
df2['卫'] = df2['卫'].astype(float)
  • ”价格”属性
    “价格”属性格式杂乱无章,选择用正则方法提取我们需要的价格数字部分。
df2['价格'] = df2['价格'].map(lambda str: re.findall(r'\d+', str)[0]).astype(dtype='int')
  • “朝向”属性
    该属性我们只需要朝向的方位,不需要前面的“朝向:”,所以直接将“朝向:”字段替换成空。
df2['朝向'] = df2['朝向'].str.replace('朝向:', '')
  • “位置”属性
    “位置”属性里面包含着很重要的一项——区域,众所周知区域这一因素对房租的影响很大,不同区的房租价格之间差距很大,这里用for循环将字符串中的区域属性提取出来。
word=list(df2['位置'])     #字符串转列表
l = len(word)
alist = []
for i in range(l):
   word[i] = word[i][2:4]
   alist.append(word[i])
df2['区'] = alist
df2.drop(['位置'], axis=1, inplace=True)

在这里插入图片描述
图2-3 上述操作处理后的数据
利用describe()函数查看此时数据的基本信息:
在这里插入图片描述

由上表可知成都租房价格每月大概在2157左右,相比于北上广深这种一线城市,租房压力真的是小了很多,房子的面积在62平方米左右,如果一个人居住的话是刚好合适的,2个卧室,1个客厅,1个卫生间,对于独居的人来说也够了。

  • 哑变量处理
    将非数值型数据转化为数值型数据,对类目型的特征因子化,对“朝向”,“租赁方式”,“区”这几个属性进行处理,做这步处理的原因在于许多算法模型建模需要输入的特征值都要为数值型,所以对于非数值型的数据值我们应当进行特征因子化。
df2_direction = pd.get_dummies(df2['朝向'],prefix= '朝向')
df2_zuling = pd.get_dummies(df2['租赁方式'],prefix= '租赁方式')
df2_area = pd.get_dummies(df2['区'],prefix= '区域')

在这里插入图片描述

图2-4 哑变量处理后的数据

数据集的划分

将数据带入模型前我们需要将数据分成训练集和测试集,训练集数据用来训练模型,得出输入和输出间的关系,测试集数据用来评估模型的性能,好的数据集划分能够提高模型的收敛速度,如果数据集没有划分好将会影响模型的设置。其中需要注意的是数据集的划分还需要由数据数据量的大小来决定,对于小规模的数据集我们可以采用8:2划分原则,因为我们这里是小数据集,所以这里使用sklearn的train_test_split函数随机划分数据集,80%的数据用于模型的训练,20%的数据用于模型的测试,但如果数据量到达千万以上可以采用98:2的划分方法。

数据归一化

从上面的数据可以看出来不同属性间的数值差距较大,而模型训练中各属性间差距太大会造成收敛速度下降,严重的可能还会导致不收敛,而归一化处理可以加速模型的的收敛速度,所以我们利用 sklearn的StandardScaler函数进行数据的归一化处理。

from sklearn.preprocessing import StandardScaler
std_y = StandardScaler()
y_train = std_y.fit_transform(y_train.values.reshape(-1, 1))
y_test = std_y.fit_transform(y_test.values.reshape(-1, 1))  

值得一提的是,因为我们后期需要带入真实数据对想要的房子进行房租的预测,而数据归一化会导致房租的价格发生错误,所以在模型的性能预测中使用数据归一化,得到模型的性能分数,而进行房价预测处理时不使用数据的归一化,以得到正确的房租预测数据。

2.3 预测租房价格模型构造

多元线性回归模型

(1)算法简介
线性回归是一种预测性的建模技术,研究因变量和自变量间的关系,常用于预测分析,目标是使得预测值和真实值间差异最小,线性回归通过构建损失函数,来求解损失函数最小时的参数w和b。在sklearn中将线性回归定义为“普通最小二乘法”,可以直接调用sklearn库中的 LinearRegression函数实现, 目的就是使得观测值和预测值间的残差平方和最小。
本案例影响租房价格的因素有多个,所以是多元线性回归。
(2)模型构造

1.从sklearn库中引入线性回归模型
from sklearn.linear_model import LinearRegression  
2.线性回归模型训练
linear = LinearRegression()
lr_model = linear.fit(x_train,y_train)
3.将斜率、截距打印出来
print(lr_model.intercept_, model.coef_)

4.打印出模型的回归系数
pd.DataFrame({"columns":list(x_train.columns),"coef":list(lr_model.coef_.T)})

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

从上表可见朝向和区域对房租的影响都很大。

k近邻分类(KNN)算法模型

(1)算法简介
k近邻法是一种基本分类与回归方法,是监督学习算法,可用于回归。该算法实现过程为存在一个样本数据集合,该样本数据集的属性已知,且其中每个数据都已知所属的分类。而对不知道分类的待分类数据,将待分类数据的每个属性属性与样本集中数据对应的属性比较,后算法提取样本中最相似的对象的分类标签,通常情况下我们只选择样本数据集中前k个最相似的对象数据,k一般是不大于20的整数,根据选择的这k个数据的属性,判断未分类数据的类型。
(2)模型构造
为了模型更好的泛化性能我决定优化模型,因为这个训练集是小数据集,所以这里我选用的调参方法是gridSearchCV(网格搜索),网格搜索法可以自动调参,返回最优参数,可以看到返回的最优参数如下:
在这里插入图片描述

调参的核心代码:

scoring_fnc=make_scorer(accuracy_score)
kfold=KFold(n_splits=10)
pram_grid={'n_neighbors': range(1,20)}
clf=GridSearchCV(knn, pram_grid, scoring_fnc, cv=kfold)
将训练数据带入调完参数的knn模型中,得到训练好的模型clf:
clf.fit(x_train, y_train.astype('int'))

神经网络模型

(1)算法简介
Keras是一个高层神经网络库,它核心的数据结构是模型,模型是一种组织网络层的方式。Keras中主要的Sequential模型是一系列的网络层按照顺序构成的栈。
利用keras库里的Sequential模型构建神经网络,Sequential模型通过堆叠多层,构建出深度神经网络,它为最简单的线性构造顺序,从头到尾进行结构的构造,实现了多个网络层的线性堆叠。
(2)模型构造
用Sequential模型添加图层,创建一个Sequential模型,采用线性激活的全连接层(Dense)。它先封装了输入值(x)去乘以权重(w),然后再加上偏置(b),进行线性激活以产生输出,这里定义了一个有120个节点,使用relu(ReLU不但可以克服梯度消失的问题并且还能够加快模型的训练速度,如果克服了梯度消失问题,训练速度也会相应地加快)为激活函数的神经层,因为模型需要知道它所期待的输入的尺寸,出于这个原因,序贯模型中的第一层,需要接收关于其输入尺寸的信息,后面的各个层则可以自动地去推导出中间数据的尺寸,所以不需要为每个层都指定此参数,这样才能让数据顺利地进入网络。
在这里插入图片描述

图2-5 神经网络模型形式

接下来我们利用RMSprop优化器来训练模型,RMSProp是有效且实用的深度学习网络优化算法,RMSProp增加了一个衰减系数来控制历史信息的获取多少,它因为平缓,所以历史梯度平方和较小,对应学习下降的幅度较小,使得陡峭的方向变得平缓,从而加快训练速度,我觉得这点和梯度下降算法有异曲同工之处。
核心代码:opt = keras.optimizers.RMSprop(lr=0.0001, decay=1e-6)
在训练模型之前,我们需要配置学习过程,使用compile函数完成,该函数接收3个参数:

  1. 优化器(optimizer):这里采用的是现有优化器字符串标识符rmsprop。

  2. 损失函数(loss):模型试图最小化的目标函数,它是平均绝对误差(meanabsolute error(MAE ),MAE是预测值与目标值之间差值的绝对值然后求平均,MAE损失比起MSE对于局外点更鲁棒。

  3. 评估标准 metrics:MAE得分

2.4 模型性能评估

多元线性模型
在这里插入图片描述

画出模型的学习曲线
自定义了plot_learning_curve函数画出学习曲线,详细情况请参考”成都房租.py”文件。
在这里插入图片描述
图2-6 多元线性模型学习曲线

为了判断多元线性回归模型的性能画出学习曲线,来判断是否过拟合,从上面曲线可以看出,模型在训练集和测试集上的得分都在0.6左右,两者平均得分差距仅有0.08,当训练样本数在1000以上时,测试集与训练集得分相差较小,两条曲线中间间隔不大,而我们的训练数据多与1000个,所以该模型不存在过拟合的问题。
Knn模型
在这里插入图片描述
神经网络(cnn)模型
该模型用了1134个训练数据和284测试数据,进行50次迭代后,得到的结果如下:
在这里插入图片描述

2.5 根据个人要求进行房租的预测

我想要预测如果我要租一个面积为71平方米,3室1厅1卫 ,朝向为东南,在温江区,租赁方式为整租的房子需要多少钱,将上述数据带入多元线性回归模型中,得房租价格为1359.98334672元,带入knn模型中,得房租价格为2500元,
带入神经网络模型中,得房租价格为1924.9294元。可见我租房的预算定在2000元左右就可以了。

2.6 结论

从上面模型的得分来看knn算法和神经网络模型的性能都较好,而多元线性回归就差了许多,我猜想是因为数据的维度较大而数据量较小而影响了多元线性算法的拟合性能,数据量小这一缺点也使得knn算法模型在训练集和测试集上的得分差距较大,在训练集上的得分高于测试集上的,神经网络算法相比于前两种算法受到数据量的影响较小,在训练集和测试集上得分差距不大,神经网络模型学习和构建复杂关系的能力很强,更好地模拟异方差性,它具备学习数据中隐藏关系的能力,而不在数据中强加任何固定关系,这在这个案例中非常有用。

总结与改进

3.1研究结论

本文爬取了美团和链家的数据进行一系列的数据分析处理,模型训练等操作,由成都美食数据的可视化可知成都市的饮食习惯偏辛辣,餐厅大多是火锅店,多聚集于武侯区,新津区的餐厅人均价格最高。后期通过3个模型的训练,带入我们想租房的信息,若想租到一个面积为71平方米,3室1厅1卫 ,朝向为东南,在温江区的房子房租价格大概在2000左右,总体来看成都市还是很适合能吃辣,且适合对房租价格敏感的人群居住。

3.2改进方面

①数据集
租房数据中的“房型”属性中包含着此房是否精装修,由生活经验来讲房子是否精装修对于房租价格是由一定影响的,精装修后的房租要高点,如果加上这一项房租判断的准确度应该有所提高。
“房源介绍”属性中还包含有是否可以随时入住、楼层是高楼层还是低楼层、车位、用水、用电、燃气、采暖的情况,这些都是影响房租价格的因素,后期改进可以将它们的信息提取出来用。
并且一个房子租金价格影响还有许多因素,在本案例中我只能尽最大的努力多带入一些影响因素,而其他一些被忽略的因素还需要进一步地收集并分析整理。
因为八爪鱼爬取数据的速度过慢,所以导致数据量较小,后续可以设计一个爬虫程序多爬取数据进行分析,在数据量到达一定程度后由模型带来的准确度差距的影响会小很多。
②网络搜索平台多样化
本文的数据来自于美团和链家,数据获取途径较少,数据质量层次不齐的,后期应多爬取多家网站数据(如房天下和大众点评),使得数据来源更丰富,数据数量更庞大,预测更加准确。
③选择的模型
本文只用了knn,线性回归,神经网络三个模型,后期可以增加决策树模型和svm模型等多种模型,使得获得的结果更加完善,并且为了了解为什么多元线性回归在案例中的性能较差,我翻阅资料后得知因为我们带入的数据特征间不是相互独立的,而最小二乘法则很注重特征项间的相关性,如果特征项间的相关程度较高的话就会导致“多重线性”,这样就使得我们的模型对于数据集的随机误差变得很敏感,导致模型的方差很大,所以模型的性能就没这么好了,后期我打算直接用python代码来实现回归拟合,而不直接调用LinearRgression函数。

*欢迎大家一起唠嗑玩耍,一起共同进步!!

  • 0
    点赞
  • 0
    评论
  • 4
    收藏
  • 一键三连
    一键三连
  • 扫一扫,分享海报

©️2021 CSDN 皮肤主题: 1024 设计师:白松林 返回首页
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、C币套餐、付费专栏及课程。

余额充值