线性回归-理论篇

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/flyfish1986/article/details/86909160

作者:邵盛松

"回归"一词是怎么来的

本文中描述的高中教科书是 人民教育出版社B版,高中教科书 《数学 选修 1-2》的第一章《“回归”一词的由来》22页

英国的统计学家弗朗西斯·高尔顿(Francis Galton,1822—1911)用统计方法研究两个变量之间关系。他研究父母身高与子女身高之间的关系,“回归”这个词由他引入的。

解决什么样的问题

假设你是一个老板,想到其他城市再开一家分店,你拥有一份城市人口数对应收益的数据,问当一个城市有8 百万人,那么这家分店收益是多少?
数据如下

人口(百万) 收益(亿元)
1 6
2 5
3 7
4 10

回归公式

高中教科书《数学2 必修》中的《直线的方程》74页
点斜式方程
k = y 2 y 1 x 2 x 1 k = \frac { y _ { 2 } - y _ { 1 } } { x _ { 2 } - x _ { 1 } }

y 2 y 1 = k ( x 2 x 1 ) y_2 - y _ { 1 } = k \left( x_2 - x _ { 1 } \right)
斜截式方程
y = k x + b y = k x + b
两点式方程
y y 1 y 2 y 1 = x x 1 x 2 x 1 ( x 1 x 2 , y 1 y 2 ) \frac { y - y _ { 1 } } { y _ { 2 } - y _ { 1 } } = \frac { x - x _ { 1 } } { x _ { 2 } - x _ { 1 } } (x _ { 1 } \neq { x _ { 2 } },y _ { 1 } \neq { y _ { 2 } })
一般式
直线的方程都是关于 x , y x,y 的二元一次方程
A x + B y + C = 0 ( ( A 2 + B 2 0 ) ) \mathrm { Ax } + \mathrm { By } + \mathrm { C } = 0 (\left( A ^ { 2 } + B ^ { 2 } \neq 0 \right))

斜率 (图片来自wiki)
在这里插入图片描述
k = tan θ = y 2 y 1 x 2 x 1 = Δ y Δ x k = \tan \theta = \frac { y _ { 2 } - y _ { 1 } } { x _ { 2 } - x _ { 1 } } = \frac { \Delta y } { \Delta x }

导数

在3Blue1Brown的《微积分的本质 - 02 - 导数的悖论》详细介绍了导数的意义
说明了发明微积分的先辈们为什么要引入一个导数的定义
巴罗、 牛顿 、莱布尼茨发明了微积分,柯西、魏尔斯特拉斯给出了严格定义,
微积分的大厦不是一蹴而就完成的.
牛顿要解决是物理问题,数学是他的工具,如果没有工具,他就自己造。
给行驶中的车辆拍个照,问照片中的这辆车瞬时速度是多少?计算速度 要求路程 和时间,照片中的车没路程没时间哪里来的速度。
速度到底说的是什么意思,
用一小段时间内距离的变化表示,这个很小的时间段,不管有多小,总要有那么个时间段,时间段为 d t dt 可以想象成0.0000001,只能用逻辑推理,而无法想象有无数个0后面跟着一个1是个什么样的,就像假设宇宙有无限大,无限大怎么想象。 d t dt 非常非常小的趋近于0, 距离变化为 d s ds , 速度 v ( t ) v(t) 就是

d s d t = s ( t + d t ) s ( t ) d t \frac{ds}{dt}=\frac{s(t+dt)-s(t)}{dt}
上述的这个式子就可以描述一个变化率。
让dt非常接近0,是个技巧,我看这就是萌芽状态的微积分,看这个式子是不是和定义的极限很像,所以定义导数时,先定义了极限。也是因为这个技巧变化率就有了意义
导数就是计算“最佳近似”的工具,就像画一个切线,两点确定一条直线,如果是两个点就是割线。如果是一个点,直线怎么画?还是大牛们想出的那个技巧“无限接近”,
一个点向另一个点不断的移动,移动到越来越近都快要重合了但是没重合,直线的斜率越来越接近要找的斜率,通过该点的切线的斜率。
= lim h 0 f ( x + h ) f ( x ) h = \lim _ { h \rightarrow 0 } \frac { f ( x + h ) - f ( x ) } { h }

当极限存在就说通了。经过计算得出来的数就成了导数,实际书上或者其他地方只要能看到的,画的切线都是“最佳近似”的切线。“计算”可以精确,“画”只能最佳近似。
看割线与切线,图片来自wiki
在这里插入图片描述
在这里插入图片描述
我主要是做工程,牛人们是发明公式,而我主要是使用着牛人们发明的公式。
在这里插入图片描述
f ( x ) = lim Δ x 0 f ( x + Δ x ) f ( x ) Δ x = lim Δ x 0 Δ y Δ x f ^ { \prime } ( x ) = \lim _ { \Delta x \rightarrow 0 } \frac { f ( x + \Delta x ) - f ( x ) } { \Delta x } = \lim _ { \Delta x \rightarrow 0 } \frac { \Delta y } { \Delta x }

林群在上海交大报告《微积分降到最低点》中举了一个很简单的例子说明什么是导数

微积分之首是导数,擒贼先擒王。导数是什么?
先看整数除法
91 10 = 9 + 0.1 \frac { 91 } { 10 } = 9 + 0.1

若四舍五入,右边剩下整数9,简化做了除法,回到 x 2 x^2
它的导数就是做除法
( x + h ) 2 x 2 h = ? \frac { ( x + h ) ^ { 2 } - x ^ { 2 } } { h } = ?
简单代数即得等式:对于给定 x x 与任一 h h
( x + h ) 2 x 2 h = 2 x + h \frac { ( x + h ) ^ { 2 } - x ^ { 2 } } { h } = 2 x + h

这等式是纯代数,无论 h h 有多大。当你要求 h 0 h \rightarrow 0 (瞬时速度 ),左边变成除法,但右边变成 2 x + 0 2x+0 .称为 x 2 x^2 的导数,记
( x 2 ) = 2 x \left( x ^ { 2 } \right) ^ { \prime } = 2 x

总结他的理解方式是 导数时差商的简化

字母变更下

h θ ( x ) = θ 0 + θ 1 x h_\theta(x)=\theta_0+\theta_1x

x
h
y

h 表示 hypothesis(假设),是一个函数,从x 到 y 的函数映射
m 表示样本数 对应例子中的4个样本
x 代表特征,输入变量,自变量 对应例子中的人口数
y 代表目标变量,输出变量,因变量 对应例子中的收益
整个步骤

1 预测函数(Hypothesis)

h θ ( x ) = θ 0 + θ 1 x h_{\theta}(x)=\theta_{0}+\theta_{1}x

2 参数(Parameters)

θ 0 , θ 1 \theta_{0},\theta_{1}

3 代价函数 (Cost Function),有的地方称为损失函数(Loss Function) 或者 误差函数(Error Function)

J ( θ 0 , θ 1 ) = 1 2 m i = 1 m ( h θ x ( i ) y ( i ) ) 2 J(\theta_{0},\theta_{1}) = \frac{1}{2m}\sum_{i=1}^{m} (h_\theta x^{(i)}-y^{(i)})^2

4 目的(Goal)

( θ 0 , θ 1 ) = min θ 0 , θ 1 J ( θ 0 , θ 1 ) (\theta_{0},\theta_{1})=\min_{\theta_{0},\theta_{1}} J(\theta_{0},\theta_{1})
只有一个特征,这样的问题叫作单变量线性回归问题 或者一元线性回归问题
可视化理解 θ 0 = 0 \theta_0=0 的情况

#假设有三组数据,数据分别为(1,1),(2,2),(3,3)
x=np.array([1,2,3])
y=np.array([1,2,3])
#预测1
y1=0.5*x
y2=1*x
y3=-0.5*x
print( (1/(2*len(x)) )* sum(np.power(y1-y,2))) #0.58
print( (1/(2*len(x)) )* sum(np.power(y2-y,2))) #0
print( (1/(2*len(x)) )* sum(np.power(y3-y,2))) #5.25

#画图 看看是J(theta1)什么样子的
#a=np.linspace(-2,2,9)#[-2.  -1.5 -1.  -0.5  0.   0.5  1.   1.5  2. ]
theta1=np.linspace(-2,4,17)
j=np.array([])
for i in theta1:
    y_=i*x
    b= (1/(2*len(x)) )* sum(np.power(y_-y,2))
    j=np.append(j,b)
print(j) 

plt.xlabel('theta1')
plt.ylabel('J(theta1)')
plt.plot(theta1,j) 

在这里插入图片描述
这个图像很像抛物线,高中 《数学 选修 2-1》59页抛物线

如果有多个特征,不仅仅是人口 x 1 x_1 ,还包括,等级 x 2 x_2 ,GDP x 3 x_3 等,这样的问题叫作多变量线性回归问题 或者多元线性回归问题
回归公式
h θ ( x ) = θ 0 + θ 1 x 1 + θ 2 x 2 + + θ n x n = θ T x h_\theta(x)=\theta_0+\theta_1x_1+\theta_2x_2+\dots+\theta_nx_n=\theta^Tx
公式的矩阵形式
θ T x = [ θ 1 θ 2 . . . θ n ] [ x 1 x 2 . . . x n ] = i = 1 n θ i x i = h θ ( x ) \theta^T x = \left[ \begin{matrix} \theta _ 1 \\\\ \theta _ 2 \\\\ ...\\\\ \theta _ n \\\\ \end{matrix} \right] \left[ \begin{matrix} x _ 1 & x _ 2 & ... & x _ n \end{matrix} \right] = \sum_{i=1}^n\theta _ i x _ i = h_\theta(x)
上述公式中T的含义 行变列,列变行。
[ 1 , 2 3 , 4 5 , 6 ] T = [ 1 , 3 , 5 2 , 4 , 6 ] {\begin{bmatrix}1,2\\3,4\\5,6\end{bmatrix}}^{\mathrm {T} }={\begin{bmatrix}1,3,5\\2,4,6\end{bmatrix}}
代价函数 (cost function)
J ( θ ) = 1 2 m i = 1 m ( h θ ( x ( i ) ) y ( i ) ) 2 , m J(\theta)=\frac{1}{2m}\sum\limits_{i=1}^{m}(h_\theta(x^{(i)})-y^{(i)})^2,\quad {m 为样本数}

矩阵形式
J ( θ ) = 1 2 m ( X θ y ) T ( X θ y ) J(\theta)=\frac{1}{2m}(X\theta-y)^T(X\theta-y)
梯度下降

柯西将极限的定义引入了微积分,很创新。因为微积分的创造者们没有把一件事说明白,他用新的概念把这件事说明白了。问题变了,思维方式就变了,之前的人的问题是什么什么是多少,他的问题是如何定义“什么什么”的问题。他定义的框架把微积分的严谨度向前迈了一大步,所以问什么样的问题最重要。微积分的现代体系就是他建的。

数学有些地方又是借鉴物理知识,可以在后面的深度学习部分看到。从芝诺用不是数学的语言-大白话描述它,到现在都2500多年了。中国的先人们发现的什么什么定理领先西方多少多少年,到了明朝后期比较尴尬了,19世纪末期清代的李善兰把这个知识引入到中国。别人是先进的,那就无论好坏对错全盘吸收,然后持续积累改进迭代。如果后人把问题再变了,那又会离“微积分真理”又进了一步。人的语言可以表达不存在的东西,因相信而这不存在东西也就变得存在。

说梯度的时候,还得理解方向导数,偏导数。
最小化 f(x)的问题,如果是一元的,一个 导数的概念就够了;如果是多元的,就出现了偏导数,方向导数,梯度的概念。
导数精确描述了函数变化率,变化率可理解为变量的变化“快慢”问题。研究变化率的问题之前的 y=kx+b,就一个未知数x,x也叫自变量,可以说一元函数,研究多元函数的时候就出现了偏导。偏可以理解成部分,多元就是一个自变量固定,在编程里叫常量。三维可以可视化易于理解,超过三维在我看来只能逻辑推理,所以用一元,二元来可视化理解。假设一个二元函数的偏导数,它反应的是函数沿坐标轴方向的变化率。一个点画线的时候可以朝着坐标轴方向,也可以朝着其他方向,其他方向就成了方向导数
式子 z = f ( x , y ) z = f ( x , y ) 的偏导数
函数在点 x 0 , y 0 (x_0,y_0) 沿着 x x 轴方向的变化率
f x ( x 0 , y 0 ) = lim Δ x 0 f ( x 0 + Δ x , y 0 ) f ( x 0 , y 0 ) Δ x f _ { x } ^ { \prime } \left( x _ { 0 } , y _ { 0 } \right) = \lim _ { \Delta x \rightarrow 0 } \frac { f \left( x _ { 0 } + \Delta x , y _ { 0 } \right) - f \left( x _ { 0 } , y _ { 0 } \right) } { \Delta x }
函数在点 x 0 , y 0 (x_0,y_0) 沿着 y y 轴方向的变化率
f y ( x 0 , y 0 ) = lim Δ y 0 f ( x 0 , y 0 + Δ y ) f ( x 0 , y 0 ) Δ y f _ { y } ^ { \prime } \left( x _ { 0 } , y _ { 0 } \right) = \lim _ { \Delta y \rightarrow 0 } \frac { f \left( x _ { 0 } , y _ { 0 } + \Delta y \right) - f \left( x _ { 0 } , y _ { 0 } \right) } { \Delta y }
定义偏导数是可以使用导数来定义,也可以使用极限来定义,甚至可以使用方向导数来定义

下面用数学语言来描述方向导数,用数学语言作为标杆,优点严谨,强逻辑,不产生歧义,缺点不易懂。之后我用大白话说明是什么问题。多本教科书均有定义,这里采用 同济大学《高等数学 第七版 下册》103页的《方向导数与梯度》
原图是这样的
在这里插入图片描述

l l x O y xOy 平面上以 P 0 ( x 0 , y 0 ) P_0(x_0,y_0) 为始点的一条射线, e l = ( cos α , cos β ) e_l=(\cos \alpha,\cos \beta) 是与 l l l同方向的单位向量,射线 l l 的参数方程为

x = x 0 + t cos α y = y 0 + t cos β t 0 \begin{array} { c } { x = x _ { 0 } + t \cos \alpha } \\ { y = y _ { 0 } + t \cos \beta } \\ { t \geqslant 0 } \end{array}

设函数 z = f ( x , y ) z=f(x,y) 在点 P 0 ( x 0 , y 0 ) P_0(x_0,y_0) 的某个领域 U ( P 0 ) U(P_0) 内有定义, P ( x 0 + t c o s α , y 0 + t c o s β ) P(x_{0}+tcos\alpha,y_{0}+tcos\beta) l l 上的另一点,且 P U ( P 0 ) P\in U(P_{0}) 。如果函数增量 f ( x 0 + t c o s α , y 0 + t c o s β ) f ( x 0 , y 0 ) {f(x_{0}+tcos\alpha,y_{0}+tcos\beta)-f(x_{0},y_{0})} 与点 P P 到点 P 0 P_0 的距离 P P 0 = t |PP_0|=t 的比值
f ( x 0 + t c o s α , y 0 + t c o s β ) f ( x 0 , y 0 ) t \frac{f(x_{0}+tcos\alpha,y_{0}+tcos\beta)-f(x_{0},y_{0})}{t}

P P 沿着 l l 趋向于 P 0 ( t 0 + ) P_{0}(即t\rightarrow0^{+}) 时的极限存在,则称此极限为函数 f ( x , y ) f(x,y) 在点 P 0 P_0 沿方向ll的方向导数

f l ( x 0 , y 0 ) = lim t 0 + f ( x 0 + t c o s α , y 0 + t c o s β ) f ( x 0 , y 0 ) t \frac{\partial f}{\partial l} \mid_{(x_{0},y_{0})}=\lim_{t \rightarrow 0^{+}}\frac{f(x_{0}+tcos\alpha,y_{0}+tcos\beta)-f(x_{0},y_{0})}{t}`
教科书的内容不好理解,从简单的入手,为了易于理解我从勾股定理和三角函数开始说

图片来自wiki
在这里插入图片描述

直角三角形的两条直角边长分别是a和b,斜边长是h,数学语言是
a 2 + b 2 = h 2 a ^ { 2 } + b ^ { 2 } = h ^ { 2 }
在《九章算术》中看赵爽写那么多字就为了描述勾股定理,而且是文言文,发明定理的牛人,佩服佩服。后人用字母、数字、符号等记录简单方便了许多。
三角函数 sin cos \sin \cos
sin
sin A =  opposite(对边)   hypotenuse(斜边)  \sin A = \frac { \text { opposite(对边) } } { \text { hypotenuse(斜边) } }
cos
cos A =  adjacent(邻边)   hypotenuse(斜边)  \cos A = \frac { \text { adjacent(邻边) } } { \text { hypotenuse(斜边) } }
tan
tan A = sin A cos A \tan A = \frac { \sin A } { \cos A }
它要表达的图是这样的,耗时的画图,看的图简化下
在这里插入图片描述

单位向量 e l = ( cos α , cos β ) e_l=(\cos \alpha,\cos \beta) 怎么解释
首先得有个向量假设叫它a,长度不能为0,还有个向量e,与a方向一样,长度是1,那么这个e就叫做向量a的单位向量。就像在坐标轴上画刻度,至于多大间隔为1,自己定。

这就是上面提到的单位向量 e l e_l
( cos α , cos β ) (\cos \alpha,\cos \beta) a是向量 e l e_l 的x轴坐标分量和y轴坐标分量,相当于直角三角形的斜边是1,根据前面的三角函数,知道了角度,可以计算对边和斜边。
图片中
t c o s ( a l p h a ) = t c o s ( α ) = Δ x t*cos(alpha)=t*cos(\alpha)=\Delta x
t c o s ( b e t a ) = t c o s ( β ) = Δ y t*cos(beta)=t*cos(\beta)=\Delta y
就有了如下式子
ρ = P P 0 = Δ x 2 + Δ y 2   Δ z = f ( x + Δ x , y + Δ y ) f ( x , y ) f l = lim ρ 0 f ( x + Δ x , y + Δ y ) f ( x , y ) ρ \rho = \left| P P _ { 0 } \right| = \sqrt { \Delta x ^ { 2 } + \Delta y ^ { 2 } } \ \\ \Delta z = f ( x + \Delta x , y + \Delta y ) - f ( x , y ) \\ \frac { \partial f } { \partial l } = \lim _ { \rho \rightarrow 0 } \frac { f ( x + \Delta x , y + \Delta y ) - f ( x , y ) } { \rho }

方向导数就像我们给地球定义了东西南北,正南正北刮的就像偏导数,地球上的风是可以按照任意方向刮的,就像方向导数。
在这里插入图片描述
根据上面的抛物线简化下
目的是找到抛物线中最低的点,也就是y轴中最小的那个坐标
先随意取一点,这条直线的斜率是三角形的高除以宽,也就是h/g,相当于tan(alpha)
看图知道如果切线平行于x轴,相当于tan0=0
当点向下移动时,斜率越来越小
t a n 6 0 = 3 tan60 ^ { \circ }=\sqrt { 3 }
t a n 4 5 = 1 tan45 ^ { \circ }=1
t a n 3 0 = 3 3 tan30 ^ { \circ }=\frac { \sqrt { 3 } } { 3 }
t a n 0 = 0 tan0 ^ { \circ }=0

梯度
函数在某点的梯度是这样一个向量,它的方向是函数在这点方向导数取得最大值得方向,它的模为方向导数的最大值.

解释什么是向量的模?
向量的模就是向量的长度
假设平面有两个点 A ( x 1 , y 1 ) B ( x 2 , y 2 ) A \left( x _ { 1 } , y _ { 1 } \right) B \left( x _ { 2 } , y _ { 2 } \right) ,它们之间的距离是(还是勾股定理)
A B = ( x 2 x 1 ) 2 + ( y 2 y 1 ) 2 | \vec { \mathbf { A B } } | = \sqrt { \left( \boldsymbol { x } _ { 2 } - \boldsymbol { x } _ { \mathbf { 1 } } \right) ^ { 2 } + \left( \boldsymbol { y } _ { 2 } - \boldsymbol { y } _ { \mathbf { 1 } } \right) ^ { 2 } }
这类距离也叫欧式距离,在机器学习中叫2-范数
nabla
换成表示方式就是
已知 a = ( x , y ) | \vec { \boldsymbol { a } } | =( x , y ) ,那么模就是
a = x 2 + y 2 | \vec { \boldsymbol { a } } | = \sqrt { \boldsymbol { x } ^ { 2 } + \boldsymbol { y } ^ { 2 } }
梯度的符号是$\operatorname { grad } f(x_0,y_0) $或者 f ( x 0 , y 0 ) \nabla f(x_0,y_0) ,倒三角的符号是
梯度是这样的
gradf ( x , y ) = ( f x ) 2 + ( f y ) 2 \operatorname { grad f } ( x , y ) = \sqrt { \left( \frac { \partial f } { \partial x } \right) ^ { 2 } + \left( \frac { \partial f } { \partial y } \right) ^ { 2 } }

以二元z=f(x,y)这样的曲面用等值线表示
先使用Python画一个

import numpy as np
import matplotlib.pyplot as plt

def f(x, y):
   return (x**2+y**2) 

n = 64
x = np.linspace(-1, 1, n)
y = np.linspace(-1, 1, n)

#画原图
fig = plt.figure()
x1,y1 = np.meshgrid(x,y)
pic1=fig.add_subplot(111,projection='3d')
pic1.plot_surface(x1,y1,f(x1,y1),rstride=3,cstride=3,cmap=plt.cm.jet)
plt.show()

#画等值线
fig = plt.figure()
x2, y2 = np.meshgrid(x, y)
t = plt.contour(x2, y2, f(x2, y2), 10)
plt.clabel(t, inline=True, fontsize=10)
plt.show()

原图
在这里插入图片描述
在吴恩达的机器学习视频教程 Gradient Descent For Linear Regression中也有类似的这样的图,this is called a convex function
关于函数的这个“凸”,各种书籍资料都没有统一,这个凹凸正好是中国的象形字,但老外用的是字母。所以看书的时候要注意书中的定义和上下文,例如在陈宝林《最优化理论与算法》中用的抛物线的开口向上为凸函数和抛物线的开口向下为凹函数,我后面的说法采用张景中的上凸和下凸,直观无歧义。在他的著作《直来直去的微积分》中描述了林群的不使用极限概念定义导数,目的是让数学变得更容易学习。就像例如同样是对速度的定义,哪个更容易懂些。
初中的定义:速度等于路程与时间之比。
高中的定义:速度等于位移和发生位移所用时间的比值。
大学的定义:速度是描述质点运动快慢和方向的物理量等于位移对时间的微分,
同时也等于加速度的积分。
我这里使用了极限的概念来理解,如果使用林群的“一致性不等式”定义导数证明泰勒公式变得简单了。
等值线
在这里插入图片描述

泰勒公式
《普林斯顿数学指南》第三卷中说 泰勒并不是第一个发现这个定理的人,尽管这个定理以他这个名字命名,但他是第一个领会到它的意义和应用它的人。
泰勒公式的思想是局部逼近,用多项式来近似表示一个复杂函数,就像有句话说的“如果我看过你看过的世界,走过你走过的路,是不是就能更靠近你一点”

用切线近似的表示一个弧

近似公式

f ( x ) f ( x 0 ) + f ( x 0 ) ( x x 0 ) f ( x ) \approx f \left( x _ { 0 } \right) + f ^ { \prime } \left( x _ { 0 } \right) \left( x - x _ { 0 } \right)

f ( x ) f ( x 0 ) + f ( x 0 ) ( x x 0 ) + a 2 ( x x 0 ) 2 f ( x ) \approx f \left( x _ { 0 } \right) + f ^ { \prime } \left( x _ { 0 } \right) \left( x - x _ { 0 } \right) + a _ { 2 } \left( x - x _ { 0 } \right) ^ { 2 }

n次多项式近似的表示f(x)
P ( x ) = a 0 + a 1 ( x x 0 ) + a 2 ( x x 0 ) 2 + + a n ( x x 0 ) n P ( x ) = a _ { 0 } + a _ { 1 } \left( x - x _ { 0 } \right) + a _ { 2 } \left( x - x _ { 0 } \right) ^ { 2 } + \cdots + a _ { n } \left( x - x _ { 0 } \right) ^ { n }

P n ( x ) = P ( x 0 ) + P ( x 0 ) ( x x 0 ) + P ( x 0 ) 2 ! ( x x 0 ) 2 + + P ( n ) ( x 0 ) n ! ( x x 0 ) n \begin{aligned} P _ { n } ( x ) = & P \left( x _ { 0 } \right) + P ^ { \prime } \left( x _ { 0 } \right) \left( x - x _ { 0 } \right) + \frac { P ^ { \prime \prime } \left( x _ { 0 } \right) } { 2 ! } \left( x - x _ { 0 } \right) ^ { 2 } + \cdots + \frac { P ^ { ( n ) } \left( x _ { 0 } \right) } { n ! } \left( x - x _ { 0 } \right) ^ { n } \end{aligned}

算法
θ j = θ j α θ j J ( θ ) α \theta_j := \theta_j-\alpha\frac{\partial}{\partial\theta_j}J(\theta) \quad {\alpha 是学习率}

r e p e a t   u n t i l   c o n v e r g e n c e { θ j : = θ j α θ j J ( θ 0 , θ 1 ) } \begin{aligned} & repeat\ until\ convergence \{ \\ & \theta _ { j } : = \theta _ { j } - \alpha \frac { \partial } { \partial \theta _ { j } } J \left( \theta _ { 0 } , \theta _ { 1 } \right) \\ &\}\\ \end{aligned}

求代价函数的导数
θ j J ( θ 0 θ 1 ) = θ j 1 2 m i = 1 m ( h θ ( x ( i ) ) y ( i ) ) 2 \frac { \partial } { \partial \theta _ { j } } J \left( \theta _ { 0 } \theta _ { 1 } \right) = \frac { \partial } { \partial \theta _ { j } } \frac { 1 } { 2 m } \sum _ { i = 1 } ^ { m } \left( h _ { \theta } \left( x ^ { ( i ) } \right) - y ^ { ( i ) } \right) ^ { 2 }

j=0
θ 0 J ( θ 0 θ 1 ) = 1 m i = 1 m ( h θ ( x ( i ) ) y ( i ) ) \frac { \partial } { \partial \theta _ { 0 } } J \left( \theta _ { 0 } \theta _ { 1 } \right) = \frac { 1 } { m } \sum _ { i = 1 } ^ { m } \left( h _ { \theta } \left( x ^ { ( i ) } \right) - y ^ { ( i ) } \right)
j=1
θ 1 J ( θ 0 θ 1 ) = 1 m i = 1 m ( ( h θ ( x ( i ) ) y ( i ) ) x ( i ) ) \frac { \partial } { \partial \theta _ { 1 } } J \left( \theta _ { 0 } \theta _ { 1 } \right) = \frac { 1 } { m } \sum _ { i = 1 } ^ { m } \left( \left( h _ { \theta } \left( x ^ { ( i ) } \right) - y ^ { ( i ) } \right) \cdot x ^ { ( i ) } \right)

算法变更为
因为公式在这里没有展示出来,所以又传了图片
在这里插入图片描述

$$
\begin{aligned}
repeat \ {\
&\theta _ { 0 } : = \theta _ { 0 } - \alpha \frac { 1 } { \mathrm { m } } \sum _ { \mathrm { i } = 1 } ^ { \mathrm { m } } \left( \mathrm { h } _ { \theta } \left( \mathrm { x } ^ { ( \mathrm { i } ) } \right) - \mathrm { y } ^ { ( \mathrm { i } ) } \right)
\ \ \
&\theta _ { 1 } : = \theta _ { 1 } - \alpha \frac { 1 } { \mathrm { m } } \sum _ { \mathrm { i } = 1 } ^ { \mathrm { m } } \left( \left( \mathrm { h } _ { \theta } \left( \mathrm { x } ^ { ( \mathrm { i } ) } \right) - \mathrm { y } ^ { ( \mathrm { i } ) } \cdot \mathrm { x } ^ { ( \mathrm { i } ) } \right)\right.
&\ \}

\end{aligned}
$$
代码

import matplotlib.pyplot as plt
import numpy as np
import matplotlib
zhfont = matplotlib.font_manager.FontProperties(fname='C:\Windows\Fonts\simsun.ttc')



#theta0需要和1相乘,所以加了一列1
def getDataSet():
    dataset_x = np.array([[1,1,1,1],[1,2,3,4]]).T
    y = np.array([[6],[5],[7],[10]])
    print(dataset_x)
    print(y)
    return dataset_x,y


def getCost(dataset_x, y ,theta):
    temp = np.power((dataset_x*theta.T) - y,2)
    return 1/(2*len(dataset_x)*sum(temp))


    '''
    theta: 需要更新的theta值
    alpha: 学习速率
    iters:迭代次数
    '''
def gradientDescent(dataset_x, y ,theta, alpha, iters):

    temp = np.mat(np.zeros(theta.shape))    
    cost = np.zeros(iters)
    parameters = int (theta.shape[1])     
 
    for  i in range(iters):               
        error = dataset_x*theta.T - y
        for j in range(parameters):      
            term = np.multiply(error,dataset_x[:,j])
            temp[0,j] = theta[0,j] - alpha / len(dataset_x) * sum(term)
        theta = temp
        cost[i] = getCost(dataset_x,y,theta)
    return  theta,cost
 
 
if __name__ == '__main__':
    dataset_x,y = getDataSet()
    alpha = 0.01   
    theta = np.mat(np.array([0,0]))  
    print(theta)
    dataset_x = np.mat(dataset_x)
    y = np.mat(y)
    print(dataset_x)
    print(y)
    iters = 100
    theta,cost = gradientDescent(dataset_x,y,theta,alpha,iters)
    x = np.linspace(dataset_x[:,1].min(),dataset_x[:,1].max(),100)
    h = theta[0,0] + (theta[0,1] * x)
    
    
    plt.scatter(np.array(dataset_x[:,1]),np.array(y[:,0]))
    plt.xlabel('人口数',fontproperties=zhfont)
    plt.ylabel('收益',fontproperties=zhfont)
    plt.plot(x,h)

在这里插入图片描述
L1-norm(LASSO回归)
J ( θ ) = 1 2 i = 1 m ( h θ ( x i ) y ( i ) ) 2 + λ j = 1 n θ j     λ > 0 J(\theta) = \frac{1}{2}\sum^m_{i=1}(h_{\theta}(x^{i}) - y^{(i)})^2 + \lambda\sum^n_{j=1} |\theta_j| \ \ \ \lambda > 0
L2-norm(Ridge回归,岭回归)
J ( θ ) = 1 2 i = 1 m ( h θ ( x i ) y ( i ) ) 2 + λ j = 1 n θ j 2     λ > 0 J(\theta) = \frac{1}{2}\sum^m_{i=1}(h_{\theta}(x^{i}) - y^{(i)})^2 + \lambda\sum^n_{j=1} \theta_j^2 \ \ \ \lambda > 0

同时引入L1-norm和L2-norm(弹性网络ElasitcNet)
J ( θ ) = 1 2 i = 1 m ( h θ ( x i y ( i ) ) ) 2 + λ ( p j = 1 n θ j 2 + ( 1 p ) j = 1 n θ j )     λ > 0 & & p [ 0 , 1 ] J(\theta) = \frac{1}{2}\sum^m_{i=1}(h_{\theta}(x^{i} - y^{(i)}))^2 + \lambda(p\sum^n_{j=1} \theta_j^2 +(1-p)\sum^n_{j=1} |\theta_j| )\ \ \ \lambda > 0 \&\& p \in [0,1]

猜你喜欢

转载自blog.csdn.net/flyfish1986/article/details/86909160