基于大数据的xx市二手房价格预测研究--基于Hadoop

       房地产业是国民经济的支柱产业,与大部分行业都有紧密联系。合理的房地产价格是保持社会和谐和保障民生的关键。本文旨在利用大数据技术与机器学习模型对xx市不同类型的二手房在2024年的房价进行预测,为购房者、房产开发商提供二手房较为详细的价格指导。房价的预测对于购房者和房屋投资者而言,有助于他们作出更合理的购房或投资决策;对于开发商而言,可以为市场策略提供参考。

        为实现xx市二手房2024年房价的预测,首先通过对文献期刊的深入研究,选取与房价密切相关的关键特征作为影响因素,并在此基础上通过Python网络爬取技术收集并整理了xx市二手房市场的交易数据,包括房屋类型、房屋户型、建筑面积、建筑年代、装修程度等特征,以及重要的历史交易价格和交易时间。其次在数据处理过程中,先对原始数据进行了清洗、预处理以及标准化来消除异常值、缺失值和量纲差异的影响。利用大数据分析和机器学习技术,特别是Pyspark分布式处理框架,结合随机森林和GBDT决策树两种算法,对收集到的数据进行建模和模型评估优化。

一、数据采集与预处理

1. 数据采集

       使用Python网络爬虫技术爬取链家网站中xx市二手房成交房屋数据信息、并进行数据预处理以及标准化,本次爬取数据使用Python主流的爬虫三大库包中的Lxml库,Lxml库的作用和BeautifulSoup库的作用类似,也是用于解析和提取数据,但是其解析速度比BeautifulSoup库更快。

        具体方式:进入链家网站主页,获取网站的URL地址。通过get方式发送requests请求来实现数据爬取。本文通过登录网址来获取网站cookie来进行模拟登录操作,获取响应。使用Lxml库进行解析,因为Lxml的性能较高,爬取数据更加方便快捷。将所获取的数据进行保存,本文实验数据的保存格式为CSV文件。

        在数据保存过程中,采用通配符的方式筛选关键信息,代码如下所示。

"""解析单个房源信息"""
    patterns = {
        '面积': r'(\d+\.?\d*)平米|㎡',
        '房间': r'(\d*室\d*厅)',
        '朝向': r'(东|西|南|北|东南|东北|西南|西北)',
        '装修': r'(精装|简装|毛坯|其他)',
        # '楼层': r'(\d+|低楼层|中楼层|高楼层)\(共(\d+)层\)',
        '楼层': r'((?:低楼层|中楼层|高楼层|地下室(?:\s*\(共\d+层\))?|\d+层))',
        '建房年份': r'(\d{4})年',
        '房屋结构': r'(板楼|塔楼|板塔结合)',
    }

        爬取部分数据如图所示。

2. 数据预处理

        ① 在数据预处理阶段,由于数据爬取是按区分别保存在CSV文件中,所以需要先把爬取好的数据进行合并。

        ②数据清洗

        a.去除空缺值

        由于数据集收集数据较多,但部分属性存在空缺值,因此,直接将缺失值数量大于3的行进行删除,将其余空缺值采用众数或其他方式进行填充。(后续代码均为使用pyspark操作)。

from pyspark.sql.functions import col, when, isnan, lit  

columns = df.columns  

# 针对每列,计算该列是否缺失(null或nan)  
# 注意字符串列不需要 isnan 判断(isnan只支持数值列)  
# 先构建一个判断缺失的表达式列表  
exprs = []  
for c in columns:  
    # 尝试用 isNull 判断,数值列用 isnan 判断,字符串列跳过 isnan  
    # 先用 try 捕获判断列数据类型  
    try:  
        df.select(col(c).cast("double")).collect()  
        # 可以cast成double,认为是数值列,加 isnan 判断  
        exprs.append(when(col(c).isNull() | isnan(col(c)), 1).otherwise(0))  
    except:  
        # 字符串列,只判断 null  
        exprs.append(when(col(c).isNull(), 1).otherwise(0))  

# 用 reduce 连加,求出每行缺失列数总和  
from functools import reduce  
from operator import add  

missing_count_col = reduce(add, exprs)  

df_with_missing = df.withColumn("missing_count", missing_count_col)  

# 计算最大、平均缺失数量  
max_missing = df_with_missing.agg({"missing_count": "max"}).collect()[0][0]  
avg_missing = df_with_missing.agg({"missing_count": "avg"}).collect()[0][0]  

print(f"每行最大空缺值数量: {max_missing}")  
print(f"每行平均空缺值数量: {avg_missing:.2f}")  

# 删除缺失值数量大于3的行  
filtered_df = df_with_missing.filter(col("missing_count") <= 3).drop("missing_count")  
print("过滤后行数:", filtered_df.count())  

# 统计每列缺失值(null 包含)  
from pyspark.sql.functions import count, isnan  

missing_per_column = df.select([  
    count(when(col(c).isNull() | (isnan(col(c)) if df.schema[c].dataType.simpleString() in ['double', 'float'] else lit(False)), c)).alias(c)  
    for c in columns  
])  

print("每列空缺值数量:")  
missing_per_column.show()  

       b.删除重复行

        查看数据表头的列名,确保数据的完整性,并去除重复项,这里使用drop_duplicates() 方法用于删除数据集中的重复行

        c. 特征工程--标签映射,部分代码如下:

from pyspark.sql.functions import udf  
from pyspark.sql.types import IntegerType  

# 定义字典  
direction_mapping = {'东':1, '南':2, '西':3, '北':4}  
renovation_mapping = {'精装':1, '简装':2, '其他':3, '毛坯':4}  
structure_mapping = {'板楼':1, '塔楼':2, '板塔结合':3}  

# 定义映射UDF  
def map_value(mapping_dict):  
    def mapper(x):  
        if x in mapping_dict:  
            return mapping_dict[x]  
        else:  
            return None  
    return udf(mapper, IntegerType())  

df_cleaned6 = df_cleaned6 \
    .withColumn("朝向", map_value(direction_mapping)(col("朝向"))) \
    .withColumn("装修", map_value(renovation_mapping)(col("装修"))) \
    .withColumn("房屋结构", map_value(structure_mapping)(col("房屋结构")))  

df_cleaned6.show(truncate=False)  
print("目前行数:", df_cleaned6.count())  
from pyspark.sql.functions import create_map, lit  
from itertools import chain  

region_mapping = {  
    'chaoyang': 1, 'haidian': 2, 'xicheng': 3, 'dongcheng': 4, 'changping': 5,  
    'huairou': 6, 'mentougou': 7, 'fangshan': 8, 'tongzhou': 9, 'shunyi': 10,  
    'daxing': 11, 'pinggu': 12, 'miyun': 13, 'yanqing': 14, 'shijingshan': 15,  
    'fengtai': 16  
}  

mapping_expr = create_map([lit(x) for x in chain(*region_mapping.items())])  

df_cleaned8 = df_cleaned7.withColumn("region_numeric", mapping_expr.getItem(col("区域")))  

df_cleaned8.select("区域", "region_numeric").show(10, truncate=False)  
print("目前行数:", df_cleaned8.count())  

 最后处理完数据剩余17000+行数据。

二、基于Hadoop的分布式存储

        具体Hadoop搭建,本文不做过多描述,后续会出专门一篇描述Hadoop的搭建和pyspark联合使用。

三、数据分析

        1. 相关性分析

        在本次数据分析过程中,我们采用了相关性分析方法来探索各个变量与价格之间的关系,并通过绘制相关性分析热力图来直观地呈现这些关系。

        第一步:判断特征的数据分布。相关分析法主要有三个系数分别为:Pearson相关系数、Spearman秩相关系数以及Kendall's tau-b相关系数,其中Kendall相关系数用于判断数据一致性,而Pearson相关系数和Spearman秩相关系数的使用主要区别于数据是否满足正态分布,当数据满足正态分布时使用前者,反之,不满足正态分布时使用后者。所以第一步对预处理完的数据查看下其数据分布情况。分析步骤:1.对数据进行Shapiro-Wilk或者Kolmogorov–Smirnov检验,查看其显著性;2.若不呈现出显著性(P>0.05),说明符合正态分布,反之说明不符合正态分布。由于样本数数量大于5000,故使用Kolmogorov–Smirnov检验,结果显示所有特征均不符合正态分布。故使用Spearman相关系数

        第二步:使用Spearman秩相关系数结合热力图对数据相关性进行可视化分析。结果如下图所示,结果解释:当|r|>0.95时,变量间存在显著性相关;当0.95>|r|>0.8时,变量间高度相关;当0.8>|r|>0.5时,变量间中度相关;当0.5>|r|>0.3时,变量间低度相关;当|r|<0.3时,变量间关系极弱,认为不相关。从第一张图中将|r|>0.3的变量筛选出,结果如图所示。

        从热力图中可以看出,某些变量之间存在显著的正相关或负相关关系,这表明它们对价格有着重要的影响。

 2. 数据可视化

        部分数据可视化如图所示。

 

四、模型训练与评估

        1. 评价指标:

        本文所研究的房价预测实际选取的模型都是回归问题,所以本文选取了四个回归模型的评价指标,同时也是目前回归问题使用最多的评价指标:R2、MSE、MAE、RMSE。

a. R² (R-squared / 决定系数)

  • 含义: 衡量模型解释因变量变异程度的能力。它表示模型能解释多少自变量(特征)的变化导致因变量(目标)的变化。取值范围在0到1之间(理论上可以小于0,表示模型比直接用均值预测还差)。越接近1,表示模型拟合效果越好,解释力越强。

b. MSE (Mean Squared Error / 均方误差)

  • 含义: 所有数据点预测误差平方的平均值。它对较大的误差给予更高的惩罚。MSE越小,表示模型的预测值与实际值越接近,模型拟合效果越好。

c. MAE (Mean Absolute Error / 平均绝对误差)

  • 含义: 所有数据点预测误差绝对值的平均值。它直接反映了预测值与实际值之间的平均绝对差距。MAE越小,表示模型的预测值与实际值越接近,模型拟合效果越好。相比于MSE,MAE对异常值不那么敏感。

d. RMSE (Root Mean Squared Error / 均方根误差)

  • 含义: MSE的平方根。它将误差单位转换回与原始数据相同的单位,使其更易于解释。RMSE也像MSE一样对较大的误差比较敏感。RMSE越小,表示模型的预测值与实际值越接近,模型拟合效果越好。

        2. 模型训练与评估
  • a. 数据准备与特征工程

    • 定义了特征列(feature_cols)和标签列(label_col),其中特征包括面积、单价、卧室数、客厅数、总房间数和区域编码,标签为总价。

    • 使用 VectorAssembler 将特征列合并为向量列(features_raw),并通过 MinMaxScaler 对特征进行归一化处理,输出归一化后的特征列(features)。

  • b. 数据集划分

    • 将原始数据集按 8:2 的比例随机划分为训练集(train_df)和测试集(test_df),并设置随机种子(seed=42)以确保结果可复现。

  • c. 模型定义

    • 定义了三种回归模型:

      • 决策树回归(Decision Tree):基础树模型,用于对比。

      • 随机森林回归(Random Forest):集成多个决策树,设置树数量为 100。

      • 梯度提升树回归(GBDT):类似 XGBoost,设置迭代次数为 100。

    • 将模型封装为元组列表(models),便于循环训练和评估。

  • d. 评估指标定义

    • 使用 RegressionEvaluator 定义了三个评估指标:

      • RMSE(均方根误差):衡量预测值与真实值的平均偏差,值越小越好。

      • R²(决定系数):衡量模型解释目标变量变异的比例,越接近 1 越好。

      • MAE(平均绝对误差):直接反映预测误差的平均绝对值,值越小越好。

  • e. 模型训练与评估循环

    • 对每个模型执行以下步骤:

      • 构建 Pipeline:将特征工程(assembler 和 scaler)和模型(algo)串联成 Pipeline。

      • 训练模型:使用训练集拟合 Pipeline,生成模型对象。

      • 预测与评估:在测试集上生成预测值,并计算 RMSE、R² 和 MAE。

      • 特征重要性分析:提取模型(如随机森林或 GBDT)的特征重要性分数,并绘制条形图。

    • 打印每个模型的评估结果,并保存特征重要性图表。

  • f. 结果汇总

    • 将所有模型的评估结果(模型名称、RMSE、R²、MAE)存储为列表,并转换为 Pandas DataFrame 输出,便于对比分析。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值