线性回归

       回归(Regression)是从外语中翻译过来的词。翻译词的特点是带有原词的主要含义,但与原词表达的意思又不完全一样,甚至从中文字面上都难以理解,例如大家最熟悉的函数(function)这个翻译词。回归(Regression)简单理解可以说是“回去归来”,回归于事物的本来面目。

       那么什么是线性回归呢?先不说概念,先看一个实例。下表是北京市海淀区中关村地区近期成交二手房源的情况(数据来源于北京链家网http://bj.lianjia.com/)。

成交日期

面积(米2)

总价(万元)

2016.08.15

81

715

2016.08.15

45

500

2016.08.14

59

610

2016.08.14

50

560

2016.08.14

52

440

2016.08.11

48

480

2016.08.11

79

852

2016.08.11

61

625

2016.08.10

56

620

2016.08.10

69

690

2016.08.10

70

735

2016.08.10

72

877

2016.08.09

48

495

2016.08.08

42

408

2016.08.06

55

605

2016.08.06

41

342

2016.08.05

69

720

2016.08.05

77

730

2016.08.05

62

590

2016.08.04

64

639

2016.08.04

53

646

2016.08.02

87

986

2016.08.02

64

709

2016.08.01

60

600


       先画出数据的散点图,横轴表示房子的面积,纵轴表示房子的价格。如果你在该地区有一套面积108平方米的房子想出售,看了链家地产提供的近期销售情况,你预测下你的房子能卖多少钱?
                                

       根据图上的数据分布,可以看到,这些数据近似的分布在一条直线周围。

 

       利用初等数学知识,我们知道直线的函数表示是y=k*x+b,x是自变量,在这里就是房子的面积,y是因变量,这里就是房子的价格,k是直线的斜率,b是截距。如果我们求得了这条直线方程,那么,代入你的房子面积x=108平方米,就能预测你的房子的价格y了。

       线性回归简单点说,就是给定一个数据集(本例就是上面链家网给出的北京中关村地区8月1日-15日的二手房销售数据),能够求出一条直线y=k*x+b,而这个直线能够较好的反映这个数据集的数据关系。这种反映一个因变量与一个自变量之间的线性关系的回归就是一元线性回归。一元线性回归形式简单,易于理解,但却蕴含着机器学习中一些重要的基本思想。

       我们知道,在初等数学中,如果可以用一次方程(y=k*x+b)来表达两个变量之间关系的话,这两个变量之间的关系称为线性关系,也就是直线关系;当然在更高维度上,线性关系表示的是多个变量的一次方程,这时候就不是直线了,像x+y+z=1表示的就是一个平面。多个自变量(大于1个)的线性回归称为多元线性回归;如果变量之间不是线性关系,那就是非线性回归,多元线性回归和非线性回归将在后面再讲。

       那么怎样求出这条直线(y=k*x+b)呢?也就是如何确定k和b呢?假设数据集中只有2条数据,例如前2条:

2016.08.15

81

715

2016.08.15

45

500

       那么我们可以联立方程组:

       715=k*81+b

       500=k*45+b

       利用初中数学知识求得k,b分别为k=5.9722,b=231.25。如果我们取最后2条数据:

2016.08.02

64

709

2016.08.01

60

600

       709=k*64+b,600=k*60+b,可以求得k,b分别为k=27.25,b=-1035。

       显然,仅仅根据数据集中随机选取2个数据,求得的直线方程是不一样的,甚至相差还很大。这很显然,因为从图中就可以看出来,不可能有一条直线穿过所有的点。那么,能不能取一条直线,让数据集中所有点到该直线的距离都尽可能近,从而用这条直线最优化的反映数据集合中所有数据之间的关系呢?实质上这就是线性回归的主要工作。如下图所示:


       上图中红色方块分别为数据点到直线的垂直距离,对于数据集合中的所有数据来说,如果这些垂直距离的和最小,那么这条直线就是我们求得的最佳直线。 

       我们知道点到直线的垂直距离计算公式为:,需要进行开方运算,这样比较麻烦,运算量也大。因此,一般采用的是竖直距离,即从点作平行于Y轴的直线,计算点到直线的这个线段的距离。如下图所示:

 

       我们设最优直线的函数为f(x)=k*x+b,再构造一个代价函数:


       其中,表示数据集中第i个数据,表示了第i个数据点到直线的竖直距离的平方。代价函数C也称为损失函数,学过概率论的一眼就能看出这里构建的代价函数与均方误差(mean squared error,MSE)的公式是一样的。实质上还可以用等多种代价函数形式,但一般使用的是均方误差(MSE)形式,至于为什么用这种形式比较好,以后再讲。

       那么,实际上我们是在求代价函数C在最小值情况下的(k,b)的值。将数据集中所有数据代入求C的公式:


       可以看出,实质上C是k,b的二元二次函数,求C的最小值,实际就是求二元二次函数C=f(k,b)的最小值。求函数最小值的方法有很多,梯度下降算法就是一种。但对于本例的情况,可以简单使用梯度为0的方法。

对于 ,分别对k,b求偏导数,得到:



令上述2个偏导数等于0,联立得到k,b的解为:


原始数据保存在regression.txt中:

date,area,cost

2016.08.15,81,715

2016.08.15,45,500

2016.08.14,59,610

2016.08.14,50,560

2016.08.14,52,440

2016.08.11,48,480

2016.08.11,79,852

2016.08.11,61,625

2016.08.10,56,620

2016.08.10,69,690

2016.08.10,70,735

2016.08.10,72,877

2016.08.09,48,495

2016.08.08,42,408

2016.08.06,55,605

2016.08.06,41,342

2016.08.05,69,720

2016.08.05,77,730

2016.08.05,62,590

2016.08.04,64,639

2016.08.04,53,646

2016.08.02,87,986

2016.08.02,64,709

2016.08.01,60,600

代码如下:

import pandas as pd

ds = pd.read_csv("regression.txt")
x, y = ds.area, ds.cost
n = len(ds.area)
ka, kb, kc = 0, 0, 0
for i in range(n):
    ka += y[i] * (x[i] - x.mean())
    kb += x[i] ** 2
    kc += x[i]
k = ka / (kb - kc ** 2 / n)

b = 0
for j in range(n):
    b += y[i] - k * x[i]
b = b / n
print('k=', k, 'b=', b)

输出结果:

k= 10.8404658722 b= -50.4279523294

画图看看求得的最佳直线方程与数据的关系:

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

ds = pd.read_csv("regression.txt")
x = ds.area
y = ds.cost
T = np.arctan2(x, y)
plt.scatter(x, y, c=T, s=20, alpha=0.8, marker='o')
x1 = np.linspace(35, 95, 100)

k = 10.8404658722
b = -50.4279523294

y1 = k * x1 + b
plt.plot(x1, y1)
plt.show()

       可以看出,求得的最佳直线与数据集贴合的非常好。

       再回到我们最初的目的,你要出售的房子面积108平方米,预测价格:y=10.8404658722*108-50.4279523294=1120万,哇,发财了。

  • 12
    点赞
  • 19
    收藏
    觉得还不错? 一键收藏
  • 3
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值