专栏首页早起Python原理+代码|Python实战多元线性回归模型

原理+代码|Python实战多元线性回归模型

本文含 3605 字,19 图表截屏

建议阅读 8 分钟

前言

「多元线性回归模型」非常常见,是大多数人入门机器学习的第一个案例,尽管如此,里面还是有许多值得学习和注意的地方。其中多元共线性这个问题将贯穿所有的机器学习模型,所以本文会「将原理知识穿插于代码段中」,争取以不一样的视角来叙述和讲解「如何更好的构建和优化多元线性回归模型」。主要将分为两个部分:

  • 详细原理
  • Python 实战

Python 实战

Python 多元线性回归的模型的实战案例有非常多,这里虽然选用的经典的房价预测,但贵在的流程简洁完整,其中用到的精度优化方法效果拔群,能提供比较好的参考价值。

数据探索

本文的数据集是经过清洗的美国某地区的房价数据集

import pandas as pd
import numpy as np
import seaborn as sns
import matplotlib.pyplot as plt

df = pd.read_csv('house_prices.csv')
df.info();df.head()

参数说明:

  • neighborhood/area:所属街区和面积
  • bedrooms/bathrooms:卧室和浴室
  • style:房屋样式

多元线性回归建模

现在我们直接构建多元线性回归模型

from statsmodels.formula.api import ols
                      # 小写的 ols 函数才会自带截距项,OLS 则不会
         # 固定格式:因变量 ~ 自变量(+ 号连接)
lm = ols('price ~ area + bedrooms + bathrooms', data=df).fit()
lm.summary()

红框为我们关注的结果值,其中截距项Intercept的 P 值没有意义,可以不用管它

模型优化

从上图可以看到,模型的精度较低,因为还有类别变量neighborhoodstyle没有完全利用。这里我们先查看一下类别变量的类别分布情况:

# 类别变量,又称为名义变量,nominal variables
nominal_vars = ['neighborhood', 'style']

for each in nominal_vars:
    print(each, ':')
    print(df[each].agg(['value_counts']).T)  # Pandas 骚操作
    # 直接 .value_counts().T 无法实现下面的效果
     ## 必须得 agg,而且里面的中括号 [] 也不能少
    print('='*35)

虚拟变量的设置

因为类别变量无法直接放入模型,这里需要转换一下,而多元线性回归模型中类别变量的转换最常用的方法之一便是将其转化成虚拟变量。原理其实非常简单,将无法直接用于建模的名义变量转换成可放入模型的虚拟变量的核心就短短八个字:「四散拆开,非此即彼」。下面用一个只有 4 行的微型数据集辅以说明。

从上表中,不难发现:

  • 该名义变量有 n 类,就能拆分出 n 个虚拟变量
  • 巧妙的使用 0 和 1 来达到「用虚拟变量列代替原名义变量所在类别」

接下来要做的就是将生成的虚拟变量们放入多元线性回归模型,但要注意的是:「转化后的虚拟变量们需要舍弃一个」,才能得到满秩矩阵。具体原因和有关线性代数的解释可以查看笔者打包好的论文,我们可以理解为,当该名义变量可划分为 n 类时,只需要 n-1 个虚拟变量就已足够获知所有信息了。该丢弃哪个,可根据实际情况来决定。

因此为原数据集的某名义变量添加虚拟变量的步骤为:

  • 抽出希望转换的名义变量(一个或多个)
  • pandasget_dummies函数
  • 与原数据集横向拼接

注意虚拟变量设置成功后,需要与原来的数据集拼接,这样才能将其一起放进模型。

再次建模后,发现模型精度大大提升,但潜在的多元共线性问题也随之显现出来

在解释模型中虚拟变量的系数之前,我们先消除模型中多元共线性的影响,因为在排除共线性后,模型中的各个自变量的系数又会改变,最终的多元线性回归模型的等式又会不一样。多重线性回归模型的主要假设之一是我们的预测变量(自变量)彼此不相关。我们希望预测变量(自变量)与反应变量(因变量)相关,而不是彼此之间具有相关性。方差膨胀因子(Variance Inflation Factor,以下简称VIF),是「指解释变量之间存在多重共线性时的方差与不存在多重共线性时的方差之比」

上图公式可以看出在方差膨胀因子的检测中:

方差膨胀因子的检测

我们自己来写一个方差膨胀因子的检测函数

def vif(df, col_i):
    """
    df: 整份数据
    col_i:被检测的列名
    """
    cols = list(df.columns)
    cols.remove(col_i)
    cols_noti = cols
    formula = col_i + '~' + '+'.join(cols_noti)
    r2 = ols(formula, df).fit().rsquared
    return 1. / (1. - r2)

现在进行检测

test_data = results[['area', 'bedrooms', 'bathrooms', 'A', 'B']]
for i in test_data.columns:
    print(i, '\t', vif(df=test_data, col_i=i))

发现bedroomsbathrooms存在强相关性,可能这两个变量是解释同一个问题,方差膨胀因子较大的自变量通常是成对出现的。

果然,bedroomsbathrooms这两个变量的方差膨胀因子较高,这里删除自变量bedrooms再次进行建模

lm = ols(formula='price ~ area + bathrooms + A + B', data=results).fit()
lm.summary()

模型精度稍降,但消除了多元共线性后能够使模型的泛化能力提升。再次进行多元共线性检测

test_data = results[['area', 'bedrooms', 'A', 'B']]
for i in test_data.columns:
    print(i, '\t', vif(df=test_data, col_i=i))

那么多元共线性就「只有通过方差膨胀因子才能看的出来吗?」 其实并不一定,通过结合散点图或相关稀疏矩阵和模型中自变量的系数也能看出端倪。下图是未处理多元共线性时的自变量系数。

可以很明显的看出,bathrooms的参数很可能是有问题的,怎么可能bathrooms的数据量每增加一个,房屋总价还减少 1.373*10 的四次方美元呢?简单的画个散点图和热力图也应该知道房屋总价与bathrooms 个数应该是成正比例关系的。

模型解释

多元线性回归模型的可解释性比较强,将模型参数打印出来即可求出因变量与自变量的关系

所以最终的建模结果如下,且该模型的精度为0.916

price = 266.53×area + bedrooms×29561 - A×8707.18 + B×449896.73 - 136345.41

另外在等式结果中,截距项Interceptarea,bedrooms等变量的系数都还好理解;A,B 这两个虚拟变量可能相对困难些。其实根据原理部分的表格来看,如果房屋在 C 区,那等式中 A 和 B 这两个字母的值便是 0,所以这便引出了非常重要的一点:使用了虚拟变量的多元线性回归模型结果中,存在于模型内的虚拟变量都是跟被删除掉的那个虚拟变量进行比较。所以这个结果便表示在其他情况完全一样时(即除虚拟变量外的项)A 区的房屋比 C 区低 8707.18 美元,B 区则比 C 区贵 449896.73.7 美元。当然我们也可以画个箱线图来查看与检验,发现结果正如模型中 A 与 B 的系数那般显示。

小结

本文以多元线性回归为基础和前提,在因变量房价与多个自变量的实际观测值建立了多元线性回归模型;分析并检验各个预测变量对因变量的综合线性影响的显著性,并尽可能的消除多重共线性的影响,筛选出因变量有显著线性影响的自变量,对基准模型进行优化,并对各自变量相对重要性进行评定,进而提升了回归模型的预测精度。如果对本文的源数据和代码感兴趣,可以在后台回复数据挖掘进行获取,我们下个案例见。

本文分享自微信公众号 - 早起Python(zaoqi-python),作者:萝卜

原文出处及转载信息见文内详细说明,如有侵权,请联系 yunjia_community@tencent.com 删除。

原始发表时间:2020-08-05

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

我来说两句

0 条评论
登录 后参与评论

相关文章

  • 文末重磅福利|Python实现回归预测及模型优化

    大家好,之前写多了自动化办公的内容,现在换个机器学习的专题跟大家交流学习,作为一个眼科研究生后面也希望后面多通过一些眼科案例顺带普及下眼科知识!在眼科中AI的一...

    刘早起
  • 玩转数据处理120题|R语言版本

    大家好,本文为R语言数据处理120题系列完整版本。作者精心挑选120道数据处理中相关操作以习题形式发布,一共涵盖了数据处理、计算、可视化等常用操作,并对部分题目...

    刘早起
  • 偷学Python第四天|分支结构,附练习案例

    为了照顾基础阶段的读者,本文带来的是偷学Python第四天,分支结构的学习。其他内容将在近期更新完毕。本文目录如下:

    刘早起
  • 【临床研究】一个你无法逃避的问题:多元回归分析中的变量筛选

    临床模型研究,说到底是做一个模型,那么模型应该如何纳入自变量,纳入哪些自变量,这都是至关重要的问题。线性回归,逻辑回归和Cox比例风险回归模型是被广泛使用的多元...

    用户6317549
  • C - 基础总结

    xx_Cc
  • 【案例】SPSS商业应用系列第3篇:最近邻元素分析模型

    应用 IBM SPSS Statistic 的最近邻元素分析模型对汽车厂商预研车型进行市场评估。 某汽车厂商的研发部门提出了多个预研车型的技术指标...

    机器学习AI算法工程
  • 终极 shell 脚本 快速入门指南 (二) 之变量

    上一篇 终极 shell 脚本 快速入门指南 (一) 我们已经搞定 hello world 了。现在让我们更深入♂地了解 shell 脚本吧。

    白玉无冰
  • 变量置换

    除了直接给变量赋值之外,另一种常见情形是把某个变量的值赋给另外一个变量。例如,变量x的值为1,我们期望变量y的值是x+2也就是3。采用如下代码,最终发现y的结果...

    Lauren的FPGA
  • 【JAVA零基础入门系列】Day4 变量与常量

      这一篇主要讲解Java中的变量,什么是变量,变量的作用以及如何声明,使用变量。   那么什么是变量?对于初学者而言,可以将变量理解为盒子,这些盒子可以用来存...

    弗兰克的猫
  • 笔记︱虚拟变量回归=差异显著(方差分析)+差异量化(系数值)

    虚拟变量作为自变量,放在回归方程中在教科书里面讲的都很多,笔者以前在学习的时候觉得虚拟变量较之方差分析,还有更多惊喜。谢宇老师的《回归分析》书中对虚...

    素质

扫码关注云+社区

领取腾讯云代金券