# 0 简介
今天学长向大家介绍一个适合作为毕设的项目
毕设分享 python大数据房价预测与可视化系统
项目获取:
https://gitee.com/assistant-a/project-sharing
1 数据爬取
1.需求描述
对于数据挖掘工程师来说,有时候需要抓取地理位置信息,比如统计房子周边基础设施信息,比如医院、公交车站、写字楼、地铁站、商场等,一般的爬虫可以采用python脚本爬取,有很多成型的框架如scrapy,但是想要爬百度地图就必须遵循它的javascriptapi,那么肯定需要自己写javascript脚本与百度api进行交互,问题是:这种交互下来的数据如何储存(直接写进文本or使用sql数据库?),如何自动化这种交互方式。
因此,本文的目标是用一个rails应用配合js脚本来实现这种自动化抓取和储存,思路是js脚本负责与百度地图api交互,rails服务器端负责储存抓取的数据,js和rails服务器用ajax方式传递数据.前提是rails服务器里已经有相应的房屋数据,如房屋的街道地址,小区名字等. 接下来需要做的就是为周边信息数据建表以及相应的关联表(因为它们为多对多关系)
2.流程详解
js代码在用户浏览器中执行,因此爬取的主要部分逻辑都需要写在js脚本里,而rails服务器端需要完成的是获得当前需要抓取的房屋数据以及储存js抓取的数据。下图为对id=1的房屋周边数据抓取的分解过程:
-
- 首先由用户在浏览器中点击开始按钮,激活getdatafromserver()方法,浏览器向rails服务器发送请求,服务器的return_next()方法返回当前需要抓取的房屋数据(主要是街道或者小区的位置信息)
-
- 通过getpoint方法,浏览器向baidu api 发送请求查找房屋坐标,若有结果则继续,否则直接递归调用getdatafromserver()
-
- 使用查询到的房屋坐标搜索周边的信息:对于每一类信息(如地铁,医院等),在查询到结果后立即向服务器发送查询结果以及房屋信息,并标记当前的数据类型(地铁,医院…).服务器在接收到数据后,先判断数据类型,然后根据类别再对房屋的周边信息进行储存.
-
- 如果完成当前房屋所有的周边数据的查询后, 再次调用getdatafromserver()来获得下一个房屋的数据
3. 代码实现
3.1 浏览器端(js)
1.getdatafromserver
: ajax向get_data_url地址以get方法请求json格式的数据,成功拿到数据后先用小区来匹配房屋坐标,如果失败再用街道匹配,若两者都没找到结果,那么此房屋的地理信息为空,则查询下一个房屋;若能找到房屋坐标,调用searchstart()开始搜索周边数据
function getdatafromserver() {
$.ajax({
type: "get",
url: get_data_url,
datatype: 'json',
success: function (house_data) {
// 拿到房屋数据后先显示出来
displayhousedata(house_data);
// 然后先用街道去查坐标
mygeo.getpoint(house_data.street, function (point) {
if (point) {
// 如果查到坐标,开始检索周围信息
searchstart(point, house_data);
} else {
// 如果
2.searchstart
和searchnearby
: searchstart为searchnearby的入口,searchnearby方法构建了一个bmap.localsearch对象的函数变量,调用searchnearby并传入关键词就可以查找house_loc附近的所有的包含关键词的位置信息,search_range能指定查找附近的范围.
bmap.localsearch通过onsearchcomplete指定了查询完成后的回调函数:这里我们对查询的结果做一个遍历,计算出这个查询结果与房屋的距离,然后将这些信息整合到一个数组里,传给senddata()来发送数据
function searchstart(point, house_data) {
// 先在地图上标记出来
map.centerandzoom(point, 16);
map.addoverlay(new bmap.marker(point));
// 首先查询此房屋的第一个关键词信息(公交车站,idx=0)
settimeout(function () {
searchnearby(point, house_data, 0);
}, timeinterval);
}
function searchnearby(house_loc, house_data, keyword_idx) {
var nearby_info = [];
// 清除地图覆盖物
map.clearoverlays();
var local = new bmap.localsearch(map, {
renderoptions: {map: map, autoviewport: false},
pagecapacity: 50,
onsearchcomplete: function (results) {
displayclear();
if (local.getstatus() == bmap_status_success) {
// 百度地图成功返回,将每个周边信息储存到nearby_info里
for (var i = 0; i < results.getcurrentnumpois(); i++) {
var locate = results.getpoi(i);
if (locate != null) {
// 查询结果与房屋的距离
var distance = parsefloat(map.getdistance(locate.point, house_loc)).tofixed(1);
nearby_info.push(locate.title + "/" + locate.point.lng + '/' + locate.point.lat + '/' + distance);
displaynearbydata(nearby_info, locate, distance)
}
}
// 获得百度地图查询结果后立即发送给服务器
return senddata(keywords_en[keyword_idx], nearby_info, house_data, house_loc, keyword_idx)
} else {
getdatafromserver();
console.log("no records with baiduapi:", local.getstatus());
return false;
}
}
});
local.searchnearby(keywords[keyword_idx], house_loc, search_range);
}
3.senddata
: senddata负责发送查询数据nearby_info,周边数据类型由nearby_type指定,房子本身的数据信息由house_data提供而坐标由house_loc给出, idx记录着现在查询的关键词的索引.
senddata使用ajax post方法提交数据, 当提交成功后,通过调用searchnearby并传递下一个关键词的id来检索这个房子其他周边信息;如果当前关键词已经是最后一个,那么调用getdatafromserver来启动下一轮的查询
function senddata(nearby_type, nearby_info, house_data, house_loc, idx) {
data = "nearby_type=" + nearby_type + "&nearby;_info=" + nearby_info + "&id;=" + house_data.id + "⪫=" + house_loc.lat + "&lng;=" + house_loc.lng;
$.ajax({
type: "post",
url: post_data_url,
data: data,
datatype: "json",
success: function (data) {
if (flag) {
console.log("warning", 'pause');
} else {
// 当查询到最后一个kewords时,请求服务器获得下一个房屋信息
if (idx == keywords.length - 1) {
getdatafromserver();
} else {
// 查询此房屋的下一个关键词信息
settimeout(function () {
searchnearby(house_loc, house_data, idx + 1);
}, timeinterval);
}
console.log("success", data);
}
return true;
},
error: function () {
alert('error in post');
return false;
},
timeout: function () {
alert('time out in post');
return false;
}
});
}
2 设计内容
2.1. 数据挖掘 (done)
1.1 在房价网站上利用爬虫爬下当前所有房子的价格和基本信息(房型、面积、楼层、建造时间等)
1.2 利用百度api对每套房产的周边信息进行挖掘(公交车站、地铁、写字楼、医院、学校、商场等)
1.3 将所有信息储存在关系型数据里,构建数据仓库(data warehouse)
2.2. 建立模型对数据进行分析(under construction)
2.1 选择模型
2.2 训练
2.3. 数据可视化(partial done)
3.1 导入百度的可视化工具库(echarts)
3.2 利用训练的模型对指定房屋价格进行评估和预测,并以科学地方法将结果进行可视化展示
房屋预测功能具体应用场景:
-
对于买家,输入那个房子的坐标,我们通过这个数据集对这个房子的价钱进行预测,以帮助买家合理判断值不值买这个房子(开发中)
-
对于卖家,输入他自己的房子坐标,我们可以对这个房子价钱进行评估,让卖家对自己的卖价有个大致的定位,更好的选择自己的出手价格(开发中)
设计效果截图
数据说明
现有的一些字段以及字段之间的关联如下:
data_type.png
7.开发
原始数据由[scrapy-hoursepricing]爬取,抓取后的数据将存为json格式,然后由housepricing进行解析并储存在数据库中
本项目由rails框架开发,请自行安装相关环境,请先fork此项目,然后运行下面:
git clone your_forked_project
cd project_path
bundle install
rake db:migrate
rake db:seed
在浏览器中输入localhost:3000
,即可访问主页
8.docker运行
为了方便运行和部署,这里提供了简单的docker镜像。
开发者首先需要在电脑上安装docker
和docker-compose
,然后运行下面:
# 编辑数据库配置
cp docker-util/app.env.example docker-util/app.env
vim docker-util/app.env
# 拉取或生成镜像
docker-compose build
# or
docker pull pengedy/housepricing
# 运行
docker-compose up
即可访问http://localhost:3000
若需要原数据(我目前用的数据),请导入根目录下的mydb.dump
到postgresql数据库
最后
项目分享:
发表评论