目录
一、需求说明
深圳二手房数据分析及价格预测的总体目标:基于Python数据科学基础,利用所学Python语言和数据分析的相关知识,对深圳二手房价数据进行分析和建立房价预测模型进行预测,实现数据合并对数据质量进行检测和自变量与因变量进行可视化分析建立预测模型,并能使用户通过其显示结果和可视化对每种特征的变化有一个直观的了解,从而达到二手房价预测的目的。
1.1基本任务
- 数据质量检验,筛选出有价值的数据。
- 因变量分析:对单位房价进行分析。
- 自变量分析和可视化:实现对深圳二手房价各种特征的分析。包括分类变量和连续变量。
- 对数据集进行抽样。分训练数据和测试数据作测试。对数据进行二分类处理,分类变量生产哑变量。
- 线性回归模型,对房价进行预测。
1.2 任务目的
1.数据检测模块
本模块的主要目的是导入数据集对数据进行合并,数据检测,数据预处理,使数据更加有合理性。
2.因变量分析模块
本模块的主要目的是对单位面积房价分析,显示直方图单位面积房价各区变化,防止出现异常值的错误。
3.自变量分析模块
本模块的主要目的是对自变量分析,查看整体数据有没有异常值,分为分类变量和连续变量,更好的查看。
4.自变量对因变量可视化模块
本模块的主要目的是利用可视化,可以更直观的展现这些自变量是否对因变量有影响,相关度大不大,为下面的预测提供更好的数据。
5.建立预测模型模块
本模块的主要目的是划分数据集,对数据进行更一步的处理,对模型进行训练,为下一个模块更好的预测。
6. 预测模块
本模块的主要目的是预测一个客户所需求的房子的房价
1.3测试数据
- 找一个条件为南山区、有3个房间、面积大概再80㎡、有地铁、学区房的房子的大概花费
二、概要设计说明
数据检测模块 |
自变量分析模块 |
因变量分析模块 |
可视化模块 |
建立预测模型模块 |
预测模块 |
三、详细设计
3.1 数据检测模块
导入库读取数据
import pandas as pd
import os
file_path="D:\jupyter\data"
#读取file_path目录下的所有文件
file_name=os.listdir(file_path)
df=pd.DataFrame()
#读取数据
for i in file_name:
file=pd.read_excel(os.path.join(file_path,i))
df=df.append(file)
df.head()
print(df.describe()) #查看数据描述
数据的处理(异常值,重复值,缺失值)
df=df.drop(columns='Unnamed: 0')
#缺失值
df.isna().sum() #是否有缺失值总数
#重复值
df.duplicated().sum()
#删除重复值
df=df.drop_duplicates()
area_map={'baoan':'宝安','dapengxinqu':'大鹏新区','futian':'福田','guangming':'光明',
'longhua':'龙华','luohu':'罗湖','nanshan':'南山','pingshan':'坪山','yantian':'盐田'
,'longgang':'龙岗'}
df['district']=df['district'].apply(lambda x : area_map[x])
df.head()
df.to_excel('D:\jupyter\data.xls')
3.2 因变量分析模块
import matplotlib.pyplot as plt
import matplotlib
matplotlib.rcParams['axes.unicode_minus']=False #解决保存图像时负号'-'显示为方块的问题
plt.rcParams['font.sans-serif'] = ['SimHei'] #指定默认字体 ,解决不能显示中文字体的问题#
data=pd.read_excel('D:\jupyter\data.xls')
data.head()
#因变量图形(主要看看形态)
# 单位面积房价直方图
fangjia=data['per_price']
plt.hist(fangjia,bins=20,density=0,facecolor='lightblue',edgecolor='black')
plt.xlabel("单位面积房价(万/m*m)",fontname='SimHei',size=13)
plt.ylabel("频数",fontname='SimHei',size=13)
plt.title('单位面积房价分布')
plt.show()
#有明显偏差,呈现右偏分布。单位面积房价集中在3-6万之间。存在少数天价房,
#从而拉高了房价的平均水平。
print(data.per_price.agg(['mean','median','std'])) #查看price的均值、中位数和标准差等更多信息
print(data.per_price.quantile([0.25,0.5,0.75]))
pd.concat([(data[data.per_price==min(data.per_price)]),(data[data.per_price==max(data.per_price)])])#查看房价最高和最低的两条观测
3.3 自变量分析模块
for i in range(8):
if i!=3:
print(data.columns.values[i],":")
print(data[data.columns.values[i]].agg(['value_counts']).T)
print('==================================')
else:
continue
print('AREA:')
print(data.AREA.agg(['min','mean','max','median','std']).T)
print('==================================')
print('per_price:')
print(data.per_price.agg(['min','mean','max','median','std']).T)
3.4 可视化模块
【district】
#不同城区的单位面积房价
import seaborn as sns
d=data.groupby(by=['district'])['per_price']
d.mean().plot(kind='bar')
plt.xlabel("地区")
plt.ylabel("单位面积房价(万元/平方米)")
plt.title('各个区单位面积房价均值比较')
z=data[['district','per_price']]
plt.figure(figsize=(10,5))
# sns.set(font='SimHei')
sns.boxplot(x='district',y='per_price',data=z)
plt.xlabel("地区")
plt.ylabel("单位面积房价(万元/平方米)")
plt.title('不同城区的单位面积房价')
#不同城区的房屋单位面积房价差异较大,宝安区、福田区、南山区的单位面积房价
# 明显偏高
各个区的房屋信息数量情况比较中可以看出罗湖区的房屋信息数量最多,说明当地经济水平高,人流量大。
南山区的平均房价最高。
不同城区的房屋单位面积房价差异较大,宝安区、福田区、南山区的单位面积房价明显偏高,浮动较大。
房屋所在区对单位面积房价影响明显。
【roomnum】
room=data.groupby(by=['roomnum'])['per_price']
room.mean().plot(kind='bar')
plt.xlabel("卧室数")
plt.ylabel("单位面积房价(万元/平方米)")
plt.title('不同卧室数的单位面积房价比较')
plt.figure(figsize=(10,5))
x=data[['roomnum','per_price']]
sns.boxplot(x='roomnum',y='per_price',data=x)
plt.xlabel("卧室数")
plt.ylabel("单位面积房价(万元/平方米)")
plt.title('不同卧室数的单位面积房价')
不同卧室数对单位面积房价有轻微影响。且不同房数的单位面积房价相差不大。
【hall】
hall=data.groupby(by=['hall'])['per_price']
hall.mean().plot(kind='bar')
plt.xlabel("厅数")
plt.ylabel("单位面积房价(万元/平方米)")
plt.title('不同厅数的单位面积房价')
plt.figure(figsize=(10,5))
c=data[['hall','per_price']]
sns.boxplot(x='hall',y='per_price',data=c)
plt.xlabel("厅数")
plt.ylabel("单位面积房价(万元/平方米)")
plt.title('不同厅数的单位面积房价')
不同厅数对单位面积房价有轻微影响。3间厅数的单位面积房价明显偏高,其他厅数的房价相差不大。
【C_floor】
cfloor=data.groupby(by=['C_floor'])['per_price']
cfloor.mean().plot(kind='bar')
plt.xlabel("楼层")
plt.ylabel("单位面积房价(万元/平方米)")
plt.title('不同楼层的单位面积房价')
plt.figure(figsize=(6,5))
v=data[['C_floor','per_price']]
sns.boxplot(x='C_floor',y='per_price',data=v)
plt.xlabel("楼层")
plt.ylabel("单位面积房价(万元/平方米)")
plt.title('不同楼层的单位面积房价')
不同楼层对单位面积房价影响不大。
【subway】
#是否临近地铁对单位面积房价的影响
plt.figure(figsize=(4,5))
rail=data.groupby(by=['subway'])['per_price']
rail.mean().plot(kind='bar')
plt.xlabel("地铁")
plt.ylabel("单位面积房价(万元/平方米)")
plt.title('是否临近地铁对单位面积房价影响')
plt.figure(figsize=(4,5))
b=data[['subway','per_price']]
sns.boxplot(x='subway',y='per_price',data=b)
plt.xlabel("是否临近地铁")
plt.ylabel("单位面积房价(万元/平方米)")
plt.title('是否临近地铁的单位面积房价')
靠近地铁的单位面积房价更高。
【school】
#是否是学区房对房价的影响
plt.figure(figsize=(4,5))
school=data.groupby(by=['school'])['per_price']
school.mean().plot(kind='bar')
plt.xlabel("学区")
plt.ylabel("单位面积房价(万元/平方米)")
plt.title('是否是学区对单位面积房价影响')
plt.figure(figsize=(5,5))
sns.boxplot(x='school',y='per_price',data=data)
plt.xlabel("学区")
plt.ylabel("单位面积房价(万元/平方米)")
plt.title('是否是学区的单位面积房价')
学区房的单位面积房价较高。
【area】
#面积AREA和单位面积房价per_price的散点图
plt.figure(figsize=(20,6))
sns.set(font='SimHei')
plt.scatter(x=data.AREA,y=data.per_price,marker='o')
plt.xlabel("面积")
plt.ylabel("单位面积房价")
从左到右逐渐稀疏,左密集右稀疏,右偏函数,考虑取对数。
#面积AREA和单位面积房价per_price(取对数后)的散点图
import numpy as np
per=np.log(data['per_price'])
plt.figure(figsize=(20,6))
sns.set(font='SimHei')
plt.scatter(x=data.AREA,y=per,marker='o')
plt.xlabel("面积")
plt.ylabel("单位面积房价(对数)")
房价取对数后,散点图的结果类似三角关系,散点结果点任比较密
#面积AREA(取对数后)和单位面积房价per_price(取对数后)的散点图
per=np.log(data['per_price'])
area=np.log(data['AREA'])
plt.figure(figsize=(20,8))
sns.set(font='SimHei')
plt.scatter(x=area,y=per,marker='o')
plt.xlabel("面积(对数)")
plt.ylabel("单位面积房价(对数)")
图形为中间密两边疏的状态,这样的图无论是X分布还是Y分布都是正态分布
同等面积的单位面积房价波动较大。
3.5 建立预测模型模块
导入数据
import pandas as pd
import numpy as np
data=pd.read_excel('D:\jupyter\data.xls')
data_new=pd.concat([data.iloc[:,0:4],data.iloc[:,6:10]],axis=1)
哑变量
def hall(hall):
if hall== 3:
return 1
else:
return 0
data_new['Hall'] = data_new.apply(lambda x: hall(x.hall), axis=1)
a = pd.get_dummies(data_new['district'])
data_new['per_price_log']=np.log(data_new['per_price'])
data_new['AREA_log']=np.log(data_new['AREA'])
data_new=pd.concat([data_new,a],axis=1)
data_new=data_new.drop(['district','hall','AREA','per_price'],axis=1)
data_new['Hall'].corr(data_new['per_price_log'])
3.6预测模块
抽样
x=pd.concat([data_new.iloc[:,0:4],data_new.iloc[:,5:]],axis=1)
print(x)
y = data_new.loc[:, 'per_price_log']
# 数据分割,随机采样30%作为测试样本,其余作为训练样本
from sklearn.model_selection import train_test_split
x_train, x_test, y_train, y_test = train_test_split(x, y, random_state=1,stratify=a, test_size=0.2)
训练模型
import statsmodels.api as sm
import matplotlib.pyplot as plt
#x_train=sm.add_constant(x_train)
Model=sm.OLS(y_train,x_train)
Model=Model.fit()
print(Model.summary())
画模型
x = Model.predict(x_test)
plt.figure(figsize=(8,8)) #设置画布
plt.scatter(x,y_test,color='black')
plt.xlabel('predict1',fontname='SimHei',size=15)
plt.ylabel('resid1',fontname='SimHei',size=15)
plt.show()
导出模型
# 导出模型文件
from sklearn.externals import joblib
joblib.dump(Model,'Model.pickle')
预测结果
import math
pX=pd.DataFrame({'roomnum':[3],'school':[1],'subway':[1],'Hall':[0],'AREA_log':[np.log(80)],'光明':[0],'南山':[1],'坪山':[0],'大鹏新区':[0],'宝安':[0],'盐田':[0],'福田':[0],'罗湖':[0],'龙华':[0],'龙岗':[0]})
#Model.predict(sm.add_constant(pX,has_constant='add'))
x=Model.predict(pX)
print("单位面积房价: ",round(math.exp(x),2), "万元/平方米")
print("总价:",round(math.exp(x)*80,2), "万元")
数据源 http://链接: https://pan.baidu.com/s/1gsSlTEdg0rMutgGTCQUjdA 提取码: tt5m 复制这段内容后打开百度网盘手机App,操作更方便哦
(小组合作,合作者:m0_63954396(白日熊猫))