数据科学俱乐部

中国数据科学家社区

本篇将继续上一篇数据分析用Python分析北京二手房房价之后进行数据挖掘建模预测,这两部分构成了一个简单的完整项目。结合两篇文章通过数据分析和挖掘的方法可以达到二手房屋价格预测的效果。

下面从特征工程开始讲述。

特征工程

特征工程包括的内容很多,有特征清洗,预处理,监控等,而预处理根据单一特征或多特征又分很多种方法,如归一化,降维,特征选择,特征筛选等等。这么多的方法,为的是什么呢?目的是让这些特征更友好的作为模型的输入,处理数据的好坏会严重的影响模型性能,而好的特征工程有的时候甚至比建模调参更重要。

下面是继上一次分析之后对数据进行的特征工程,博主将一个一个帮大家解读。

 1""" 2特征工程 3""" 4# 移除结构类型异常值和房屋大小异常值 5df = df[(df['Layout']!='叠拼别墅')&(df['Size']<1000)] 6 7# 去掉错误数据“南北”,因为爬虫过程中一些信息位置为空,导致“Direction”的特征出现在这里,需要清除或替换 8df['Renovation'] = df.loc[(df['Renovation'] != '南北'), 'Renovation'] 910# 由于存在个别类型错误,如简装和精装,特征值错位,故需要移除11df['Elevator'] = df.loc[(df['Elevator'] == '有电梯')|(df['Elevator'] == '无电梯'), 'Elevator']1213# 填补Elevator缺失值14df.loc[(df['Floor']>6)&(df['Elevator'].isnull()), 'Elevator'] = '有电梯'15df.loc[(df['Floor']<=6)&(df['Elevator'].isnull()), 'Elevator'] = '无电梯'1617# 只考虑“室”和“厅”,将其它少数“房间”和“卫”移除18df = df.loc[df['Layout'].str.extract('^d(.*?)d.*?') == '室']1920# 提取“室”和“厅”创建新特征21df['Layout_room_num'] = df['Layout'].str.extract('(^d).*', expand=False).astype('int64')22df['Layout_hall_num'] = df['Layout'].str.extract('^d.*?(d).*', expand=False).astype('int64')2324# 按中位数对“Year”特征进行分箱25df['Year'] = pd.qcut(df['Year'],8).astype('object')2627# 对“Direction”特征28d_list_one = ['东','西','南','北']29d_list_two = ['东西','东南','东北','西南','西北','南北']30d_list_three = ['东西南','东西北','东南北','西南北']31d_list_four = ['东西南北']    32df['Direction'] = df['Direction'].apply(direct_func)33df = df.loc[(df['Direction']!='no')&(df['Direction']!='nan')]3435# 根据已有特征创建新特征36df['Layout_total_num'] = df['Layout_room_num'] + df['Layout_hall_num']37df['Size_room_ratio'] = df['Size']/df['Layout_total_num']3839# 删除无用特征40df = df.drop(['Layout','PerPrice','Garden'],axis=1)4142# 对于object特征进行onehot编码43df,df_cat = one_hot_encoder(df)

由于一些清洗处理在上一篇文章已经提到,博主从17行代码开始。

Layout

先来看看没经处理的Layout特征值是什么样的。

1df['Layout'].value_counts()

大家也都看到了,特征值并不是像想象中的那么理想。有两种格式的数据,一种是"xx室xx厅",另一种是"xx房间xx卫",但是绝大多数都是xx室xx厅的数据。而对于像"11房间3卫"或者"5房间0卫"这些的Layout明显不是民住的二手房(不在我们的考虑范围之内),因此最后决定将所有"xx房间xx卫"格式的数据都移除掉,只保留"xx室xx厅"的数据。

Layout特征的处理如下:

第2行的意思是只保留"xx室xx厅"数据,但是保留这种格式的数据也是不能作为模型的输入的,我们不如干脆将"室"和"厅"都提取出来,单独作为两个新特征(如第5和6行),这样效果可能更好。

具体的用法就是使用 str.extract() 方法,里面写的是正则表达式。

1# 只考虑“室”和“厅”,将其它少数“房间”和“卫”移除2df = df.loc[df['Layout'].str.extract('^d(.*?)d.*?') == '室']34# 提取“室”和“厅”创建新特征5df['Layout_room_num'] = df['Layout'].str.extract('(^d).*', expand=False).astype('int64')6df['Layout_hall_num'] = df['Layout'].str.extract('^d.*?(d).*', expand=False).astype('int64')

Year

我们还有一个 Year 特征,为建房的年限时间。年限种类很多,分布在1950和2018之间,如果每个不同的 Year 值都作为特征值,我们并不能找出 Year 对 Price 有什么影响,因为年限划分的太细了。因此,我们只有将连续数值型特征 Year 离散化,做分箱处理

如何分箱还要看实际业务需求,博主为了方便并没有手动分箱,而使用了pandas的 qcut 采用中位数进行分割,分割数为8等份。

1# 按中位数对“Year”特征进行分箱2df['Year'] = pd.qcut(df['Year'],8).astype('object')

这是将 Year 进行分箱的结果:

Direction

这个特征没处理之前更乱,原以为是爬虫的问题,但是亲自到链家看过,朝向确实是这样的。

如上所见,像"西南西北北"或者"东东南南"这样的朝向是不符合常识的(反正我是理解不了)。因此,我们需要将这些凌乱的数据进行处理,具体实现方式是博主自己写了一个函数 direct_func,主要思想就是将各种重复但顺序不一样的特征值合并,比如"西南北"和"南西北",并将不合理的一些值移除,如"西南西北北"等。

然后通过 apply() 方法将 Direction 数据格式转换,代码如下:

1# 对“Direction”特征2d_list_one = ['东','西','南','北']3d_list_two = ['东西','东南','东北','西南','西北','南北']4d_list_three = ['东西南','东西北','东南北','西南北']5d_list_four = ['东西南北']    6df['Direction'] = df['Direction'].apply(direct_func)7df = df.loc[(df['Direction']!='no')&(df['Direction']!='nan')]

处理完结果如下,所有的内容相同而顺序不同的朝向都合并了,异常朝向也被移除了。

创建新特征

有时候仅靠已有的一些特征是不够的,需要根据对业务的理解,定义一些的新特征,然后尝试这些新特征对模型的影响,在实战中会经常使用这种方法。

这里尝试将"室"与"厅"的数量相加作为一个总数量特征,然后将房屋大小Size与总数量的比值作为一个新特征,可理解为 "每个房间的平均面积大小"。当然,新特征不是固定的,可根据自己的理解来灵活的定义。

1# 根据已有特征创建新特征2df['Layout_total_num'] = df['Layout_room_num'] + df['Layout_hall_num']3df['Size_room_ratio'] = df['Size']/df['Layout_total_num']45# 删除无用特征6df = df.drop(['Layout','PerPrice','Garden'],axis=1)

最后删除旧的特征 Layout,PerPrice,Garden。

One-hot coding

这部分是 One-hot 独热编码,因为像 Region,Year(离散分箱后),Direction,Renovation,Elevator等特征都是定类的非数值型类型,而作为模型的输入我们需要将这些非数值量化。

在没有一定顺序(定序类型)的情况下,使用独热编码处理定类数据是非常常用的做法,在pandas中非常简单,就是使用 get_dummies() 方法,而对于像Size这样的定比数据则不使用独热,博主这里用了一个自己封装的函数实现了定类数据的自动量化处理。

对于定类,定序,定距,定比这四个非常重要的数据类型相信加入知识星球的伙伴都非常熟悉了,想要了解的同学可以扫描最后二维码查看。

1# 对于object特征进行onehot编码2df,df_cat = one_hot_encoder(df)

以上的特征工程就完成了。

特征相关性

下面使用 seaborn 的 heatmap 方法对特征相关性进行可视化。

1# data_corr 2colormap = plt.cm.RdBu3plt.figure(figsize=(20,20))4# plt.title('Pearson Correlation of Features', y=1.05, size=15)5sns.heatmap(df.corr(),linewidths=0.1,vmax=1.0, square=True, cmap=colormap, linecolor='white', annot=True)

颜色偏红或者偏蓝都说明相关系数较大,即两个特征对于目标变量的影响程度相似,即存在严重的重复信息,会造成过拟合现象。因此,通过特征相关性分析,我们可以找出哪些特征有严重的重叠信息,然后择优选择。

数据建模预测

为了方便理解,博主在建模上做了一些精简,模型策略方法如下:

  • 使用Cart决策树的回归模型对二手房房价进行分析预测

  • 使用交叉验证方法充分利用数据集进行训练,避免数据划分不均匀的影响。

  • 使用GridSearchCV方法优化模型参数

  • 使用R2评分方法对模型预测评分

上面的建模方法比较简单,旨在让大家了解建模分析的过程。随着逐渐的深入了解,博主会介绍更多实战内容。

数据划分

1# 转换训练测试集格式为数组2features = np.array(features)3prices = np.array(prices)45# 导入sklearn进行训练测试集划分6from sklearn.model_selection import train_test_split7features_train, features_test, prices_train, prices_test = train_test_split(features, prices, test_size=0.2, random_state=0)

将以上数据划分为训练集测试集,训练集用于建立模型,测试集用于测试模型预测准确率。使用sklearn的 model_selection 实现以上划分功能。

建立模型

 1from sklearn.model_selection import KFold 2from sklearn.tree import DecisionTreeRegressor 3from sklearn.metrics import make_scorer 4from sklearn.model_selection import GridSearchCV 5 6# 利用GridSearchCV计算最优解 7def fit_model(X, y): 8    """ 基于输入数据 [X,y],利于网格搜索找到最优的决策树模型""" 910    cross_validator = KFold(10, shuffle=True)11    regressor = DecisionTreeRegressor()1213    params = {'max_depth':[1,2,3,4,5,6,7,8,9,10]}14    scoring_fnc = make_scorer(performance_metric)15    grid = GridSearchCV(estimator = regressor, param_grid = params, scoring = scoring_fnc, cv = cross_validator)1617    # 基于输入数据 [X,y],进行网格搜索18    grid = grid.fit(X, y)19#     print pd.DataFrame(grid.cv_results_)20    return grid.best_estimator_2122# 计算R2分数23def performance_metric(y_true, y_predict):24    """计算并返回预测值相比于预测值的分数"""25    from sklearn.metrics import r2_score26    score = r2_score(y_true, y_predict)2728    return score

使用了 KFold 方法减缓过拟合,GridSearchCV 方法进行最优参数自动搜查,最后使用R2评分来给模型打分。

调参优化模型

 1import visuals as vs 2 3# 分析模型 4vs.ModelLearning(features_train, prices_train) 5vs.ModelComplexity(features_train, prices_train) 6 7optimal_reg1 = fit_model(features_train, prices_train) 8 9# 输出最优模型的 'max_depth' 参数10print("最理想模型的参数 'max_depth' 是 {} 。".format(optimal_reg1.get_params()['max_depth']))1112predicted_value = optimal_reg1.predict(features_test)13r2 = performance_metric(prices_test, predicted_value)1415print("最优模型在测试数据上 R^2 分数 {:,.2f}。".format(r2))

由于决策树容易过拟合的问题,我们这里采取观察学习曲线的方法查看决策树深度,并判断模型是否出现了过拟合现象。以下是观察到的学习曲线图形:通过观察,最理想模型的参数"max_depth"是10,此种情况下达到了偏差与方差的最优平衡,最后模型在测试数据上的R2分数,也即二手房房价预测的准确率为:0.81。

总结

以上一个完整的从数据分析到挖掘的项目就结束了,对于项目而言比较简单,目的是让大家了解整个分析的过程。可提升改进的地方非常多,可以有更好更健壮的方案代替,一些改进思考如下:

  • 获取更多有价值的特征信息,比如学区,附近地铁,购物中心等

  • 完善特征工程,如进行有效的特征选择

  • 使用更优秀的模型算法建模或者使用模型融合

Python中文社区作为一个去中心化的全球技术社区,以成为全球20万Python中文开发者的精神部落为愿景,目前覆盖各大主流媒体和协作平台,与阿里、腾讯、百度、微软、亚马逊、开源中国、CSDN等业界知名公司和技术社区建立了广泛的联系,拥有来自十多个国家和地区数万名登记会员,会员来自以公安部、工信部、清华大学、北京大学、北京邮电大学、中国人民银行、中科院、中金、华为、BAT、谷歌、微软等为代表的政府机关、科研单位、金融机构以及海内外知名公司,全平台近20万开发者关注。

Python中文社区公众号底部回复“内推”

获取一周内推技术职位清单

▼ 点击下方阅读原文免费成为社区会员

北京二手房房价分析(建模篇)相关推荐

  1. 数据挖掘实战项目——北京二手房房价分析

    本次实战项目的主要目的是分析北京二手房房价,项目源自博文:入门Python数据分析最好的实战项目(一)和入门Python数据分析最好的实战项目(二).本篇文章仅记录博主在学习过程中的思路. 数据分析 ...

  2. 【项目实战】北京二手房房价分析与预测

    项目简介 本项目根据个人需求进行北京二手房信息的数据分析,通过数据分析观察住房特征规律,利用机器学习模型进行简单的预测. 数据源 通过爬虫爬取第三方房屋中间商网站(链家和安居客)获取数据源,仅供学习使 ...

  3. 商业大数据线下回归实验:北京二手房房价实验步骤(上)

    商业大数据线性回归实验:北京二手房房价实验步骤(上) 实验要求 (1)使用北京二手房房价.csv文件,创建一个工作流. (2) 用北京二手房房价.csv文件中的数据生成单位面积房价直方图.内部因素的单 ...

  4. 深圳二手房房价分析与建模预测(附数据集)

    之前帮师兄做了一个预测房价课题的demo,但是感觉效果不好,考虑到当时数据来源是长沙的房价数据,这次决定自己收集深圳的二手房数据来建模预测. 原本是准备上网找现成的数据集,结果很多github上的代码 ...

  5. python建筑案例_Python数据分析实战-链家北京二手房价分析

    前言 最近在自学Python,通过学习大家的分享案例,看到使用Python进行较多的主要4个方面:爬虫,数据处理,数据可视化以及机器学习建模.对我来说目标就是: 熟练使用numpy pandas 进行 ...

  6. 成都二手房房价分析-数据挖掘

    PricesDataAnalysis 本项目使用jupyter notebook开发,主要目的是分析成都二手房房价,项目地址. 数据:爬取二手房交易网站近期数据,成都各个区域交易热度较高的房屋信息. ...

  7. python二手房数据分析_Python 爬取北京二手房数据,分析北漂族买得起房吗? | 附完整源码...

    作者 徐麟 本文经授权转自公众号数据森麟(ID: shujusenlin) 房价高是北漂们一直关心的话题,本文就对北京的二手房数据进行了分析. 本文主要分为两部分:Python爬取赶集网北京二手房数据 ...

  8. 深圳二手房房价分析及预测

    分析目标: 通过处理后的房价数据,筛选对房价有显著影响的特征变量. 确定特征变量,建立深圳房价预测模型并对假设情景进行模拟 数据预处理 import pandas as pd import os fi ...

  9. 济南二手房房价分析报告

    author:qq:1318791335 # -*- coding: utf-8 -*- import numpy as np import pandas as pd import seaborn a ...

最新文章

  1. linux ubuntu 开机自动启动 fixfox 并打开指定网站
  2. Linux学习之CentOS(八)--Linux系统的分区概念
  3. movielens推荐系统_基于内容推荐(二)
  4. Tomcat配置JNDI数据源
  5. python代码少的作品_世界上有哪些代码量很少,但很牛逼很经典的算法或项目案例?...
  6. jenkins的svn路径中文问题
  7. Elipse 、Idea配置 Java-Code-Formatter
  8. 结对编程项目作业2-开发环境搭建过程
  9. 【华为云技术分享】从 Cloud 1.0 到 2.0,云计算的“多元架构命题”
  10. RSA大会:中国信息安全的“走出去”与“学回来”
  11. Windows系统命令整理-Win10
  12. 8.2学长讲解(数论入门)
  13. Python 爬虫对链家网广州二手房源信息的处理与可视化分析
  14. QTcpServer和QTcpSocket使用详解
  15. 圆柱体积怎么算立方公式_圆柱体积计算公式 怎么计算
  16. pci_register_driver
  17. linux中cp: omitting directory `XXX' 问题解决
  18. 图像处理-相关知识点
  19. 亚马逊dynamo高可用性关键字仓库
  20. 关于Android应用开发的一些安全注意事项

热门文章

  1. HTML第三次作业——Tab切换和轮播图
  2. 《电子商务》漫谈网络营销
  3. Android 11整合Mopria联盟的代码贡献以实现增强的打印功能
  4. 信号与系统陈后金matlab,陈后金信号与系统matlab实验4.pdf
  5. 研发绩效考核KPI大全
  6. QE01/QE02/QE03屏幕增强
  7. 车载毫米波雷达信号处理中的干扰问题
  8. python 创建虚拟环境时报错OSError, setuptools下载失败
  9. 开源库和开源代码源码
  10. java date 转换成毫秒_Java程序将Date转换为毫秒