线性回归和时间序列分析北京房价影响因素可视化案例1:https://developer.aliyun.com/article/1485144
回归模型
策略
- 从tradeTime中提取年份和月份
按年度和月份分组,得到房屋的数量和均价
- 拆分数据集:
- 对于年[2010-2017]=在这组年上训练并运行回归模型
- 对于>2017年:逐月对测试样本并预测平均价格
平均价格总览
首先我们需要看看我们想要预测什么
df3$year <- year(df3$tradeTimeTs) df3$month <- month(df3$tradeTimeTs)
df3 %>% filter(year>2009) %>% group_by(monthlyTrad) %>% summarise(count=n(), mean = mean(price)) %>% ggplot(aes(x=monthlyTradeTS, y= mean)) +
- 平均价格上涨至2017年中期,然后迅速下降
- 同时,房屋数量随着价格的上涨而增加,而且现在房屋交易的数量也随着价格的上涨而减少。
准备训练/测试样本
我在2017-01-01拆分数据。对于所有样本,我需要把分类特征变成伪变量。
df_train <- data.frame(df %>% filter(year>2009 & year<2017)) df_test <- data.frame(df %>% filter(year>=2017)) as.data.frame(cbind( df_train %>% select_if(is.numeric) %>% select(-Lng, -Lat, -year, -month), 'bldgType'= dummy.code(df_train$buildingType), 'bldgStruc'= dummy.code(df_train$buildingStructure), 'renovation'= dummy.code(df_train$renovationCondition), 'hasElevator'= dummy.code(df_train$elevator),
在这一步中,我只训练一个线性模型
regressors<-c('lm') Control <- trainControl(method = "cv",number = 5, repeats=3) for(r in regressors){ cnt<-cnt+1 res[[cnt]]<-train(totalPrice ~., data = train ,method=r,trControl = Control)
r^2在0.88左右,不错。让我们看看细节。
训练精度
g1<-ggplot(data=PRED,aes(x=Prediction,y=True)) + geom_jitter() + geom_smooth(method='lm',size=.5) + #计算指标 mse <- mean((PRED$True-PRED$Prediction)^2) rmse<-mse^0.5 SSE = sum((PRED$Pred - PR
## [1] "MSE: 15952.845934 RMSE : 126.304576 R2 :0.795874"
- 所以看起来残差还不错(分布是正态的,以0为中心),但对于低价格来说似乎失败了。
训练和测试样本的预测与时间的关系
- 基本上与上述相同,但我将重复预测所有月份的训练数据
- 我的目标指标是平均房价。
- 训练是在10多年的训练样本中完成的,因此逐月查看预测将非常有趣。
# 训练样本->训练精度 for (i in 1:length(dates_train)){ current_df <- prepareDF(current_df) current_pred <- mean(predict(res[[1]],current_df)) #运行测试样本-->测试精度 for (i in 1:length(dates_test)){ current_df <- prepareDF(current_df) current_pred <- mean(predict(res[[1]],current_df))
RES %>% reshape2::melt(id=c('date','split')) %>% ggplot(aes(x=date,y=value)) + geom_line(aes(color=variable, lty=split),size=1) +
- 预测对于2012年之后的数据确实非常好,这可能与有足够数据的月份相对应
改进
地理位置作为特征
- 下面是一个有趣的图;它显示了每个位置的总价格。在二维分布的中心,价格更高。
- 这个想法是计算每个房子到中心的距离,并关联一个等级/分数
BeijingLoc <- data.frame('Long'=116.4075,'Lat' = 39.904) df3 %>% ggplot(aes(x=Lng,y=Lat)) + geom_point(aes(color=price),size=.1,alpha=.5) + theme(legend.position = 'bottom') +