|
上一篇文章写了用R爬取租房数据以及做初步数据分析,这篇文章拿之前爬的数据,对房源进行分类以及探究影响租金的因素。
爬取的数据文末会附上链接。
1 使用kmeans对房源数据进行聚类
kmeans聚类是一种简单粗暴的无监督学习方法,通过点到中心点的距离的计算并反复迭代,可以将没有标签的数据集自动归类。
1.1数据导入
首先,导入数据,
house2 <- read.csv("house2.csv",stringAsFactor = T)
View(house2)

1.2 数据预处理
为了能用散点图(只有x和y两个坐标)更直观的看出聚类效果,这里就简单选取两个数值型变量:房源价格和面积做聚类。
df<-data.frame(price=house$price,area=house$area)
str(df)


因为kmeans涉及到计算点与中心点之间的距离,因此在计算时要去除数据的单位限制,也就是对数据进行标准化,便于不同单位或量级的指标能够进行比较和加权。
这里使用z-score 标准化的方法,它的好处是即使有可能存在离群值,不会对标准化后的数据产生很大的影响。
df2<- data.frame(scale(df))#对数据进行标准化
View(df2)

经过标准化后,价格和面积的数据在量纲上就差不多了。
1.3 判断最佳聚类个数
在建立模型之前,应该先确定模型最佳聚类个数。
因为K-means方法的原则是让组内间距尽可能小,组间差距尽可能大。因此判断最佳聚类个数可以以组内平方和基本不再明显变化的最少聚类个数为标准,从而确定聚类的数目。
##构建聚类曲线确定最佳聚类数目
k <- (nrow(df2)-1)*sum(apply(df2,2,var))
k.plot <- function(data, nc, seed=1234){
for (i in 2:nc){
set.seed(seed)
k[i] <- kmeans(data, centers=i, iter.max = 100, nstart=25)$tot.withinss
}
plot(1:nc, k, type="b", xlab="聚类个数",
ylab="组内平方和",col = 'lightcoral',
lwd = 2)
}
k.plot(df2,nc=15)

曲线中当聚类个数为4、5的时候,组内平方和曲线已经不再明显变化了了,因此可以选择4或者5。
1.4 建立K-means模型
set.seed(1234)
clust <- kmeans(x = df2, centers =4 , iter.max = 100)
table(clust$cluster)
house$cluster <- clust$cluster
p <- ggplot(data = df2, mapping = aes(x = area,y = price, color = factor(model$cluster)))
+geom_point(pch = 20, size = 3)+scale_colour_manual(values = c("black","yellow", "green","red"))
查看聚类结果如下图所示:


根据以上聚类结果,我们可以比较各类中房子平均面积、平均租金和人均租金、房子人均可居住人数以及房子所在楼层。

table(house$floors,house$cluster)

根据以上模型结果显示,可分为四类:
第一类为特大户型,具有房源数量少(148套)、面积非常大(466㎡)、租金昂贵、低楼层的特点。即使按照可居住人数对租金进行平摊,人均价格也高达17000多元,这样的房子很可能是独门独院的,或许是别墅也说不定;
第二类为大户型,与前一种类型相比,价格更实惠(减少了2/3)、数量大的多(1458套),同样具有面积大、人均价格偏高的的特点。这一类的房子低楼层较多,也有中楼层和高楼层的。比较适合人口数较多的中产家庭居住。
第三类为普通户型,价格较实惠、数量比较多,比较适合有孩子的普通家庭居住或者几个人合租,低楼层、中楼层、高楼层的房源数都占有一定比例;
第四类为小户型,平均面积小(68㎡)、适合一个人或者两个人住,价格最便宜。
2 回归模型探究影响租金的因素
2.1 数据预处理
在建立线性回归模型之前,需要对数据进行两步处理:对于分类变量,要转换成哑变量;对于数值型变量,要检验数据的正态性。
2.1.1 数值型数据:正态性检验
#定义一个正态性检验的函数,样本量大于5000用ks检验,小样本用sw检验
norm.test<-function(data,alpha=0.05){ #alpha为显著性水平,默认设置为0.05
if (length(data) > 5000) {
resul <- ks.test(data,'pnorm')
}else{
resul<-shapiro.test(data)
}
if(resul$p.value>alpha){
print(paste("服从正态分布,p值为",resul$p.value,">",alpha))
}else{
print(paste("不服从正态分布,p值为",resul$p.value,"< ",alpha)
}
resul
}
norm.test(house$area)
norm.test(house$price)
norm.test(house$num_person)
结果显示三个变量均不属于正态分布,需要在建立模型时对模型进行修正。
2.1.2 分类变量:转换为哑变量
哑变量(dummy variable)可以将线性回归模型中的分类变量进行量化,生成矩阵,数字取值为0或1。
举个例子:
生成哑变量之前,

生成哑变量之后,

对数据中的分类变量转换哑变量,具体实施的代码如下:
library(caret)
dummy <- dummyVars(formula = ~floors + plc1, data = house)#转换成哑变量
pred <- predict(dummy, newdata = house)
house2 <- cbind(house,pred)#将哑变量整合到数据集中
View(house2)
model.data <- subset(house2,select = -c(3,5))#去除原有的分类变量
2.2 建立线性回归模型
fit1 <- lm(price~ .,data = model.data)#建立初始模型
上面提到了数据非正态的问题,这里使用cox-box转换来修正非正态的数据。
具体代码如下:
# Cox-Box转换
library(car)
powerTransform(fit1)#确定λ的值
p=bcPower(model.data$price,-0.1)
model.data2 <- model.data[,-1]#不能价格放入自变量中
fit2 <- lm(p ~ .,data = model.data2)
hist(p)
summary(fit2)
经过修正后,数据分布如图所示,

经过修正后的模型如图所示,
![model.data2 <- model.data[,-1]](https://img-blog.csdnimg.cn/20181229155928935.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3FxXzQxODU1NzY4,size_16,color_FFFFFF,t_70)
上图显示,P值远远小于0.05,说明非常显著,R方的值为0.7022。
此外,从上图中发现,有几项数据中有NA的存在,这说明变量存在多重共线性,这里使用向后逐步回归的方法去除多余变量。
#向后逐步回归
tstep<-step(fit2)
summary(tstep)
最终结果显示如下:

模型结论
用线性回归模型之前对分类数据进行量化,修正数据的非正态性,最终得到回归模型,观察模型可得出以下结论:
1.房源的面积和可居住人数都会对租房价格产生正向影响。
2.低楼层或者高楼层都会负向影响价格。在其他条件相同的情况下,中楼层的租房价格高于低楼层的或者高楼层的租房价格。
3.模型以长宁区的租房为基准(初始模型中为NA的地区为长宁区),在此条件下,只有黄浦区和静安区的变量系数为正,其余地区的变量系数为负。除黄浦区和静安区外,其余地区变量均对模型有负向影响。
数据链接:https://pan.baidu.com/s/13OKeXewnyUG8oywqmNkCVw
提取码:5nnn |