梯度下降法:
损失函数:
l
o
s
s
=
∑
i
=
1
n
1
2
n
[
y
−
(
k
x
+
b
)
]
2
loss=\sum_{i=1}^{n}\frac{1}{2n}[y-(kx+b)]^2
loss=i=1∑n2n1[y−(kx+b)]2
对
k
,
b
k,b
k,b求梯度:
k
g
r
a
d
=
∂
l
o
s
s
∂
k
=
−
∑
i
=
1
n
x
n
[
y
−
(
k
x
+
b
)
]
k_{grad}=\frac{\partial loss}{\partial k}=-\sum_{i=1}^{n}\frac{x}{n}[y-(kx+b)]
kgrad=∂k∂loss=−i=1∑nnx[y−(kx+b)]
b
g
r
a
d
=
∂
l
o
s
s
∂
b
=
−
∑
i
=
1
n
1
n
[
y
−
(
k
x
+
b
)
]
b_{grad}=\frac{\partial loss}{\partial b}=-\sum_{i=1}^{n}\frac{1}{n}[y-(kx+b)]
bgrad=∂b∂loss=−i=1∑nn1[y−(kx+b)]
梯度下降迭代公式:
k
′
=
k
−
l
r
∗
k
g
r
a
d
k^\prime=k-lr*k_{grad}
k′=k−lr∗kgrad
b
′
=
b
−
l
r
∗
b
g
r
a
d
b^\prime=b-lr*b_{grad}
b′=b−lr∗bgrad
其中
l
r
lr
lr表示学习率。
import numpy as np
from matplotlib import pyplot as plt
data=np.genfromtxt("data.csv",delimiter=',')
x_data=data[:,0]
y_data=data[:,1]
plt.scatter(x_data,y_data)
plt.show()
lr=0.0001
b=0
k=0
epochs=100
def loss(x_data,y_data,k,b):#损失函数
n=len(x_data)
tot=0
for i in range(0,n):
tot+=(k*x_data[i]+b-y_data[i])**2
return tot/n/2
def grad_descent(x_data,y_data,k,b,lr,epochs):#梯度下降
n=len(x_data)
for i in range(epochs):
b_grad=0
k_grad=0
for j in range(n):
b_grad+=(1/n)*(k*x_data[j]+b-y_data[j])
k_grad+=(1/n)*x_data[j]*(k*x_data[j]+b-y_data[j])
b=b-lr*b_grad
k=k-lr*k_grad
if(i%10==0):
print("epochs={0}".format(i))
plt.plot(x_data,y_data,'b.')
plt.plot(x_data,k*x_data+b,'r')
plt.show()
return k,b
print("starting k={0},b={1},loss={2}".format(k,b,loss(x_data,y_data,k,b)))
print("running")
k,b=grad_descent(x_data,y_data,k,b,lr,epochs)
print("after {0} epochs k={1},b={2},loss={3}".format(epochs,k,b,loss(x_data,y_data,k,b)))
sklearn法:
import numpy as np
from matplotlib import pyplot as plt
from sklearn.linear_model import LinearRegression
data=np.genfromtxt("data.csv",delimiter=',')
x_data=data[:,0,np.newaxis]#sklearn 导入的数据需要是一个二维矩阵
y_data=data[:,1,np.newaxis]
plt.scatter(x_data,y_data)
plt.show()
model=LinearRegression()
model.fit(x_data,y_data)#fit 用来建立回归直线
plt.plot(x_data,y_data,'b.')
plt.plot(x_data,model.predict(x_data),'r')# model.predict可以预测x对应的y
plt.show()