文章目录
- 0 前言
- 1 课题背景
- 2 数据爬取
- 2.1 爬虫简介
- 2.2 房价爬取
- 3 数据可视化分析
- 3.1 ECharts
- 3.2 相关可视化图表
- 4 其他分析
- 4.1 导入相关的数据
- 4.2 导入训练数据集和测试数据集
- 4.3 观察各项主要特征与房屋售价的关系
- 5 最后
0 前言
今天分享一个大数据毕设项目:毕设分享 大数据房价数据分析及可视化(源码分享)
项目获取:
https://gitee.com/sinonfin/algorithm-sharing
实现效果
毕业设计 房价大数据可视化分析
1 课题背景
房地产是促进我国经济持续增长的基础性、主导性产业。如何了解一个城市的房价的区域分布,或者不同的城市房价的区域差异。如何获取一个城市不同板块的房价数据?
本项目利用Python实现某一城市房价相关信息的爬取,并对爬取的原始数据进行数据清洗,存储到数据库中,利用pyechart库等工具进行可视化展示。
2 数据爬取
2.1 爬虫简介
网络爬虫是一种按照一定的规则,自动地抓取万维网信息的程序或者脚本。爬虫对某一站点访问,如果可以访问就下载其中的网页内容,并且通过爬虫解析模块解析得到的网页链接,把这些链接作为之后的抓取目标,并且在整个过程中完全不依赖用户,自动运行。若不能访问则根据爬虫预先设定的策略进行下一个 URL的访问。在整个过程中爬虫会自动进行异步处理数据请求,返回网页的抓取数据。在整个的爬虫运行之前,用户都可以自定义的添加代理,伪 装 请求头以便更好地获取网页数据。
爬虫流程图如下:
实例代码
# get方法实例 import requests #先导入爬虫的库,不然调用不了爬虫的函数 response = requests.get("http://httpbin.org/get") #get方法 print( response.status_code ) #状态码 print( response.text )
2.2 房价爬取
累计爬取链家深圳二手房源信息累计18906条
- 爬取各个行政区房源信息;
- 数据保存为DataFrame;
相关代码
from bs4 import BeautifulSoup import pandas as pd from tqdm import tqdm import math import requests import lxml import re import time area_dic = {'罗湖区':'luohuqu', '福田区':'futianqu', '南山区':'nanshanqu', '盐田区':'yantianqu', '宝安区':'baoanqu', '龙岗区':'longgangqu', '龙华区':'longhuaqu', '坪山区':'pingshanqu'} # 加个header以示尊敬 headers = {'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/65.0.3325.146 Safari/537.36', 'Referer': 'https://sz.lianjia.com/ershoufang/'} # 新建一个会话 sess = requests.session() sess.get('https://sz.lianjia.com/ershoufang/', headers=headers) # url示例:https://sz.lianjia.com/ershoufang/luohuqu/pg2/ url = 'https://sz.lianjia.com/ershoufang/{}/pg{}/' # 当正则表达式匹配失败时,返回默认值(errif) def re_match(re_pattern, string, errif=None): try: return re.findall(re_pattern, string)[0].strip() except IndexError: return errif # 新建一个DataFrame存储信息 data = pd.DataFrame() for key_, value_ in area_dic.items(): # 获取该行政区下房源记录数 start_url = 'https://sz.lianjia.com/ershoufang/{}/'.format(value_) html = sess.get(start_url).text house_num = re.findall('共找到 (.*?) 套.*二手房', html)[0].strip() print('💚{}: 二手房源共计「{}」套'.format(key_, house_num)) time.sleep(1) # 页面限制🚫 每个行政区只能获取最多100页共计3000条房源信息 total_page = int(math.ceil(min(3000, int(house_num)) / 30.0)) for i in tqdm(range(total_page), desc=key_): html = sess.get(url.format(value_, i+1)).text soup = BeautifulSoup(html, 'lxml') info_collect = soup.find_all(class_="info clear") for info in info_collect: info_dic = {} # 行政区 info_dic['area'] = key_ # 房源的标题 info_dic['title'] = re_match('target="_blank">(.*?)int(y)}', (x.mean(), y), ha='center', va='bottom') # Format x-axes axs[1].set_xticklabels(axs[1].xaxis.get_majorticklabels(), rotation=90) axs[0].xaxis.set_visible(False) # Narrow the gap between the plots plt.subplots_adjust(hspace=0.01)
从上图结果可以看出,我们训练数据集中Neighborhood这一列数据不均匀,NAmes有299条数据,而Blueste只有4条数据,Gilbert只有6条数据,GmHill只有2条数据,这样造成数据没那么准确。
(6)Overall Qual 与SalePrice
总体评价越高,应该房屋的价格越高
#Overall Qual var = 'Overall_Qual' data = pd.concat([training_data['SalePrice'], training_data[var]], axis=1) fig = sns.boxplot(x=var, y="SalePrice", data=data) fig.axis(ymin=0, ymax=800000)
3.数值型变量
(1) Lot Area与SalePrice
#数值型变量 #1.Lot Area sns.jointplot( x='Lot_Area', y='SalePrice', data=training_data, stat_func=None, kind="reg", ratio=4, space=0, scatter_kws={ 's': 3, 'alpha': 0.25 }, line_kws={ 'color': 'black' } )
看起来没有什么明显的趋势,散点图主要集中在前半部分,不够分散
(2)Gr_Liv_Area与SalePrice
Gr_Liv_Area代表建筑在土地上的房屋的面积
猜测两者应该成正相关,即房屋面积越大,房屋的价格越高
sns.jointplot( x='Gr_Liv_Area', y='SalePrice', data=training_data, stat_func=None, kind="reg", ratio=4, space=0, scatter_kws={ 's': 3, 'alpha': 0.25 }, line_kws={ 'color': 'black' } )
结果:两者的确呈现正相关的线性关系,发现Gr_ Liv_ Area中有处于5000以上的异常值
编写函数,将5000以上的Gr_ Liv_ Area异常值移除
def remove_outliers(data, variable, lower=-np.inf, upper=np.inf): """ Input: data (data frame): the table to be filtered variable (string): the column with numerical outliers lower (numeric): observations with values lower than this will be removed upper (numeric): observations with values higher than this will be removed Output: a winsorized data frame with outliers removed """ data=data[(data[variable]>lower)&(data[variable]
再次绘图
两者的确呈现正相关的线性关系
(3)Total_Bsmt_SF与SalePrice
#3.Total Bsmt SF sns.jointplot( x='Total_Bsmt_SF', y='SalePrice', data=training_data, stat_func=None, kind="reg", ratio=4, space=0, scatter_kws={ 's': 3, 'alpha': 0.25 }, line_kws={ 'color': 'black' } )
(4)TotRms_AbvGrd与SalePrice
#4.TotRmsAbvGrd sns.jointplot( x='TotRms_AbvGrd', y='SalePrice', data=training_data, stat_func=None, kind="reg", ratio=4, space=0, scatter_kws={ 's': 3, 'alpha': 0.25 }, line_kws={ 'color': 'black' } )
4. 绘制相关性矩阵
#绘制相关性矩阵 corrmat = training_data.corr() f, ax = plt.subplots(figsize=(40, 20)) sns.heatmap(corrmat, vmax=0.8,square=True,cmap="PiYG",center=0.0)
其中数值型变量中,Overall_Qual(房屋的整体评价) 、Year_Built(房屋建造年份)、Year_Remod/Add(房屋整修年份)、Mas
Vnr Area(房屋表层砌体模型)、Total_ Bsmt_ SF(地下总面积)、1stFlr_SF(一楼总面积) 、 Gr_ L
iv_Area(地上居住面积)、Garage_Cars (车库数量)、Garage_Area(车库面积)都与呈正相关
最后从Year_Built(房屋建造年份)、Year_Remod/Add(房屋整修年份)中选取Year_Built,从1stFlr_SF(一楼总面积)
、 Gr_ L iv_Area(地上居住面积)中选取Gr_ L iv_Area,从Garage_Cars
(车库数量)、Garage_Area(车库面积)中选取Garage_Cars (车库数量)。
6. 拟合模型
sklearn中的回归有多种方法,广义线性回归集中在linear_model库下,例如普通线性回归、Lasso、岭回归等;另外还有其他非线性回归方法,例如核svm、集成方法、贝叶斯回归、K近邻回归、决策树回归、随机森林回归方法等,通过测试各个算法的
(1)加载相应包
#拟合数据 from sklearn import preprocessing from sklearn import linear_model, svm, gaussian_process from sklearn.ensemble import RandomForestRegressor from sklearn.cross_validation import train_test_split import numpy as np
(2)查看各列缺失值
#查看各列缺失值 print(training_data.Overall_Qual.isnull().any()) print(training_data.Gr_Liv_Area.isnull().any()) print(training_data.Garage_Cars.isnull().any()) print(training_data.Total_Bsmt_SF.isnull().any()) print(training_data.Year_Built.isnull().any()) print(training_data.Mas_Vnr_Area.isnull().any())
发现Total_Bsmt_SF和Mas_Vnr_Area两列有缺失值
#用均值填补缺失值 training_data.Total_Bsmt_SF=training_data.Total_Bsmt_SF.fillna(training_data.Total_Bsmt_SF.mean()) training_data.Mas_Vnr_Area=training_data.Mas_Vnr_Area.fillna(training_data.Mas_Vnr_Area.mean()) print(training_data.Total_Bsmt_SF.isnull().any()) print(training_data.Mas_Vnr_Area.isnull().any())
(3)拟合模型
# 获取数据 from sklearn import metrics cols = ['Overall_Qual','Gr_Liv_Area', 'Garage_Cars','Total_Bsmt_SF', 'Year_Built','Mas_Vnr_Area'] x = training_data[cols].values y = training_data['SalePrice'].values X_train,X_test, y_train, y_test = train_test_split(x, y, test_size=0.33, random_state=42) clf = RandomForestRegressor(n_estimators=400) clf.fit(X_train, y_train) y_pred = clf.predict(X_test) 计算MSE: print(metrics.mean_squared_error(y_test,y_pred))
(4)绘制预测结果的散点图
import numpy as np x = np.random.rand(660) plt.scatter(x,y_test, alpha=0.5) plt.scatter(x,y_pred, alpha=0.5,color="G")
(5)加载测试集数据
test_data=pd.read_csv("ames_test.csv") test_data.head(5)
查看缺失值
#查看各列缺失值 print(test_data.Overall_Qual.isnull().any()) print(test_data.Gr_Liv_Area.isnull().any()) print(test_data.Garage_Cars.isnull().any()) print(test_data.Total_Bsmt_SF.isnull().any()) print(test_data.Year_Built.isnull().any()) print(test_data.Mas_Vnr_Area.isnull().any())
#用均值填补缺失值 test_data.Garage_Cars=training_data.Garage_Cars.fillna(training_data.Garage_Cars.mean()) print(test_data.Garage_Cars.isnull().any())
(6)预测测试集的房价
#预测 cols = ['Overall_Qual','Gr_Liv_Area', 'Garage_Cars','Total_Bsmt_SF', 'Year_Built','Mas_Vnr_Area'] x_test_value= test_data[cols].values test_pre=clf.predict(x_test_value) #写入文件 prediction = pd.DataFrame(test_pre, columns=['SalePrice']) result = pd.concat([test_data['Id'], prediction], axis=1) result.to_csv('./Predictions.csv', index=False) test_data.Garage_Cars=training_data.Garage_Cars.fillna(training_data.Garage_Cars.mean()) print(test_data.Garage_Cars.isnull().any())
(6)预测测试集的房价
#预测 cols = ['Overall_Qual','Gr_Liv_Area', 'Garage_Cars','Total_Bsmt_SF', 'Year_Built','Mas_Vnr_Area'] x_test_value= test_data[cols].values test_pre=clf.predict(x_test_value) #写入文件 prediction = pd.DataFrame(test_pre, columns=['SalePrice']) result = pd.concat([test_data['Id'], prediction], axis=1) result.to_csv('./Predictions.csv', index=False)
5 最后
项目获取:
https://gitee.com/sinonfin/algorithm-sharing
猜你喜欢
网友评论
- 搜索
- 最新文章
- 热门文章