[Rscript]以北京二手房为例做数据清理和建模

一、数据清洗

setwd("C:/data/")					#工作路径
dat=read.csv("二手房.csv",header=T)		#读入二手房数据
names(dat)						#查看变量名
dat0=dat 						#工作文件命名为dat0

######通过最简单的描述分析,清洗数据,一个一个变量处理

#CATE,各个城区的观测数,分布比较均匀,石景山偏少,不做处理
table(dat$CATE)				#查看城区的分布

#卧室数和厅数,查看分布
table(dat$bedrooms)			#取值为0,6,7,8,9的相对较少,考虑删除
table(dat$halls)			      #取值为4和9的只有6个观测,考虑删除
dat0=dat0[dat0[,2]>0&dat0[,2]<6,]	#对卧室数变量做部分删除处理
dat0=dat0[dat0[,3]<4,]			#对厅数变量做部分删除处理

#房屋面积,有许多outlier,建议将面积小于30和大于300的做删除处理,依据是1%和99%分位数
quantile(dat$AREA,c(0.01,0.99))		#查看房屋面积的1%和99%分位数
dat0=dat0[dat0[,4]>30&dat0[,4]<300,]	#对AREA变量做部分删除处理

#楼层,basement相对较少,去掉地下室进行建模分析
#低中高层不具有可比性,后续讨论需要注意
table(dat$floor)					#查看楼层数的分布
dat0=dat0[dat0[,5]!="basement ",]		#去掉地下室观测
	
#是否邻近地铁,是否学区房是0-1变量,计算均值,即地铁房和学区房占比	
mean(dat$subway)		#82.9%的观测是邻近地铁的
mean(dat$school)		#30.1%的观测是学区房

#单位面积房价,同样有许多outlier,按照0.1%和99.9%分位数,去掉单价小于1.35万和大于15万的
quantile(dat$price,c(0.001,0.999))			#查看单位面积房价的0.1%和99.9%分位数
dat0=dat0[dat0[,8]>13500&dat0[,8]<150000,]	#对单位面积房价变量做部分删除处理

#北京的经纬度取值范围:39.5--41 & 115.5--117.5
dat0=dat0[dat0[,9]>=115.5&dat0[,9]<=117.5,]
dat0=dat0[dat0[,10]>=39.5&dat0[,10]<=41,]

######查看删除的观测条数和比例
diff=dim(dat)[1]-dim(dat0)[1]		
round(100*diff/dim(dat)[1],2)	

###保存做过清洗的数据集
write.csv(dat0,file="mydata.csv")

二、描述和建模

setwd("C:/data/")					#工作路径
dat0=read.csv("mydata.csv",header=T)	#读入清洗过后的数据
dat0=dat0[,-1]					#去掉第一列序号
n=dim(dat0)[1]					#样本量
summary(dat0)					#查看数据基本描述

dat0$price=dat0$price/10000			#价格单位转换成万元

#将城区的水平由拼音改成中文,以便作图输出美观
dict1=levels(dat0$CATE)				#拼音字典
dict2=c("朝阳","东城","丰台","海淀","石景山","西城")	#中文字典
dat0$CATE=dict2[match(dat0$CATE,dict1)]	#匹配拼音和中文字典

#调整城区和楼层的因子水平顺序,以便作图输出美观
dat0$CATE=factor(dat0$CATE,levels=c("石景山","丰台","朝阳","东城","海淀","西城"))
dat0$floor=factor(dat0$floor,levels=c("high","middle","low"))

######对dat0做描述分析

#因变量直方图
hist(dat0$price,xlab="单位面积房价(万元/平方米)",ylab="频数",main="",col="lightblue")
#查看房价最高和最低的两条观测
dat0[dat0[,8]==min(dat0[,8]),]
dat0[dat0[,8]==max(dat0[,8]),]

#城区对房价的分组箱线图
boxplot(price~CATE,data=dat0,col="lightblue",ylab="单位面积房价(万元/平方米)")	

par(mfrow=c(1,2))	#画1*2的图

#地铁、学区的分组箱线图
boxplot(price~subway,data=dat0,col=c("lightblue","orange"),names=c("非地铁","地铁"),ylab="单位面积房价(万元/平方米)")	
boxplot(price~school,data=dat0,col=c("lightblue","orange"),names=c("非学区","学区"),ylab="单位面积房价(万元/平方米)")	

par(mfrow=c(1,3))	#画1*3的图

#卧室数、厅数、楼层的分组箱线图
boxplot(price~bedrooms,data=dat0,col="lightblue",ylab="单位面积房价(万元/平方米)",xlab="卧室数")	
boxplot(price~halls,data=dat0,col="lightblue",ylab="单位面积房价(万元/平方米)",xlab="厅数")		
boxplot(price~floor,data=dat0,col="lightblue",names=c("高","中","低"),xlab="楼层",ylab="单位面积房价(万元/平方米)")	

par(mfrow=c(1,1))	#画1*1的图

#房屋面积和单位面积房价的散点图
plot(dat0$AREA,dat0$price,xlab="面积(平方米)",ylab="单位面积房价(万元/平方米)")

###厅数做因子化处理,变成二分变量,使得建模有更好的解读
style=rep("其他",n)
style[which(dat0$halls==0)]="无厅"		
style[which(dat0$halls>0)]="有厅"		
style=factor(style,levels=c("无厅","有厅"))

###将是否有厅bind到已有数据集
dat0=cbind(dat0,style)	

###线性回归模型
lm1=lm(price~CATE+school+subway+style+floor+bedrooms+AREA,data=dat0)
summary(lm1)			#回归结果展示
par(mfrow=c(2,2))			#画2*2的图
plot(lm1,which=c(1:4))		#模型诊断图,存在异方差现象,对因变量取对数

###对数线性模型
lm2=lm(log(price)~CATE+school+subway+style+floor+bedrooms+AREA,data=dat0)
summary(lm2)			#回归结果展示
par(mfrow=c(2,2))			#画2*2的图
plot(lm2,which=c(1:4))		#模型诊断图,异方差现象得到消除

###有交互项的对数线性模型,城区和学区之间的交互作用
lm3=lm(log(price)~CATE*school+subway+style+floor+bedrooms+AREA,data=dat0)	
summary(lm3)			#回归结果展示

par(mfrow=c(2,3))			#画2*3的图
###分城区的学区房分组箱线图
boxplot(price~school,data=dat0[dat0$CATE=="石景山",],main="石景山区")
boxplot(price~school,data=dat0[dat0$CATE=="丰台",],main="丰台")
boxplot(price~school,data=dat0[dat0$CATE=="朝阳",],main="朝阳")
boxplot(price~school,data=dat0[dat0$CATE=="东城",],main="东城")
boxplot(price~school,data=dat0[dat0$CATE=="海淀",],main="海淀")
boxplot(price~school,data=dat0[dat0$CATE=="西城",],main="西城")

###假想情形,做预测,x_new是新的自变量
x_new=dat0[1,]
x_new[,1]="西城";x_new[,2]=2;x_new[,3]=1;x_new[,4]=85;x_new[,5]="low";x_new[,6]=1;x_new[,7]=1;x_new[,13]="有厅"
predict(lm3,x_new)		#预测值

三、函数补充

1、match函数
Match: default: match(x, table, nomatch = NA_integer_,incomparables = NULL), match(x, y)返回的是vector x中每                 个元素在vectory中对映的位置(positions in y),如果vector x中存在不在vectory中的元素,该元素处返回的是                     NA,incomparables选项在x,y类型不同时使用,现在对了类型的强制转换并不熟悉,并且这个很少会用到,一般是                 同类型的比较。
[eg]:
a <- c(20,10,12)
b <- 10:20
match(a,b)
输出结果为: [1] 11  1  3
即a中的元素在b中的位置

2、which函数
用法:which(test),返回test为真值的位置(指针)


猜你喜欢

转载自blog.csdn.net/tomocat/article/details/79153089