如果你手上有一批数据,你可能应用统计学、挖掘算法、可视化方法等技术玩转你的数据,但你没有数据的时候,我该怎么玩呢?接下来就带着大家玩玩没有数据情况下的数据分析。 本文从如下几个角度详细讲解数据分析的流程: 1、数据源的获取; 2、数据探索与清洗; 3、模型构建(聚类算法和线性回归); 4、模型预测; 5、模型评估; 一、数据源的获取 正如本文的题目一样,我要分析的是上海二手房数据,我想看看哪些因素会影响房价?哪些房源可以归为一类?我该如何预测二手房的价格?可我手上没有这样的数据样本,我该如何回答上面的问题呢? 互联网时代,网络信息那么发达,信息量那么庞大,随便找点数据就够喝一壶了。前几期我们已经讲过了如何从互联网中抓取信息,采用Python这个灵活而便捷的工具完成爬虫, 当然,上海二手房的数据仍然是通过爬虫获取的,爬取的平台来自于链家,页面是这样的: 我所需要抓取下来的数据就是红框中的内容,即上海各个区域下每套二手房的小区名称、户型、面积、所属区域、楼层、朝向、售价及单价。先截几张Python爬虫的代码,源代码和数据分析代码写在文后的链接中,如需下载可以到指定的百度云盘链接中下载。 上面图中的代码是构造所有需要爬虫的链接。
爬下来的数据是长这样的(总共28000多套二手房): 二、数据探索与清洗(一下均以R语言实现) 当数据抓下来后,按照惯例,需要对数据做一个探索性分析,即了解我的数据都长成什么样子。 1、户型分布 # 户型分布 library(ggplot2) type_freq <->-> # 绘图 type_p <- ggplot(data="type_freq," mapping="aes(x" =="" reorder(var1,="" -freq),y="Freq))" +="" geom_bar(stat='identity' ,="" fill='steelblue' )="" +="" theme(axis.text.x="" ="element_text(angle" =="" 30,="" vjust="0.5))" +="" xlab('户型')="" +="">-> type_p
# 把低于一千套的房型设置为其他 type <->-> house$type.new <- ifelse(house$户型="" %in%="" type,="">-> type_freq <->-> # 绘图 type_p <- ggplot(data="type_freq," mapping="aes(x" =="" reorder(var1,="" -freq),y="Freq))" +="" geom_bar(stat='identity' ,="" fill='steelblue' )="" +="" theme(axis.text.x="" ="element_text(angle" =="" 30,="" vjust="0.5))" +="" xlab('户型')="" +="">-> type_p 2、二手房的面积和房价的分布 # 面积的正态性检验 norm.test(house$面积) # 房价的正态性检验 norm.test(house$价格.W.)
3、二手房的楼层分布 原始数据中关于楼层这一变量,总共有151种水平,如地上5层、低区/6层、中区/11层、高区/40层等,我们觉得有必要将这151种水平设置为低区、中区和高区三种水平,这样做有助于后面建模的需要。 # 把楼层分为低区、中区和高区三种 house$floow <- ifelse(substring(house$楼层,1,2)="" %in%="" c('低区','中区','高区'),="">-> # 各楼层类型百分比分布 percent <- paste(round(prop.table(table(house$floow))*100,2),'%',sep=''>-> df <->-> df <- cbind(df,="">-> df
4、上海各地区二手房的均价 # 上海各区房价均价 avg_price <- aggregate(house$单价.平方米.,="" by="list(house$区域),">-> #绘图 p <- ggplot(data="avg_price," mapping="aes(x" =="" reorder(group.1,="" -x),="" y="x," group="1))" +="" geom_area(fill='lightgreen' )="" +="" geom_line(colour='steelblue' ,="" size="2)" +="" geom_point()="" +="" xlab('')="" +="">-> p
5、房屋建筑时间缺失严重
library(Hmisc) # 自定义众数函数 stat.mode <- function(x,="" rm.na="">-> if (rm.na == TRUE){ y = x[!is.na(x)] } res = names(table(y))[which.max(table(y))] return(res) } # 自定义函数,实现分组替补 my.impute <- function(data,="" category.col="">-> miss.col = NULL, method = stat.mode){ impute.data = NULL for(i in as.character(unique(data[,category.col]))){ sub.data = subset(data, data[,category.col] == i) sub.data[,miss.col] = impute(sub.data[,miss.col], method) impute.data = c(impute.data, sub.data[,miss.col]) } data[,miss.col] = impute.data return(data) } # 将建筑时间中空白字符串转换为缺失值 house$建筑时间[house$建筑时间 == ''] <->-> #分组替补缺失值,并对数据集进行变量筛选 final_house <- subset(my.impute(house,="" '区域',="" '建筑时间'),select="">-> #构建新字段,即建筑时间与当前2016年的时长 final_house <- transform(final_house,="" builtdate2now="">-> #删除原始的建筑时间这一字段 final_house <- subset(final_house,="" select="">-> 最终完成的干净数据集如下:
三、模型构建 tot.wssplot <- function(data,="" nc,="" seed="">-> #假设分为一组时的总的离差平方和 tot.wss <->-> for (i in 2:nc){ #必须指定随机种子数 set.seed(seed) tot.wss[i] <- kmeans(data,="" centers="i," iter.max="">-> } plot(1:nc, tot.wss, type='b', xlab='Number of Clusters', ylab='Within groups sum of squares',col = 'blue', lwd = 2, main = 'Choose best Clusters') } # 绘制不同聚类数目下的组内离差平方和 standrad <->-> myplot <- tot.wssplot(standrad,="" nc="">->
# 将样本数据聚为5类 set.seed(1234) clust <- kmeans(x="standrad," centers="5," iter.max="">-> table(clust$cluster) # 按照聚类的结果,查看各类中的区域分布 table(final_house$区域,clust$cluster) # 各户型的平均面积 aggregate(final_house$面积, list(final_house$type.new), mean) # 按聚类结果,比较各类中房子的平均面积、平均价格和平均单价 aggregate(final_house[,3:5], list(clust$cluster), mean) 从平均水平来看,我大体可以将28000多套房源合成为如下几种说法: a、大户型(3室2厅、4室2厅),属于第2类。平均面积都在130平以上,这种大户型的房源主要分布在青浦、黄埔、松江等地(具体可从各类中的区域分布图可知)。 b、地段型(房价高),属于第1类。典型的区域有黄埔、徐汇、长宁、浦东等地(具体可从各类中的区域分布图可知)。 c、大众蜗居型(面积小、价格适中、房源多),属于第4和5类。典型的区域有宝山、虹口、闵行、浦东、普陀、杨浦等地 d、徘徊型(大户型与地段型之间的房源),属于第3类。典型的区域有奉贤、嘉定、青浦、松江等地。这些地区也是将来迅速崛起的地方。 # 绘制面积与单价的散点图,并按聚类进行划分 p <- ggplot(data="final_house[,3:5]," mapping="aes(x" =="" 面积,y="单价.平方米.," color="">-> p <- p="" +="" geom_point(pch="20," size="">-> p + scale_colour_manual(values = c('red','blue', 'green', 'black', 'orange')) 接下来我想借助于已有的数据(房价、面积、单价、楼层、户型、建筑时长、聚类水平)构建线性回归方程,用于房价因素的判断及预测。由于数据中有离散变量,如户型、楼层等,这些变量入模的话需要对其进行哑变量处理。 # 构造楼层和聚类结果的哑变量 # 将几个离散变量转换为因子,目的便于下面一次性处理哑变量 final_house$cluster <->-> final_house$floow <->-> final_house$type.new <->-> # 筛选出所有因子型变量 factors <- names(final_house)[sapply(final_house,="" class)="=">-> # 将因子型变量转换成公式formula的右半边形式 formula <- f="">-><- as.formula(paste('~',="" paste(factors,="" collapse='+'>-> dummy <- dummyvars(formula="formula," data="">-> pred <- predict(dummy,="" newdata="">-> head(pred) # 将哑变量规整到final_house数据集中 final_house2 <->-> # 筛选出需要建模的数据 model.data <- subset(final_house2,select="">-> # 直接对数据进行线性回归建模 fit1 <- lm(价格.w.="" ~="" .,data="">-> summary(fit1)
library(car) powerTransform(fit1) 根据结果显示,0.23非常接近上表中的0值,故考虑将二手房的价格进行对数变换。 fit2 <- lm(log(价格.w.)="" ~="" .,data="">-> summary(fit2)
最后我们再看一下,关于最终模型的诊断结果: # 使用plot方法完成模型定性的诊断 opar <- par(no.readonly="">-> par(mfrow = c(2,2)) plot(fit2) par(opar)
今天的学习过程就到这里,如果有疑问可以给我留言或者加微信(lsx19890717)详聊。本文中的爬虫代码、R语言脚本和数据均可在如下链接中获取: 链接: http://pan.baidu.com/s/1c1BFhXe 密码: 36dm |
|
来自: 豪宅销售Edward > 《读书》