python对于一元线性回归模型_用Python实现一元线性回归的梯度下降

线性回归

线性回归公式:$h_θ$ = $θ_0$ + $θ_1x$

平方差代价函数:$J(θ)$ = $\frac1{2m}\sum_{i=1}^{m}{(h_θ(x^{(i)}) - y^{(i)})}^2$

梯度下降

$θ_j := θ_j - α\frac∂ {∂ θ_j}J(θ_0,θ_1)$

使用上面的公式不断的更新代价函数$J(θ)$,直到$J(θ)$收敛或者不再发散,其中:

$\frac∂ {∂ θ_j}J(θ_0,θ_1)$ = $\frac∂{∂θ_j}\frac1{2m} \sum_{i=1}^{m}(θ_0 +θ_1x^{(i)} - y^{(i)})^2$

$j = 0:\frac∂ {∂ θ_0}J(θ_0,θ_1) = \frac1m\sum_{i=1}^{m}(h_θ(x^{(i)}) - y^{(i)})$

$j = 1:\frac∂ {∂ θ_1}J(θ_0,θ_1) = \frac1m\sum_{i=1}^{m}(h_θ(x^{(i)}) - y^{(i)}) * x^{(i)}$

算出代价函数$j$的斜率后,将其代回梯度下降算法,代入之后的线性回归的梯度下降算法为: $θ_0 := θ_0 - α\frac1m\sum_{i=1}^{m}(h_θ(x^{(i)}) - y^{(i)})$

$θ_1 := θ_1 -α\frac1m\sum_{i=1}^{m}(h_θ(x^{(i)}) - y^{(i)}) * x^{(i)}$

不断重复该过程直到收敛或者不再发散。

python代码实现

import numpy as np

import matplotlib.pyplot as plt

import pandas as pd

def h(xita0,xita1,data):

data['y_pre'] = xita0 + data['x']*xita1

j0 = (1/(data.shape[0])*2) * sum(data['y_pre'] - data['y'])

j1 = (1/(data.shape[0])*2) * sum((data['y_pre'] - data['y']) * data['x'])

return j0,j1

def j(data,aerfa=0.001,max_iters=100000,precision=0.00001):

xita0 = 0

xita1 = 0

for i in range(max_iters):

print('xita0,xita1:',xita0,xita1)

j0,j1 = h(xita0,xita1,data)

print(j0,j1)

if abs(j1) < precision:

break

xita0 = xita0 - aerfa * j0

xita1 = xita1 - aerfa * j1

print(i)

return xita0,xita1

num_points = 1000

vectors_set = []

for i in range(num_points):

x1 = np.random.normal(0.0, 0.55)

y1 = x1 * 0.5 + 0.5 + np.random.normal(0.0, 0.03)

vectors_set.append([x1, y1])

data = pd.DataFrame(vectors_set,columns=['x','y'])

xita0,xita1 = j(data)

x_data = [v[0] for v in vectors_set]

y_data = [v[1] for v in vectors_set]

y_pre = [xita0 + xita1*v[0] for v in vectors_set]

plt.scatter(x_data,y_data,c='b')#c表示颜色

plt.plot(x_data,y_pre)

plt.show()

复盘

平方差代价函数:$J(θ)$ = $\frac1{2m}\sum_{i=1}^{m}{((θ_0 + θ_1x) - y^{(i)})}^2$ 梯度下降法求解的过程就是通过不断的迭代,通过不同的$θ_0 和 θ_1$的组合,来求$J(θ)$的值,使得$J(θ)$最小的那个组合,就是线性回归模型中最优的$θ_0 和 θ_1$。 下面,我们使用python来求解:

from matplotlib import pyplot as plt

from mpl_toolkits.mplot3d import Axes3D

import pandas as pd

def surface3d_data():

'''我们从0到1易0.05的步长迭代不同的θ_0(x)和 θ_1(y)的组合,来计算代价值(z)'''

for t0 in float_range(0, 1, 0.05):

x = float(t0)

for t1 in float_range(0, 1, 0.05):

y = float(t1)

z = round((1/(data.shape[0])*2) * sum(np.square((x + y*data['x'])-data['y'])),4)

yield [x, y, z]

def draw(x, y, z):

'''采用matplolib绘制曲面图:param x: x轴坐标数组:param y: y轴坐标数组:param z: z轴坐标数组:return:'''

X = x

Y = y

Z = z

fig = plt.figure(figsize=(30,30))

ax = fig.add_subplot(111, projection='3d')

ax.plot_trisurf(X, Y, Z)

plt.show()

res = list(surface3d_data())

df = pd.DataFrame(res,columns=['xita0','xita1','j'])

#查看使得代价函数最小的'xita0','xita1'是多少

print(df.loc[df.j.idxmin(),:])

# 输出结果为:

# xita0 0.5000

# xita1 0.5000

# j 0.0009

# 和我们生成随机数点的公式相同,如下:

# y1 = x1 * 0.5 + 0.5 + np.random.normal(0.0, 0.03)

x = [v[0] for v in res]

y = [v[1] for v in res]

z = [v[2] for v in res]

draw(x, y, z) #画出代价函数的曲面图

通过观察可得,曲面大概在x = 0.5,y = 0.5点的点上取得最小值。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值