【机器学习】决策树概念+ID3\C4.5\CART+剪枝+特殊值处理

决策树是一种监督学习算法,用于分类和回归,通过树形结构展示决策规则。ID3算法基于信息增益选择属性,但易偏向于取值多的属性;C4.5引入信息增益率,缓解此问题,但仍可能偏向取值少的属性;CART使用基尼指数,构建二叉树。决策树的剪枝策略包括预剪枝和后剪枝,以防止过拟合。离散值、连续值和缺失值的处理也是决策树应用中的关键问题。
摘要由CSDN通过智能技术生成

决策树是一个监督学习算法,是一个预测算法,以树形数据结构来展示决策规则和分类结果,可以用于分类和回归,其重点是将看似无序、杂乱的已知数据通过某种技术手段将它们转化成可以预测未知数据的树状模型。

每一条从 根结点(对最终分类结果贡献最大的属性)叶子结点(最终分类结果) 的路径都代表一条决策的规则。

决策树是一树状结构,它的每一个叶节点对应着一个分类,非叶节点对应着在某个属性上的划分,构造决策树的核心问题是在每一步如何选择适当的属性对样本做拆分(也就是说,该如何确定下一条路应该走到左孩子还是右孩子)。

对一个分类问题,从已知类标记的训练样本中学习并构造出决策树是一个自上而下,分而治之的过程:

在这里插入图片描述

  1. 首先从开始位置,将所有数据划分到一个节点,即根节点

  2. 判断数据是否为空:

    • 若该节点的数据为空,则进一步判断这个节点是不是根节点:

      • 若是根节点,则说明构建决策树时没有数据给进来,返回一个空指针表示这棵树是个空树即可

      • 若不是根节点,说明在某个属性的判断条件里,没有训练数据满足走向这个节点的条件,因此将该节点标记为训练数据中类别最多的类,停止继续分裂

        这里我其实有个疑问...为什么要标记成类别最多的类?

    • 若该节点的数据不为空,则进一步判断数据是否属于同一类(即是否需要继续分裂):

      • 分到该节点的数据都属于同一类,则跳出循环,节点标记为该类别,不再继续分裂
      • 分到该节点的数据不属于同一类则考虑对该节点进行划分。既然是算法,则不能随意的进行划分,要讲究效率和精度,选择当前条件下的最优属性划分(什么是最优属性,这是决策树的重点,后面会详细解释)
  3. 若生成新的节点,则重回第2步进行循环,不断生成新的分支节点,直到没有新的节点产生则构树结束,生成一棵决策树

那么如何判断对哪个属性进行条件的划分呢?这就要对一组数据的各个属性进行分析,得到一个量化该属性的标准,然后依照此标准在众多的属性中选择最优。

这里先说明一下:同一个属性不是只能使用一次的

以下内容部分参考如何构建决策树

首先对问题做个简单的定义:

  • D D D为样本集合, p i p_i pi是样本集合 D D D中第 i i i类样本所占的比例, i ∈ { 1 , 2 , ⋯   , N } i\in\{1,2,\cdots,N\} i{1,2,,N}

    注意这里的样本集合不是全体样本哦,是指当前节点包括的样本,随着节点不断的划分这个 D D D是会变化的

  • Information Entropy,信息熵,用来描述整个随机分布所带来的信息量平均值,说句人话就是:随机变量的取值个数越多,信息熵就越大,混乱程度就越大。当随机分布为均匀分布时,熵最大。

    E n t ( D ) = − ∑ i = 1 N p i log ⁡ 2 p i Ent(D)=-\sum_{i=1}^Np_i\log_2p_i Ent(D)=i=1Npilog2pi

    如果想通俗的理解信息熵,可以去看通俗理解信息熵

  • Conditional Entropy,条件熵,将样本集合 D D D按属性 a a a进行划分,按照 a a a v v v个可能的取值将集合 D D D划分成 v v v个子集,每个可能的取值集合为 D v D^v Dv

    E n t a = ∑ v ∣ D v ∣ ∣ D ∣ E n t ( D v ) Ent_a=\sum_{v}\frac{|D^v|}{|D|}Ent(D^v) Enta=vDDvEnt(Dv),其中 ∣ D v ∣ |D^v| Dv ∣ D ∣ |D| D表示集合中元素的个数

随着决策树的不停构建,咱们是希望决策树的分支节点中所包含的样本尽可能属于同一类的,也就是希望节点的“纯度”越来越高,熵越来越低

此时再对选择属性的标准做一个定义:随着树深度的增加,节点的可以迅速地降低。熵降低的速度越来越快,希望得到一个最矮的高度树。

以下的三种典型的决策树,其主要区别就在<如何量化并选择属性>这一点上

ID3

使用 信息增益(即信息熵的增加值) 作为属性的选择标准

信息增益=信息熵-条件熵,即 G a i n ( D , a ) = E n t ( D ) − E n t a ( D ) Gain(D,a)=Ent(D)-Ent_a(D) Gain(D,a)=Ent(D)Enta(D),很简单,就是划分前的信息熵减去用某个属性划分后的信息熵

举个例子来直观的看ID3的建树过程:

在这里插入图片描述

以这个分类问题为例,输入为瓜的各种属性,输出为是否为好瓜,也就是说这个分类问题是二分类

  1. 首先将17个样本作为样本集 D D D p 是 = 8 17 , p 否 = 9 17 p_{\text{是}}=\frac{8}{17},p_{\text{否}}=\frac{9}{17} p=178,p=179,那么样本集 D D D的信息熵就是

    E n t ( D ) = − ∑ i = 1 N p i log ⁡ 2 p i = − ( 8 17 log ⁡ 2 8 17 + 9 17 log ⁡ 2 9 17 ) = 0.998 Ent(D)=-\sum_{i=1}^Np_i\log_2p_i=-(\frac{8}{17}\log_2\frac{8}{17}+\frac{9}{17}\log_2\frac{9}{17})=0.998 Ent(D)=i=1Npilog2pi=(178log2178+179log2179)=0.998(二分类,i最多为2)

  2. 在此时的样本集 D D D中,共有色泽、根蒂、敲声、纹理、脐部和触感共6种属性,分别计算这6种属性的条件信息熵:

    E n t 色泽 ( D ) = ∑ v ∈ { 青绿,乌黑,浅白 } ∣ D v ∣ ∣ D ∣ E n t ( D v ) = 6 17 E n t ( D 青绿 ) + 6 17 E n t ( D 乌黑 ) + 5 17 E n t ( D 浅白 ) = 6 17 ⋅ ( − ∑ i ∈ { ( 青绿 , 是 ) , ( 青绿 , 否 ) } p i log ⁡ p i ) + 6 17 ⋅ ( − ∑ i ∈ { ( 乌黑 , 是 ) , ( 乌黑 , 否 ) } p i log ⁡ p i ) + 5 17 ⋅ ( − ∑ i ∈ { ( 浅白 , 是 ) , ( 浅白 , 否 ) } p i log ⁡ p i ) = − 6 17 ( 3 6 log ⁡ 2 3 6 + 3 6 log ⁡ 2 3 6 ) − 6 17 ( 4 6 log ⁡ 2 4 6 + 2 6 log ⁡ 2 2 6 ) − 5 17 ( 1 5 log ⁡ 2 1 5 + 4 5 log ⁡ 2 4 5 ) = 0.889 \begin{aligned}Ent_{\text{色泽}}(D)&=\sum_{v\in\{\text{}青绿,乌黑,浅白\}}\frac{|D^v|}{|D|}Ent(D^v)\\&=\frac{6}{17}Ent(D^{\text{青绿}})+\frac{6}{17}Ent(D^{\text{乌黑}})+\frac{5}{17}Ent(D^{\text{浅白}})\\&=\frac{6}{17}\cdot\Bigl(-\sum_{i\in\{(青绿,是),(青绿,否)\}}p_i\log p_i\Bigr)+\frac{6}{17}\cdot\Bigl(-\sum_{i\in\{(乌黑,是),(乌黑,否)\}}p_i\log p_i\Bigr)\\&\qquad+\frac{5}{17}\cdot\Bigl(-\sum_{i\in\{(浅白,是),(浅白,否)\}}p_i\log p_i\Bigr)\\&=-\frac{6}{17}(\frac{3}{6}\log_2\frac{3}{6}+\frac{3}{6}\log_2\frac{3}{6})-\frac{6}{17}(\frac{4}{6}\log_2\frac{4}{6}+\frac{2}{6}\log_2\frac{2}{6})-\frac{5}{17}(\frac{1}{5}\log_2\frac{1}{5}+\frac{4}{5}\log_2\frac{4}{5})\\&=0.889\end{aligned} Ent色泽(D)=v{青绿,乌黑,浅白}DDvEnt(Dv)=176Ent(D青绿)+176Ent(D乌黑)+175Ent(D浅白)=176(i{(青绿,),(青绿,)}pilogpi)+176(i{(乌黑,),(乌黑,)}pilogpi)+175(i{(浅白,),(浅白,)}pilogpi)=176(63log263+63log263)176(64log264+62log262)175(51log251+54log254)=0.889

    同理计算得

    E n t 根蒂 ( D ) = 0.855 , E n t 敲声 ( D ) = 0.857 , E n t 纹理 ( D ) = 0.617 , E n t 脐部 ( D ) = 0.709 , E n t 触感 ( D ) = 0.992 Ent_{\text{根蒂}}(D)=0.855,Ent_{\text{敲声}}(D)=0.857,Ent_{\text{纹理}}(D)=0.617,\\Ent_{\text{脐部}}(D)=0.709,Ent_{\text{触感}}(D)=0.992 Ent根蒂(D)=0.855,Ent敲声(D)=0.857,Ent纹理(D)=0.617,Ent脐部(D)=0.709,Ent触感(D)=0.992

  3. 利用1和2求出的信息熵和条件信息熵对应相减得到信息增益:

    G a i n ( D , 色泽 ) = 0.109 , G a i n ( D , 根蒂 ) = 0.143 , G a i n ( D , 敲声 ) = 0.141 , G a i n ( D , 纹理 ) = 0.381 , G a i n ( D , 脐部 ) = 0.289 , G a i n ( D , 触感 ) = 0.006 Gain(D,\text{色泽})=0.109,Gain(D,\text{根蒂})=0.143,Gain(D,\text{敲声})=0.141,\\Gain(D,\text{纹理})=0.381,Gain(D,\text{脐部})=0.289,Gain(D,\text{触感})=0.006 Gain(D,色泽)=0.109,Gain(D,根蒂)=0.143,Gain(D,敲声)=0.141,Gain(D,纹理)=0.381,Gain(D,脐部)=0.289,Gain(D,触感)=0.006

    选择信息增益最大的纹理属性作为划分属性,将节点进行划分:

在这里插入图片描述

  1. 分别令三个子节点的样本集合为 D D D,重新从1一开始,因此决策树的构建是一个递归过程

从上面2和3的计算过程也可以看出,在整个计算过程中,划分前的信息熵是个定值,划分后的信息熵(即条件信息熵)越低,则信息增益越大,所以可以看出,选信息增益最大的节点用来划分实质就是选择划分前后信息熵降低的程度最大的那个属性作为划分属性

最终构建出的决策树为:

在这里插入图片描述

但是ID3有个致命的缺点:只适用于离散的属性描述,以及,偏向选择可取值数目比较多的属性(但是在有些情况下这类属性可能不会提供太多有价值的信息,不具备泛化能力,无法进行预测)

C4.5

使用信息增益率作为属性的选择标准,相比于ID3,C4.5的一大改进就是不仅能够处理离散的属性值,也能处理连续的属性值

信息增益率实际就是某属性的信息增益与该属性的取值信息熵的比值,即:

G a i n − r a t i o ( D , a ) = G a i n ( D , a ) I V ( a ) Gain-ratio(D,a)=\frac{Gain(D,a)}{IV(a)} Gainratio(D,a)=IV(a)Gain(D,a),其中 I V ( a ) = − ∑ v ∣ D v ∣ ∣ D ∣ log ⁡ 2 ∣ D v ∣ ∣ D ∣ IV(a)=-\sum_{v}\frac{|D^v|}{|D|}\log_2 \frac{|D^v|}{|D|} IV(a)=vDDvlog2DDv在周志华的西瓜书中称为属性 a a a的“固有值”,但是观察计算式,和信息熵的计算式是一样的,只不过此时的 p i p_i pi是某个取值的样本出现的概率,因此我理解它为取值的信息熵,衡量了内部取值数目的多少

I V ( a ) IV(a) IV(a)表示的就是这个属性 a a a的纯度。 a a a的内部取值数目越少,它的纯度就越高, I V ( a ) IV(a) IV(a)的值越低;相反,当 a a a的内部取值数目非常多时,它的纯度就很低, I V ( a ) IV(a) IV(a)的值也就很高。

我仔细思考了一下为什么要除以取值信息熵,是为了杜绝某些属性的取值下只有一个样本数据的情况,举个简单的例子:

样本集 D D D共有5个样本数据 x 1 , x 2 , x 3 , x 4 , x 5 x_1,x_2,x_3,x_4,x_5 x1,x2,x3,x4,x5,其中属性 a a a有4个不同的取值 a 1 , a 2 , a 3 , a 4 a_1,a_2,a_3,a_4 a1,a2,a3,a4,属性取值为 a 1 a_1 a1的样本只有 x 1 x_1 x1、取值为 a 2 a_2 a2的样本只有 x 2 x_2 x2、取值为 a 3 a_3 a3的样本只有 x 3 x_3 x3、取值为 a 4 a_4 a4的样本有 x 4 x_4 x4 x 5 x_5 x5,假设划分前的信息熵为 E n t = m Ent=m Ent=m,那么如果按属性 a a a划分, a a a的条件信息熵就可能为:

E n t a = − 1 5 ( 1 log ⁡ 2 1 ) − 1 5 ( 1 log ⁡ 2 1 ) − 1 5 ( 1 log ⁡ 2 1 ) − 2 5 ( 1 log ⁡ 2 1 ) = 0 Ent_a=-\frac{1}{5}(1\log_21)-\frac{1}{5}(1\log_21)-\frac{1}{5}(1\log_21)-\frac{2}{5}(1\log_21)=0 Enta=51(1log21)51(1log21)51(1log21)52(1log21)=0

那么此时属性 a a a的信息增益肯定就是最大值 G a i n ( D , a ) = E n t = m Gain(D,a)=Ent=m Gain(D,a)=Ent=m,相当于每个取值都只有一个数据支撑,显然可能是样本中的一些特殊情况,而用这样的属性进行分类显然就是不具有泛化性的,因此除以取值信息熵,使取值信息熵尽可能的小,让该属性下的每个取值都有足够多的数据支撑,使模型更具有泛化性

C4.5的构树过程和ID3是基本一样的,唯一的区别就是在ID3针对每个属性计算其 G a i n ( D , a ) Gain(D,a) Gain(D,a)的基础上进一步计算 G a i n − r a t i o ( D , a ) Gain-ratio(D,a) Gainratio(D,a),最后选择 G a i n − r a t i o ( D , a ) Gain-ratio(D,a) Gainratio(D,a)最大的那个属性进行划分,在此不再赘述。

令人尴尬的是,C4.5虽然避免了ID3算法中倾向于选择取值比较多的属性这一毛病,然而,它又倾向于选择取值数目比较少的属性,因此,在实际的C4.5算法中,并不是直接选择增益率最大的那个属性进行划分,而是采用一个启发式:

先从候选划分属性中找出信息增益高于平均水平的那个属性,然后再选择信息增益率最高的那个属性。

CART

使用基尼指数作为属性的选择标准,同时,与ID3和C4.5相比CART决策树是严格的二叉树结构,就是说1个节点最多划分为2个子结点,ID3和C4.5并不是严格的二叉树结构,比如根节点根据属性划分成了3个子结点。

基尼系数也是一种衡量信息不确定性的方法,与信息熵计算出来的结果差距很小,基本可以忽略,但是基尼系数要计算快得多,因为没有对数

  • 某个样本集 D D D的基尼系数 G i n i ( D ) = 1 − ∑ i = 1 N ( ∣ D i ∣ ∣ D ∣ ) 2 Gini(D)=1-\sum_{i=1}^N\left(\frac{\left|D_i\right|}{\left|D\right|}\right)^2 Gini(D)=1i=1N(DDi)2,其中 D i D_i Di是属于类别 i i i的样本集

    通俗的可以这么理解,基尼指数就是在样本集中随机抽出两个样本不同类别的概率。当样本集越混乱(不纯)的时候,这个概率也就越大,即基尼指数也越大。这个规律与信息熵的相同。

  • 按照属性 a a a划分后的样本集 D D D的基尼系数 G i n i _ i n d e x ( D , a ) = ∑ v ∣ D v ∣ ∣ D ∣ G i n i ( D v ) Gini\_index(D,a)=\sum_{v}\frac{\left|D^v\right|}{\left|D\right|}Gini(D^v) Gini_index(D,a)=vDDvGini(Dv)

在选择合适的决策节点时,选择能使基尼系数最小的属性来划分:

a ∗ = arg ⁡ min ⁡ a G i n i _ i n d e x ( D , a ) a_*=\arg\min _aGini\_index(D,a) a=argminaGini_index(D,a)

除此以外,CART既可以作为分类树,也可以作为回归树,具体来说:

  • 当终结点是连续变量时,该树为回归树
  • 当终结点为分类变量时,该树为分类树

前剪枝,后剪枝

在这里插入图片描述

首先需要知道为什么要剪枝:决策树是充分考虑了所有的数据点而生成的复杂树,它在学习的过程中为了尽可能的正确的分类训练样本,不停地对结点进行划分,因此这会导致整棵树的分支过多,造成决策树很庞大。决策树过于庞大,有可能出现过拟合的情况,决策树越复杂,过拟合的程度会越高。所以,为了避免过拟合,咱们需要对决策树进行剪枝。

预剪枝

前剪枝又叫预剪枝,指的是在找到当前节点的最优划分属性之后、分裂节点之前,先对这个最优划分属性进行一次评估,如果当前结点的划分不能带来决策树模型泛化性能的提升,则不对当前结点进行划分,并且将当前结点标记为叶结点。

所以,预剪枝的过程就是边构造决策树边剪枝的过程,那么如何对选出的最优划分属性进行评估确定它是否需要被剪枝呢?有以下的几种方法:

  1. 一种最为简单的方法就是限定决策树的深度,当当前节点所在的深度过大时,就不再分裂

  2. 设定一个阈值,即当选择的最优属性其信息增益、信息增益比、基尼系数低于我们设定的阈值时,就不再分裂

  3. 设定某个指标,比较节点划分前后的泛化能力,这是目前最常用的方法,具体来说,就是使用测试集对划分前后决策树分类的准确率做一个评估,如果准确率提高,就进行分裂,如果准确率不变甚至下降,就不对其进行分裂

    那么测试集从哪里来?这就涉及到之前网格搜索和交叉验证的知识了,我们将训练集分出一部分作为测试集。

    举个例子:

    在划分前,当前节点样本集中有10个样本,6好4坏,那么我们就认为当前节点在划分前会将走到这个节点的样本划分到好瓜这个类中,然后将测试集的数据一个一个输入到当前的决策树中进行分类,以此来表示测试集在划分前的准确率

    在划分后,当前节点会生成多个子节点(这里假设分成了3个),那么每个子节点中都会分得一部分满足条件的样本,然后再仿照划分前的方法对这些子节点进行类别统计,用测试集中的数据对划分后的准确率进行计算

    最后对比划分前后在测试集上分类准确率的变化,再决定是否将该节点分裂

后剪枝

后剪枝就是在生成完整的决策树之后再决定对哪些节点进行剪枝,是一个构造完再剪枝的过程,具体来说就是:先用训练集把整颗决策树构造完毕,然后自底向上的对非叶结点进行考察,若将该结点对应的子树换为叶结点能够带来泛化性能的提升,则把该子树替换为叶结点。后剪枝对比的是剪枝前后准确率的变化,如果准确率不变或者下降,则不需要剪枝。预剪枝对比的是节点划分前后准确率的变化,其实在思想上是一致的

这种对比准确率的后剪枝方法又叫Reduced-Error Pruning即REP错误率降低剪枝,除此以外还有Pesimistic-Error Pruning(PEP,悲观错误剪枝)和Cost-Complexity Pruning(CCP,代价复杂度剪枝),感兴趣可以自己了解一下。

理论上讲, 后剪枝生成的决策树要比预剪枝生成的效果好,但是后剪枝在计算复杂度上比预剪枝高

特殊类型数据处理:离散值、连续值、缺失值

离散值

上面内容中ID3的例子就是离散值,比如纹理(清晰,稍糊,模糊)、色泽(青绿,乌黑,浅白)、触感(硬滑,软粘),这类数据的可取值的个数是有限的,比如纹理只有可能是清晰,稍糊,模糊,在细分就没意思了,这样的属性在代码实现上遇到的困难其实并不多,直接使用自然数对所有可能的取值标号即可,在决定如何去往下一个子节点的分支时用等号判断即可(比如纹理中1代表清晰2代表稍糊3代表模糊,那么某个测试样本的纹理=1or2or3会确定其下一步的走向)

连续值

这种情况下,属性的可取值无穷多,已有的训练集样本只包含了其中一部分的取值,比如苹果的重量可能是1kg到5kg中的任何一个数值,这时就无法直接划分节点,需要先将连续值离散化。CART在处理连续值数据时使用的是二分法

给定样本集 D D D,和连续值的属性 a a a a a a D D D上出现了 n n n个不同的取值,将这些取值从小到大排序成 { a 1 , a 2 , ⋯   , a n } \{a_1,a_2,\cdots,a_n\} {a1,a2,,an},对于其中相邻的两个取值 a i a_i ai a i + 1 a_{i+1} ai+1,求出二者的中位点 T a = a i + a i + 1 2 T_a=\frac{a_i+a_{i+1}}{2} Ta=2ai+ai+1作为候选划分点(即离散化),这样我们就得到了 n − 1 n-1 n1个候选划分点

比如属性a的取值为 { 1.2 , 2 , 4 , 6 , 7.0 } \{1.2,2,4,6,7.0\} {1.2,2,4,6,7.0},我们选择两两值取中位数,就得到 { 1.2 + 2 2 , 2 + 4.6 2 , 4.6 + 7.0 2 } \{\frac{1.2+2}{2}, \frac{2+4.6}{2}, \frac{4.6+7.0}{2}\} {21.2+2,22+4.6,24.6+7.0}三个候选点

得到了 n − 1 n-1 n1个候选划分点后,对每个候选点 t t t而言,按照 a < t a<t a<t a ≥ t a\geq t at D D D分为 D t , − D^{t,-} Dt, D t , + D^{t,+} Dt,+两个子集用来计算条件信息熵然后计算信息增益,最后选出能使信息增益最大的那个 t t t,即:

t ∗ = arg ⁡ max ⁡ t ∈ T a [ E n t ( D ) − ∑ v ∈ { − , + } ∣ D t , v ∣ ∣ D ∣ E n t ( D t , v ) ] t^*=\arg\max_{t\in T_a}\Bigl[Ent(D)-\sum_{v\in\{-,+\}}\frac{|D^{t,v}|}{|D|}Ent(D^{t,v})\Big] t=argmaxtTa[Ent(D)v{,+}DDt,vEnt(Dt,v)]

最右侧的求和就是使用某个候选点将样本集二分后的加权信息熵

选出最佳的 t ∗ t^* t之后,就将当前节点分成两个分支 a < t ∗ a<t^* a<t a ≥ t ∗ a\geq t^* at

缺失值处理

由于各种原因,我们得到的数据经常含有缺失值。当然如果一条样本缺失值太多,我们可以直接舍弃。但对于只缺失少量数据的样本,我们丢弃就有些可惜,尤其是对于不方便收集的数据样本。具体方法是:在样本集 D D D中找出没有缺失值的子集 D ′ D' D,用 ρ = ∣ D ′ ∣ ∣ D ∣ \rho=\frac{|D'|}{|D|} ρ=DD表示无缺失值的样本所占的比例,然后在 D ′ D' D上进行划分求信息增益,再乘以无缺失值的样本数占总样本的比例 ρ \rho ρ,即 G a i n ( D , a ) = ρ ⋅ G a i n ( D ′ , a ) Gain(D,a)=\rho\cdot Gain(D',a) Gain(D,a)=ρGain(D,a)

在找到最优划分属性后,将带缺失值的样本分到相应的子节点里的情况就有两个:

  1. 样本在该属性上取值已知,则正常分入其取值对应的节点
  2. 样本在该属性上取值未知,样本同时划分到所有节点,然后将该样本在不同样本中赋予不同的权重,而这个权重也是由 D ′ D' D得到的,即无缺失值样本中在属性 a a a上取值为 a v a_v av的样本所占的比例。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值