import matplotlib # 导入图表模块
import matplotlib.pyplot as plt # 导入绘图模块
# 避免中文乱码
matplotlib.rcParams['font.sans-serif'] = ['SimHei']
matplotlib.rcParams['axes.unicode_minus'] = False
# 显示饼图
def pie_chart(size,label,title):
"""
绘制饼图
size:各部分大小
labels:设置各部分标签
labeldistance:设置标签文本距圆心位置,1.1表示1.1倍半径
autopct:设置圆里面文本
shadow:设置是否有阴影
startangle:起始角度,默认从0开始逆时针转
pctdistance:设置圆内文本距圆心距离
"""
plt.figure() # 图形画布
plt.pie(size, labels=label,labeldistance=1.05,
autopct="%1.1f%%", shadow=True, startangle=0, pctdistance=0.6)
plt.axis("equal") # 设置横轴和纵轴大小相等,这样饼才是圆的
plt.title(title, fontsize=12)
plt.legend(bbox_to_anchor=(0.03, 1)) # 让图例生效,并设置图例显示位置
plt.show() # 显示饼图
def broken_line(y,y_pred,title):
'''
y:y轴折线点,也就是房子总价
y_pred,预测房价的折线点
color:折线的颜色
marker:折点的形状
'''
plt.figure() # 图形画布
plt.plot(y, color='r', marker='o',label='真实房价') # 绘制折线,并在折点添加蓝色圆点
plt.plot(y_pred, color='b', marker='*',label='预测房价')
plt.xlabel('房子数量')
plt.ylabel('房子总价')
plt.title(title) # 表标题文字
plt.legend() # 显示图例
plt.grid() # 显示网格
plt.show() # 显示图表
# 显示均价条形图
def average_price_bar(x,y, title):
plt.figure() # 图形画布
plt.bar(x,y, alpha=0.8) # 绘制条形图
plt.xlabel("区域") # 区域文字
plt.ylabel("均价") # 均价文字
plt.title(title) # 表标题文字
# 为每一个图形加数值标签
for x, y in enumerate(y):
plt.text(x, y + 100, y, ha='center')
plt.show() # 显示图表
# 显示装修条形图
def renovation_bar(x,y, title):
plt.figure() # 图形画布
plt.bar(x,y, alpha=0.8) # 绘制条形图
plt.xlabel("装修类型") # 区域文字
plt.ylabel("数量") # 均价文字
plt.title(title) # 表标题文字
# 为每一个图形加数值标签
for x, y in enumerate(y): #关于enumerate的用法,https://blog.csdn.net/Windgs_YF/article/details/89025136
plt.text(x, y + 10, y, ha='center')
plt.show() # 显示图表
# 显示热门户型的水平条形图
def bar(price,type, title):
"""
绘制水平条形图方法barh
参数一:y轴
参数二:x轴
"""
plt.figure() # 图形画布
plt.barh(type, price, height=0.3, color='r', alpha=0.8) # 从下往上画水平条形图
plt.xlim(0, 15000) # X轴的均价0~15000
plt.xlabel("均价") # 均价文字
plt.title(title) # 表标题文字
# 为每一个图形加数值标签
for y, x in enumerate(price):
plt.text(x + 10, y,str(x) + '元', va='center')
plt.show() # 显示图表
import pandas as pd # 导入数据统计模块
from sklearn.svm import LinearSVR # 导入回归函数
#解决数据输出时列名不对齐的问题
pd.set_option('display.unicode.east_asian_width', True)
data = pd.read_csv('data.csv') # 读取csv数据文件
data.head()
del data['Unnamed: 0'] # 将索引列删除
data.dropna(axis=0, how='any', inplace=True) # 删除data数据中的所有空值
data['单价'] = data['单价'].map(lambda d: d.replace('元/平米', '')) # 将单价“元/平米”去掉
data['单价'] = data['单价'].astype(float) # 将房子单价转换为浮点类型
data['总价'] = data['总价'].map(lambda z: z.replace('万', '')) # 将总价“万”去掉
data['总价'] = data['总价'].astype(float) # 将房子总价转换为浮点类型
data['建筑面积'] = data['建筑面积'].map(lambda p: p.replace('平米', '')) # 将建筑面价“平米”去掉
data['建筑面积'] = data['建筑面积'].astype(float) # 将建筑面积转换为浮点类型
data.head()
# 获取各区二手房均价分析
def get_average_price():
group = data.groupby('区域') # 将房子区域分组
average_price_group = group['单价'].mean() # 计算每个区域的均价
region = average_price_group.index # 获取average_price_group下的index属性(区域)
average_price = average_price_group.values.astype(int) # 区域对应的均价
return region, average_price # 返回区域与对应的均价
region, average_price= get_average_price() # 获取房子区域与均价
average_price_bar(region,average_price,'各区二手房均价分析')
# 获取各区房子数量比例
def get_house_number():
group_number = data.groupby('区域').size() # 房子区域分组数量
region = group_number.index # 区域
numbers = group_number.values # 获取每个区域内房子出售的数量
percentage = numbers / numbers.sum() * 100 # 计算每个区域房子数量的百分比
return region, percentage # 返回百分比
region, percentage = get_house_number() # 获取房子区域与数量百分比
pie_chart(percentage,region,'各区二手房数量所占比例') # 显示图表
# 获取全市二手房装修程度对比
def get_renovation():
group_renovation = data.groupby('装修').size() # 将房子装修程度分组并统计数量
type = group_renovation.index # 装修程度
number = group_renovation.values # 装修程度对应的数量
return type, number # 返回装修程度与对应的数量
type, number = get_renovation() # 获取全市房子装修程度
renovation_bar(type,number,'全市二手房装修程度分析') # 显示图表
# 获取二手房热门户型均价
"""
通过top_five变量获取空余最多的5个户型,然后通过house_type_mean获取每种户型的均价,
tipe变量是获取户型和对应的均价
"""
def get_house_type():
house_type_number = data.groupby('户型').size() # 房子户型分组数量
sort_values = house_type_number.sort_values(ascending=False) # 将户型分组数量进行降序
top_five = sort_values.head(5) # 提取前5组户型数据
house_type_mean = data.groupby('户型')['单价'].mean() # 计算每个户型的均价
type = house_type_mean[top_five.index].index # 户型
price = house_type_mean[top_five.index].values # 户型对应的均价
return type, price.astype(int) # 返回户型与对应的数量
type, price = get_house_type() # 获取全市二手房热门户型均价
bar(price,type,'热门户型均价分析')
data_copy = data.copy() # 拷贝数据
print(data_copy[['户型', '建筑面积']].head())
data_copy[['室', '厅', '卫']] = data_copy['户型'].str.extract('(\d+)室(\d+)厅(\d+)卫')
data_copy['室'] = data_copy['室'].astype(float) # 将房子室转换为浮点类型
data_copy['厅'] = data_copy['厅'].astype(float) # 将房子厅转换为浮点类型
data_copy['卫'] = data_copy['卫'].astype(float) # 将房子卫转换为浮点类型
print(data_copy[['室','厅','卫']].head()) # 打印“室”、“厅”、“卫”数据
del data_copy['小区名字']
del data_copy['户型']
del data_copy['朝向']
del data_copy['楼层']
del data_copy['装修']
del data_copy['区域']
del data_copy['单价']
data_copy.dropna(axis=0, how='any', inplace=True) # 删除data数据中的所有空值
# 获取“建筑面积”小于300平米的房子信息
new_data = data_copy[data_copy['建筑面积'] < 300].reset_index(drop=True)
print(new_data.head())
# 添加自定义预测数据
new_data.loc[2505] = [None, 88.0, 2.0, 1.0, 1.0]
new_data.loc[2506] = [None, 136.0, 3.0, 2.0, 2.0]
data_train=new_data.loc[0:2504]
x_list = ['建筑面积', '室', '厅', '卫'] # 自变量参考列
data_mean = data_train.mean() # 获取平均值
data_std = data_train.std() # 获取标准偏差
data_train = (data_train - data_mean) / data_std # 数据标准化
x_train = data_train[x_list].values # 特征数据
y_train = data_train['总价'].values # 目标数据,总价
linearsvr = LinearSVR(C=0.1) # 创建LinearSVR()对象
linearsvr.fit(x_train, y_train) # 训练模型
x = ((new_data[x_list] - data_mean[x_list]) / data_std[x_list]).values # 标准化特征数据
new_data[u'y_pred'] = linearsvr.predict(x) * data_std['总价'] + data_mean['总价'] # 添加预测房价的信息列
print('真实值与预测值分别为:\n', new_data[['总价', 'y_pred']])
y = new_data[['总价']][2490:] # 获取2490以后的真实总价
y_pred = new_data[['y_pred']][2490:] # 获取2490以后的预测总价
broken_line(y,y_pred,'二手房售价预测') # 绘制及显示图表
本章主要使用Python开发了二手房房价分析与预测系统,该项目主要应用了Pandas和Scikit-Learn模块。其中Pandas模块主要应用于实现数据的预处理以及数据的分类等,而Scikit-Learn模块主要用于实现数据的回归模型以及预测功能,最后通过绘图模块Matplotlib,将分析后的数据绘制成图表,从而形成更直观的可视化数据。在开发中,数据分析时该项目的重点和难点,需要读者认知领会其中的算法,方便读者开发其他项目。