词向量算法—Word2Vec和GloVe

最近学习nlp,从CS224n视频课2019winter的课程入手,听完了前几个lecture,以及做完斯坦福课程官网上对应的编程作业之后对词向量的算法有了大致的了解。

但网上对于词向量算法好多都是一两句话介绍原理就完事,我自己对这些算法进行推导和理解了下,所以这个博客主要是对算法进行理解和推导,这样就更透彻一些。

词向量

以前我们在初高中做英语阅读理解的时候,对于不认识的单词,英语老师会告诉我们,可以通过它所在的上下文进行猜测,有的时候这种方法可以帮助我们在不认识这个单词的情况下也能很好的理解这句话的含义。在自然语言处理中,最基础的就是词语,机器理解词语不像人类那么直观,我们希望对于每个词语都有一个一定维度的向量可以表示,然后机器就可以凭借这个向量来获取这个词语所表达的意思,并且学到词语之间相互的关系用来组词和组句。

很naive的做法就是将所有词汇设计成一个巨大的表,然后每个词语的向量映射成一个独热向量,即词语所在位置是1,其余是0。但是这样做的话所有向量都是正交的,没办法表示两个词语之间的关系,而且词语的维数就是词汇表的长度,太高了!此外,可以人工的设计少点的一些特征,例如feature1表示动词、feature2表示形容词、……、feature100表示是否是动物等等,这样获得了一些不是好多0的向量,并且把维数降下来了,相当于将高维的sparse向量给嵌入到低维的空间中得到一个dense的向量,因此词向量也称为词嵌入。虽然理论上这样做是可以解决上述两个难题的,但人工设计特征也太为难了,而且设计的不好那效果也很差。因此,Word2Vec和GloVe这两种词向量模型就是利用算法来自动生成低维空间中的词向量的。

这些词向量模型其实可以整体地表示为 F ( V ) F(V) F(V)的形式,其中 V V V就是词向量矩阵,模型的参数就是词向量,模型的目的就是学习到这些词向量/参数,所以通过定义不同的代价函数来逐步优化这些参数,最后就可以得到一个比较好的词向量模型啦。

Word2Vec是2013年谷歌的Mikolov大神团队提出来的,基本的想法是根据分布语义(distributional semantics)来提取出词向量,就是根据单词之间出现的位置来获取信息。Word2Vec分为两种Skip-Gram模型和Continuous Bag of Words模型。Skip-Gram模型是根据中心词来预测上下文的概率分布,而CBOW模型则是根据上下文词来预测中心词的概率分布。

Skip-Gram模型

因为Word2Vec是考虑上下文词和中心词的关系来建模的,所以对于一个单词,可以设它有两个向量来表示(最后可以取两个向量的平均作为这个单词的词向量):

  • v v v 表示中心词的词向量
  • u u u 表示上下文词的词向量

若词向量模型设定的维数为 n n n,例如 n = 100 n=100 n=100,那么 v v v u u u都是一个 n n n维的向量。

Skip-Gram模型是根据中心词来预测周围上下文词的概率分布,即 P ( o ∣ c ) P(o|c) P(oc)(其中 c c c表示中心词, o o o表示上下文词)

那么如何用词向量来表示这个概率呢?答案是“向量之间的内积”!

因为内积可以衡量两个词向量之间的位置关系,在词向量空间中也就是衡量了两个单词之间的相似度。可问题又来了,向量内积是一个实数,并不是在区间 [ 0 , 1 ] [0,1] [0,1]的呀!这个时候就想到做个归一化吧,softmax函数就登场了。因为中心词和单词表 V V V中每一个单词都可以做一次内积,都表示了中心词和任意一个词的相似度,将单词之间的内积经由softmax函数之后不就可以解释成概率了吗。所以基于中心词 c c c得到上下文词 o o o的概率为:
P ( o ∣ c ) = exp ⁡ ( u o T ⋅ v c ) ∑ w ∈ V exp ⁡ ( u w T ⋅ v c ) P(o|c)={\exp(u_o^T\cdot v_c)\over \sum_{w\in V}\exp(u_w^T\cdot v_c)} P(oc)=wVexp(uwTvc)exp(uoTvc)

有了这个概率表示之后模型的目的是什么呢?答案当然是“最大化出现在中心词附近的那些上下文词的概率
在这里插入图片描述

在图中“banking”就是中心词,在窗口大小 m = 2 m=2 m=2的情况下,最大化出现在这个窗口内的所有上下文词的概率,即:
max ⁡ θ ∏ − m ≤ j ≤ m ,   j ≠ 0 P ( w t + j ∣ w t ; θ ) \max_\theta\prod_{-m\leq j\leq m,\ j\neq0}P(w_{t+j}|w_t;\theta) θmaxmjm, j=0P(wt+jwt;θ)

这里的 θ \theta θ表示模型的参数,其实就是上面说的词向量 v v v u u u。所以对于位置 t = 1 , 2 , ⋯   , T t=1,2,\cdots,T t=1,2,,T,似然函数就可以表示为:
L ( θ ) = ∏ t = 1 T ∏ − m ≤ j ≤ m ,   j ≠ 0 P ( w t + j ∣ w t ; θ ) L(\theta) = \prod_{t=1}^T\prod_{-m\leq j\leq m,\ j\neq0}P(w_{t+j}|w_t;\theta) L(θ)=t=1Tmjm, j=0P(wt+jwt;θ)

最大似然估计对应着就是最小化负对数似然函数所得到的模型参数,所以模型的损失函数可以定义为(平均)负对数似然函数,即:
J ( θ ) = − 1 T log ⁡ L ( θ ) = − 1 T ∑ t = 1 T ∑ − m ≤ j ≤ m ,   j ≠ 0 log ⁡ P ( w t + j ∣ w t ; θ ) \begin{aligned}J(\theta) &=-{1\over T}\log L(\theta)\\ &= -{1\over T}\sum_{t=1}^T\sum_{-m\leq j\leq m,\ j\neq0}\log P(w_{t+j}|w_t;\theta)\end{aligned} J(θ)=T1logL(θ)=T1t=1Tmjm, j=0logP(wt+jwt;θ)

至此,只要对这个损失函数进行优化,最小化这个损失函数到一定范围,那就可以获得一个很好的词向量模型了。

那么问题又来了,如何进行优化呢?答案是“梯度下降法”呀!

那就要推导一下损失函数对于参数或者说词向量 v v v u u u的偏导数(梯度)了。

主要看看连加符号里面关于中心词向量的偏导 ∇ v c log ⁡ P ( o ∣ c ) \nabla_{v_c} \log P(o|c) vclogP(oc)
∇ v c log ⁡ P ( o ∣ c ) = ∂ ∂ v c log ⁡ exp ⁡ ( u o T ⋅ v c ) ∑ w ∈ V exp ⁡ ( u w T ⋅ v c ) = ∂ ∂ v c log ⁡ ( exp ⁡ ( u o T ⋅ v c ) ) − ∂ ∂ v c log ⁡ ∑ w ∈ V exp ⁡ ( u w T ⋅ v c ) = u o − 1 ∑ w ∈ V exp ⁡ ( u w T ⋅ v c ) ⋅ ∂ ∂ v c ∑ x ∈ V exp ⁡ ( u x T ⋅ v c ) = u o − 1 ∑ w ∈ V exp ⁡ ( u w T ⋅ v c ) ⋅ ∑ x ∈ V exp ⁡ ( u x T ⋅ v c ) ⋅ u x = u o − ∑ x ∈ V exp ⁡ ( u x T ⋅ v c ) ∑ w ∈ V exp ⁡ ( u w T ⋅ v c ) ⋅ u x = u o − ∑ x ∈ V P ( x ∣ c ) ⋅ u x \begin{aligned} \nabla_{v_c} \log P(o|c) &= {\partial\over \partial{v_c}}\log{\exp(u_o^T\cdot v_c)\over \sum_{w\in V}\exp(u_w^T\cdot v_c)}\\ &={\partial\over \partial{v_c}}\log(\exp(u_o^T\cdot v_c)) - {\partial\over \partial{v_c}}\log \sum_{w\in V}\exp(u_w^T\cdot v_c)\\ &=u_o - {1\over \sum_{w\in V}\exp(u_w^T\cdot v_c)}\cdot{\partial\over \partial{v_c}}\sum_{x\in V}\exp(u_x^T\cdot v_c)\\ &=u_o - {1\over \sum_{w\in V}\exp(u_w^T\cdot v_c)}\cdot\sum_{x\in V}\exp(u_x^T\cdot v_c)\cdot u_x\\ &= u_o - \sum_{x\in V}{\exp(u_x^T\cdot v_c)\over \sum_{w\in V}\exp(u_w^T\cdot v_c)}\cdot u_x\\ &=u_o - \sum_{x\in V}P(x|c)\cdot u_x \end{aligned} vclogP(oc)=vclogwVexp(uwTvc)exp(uoTvc)=vclog(exp(uoTvc))vclogwVexp(uwTvc)=uowVexp(uwTvc)1vcxVexp(uxTvc)=uowVexp(uwTvc)1xVexp(uxTvc)ux=uoxVwVexp(uwTvc)exp(uxTvc)ux=uoxVP(xc)ux

这个结果表示:实际观测到的上下文词 o o o的词向量 u o u_o uo,减去基于中心词 c c c的上下文词的期望。所以在梯度下降更新参数时,若实际的上下文词向量与基于中心词的期望词向量相差较小,那中心词的词向量需要调整的就小

再看看连加符号里面关于上下文词向量的偏导 ∇ u w log ⁡ P ( o ∣ c ) \nabla_{u_w} \log P(o|c) uwlogP(oc)

1、当 w = o w=o w=o时,即这个单词是中心词 c c c的上下文词时:
∇ u o log ⁡ P ( o ∣ c ) = ∂ ∂ u o log ⁡ exp ⁡ ( u o T ⋅ v c ) ∑ w ∈ V exp ⁡ ( u w T ⋅ v c ) = ∂ ∂ u o log ⁡ ( exp ⁡ ( u o T ⋅ v c ) ) − ∂ ∂ u o log ⁡ ∑ w ∈ V exp ⁡ ( u w T ⋅ v c ) = v c − 1 ∑ w ∈ V exp ⁡ ( u w T ⋅ v c ) ⋅ ∂ ∂ u o ∑ w ∈ V exp ⁡ ( u w T ⋅ v c ) = v c − 1 ∑ w ∈ V exp ⁡ ( u w T ⋅ v c ) ⋅ exp ⁡ ( u o T ⋅ v c ) ⋅ v c = v c − exp ⁡ ( u o T ⋅ v c ) ∑ w ∈ V exp ⁡ ( u w T ⋅ v c ) ⋅ v c = v c ⋅ ( 1 − P ( o ∣ c ) ) \begin{aligned} \nabla_{u_o} \log P(o|c) &= {\partial\over \partial{u_o}}\log{\exp(u_o^T\cdot v_c)\over \sum_{w\in V}\exp(u_w^T\cdot v_c)}\\ &={\partial\over \partial{u_o}}\log(\exp(u_o^T\cdot v_c)) - {\partial\over \partial{u_o}}\log \sum_{w\in V}\exp(u_w^T\cdot v_c)\\ &=v_c - {1\over \sum_{w\in V}\exp(u_w^T\cdot v_c)}\cdot{\partial\over \partial{u_o}}\sum_{w\in V}\exp(u_w^T\cdot v_c)\\ &=v_c - {1\over \sum_{w\in V}\exp(u_w^T\cdot v_c)}\cdot\exp(u_o^T\cdot v_c)\cdot v_c\\ &= v_c - {\exp(u_o^T\cdot v_c)\over \sum_{w\in V}\exp(u_w^T\cdot v_c)}\cdot v_c\\ &=v_c\cdot(1 - P(o|c)) \end{aligned} uologP(oc)=uologwVexp(uwTvc)exp(uoTvc)=uolog(exp(uoTvc))uologwVexp(uwTvc)=vcwVexp(uwTvc)1uowVexp(uwTvc)=vcwVexp(uwTvc)1exp(uoTvc)vc=vcwVexp(uwTvc)exp(uoTvc)vc=vc(1P(oc))

上式表明: P ( o ∣ c ) → 1 P(o|c)\to 1 P(oc)1时,即通过中心词 c c c可以很好的预测上下文词 o o o,那此时这个偏导就几乎为0,也就是在梯度下降中, u o u_o uo参数几乎不需要调整

2、当 w ≠ o w\neq o w=o时,即这个单词不是中心词 c c c的上下文词时:
∇ u w log ⁡ P ( o ∣ c ) = ∂ ∂ u w log ⁡ exp ⁡ ( u o T ⋅ v c ) ∑ w ∈ V exp ⁡ ( u w T ⋅ v c ) = ∂ ∂ u w log ⁡ ( exp ⁡ ( u o T ⋅ v c ) ) − ∂ ∂ u w log ⁡ ∑ w ∈ V exp ⁡ ( u w T ⋅ v c ) = − 1 ∑ w ∈ V exp ⁡ ( u w T ⋅ v c ) ⋅ ∂ ∂ u w ∑ x ∈ V exp ⁡ ( u x T ⋅ v c ) = − 1 ∑ w ∈ V exp ⁡ ( u w T ⋅ v c ) ⋅ exp ⁡ ( u w T ⋅ v c ) ⋅ v c = − exp ⁡ ( u w T ⋅ v c ) ∑ w ∈ V exp ⁡ ( u w T ⋅ v c ) ⋅ v c = − P ( w ∣ c ) ⋅ v c \begin{aligned} \nabla_{u_w} \log P(o|c) &= {\partial\over \partial{u_w}}\log{\exp(u_o^T\cdot v_c)\over \sum_{w\in V}\exp(u_w^T\cdot v_c)}\\ &={\partial\over \partial{u_w}}\log(\exp(u_o^T\cdot v_c)) - {\partial\over \partial{u_w}}\log \sum_{w\in V}\exp(u_w^T\cdot v_c)\\ &=- {1\over \sum_{w\in V}\exp(u_w^T\cdot v_c)}\cdot{\partial\over \partial{u_w}}\sum_{x\in V}\exp(u_x^T\cdot v_c)\\ &=- {1\over \sum_{w\in V}\exp(u_w^T\cdot v_c)}\cdot\exp(u_w^T\cdot v_c)\cdot v_c\\ &= - {\exp(u_w^T\cdot v_c)\over \sum_{w\in V}\exp(u_w^T\cdot v_c)}\cdot v_c\\ &= - P(w|c)\cdot v_c \end{aligned} uwlogP(oc)=uwlogwVexp(uwTvc)exp(uoTvc)=uwlog(exp(uoTvc))uwlogwVexp(uwTvc)=wVexp(uwTvc)1uwxVexp(uxTvc)=wVexp(uwTvc)1exp(uwTvc)vc=wVexp(uwTvc)exp(uwTvc)vc=P(wc)vc

这样基本上就解决了Skip-Gram模型的理解与训练的问题。

Continuous Bag of Words模型(CBOW)

类似Skip-Gram模型的方法,不同的是CBOW是根据上下文词来预测中心词的概率分布,依然用

  • v v v 表示中心词的词向量
  • u u u 表示上下文词的词向量

那么固定窗口 m m m内的上下文词向量可以表示为:
u c − m ,   u c − m + 1 ,   ⋯   ,   u c − 1 ,   ⋯   ,   u c + 1 ,   ⋯   ,   u c + m − 1 ,   u c + m u_{c-m},\ u_{c-m+1}, \ \cdots, \ u_{c-1}, \ \cdots, \ u_{c+1}, \ \cdots, \ u_{c+m-1},\ u_{c+m} ucm, ucm+1, , uc1, , uc+1, , uc+m1, uc+m

中心词向量为: v c v_c vc

首先将上面窗口内的 2 m 2m 2m个上下文词的词向量做一个平均,得到平均词向量:
u ^ = 1 2 m ( u c − m ,   u c − m + 1 ,   ⋯   ,   u c + m − 1 ,   u c + m ) \hat u = {1\over 2m}(u_{c-m},\ u_{c-m+1}, \ \cdots, \ u_{c+m-1},\ u_{c+m}) u^=2m1(ucm, ucm+1, , uc+m1, uc+m)

这样,基于上下文词的平均词向量 u ^ \hat u u^来预测中心词 c c c的概率就可以表示为:
P ( c ∣ o ) = exp ⁡ ( v c T ⋅ u ^ ) ∑ w ∈ V exp ⁡ ( v w T ⋅ u ^ ) P(c|o)={\exp(v_c^T\cdot \hat u)\over \sum_{w\in V}\exp(v_w^T\cdot \hat u)} P(co)=wVexp(vwTu^)exp(vcTu^)

类似Skip-Gram,CBOW模型的代价函数也是负对数似然函数:
J ( θ ) = − 1 T ∑ t = 1 T ∑ − m ≤ j ≤ m ,   j ≠ 0 log ⁡ P ( w t ∣ w t + j ; θ ) \begin{aligned}J(\theta) &= -{1\over T}\sum_{t=1}^T\sum_{-m\leq j\leq m,\ j\neq0}\log P(w_{t}|w_{t+j};\theta)\end{aligned} J(θ)=T1t=1Tmjm, j=0logP(wtwt+j;θ)

模型的训练也类似,先求的损失函数对于参数( u u u v v v)的梯度,然后不断更新参数来持续最小化损失函数。

GloVe模型

GloVe模型,全称为Global Vectors

这个算法希望加强对统计信息的利用,而且也能很好地概括词语的相关性信息。

  • X i j X_{ij} Xij 表示单词 j j j出现在单词 i i i的上下文中的次数
  • X i = ∑ k X i k X_i=\sum_k X_{ik} Xi=kXik 表示所有出现在单词 i i i的上下文中的单词次数
  • P i j = P ( j ∣ i ) = X i j / X i P_{ij}=P(j|i) = X_{ij}/X_i Pij=P(ji)=Xij/Xi 表示单词 j j j出现在单词 i i i上下文中的共现概率
  • X X X 表示共现矩阵,元素由 X i j X_{ij} Xij组成

当两个词语相关性比较高时,那么共现概率也比较大,反之则小。经过统计分析,发现用共现概率的比值来考察一对单词在第三个单词的上下文中哪个更常出现是有一定的规律的:

共现概率之比 P i k P j k P_{ik}\over P_{jk} PjkPik单词 j , k j,k j,k相关单词 j , k j,k j,k不相关
单词 i , k i,k i,k相关 ≈ 1 \approx 1 1很大
单词 i , k i,k i,k不相关很小 ≈ 1 \approx 1 1

假设由词向量 v i , v j , v k v_i, v_j, v_k vi,vj,vk来计算共现概率之比的函数为 f ( v i , v j , v k ) f(v_i, v_j, v_k) f(vi,vj,vk),则有:
P i k P j k = f ( v i , v j , v k ) {P_{ik}\over P_{jk}}=f(v_i, v_j, v_k) PjkPik=f(vi,vj,vk)

这个等式左边是从语料中统计获得,右边的函数是由参数决定,也就是由词向量决定。

GloVe算法希望等式左右两边尽可能接近,故损失函数可以定义为:
J = ∑ i , j , k ( P i k P j k − f ( v i , v j , v k ) ) 2 J=\sum_{i,j,k}\bigg( {P_{ik}\over P_{jk}}-f(v_i, v_j, v_k)\bigg)^2 J=i,j,k(PjkPikf(vi,vj,vk))2

也就是说,我们希望由词向量确定的函数可以很好地表示这种共现概率之比的关系,如果可以做到,那就说明这个词向量涵盖了词语的相关性信息,就是一个很好的词向量了。

那么这个函数具体应该长什么样呢?作者在原论文中对函数的形式进行以下讨论和猜想:

1、由于向量空间是线性的,所以一个自然的假设就是 f f f是关于 v i , v j v_i, v_j vi,vj之差的形式:
f ( v i − v j , v k ) = P i k P j k f(v_i-v_j, v_k) = {P_{ik}\over P_{jk}} f(vivj,vk)=PjkPik

2、观察等式左右两边,左边比值 P i k P j k {P_{ik}\over P_{jk}} PjkPik是一个标量,而右边关于词向量的函数是一个向量,因此 f f f要消除向量的形式,自然地使用到内积:
f ( ( v i − v j ) T ⋅ v k ) = P i k P j k f((v_i-v_j)^T\cdot v_k) = {P_{ik}\over P_{jk}} f((vivj)Tvk)=PjkPik

f f f要求满足 f ( ( v i − v j ) T ⋅ v k ) = f ( v i T ⋅ v k ) f ( v j T ⋅ v k ) f((v_i-v_j)^T\cdot v_k) ={f(v_i^T\cdot v_k)\over f(v_j^T\cdot v_k)} f((vivj)Tvk)=f(vjTvk)f(viTvk),这个等式的解为 f f f exp ⁡ \exp exp,所以有:
exp ⁡ ( ( v i − v j ) T ⋅ v k ) = exp ⁡ ( v i T v k ) exp ⁡ ( v j T v k ) = P i k P j k \exp((v_i-v_j)^T\cdot v_k) = {\exp(v_i^Tv_k)\over \exp(v_j^Tv_k)}= {P_{ik}\over P_{jk}} exp((vivj)Tvk)=exp(vjTvk)exp(viTvk)=PjkPik

且要求分子分母要对应相等,所以 exp ⁡ ( v i T v j ) = P i j \exp(v_i^Tv_j)=P_{ij} exp(viTvj)=Pij,即
log ⁡ P i j = v i T v j \log P_{ij} = v_i^Tv_j logPij=viTvj

所以损失函数可以简化地定义为:
J = ∑ i , j ( log ⁡ P i j − v i T v j ) 2 J = \sum_{i,j}\bigg(\log P_{ij} - v_i^Tv_j\bigg)^2 J=i,j(logPijviTvj)2

但注意, log ⁡ P i j \log P_{ij} logPij不具有对称性,即 log ⁡ P i j ≠ log ⁡ P j i \log P_{ij}\neq \log P_{ji} logPij=logPji,但 v i T v j = v j T v i v_i^Tv_j=v_j^Tv_i viTvj=vjTvi,所以还需要在对称性上进行改造。

由前面最开始共现概率的定义 P i j = P ( j ∣ i ) = X i j / X i P_{ij}=P(j|i) = X_{ij}/X_i Pij=P(ji)=Xij/Xi 可得:
v i T v j = log ⁡ P i j = log ⁡ X i j − log ⁡ X i v_i^Tv_j=\log P_{ij}=\log X_{ij}-\log X_i viTvj=logPij=logXijlogXi

添置一个偏置项 b j b_j bj,并且将 log ⁡ X i \log X_i logXi吸收到偏置项 b i b_i bi中,以此来重获对称性,那么上式可以变为:
v i T v j + b j + b i = log ⁡ X i j v_i^Tv_j+ b_j+ b_i=\log X_{ij} viTvj+bj+bi=logXij

所以损失函数又可以改为:
J = ∑ i , j ( v i T v j + b j + b i − log ⁡ X i j ) 2 J= \sum_{i,j}\bigg(v_i^Tv_j+ b_j+ b_i-\log X_{ij}\bigg)^2 J=i,j(viTvj+bj+bilogXij)2

最后,再基于出现频率越高的单词对应权重应该越大的想法,在这个损失函数中加入权重项 f f f,变成:
J = ∑ i , j f ( X i j ) ( v i T v j + b j + b i − log ⁡ X i j ) 2 J= \sum_{i,j}f(X_{ij})\bigg(v_i^Tv_j+ b_j+ b_i-\log X_{ij}\bigg)^2 J=i,jf(Xij)(viTvj+bj+bilogXij)2

这个权重函数由实验确定为:
f ( x ) = { ( x x m a x ) 0.75 ,    x < x m a x 1 ,    x ≥ x m a x f(x)=\begin{cases} ({x\over x_{max}})^{0.75},\ \ x<x_{max}\\ 1,\ \ x\geq x_{max} \end{cases} f(x)={(xmaxx)0.75,  x<xmax1,  xxmax

由这样的权重函数来限制词频过高时的权重

这样就得到了GloVe的损失函数,利用梯度下降求得负梯度进行词向量的更新就可以训练模型了。

总结起来,其实这三种模型,本质上说来方法都类似,只是出发点不一样导致代价函数不同,理解起来就稍微有点差别。

  • 2
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值