梯度下降的概念
梯度下降是迭代法的一种,可以用于求解最小二乘问题(线性和非线性都可以)。在求解机器学习算法的模型参数,即无约束优化问题时,梯度下降(Gradient Descent)是最常采用的方法之一,另一种常用的方法是最小二乘法。在求解损失函数的最小值时,可以通过梯度下降法来一步步的迭代求解,得到最小化的损失函数和模型参数值。
简介
梯度:对于可微的数量场,以为分量的向量场称为f的梯度或斜量。
梯度下降法(gradient descent)是一个最优化算法,常用于机器学习和人工智能当中用来递归性地逼近最小偏差模型。
迭代公式
梯度下降法的计算过程就是沿梯度下降的方向求解极小值(也可以沿梯度上升方向求解极大值)
其迭代公式为
a
k
+
1
=
a
k
+
ρ
k
s
‾
(
k
)
a_{k+1}=a_k+ρ_k\overline{s}^{(k)}
ak+1=ak+ρks(k),
ρ
k
ρ_k
ρk表示梯度方向上的搜索步长,
s
‾
(
k
)
\overline{s}^{(k)}
s(k)代表梯度负方向。
应用
任意给一个初始出发点,设
x
0
=
−
2
x_0=-2
x0=−2,利用梯度下降法求函数
y
=
1
2
x
2
−
x
y=\frac12x^2-x
y=21x2−x的极小值
(1)定义参数:
η
=
0.9
,
,
ε
=
0.01
η=0.9,,ε=0.01
η=0.9,,ε=0.01
(2)计算导数:
d
y
d
x
=
x
−
1
\frac {dy}{dx}=x-1
dxdy=x−1
(3)当前导数值:
y
′
=
−
3
y^{'}=-3
y′=−3
(4)修改参数当前值:
x
′
=
x
−
η
d
y
d
x
=
−
2
−
0.9
∗
(
−
3
)
=
0.7
x^{'}=x-η\frac {dy}{dx}=-2-0.9*(-3)=0.7
x′=x−ηdxdy=−2−0.9∗(−3)=0.7
Δ
x
=
−
0.9
∗
(
−
3
)
=
2.7
Δx=-0.9*(-3)=2.7
Δx=−0.9∗(−3)=2.7
(5)当前导数值:
y
′
=
−
0.3
y^{'}=-0.3
y′=−0.3
(6)修改参数当前值:
x
′
=
x
−
η
d
y
d
x
=
0.7
−
0.9
∗
(
−
0.3
)
=
0.97
x^{'}=x-η\frac {dy}{dx}=0.7-0.9*(-0.3)=0.97
x′=x−ηdxdy=0.7−0.9∗(−0.3)=0.97
Δ
x
=
−
0.9
∗
(
−
0.3
)
=
0.27
Δx=-0.9*(-0.3)=0.27
Δx=−0.9∗(−0.3)=0.27
(7)当前导数值:
y
′
=
−
0.03
y^{'}=-0.03
y′=−0.03
(8)修改参数当前值:
x
′
=
x
−
η
d
y
d
x
=
0.97
−
0.9
∗
(
−
0.03
)
=
0.997
x^{'}=x-η\frac {dy}{dx}=0.97-0.9*(-0.03)=0.997
x′=x−ηdxdy=0.97−0.9∗(−0.03)=0.997
Δ
x
=
−
0.9
∗
(
−
0.03
)
=
−
0.027
Δx=-0.9*(-0.03)=-0.027
Δx=−0.9∗(−0.03)=−0.027
(9)当前导数值:
y
′
=
−
0.003
y^{'}=-0.003
y′=−0.003
(10)修改参数当前值:
x
′
=
x
−
η
d
y
d
x
=
0.997
−
0.9
∗
(
−
0.003
)
=
0.9997
x^{'}=x-η\frac {dy}{dx}=0.997-0.9*(-0.003)=0.9997
x′=x−ηdxdy=0.997−0.9∗(−0.003)=0.9997
Δ
x
=
−
0.9
∗
(
−
0.3
)
=
0.0027
<
ε
Δx=-0.9*(-0.3)=0.0027< ε
Δx=−0.9∗(−0.3)=0.0027<ε
(11)0.0027< ε结束
代码
# -*- coding: utf-8 -*-
"""
Created on Wed Dec 16 00:17:40 2020
@author: leejongsuk
"""
import numpy as np
def f(x):
return np.power(x,2)*0.5-x
def df1(x):
return x-1;
learning_rate=0.9
n=0.01
max_loop=10
x_init=-2
x=x_init
print("Initial value of x is \n",x)
print("Initial value of Df1(x) is \n",df1(x))
for i in range(max_loop):
x=x-learning_rate*df1(x)
x1=-learning_rate*df1(x)
print("Current value of x is \n",x)
print("Current value of Df1(x) is \n",df1(x))
if x1<n:
break
print("min value of x=",x)
运行结果:
Initial value of x is
-2
Initial value of Df1(x) is
-3
Current value of x is
0.7000000000000002
Current value of Df1(x) is
-0.2999999999999998
Current value of x is
0.97
Current value of Df1(x) is
-0.030000000000000027
Current value of x is
0.997
Current value of Df1(x) is
-0.0030000000000000027
min value of f(x)= 0.997
矩阵分解的概念
矩阵分解是将矩阵拆解为数个矩阵的乘积。
过程
- 首先令 r ^ i j = p i T = ∑ k = 1 k p i k q k j \hat{r}_{ij}=p_i^T={\sum_{k=1}^k }p_{ik}q_{kj} r^ij=piT=∑k=1kpikqkj
- 损失函数:使用原始的评分矩阵
R
m
×
n
R_{m×n}
Rm×n 与重新构建的评分矩阵
R
^
m
×
n
\hat{R}_{m×n}
R^m×n之间的误差的平方作为损失函数.如果R(i,j)已知,则R(i,j)的误差平方和为:
e
i
j
2
=
(
r
i
j
−
r
^
i
j
)
2
=
(
r
i
j
−
∑
k
=
1
k
p
i
k
q
k
j
)
2
e_{ij}^2=(r_{ij}-\hat{r}_{ij})^2=(r_{ij}-{\sum_{k=1}^k }p_{ik}q_{kj})^2
eij2=(rij−r^ij)2=(rij−k=1∑kpikqkj)2
最终,需要求解所有的非“-”项的损失之和的最小值:
3.使用梯度下降法获得修正的p和q分量:
求解损失函数的负梯度
求解负梯度方向的更新变量
4.不停迭代直到算法最终收敛(直到sum(e^2) <=阈值)
# -*- coding: utf-8 -*-
"""
Created on Wed Dec 16 21:37:09 2020
@author: leejongsuk
"""
import matplotlib.pyplot as plt
from math import pow
import numpy
def matrix_factorization(R,P,Q,K,steps=5000,alpha=0.0002,beta=0.02):
Q=Q.T # .T操作表示矩阵的转置
result=[]
for step in range(steps):
for i in range(len(R)):
for j in range(len(R[i])):
if R[i][j]>0:
eij=R[i][j]-numpy.dot(P[i,:],Q[:,j]) # .dot(P,Q) 表示矩阵内积
for k in range(K):
P[i][k]=P[i][k]+alpha*(2*eij*Q[k][j]-beta*P[i][k])
Q[k][j]=Q[k][j]+alpha*(2*eij*P[i][k]-beta*Q[k][j])
eR=numpy.dot(P,Q)
e=0
for i in range(len(R)):
for j in range(len(R[i])):
if R[i][j]>0:
e=e+pow(R[i][j]-numpy.dot(P[i,:],Q[:,j]),2)
for k in range(K):
e=e+(beta/2)*(pow(P[i][k],2)+pow(Q[k][j],2))
result.append(e)
if e<0.001:
break
return P,Q.T,result
if __name__ == '__main__':
R=[
[5,3,0,2],
[4,0,0,1],
[5,3,0,1],
[1,0,1,4],
[0,1,5,4]
]
R=numpy.array(R)
N=len(R)
M=len(R[0])
K=2
P=numpy.random.rand(N,K) #随机生成一个 N行 K列的矩阵
Q=numpy.random.rand(M,K) #随机生成一个 M行 K列的矩阵
nP,nQ,result=matrix_factorization(R,P,Q,K)
print("原始的评分矩阵R为:\n",R)
R_MF=numpy.dot(nP,nQ.T)
print("经过MF算法填充0处评分值后的评分矩阵R_MF为:\n",R_MF)
代码参考:https://www.cnblogs.com/shenxiaolin/p/8637794.html