机器学习-特征工程中的数据预处理

 

       对于一个机器学习问题,数据和特征决定了机器学习的上限,而模型和算法只是逼近这个上限。由此可见,数据和特征在模型的整个开发过程中是比较重要。特征工程,顾名思义,是对原始数据进行一系列工程处理,将其提炼为特征,作为输入供算法和模型使用。从本质上来讲,特征工程是一个表示和展现数据的过程。在实际工作中,特征工程旨在去除原始数据中的杂质和冗余,以设计更高效的特征以刻画求解的问题与预测模型之间的关系。

       在实际的模型应用中并不是特征越多越好,特征越多固然会给我们带来很多额外的信息,但是与此同时,一方面,这些额外的信息也增加实验的时间复杂度和最终模型的复杂度,造成的后果就是特征的“维度灾难”,使得计算耗时大幅度增加;另一方面,可能会导致模型的复杂程度上升而使得模型变得不通用。所以我们就要在众多的特征中选择尽可能相关的特征有效的特征,使得计算的时间复杂度大幅度减少来简化模型,并且保证最终模型的有效性不被减弱或者减弱很少,这也就是我们特征选择的目的

特征工程主要包括以下方面:

我们重点从3个方面来详细说明特征工程的具体操作:

机器学习-特征工程中的数据预处理

机器学习-特征工程中的特征选择

机器学习-特征工程中的特征降维

 

1. 数据标准化和归一化

       在多指标评价体系中,由于各评价指标的性质不同,通常具有不同的量纲和数量级。当各指标间的水平相差很大时,如果直接用原始指标值进行分析,就会突出数值较高的指标在综合分析中的作用,相对削弱数值水平较低指标的作用。因此,为了保证结果的可靠性,需要对原始指标数据进行标准化处理,去除数据的单位限制,将其转化为无量纲的纯数值,便于不同单位或量级的指标能够进行比较和加权。去除特征值的量纲,那么去除量纲也有两种不同的方法,一个叫归一化,一个叫标准化。标准化的目的是将样本的各个特征值转换到同一量纲下,使得不同度量的特征具有可比性;归一化的目的是将各样本转化为单位向量使得模型迭代更快更好。

常见的无量纲化操作中,其中最常用的是min-max标准化、 z-score 标准化和Normalization归一化,具体为:

(1)min-max标准化

min-max标准化是对原始数据进行线性变换,将其映射到[0,1]之间,该方法也被称为离差标准化,但是请注意,网上更多人喜欢把z-score称为标准化方法,把min-max称为归一化方法,然后在此基础上,强行给标准化(z-score)与归一化(min-max)划条界线,以显示二者之间的相异性二者之间确实有很大的不同,但是这两个方法说到底还都是用来去除量纲的,都是无量纲化技术中的一员而已,所以,请不要纠结标准化与归一化这两个概念了。

                

上式中,min是样本的最小值,max是样本的最大值。由于最大值与最小值可能是动态变化的,同时也非常容易受噪声(异常点、离群点)影响,因此一般适合小数据的场景,min-max标准化示例为:

    

(2)z-score标准化

z-score标准化(zero-mena normalization,0-均值标准化)方法的公式如下所示:

               

上式中,x是原始数据,u是样本均值,σ是样本标准差。回顾下正态分布的基本性质,若xN(u,σ^2),则有

           

其中,N(0,1)表示标准正态分布,z-score标准化示例为:

        

       可以看出,z-score标准化方法试图将原始数据集标准化成均值为0,方差为1且接近于标准正态分布的数据集。然而,一旦原始数据的分布不接近于一般正态分布,则标准化的效果会不好。该方法比较适合数据量大的场景(即样本足够多,现在都流行大数据,因此可以比较放心地用)。此外,相对于min-max归一化方法,该方法不仅能够去除量纲,还能够把所有维度的变量一视同仁(因为每个维度都服从均值为0、方差1的正态分布),在最后计算距离时各个维度数据发挥了相同的作用,避免了不同量纲的选取对距离计算产生的巨大影响。所以,涉及到计算点与点之间的距离,如利用距离度量来计算相似度、PCA、LDA,聚类分析等,并且数据量大(近似正态分布),可考虑该方法。相反地,如果想保留原始数据中由标准差所反映的潜在权重关系应该选择min-max归一化。

(3)Normalization

Normalization的数据预处理方法,在一些地方,有人把这种方法翻译为正则化,但是机器学习中的正则化更多是与模型相关(比如逻辑回归在损失函数后增加L2正则项);也有人称之为归一化,但是吧,有时这种方法并没体现“归一”特性,如处理后的数据该是负号的还是负号。其实这个方法是根据范数来进行Normalization的,何为范数?听着感觉高大上,其实非常常见。Lp-范数的计算公式如下所示:

             

可见,L2范数即为欧式距离,则规则为L2的Normalization公式如下所示,易知,其将每行(条)数据转为相应的“单位向量”。

                       

Normalization的过程是将每个样本缩放到单位范数(结合单位向量进行理解,p=2时为单位向量,其他为单位范数),如果后面要使用如二次型(点积)或者其它核方法计算两个样本之间的相似性这个方法会很有用。L2的Normalization示例为:

        

从经验上说,归一化是让不同维度之间的特征在数值上有一定比较性,可以大大提高分类器的准确性,具体的优点有:

(1) 提升模型的收敛速度

       如下图,x1的取值为0-2000,而x2的取值为1-5,假如只有这两个特征,对其进行优化时,会得到一个窄长的椭圆形,导致在梯度下降时,梯度的方向为垂直等高线的方向而走之字形路线,这样会使迭代很慢,相比之下,右图的迭代就会很快(理解:也就是步长走多走少方向总是对的,不会走偏)

            

(2)提升模型的精度

       另一好处是提高精度,这在涉及到一些距离计算的算法时效果显著,比如算法要计算欧氏距离,上图中x2的取值范围比较小,涉及到距离计算时其对结果的影响远比x1带来的小,所以这就会造成精度的损失。所以归一化很有必要,他可以让各个特征对结果做出的贡献相同。  

标准化与归一化的区别

对象不一样:

  • 标准化的对象是一个特征列
  • 归一化的对象是一个样本行;

目的不一样:

  • 标准化的目的是将样本的各个特征值转换到同一量纲下使得不同度量的特征具有可比性;
  • 归一化的目的是将各样本转化为单位向量使得模型迭代更快更好;

在sklearn中有提供数据的相关标准化和归一化方法,可以直接调用:

from sklearn.preprocessing import StandardScaler
from sklearn.preprocessing import MinMaxScaler
from sklearn.preprocessing import Normalizer

#标准化,返回值为标准化后的数据
StandardScaler().fit_transform(iris.data)

#区间缩放,返回值为缩放到[0, 1]区间的数据
MinMaxScaler().fit_transform(iris.data)

 #归一化,返回值为归一化后的数据
Normalizer().fit_transform(iris.data)


2. 特征二值化

       对于某些定量特征,其包含的有效信息为区间划分,例如学习成绩,假若只关心“及格”或不“及格”,那么需要将定量的考分,转换成“1”和“0”表示及格和未及格。定量特征二值化的核心在于设定一个阈值,大于阈值的赋值为1,小于等于阈值的赋值为0。二值化是对文本计数数据的常见操作,分析人员可以决定仅考虑某种现象的存在与否。它还可以用作考虑布尔随机变量的估计器的预处理步骤(例如,使用贝叶斯设置中的伯努利分布建模)。公式表达如下:

         

from sklearn.preprocessing import Binarizer

#二值化,阈值设置为3,返回值为二值化后的数据
Binarizer(threshold=3).fit_transform(iris.data)

但是在特征二值化中存在一个问题,比如一个特征为性别,有两种属性“男”,“女”,那么特征二值化后,将男 --> 0 , 女 --> 1 ,但是对于这个变量来说,0和1存在大小关系,男和女不存在对比关系,在后期的模型训练中可能会导致模型的一个错误理解,在后面的哑编码中可以避免这种问题。

 

3. 哑编码/独热编码

       首先哑编码面向的是离散型的特征,哑编码是将一个离散型特征进行一对多映射产出多个特征的编码方式,每个特征编码只代表一个若干级别间的差异,下图即为年龄特征,离散化成为年龄段特征,再最后哑编码为四个不同的特征,寄现将连续型特征转化为离散型特征,然后再转换为哑编码。

      

哑编码的优点:

  • 简化了模型训练的复杂性,降低模型过拟合的风险(是离散化带来的优势);
  • 离散化后的特征对异常数据有很强的鲁棒性(是离散化带来的优势);
  • 稀疏向量内积乘法运算速度快,因为稀疏矩阵有实数的值很少,做内积运算时就会有很多优化手段;
  • 线性模型表达能力受限,单变量离散化为N个后,每个变量有单独的权重,相当于为模型引入了非线性,能够提升模型表达能力,加大拟合能力;
  • 离散化后可以进行特征交叉,由M+N个变量变为M*N个变量,进一步引入非线性,提升表达能力;


常见的对离散型数据进行哑编码处理,常见的处理方法有两种:
sklearn:使用sklearn库中的OneHotEncoder()方法进行独热编码。
pandas:使用pandas库中的函数pd.dummies()或pd.factorize()进行独热编码;

 

(1)One-Hot编码

One-Hot编码,又称为一位有效编码,主要是采用N位状态寄存器来对N个状态进行编码,每个状态都由他独立的寄存器位,并且在任意时候只有一位有效。

       

One-Hot的优点:
1、能够处理非连续型数值特征;
2、在一定程度上扩充了特征(例如:性别本身是一个特征,经过one hot编码以后,就变成了男或女两个特征。);
3、将离散特征的取值扩展到了欧式空间(离散特征的某个取值就对应欧式空间的某个点,在回归,分类,聚类等机器学习算法中,特征之间距离的计算或相似度的计算是非常重要的,而我们常用的距离或相似度的计算都是在欧式空间的相似度计算,计算余弦相似性,基于的就是欧式空间。);
4、将离散型特征使用one-hot编码,可以让特征之间的距离计算更加合理,相当于做了归一化处理;

One-Hot用在GBDT、XGBoost这些模型里面都挺好的,但是用在逻辑回归里不行。因为逻辑回归要求变量间相互独立,如果你只有一个属性需要做one-hot编码还好,如果你有多个属性需要做one-ont编码,那么当某个样本的多个one-hot属性同时为1时,这两个属性就完全相关了,必然会导致singular error,也就是非奇异矩阵不能求解唯一解,得不出唯一的模型,但是你又不可能把同一个属性的某一个one-hot延伸变量删除。如果在逻辑回归中入模标称属性,可以直接替换成数值,然后做woe变换,用每个类别的woe值来代替原来的数值,这样既能够避免生成相关性强的变量,又能避开类别间大小无法比较的问题。

 

(2)Dummy哑变量编码

哑变量就是将原始特征变量转换成以原始特征值分类的多维度的变量,并用是否(0,1)这种方式的新特征值替代和量化。和One-Hot编码基本一样,但是比One-Hot编码少了一个状态。哑变量编码直观的解释就是任意的将一个状态去除。

       

同理,在列举一个示例,比如以“学历”这个变量为例,有五种状态,分别为小学、中学、大学、硕士、博士,

       

对于定类类型的数据,建议使用one-hot encoding。定类类型就是纯分类,不排序,没有逻辑关系。比如性别分男和女,男女不存在任何逻辑关系,我们不能说男就比女好,或者相反。再者,中国各省市分类也可以用独热编码,同样各省不存在逻辑关系,这时候使用one-hot encoding会合适些。但注意,一般会舍去一个变量,比如男的对立面肯定是女,那么女就是重复信息,所以保留其中一个变量即可。
对于定序类型的数据,建议使用label encoding。定序类型也是分类,但有排序逻辑关系,等级上高于定类。比如,学历分小学,初中,高中,本科,研究生,各个类别之间存在一定的逻辑,显然研究生学历是最高的,小学最低。这时候使用Label encoding会显得更合适,因为自定义的数字顺序可以不破坏原有逻辑,并与这个逻辑相对应。
对数值大小敏感的模型必须使用one-hot encoding或者Dummy。典型的例子就是LRSVM。二者的损失函数对数值大小是敏感的,并且变量间的数值大小是有比较意义的。而Label encoding的数字编码没有数值大小的含义,只是一种排序,因此对于这些模型都使用one-hot encoding。
对数值大小不敏感的模型(如树模型)不建议使用one-hot encoding。一般这类模型为树模型。如果分类类别特别多,那么one-hot encoding会分裂出很多特征变量。这时候,如果我们限制了树模型的深度而不能向下分裂的话,一些特征变量可能就因为模型无法继续分裂而被舍弃损失掉了。因此,此种情况下可以考虑使用Label encoding


4. 缺失值计算

       由于各种原因,许多现实世界的数据集包含缺少的值,通常编码为空白,NaN或其他占位符。然而,这样的数据集与Scikit-learn的分类器不兼容,它们假设数组中的所有值都是数字,并且都具有和保持含义。使用不完整数据集的基本策略是丢弃包含缺失值的行或列。然而,这样的代价是可能丢失有价值的数据,如果每行或每列缺失数据占比比较大,建议直接放弃这些数据,否则更好的策略是估算缺失值,并将其填充。

  • 当某个变量或者某个样本中缺失值占比过大时(空值率达到90%以上),那么我们可以认为这一变量或者样本没有意义,可以直接删除;
  • 用平均值、中值、分位数、众数、随机值等替代(效果一般,因为等于人为增加了噪声);
  • 用其他变量做预测模型来算出缺失变量。效果比方法2略好。有一个根本缺陷,如果其他变量和缺失变量无关,则预测的结果无意义。如果预测结果相当准确,则又说明这个变量是没必要加入建模的。一般情况下,介于两者之间;
  • 把变量映射到高维空间。比如性别,有男、女、缺失三种情况,则映射成3个变量:是否男、是否女、是否缺失。连续型变量也可以这样处理。比如Google、百度的CTR预估模型,预处理时会把所有变量都这样处理,达到几亿维。这样做的好处是完整保留了原始数据的全部信息、不用考虑缺失值、不用考虑线性不可分之类的问题。缺点是计算量大大提升;


5. 异常值处理

       在机器学习中,异常检测和处理是一个比较小的分支,或者说,是机器学习的一个副产物,因为在一般的预测问题中,模型通常是对整体样本数据结构的一种表达方式,这种表达方式通常抓住的是整体样本一般性的性质,而那些在这些性质上表现完全与整体样本不一致的点,我们就称其为异常点,通常异常点在预测问题中是不受开发者欢迎的,因为预测问题通产关注的是整体样本的性质,而异常点的生成机制与整体样本完全不一致,如果算法对异常点敏感,那么生成的模型并不能对整体样本有一个较好的表达,从而预测也会不准确。异常值产生的原因有一下几个方面:

数据输入错误,人为错误(如数据收集,记录或输入过程中导致的错误)会导致数据中的异常值。 例如:客户的年收入是10万美元,但意外地,数据输入操作附加一个零。 现在的收入就是100万美元,是10倍。 显然,与其他人相比,这将是异常值。

测量误差,这是异常值最常见的来源。 当使用的测量仪器出现故障时,会引起这种情况。 例如:有10台称重机。 其中9个是正确的,1个是错误的。 故障机器上的人员测量重量将高于或低于组内其余人员。 在故障机器上测量的重量可能导致异常值。

实验误差,异常值的另一个原因是实验误差。 例如:在7名跑步者的100米冲刺中,有一名选手错过了跑的口令,让他开始延迟。 因此,这使得跑步者的跑步时间比其他跑步者要多, 总运行时间可能是一个异常值。

故意异常值,通常在自我报告的措施中涉及敏感数据。 例如:通常青少年报告酒量,只有其中一小部分报告实际价值,这里的实际值可能看起来像异常值,因为其余的青少年正在假值。

数据处理错误,无论何时执行数据挖掘,我们从多个来源提取数据,某些操作或提取错误可能会导致数据集中的异常值。

抽样错误,例如,衡量运动员的身高,错误地在样品中包括几名篮球运动员。 这种包含可能会导致数据集中的异常值。

自然异常值,当异常值不是人为的(由于错误),它是一个自然的异常值。 例如:注意到其中一家著名的保险公司,前50名财务顾问的表现远远高于其他人。 令人惊讶的是,这不是由于任何错误。 因此,每当与顾问一起执行任何数据挖掘活动时,我们都会分别对待此细分。

对待异常值的处理方法有以下几种:

(1)简单统计

如果使用pandas,我们可以直接使用describe()来观察数据的统计性描述(只是粗略的观察一些统计量),不过统计数据为连续型的,如下:

df.describe()

或者简单使用散点图也能很清晰的观察到异常值的存在。如下所示:

(2)3∂原则

这个原则有个条件:数据需要服从正态分布。在3∂原则下,观测值与平均值的差别如果超过3倍标准差,那么可以将其视为异常值。正负3∂的概率是99.7%,那么距离平均值3∂之外的值出现的概率为P(|x-u| > 3∂) <= 0.003,属于极个别的小概率事件。如果数据不服从正态分布,也可以用远离平均值的多少倍标准差来描述,多少倍的取值需要根据经验和实际情况来决定。

(3)箱型图

       这种方法是利用箱型图的四分位距(IQR)对异常值进行检测,也叫Tukey‘s test。箱线图(Boxplot)也称箱须图(Box-whisker Plot),是利用数据中的五个统计量:最小值、第一四分位数、中位数、第三四分位数与最大值来描述数据的一种方法,它也可以粗略地看出数据是否具有有对称性,分布的分散程度等信息,特别可以用于对几个样本的比较。

箱线图具体含义如下,首先计算出第一四分位数(Q1)、中位数、第三四分位数(Q3)。中位数我们都知道,就是将一组数字按从小到大的顺序排序后,处于中间位置(也就是50%位置)的数字。第一四分位数、第三四分位数是按从小到大的顺序排序后,处于25%、75%的数字。

令 IQR=Q3−Q1,那么 Q3+1.5(IQR) 和 Q1−1.5(IQR) 之间的值就是可接受范围内的数值,这两个值之外的数认为是异常值;
在Q3+1.5IQR(四分位距)和Q1-1.5IQR处画两条与中位线一样的线段,这两条线段为异常值截断点,称其为内限;
在Q3+3IQR和Q1-3IQR处画两条线段,称其为外限;

这里写图片描述

处于内限以外位置的点表示的数据都是异常值,其中在内限与外限之间的异常值为温和的异常值(mild outliers),在外限以外的为极端的异常值(li)的异常值extreme outliers。这种异常值的检测方法叫做Tukey’s method。从矩形盒两端边向外各画一条线段直到不是异常值的最远点 表示该批数据正常值的分布区间点,示该批数据正常值的分布区间。一般用“〇”标出温和的异常值,用“*”标出极端的异常值。

 

Percentile = np.percentile(df['length'],[0,25,50,75,100])
IQR = Percentile[3] - Percentile[1]
UpLimit = Percentile[3] + IQR*1.5
DownLimit = Percentile[1] - IQR*1.5

也可以使用seaborn的可视化方法boxplot来实现:

f,ax=plt.subplots(figsize=(10,8))
sns.boxplot(y='length',data=df,ax=ax)
plt.show()

上图中的菱形点就是异常值。

(4)基于模型检测

       基于模型检测的这种方法一般会构建一个概率分布模型,并计算对象符合该模型的概率,把具有低概率的对象视为异常点。如果模型是簇的集合,则异常是不显著属于任何簇的对象;如果模型是回归时,异常是相对远离预测值的对象。

       离群点的概率定义:离群点是一个对象,关于数据的概率分布模型,它具有低概率。这种情况的前提是必须知道数据集服从什么分布,如果估计错误就造成了重尾分布。比如特征工程中的RobustScaler方法,在做数据特征值缩放的时候,它会利用数据特征的分位数分布,将数据根据分位数划分为多段,只取中间段来做缩放,比如只取25%分位数到75%分位数的数据做缩放,这样减小了异常数据的影响。

优缺点:

(1)有坚实的统计学理论基础,当存在充分的数据和所用的检验类型的知识时,这些检验可能非常有效;
(2)对于多元数据,可用的选择少一些,并且对于高维数据,这些检测可能性很差。

 

(5)基于近邻度的离群点检测

       统计方法是利用数据的分布来观察异常值,一些方法甚至需要一些分布条件,而在实际中数据的分布很难达到一些假设条件,在使用上有一定的局限性。确定数据集的有意义的邻近性度量比确定它的统计分布更容易。这种方法比统计学方法更一般、更容易使用,因为一个对象的离群点得分由到它的k-最近邻(KNN)的距离给定。需要注意的是:离群点得分对k的取值高度敏感,如果k太小,则少量的邻近离群点可能导致较低的离群点得分;如果K太大,则点数少于k的簇中所有的对象可能都成了离群点。为了使该方案对于k的选取更具有鲁棒性,可以使用k个最近邻的平均距离。

优缺点:

(1)简单;
(2)缺点:基于邻近度的方法需要O(m2)时间,大数据集不适用;
(3)该方法对参数的选择也是敏感的;
(4)不能处理具有不同密度区域的数据集,因为它使用全局阈值,不能考虑这种密度的变化。

 

(6)基于密度的离群点检测

       从基于密度的观点来说,离群点是在低密度区域中的对象。基于密度的离群点检测与基于邻近度的离群点检测密切相关,因为密度通常用邻近度定义。一种常用的定义密度的方法是,定义密度为到k个最近邻的平均距离的倒数。如果该距离小,则密度高,反之亦然。另一种密度定义是使用DBSCAN聚类算法使用的密度定义,即一个对象周围的密度等于该对象指定距离d内对象的个数。

优缺点:

(1)给出了对象是离群点的定量度量,并且即使数据具有不同的区域也能够很好的处理;
(2)与基于距离的方法一样,这些方法必然具有O(m2)的时间复杂度。对于低维数据使用特定的数据结构可以达到O(mlogm);
(3)参数选择是困难的。虽然LOF算法通过观察不同的k值,然后取得最大离群点得分来处理该问题,但是,仍然需要选择这些值的上下界。

 

(7)基于聚类的方法来做异常点检测

基于聚类的离群点:一个对象是基于聚类的离群点,如果该对象不强属于任何簇,那么该对象属于离群点。

离群点对初始聚类的影响:如果通过聚类检测离群点,则由于离群点影响聚类,存在一个问题:结构是否有效。这也是k-means算法的缺点,对离群点敏感。为了处理该问题,可以使用如下方法:对象聚类,删除离群点,对象再次聚类(这个不能保证产生最优结果)。

优缺点:

(1)基于线性和接近线性复杂度(k均值)的聚类技术来发现离群点可能是高度有效的;
(2)簇的定义通常是离群点的补,因此可能同时发现簇和离群点;
(3)产生的离群点集和它们的得分可能非常依赖所用的簇的个数和数据中离群点的存在性;
(4)聚类算法产生的簇的质量对该算法产生的离群点的质量影响非常大。

 

(8)专门的离群点检测

       其实以上说到聚类方法的本意是是无监督分类,并不是为了寻找离群点的,只是恰好它的功能可以实现离群点的检测,算是一个衍生的功能。除了以上提及的方法,还有两个专门用于检测异常点的方法比较常用:One Class SVM和Isolation Forest,详细内容不进行深入研究。

 

异常值的处理方法

检测到了异常值,我们需要对其进行一定的处理。而一般异常值的处理方法可大致分为以下几种:

  • 删除含有异常值的记录:直接将含有异常值的记录删除;

  • 视为缺失值:将异常值视为缺失值,利用缺失值处理的方法进行处理;

  • 平均值修正:可用前后两个观测值的平均值修正该异常值;

  • 不处理:直接在具有异常值的数据集上进行数据挖掘;

是否要删除异常值可根据实际情况考虑。因为一些模型对异常值不很敏感,即使有异常值也不影响模型效果,但是一些模型比如逻辑回归LR对异常值很敏感,如果不进行处理,可能会出现过拟合等非常差的效果

 

 

 

参考链接:https://blog.csdn.net/qq_41080850/article/details/83829045
参考链接:https://blog.csdn.net/qq_41080850/article/details/86695846
参考链接:https://blog.csdn.net/jyxmust/article/details/80659324
参考链接:https://www.jianshu.com/p/0127b187a7c2
参考链接:https://www.jianshu.com/p/500d5a20d4ec
参考链接:https://cloud.tencent.com/developer/article/1642280
参考链接:https://www.imooc.com/article/285304
参考链接:https://www.cnblogs.com/jasonfreak/p/5448385.html
参考链接:https://zhuanlan.zhihu.com/p/103070096

 

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值