大数据——协同过滤推荐算法:矩阵分解

news2024/11/24 5:02:31

矩阵分解的方法也分为很多种:SVD、LFM、BiasSVD和SVD++。

  • Traditional SVD
    一般SVD矩阵分解指的是SVD奇异值分解,将矩阵分解成三个相乘矩阵,中间矩阵就是奇异值矩阵。SVD分解的前提是矩阵是稠密的,现实场景中数据都是稀疏的,无法使用SVD,需要均值或者其他方法来填充,会对数据造成一定影响。具体公式如下:
    M m × n = U m × k ∑ k × k K k × n T M_{m×n} = U_{m×k}\sum_{k×k}K^T_{k×n} Mm×n=Um×kk×kKk×nT
  • FunkSVD(LFM)
    FunkSVD是最原始的LFM模型,它将矩阵分解为2个矩阵:用户-隐含特征矩阵,物品-隐含特征矩阵,一般这个过程跟线性回归类似。以下公式为矩阵分解后的损失函数,p为用户-隐含特征矩阵,q为物品-隐含特征矩阵,我们通过求损失函数的最小值来计算p和q,后面部分为L2范式,防止过拟合。下面公式用随机梯度下降来求最优解。
    m i n q p ∑ ( u , i ) ∈ R ( r u i − q i T p u ) 2 + λ ( ∣ ∣ q i ∣ ∣ 2 + ∣ ∣ p u ∣ ∣ 2 ) \mathop{min}\limits_{qp}\sum_{(u,i)∈R}(r_{ui}-q^T_ip_u)^2+\lambda(||q_i||^2+||p_u||^2) qpmin(u,i)R(ruiqiTpu)2+λ(∣∣qi2+∣∣pu2)
  • BiasSVD
    BiasSVD就是在FunkSVD的基础上加上Baseline基准预测的偏置项,具体公式如下:
    m i n q p ∑ ( u , i ) ∈ R ( r u i − u − b u − b i − q i T p u ) 2 + λ ( ∣ ∣ q i ∣ ∣ 2 + ∣ ∣ p u ∣ ∣ 2 + ∣ ∣ b u ∣ ∣ 2 + ∣ ∣ b i ∣ ∣ 2 ) \mathop{min}\limits_{qp}\sum_{(u,i)∈R}(r_{ui}-u-b_u-b_i-q^T_ip_u)^2+\lambda(||q_i||^2+||p_u||^2+||b_u||^2+||b_i||^2) qpmin(u,i)R(ruiububiqiTpu)2+λ(∣∣qi2+∣∣pu2+∣∣bu2+∣∣bi2)
  • SVD++
    改进的BiasSVD,即在BiasSVD的基础上再加上用户的隐式反馈信息。这里不做多介绍。

1 LFM原理解析

LFM隐语义模型的核心思想是通过隐含特征联系用户和物品。
在这里插入图片描述

P是用户和隐含特征矩阵,这里表示三个隐含特征;
Q是隐含特征和物品矩阵
Q是User-Item,由P*Q得来。

我们利用矩阵分解技术,将User-Item评分矩阵分解为P和Q的矩阵,然后利用P*Q还原评分矩阵。其中 R 11 = P 1 , k ⃗ ⋅ Q k , 1 ⃗ R_{11} = \vec{P_{1,k}}·\vec{Q_{k,1}} R11=P1,k Qk,1
所以我们的评分为:
r u i ^ = p u , k ⃗ ⋅ q i , k ⃗ = ∑ k = 1 k p u k q i k \hat{r_{ui}} = \vec{p_{u,k}}·\vec{q_{i,k}} = \sum_{k=1}^{k}p_{uk}q_{ik} rui^=pu,k qi,k =k=1kpukqik

损失函数

C o s t = ∑ u , i ∈ R ( r u i − r ^ u i ) 2 = ∑ u , i ∈ R ( r u i − ∑ k = 1 k p u k q i k ) 2 Cost = \sum_{u,i∈R}(r_{ui}-\hat r_{ui})^2 = \sum_{u,i∈R}(r_{ui}-\sum_{k=1}^{k}p_{uk}q_{ik})^2 Cost=u,iR(ruir^ui)2=u,iR(ruik=1kpukqik)2
加入L2范式防止过拟合,如下:
C o s t = ∑ u , i ∈ R ( r u i − ∑ k = 1 k p u k q i k ) 2 + λ ( ∑ U p u k 2 + ∑ I q i k 2 ) Cost = \sum_{u,i∈R}(r_{ui}-\sum_{k=1}^{k}p_{uk}q_{ik})^2 +\lambda(\sum_U p^2_{uk}+\sum_I q^2_{ik}) Cost=u,iR(ruik=1kpukqik)2+λ(Upuk2+Iqik2)
对损失函数求偏导可得:
∂ ∂ p u k C o s t = 2 ∑ u , i ∈ R ( r u i − ∑ k = 1 k p u k q i k ) ( − q i k ) + 2 λ p u k \frac{∂}{∂p_{uk}}Cost = 2\sum_{u,i∈R}(r_{ui}-\sum_{k=1}^{k}p_{uk}q_{ik})(-q_{ik}) + 2\lambda p_{uk} pukCost=2u,iR(ruik=1kpukqik)(qik)+2λpuk
∂ ∂ q i k C o s t = 2 ∑ u , i ∈ R ( r u i − ∑ k = 1 k p u k q i k ) ( − p u k ) + 2 λ q i k \frac{∂}{∂q_{ik}}Cost = 2\sum_{u,i∈R}(r_{ui}-\sum_{k=1}^{k}p_{uk}q_{ik})(-p_{uk}) + 2\lambda q_{ik} qikCost=2u,iR(ruik=1kpukqik)(puk)+2λqik

随机梯度下降法优化

根据偏导可更新梯度下降参数:
p u k : = p u k + α [ ∑ u , i ∈ R ( r u i − ∑ k = 1 k p u k q i k ) ( q i k ) − λ 1 p u k ] p_{uk}:=p_{uk} + \alpha[\sum_{u,i∈R}(r_{ui}-\sum_{k=1}^{k}p_{uk}q_{ik})(q_{ik}) - \lambda_1 p_{uk}] puk:=puk+α[u,iR(ruik=1kpukqik)(qik)λ1puk]
q i k : = p i k + α [ ∑ u , i ∈ R ( r u i − ∑ k = 1 k p u k q i k ) ( p u k ) − λ 2 q i k ] q_{ik}:=p_{ik} + \alpha[\sum_{u,i∈R}(r_{ui}-\sum_{k=1}^{k}p_{uk}q_{ik})(p_{uk}) -\lambda_2 q_{ik}] qik:=pik+α[u,iR(ruik=1kpukqik)(puk)λ2qik]
随机梯度下降
应用到每个向量里
p u k : = p u k + α [ ( r u i − ∑ k = 1 k p u k q i k ) ( q i k ) − λ 1 p u k ] p_{uk}:=p_{uk} + \alpha[(r_{ui}-\sum_{k=1}^{k}p_{uk}q_{ik})(q_{ik}) - \lambda_1 p_{uk}] puk:=puk+α[(ruik=1kpukqik)(qik)λ1puk]
q i k : = p i k + α [ ( r u i − ∑ k = 1 k p u k q i k ) ( p u k ) − λ 2 q i k ] q_{ik}:=p_{ik} + \alpha[(r_{ui}-\sum_{k=1}^{k}p_{uk}q_{ik})(p_{uk}) -\lambda_2 q_{ik}] qik:=pik+α[(ruik=1kpukqik)(puk)λ2qik]

算法实现

这里只展示LFM算法的代码,数据集分割代码和评估代码见:大数据——协同过滤推荐算法:线性回归算法

# FunkSVD
class LFM(object):
   '''max_epochs 梯度下降迭代次数
       alpha 学习率
       reg 过拟合参数
       columns 数据字段名称'''
   def __init__(self,max_epochs,p_reg,q_reg,alpha,number_LatentFactors=30,columns=['userId','movieId','rating']):
       self.max_epochs = max_epochs
       self.p_reg = p_reg
       self.q_reg = q_reg
       self.number_LatentFactors=number_LatentFactors #隐式特征的数量
       self.alpha = alpha
       self.columns = columns
       
   def fit(self,data):
       '''
       :param data:uid,mid,rating
       :return:'''
       self.data = data
       # 用户评分数据
       self.users_rating = data.groupby(self.columns[0]).agg([list])[[self.columns[1], self.columns[2]]]
       # 电影评分数据
       self.items_rating = data.groupby(self.columns[1]).agg([list])[[self.columns[0], self.columns[2]]]
       # 全局平均分
       self.global_mean = self.data[self.columns[2]].mean()
       # 调用随机梯度下降训练模型参数
       self.p,self.q = self.sgd()
       
   def _init_matrix(self):
       # 构建p的矩阵,其中第二项元素的大小为用户数量*隐式特征
       p = dict(zip(self.users_rating.index, 
                    np.random.rand(len(self.users_rating), self.number_LatentFactors).astype(np.float32)))
       # 构建q的矩阵,其中第二项元素的大小为物品数量*隐式特征
       q = dict(zip(self.items_rating.index,
                    np.random.rand(len(self.items_rating), self.number_LatentFactors).astype(np.float32)))
       return p,q
   
   def sgd(self):
       '''
       最小二乘法,优化q和p值
       :return: q p'''
       p,q = self._init_matrix()
       
       for i in range(self.max_epochs):
           error_list = []
           for uid,mid,r_ui in self.data.itertuples(index=False):
               # user-lf p
               # item-lf q
               v_pu = p[uid]
               v_qi = q[mid]
               err = np.float32(r_ui - np.dot(v_pu, v_qi))
               
               v_pu += self.alpha*(err*v_qi - self.p_reg*v_pu)
               v_qi += self.alpha*(err*v_pu - self.q_reg*v_qi)
               
               p[uid] = v_pu
               q[mid] = v_qi
               
               error_list.append(err**2)
               
       return p,q
   
   def predict(self,uid,mid):
       '''
       使用评分公式进行预测
       param uid,mid;
       return predict_rating;'''
       if uid not in self.users_rating.index or mid not in self.items_rating.index:
           return self.global_mean
       p_u = self.p[uid]
       q_i = self.q[mid]
       return np.dot(p_u,q_i)
   
   def test(self,testset):
       '''
       使用预测函数预测测试集数据
       param testset;
       return yield;'''
       for uid,mid,real_rating in testset.itertuples(index=False):
           try:
               # 使用predict函数进行预测
               pred_rating = self.predict(uid,mid)
           except Exception as e:
               print(e)
           else:
               # 返回生成器对象
               yield uid,mid,real_rating,pred_rating

测试LFM算法

trainset, testset = data_split('ml-latest-small/ratings.csv',random=True)
lfm = LFM(100,0.01,0.01,0.02,10,['userId','movieId','rating'])
lfm.fit(trainset)
pred_test = lfm.test(testset)
# 生成器对象用list进行转化,然后转化为dataframe格式
df_pred_LFM = pd.DataFrame(list(pred_test), columns=[['userId','movieId','rating','pred_rating']])
rmse, mae = accuray(df_pred_als,'all')
print('rmse:',rmse,';mae:',mae)

rmse: 1.0718 ;mae: 0.8067

2 BiasSVD原理

BiasSVD是在FunkSVD矩阵分解的基础上加上了偏置项的。评分公式如下:
r ^ u i = u + b u + b i + p u k ⃗ ⋅ q k i ⃗ = u + b u + b i + ∑ k = 1 k p u k ⋅ q k i \hat r_{ui} = u+b_u+b_i+\vec{p_{uk}}·\vec{q_{ki}} = u+b_u+b_i+\sum^{k}_{k=1}{p_{uk}}·{q_{ki}} r^ui=u+bu+bi+puk qki =u+bu+bi+k=1kpukqki

损失函数
C o s t = ∑ u , i ∈ R ( r u i − r ^ u i ) 2 = ∑ u , i ∈ R ( r u i − u − b u − b i − ∑ k = 1 k p u k ⋅ q k i ) 2 Cost = \sum_{u,i∈R}(r_{ui}-\hat r_{ui})^2 = \sum_{u,i∈R}(r_{ui}-u-b_u-b_i-\sum^{k}_{k=1}{p_{uk}}·{q_{ki}})^2 Cost=u,iR(ruir^ui)2=u,iR(ruiububik=1kpukqki)2
加入L2范式
C o s t = ∑ u , i ∈ R ( r u i − r ^ u i ) 2 = ∑ u , i ∈ R ( r u i − u − b u − b i − ∑ k = 1 k p u k ⋅ q k i ) 2 + λ ( ∑ U b u 2 + ∑ I b i 2 + ∑ U p u k 2 + ∑ I q i k 2 ) Cost = \sum_{u,i∈R}(r_{ui}-\hat r_{ui})^2 = \sum_{u,i∈R}(r_{ui}-u-b_u-b_i-\sum^{k}_{k=1}{p_{uk}}·{q_{ki}})^2 +\lambda(\sum_Ub^2_u+\sum_Ib^2_i+\sum_Up^2_{uk}+\sum_Iq^2_{ik}) Cost=u,iR(ruir^ui)2=u,iR(ruiububik=1kpukqki)2+λ(Ubu2+Ibi2+Upuk2+Iqik2)

随机梯度下降法优化
梯度下降更新参数:
p u k : = p u k + α [ ( r u i − u − b u − b i − ∑ k = 1 k p u k ⋅ q k i ) q i k − λ 1 p u k ] p_{uk}:=p_{uk} + \alpha[(r_{ui}-u-b_u-b_i-\sum^{k}_{k=1}{p_{uk}}·{q_{ki}})q_{ik}-\lambda_1p_{uk}] puk:=puk+α[(ruiububik=1kpukqki)qikλ1puk]
q i k : = p i k + α [ ( r u i − u − b u − b i − ∑ k = 1 k p u k ⋅ q k i ) p u k − λ 2 q i k ] q_{ik}:=p_{ik} + \alpha[(r_{ui}-u-b_u-b_i-\sum^{k}_{k=1}{p_{uk}}·{q_{ki}})p_{uk}-\lambda_2q_{ik}] qik:=pik+α[(ruiububik=1kpukqki)pukλ2qik]
b u : = b u + α [ ( r u i − u − b u − b i − ∑ k = 1 k p u k ⋅ q k i ) − λ 3 b u ] b_{u}:=b_{u} + \alpha[(r_{ui}-u-b_u-b_i-\sum^{k}_{k=1}{p_{uk}}·{q_{ki}})-\lambda_3b_{u}] bu:=bu+α[(ruiububik=1kpukqki)λ3bu]
b i : = b i + α [ ( r u i − u − b u − b i − ∑ k = 1 k p u k ⋅ q k i ) − λ 4 b i ] b_{i}:=b_{i} + \alpha[(r_{ui}-u-b_u-b_i-\sum^{k}_{k=1}{p_{uk}}·{q_{ki}})-\lambda_4b_{i}] bi:=bi+α[(ruiububik=1kpukqki)λ4bi]

算法实现

# BiasSVD
class BiasSvd(object):
   '''max_epochs 梯度下降迭代次数
       alpha 学习率
       reg 过拟合参数
       columns 数据字段名称'''
   def __init__(self,alpha,p_reg,q_reg,bu_reg,bi_reg,number_LatentFactors=10,max_epochs=10,columns=['userId','movieId','rating']):
       self.max_epochs = max_epochs
       self.p_reg = p_reg
       self.q_reg = q_reg
       self.bu_reg = bu_reg
       self.bi_reg = bi_reg
       self.number_LatentFactors=number_LatentFactors #隐式特征的数量
       self.alpha = alpha
       self.columns = columns
       
   def fit(self,data):
       '''
       :param data:uid,mid,rating
       :return:'''
       self.data = data
       # 用户评分数据
       self.users_rating = data.groupby(self.columns[0]).agg([list])[[self.columns[1], self.columns[2]]]
       # 电影评分数据
       self.items_rating = data.groupby(self.columns[1]).agg([list])[[self.columns[0], self.columns[2]]]
       # 全局平均分
       self.global_mean = self.data[self.columns[2]].mean()
       # 调用随机梯度下降训练模型参数
       self.p,self.q, self.bu,self.bi= self.sgd()
       
   def _init_matrix(self):
       # 构建p的矩阵,其中第二项元素的大小为用户数量*隐式特征
       p = dict(zip(self.users_rating.index, 
                    np.random.rand(len(self.users_rating), self.number_LatentFactors).astype(np.float32)))
       # 构建q的矩阵,其中第二项元素的大小为物品数量*隐式特征
       q = dict(zip(self.items_rating.index,
                    np.random.rand(len(self.items_rating), self.number_LatentFactors).astype(np.float32)))
       return p,q
   
   def sgd(self):
       '''
       随机梯度下降,优化q和p值
       :return: q p'''
       p,q = self._init_matrix()
       bu = dict(zip(self.users_rating.index, np.zeros(len(self.users_rating))))
       bi = dict(zip(self.items_rating.index,np.zeros(len(self.items_rating))))
       
       for i in range(self.max_epochs):
           error_list = []
           for uid,mid,r_ui in self.data.itertuples(index=False):
               # user-lf p
               # item-lf q
               v_pu = p[uid]
               v_qi = q[mid]
               err = np.float32(r_ui - self.global_mean - bu[uid] - bi[mid]-np.dot(v_pu, v_qi))
               
               v_pu += self.alpha*(err*v_qi - self.p_reg*v_pu)
               v_qi += self.alpha*(err*v_pu - self.q_reg*v_qi)
               
               p[uid] = v_pu
               q[mid] = v_qi
               
               bu[uid] += self.alpha*(err - self.bu_reg*bu[uid])
               bi[mid] += self.alpha*(err - self.bi_reg*bi[mid])
               
               error_list.append(err**2)
               
       return p,q,bu,bi
   
   def predict(self,uid,mid):
       '''
       使用评分公式进行预测
       param uid,mid;
       return predict_rating;'''
       if uid not in self.users_rating.index or mid not in self.items_rating.index:
           return self.global_mean
       p_u = self.p[uid]
       q_i = self.q[mid]
       return self.global_mean+self.bu[uid]+self.bi[mid]+np.dot(p_u,q_i)
   
   def test(self,testset):
       '''
       使用预测函数预测测试集数据
       param testset;
       return yield;'''
       for uid,mid,real_rating in testset.itertuples(index=False):
           try:
               # 使用predict函数进行预测
               pred_rating = self.predict(uid,mid)
           except Exception as e:
               print(e)
           else:
               # 返回生成器对象
               yield uid,mid,real_rating,pred_rating

算法使用

trainset, testset = data_split('ml-latest-small/ratings.csv',random=True)
bsvd = BiasSvd(0.02,0.01,0.01,0.01,0.01,10,20,['userId','movieId','rating'])
bsvd.fit(trainset)
pred_test = bsvd.test(testset)
# 生成器对象用list进行转化,然后转化为dataframe格式
df_pred_LFM = pd.DataFrame(list(pred_test), columns=[['userId','movieId','rating','pred_rating']])
rmse, mae = accuray(df_pred_als,'all')
print('rmse:',rmse,';mae:',mae)

rmse: 1.0718 ;mae: 0.8067

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/875039.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

(7)(7.4) 集结航点

文章目录 7.4.1 概述 7.4.2 设置集结航点 7.4.3 飞行示例 7.4.4 附录 7.4.1 概述 通常情况下,当固定翼或旋翼飞机进入"返回发射"(Return to Launch (RTL))模式(通常由自动驾驶仪失控保护触发)(failsafe)时,默认行为…

探讨uniapp的网络通信问题

uni-app 中有很多原生的 API,其中我们经常会用到的肯定有:uni.request(OBJECT) method 有效值 注意:method有效值必须大写,每个平台支持的method有效值不同,详细见下表。 success 返回参数说明 data 数据说明 最终…

《Java极简设计模式》第03章:工厂方法模式(FactoryMethod)

作者:冰河 星球:http://m6z.cn/6aeFbs 博客:https://binghe.gitcode.host 文章汇总:https://binghe.gitcode.host/md/all/all.html 源码地址:https://github.com/binghe001/java-simple-design-patterns/tree/master/j…

【量化课程】08_1.机器学习量化策略基础实战

文章目录 1. 常用机器学习模型1.1 回归模型1.2 分类模型1.2.1 SVC介绍1.2.2 SVC在量化策略中的应用 2. 机器学习量化策略实现的基本步骤3. 策略实现 1. 常用机器学习模型 1.1 回归模型 线性回归多层感知器回归自适应提升树回归随机森林回归 1.2 分类模型 线性分类支持向量机…

openLayers实战(五):overlay绘制标记

引入与创建overlay import Overlay from "ol/Overlay";// 创建map实例以及其他地图操作请看前几篇文章 // 省略2k行代码methods: {creatMark(markDom, txt, idstr) {if (markDom null) {markDom document.createElement("div");if (txt) {ma…

2024」预备研究生mem-阴影图形

一、阴影图形 二、课后题

java 加载商户API私钥 (pem证书私钥)

1. pem证书放在resources目录下 2. 加载证书的工具类 import com.wechat.pay.contrib.apache.httpclient.util.PemUtil; // 商户API私钥 (把证书放在项目路径下, 然后加载出来), 加载证书的工具类PrivateKey merchantPrivateKey PemUtil.loadPrivateKey(new FileInp…

深入探究进程、线程和协程:并发编程的三重境界

文章目录 🍀引言🍀进程:隔离的执行环境🍀概念🍀应用场景🍀代码演示 🍀线程:轻量级的执行单元🍀概念🍀应用场景🍀代码演示 🍀协程&…

文件恢复软件推荐!这款你值得拥有!

“朋友们,怎么会有人总是在清理电脑的时候把重要的文件一起删掉啊?我真的每次只要一清理电脑,重要文件必不见!大家有什么比较实用的文件恢复软件推荐吗?感谢!” 使用电脑时误删文件已经是一件比较常见的事情…

1.MySQL数据库的基本操作

数据库操作过程: 1.用户在客户端输入 SQL 2.客户端会把 SQL 通过网络发送给服务器 3.服务器执行这个 SQL,把结果返回给客户端 4.客户端收到结果,显示到界面上 数据库的操作 这里的数据库不是代表一个软件,而是代表一个数据集合。 显示当前的数据库 …

【编码魔法师系列_六大原则5】迪米特原则(Law of Demeter Principle)

学会设计模式,你就可以像拥有魔法一样,在开发过程中解决一些复杂的问题。设计模式是由经验丰富的开发者们(GoF)凝聚出来的最佳实践,可以提高代码的可读性、可维护性和可重用性,从而让我们的开发效率更高。通…

DolphinDB 入选 Gartner《中国数据库市场指南》代表厂商

近日,国际知名研究机构 Gartner 发布2023年《中国 DBMS 市场指南(Market Guide for DBMS, China)》研究报告,在中国范围内评估并重点推荐了36家极具实力的企业,DolphinDB 以领先的技术和商业能力顺势入榜。 DolphinDB …

Mybatis 源码 ② :流程分析

文章目录 一、前言二、Mybatis 初始化1. AutoConfiguredMapperScannerRegistrar2. MapperScannerConfigurer3. ClassPathMapperScanner3.1 ClassPathMapperScanner#scan3.2 ClassPathMapperScanner#processBeanDefinitions 4. 总结 三、 Mapper Interface 的创建1. MapperFacto…

3段代码详解python中的单线程、多线程和多进程

目录 1. 单线程: 2. 多线程: 3. 多进程: 什么时候使用单线程、多线程和多进程 总结 在并发编程中,使用适当的并发模型可以提高程序执行效率和性能。Python提供了单线程、多线程和多进程三种方式来实现并发执行任务。 单线程…

护眼灯买哪种好,2023护眼台灯推荐

护眼台灯的光照一般比较均匀,相比普通台灯,一般具有防蓝光、防频闪等功能,能够提供一个健康舒适的学习、生活灯光环境,建议选购内置智能感光模式的护眼台灯,以确保灯光亮度一直处于均衡状态,让眼睛更轻松。…

从源代码编译构建Apach Spark3.2.4

从源代码编译构建Apach Spark3.2.4 编译说明编译Apache Spark下载源码构建环境准备使用本地Maven构建更改Scala版本下载Jar包构建可运行的发行版构建异常构建成功 运行测试 编译说明 对于大多数用户来说,使用官方预编译版本的Spark已经足够满足日常需求。只有在特定…

Hands on RL 之 Proximal Policy Optimization (PPO)

Hands on RL 之 Proximal Policy Optimization (PPO) 文章目录 Hands on RL 之 Proximal Policy Optimization (PPO)1. 回顾Policy Gradient和TRPO2. PPO (Clip)3. PPO(Penalty)4. PPO中Advantage Function的计算5.实现 PPO-ClipReference 1. 回顾Policy Gradient和TRPO ​ 首…

构建Actual网页客户端镜像

什么是 Actual ? Actual 是一款超快速且注重隐私的本地优先的财务应用程序,用于管理您的财务。其核心是经过充分验证且深受喜爱的信封预算方法。它是 100% 免费和开源的。 Actual 具有多设备同步、可选的端到端加密等等功能。默认情况下,它不…

ssm医院门诊挂号系统源码和论文PPT

ssm医院门诊挂号系统源码和论文PPT008 开题报告 任务书 源码 数据库sql 论文 开发环境: 开发工具:idea 数据库mysql5.7(mysql5.7最佳) 数据库链接工具:navcat,小海豚等 开发技术:java ssm tomcat8.5 1.选题的背景和意义 …

高性能MySQL实战(二):索引

大家好,我是 方圆。我们在上篇 高性能MySQL实战(一):表结构 中已经建立好了表结构,这篇我们则是针对已有的表结构和搜索条件为表创建索引。除此之外,我还会讲一些关于索引必须要了解的知识。原文收录在我的…