Slate-based Recommender Systems 论文解读

2023-10-31 18:30

本文主要是介绍Slate-based Recommender Systems 论文解读,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

Reinforcement Learning for Slate-based Recommender Systems: A Tractable Decomposition and Practical Methodology

论文地址:https://www.cs.toronto.edu/~cebly/Papers/SlateQ_IJCAI_2019.pdf

本博客对SlateQ论文进行了解读,如有错误请评论指正。

文章目录

      • 1. 论文算法介绍(第四、五章)
        • 1.1. SlateQ: 基于强化学习的推荐列表分解技术
        • 1.2. 用Q值对推荐列表进行优化
        • 1.3. 三种优化方法的比较
      • 2. 论文算法的在线实现(第九章)
      • 2.1. 两个重要组件
      • 2.2. SlateQ算法流程
        • 2.2.1. 伪代码
        • 2.2.2. 对伪代码的解释

1. 论文算法介绍(第四、五章)

1.1. SlateQ: 基于强化学习的推荐列表分解技术

SlateQ算法将推荐列表(Slate)的整体生成 分解为了 生成单个推荐项再组成推荐列表。它的提出基于两个假设(论文第10页):

  1. SC(Single choice)
    用户一次只在推荐列表中点击一个推荐项或不点击任何推荐项
  2. RTDS(Reward/transition dependence on selection)
    用户对推荐项的选择会产生不同的回报和状态转移

由上述两个假设,可以得到以下两个推论(论文11页公式12和13):
R ( s , A , i ) = R ( s , A ′ , i ) = R ( s , i ) ∀ A , A ′ containing  i R(s,A,i)=R(s,A',i)=R(s,i)\qquad\forall A,A'\ \text{containing}\ i R(s,A,i)=R(s,A,i)=R(s,i)A,A containing i P ( s ′ ∣ s , A , i ) = P ( s ′ ∣ s , A ′ , i ) = P ( s ′ ∣ s , i ) ∀ A , A ′ containing  i P(s'|s,A,i)=P(s'|s,A',i)=P(s'|s,i)\qquad\forall A,A'\ \text{containing}\ i P(ss,A,i)=P(ss,A,i)=P(ss,i)A,A containing i

这两个公式表达了:无论推荐项 i i i 出现在哪一个推荐列表中,只要它被用户选择了,那么它所产生的回报值和状态转移都是一样的。

在以上推论的前提下,论文利用马尔科夫决策过程模型(MDP)构造了推荐项辅助函数(论文11页公式14),用于计算在状态 s s s 时推荐列表中单个推荐项的 LTV(long-term value,长期价值):
Q ‾ π ( s , i ) = R ( s , i ) + γ ∑ s ′ ∈ S P ( s ′ ∣ s , i ) V π ( s ′ ) \overline{Q}^\pi(s,i)=R(s,i)+\gamma\sum_{s'\in S}P(s'|s,i)V^\pi(s') Qπ(s,i)=R(s,i)+γsSP(ss,i)Vπ(s)

在有了单个推荐项LTV的基础上,计算出推荐列表整体的LTV(论文11页Proposition 1),即所有推荐项LTV的期望值:
Q π ( s , A ) = ∑ i ∈ A P ( i ∣ s , A ) Q ‾ π ( s , i ) Q^\pi(s,A)=\sum_{i\in A}P(i|s,A)\overline{Q}^\pi(s,i) Qπ(s,A)=iAP(is,A)Qπ(s,i)

单个推荐项LTV值 Q ‾ π ( s , i ) \overline{Q}^\pi(s,i) Qπ(s,i)可以用TD方法来更新(论文12页公式19): Q ‾ π ( s , i ) ← α ( r + γ ∑ j ∈ A ′ P ( j ∣ s ′ , A ′ ) Q ‾ π ( s ′ , j ) ) + ( 1 − α ) Q ‾ π ( s , i ) \overline{Q}^\pi(s,i)\leftarrow \alpha(r+\gamma\sum_{j\in A'}P(j|s',A')\overline{Q}^\pi(s',j))+(1-\alpha)\overline{Q}^\pi(s,i) Qπ(s,i)α(r+γjAP(js,A)Qπ(s,j))+(1α)Qπ(s,i)

也可以用Q-Learning的方法来更新(论文13页公式20): Q ‾ ( s , i ) ← α ( r + γ max ⁡ A ′ ∈ A ∑ j ∈ A ′ P ( j ∣ s ′ , A ′ ) Q ‾ ( s ′ , j ) ) + ( 1 − α ) Q ‾ ( s , i ) \overline{Q}(s,i)\leftarrow \alpha(r+\gamma\max_{A'\in A}\sum_{j\in A'}P(j|s',A')\overline{Q}(s',j))+(1-\alpha)\overline{Q}(s,i) Q(s,i)α(r+γAAmaxjAP(js,A)Q(s,j))+(1α)Q(s,i)

显然,使用Q-Learning的方法来更新时可以选取到最大的 Q ‾ ( s , i ) \overline{Q}(s,i) Q(s,i),也就可以得到最优的 Q ( s , A ) Q(s,A) Q(s,A)(论文13页公式Proposition 3): Q ( s , A ) = ∑ i ∈ A P ( i ∣ s , A ) Q ‾ ( s , i ) Q(s,A)=\sum_{i\in A}P(i|s,A)\overline{Q}(s,i) Q(s,A)=iAP(is,A)Q(s,i)

1.2. 用Q值对推荐列表进行优化

在已经明确可以通过组合单个推荐项得到整体推荐列表的情况下,我们具体怎么去得到最优的推荐列表 A A A呢?这就涉及到对 Q ( s , A ) Q(s,A) Q(s,A)的优化了。

如论文13页Proposition 3 和 论文14页公式21所示,对 Q ( s , A ) Q(s,A) Q(s,A)的优化公式表示为: max ⁡ A ∈ I , ∣ A ∣ = k Q ( S , A ) = max ⁡ A ∈ I , ∣ A ∣ = k ∑ i ∈ A P ( i ∣ s , A ) Q ‾ ( s , i ) \max_{A\in I,|A|=k}Q(S,A)=\max_{A\in I,|A|=k}\sum_{i\in A}P(i|s,A)\overline{Q}(s,i) AI,A=kmaxQ(S,A)=AI,A=kmaxiAP(is,A)Q(s,i)其中, A ∈ I , ∣ A ∣ = k A\in I,|A|=k AI,A=k表示推荐列表中的推荐项从整体数据集中选取而来,且推荐列表的长度为 k k k(实际上在在线实验时 k k k值不固定,参考论文30页第九章)。

论文提出了三种方法对 Q π ( s , A ) Q^\pi(s,A) Qπ(s,A)进行优化:
方法一:LP(Linear Program,线性规划)
定义(论文15页公式22和23): max ⁡ ∑ i ∈ I x i v ( s , i ) Q ‾ ( s , i ) v ( s , ⊥ ) + ∑ j x j v ( s , j ) \max \sum_{i\in I}\frac{x_iv(s,i)\overline{Q}(s,i)}{v(s,\bot)+\sum_{j}x_jv(s,j)} maxiIv(s,)+jxjv(s,j)xiv(s,i)Q(s,i) s . t . ∑ i ∈ I x i = k ; x i ∈ 0 , 1 , ∀ i ∈ I s.t.\sum_{i\in I}x_i=k;\qquad x_i\in{0,1},\forall i \in I s.t.iIxi=k;xi0,1,iI其中, x i x_i xi表示推荐项 i i i是否属于 A A A,是则为1,否则为0; v ( s , i ) v(s,i) v(s,i)表示推荐项对用户的吸引力,可以是推荐项的评分或即时pCTR等; x j x_j xj v ( s , j ) v(s,j) v(s,j)同理; v ( s , ⊥ ) v(s,\bot) v(s,)表示空推荐对用户的吸引力。

公式(24-28)是对上述定义的简化,这里不作介绍。

方法二:Top-k
Top-k方法通过计算推荐项的 V = v ( s , i ) Q ‾ ( s , i ) V=v(s,i)\overline{Q}(s,i) V=v(s,i)Q(s,i),然后每次取 V V V最大推荐项 i i i 的进行推荐,最终组成推荐列表。

方法三:Greedy(贪心)
贪婪方法通过下列公式产生单个推荐项(论文16页),最终组成推荐列表: i = arg max ⁡ i ∉ A ′ v ( s , i ) Q ‾ ( s , i ) + ∑ l < L v ( s , i ( l ) ) Q ‾ ( s , i ( l ) ) v ( s , i ) + v ( s , ⊥ ) + ∑ l < L v ( s , i ( l ) ) i=\argmax_{i\notin A'}\frac{v(s,i)\overline{Q}(s,i)+\sum_{l<L}v(s,i_{(l)})\overline{Q}(s,i_{(l)})}{v(s,i)+v(s,\bot)+\sum_{l<L}v(s,i_{(l)})} i=i/Aargmaxv(s,i)+v(s,)+l<Lv(s,i(l))v(s,i)Q(s,i)+l<Lv(s,i(l))Q(s,i(l))其中, i ∉ A ′ i\notin A' i/A表示新推荐的推荐项 i i i 不属于已经推荐出去的推荐项; L ∈ [ 1 , k ] L\in[1,k] L[1,k],表示已经推荐出去的推荐项个数。

Greedy方法可以看做是每进行一次推荐,就从推荐集合 I I I中去除被推荐出去的项的Top-k方法。

1.3. 三种优化方法的比较

考虑以下例子,推荐列表大小 k = 2 k=2 k=2,待推荐集合 I I I为(论文16页表格):

ItemScore( v ( s , i ) v(s,i) v(s,i) )Q-value
⊥ \bot 10
a20.8
b 1 b_1 b111
b 2 b_2 b211

1、用LP方法进行产生推荐项
V ( { a , ⊥ } ) = ∑ i ∈ I x i v ( s , i ) Q ‾ ( s , i ) v ( s , ⊥ ) + ∑ j x j v ( s , j ) = 1 × 2 × 0.8 + 0 1 + 1 × 2 + 0 = 1.6 3 = 0.53 V(\{a,\bot\})=\sum_{i\in I}\frac{x_iv(s,i)\overline{Q}(s,i)}{v(s,\bot)+\sum_{j}x_jv(s,j)}=\frac{1 \times 2 \times 0.8+0}{1+1\times2+0}=\frac{1.6}{3}=0.53 V({a,})=iIv(s,)+jxjv(s,j)xiv(s,i)Q(s,i)=1+1×2+01×2×0.8+0=31.6=0.53 V ( { b i , ⊥ } ) = ∑ i ∈ I x i v ( s , i ) Q ‾ ( s , i ) v ( s , ⊥ ) + ∑ j x j v ( s , j ) = 1 × 1 × 1 + 0 1 + 1 × 1 + 0 = 1 2 = 0.5 V(\{b_i,\bot\})=\sum_{i\in I}\frac{x_iv(s,i)\overline{Q}(s,i)}{v(s,\bot)+\sum_{j}x_jv(s,j)}=\frac{1 \times 1 \times 1+0}{1+1\times1+0}=\frac{1}{2}=0.5 V({bi,})=iIv(s,)+jxjv(s,j)xiv(s,i)Q(s,i)=1+1×1+01×1×1+0=21=0.5 V ( { a , a } ) = ∑ i ∈ I x i v ( s , i ) Q ‾ ( s , i ) v ( s , ⊥ ) + ∑ j x j v ( s , j ) = 1 × 2 × 0.8 + 1 × 2 × 0.8 1 + 1 × 2 + 1 × 2 = 3.2 5 = 0.64 V(\{a,a\})=\sum_{i\in I}\frac{x_iv(s,i)\overline{Q}(s,i)}{v(s,\bot)+\sum_{j}x_jv(s,j)}=\frac{1 \times 2 \times 0.8 + 1 \times 2 \times 0.8}{1+1 \times 2 + 1\times2}=\frac{3.2}{5}=0.64 V({a,a})=iIv(s,)+jxjv(s,j)xiv(s,i)Q(s,i)=1+1×2+1×21×2×0.8+1×2×0.8=53.2=0.64 V ( { a , b i } ) = ∑ i ∈ I x i v ( s , i ) Q ‾ ( s , i ) v ( s , ⊥ ) + ∑ j x j v ( s , j ) = 1 × 2 × 0.8 + 1 × 1 × 1 1 + 1 × 2 + 1 × 1 = 2.6 4 = 0.65 V(\{a,b_i\})=\sum_{i\in I}\frac{x_iv(s,i)\overline{Q}(s,i)}{v(s,\bot)+\sum_{j}x_jv(s,j)}=\frac{1 \times 2 \times 0.8 + 1 \times 1 \times 1}{1+1 \times 2 + 1\times1}=\frac{2.6}{4}=0.65 V({a,bi})=iIv(s,)+jxjv(s,j)xiv(s,i)Q(s,i)=1+1×2+1×11×2×0.8+1×1×1=42.6=0.65 V ( { b 1 , b 2 } ) = ∑ i ∈ I x i v ( s , i ) Q ‾ ( s , i ) v ( s , ⊥ ) + ∑ j x j v ( s , j ) = 1 × 1 × 1 + 1 × 1 × 1 1 + 1 × 1 + 1 × 1 = 2 3 = 0.67 V(\{b_1,b_2\})=\sum_{i\in I}\frac{x_iv(s,i)\overline{Q}(s,i)}{v(s,\bot)+\sum_{j}x_jv(s,j)}=\frac{1 \times 1 \times 1 + 1 \times 1 \times 1}{1+1 \times 1 + 1\times1}=\frac{2}{3}=0.67 V({b1,b2})=iIv(s,)+jxjv(s,j)xiv(s,i)Q(s,i)=1+1×1+1×11×1×1+1×1×1=32=0.67

其中, b i b_i bi表示 b 1 b_1 b1 b 2 b_2 b2

显然为了可以得到 Q ( s , A ) Q(s,A) Q(s,A),应当推荐 b 1 , b 2 b_1,b_2 b1,b2组成推荐列表。

2、用Top-k方法进行产生推荐项
V ( { a , ⊥ } ) = v ( s , i ) Q ‾ ( s , i ) = 2 × 0.8 + 0 = 1.6 V(\{a,\bot\})=v(s,i)\overline{Q}(s,i)=2\times 0.8 + 0=1.6 V({a,})=v(s,i)Q(s,i)=2×0.8+0=1.6 V ( { b i , ⊥ } ) = v ( s , i ) Q ‾ ( s , i ) = 1 × 1 + 0 = 1 V(\{b_i,\bot\})=v(s,i)\overline{Q}(s,i)=1\times 1 + 0=1 V({bi,})=v(s,i)Q(s,i)=1×1+0=1 V ( { a , a } ) = v ( s , i ) Q ‾ ( s , i ) = 2 × 0.8 + 2 × 0.8 = 3.2 V(\{a,a\})=v(s,i)\overline{Q}(s,i)=2\times 0.8 + 2\times 0.8=3.2 V({a,a})=v(s,i)Q(s,i)=2×0.8+2×0.8=3.2 V ( { a , b i } ) = v ( s , i ) Q ‾ ( s , i ) = 2 × 0.8 + 1 × 1 = 2.6 V(\{a,b_i\})=v(s,i)\overline{Q}(s,i)=2\times 0.8 + 1\times 1=2.6 V({a,bi})=v(s,i)Q(s,i)=2×0.8+1×1=2.6 V ( { b 1 , b 2 } ) = v ( s , i ) Q ‾ ( s , i ) = 1 × 1 + 1 × 1 = 2 V(\{b_1,b_2\})=v(s,i)\overline{Q}(s,i)=1\times 1 + 1\times 1=2 V({b1,b2})=v(s,i)Q(s,i)=1×1+1×1=2

显然为了可以得到 Q ( s , A ) Q(s,A) Q(s,A),应当推荐 a , a a,a a,a组成推荐列表。

2、用Greedy方法进行产生推荐项

公式太长,不写了,很显然为了可以得到 Q ( s , A ) Q(s,A) Q(s,A),应当推荐出去 a , b 1 a,b_1 a,b1 a , b 2 a,b_2 a,b2

2. 论文算法的在线实现(第九章)

2.1. 两个重要组件

论文介绍的在线实验中定义了两个关键组件(论文28页)

  1. 候选推荐项生成器
    从一个最匹配用户上下文(当前状态 s s s)的大推荐数据集中生成一个含有数百个候选推荐项的小子集 I I I
  2. 排名器
    将用户上下文(当前状态 s s s)和推荐项特征 i i i 输入进深度神经网络 Q ‾ ( s , i ) \overline{Q}(s,i) Q(s,i)对候选推荐项进行评分和排名(使用LTV)

其中深度神经网络 Q ‾ ( s , i ) \overline{Q}(s,i) Q(s,i)含有4个隐藏层(2048、1024、512、256),激活函数为ReLu。

2.2. SlateQ算法流程

2.2.1. 伪代码

论文29页Algorithm 1
在这里插入图片描述

2.2.2. 对伪代码的解释

1、参数

  • T T T:算法迭代的次数
  • M M M:更新标签神经网络 Q ‾ l a b e l \overline{Q}_{label} Qlabel的间隔频率参数
  • γ \gamma γ:计算LTV时的时间折扣率。如果两个访问分别发生在时间 t 1 t_1 t1 t 2 t_2 t2,则在 t 2 t_2 t2处的奖励的相对折扣为 γ t 2 − t 1 / c \gamma^{t_2-t_1/c} γt2t1/c,其中 c c c是控制折扣时间尺度的参数。
  • θ m a i n \theta_{main} θmain:主神经网络 Q ‾ m a i n \overline{Q}_{main} Qmain的参数
  • Q ‾ m a i n \overline{Q}_{main} Qmain:主神经网络,用于预测项目的长期价值(LTV)
  • θ l a b e l \theta_{label} θlabel:标签神经网络 Q ‾ l a b e l \overline{Q}_{label} Qlabel的参数
  • θ p c t r \theta_{pctr} θpctr:用于预测pCTR的神经网络参数(pCTR:每个推荐项的点击率,点击率:点击次数占展示次数的百分比)

2、输入

  • D t r a i n i n g = ( s , A , C , L m y o p i c , s ′ , A ′ ) D_{training}=(s,A,C,L_{myopic},s',A') Dtraining=(s,A,C,Lmyopic,s,A):训练数据集(适用于Sarsa)
  • s s s:当前状态。即用户的各类信息(例如,用户过去的历史记录、行为和响应以及静态用户属性)
  • A = ( a 1 , . . . , a k ) A=(a_1,...,a_k) A=(a1,...,ak):在状态 s s s时的推荐列表, a i a_i ai表示单个的推荐项, k k k的大小可以不固定
  • C = ( c 1 , . . . , c k ) C=(c_1,...,c_k) C=(c1,...,ck) c i c_i ci表示用户是否点击了推荐项 a i a_i ai
  • L m y o p i c = ( L m y o p i c 1 , . . . , L m y o p i c k ) L_{myopic}=(L^1_{myopic},...,L^k_{myopic}) Lmyopic=(Lmyopic1,...,Lmyopick) L m y o p i c i L^i_{myopic} Lmyopici表示推荐项 a i a_i ai的短视价值(立即回报)
  • s ′ s' s:下一个要转移过去的状态
  • A ′ = ( a 1 ′ , . . . , a k ′ ) A'=(a'_1,...,a'_k) A=(a1,...,ak):状态 s ′ s' s时产生的推荐列表

3、输出
训练好的主神经网络 Q ‾ m a i n \overline{Q}_{main} Qmain,用于预测推荐项的长期价值

4、初始化
θ l a b e l = 0 \theta_{label}=0 θlabel=0
θ m a i n \theta_{main} θmain θ p c t r \theta_{pctr} θpctr随机初始化;

5、流程
5. 循环 T T T i = 1 , . . . , T i=1,...,T i=1,...,T
6. \qquad i mod  M = 0 i\ \text{mod}\ M=0 i mod M=0,则更新标签网络 Q ‾ l a b e l \overline{Q}_{label} Qlabel
7. \qquad\qquad θ l a b e l ← θ m a i n \theta_{label} \leftarrow \theta_{main} θlabelθmain
9. \qquad\qquad 循环 取出每一个训练数据 ( s , A , C , L m y o p i c , s ′ , A ′ ) ∈ D t r a i n i n g (s,A,C,L_{myopic},s',A')\in D_{training} (s,A,C,Lmyopic,s,A)Dtraining
10. \qquad\qquad\qquad 循环 取出推荐列表中的每一个推荐项 a i ∈ A a_i\in A aiA
11. \qquad\qquad\qquad\qquad 根据点击标签 c i c_i ci更新 θ p c t r \theta_{pctr} θpctr
12. \qquad\qquad\qquad\qquad a i a_i ai被用户点击,则:
13. \qquad\qquad\qquad\qquad\qquad 更新pCTR: p C T R ( s ′ , a i ′ , A ′ ) ← p C T R ( s ′ , a i ′ ) ∑ a i ′ ∈ A p C T R ( s ′ , a i ′ ) pCTR(s',a'_i,A')\leftarrow\frac{pCTR(s',a'_i)}{\sum_{a'_i\in A}pCTR(s',a'_i)} pCTR(s,ai,A)aiApCTR(s,ai)pCTR(s,ai)
14. \qquad\qquad\qquad\qquad\qquad 更新项目的LTV: l l t v i = l m y o p i c i + ∑ a i ′ ∈ A p C T R ( s ′ , a i ′ , A ′ ) Q ‾ l a b e l ( s ′ , a i ′ ) l^{i}_{ltv}=l^{i}_{myopic}+\sum_{a'_i\in A}pCTR(s',a'_i,A')\overline{Q}_{label}(s',a'_i) lltvi=lmyopici+aiApCTR(s,ai,A)Qlabel(s,ai)
15. \qquad\qquad\qquad\qquad\qquad 使用 l l t v i l^{i}_{ltv} lltvi更新主神经网络参数 θ m a i n \theta_{main} θmain

这篇关于Slate-based Recommender Systems 论文解读的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/317265

相关文章

java之Objects.nonNull用法代码解读

《java之Objects.nonNull用法代码解读》:本文主要介绍java之Objects.nonNull用法代码,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐... 目录Java之Objects.nonwww.chinasem.cnNull用法代码Objects.nonN

SpringCloud负载均衡spring-cloud-starter-loadbalancer解读

《SpringCloud负载均衡spring-cloud-starter-loadbalancer解读》:本文主要介绍SpringCloud负载均衡spring-cloud-starter-loa... 目录简述主要特点使用负载均衡算法1. 轮询负载均衡策略(Round Robin)2. 随机负载均衡策略(

解读spring.factories文件配置详情

《解读spring.factories文件配置详情》:本文主要介绍解读spring.factories文件配置详情,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教... 目录使用场景作用内部原理机制SPI机制Spring Factories 实现原理用法及配置spring.f

Spring MVC使用视图解析的问题解读

《SpringMVC使用视图解析的问题解读》:本文主要介绍SpringMVC使用视图解析的问题解读,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教... 目录Spring MVC使用视图解析1. 会使用视图解析的情况2. 不会使用视图解析的情况总结Spring MVC使用视图

Linux中的进程间通信之匿名管道解读

《Linux中的进程间通信之匿名管道解读》:本文主要介绍Linux中的进程间通信之匿名管道解读,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教... 目录一、基本概念二、管道1、温故知新2、实现方式3、匿名管道(一)管道中的四种情况(二)管道的特性总结一、基本概念我们知道多

Linux系统之authconfig命令的使用解读

《Linux系统之authconfig命令的使用解读》authconfig是一个用于配置Linux系统身份验证和账户管理设置的命令行工具,主要用于RedHat系列的Linux发行版,它提供了一系列选项... 目录linux authconfig命令的使用基本语法常用选项示例总结Linux authconfi

解读docker运行时-itd参数是什么意思

《解读docker运行时-itd参数是什么意思》在Docker中,-itd参数组合用于在后台运行一个交互式容器,同时保持标准输入和分配伪终端,这种方式适合需要在后台运行容器并保持交互能力的场景... 目录docker运行时-itd参数是什么意思1. -i(或 --interactive)2. -t(或 --

解读为什么@Autowired在属性上被警告,在setter方法上不被警告问题

《解读为什么@Autowired在属性上被警告,在setter方法上不被警告问题》在Spring开发中,@Autowired注解常用于实现依赖注入,它可以应用于类的属性、构造器或setter方法上,然... 目录1. 为什么 @Autowired 在属性上被警告?1.1 隐式依赖注入1.2 IDE 的警告:

Rust中的注释使用解读

《Rust中的注释使用解读》本文介绍了Rust中的行注释、块注释和文档注释的使用方法,通过示例展示了如何在实际代码中应用这些注释,以提高代码的可读性和可维护性... 目录Rust 中的注释使用指南1. 行注释示例:行注释2. 块注释示例:块注释3. 文档注释示例:文档注释4. 综合示例总结Rust 中的注释

解读Pandas和Polars的区别及说明

《解读Pandas和Polars的区别及说明》Pandas和Polars是Python中用于数据处理的两个库,Pandas适用于中小规模数据的快速原型开发和复杂数据操作,而Polars则专注于高效数据... 目录Pandas vs Polars 对比表使用场景对比Pandas 的使用场景Polars 的使用