作者:汪喵行  R语言中文社区专栏作者

知乎ID:https://www.zhihu.com/people/yhannahwang

前言

上两节我们已经成功爬取了链家网的3w条数据,并且做了一些浅显的分析,那么这一节我们就利用机器学习,用除了房屋价格之外的其他因素(房屋高度/房屋面积等)来预测一套房子的价格。

objective:用除了房屋总价和房屋单位价格的其他因素,来预测房子的价格

用到的R包: splitstackshape / dummies / rpart / rpart.plot / RWeka / ggplot2

1.Data pre-processing

首先,根据我们的目标,我们需要预测的房屋总价是一个numeric的变量,具体的机器学习的方法有很多,比如简单的线性回归,回归树,模型树,甚至神经网络等等,这里具体介绍用regression tree和model tree来进行预测。这是因为对于比较复杂的数据,直接用建立一个全局线性规划模型有时候是不切实际并且费劲的,但是regression tree和model tree能够解决这个问题。

读取数据


1house_info <- read.csv("house_inf.csv",stringsAsFactors = FALSE)

由于之前数据里面还有一些需要处理的字符之类,在我们训练模型之前先把这些字符啊什么的都处理处理。

1content <- as.vector(house_info$house_level)2content_size <-as.vector(house_info$house_size) 3content <- gsub(".*平.*地上","",content)4content_size <- gsub("厅","",content_size)5level <- as.data.frame(content)6size <- as.data.frame(content_size)7house_info[7] <- level8house_info[3] <- size9# 相当于把house_level,house_size里面的字去掉以后再放回去

看一下output:


这里我们发现:

1.house_size这个变量其实可以拆成两个,变成bedroom和hall。因为要用“室”来切分这个变量,所以之前我没有把变量里这个字去掉。

2.第一列对于我们预测房价没有什么意义,所以也直接去掉。

3.第5列其实也可以看成一个除了房屋总价的因变量,所以也应该去掉。

1library(splitstackshape)2house_infos <- concat.split.multiple(house_info,"house_size", "室")3colnames(house_infos)[7:8] <- c("bedroom","hall")4house_infos <- house_infos[,-1]#去掉第一列5house_infos <- house_infos[,-4]#去掉第五列

看一下output:


Model要求的形式是每一个variable是numeric或者int形式的,所以这里有个麻烦就是我们的house_loc,这是一个类别型变量,很容易想到的办法是给予每个区一个数字代替,但是这样是错误的,因为model对于这个变量会区分大小。比如“黄浦区”是1,“长宁区”是12,那么因为12>1,我们的model会认为“长宁区”>“黄浦区”,但是这种情况并不正确,所以用这种方法,我们的model准确度会很差。

其实对于类别型变量有一种方法就是one-hot Encoding(独热变量),把类别型变量变成dummy variables,既能实现类别型变量的区分,也不会造成直接赋值带来的问题。

这里用R中的dummies package就可以实现:

1library(dummies)2#one-hot encoding on categorical variables3house_infosd <- dummy.data.frame(house_infos, names=c("house_loc"), sep="_")   

看一下output:


可以看出,我们原来一个house_loc变量,在运用dummies以后变成了15个变量,比如house_loc_黄浦,如果某条数据里为0,那么说明这套房子不在黄浦区,为1则说明在黄浦区,这个变量只能取0/1这两个值,代表是否存在。其他14个和house_loc变来的变量也是如此。

2.ML on data

首先我们要划分训练集和测试集,这里按照3:1进行划分。

1#split the train and test datasets2order <- sample(30000,22500)3train <- house[order,]4test <- house[-order,]5test_p <- test$house_p 6test_f <- test[-1]  # remove the variable which we want to predict

到此,train里面是我们包括house_p的训练数据,一共22500条,test_f是我们去掉house_p的测试数据,共7500条。

Regression tree

regression tree make predictions based on the average value of examples that reach a leaf. 回归树使用CART算法来构建树,使用二元切分法来分割数据,其叶节点包含单个值。首先,计算所有数据的均值,然后计算每条数据的值到均值的差值,再求平方和,即我们用总方差的方法来度量连续型数值的混乱度。在回归树中,叶节点包含单个值,所以总方差可以通过均方差乘以数据集中样本点的个数来得到。

在R中用rpart包来建立模型:

1library(rpart)2model <- rpart(house_p ~ .,data = train)3

output:


这里我们可以看见决策回归树是怎样来判定的,也可以用rpart.plot把树画出来:

1library(rpart.plot)2rpart.plot(model, digits = 5) 

这里寻找的第一个切分点是house_m,当测试数据进来以后,会根据house_m的值去走到叶子节点,进行预测。

下面我们把测试集放进去进行预测:

1pre <- predict(model,test_f)

pre是我们用test数据集预测数来的房屋价格,test$house_p是test数据集里面原有的房屋价格。可以看出它们在中间部分的分布差不多,极值的差别还是很大的。


cor在0.81左右,说明真实值和预测值是很相关的。说明模型准确度还可以。

算一下MAE

1# MAE2MAE <- function(actual, predicted) { mean(abs(actual - predicted)) }3MAE(pre, test$house_p) 

MAE= 147.8623

单纯的MAE是看不出我们预测值和真实值的差别的,所以我们可以用整个数据的平均值去放到整个数据的预测变量里,看看这个MAE2是多少,再和我们model的MAE比较:

1mean(test$house_p) 2MAE(527.3331, test$house_p) 

MAE2=259.311>147.8623=MAE,说明我们的模型减小了误差,但是并不是那么好,可以考虑用model tree试试看。

Model tree

模型树与回归树的差别在于:回归树的叶节点是节点数据标签值的平均值,而模型树的节点数据是一个线性模型。简单来说,就是只有当某个data到达某个叶子节点的时候,才会用叶子节点上面建立的model去预测。

Model tree里面会用到的就是这个Rweka包:

1library(RWeka) 2model.m5p <- M5P(house_p ~ ., data = train)3

house_p是我们要预测的因变量,这个.代表除了house_p之外的其他变量,"data="后面跟的就是我们需要训练的数据。


我们最后训练的模型就是这样子的,LM1-LM13代表的是每个叶子节点上的线性模型,也就是说,当我们用这个模型树进行预测的时候,当某个test data走到某个叶子节点的时候,就会用那个叶子节点上的model来进行预测。

带入测试数据:

1pre.m5p <- predict(model.m5p, test_f)

比较一下真实值和预测值的情况:


1cor(pre.m5p,test$house_p)

cor也可以看出,比刚刚的相关度0.81要高了很多。MAE比刚刚小了一些,说明model tree准确度和相关度都是优于regression tree的。

最后让我们以一张model tree预测的预测房价和真实房价的对比图结尾:

散点越靠近y=x这条线,说明模型效果越好。从图中看出,我们的模型还是比较好的。

根据这个模型我们也可以知道,可以去找那些在y=x这条线以下的房子,因为这些是低于市场价的。

最后写写模型可以改进的地方。

1.数据方面,单单把上海分成十几个区可能不大科学,但是考虑到独热变量可能带来的维度飙升问题所以还是选择只用十多个区而不再细分

2.可能可以对于一些异常值进行处理

3.回归树和模型树可能可以剪枝(?)效果可能会好一些,但也需要尝试才知道

最后的最后,做再多的模型,还是!买!不!起!房!

罢了罢了,与其唱一首 凉凉 送给自己,不如过好佛系的一生。足矣。

参考文献

《Machine Learning with R, 2nd Edition》 by Brett Lantz

附上画图代码

 1library(ggplot2) 2ggplot(data = b,aes(x=b$V1 ,y=b$pre.m5p))+ 3  labs(x="Actual price",y="predict price", 4       title = "Actual & predict price")+ 5  geom_point(size=3,shape=21,color="dark red",alpha=0.3)+ 6  geom_abline(intercept = 45,color="black")+ 7  theme(axis.text.x = element_text(angle = 0,size=11), 8        panel.grid.major=element_blank(), 9        panel.grid.minor=element_blank(),10        panel.background = element_rect(fill = "gray97"),11        panel.border=element_rect(fill="transparent",color="light gray"),12        plot.title = element_text(lineheight = 610,colour = "gray9"))


今日祈祷:

没房子的你,过得还好吗?祝愿看到此篇的朋友们都能有一个属于自己的豪宅。

往期精彩:

  • 是否,是否,总是富肥穷瘦?(文末上周投票公布)

  • 功不唐捐,每日一道LeetCode,玉汝于成,终获offer满满!

  • R语言中文社区2018年终文章整理(作者篇)

  • R语言中文社区2018年终文章整理(类型篇)

公众号后台回复关键字即可学习

回复 爬虫            爬虫三大案例实战
回复 Python       1小时破冰入门
回复 数据挖掘     R语言入门及数据挖掘
回复 人工智能     三个月入门人工智能
回复 数据分析师  数据分析师成长之路 
回复 机器学习     机器学习的商业应用
回复 数据科学     数据科学实战
回复 常用算法     常用数据挖掘算法

有房子的朋友请坐下

R爬虫小白入门:Rvest爬链家网+分析(三)相关推荐

  1. python爬房源信息_Python爬链家网租房信息

    爬去链家网的租房信息然后存储到数据库中. #-*- coding:utf-8 -*- import requests import re import random import MySQLdb fr ...

  2. 爬虫小白入门实例 —— 爬取全国某天所有火车的运行时刻表

    受好朋友的委托,帮忙爬取全国某天所有火车的运行时刻表. 在此之前没有用过爬虫,但是会用python,所以迅速学习了一下. 把自己的学习过程整理如下,爬虫小白可以通过下述内容快速入门. 任务描述: 爬取 ...

  3. pyspider爬链家网入库遇到的坑

    今天不详细讲代码逻辑,只讲如何入库 mongo的入库 from pyspider.libs.base_handler import * from lxml import etree import py ...

  4. Python爬取链家网获取二手房数据并调用高德api获得经纬度

    链家网获得数据地址,高德api获得经纬度(同理链家网也可以换成其他58同城,赶集网的数据,因为反爬虫比较厉害,没时间整,就用链家网的数据先试试水) 首先爬链家网,Info包含一条信息 import j ...

  5. 爬虫实例:链家网房源数据爬取

    初接触python爬虫,跟着视频学习一些很基础的内容,小小尝试了一下,如有错误感谢指正. 库和方法介绍: (1)requests requests是python的工具包,用于发出请求,,是用来获取网站 ...

  6. Python爬虫攻略(2)Selenium+多线程爬取链家网二手房信息

    申明:本文对爬取的数据仅做学习使用,请勿使用爬取的数据做任何商业活动,侵删 前戏 安装Selenium: pip install selenium 如果下载速度较慢, 推荐使用国内源: pip ins ...

  7. 爬虫,爬取链家网北京二手房信息

    # 链家网二手房信息爬取 import re import time import requests import pandas as pd from bs4 import BeautifulSoup ...

  8. 【爬虫】爬取链家网青城山二手房源信息

    一.项目背景 本项目是用python爬虫来实现爬取链家网青城山的二手房信息,我们小组是针对于在我们成都东软学院周边的二手房信息做一个数据爬取和建表.我们小组做这个项目的背景是因为在不久的将来,我们大学 ...

  9. Python 小项目 01 爬虫项目 爬取链家网南京地区二手房信息

    SpiderLianjia 介绍 python爬虫小程序,爬取链家网南京地区普通住宅二手房数据. 代码下载: https://gitee.com/lihaogn/SpiderLianjia 1 程序设 ...

  10. Python爬虫入门教程石家庄链家租房数据抓取

    1. 写在前面 这篇博客爬取了链家网的租房信息,爬取到的数据在后面的博客中可以作为一些数据分析的素材. 我们需要爬取的网址为:https://sjz.lianjia.com/zufang/ 2. 分析 ...

最新文章

  1. html中设置表格单实线,css实现表格实线的方法
  2. 研读pytorch版本的BERT分类代码
  3. python实现列表去重_python实现七种列表去重方法
  4. Django MPTT —— 概述
  5. linux防火墙的复规则,Centos下iptables防火墙规则编辑方法 - YangJunwei
  6. ssms中怎么设置自增_如何在SSMS状态栏中设置自定义颜色
  7. Epic Citadel Demo展示互联网作为游戏平台的巨大能量
  8. 参考资料:图片效果展示
  9. 绿盟扫描出来的ubuntu12.04下apache漏洞修复
  10. GitHub中文排行榜,帮助你发现高分优秀中文项目
  11. java-pdf-itext7、itextpdf 生成pdf 文档 定制票据打印
  12. 天津美术学院2021级专升本新生报到前后相关要求
  13. 常见的网站功能需求及解决方案
  14. Vue packages version mismatch
  15. 历年百度搜索风云榜小说年度冠军,2019年元尊、圣墟、剑来大PK
  16. 岁月划过生命线(我的2013-大二.上)
  17. 分享-目前免费-简历在线制作网站
  18. 下载安装纯净版火狐浏览器的步骤
  19. 李开复 ---- 给中国学生的第七封信:21世纪最需要的7种人才
  20. 计算机CCT考试模拟操作题,基础计算机cct考试模拟题.doc

热门文章

  1. OC中的字符串转换为C中的字符串
  2. 一个基于 SpringBoot+Redis+Vue 仿饿了么外卖系统(后台+移动端),可二次开发接私活!...
  3. Spring,SpringMVC,SpringBoot,SpringCloud有什么区别和联系?
  4. 这么多牛逼的Java常用Json库,万万没想到它的性能最好!
  5. 为什么我们公司强制弃坑Fastjson了?主推...
  6. 985 硕士待业200天,工作 10 年存款 2W : 累死你的不是工作,而是“选择”
  7. 你为什么人到中年还是个普通员工?
  8. 点击搜索到获得结果之间的零点几秒 都发生了什么?
  9. 全球IPv4地址正式耗尽!
  10. python消费kafka_Python脚本消费kafka数据