library(tidyverse)
library(modelr)
library(lubridate)
library(readxl)

研究背景

房价的高低与社会上每个人都息息相关,而且房地产价格在整个社会价格体系中,处于基础价格的重要地位。从生产领域的角度分析,房地产是一切商品生产的空间和场所。在市场经济中具有非常重要的功能和作用,基础性价格,房地产价格水平一定程度上决定着市场总体价格水平。而住房作为重要的消费资料,住房价格对调节居民的生活水平有重要的功能和作用格作为市场经济最重要的调节机制,还发挥着调节房地产市场供求总量和结构的重要作用。表现为可以调节房地产供求关系,商品房价格高,开发商有利可图,增加开发量,由此增加供给,而房价高,消费者减少购买,也会缩小需求;反之商品房价格低,开发商无利可图,就缩减开发量,由此减少供给,而房价低,促使消费者购买,又会增加需求。由此可见,房价对社会、人民起着至关重要的作用,本文变旨在研究房价变动的影响因素。

数据介绍

本文选取了台湾新北市2012年8月至2013年7月之间一年的房产价格,共包含7个变量。 其中自变量为: X1 =交易日期(例如:20120801代表2012年8月1日); X2 =房屋年龄(单位:年,取值范围【0~44】) ; X3 =到最近地铁站的距离(单位:米,取值范围【23.38~6488.02】); X4 =徒步生活圈中便利店的数量(单位:个数,取值范围【0~10】选取房产附近的500米作为徒步生活圈); X5 =地理坐标,纬度。(单位:度); X6 =地理坐标,经度。(单位:度)。 因变量为: Y =单位面积房价(10000新台币/平,其中平为台湾本地单位,1平方= 3.3平方米)

data <- read_excel("C:/Users/twf/Desktop/DATA.xlsx")

数据预处理

时间提取

由于原始数据中,交易日期的数据为数值型数据,无法进行相关的计算。而为了得到标准数据格式,需要对交易日期数据进行拆分。首先把原始的数值数据拆分为年、月、日,然后把年、月、日变量合为日期格式数据,最后选出日期数据和剩余变量。

变量重命名

把原始数据变量名命名为相关的实际意义的名字。

data=data%>%
  separate(X1,into=c("year","md"),sep = 4)%>%
  separate(md,into=c("month","day"),sep=2,convert = TRUE)%>%
  mutate(X7=make_date(year,month,day))

data_new=data%>%
  select(X7,X2,X3,X4,X5,X6,Y)
names(data_new)=c("date","age","distance","num","lat","lon","price")
head(data_new,10)
## # A tibble: 10 x 7
##    date         age distance   num   lat   lon price
##    <date>     <dbl>    <dbl> <dbl> <dbl> <dbl> <dbl>
##  1 2012-08-01   7.1   2175.      3  25.0  122.  32.1
##  2 2012-08-02  34.5    623.      7  25.0  122.  40.3
##  3 2012-08-05  20.4   2470.      4  25.0  122.  23.8
##  4 2012-08-03   1.5     23.4     7  25.0  122.  47.7
##  5 2012-08-04   3.1    384.      5  25.0  122.  56.2
##  6 2012-08-06   3.1    578.      6  25.0  122.  47.7
##  7 2012-08-07  29.4   4510.      1  24.9  121.  13.2
##  8 2012-08-08  32.7    392.      6  25.0  122.  30.5
##  9 2012-08-09  30.6    144.      8  25.0  122.  53.3
## 10 2012-08-10  33.4    187.      6  25.0  122.  42.2

数据分析

数据分布

因为房产交易不仅与房价有关,也与交易数量相关,所以首先按日期计算每天的房产交易数量,并进行可视化。从图中可以看出,每天的房产交易量的取值范围为1至4,但大多数为1。然后是房产价格随时间的变化图,从图中发现在2012年12月份房价有一定的下降。为了进一步研究房价与日期之间的关系,本文把日期分为星期和月份进行相关分析。先做房产价格与月份之间的关系分析,并借此观察房产价格是否存在季节效应。

daily_num=data_new%>%
  group_by(date)%>%
  summarise(n=n())

ggplot(daily_num,aes(date,n))+
  geom_line()

ggplot(data_new,aes(date,price))+
  geom_line()

房价的日期影响

房价与月份的关系

在市场中,商品的销售几乎都会有淡季与旺季之分,而为了研究房产行业是否也有旺季与淡季的区分,首先把日期按月份划分得到相关数据,并与房产价格做相关分析。从箱线图中并不能看出明显的趋势,每个月份的价格都没显著的波动。

data_month=data_new%>%
  mutate(month=month(date,label = TRUE))%>%
  select(month,price,date)
ggplot(data_month,aes(month,price))+
  geom_boxplot()

先拟合房产价格和月份的的模型,并将预测值覆盖在原始数据上。发现只有12月份的房价相对较低,这可能与年底销售方为了能尽量把房产卖出有关。一年到底各种物品都有打折促销,房产价格也不例外,卖方可能在原先房价基础上给出一定折扣。另一方面,房产有唯一性即每一个房产都是独一无二的,年底时剩下的房产质量(如位置、户型等)可能相对较差。所以,在年底房价会有一定的降低。

mod0=lm(price~month,data = data_month)

grid_month=data_month%>%
  data_grid(month)%>%
  add_predictions(mod0,"price")
  
ggplot(data_month,aes(month,price))+
  geom_boxplot()+
  geom_point(data=grid_month,color="red",size=4)

然后计算残差,并对其进行可视化表示。发现12月份总的残差较小,而其他没有什么明显趋势。对买房的人来说,在年底买房相对而言可以节省一定的开支。但是由于房产价格“打折”的力度并没有那么明显,同时考虑到房产质量问题,消费者也没有必要一定等到年底买房。 总的来说,不同月份对房价并没有显著的影响,同样也看出不同的季度应该也不会影响到房产价格即。为了进一步的研究房价的时间波动,下面进行房产价格与星期数相关研究。

data_month=data_month%>%
  add_residuals(mod0)
data_month%>%
  ggplot(aes(date,resid))+
  geom_ref_line(h=0)+
  geom_line()

房价与星期的关系

既然房产价格没有明显季节效应,下面继续研究房价是否会有周内效应,即不同的星期数是否会影响房价。先来观测不同星期的房产交易数量。从图中可以看出周一至周五以及周日的交易数相差不大,但周六的房产交易数有了明显的上升。可能在周六人们有足够的时间看房,且在周末工作了一周了的上班族会有更加好的心情,更愿意出钱去买房。另一方面,在周六买房的人们在周日有足够的时间来搬家,并进行大扫除来把新买来的房子打扫干净。

data_week=data_new%>%
  mutate(wday=wday(date,label = TRUE))%>%
  select(wday,price,date)

data_week%>%
  ggplot(aes(wday))+
  geom_bar(aes(fill=wday))

然后观察不同星期与房产价格的关系。从图中可以看出,周日至周五的房产价格较为平稳,而到了周六房价也有了一定的提高。这可能与周六的房产成交量多有关,房产公司与中介公司也认为买房的人更加愿意在周六去买房,所以会给房子提升一定的价格。

ggplot(data_week,aes(wday,price))+
  geom_boxplot()

先拟合房产价格和星期数的模型,并将预测值覆盖在原始数据上。通过预测不同星期的房价,发现星期六的房产价格有明显的提高,而周五的房价相对较低。

mod1=lm(price~wday,data = data_week)
grid_week=data_week%>%
  data_grid(wday)%>%
  add_predictions(mod1,"price")

ggplot(data_week,aes(wday,price))+
  geom_boxplot()+
  geom_point(data=grid_week,color="red",size=4)

然后计算残差,并对其进行可视化表示。从图中发现,大部分残差在0的上下波动,且没有发现明显的波动趋势,说明它去除了大部分的周内效应。

通过拟合房产价格与不同星期数之间的关系,我们发现房产价格的确有一定的星期效应。其中周日至周五的房价较为平稳,相差不大,但是周六的房价有一定的提升。一方面是消费者可能更加愿意在周六买房,另一方面销售方也知道周六是看房的高峰期,这些都会使得房产价格在原先的价格上有一定的提升。同时发现周五的房产价格相对有所下降。所以作为消费者,若是没有迫切的住房需求,可以在周末的时间看房,但不必急于立刻付钱买房。买家可以延迟到在下周五再观察下房价,若是房价有所下降则可以节省一定的购买金额。若是某些优质房源或对于是有硬性入住需要的消费者,则没有必要等待,因为时间也是一种成本。当然。房产价格与星期数的相关研究只作为一定参考。

data_week=data_week%>%
  add_residuals(mod1)
ggplot(data_week,aes(resid))+
  geom_freqpoly(binwidth=6)

data_week%>%
  ggplot(aes(date,resid))+
  geom_ref_line(h=0)+
  geom_line()

以上是房产价格与日期的关系,总的来说,房价有一定的周内效应但几乎没有季节效应。当然,这些只是房价在时间上的变化趋势,只能说明星期数对房价波动有一定影响,但并不能对房价起到决定作用。所以为了研究房产价格的具体决定因素,下面进行相关的回归分析。

房屋年龄对房价的影响

房屋年龄(未分类)影响

影响房产价格的一大因素是房屋年龄,先绘制房价与房屋年龄的拟合一条曲线来观测大致分布。 从图中可以看出,分布呈现凹型,说明随着房屋年龄的增长,房价呈现出现下降再上升的趋势。

data_age=data_new%>%
  select(price,age)

ggplot(data_age,aes(age,price))+
  geom_smooth(se=FALSE)

下面拟合房价与房屋年龄的模型,由它们的散点分布图可以得知房价与房屋年龄间可能存在二次关系,于是拟合一元二次的线性模型。然后用得到的模型进行房屋年龄对房产价格的预测。 从得到的结果来看,拟合的效果并不好。因为由前面的散点分布图看出,房价随着房屋年龄的增长呈现出现下降再上升的趋势。但是从预测的图来看,房产价格随着房屋年龄的增长只呈现出了逐步递减的趋势,而且递减的幅度越来越大。这明显与实际不符,下面在从残差来看下效果。

mod2=lm(price~I(age^2),data=data_age)

grid_age=data_age%>%
  data_grid(age)%>%
  add_predictions(mod2,"price")
ggplot(grid_age,aes(age,price))+
  geom_line()

从残差来看,随着房屋年龄的变大,残差仍有着先下降再上升的大致趋势。为了改进模型,下面对房屋年龄进行分类,并拟合与房价的模型。

data_age=data_age%>%
  add_residuals(mod2)
data_age%>%
  ggplot(aes(age,resid))+
  geom_ref_line(h=0)+
  geom_line()

房屋年龄(分类)影响

正常居民购买的房屋大致可以分为新楼盘开盘的房屋和二手房,而在本文中房屋的年龄取值范围为0至44年,于是把房产按房屋年龄划分为6类划分依据为:房屋年龄为0的划分为“新楼盘”;房屋年龄为(0,10]的划分为“新”;房屋年龄为(10,20]的划分为“较新”;房屋年龄为(20,30]的划分为“一般”;房屋年龄为(30,40]的划分为“较老”;房屋年龄为40年以上的划分为“老”。通过对房屋年龄的切分,把连续型变量转变为分类变量,仍能看出房价随着房屋年龄的增加出现先下降后上升的趋势,同时希望能够弥补上文中房产价格和房屋年龄间一元二次模型的不足。

data_age_cut=data_new%>%
  select(price,age)

age_cut=function(age){
  cut(age,
      breaks =c(-1,0,10,20,30,40,50),
      labels =c("新楼盘","新","较新","一般","较老","很老")
  )
}
data_age_cut=data_age_cut%>%
  mutate(age_cut=age_cut(age))
ggplot(data_age_cut)+
  geom_boxplot(aes(age_cut,price))

接下来建立房产价格与对房屋年龄分类后的回归模型,将预测值覆盖在原始数据上并进行可视化。从箱线图中我们可以看出“新楼盘”的房价基本处于最高,然后房产在随着时间增加经历了“新”和“较新”时房价出现递减的趋势。随后当房屋的年龄变的较大,房产变为“较老”和“很老”时房价又出现了逐渐递增的趋势,且最后房产价格渐渐呈现与“新楼盘”价格相近的趋势。

mod3=lm(price~age_cut,data=data_age_cut)

grid_age_cut=data_age_cut%>%
  data_grid(age_cut)%>%
  add_predictions(mod3,"price")

ggplot(data_age_cut,aes(age_cut,price))+
  geom_boxplot()+
  geom_point(data=grid_age_cut,color="red",size=4)

然后拟合残差,并对其可视化。从残差图中可以看出,模型的拟合有了一定的改进。

总的来说,房产价格与房屋年龄有一点的相关性。新楼盘因为属于一手房源,所以房屋必然处于较高的价位。而当房屋变为二手房后,房价会有明显的下降,且随着房屋年龄的增加房价会逐渐下降。但是当房屋年龄到达30年以后,房价反而会出现回弹并逐步上升。这可能是因为一方面较老的房屋在建房时的地理位置较好,随着经济的发展,老房屋周围的经济也发展起来带动了老房屋的房价升值。另一方面,由于建筑用地的需求,很多很老的房子会面临拆迁的情况,而拆迁可能会有一笔不俗的补偿金,所以40多年的房屋的价格会被抬的很高。

data_age_cut=data_age_cut%>%
  add_residuals(mod3)
data_age_cut%>%
  ggplot(aes(age,resid))+
  geom_ref_line(h=0)+
  geom_line()

两个模型的比较

为了更加明显的比较,对房屋年龄进行分类是否会对模型有改进作用,下面对两个模型做一定的比较。首先是两个模型的R方的比较,按房屋年龄作为连续型变量对房价回归得到模型的R方为0.009,而把房屋年龄拆分为分类变量并对房价建模得到的R方为0.194。可以看出模型的R方有了一定的提升,同时也可以从残差图的对比中看出拆分后的房屋年龄所拟合的残差也有了一定的提升。

所以通过比较,我认为对房屋年龄进行拆分既可以更好的拟合模型也可以更好的对数据进行解释,所以拆分是有必要。

data_age_new=data_age_cut%>%
  select(price,age,age_cut)
mod2=lm(price~I(age^2),data=data_age_new)
mod3=lm(price~age_cut,data=data_age_new)

a=mod2%>%
  summary(.)%>%
  .$r.squared%>%
  round(.,3)%>%
  str_c("未分类模型的R方为:",.,",")

b=mod3%>%
  summary(.)%>%
  .$r.squared%>%
  round(.,3)%>%
  str_c("分类模型的R方为:",.)
str_c(a,b)
## [1] "未分类模型的R方为:0.009,分类模型的R方为:0.194"
data_age_new%>%
  gather_residuals(without_cut=mod2,with_cut=mod3)%>%
  ggplot(aes(age,resid,color=model))+
  geom_line()

距离最近地铁口的距离对房价的影响

现代生活中交通工具对人们来说是必不可少的,而在较为发达的城市中地铁因便捷、快速、便宜、覆盖范围广、不会拥堵等原因也成为了人们日常出行的常用工具。所以在地铁口附近的住房也会因地铁的便利性而带来跟多的价值。

接下来,分析各房产距离最近地铁口的距离是否符房价有显著的影响。首先,观察一下距最近地铁口距离与房产价格的分布散点图,并添加一条拟合的平滑曲线。我们从图中可以看出,随着距离最近地铁口距离的增加,房价也会逐渐降低。

但是,我们也可以从拟合的平滑曲线中看到,当距离最近地铁口的距离小于1000米时,拟合的曲线的斜率较大。一方面是在这一范围内的数据点较多,另一方面也反映出这些房产应该是位于市区里的,所以斜率大,距离最近地铁口稍微近一点就会显著的提高房产价格。同时,当房屋距离最近地铁口的距离大于1000米时,可能这些房屋已经远离了市区,位于郊区附近,所以房价较低且随距离地铁口距离的波动较小。

data_distance=data_new%>%
  select(distance,price)
ggplot(data_distance,aes(distance,price))+
  geom_point()+
  geom_smooth(se=FALSE)

接下来拟合距离最近地铁口距离与房价的模型。从模型的拟合结果来看,模型的P值小于2.2e-16,是显著的,同时得到的R方为0.454,说明距离最近地铁口的距离可以解释房价变动的45%。

mod4=lm(price~distance,data=data_distance)
summary(mod4)
## 
## Call:
## lm(formula = price ~ distance, data = data_distance)
## 
## Residuals:
##     Min      1Q  Median      3Q     Max 
## -35.396  -6.007  -1.195   4.831  73.483 
## 
## Coefficients:
##               Estimate Std. Error t value Pr(>|t|)    
## (Intercept) 45.8514271  0.6526105   70.26   <2e-16 ***
## distance    -0.0072621  0.0003925  -18.50   <2e-16 ***
## ---
## Signif. codes:  0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
## 
## Residual standard error: 10.07 on 412 degrees of freedom
## Multiple R-squared:  0.4538, Adjusted R-squared:  0.4524 
## F-statistic: 342.2 on 1 and 412 DF,  p-value: < 2.2e-16

最后计算模型的残差,并可视化。从图中可以看出,残差仍有一定的规律性,在距离最近地铁口的距离1000米至3000米处较低;而在距离最近地铁口的距离3000米之外较高。对于这些规律性,需要进一步的研究,可能距离地铁口过远的地方可能有机场等因素,但这些并不在本文的研究范围之中。

data_distance=data_distance%>%
  add_residuals(mod4)
ggplot(data_distance)+
  geom_line(aes(distance,resid))+
  geom_ref_line(h=0)

徒步生活圈中便利店的数量对房价的影响

在日常生活中,房屋附近的便利店往往是所必须的,同时徒步生活圈中便利店的数量也能反映出房产附近的经济状况与宜居程度。本文选取房屋附近500米作为徒步生活圈并用在此圈内的便利店数量作为变量对房价影响进行分析。

因为原始数据中的徒步生活圈中便利店的数量为数值型变量,为了更好的观察它与房价之间的关系,把它变为字符型的分类变量。然后做模型拟合并把预测值覆盖到原数据上,再进行可视化。从得到的箱线图中可以看出,随着徒步生活圈中便利店的数量的增加房价也呈现逐渐提升的趋势。

data_num=data_new%>%
  select(num,price)

data_num$num=as.character(data_num$num)
mod5=lm(price~num,data=data_num)
grid_num=data_num%>%
  data_grid(num)%>%
  add_predictions(mod5,"price")

ggplot(data_num,aes(x=reorder(num,price,FUN=mean),y=price))+
  geom_boxplot()+
  geom_point(data=grid_num,color="red",size=4)

便利店数量与距地铁口距离的交互效应

同时,徒步生活圈中便利店的数量和距离最近地铁口的距离之间有一定的相关性。地铁口周围,来往的行人较多,便利店的盈利较大,因此便利店的数量多且房价较高。而距离地铁口较远的房屋周围可能便利店数量也较少,房价也可能较低,于是建立有交互效应的模型。首先,加入了便利店数量后模型的R方从原先的0.45提升到了0.53,拟合效果得到一定的提升。同时从残差图中也可以看出,交互效应模型的残差在原先的基础上有了一定的改进。

data_num_dis=data_new%>%
  select(price,num,distance)
mod4=lm(price~distance,data = data_num_dis)
mod6=lm(price~num*distance,data = data_num_dis)
mod6%>%
  summary(.)%>%
  .$r.squared%>%
  round(.,3)%>%
  str_c("交互模型的R方为:",.)
## [1] "交互模型的R方为:0.527"
data_num_dis%>%
  gather_residuals(without_mun=mod4,with_num=mod6)%>%
  ggplot(aes(distance,resid,color=model))+
  geom_ref_line(h=0)+
  geom_line()

经纬度对房价的影响

原始数据中给出的是各房产的经纬度,先绘制他们与房价的散点图,然后分别对房价拟合一条平滑曲线。从图中看出当维度在24.95到24.98之间是房价最高;而经度在121.53到121.54之间时房价最高。而远离这些区域时,房价呈现逐渐递减的趋势。

通过对台湾地图的查询也发现这一区域为台湾新北市的市中心所在,所以经纬度对房价的影响主要表现在距离市中心的距离上。

data_space=data_new%>%
  select(price,lat,lon)
data_space%>%
  ggplot(aes(lon,lat,color=price))+
  geom_point()

ggplot(data_space,aes(lat,price))+
  geom_smooth(se=FALSE)
## `geom_smooth()` using method = 'loess' and formula 'y ~ x'

ggplot(data_space,aes(lon,price))+
  geom_smooth(se=FALSE)
## `geom_smooth()` using method = 'loess' and formula 'y ~ x'

然后建立经纬度与房价的模型,得到的R方为0.405。反映出地理位置也在一定程度上影响了房产价格。

mod8=lm(price~lat+lon,data = data_space)
mod8%>%
  summary(.)%>%
  .$r.squared%>%
  round(.,3)%>%
  str_c("模型的R方为:",.)
## [1] "模型的R方为:0.405"

最后,房产距离市中心越近,其房屋价格也越高。但考虑到市中心房价高主要是由于商业中心的缘故,所以筛选出一些靠近地铁口,并且房价不高的房产,可以给那些有工作需要的人们提供一些建议以缓解需要买房者的经济压力。

data_new%>%
  filter(distance<500)%>%
  filter(price<45,price>30)%>%
  ggplot(aes(lon,lat,color=price))+
  geom_point()

结论与不足

通过前面的分析,我们发现在日期上,房价有一定的周内效应,而没有季节效应。同时新楼盘与很老的房屋的价格都会处于高价,距离最近地铁口的距离和便利店的数量也是对房价较大的影响因素。最后地理位置也会对房价有一定影响。把这些变量纳入模型进行拟合得到结果,发现最后的R方为0.571,说明这几个变量已经有较好的拟合效果。

但是于此同时,房价的影响因素十分复杂,如政治原因、全球化影响等,而且各地区的房价也会有地域差异。本文也只是从房产中有共性的几大方面进行分析,仍有许多方面没有考虑进去,所以文中给出的部分建议也仅供参考。

mod9=lm(price~num+distance+age+lat+lon,data = data_new)
mod9%>%
  summary(.)%>%
  .$r.squared%>%
  round(.,3)%>%
  str_c("模型的R方为:",.)
## [1] "模型的R方为:0.571"