东莞二手房数据分析
版本信息:R3.4; 操作时间:2017年9月
之前在公众号号看到一篇某地二手房数据爬取分析的帖子,有感而发,正好项目地在东莞,也做了一个东莞二手房数据爬取及分析的帖子。(后附代码)
数据获取
通过百度‘东莞二手房’,直接查看前面的‘安居客’的东莞二手房售卖网站。
通过查看网也结构,‘安居客’网页为静态网页,且其翻页地址变动具有稳健规律。故可以简单的获取到网页数据。
我主要抓取了一级页面的这些信息,我觉得用来练手这些数据足够了,还有一个原因就是业务上没啥深度的理解创造需求:
但是在爬取中也发现几个问题:
- 安居客网页售房信息只有50页,但其内容有较高的更新率,所以我采取隔天爬取爬取了好几天的数据,最后合并去重得到最终数据。这样做的好处是可以获取尽量多的数据,坏处是爬取频率过高,**网页反扒终糟IP拉黑(悲伤ing)
- 网页内容标签结构不完整,结构不是绝对整齐的,所以需要直接爬取大标签内容,然后二次清洗
最终我们获得了16995条有效数据,如此大量的数据得益于我们不怕封IP的多次抓取(其实我的IP真的被封了【哭】)。
文本分析
在描述数据之前,突发奇想的想看看各位‘地主房东’都是怎么描述自己房屋的,也就是售卖信息的标题(我认为售卖信息的标题必然要包含房屋的卖点,同样也可以反映出市场的需求点)。所以先一步给‘房屋描述’做个文本分析。
单独拿出房屋描述列,因为每一条比较短,切关键词重复出现的情况比较少,所以并没有通过分词创造矩阵,直接杂糅出了分词结果:
然后把结果整理一下,顺便去掉了单字的分词:(去掉单个字的词,提炼词频,共有8518个词,最多出现4662次,最少出现1次。)
(以为写个精装我就会相信!)
做个词云展示一下房东售卖信息的关键词,包括报告开始的那个词云也是成果之一:
从词云和词频表中,我们可以简单的总结出:
- 房东售卖房屋的关键词汇总一下(或者说市场需求的潮流):房屋精装、家电齐全、花园洋房、南北通透采光要好、视野开阔、阳台宽大,地铁口、交通便利等等硬条件。还得带上,价格合理,诚心急售!
- 词频在200左右的范围里提到了:品质、时尚、高端、生态、经典等关键词,说明随着房屋档次的上升,房屋售卖的关键词也越来越注重档次。又如词频在70左右的范围里谈到 :设计、山湖、优雅、幸福、 健怡、养生等关键词。说明土豪还是比较注重精神层面的享受。
数据描述
简单将数据集清洗一下,得到若干字段,接下来我们依托这几个字段看看它们相互关系和自身分布表达什么信息
1.各地区的房源
总体看,还是中心城区的房源数量最多,但是东南组团也是比较多房源,是新经济杠点吗?尤其是凤岗、塘厦、樟木头。至于项目的相关地:东城区,更是数量位居第二,仅次于南城区,势头迅猛!
2.各户型
- 三室两厅’的房型数9738,超过一半,东莞人民对三室两厅的房型热情是偏执的,*的!
- 3室2厅平均单价为15646.09元/m2;3室2厅平均面积为102.90799m2;
- 东莞人民不光在住房认知上看法是惊人一致的,而且东莞人民还很有钱(东莞人民有钱这件事,这才是开始,嘘!)
3.热门区域
我从数据里取了前30个热门的二手房源地,大家有兴趣买房,可以考虑先去这些地方看看。比如西平、官井头地区的房源最多,可以结合情况优先参考。
4.面积和楼层
- 低层别墅的数量多于小户,大部分人喜欢中层中户,东莞人民很有钱2.0!(这里的底、高层之分是依据原本数据里标注的提取,故存在30层的中层和15层的高层这样的局限性。So,这里无法做深入说明。)
- 表中看出,大中小户占比差别其实不大,但是之前我们得出三室两厅占比超一半,所以,东莞人民对 三室两厅的感情,夸张到什么程度了!!!(95m2以下标记为小户;95m2至120m2的标记为中户;120m2以上的标识为大户;(仅凭经验人为分组,却乏业务理解))
5.房龄关于地区
- 后来的才是正常发展速度,中间有几年东莞就像做梦一样跳跃式发展,结果后续又跳跃下降,其实结合新闻,我们知道那几年东莞繁华过后正逢某事件整顿,经济一片萧条,虽然有了复苏的势头,但是相比之前倒是有所差距。
- 各区的新建房数量都同比下降,没有出现特别明显的新增长点。(其实我更想知道这拉了数据的1900年代的房子是什么样子)
6.房龄关于户型
- 新建的房子在减少,但是,东莞人民对 三室两厅 的*追求并没有停止!相比于三室两厅、一厅、三厅的房子,东莞人民对其他房型的追求可比称之为冷淡。
7.房价
- 这单价,进2万的大众水平,和北京昌平区有的一拼了,这得多有钱,富有的东莞人民3.0!
- 单价那么高,总价也就不说什么了,但是在数据里出现了高达5000万的房子,等会要瞄一眼数据5000万的豪宅什么样。
8.地区房价
顺便瞄一眼各地区的总价和单价,这里对y轴上限做了限制,为了更好观察大众水平。
- 在房屋总价上面,大众数值除了南城、松山湖地区明显偏高以为,其他地区都较为稳定。
- 在单价分布上各地区波动较为明显,尤其是松山湖(又是松山湖)地区,毋庸置疑,松山湖地区就是东莞的土豪云集地,高端层次人士居住地。
9.豪宅
最后,我们瞄一眼原始数据里,那些房价超过3000万的房子,为什么是三千万,因为3000万相当于清朝中期20万两白银,当时买个地方官员最高到道台,相当于现在的副省长,而价格四品道台要16400两,知府也就是市长要13300两,县长要9600两。房子卖了就是一方诸侯。
数量不多,但是很惊艳,首先不出所料,不少是松山湖地区的。其次,和想象中一样,该大的大,该贵的贵,看不下去了!
马上结束了
简单总结一下:
- 东莞人民对三室两厅的户型有一种*的需求,尤其是中层的三室两厅。
- 松山湖地区是东莞的土豪区。
- 尽管经济发展受挫了,恢复才刚开始,但是不能掩盖东莞人民很有钱的事实。非常有钱!
- 房东售卖房屋的关键词汇总一下(或者说市场需求的潮流):房屋精装、家电齐全、花园洋房、南北通透采光要好、视野开阔、阳台宽大,地铁口、交通便利等等硬条件。还得带上,价格合理,诚心急售!
写在最后
本篇报告完全有感而发,起严谨性上,包括有些结论都完全依托数据,有一定局限性。
代码
library(rvest)
library(xml2)
library(stringr)
library(dplyr)
house <- data.frame()
for(i in 1:50){
gurl<- str_c("https://dg.anjuke.com/sale/p",i,"/?pi=baidu-cpc-dg-tyongdg2-all&kwid=4279453665&utm_term=%E4%B8%9C%E8%8E%9E%E6%88%BF%E4%BB%B7%E8%B5%B0%E5%8A%BF%E5%9B%BE#filtersort")
tmp <- gurl%>%read_html(encoding = "UTF-8")%>%html_nodes(".list-item")#固定父级标签部分
house_name <- tmp%>%html_nodes(".houseListTitle")%>%html_attr("title")#名称,不知道什么用,先爬下来
house_address <- tmp%>%html_nodes(".comm-address")%>%html_attr("title")#房子地址
house_price <- tmp%>%html_nodes(".price-det")%>%html_nodes("strong")%>%html_text()#价格
house_price2 <- tmp%>%html_nodes(".pro-price")%>%html_nodes(".unit-price")%>%html_text()
house_point <- tmp%>%html_nodes(".house-title+ .details-item")%>%html_text()
house_label <- tmp%>%html_nodes(".tags-bottom")%>%html_text()
houseall <- data.frame(house_name,house_address,house_price,house_price2,house_point,house_label)
house <- rbind(house, houseall)
}
write.csv(house, file="house8.csv", row.names = T, fileEncoding = "UTF-8")
#前后共爬了8次,导致ip被拉黑了
################################洗矿########################
house2 <- read.csv(file = "house2.csv",fileEncoding = "UTF-8", stringsAsFactors=F)
house3 <- read.csv(file = "house3.csv",fileEncoding = "UTF-8", stringsAsFactors=F)
house4 <- read.csv(file = "house4.csv",fileEncoding = "UTF-8", stringsAsFactors=F)
house5 <- read.csv(file = "house5.csv",fileEncoding = "UTF-8", stringsAsFactors=F)
house6 <- read.csv(file = "house6.csv",fileEncoding = "UTF-8", stringsAsFactors=F)
house7 <- read.csv(file = "house7.csv",fileEncoding = "UTF-8", stringsAsFactors=F)
house8 <- read.csv(file = "house8.csv",fileEncoding = "UTF-8", stringsAsFactors=F)
housex <- rbind(house2,house3,house4,house5,house6,house7,house8)#合并一下
write.csv(housex, file="housex.csv", row.names = T, fileEncoding = "UTF-8")#以防意外,还是写出一下
names(housex)
housex2 <- housex[,-1]#去掉唯一标识列
housex2 <- unique.data.frame(housex2)#神级函数,一键到位
rm(house1,house2,house3,house4,house5,house6,house7,house8,houseall,house)#释放内存
rm(zzz, housex)#再释放一下
library(stringr)
library(splitstackshape)
#head(housex2$house_name)
housex3 <- concat.split.multiple(housex2, "house_address", "<U+00A0><U+00A0>")
housex3 <- concat.split.multiple(housex3, "house_address_2", "-")
housex3 <- concat.split.multiple(housex3, "house_point", "|")
housex3 <- concat.split.multiple(housex3, "house_point_4", " ")
housex3$house_price2<- as.numeric(sub(pattern = "元/m2", "", housex3$house_price2, perl= TRUE))
housex3$`area(m2)` <- as.numeric(sub(pattern = "m2", "", housex3$`area(m2)`, perl= TRUE))#这里学到一个叼的
#head(housex3$area(m2))
housex3$house_label <- gsub(pattern = "\\s", "", housex3$house_label, perl= TRUE)#去掉label字段多余符号
colnames(housex3)[c(10,11,12,13)] <- c("type","area(m2)", "high", "year")#重命名
colnames(housex3)[3] <- "price(y/m2)"
##########################################粗炼################################
housex3$year <- substr(housex3$year,1,4)#提取年份
housex3$area_fz <- ifelse(housex3$`area(m2)` < 95, "小户", ifelse(housex3$`area(m2)` >= 120, "大户", "中户"))
housex3$high_fz <- ifelse(substr(housex3$high,1,2) == "高层", "高层",ifelse(substr(housex3$high,1,2) == "中层", "中层", "低层"))
##################因子转换
varname <- c("house_address_1","house_address_2_1","house_address_2_2","house_address_2_3","house_address_2_4","type","area_fz","high_fz")
for(i in varname){
housex3[,i] <- as.factor(housex3[,i])
}
housex3$city <- ifelse(housex3$house_address_2_1 =="莞城"|housex3$house_address_2_1 =="南城"|housex3$house_address_2_1 =="东城"|housex3$house_address_2_1 =="茶山"|housex3$house_address_2_1 =="寮步"|housex3$house_address_2_1 =="大岭山"|housex3$house_address_2_1 =="大朗"|housex3$house_address_2_1 =="松山湖","中心组团",
ifelse(housex3$house_address_2_1 =="常平"|housex3$house_address_2_1 =="横沥"|housex3$house_address_2_1 =="东坑"|housex3$house_address_2_1 =="石排"|housex3$house_address_2_1 =="企石"|housex3$house_address_2_1 =="桥头"|housex3$house_address_2_1 =="谢岗", "东北组团",
ifelse(housex3$house_address_2_1 =="塘厦"|housex3$house_address_2_1 =="樟木头"|housex3$house_address_2_1 =="清溪"|housex3$house_address_2_1 =="黄江"|housex3$house_address_2_1 =="凤岗", "东南组团",
ifelse(housex3$house_address_2_1 =="万江"|housex3$house_address_2_1 =="高埗"|housex3$house_address_2_1 =="石碣"|housex3$house_address_2_1 =="石龙"|housex3$house_address_2_1 =="麻涌"|housex3$house_address_2_1 =="中堂"|housex3$house_address_2_1 =="望牛墩"|housex3$house_address_2_1 =="洪梅"|housex3$house_address_2_1 =="道滘", "西北组团","西南组团"))))
################################
#housex <- read.csv(file = "housex.csv",fileEncoding = "UTF-8", stringsAsFactors=F)
#洗不动了,先这样吧
write.csv(housex3, file="housex3.csv", row.names = F, fileEncoding = "UTF-8")#写出这个数据集
#####################################################################
#####################################################################
#####################################词云来一波################################
library(jiebaR)
library(wordcloud2)
house_name <- housex3$house_name
house_name <- unlist(house_name)
class(house_name)
#head(house_name)
wk <- worker()#其實這一步,哎,都是l泪
#dir()
segname <- segment(house_name, wk)#出現分詞結果
segnamem <- segname[nchar(segname)>1]##停词字典不能用,直接粗暴的删掉一个字的
keyname <- data.frame(sort(table(segnamem), decreasing = T))#给出词频表
keynamepro <- keyname[keyname$Freq >1,]#词太多了,取一半
keynamepro2 <- keynamepro[1:1000,]#还是太多,取8分之一
write.csv(keynamepro2, file="keynamepro2.csv", row.names = F, fileEncoding = "UTF-8")#写出文件是个好习惯
wordcloud2(keyname, size = 1, figPath = "house2.png", color = "random-dark")#找一张酷炫的图
#这里写个小节
#东莞,或者大部分地区售房,先要吹嘘自己的房屋精装修,家电齐全,,其实都那样,买房嘛,花园洋房,南北通透采光要好,
#视野开阔,阳台宽大,地铁口,交通便利等等硬条件,还得带上,价格合理,诚心急售
#200多个说到 品质,时尚,高端,生态,经典,
#70多谈到 设计,山湖, 优雅,幸福, 健怡, 养生
#######################################################################
##################################ggplot2#########################################
housex3 <- read.csv(file = "housex3.csv",fileEncoding = "UTF-8", stringsAsFactors=F)#这种活还是要一气呵成,辛苦把数据集写出了,好习惯
str(housex3)#这里看看变量属性,重新定义一下。真是5000行报错炼神,醉了
library(ggplot2)
###################先来看看东莞各区域的房源
paddress <- ggplot(data = housex3, aes(house_address_2_1))
paddress + geom_bar(aes(fill= city))+
labs(x=NULL, y="待售房", title="东莞各区二手房库存") +
theme(axis.text.x = element_text(angle = 60, vjust = 0.5, size=15))+ theme_bw()
#table(housex3$house_address_2_1,housex3$city)
#theme(axis.text.y= element_text(size=15, family="myFont", color="black", face= "bold", vjust=0.5, hjust=0.5))
##可以明显的看到,南城、东城、凤岗地区的房源明显居多,而在组团区分上,
##明显是中心组团地区和东南组团地区的房源较多,东南组团地区地处郊区,城区面积大,人少可以理解。
##但是,这中心组团为市中心,这么多二手房源,可以细思一下
#################再看看各房型
toptype <- sort(table(housex3$type),decreasing=T)[1:15]
ttype <- data.frame(toptype)
ttype$type <- rownames(ttype)
ptype <- ggplot(data = ttype ,aes(x=reorder(Var1,sort(Freq)), y=Freq))#这里一点要吐槽一下赵同学,智商低的一批
ptype + geom_col(aes(fill="red"))+ theme_bw() + geom_text(label=ttype$Freq)+
labs(x=NULL, y="待售房", title="各房型受众热度") +
theme(axis.text.x = element_text(angle = 60, vjust = 0.5, size=10))
#三室两厅的房型数9738,超过一半,东莞人民对三室两厅的房型热爱是偏执的,*的,
typeprice <- aggregate(housex3$price.y.m2.,by=list(housex3$type),mean)
#而 3室2厅 平均单价为 15646.09元/m2,
typearea <- aggregate(housex3$area.m2.,by=list(housex3$type),mean)
#而 3室2厅 平均面积为 102.90799m2
#so, 东莞人在住房认知上看法还是惊人的一致另外,东莞还是有钱人多,好吧,地球还是有钱人多
#########################看看各面积分布
ggplot(housex3, aes(x=factor(1),fill= area_fz))+geom_bar(width=1)+coord_polar(theta = "y")
#各种户型占比差不多,应该跟我的阈值设置有关系,但是结合之前的结论,
#type3_2 <- housex3[which(housex3$type=="3室2厅"),]
##############################二手房地点分布
addresstop15 <- sort(table(housex3$house_address_2_2),decreasing=T)[1:30]
addresstop15 <- data.frame(addresstop15)
addresstop15$addr<- rownames(addresstop15)
ptype <- ggplot(data = addresstop15 ,aes(x=reorder(Var1,sort(Freq)), y=Freq))#这里一点要吐槽一下赵同学,智商低的一批
ptype + geom_col(aes(fill= "red"))+
labs(x=NULL, y="待售房", title="各地区房屋数量") + theme_bw() +
geom_text(aes(label=addresstop15$Freq), position = position_dodge(0.9), vjust = 0) +
theme(axis.text.x = element_text(angle = 60, vjust = 0.5, size=10))
###############################################各楼层分布
paddress <- ggplot(data = housex3, aes(high_fz))
paddress + geom_bar(aes( fill= area_fz))+
labs(x=NULL, y="待售房", title="楼层分布")
#theme(axis.text.x = element_text(angle = 60, vjust = 0.5, size=15))
#############################################房龄分布
ggplot(housex3,aes(year))+geom_bar(aes(fill=type))+
theme_bw() + xlim(1990, 2017) +
labs(x=NULL, y="待售房", title="房龄分布")#房龄和放型的关系
ggplot(housex3,aes(year))+geom_bar(aes(fill=city))+
theme_bw() + xlim(1990, 2017) +
labs(x=NULL, y="待售房", title="房龄分布")#房龄关于地区的关系
########################################二手房总价和单价分布:
ggplot(housex3,aes(price.y.m2.))+geom_histogram(aes(fill="red")) + theme_bw() +
labs(x="房屋单价", y="待售房", title="房屋单价分布") #单价分布
ggplot(housex3,aes(house_price))+geom_histogram(aes(fill="red")) + theme_bw() +
labs(x="房屋总价", y="待售房", title="房屋总价分布") #总价分布
YQ <- housex3[which(housex3$house_price > 3000),]
names(YQ)
YQ1 <- YQ[,-c(7,8,9)] #豪宅
##############################################
##############################各区细况###############
#################各区的均价#######################
avgprice <- aggregate(housex3$price.y.m2.,by=list(housex3$house_address_2_1),mean)
colnames(avgprice)[2] <- "value"
#############箱线图
tb<-ggplot(housex3,aes(house_address_2_1,house_price))
tb+geom_boxplot(outlier.colour="darkgreen",fill="grey80")+ ylim(0,2000) +
theme_bw() +labs(x=NULL, y=NULL, title="房屋总价分布") #总价
tb<-ggplot(housex3,aes(house_address_2_1,price.y.m2.))
tb+geom_boxplot(outlier.colour="darkgreen",fill="grey80")+ylim(5000,100000)+
theme_bw() + labs(x=NULL, y=NULL, title="房屋单价分布") #单价
tb<-ggplot(housex3,aes(city,price.y.m2.))
tb+geom_boxplot(outlier.colour="darkgreen",fill="grey80")+ylim(5000,100000)#单价
下一篇: git多人开发流程
推荐阅读
-
jQuery 源码分析(十) 数据缓存模块 data详解
-
MySQL数据库InnoDB存储引擎多版本控制(MVCC)实现原理分析_MySQL
-
python网页爬虫+简单的数据分析
-
大数据技术学习笔记之网站流量日志分析项目:数据采集层的实现
-
数据分析系统DIY3/3:本地64位WIN7+matlab2012b访问VMwareCentOS
-
怎样对ACCESS数据库中的表进行分析和优化
-
MySQL数据库服务器逐渐变慢分析与解决_MySQL
-
【python数据挖掘课程】二十.KNN最近邻分类算法分析详解及平衡秤TXT数据集读取
-
链家北京二手房交易数据分析
-
Python数据分析实战项目-北京二手房数据分析