【python数据分析】练习4:线性回归—二手房价预测

数据集及源码 [ https://github.com/JCATHoney/python-data-analysis

](https://github.com/JCATHoney/python-data-analysis)

一、问题描述

在对房价的影响因素进行模型研究之前,首先对各变量进行描述性分析,以初步判断房价的影响因素,进而建立房价预测模型

总体步骤如下: (一) 因变量分析:单位面积房价分析

(二) 自变量分析: 2.1 自变量自身分布分析 2.2 自变量对因变量影响分析

(三)建立房价预测模型 3.1 线性回归模型 3.2 对因变量取对数的线性模型 3.3 考虑交互项的对数线性

(四)预测: 假设有一家三口,父母为了能让孩子在东城区上学,想买一套邻近地铁的两居室,面积是70平方米,中层楼层,那么房价大约是多少呢?

二、数据集

研究二手房价的影响因素,建立房价预测模型,数据存放在“sndHsPr.csv”中。

变量说明如下:

变量含义
dist所在区
roomnum室的数量
halls厅的数量
AREA房屋面积
floor楼层
subway是否临近地铁
school是否学区房
price平米单价

三、描述性统计

3.1数据预处理

  1. 主要关注金额,日期等字段的处理

  2. 把握整体样本量,后续合理采样

  3. 将城区变量转换为中文

    import pandas as pd
    import numpy as np
    import math
    import matplotlib.pyplot as plt
    import matplotlib
    import seaborn as sns
    import statsmodels.api as sm
    from numpy import corrcoef,array
    #from IPython.display import HTML, display
    from statsmodels.formula.api import ols
    import os
    os.chdir(r"C:\Users\Away\Desktop\笔记\数据分析")
    # In[1]:
    import pandas as pd
    mdata = pd.read_csv(r'sndHsPr.csv')
    mdata.head()
    #%%
    #1、描述性统计数据预处理阶段
    describe=mdata.describe()#价格基本情况
    # count     16210.000000
    # mean      61151.810919
    # std       22293.358147
    # min       18348.000000
    # 25%       42812.250000
    # 50%       57473.000000
    # 75%       76099.750000
    # max      149871.000000
    print(mdata.shape[0])#数据量:16210  这里为什么要统计数据量呢?因为做检验时数据量不能过大,一般不超过5000,否则p值会失效
    #%%
    ## 1、描述性统计
    #数据简单处理,重点关注价格日期等字段
    #查看各个字段基本情况
    data0 = mdata
    describe=data0.describe(include="all").T
    #print(data0.dtypes)
    #价格转换为万元
    data0.price = data0.price/10000
    #type_dict = {'借':'out','贷':'income'}
    #card_t3['type1'] = card_t3.t_type.map(type_dict)
    #将区域名转换为中文
    dist_dict = {
            'chaoyang' : "朝阳",
            'dongcheng' : "东城",
            'fengtai' :  "丰台",
            'haidian' : "海淀",
            'shijingshan' : "石景山",
            'xicheng': "西城"
            }
    
    data0['dist']=data0.dist.map(dist_dict)

_中文和负号的显示: _

    matplotlib.rcParams['axes.unicode_minus']=False#解决保存图像时负号'-'显示为方块的问题
    plt.rcParams['font.sans-serif'] = ['SimHei']#指定默认字体 ,解决不能显示中文字体的问题#

3.2 变量描述性分析

  1. 因变量 price

    #因变量图形(主要看看形态)
    data0.price.plot(kind='hist',bins=20,color='lightblue')#右偏严重
    plt.xlabel("单位面积房价(万元/平方米)")
    plt.ylabel("频数")
    print(data0.price.agg(['mean','median','std']))  #查看price的均值、中位数和标准差等更多信息
    print(data0.price.quantile([0.25,0.5,0.75]))
    pd.concat([(data0[data0.price==min(data0.price)]),(data0[data0.price==max(data0.price)])])#查看房价最高和最低的两条观测

2.自变量

  • 首先对自变量进行分类,同一类的统一分析(for)

  • 除了AREA(房屋面积),都是分类变量。

分类变量,主要用条形图、盒须图

    ##1.2、自变量描述(除了房屋面积都是分类变量)
    for i in range(7):
        if i!=3:
            print(data0.columns.values[i],":")
            print(data0[data0.columns.values[i]].agg(['value_counts']).T)
            print('==================================')
        else:
            continue
    print('AREA:')
    print(data0.AREA.agg(['min','mean','max','median','std']).T)
    #%%
    #1.2.1 dist 区域 多分类变量
    #频次统计
    data0.dist.value_counts().plot(kind='bar')
    #%%
    #不同城区的房价
    data0.price.groupby(data0.dist).mean().sort_values(ascending=True).plot(kind='barh')#能看出来和城区还是有关系的
    #%%
    data1 = data0[['dist','price']]
    sns.boxplot(x='dist',y='price',data=data1)
    #dat1.boxplot(by='dist',patch_artist=True)
    plt.ylabel("单位面积房价(万元/平方米)")
    plt.xlabel("城区")
    plt.title("城区对房价的分组箱线图")#城区还是有明显影响的
    #%%
    #1.2.2 roomnum 卧室数-roomnum 多分类
    data2=data0[['roomnum','price']]
    data2.price.groupby(data2.roomnum).mean().plot(kind='bar')
    #data2.boxplot(by='roomnum',patch_artist=True)# patch_artist    是否填充箱体的颜色;
    plt.figure()
    sns.boxplot(x='roomnum',y='price',data=data2)#没啥关系

部分结果: 在这里插入图片描述在这里插入图片描述

连续变量,相关分析: 注意点:

  1. 直方图呈现右偏,进行取对数操作

  2. 第一次对y取对数后|r|反而降了,所以将x也取对数

  3. 最后的达到的效果要使在x,y两个方向都是呈现正态分布

    # 1.2.7 AREA 连续变量
    dataA=data0[['AREA','price']]
    plt.scatter(dataA.AREA,dataA.price,marker='.')#发散型,右偏-对Y取对数
    # area,price都是连续变量,进行相关分析
    xg1=dataA[['price','AREA']].corr(method='pearson')#返回一个dataframe#  r=-0.074 中度负相关。
    #对Y取对数
    dataA['price_ln'] = np.log(dataA['price'])
    plt.figure(figsize=(8,8))
    plt.scatter(dataA.AREA,dataA.price_ln,marker='.')
    plt.ylabel("单位面积房价(取对数后)")
    plt.xlabel("面积(平方米)")#小户型贵
    #求AREA_ln和price_ln的相关系数
    xg3=dataA[['price_ln','AREA']].corr(method='pearson')#|r|=0.058
    #房屋面积和单位面积房价(取对数后)的散点图
    dataA['price_ln'] = np.log(dataA['price'])  #对price取对数
    dataA['AREA_ln'] = np.log(dataA['AREA'])  #对price取对数
    plt.figure(figsize=(8,8))
    plt.scatter(dataA.AREA_ln,dataA.price_ln,marker='.')
    plt.ylabel("单位面积房价(取对数后)")
    plt.xlabel("面积(平方米)")
    #求AREA_ln和price_ln的相关系数矩阵
    data1=array(dataA['price_ln'])
    data2=array(dataA['AREA_ln'])
    datB=array([data1,data2])
    corrcoef(datB)# 0.09,高度相关,且x,y两个方向都是正态分布

初始散点图 在这里插入图片描述 对x,y取对数后的散点图: 在这里插入图片描述

  • 目前结论: 明显影响:区,地铁,学区 不明显:客厅,楼层 基本不影响:卧室(roomnum)

  • 描述性统计结束,提出我们的假设(学区房贵,靠近地铁贵。。。。),后面就开始假设检验分析,验证结论

四、建模

  1. 采样:根据城区分层抽样,每区400,定阈值

    data_new = get_sample(data0,sampling='stratified',k=400,stratified_col=['dist'])
    #2400个样本,阈值确定原则如下:
    """大致原则如下(自然科学取值偏小、社会科学取值偏大):
    n<100 alfa取值[0.05,0.2]之间
    100<n<500 alfa取值[0.01,0.1]之间
    500<n<3000 alfa取值[0.001,0.05]之间
    """
  1. 方差分析逐个检查分类变量的解释力度 注意点:对于分类变量回归分析加上C(分类变量),否则自动识别为连续变量。但是也可以自己创建哑变量(自己选择基准)

    #逐个检查分类变量的解释力度,方差分析
    import statsmodels.api as sm
    from statsmodels.formula.api import ols
    print("dist的P值为:%.4f" %sm.stats.anova_lm(ols('price ~ C(dist)',data=data_new).fit())._values[0][4])
    print("roomnum的P值为:%.4f" %sm.stats.anova_lm(ols('price ~ C(roomnum)',data=data_new).fit())._values[0][4])#明显高于0.001->不显著->独立
    print("halls的P值为:%.4f" %sm.stats.anova_lm(ols('price ~ C(halls)',data=data_new).fit())._values[0][4])#高于0.001->边际显著->暂时考虑
    print("floor的P值为:%.4f" %sm.stats.anova_lm(ols('price ~ C(floor)',data=data_new).fit())._values[0][4])#高于0.001->边际显著->暂时考虑
    print("subway的P值为:%.4f" %sm.stats.anova_lm(ols('price ~ C(subway)',data=data_new).fit())._values[0][4])
    print("school的P值为:%.4f" %sm.stats.anova_lm(ols('price ~ C(school)',data=data_new).fit())._values[0][4])
    '''
    dist的P值为:0.0000
    roomnum的P值为:0.1014 #去掉roomnum,其他保留
    halls的P值为:0.0002
    floor的P值为:0.0013
    subway的P值为:0.0000
    school的P值为:0.0000
    '''
  • 结果处理: 去掉roomnum 对与不太显著的变量“halls”做因子化处理变成二分变量

    #%%
    # 厅数和楼层的影响不太显著。对于厅数可以做因子化处理,变成二分变量('有厅','无厅')
    data_new['hall_new'] = data_new.halls
    data_new.hall_new[data_new.hall_new>0]='有厅'
    data_new.hall_new[data_new.hall_new==0]='无厅'

3、线性回归模型

    # 3 线性回归模型
    lm1 = ols("price ~ C(dist)+school+subway+C(floor)+C(hall_new)++AREA", data=data_new).fit()#这里也可以自己设计基准创建哑变量
    lm1_summary = lm1.summary()
    lm1_summary  #回归结果展示1 R方=0.599 开始忘了加hall_new 发现加了对模型没啥改进作用
  • 残差分析

    #初始线性回归模型残差分析
    data_new['pred1']=lm1.predict(data_new)#模型预测结果
    data_new['resid1']=lm1.resid#取残差
    data_new.plot('pred1','resid1',kind='scatter')  #模型诊断图,存在异方差现象,对因变量取对数
    #预测值增加,残差呈现喇叭口发散状况。考虑取对数

改进前残差分析,异方差现象 在这里插入图片描述 3.1取对数的线性模型

    # 3.1 改进取对数后再次建模
    data_new['price_ln'] = np.log(data_new['price'])
    data_new['AREA_ln'] = np.log(data_new['AREA'])
    lm2 = ols("price_ln ~ C(dist)+school+subway+C(floor)+AREA_ln", data=data_new).fit()
    lm2_summary = lm2.summary()
    lm2_summary  #回归结果展示2 R方=0.614 有一丢丢提升
    #%%
    #残差分析
    data_new['pred2']=lm2.predict(data_new)#模型预测结果
    data_new['resid2']=lm2.resid#取残差
    data_new.plot('pred2','resid2',kind='scatter')  

异方差现象改善 在这里插入图片描述 3.2 加上交互项的非线性模型

  • 思考:为什么要叫交互项? 各个因变量对自变量的影响也不是独立的,比如采样分析后发现石景上区的学区房比非学区房还便宜,与其他地方都相反。地区这个变量就和学区这个变量之间有交互作用*

    schools=['石景山','丰台','朝阳','东城','海淀','西城']
    for i in schools:
        print(i+'非学区房\t',round(data_new[(data_new['dist']==i)&(data_new['school']==0)]['price'].mean(),2),'万元/平方米\t',i+'学区房\t',round(data_new[(data_new['dist']==i)&(data_new['school']==1)]['price'].mean(),2),'万元/平方米')
    
    # 3.2 加上交互项对数模型
    lm3 = ols("price_ln ~ C(dist)*school+subway+C(floor)+AREA_ln", data=data_new).fit()
    lm3_summary = lm3.summary()
    lm3_summary  #回归结果展示 R方=0.618

预测

    #选一个好的模型来做预测
    x_new1=data_new.head(1)
    x_new1
    #%%
    x_new1['dist']='东城'
    x_new1['roomnum']=2
    x_new1['AREA_ln']=np.log(80)
    x_new1['subway']=1
    x_new1['school']=1
    x_new1['floor']='middle'
    x_new1['hall_new']="有厅"
    
    #%%
    #预测值
    print("单位面积房价:",round(math.exp(lm5.predict(x_new1)),2),"万元/平方米")
    print("总价:",round(math.exp(lm5.predict(x_new1))*70,2),"万元")
                       

结果: 单位面积房价: 7.8 万元/平方米 总价: 545.99 万元

好贵啊。。。(〒︿〒)

  • 0
    点赞
  • 35
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
### 回答1: 线性回归是一种常用的数据挖掘算法,它可以用来预测连续型变量的值。在房价预测中,我们可以使用线性回归来预测房价线性回归的原理是通过建立一个线性方程来描述自变量因变量之间的关系,然后利用已知的自变量因变量的数据来拟合这个方程,从而得到一个预测模型。在房价预测中,我们可以将房屋的面积、房间数量、地理位置等作为自变量,将房价作为因变量,然后利用已知的房屋数据来拟合一个线性方程,从而得到一个预测模型,用来预测未知房屋的价格。实践中,我们可以使用Python等编程语言来实现线性回归算法,利用已知的数据来训练模型,然后使用模型来预测未知数据的结果。 ### 回答2: 线性回归是一种用于预测连续变量的监督学习算法。在房价预测中,线性回归可以通过利用历史数据和相关因素,如房屋面积、位置和装修状况等,预测房屋的售价。 线性回归的原理是拟合一条直线来近似预测目标变量和输入因素之间的关系。这条直线被称为回归线。回归线的斜率和截距分别表示输入因素和目标变量之间的关系和预测模型的截距。 在实践中,我们需要将数据集分成训练集和测试集。从训练集中选取一个子集,用来训练模型。一旦模型被训练完成,我们可以使用测试集来评估其准确性和泛化能力。 线性回归的评估指标包括平均平方误差(Mean Squared Error,MSE)和均方根误差(Root Mean Squared Error,RMSE)。MSE 衡量模型预测与实际数据之间差异的平方和的平均值。RMSE 是 MSE 的平方根。 在实践中,我们需要注意一些问题。例如,数据集的特征选择,是否需要进行数据缩放,异常值或离群值的处理,以及是否需要进行特征工程或增加多项式特征。此外,在模型的选择上,我们可以使用不同的正则化方法,如岭回归和 Lasso。这些方法可以避免过拟合和提高模型的泛化能力。 总之,线性回归是一种简单但有效的预测房价的模型。但是,在实际应用中,我们需要结合领域知识和业务需求来调整和优化模型,以提高其性能和可靠性。 ### 回答3: 线性回归是数据挖掘中常用的一种算法,通过对已有的数据进行分析和学习,建立一个线性模型,以此来预测新的未知数据。 在房价预测中,线性回归可以用来预测房价与其它因素的关系,如房屋面积、房龄、地段、物业等。通过建立一个线性方程,可以将这些因素与房价之间的关系用数学形式表示出来,对于未知的房屋可以通过该方程来预测其价格。 线性回归的原理是基于一组数据集,其中包含了预测变量和响应变量的数据。通过这些数据建立了一个回归方程,以预测响应变量的值。回归方程是一条直线,它用输入变量的值来预测输出变量的值。线性回归中的许多算法使用误差平方和来评估回归模型的好坏。误差平方和是指所有观测值与预测值之间差的平方和。 线性回归算法的实践需要经历以下步骤: 1. 数据收集:收集房屋的各种信息,包括房屋价格、面积、年龄、地理位置、物业等。 2. 数据处理:清洗数据,排除不合理或者有误的数据,并将数据进行统一的格式化处理。 3. 特征工程:在收集的数据中,选取与房价相关的因素,将其进行特征选择,处理成线性回归算法所能接受的数据格式。 4. 模型拟合:在处理好的数据集上,利用线性回归算法进行模型拟合,得到回归方程。 5. 模型评估:通过误差平方和等指标对模型进行评估,判断其预测效果的好坏。 6. 应用预测:使用建立好的模型,输入新的数据特征,进行房价预测线性回归算法的优点是模型简单,易于理解和应用,适合于处理数量较少的数据,同时还可以提供较为准确的预测结果。但是线性回归也有其局限性,例如不能处理非线性数据,对异常值敏感等。因此,在实际应用中需要针对不同的数据模型选择合适的算法进行处理。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值