机器学习与高维信息检索 - Note 7 - 核主成分分析(Kernel Principal Component Analysis,K-PCA)

Note 7 - 核主成分分析(Kernel Principal Component Analysis)

标准PCA通过将观察到的数据投射到一个线性子空间来降低其维度。选择投影的方式是使以平方的标准欧氏准则衡量的误差最小,这也可以解释为减少白高斯噪声的一种方式。一个非常重要的应用是将PCA作为分类的预处理,因为分类器在减少噪声的特征空间中表现更好。

标准PCA的主要缺点是,它严重依赖数据的近似线性结构。在许多应用中,这是一个过于严格的假设。核PCA(K-PCA)是标准PCA的一个扩展,它没有这些缺点。K-PCA的关键思想是,它隐含地假设存在一个非线性映射

ϕ : R p → H , (7.1) \phi: \mathbb{R}^{p} \rightarrow \mathcal{H}, \tag{7.1} ϕ:RpH,(7.1)
其中 H \mathcal{H} H是一个非常高维的向量空间(甚至可能是无限维的),其内积为 1 ⟨ ⋅ , ⋅ ⟩ { }^{1}\langle\cdot, \cdot\rangle 1,。我们无妨把 H \mathcal{H} H看作是一些 R P \mathbb{R}^{P} RP,有非常大的 P P P。作为一个初步的步骤,我们重新表述众所周知的标准PCA,使其只涉及我们数据的内积。

1 { }^{1} 1 形式上,希尔伯特空间 H \mathcal{H} H是一个实数或复数内积空间,就内积所引导的距离函数而言,它也是一个完整的公制空间。

7.1 用内积表示的线性PCA(Linear PCA expressed with inner products)

X ∈ R p × n \mathbf{X} \in \mathbb{R}^{p \times n} XRp×n为居中的数据矩阵(这将是下面推导的一个关键假设),让 K : = X ⊤ X \mathbf{K}:=\mathbf{X}^{\top} \mathbf{X} K:=XX ( n × n ) (n \times n) (n×n)矩阵,由数据的所有内积组成。更确切地说, ( i , j ) (i, j) (i,j)项是 K \mathbf{K} K i i i和第 j j j观测值的内积 x i ⊤ x j \mathbf{x}_{i}^{\top} \mathbf{x}_{j} xixj

回顾一下,如果 X = U Σ V ⊤ \mathbf{X}=\mathbf{U} \boldsymbol{\Sigma} \mathbf{V}^{\top} X=UΣV是数据矩阵的SVD。那么数据向量 y ∈ R p \mathbf{y} \in \mathbb{R}^{p} yRp的前 k k k主分量是由 U k ⊤ \mathbf{U}_{k}^{\top} Uk给出的。在目前的情况下,只给出了内积,因此不可能直接得到 U k \mathbf{U}_{k} Uk。然而, K \mathbf{K} K的特征值分解允许对这个问题有一个优雅的解决方案。记住,我们有 K : = X ⊤ X \mathbf{K}:=\mathbf{X}^{\top} \mathbf{X} K:=XX 并用它的SVD代替 X \mathbf{X} X。我们得到

K = V Σ ⊤ Σ V ⊤ .  (7.2) \mathbf{K}=\mathbf{V} \boldsymbol{\Sigma}^{\top} \boldsymbol{\Sigma} \mathbf{V}^{\top} \text {. }\tag{7.2} K=VΣΣV(7.2)

记住, V \mathbf{V} V是正交的, Σ ⊤ Σ \boldsymbol{\Sigma}^{\top} \boldsymbol{\Sigma} ΣΣ是对角的。因此,方程(7.2)是 K \mathbf{K} K的特征值分解(EVD),由于EVD的唯一性,通过计算 K \mathbf{K} K k k k最大特征值与它们各自的特征向量,我们得到 σ 1 2 , ⋯   , σ k 2 \sigma_{1}^{2}, \cdots, \sigma_{k}^{2} σ12,,σk2 V k \mathbf{V}_{k} Vk。我们将假设 σ k > 0 \sigma_{k}>0 σk>0,否则我们可以减少目标子空间的维度而不损失任何数据信息。为了简单起见,我们定义对角矩阵 Σ k = diag ⁡ ( σ 1 , … , σ k ) \Sigma_{k}=\operatorname{diag}\left(\sigma_{1}, \ldots, \sigma_{k}\right) Σk=diag(σ1,,σk)

这使我们能够对于一个给定的观测值 y \mathbf{y} y只需使用内积就可以计算出 U k ⊤ y \mathbf{U}_{k}^{\top} \mathbf{y} Uky的主成分。对于一个新的测量值 y \mathbf{y} y,我们有

V k ⊤ X ⊤ y = V k ⊤ V Σ U ⊤ y = [ I k ∣ 0 ] Σ U ⊤ y = [ Σ k ∣ 0 ] U ⊤ y = Σ k U k ⊤ y . (7.3) \begin{aligned} \mathbf{V}_{k}^{\top} \mathbf{X}^{\top} \mathbf{y} &=\mathbf{V}_{k}^{\top} \mathbf{V} \boldsymbol{\Sigma} \mathbf{U}^{\top} \mathbf{y} \\ &=\left[I_{k} \mid 0\right] \boldsymbol{\Sigma} \mathbf{U}^{\top} \mathbf{y} \\ &=\left[\boldsymbol{\Sigma}_{k} \mid 0\right] \mathbf{U}^{\top} \mathbf{y} \\ &=\boldsymbol{\Sigma}_{k} \mathbf{U}_{k}^{\top} \mathbf{y} . \end{aligned} \tag{7.3} VkXy=VkVΣUy=[Ik0]ΣUy=[Σk0]Uy=ΣkUky.(7.3)

将此方程与 Σ k − 1 \Sigma_{k}^{-1} Σk1相乘,我们可以得到

U k ⊤ y = Σ k − 1 V k ⊤ X ⊤ y = Σ k − 1 V k ⊤ [ x 1 ⊤ y ⋮ x n ⊤ y ] . (7.4) \mathbf{U}_{k}^{\top} \mathbf{y}=\boldsymbol{\Sigma}_{k}^{-1} \mathbf{V}_{k}^{\top} \mathbf{X}^{\top} \mathbf{y}=\boldsymbol{\Sigma}_{k}^{-1} \mathbf{V}_{k}^{\top}\left[\begin{array}{c} \mathbf{x}_{1}^{\top} \mathbf{y} \\ \vdots \\ \mathbf{x}_{n}^{\top} \mathbf{y} \end{array}\right] . \tag{7.4} Uky=Σk1VkXy=Σk1Vkx1yxny.(7.4)

注意,这个方程的右边可以通过只涉及数据的内积的数据来计算,即Gram-matrix K \mathbf{K} K和内积 x n ⊤ y \mathbf{x}_{n}^{\top} \mathbf{y} xny

使数据居中
到目前为止,我们已经假定数据是居中的,也就是说,Gram-matrix K \mathbf{K} K来自居中化的数据。这个假设很关键,因为否则方程(7.4)的推导将不成立。现在让我们假设,我们没有可用的居中数据,而Gram-matrix K \mathbf{K} K是由非居中数据建立的。好消息是,可以通过以下公式直接从 K \mathbf{K} K推导出对应于中心数据的格拉姆矩阵,例如 K ~ \tilde{\mathbf{K}} K~,即

K ~ = H K H , (7.5) \tilde{\mathbf{K}}=\mathbf{H K H}, \tag{7.5} K~=HKH,(7.5)

其中 H = ( I n − 1 n 1 n 1 n ⊤ ) \mathbf{H}=\left(\mathbf{I}_{n}-\frac{1}{n} \mathbb{1}_{n} \mathbb{1}_{n}^{\top}\right) H=(Inn11n1n).


证明:
从方程(1.3)中可以看出,如果 X \mathbf{X} X表示非居中的数据矩阵,那么居中的矩阵由以下公式给出

X ‾ = X − μ ^ 1 n ⊤ , (7.6) \overline{\mathbf{X}}=\mathbf{X}-\hat{\mu} \mathbb{1}_{n}^{\top}, \tag{7.6} X=Xμ^1n,(7.6)

μ ^ = 1 n X 1 n \hat{\mu}=\frac{1}{n} \mathbf{X} \mathbb{1}_{n} μ^=n1X1n。 由此,可以看出

X ‾ = X − 1 n X 1 n 1 n ⊤ = X ( I n − 1 n 1 n 1 n ⊤ ) . (7.7) \overline{\mathbf{X}}=\mathbf{X}-\frac{1}{n} \mathbf{X} \mathbb{1}_{n} \mathbb{1}_{n}^{\top}=\mathbf{X}\left(\mathbf{I}_{n}-\frac{1}{n} \mathbb{1}_{n} \mathbb{1}_{n}^{\top}\right) . \tag{7.7} X=Xn1X1n1n=X(Inn11n1n).(7.7)
用对称矩阵的速记符号来表示 H : = I n − 1 n 1 n 1 n ⊤ \mathbf{H}:=\mathbf{I}_{n}-\frac{1}{n} \mathbb{1}_{n} \mathbb{1}_{n}^{\top} H:=Inn11n1n。我们可以得到

K ~ = X ‾ ⊤ X ‾ = H X ⊤ X H = H K H . (7.8) \tilde{\mathbf{K}}=\overline{\mathbf{X}}^{\top} \overline{\mathbf{X}}=\mathbf{H X}^{\top} \mathbf{X} \mathbf{H}=\mathbf{H K H} . \tag{7.8} K~=XX=HXXH=HKH.(7.8)


因此,如果我们有来自非中心数据的Gram-matrix,我们可以很容易地计算出对应于中心数据的Gram-matrix(无需明确地将 X \mathbf{X} X居中)。由此,我们可以–如上所述–计算 V k \mathbf{V}_{k} Vk Σ k \boldsymbol{\Sigma}_{k} Σk。为了计算新数据样本 y \mathbf{y} y的主成分,我们首先要根据训练样本把 y \mathbf{y} y居中处理。具体来说,这意味着我们必须从 y \mathbf{y} y减去训练数据的经验平均值 μ ^ = 1 n ∑ i x i = 1 n X 1 n \hat{\mu}=\frac{1}{n} \sum_{i} \mathbf{x}_{i}=\frac{1}{n} \mathbf{X} \mathbb{1}_{n} μ^=n1ixi=n1X1n。然后我们必须用 X ‾ = X H \overline{\mathbf{X}}=\mathbf{X H} X=XH替换公式(7.3)和(7.4)中的 X \mathbf{X} X。这就得到了

U k ⊤ ( y − 1 n X 1 n ) = Σ k − 1 V k ⊤ ( X H ) ⊤ ( y − 1 n X 1 n ) = Σ k − 1 V k ⊤ k y (7.9) \mathbf{U}_{k}^{\top}\left(\mathbf{y}-\frac{1}{n} \mathbf{X} \mathbb{1}_{n}\right)=\boldsymbol{\Sigma}_{k}^{-1} \mathbf{V}_{k}^{\top}(\mathbf{X} \mathbf{H})^{\top}\left(\mathbf{y}-\frac{1}{n} \mathbf{X} \mathbb{1}_{n}\right)=\boldsymbol{\Sigma}_{k}^{-1} \mathbf{V}_{k}^{\top} \mathbf{k}_{y} \tag{7.9} Uk(yn1X1n)=Σk1Vk(XH)(yn1X1n)=Σk1Vkky(7.9)

其中

k y = H [ x 1 ⊤ y ⋮ x n ⊤ y ] − 1 n H K 1 n \mathbf{k}_{y}=\mathbf{H}\left[\begin{array}{c} \mathbf{x}_{1}^{\top} \mathbf{y} \\ \vdots \\ \mathbf{x}_{n}^{\top} \mathbf{y} \end{array}\right]-\frac{1}{n} \mathbf{H K} \mathbb{1}_{n} ky=Hx1yxnyn1HK1n

7.2 向核PCA过渡 (Transition to Kernel PCA)

现在,通过简单地将内积 x ⊤ y \mathbf{x}^{\top} \mathbf{y} xy替换为 ⟨ ϕ ( x ) , ϕ ( y ) ⟩ \langle\phi(\mathbf{x}), \phi(\mathbf{y})\rangle ϕ(x),ϕ(y)来扩展经典的PCA是很简单的。K-PCA的实际成功是由于计算 ⟨ ϕ ( x ) , ϕ ( y ) ⟩ \langle\phi(\mathbf{x}), \phi(\mathbf{y})\rangle ϕ(x),ϕ(y)时,既不需要 ϕ \phi ϕ也不需要 ⟨ ⋅ , ⋅ ⟩ \langle\cdot, \cdot\rangle , 的内积。相反,只需要有一个函数

κ : R p × R p → R , ( x , y ) ↦ κ ( x , y ) (7.10) \kappa: \mathbb{R}^{p} \times \mathbb{R}^{p} \rightarrow \mathbb{R}, \quad(\mathbf{x}, \mathbf{y}) \mapsto \kappa(\mathbf{x}, \mathbf{y}) \tag{7.10} κ:Rp×RpR,(x,y)κ(x,y)(7.10)

这反映了 ⟨ ϕ ( x ) , ϕ ( y ) ⟩ \langle\phi(\mathbf{x}), \phi(\mathbf{y})\rangle ϕ(x),ϕ(y)的属性,即对于所有 x ∈ R p \mathbf{x} \in \mathbb{R}^{p} xRp来说是对称的,并且满足 κ ( x , x ) ≥ 0 \kappa(\mathbf{x}, \mathbf{x}) \geq 0 κ(x,x)0 的正定属性。用 κ ( x , y ) \kappa(\mathbf{x}, \mathbf{y}) κ(x,y)代替 ⟨ ϕ ( x ) , ϕ ( y ) ⟩ \langle\phi(\mathbf{x}), \phi(\mathbf{y})\rangle ϕ(x),ϕ(y),因此不需要知道特征映射 ϕ \phi ϕ,称为核技巧(Kernel trick)。

Definition 7.1 正定核 (Positive Definite Kernel)

  1. S : = { x 1 , … , x n } ⊂ R p S:=\left\{\mathbf{x}_{1}, \ldots, \mathbf{x}_{n}\right\} \subset \mathbb{R}^{p} S:={x1,,xn}Rp κ ( ⋅ ) \kappa(\cdot) κ()如上定义. 带有 ( i , j ) (i, j) (i,j) k i j = κ ( x i , x j ) k_{i j}=\kappa\left(\mathbf{x}_{i}, \mathbf{x}_{j}\right) kij=κ(xi,xj) ( n × n ) (n \times n) (n×n)-矩阵 K \mathbf{K} K 被称为 S S S的Gram-或Kernel-矩阵,相对于 κ \kappa κ

  2. 如果对于所有有限的、非空的集合 S ⊂ R p S \subset \mathbb{R}^{p} SRp来说,相应的Gram-matrix是正半定的(正定的),那么这个函数 κ ( ⋅ ) \kappa(\cdot) κ()被称为核(正定的核)。

在上一小节中,我们讨论了在潜在的希尔伯特空间中的数据居中问题。我们在这里也面临同样的问题。当一个新的数据点出现时,直接计算新数据点的非中心化内积向量与训练数据的关系是很简单的。我们将把它称为

k new  = [ ⟨ ϕ ( x 1 ) , ϕ ( y ) ⟩ ⋮ ⟨ ϕ ( x n ) , ϕ ( y ) ⟩ ] . \mathbf{k}^{\text {new }}=\left[\begin{array}{c} \left\langle\phi\left(\mathbf{x}_{1}\right), \phi(\mathbf{y})\right\rangle \\ \vdots \\ \left\langle\phi\left(\mathbf{x}_{n}\right), \phi(\mathbf{y})\right\rangle \end{array}\right] . knew =ϕ(x1),ϕ(y)ϕ(xn),ϕ(y).

那么,中心化数据的第 j j j条是

( k c e n t n e w ) j = ⟨ ϕ ( x j ) − 1 n ∑ i ϕ ( x i ) , ϕ ( y ) − 1 n ∑ i ϕ ( x i ) ⟩ \left(\mathbf{k}_{c e n t}^{n e w}\right)_{j}=\left\langle\phi\left(\mathbf{x}_{j}\right)-\frac{1}{n} \sum_{i} \phi\left(\mathbf{x}_{i}\right), \phi(\mathbf{y})-\frac{1}{n} \sum_{i} \phi\left(\mathbf{x}_{i}\right)\right\rangle (kcentnew)j=ϕ(xj)n1iϕ(xi),ϕ(y)n1iϕ(xi)

为了找到一个更简洁的表达方式,我们利用标量乘积的线性来得到

⟨ ϕ ( x j ) − 1 n ∑ i ϕ ( x i ) , ϕ ( y ) − 1 n ∑ i ϕ ( x i ) ⟩ = ⟨ ϕ ( x j ) , ϕ ( y ) ⟩ − 1 n ⟨ ∑ i ϕ ( x i ) , ϕ ( y ) ⟩ − 1 n ⟨ ϕ ( x j ) , ∑ i ϕ ( x i ) ⟩ + 1 n 2 ⟨ ∑ i ϕ ( x i ) , ∑ i ϕ ( x i ) ⟩ , \begin{gathered} \left\langle\phi\left(\mathbf{x}_{j}\right)-\frac{1}{n} \sum_{i} \phi\left(\mathbf{x}_{i}\right), \phi(\mathbf{y})-\frac{1}{n} \sum_{i} \phi\left(\mathbf{x}_{i}\right)\right\rangle \\ =\left\langle\phi\left(\mathbf{x}_{j}\right), \phi(\mathbf{y})\right\rangle-\frac{1}{n}\left\langle\sum_{i} \phi\left(\mathbf{x}_{i}\right), \phi(\mathbf{y})\right\rangle \\ -\frac{1}{n}\left\langle\phi\left(\mathbf{x}_{j}\right), \sum_{i} \phi\left(\mathbf{x}_{i}\right)\right\rangle+\frac{1}{n^{2}}\left\langle\sum_{i} \phi\left(\mathbf{x}_{i}\right), \sum_{i} \phi\left(\mathbf{x}_{i}\right)\right\rangle, \end{gathered} ϕ(xj)n1iϕ(xi),ϕ(y)n1iϕ(xi)=ϕ(xj),ϕ(y)n1iϕ(xi),ϕ(y)n1ϕ(xj),iϕ(xi)+n21iϕ(xi),iϕ(xi),

而且很容易看出,

k cent  new  = k new  − 1 n 1 n 1 n ⊤ k new  − 1 n K 1 n + 1 n 2 1 n 1 n ⊤ K 1 n = H k new  − 1 n H K 1 n . \begin{gathered} \mathbf{k}_{\text {cent }}^{\text {new }}=\mathbf{k}^{\text {new }}-\frac{1}{n} \mathbb{1}_{n} \mathbb{1}_{n}^{\top} \mathbf{k}^{\text {new }}-\frac{1}{n} \mathbf{K} \mathbb{1}_{n}+\frac{1}{n^{2}} \mathbb{1}_{n} \mathbb{1}_{n}^{\top} \mathbf{K} \mathbb{1}_{n} \\ =\mathbf{H k}^{\text {new }}-\frac{1}{n} \mathbf{H} \mathbf{K} \mathbb{1}_{n} . \end{gathered} kcent new =knew n11n1nknew n1K1n+n211n1nK1n=Hknew n1HK1n.

总之,对于一个训练集 X = [ x 1 , … x n ] , x i ∈ R p \mathbf{X}=\left[\mathbf{x}_{1}, \ldots \mathbf{x}_{n}\right], \mathbf{x}_{i} \in \mathbb{R}^{p} X=[x1,xn],xiRp 的K-PCA包括以下步骤。

  1. 找到一个合适的内核函数 κ ( ⋅ ) \kappa(\cdot) κ() 并计算Gram-matrix

K = [ κ ( x 1 , x 1 ) κ ( x 1 , x 2 ) … κ ( x 1 , x n ) κ ( x 2 , x 1 ) κ ( x 2 , x 2 ) κ ( x 2 , x n ) ⋮ ⋮ ⋱ ⋮ κ ( x n , x 1 ) κ ( x n , x 2 ) … κ ( x n , x n ) ] \mathbf{K}=\left[\begin{array}{cccc} \kappa\left(\mathbf{x}_{1}, \mathbf{x}_{1}\right) & \kappa\left(\mathbf{x}_{1}, \mathbf{x}_{2}\right) & \ldots & \kappa\left(\mathbf{x}_{1}, \mathbf{x}_{n}\right) \\ \kappa\left(\mathbf{x}_{2}, \mathbf{x}_{1}\right) & \kappa\left(\mathbf{x}_{2}, \mathbf{x}_{2}\right) & & \kappa\left(\mathbf{x}_{2}, \mathbf{x}_{n}\right) \\ \vdots & \vdots & \ddots & \vdots \\ \kappa\left(\mathbf{x}_{n}, \mathbf{x}_{1}\right) & \kappa\left(\mathbf{x}_{n}, \mathbf{x}_{2}\right) & \ldots & \kappa\left(\mathbf{x}_{n}, \mathbf{x}_{n}\right) \end{array}\right] K=κ(x1,x1)κ(x2,x1)κ(xn,x1)κ(x1,x2)κ(x2,x2)κ(xn,x2)κ(x1,xn)κ(x2,xn)κ(xn,xn)

  1. 计算Gram-matrix K ~ = H K H \tilde{\mathbf{K}}=\mathbf{H K H} K~=HKH,其中 H = I n − 1 n 1 n 1 n ⊤ \mathbf{H}=\mathbf{I}_{n}-\frac{1}{n} \mathbb{1}_{n} \mathbb{1}_{n}^{\top} H=Inn11n1n是居中化的数据。

  2. 计算特征值分解 K ~ = V Λ V ⊤ \tilde{\mathbf{K}}=\mathbf{V} \boldsymbol{\Lambda} \mathbf{V}^{\top} K~=VΛV。由于核函数的定义,矩阵 K \mathbf{K} K是半正定的,因此 Λ \boldsymbol{\Lambda} Λ的对角线项是非负的。因此,我们可以写成 Λ = Σ 2 = diag ⁡ ( σ 1 2 , … , σ n 2 ) \boldsymbol{\Lambda}=\boldsymbol{\Sigma}^{2}=\operatorname{diag}\left(\sigma_{1}^{2}, \ldots, \sigma_{n}^{2}\right) Λ=Σ2=diag(σ12,,σn2).

  3. 定义缩减矩阵 Σ k = diag ⁡ ( σ 1 , … , σ k ) ∈ R k × k \boldsymbol{\Sigma}_{k}=\operatorname{diag}\left(\sigma_{1}, \ldots, \sigma_{k}\right) \in \mathbb{R}^{k \times k} Σk=diag(σ1,,σk)Rk×k V k ∈ R n × k \mathbf{V}_{k} \in \mathbb{R}^{n \times k} VkRn×k.

  4. 缩减后的训练数据由以下公式得出

S = Σ k V k ⊤ (7.11) \mathbf{S}=\boldsymbol{\Sigma}_{k} \mathbf{V}_{k}^{\top} \tag{7.11} S=ΣkVk(7.11)

  1. 对于一个新的数据点 y ∈ R p \mathbf{y} \in \mathbb{R}^{p} yRp k k k核主成分的计算方法是

s new  : = Σ k − 1 V k ⊤ k cent  new  (7.12) \mathbf{s}_{\text {new }}:=\mathbf{\Sigma}_{k}^{-1} \mathbf{V}_{k}^{\top} \mathbf{k}_{\text {cent }}^{\text {new }} \tag{7.12} snew :=Σk1Vkkcent new (7.12)

其中

k cent  new  = H ( k new  − 1 n K 1 n )  where  k new  = [ κ ( x 1 , y ) , … , κ ( x n , y ) ] ⊤ . \begin{aligned} \mathbf{k}_{\text {cent }}^{\text {new }} &=\mathbf{H}\left(\mathbf{k}^{\text {new }}-\frac{1}{n} \mathbf{K} \mathbb{1}_{n}\right) \\ \text { where } \mathbf{k}^{\text {new }} &=\left[\kappa\left(\mathbf{x}_{1}, \mathbf{y}\right), \ldots, \kappa\left(\mathbf{x}_{n}, \mathbf{y}\right)\right]^{\top} . \end{aligned} kcent new  where knew =H(knew n1K1n)=[κ(x1,y),,κ(xn,y)].

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Stan Fu

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值