梯度下降与矩阵分解学习随笔

梯度下降的概念

梯度下降是迭代法的一种,可以用于求解最小二乘问题(线性和非线性都可以)。在求解机器学习算法的模型参数,即无约束优化问题时,梯度下降(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=21x2x的极小值
(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=x1
(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=20.93=0.7 Δ x = − 0.9 ∗ ( − 3 ) = 2.7 Δx=-0.9*(-3)=2.7 Δx=0.93=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.70.90.3=0.97 Δ x = − 0.9 ∗ ( − 0.3 ) = 0.27 Δx=-0.9*(-0.3)=0.27 Δx=0.90.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.970.90.03=0.997 Δ x = − 0.9 ∗ ( − 0.03 ) = − 0.027 Δx=-0.9*(-0.03)=-0.027 Δx=0.90.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.9970.90.003=0.9997 Δ x = − 0.9 ∗ ( − 0.3 ) = 0.0027 < ε Δx=-0.9*(-0.3)=0.0027< ε Δx=0.90.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

矩阵分解的概念

矩阵分解是将矩阵拆解为数个矩阵的乘积。

过程

  1. 首先令 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
  2. 损失函数:使用原始的评分矩阵 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=(rijr^ij)2=(rijk=1kpikqkj)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

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值