数据挖掘——第三章 数据预处理

《数据挖掘》—— 第3章 数据预处理

image-20220808155518819

文章目录

第3章 数据预处理

3.1 数据预处理:概述

数据质量:为什么要对数据预处理

数据质量涉及许多因素:

  • 准确性(accuracy):数据是否正确,是否准确;
  • 完整性(completeness):数据是否有记录,是否可获取;
  • 一致性(consistency):数据的命名约定、数据代码或输入格式是否一致;
  • 时效性(timeliness):数据是否及时更新;
  • 可信性(believability):数据有多大可能是准确的,多少数据是用户信赖的;
  • 可解释性(interpretability):数据是否容易理解。

数据预处理的主要任务

数据清理(data cleaning)
  • 填写缺失值,光滑噪声数据,识别或删除离群点,并解决不一致性来“清理”数据。
数据集成(data integration)
  • 集成多个数据库、数据立方体或文件,需要采取措施避免数据集成时的冗余。
数据归约(data reduction)
  • 得到数据集的简化表示,它的规模要小得多,但能够产生同样的(或几乎同样的)分析结果。包括维归约(dimensionality reduction)和数值规约(numerosity reduction);
  • 维归约,使用数据编码方案,以便得到原始数据的简化或“压缩”表示。例如,小波变换和主成分分析(数据压缩技术),属性子集选择(去掉不相关属性)和属性构造(从原属性集到处更有用的小属性集);
  • 数值规约,使用参数模型(例如,回归和对数线性模型)或非参数模型(例如,直方图、聚类、抽样或数据聚集),用较小的表示取代数据。
数据变换(data transformation)
  • 规范化、数据离散化;
  • 概念分层

3.2 数据清理

缺失值

处理方法
  • 忽略,仅当某一元组有较多缺失属性时适用;
  • 人工填写,费时费力;
  • 用一个全局常量填充,如使用字段“未知”作为一个新类,不太可靠;
  • 用属性的中心度量(如均值或中位数)填充;
  • 用与给定元组数同一类的所有样本的均值或中位数填充;
  • 最常用方法:用最可能的值填充,使用基于推理的工具或算法确定,如决策树和贝叶斯推理。

方法(3)~(6)使数据诱骗,填入的值可能不正确。然而,方法(6)是最流行的策略;与其他方法相比,它使用已有数据的大部分信息来预测缺失值。

噪声数据

噪声(noise):被测变量的随机误差或方差。

处理方法
分箱(binning)
  • 通过考察数据的“近邻”来光滑有序数据值。这些有序的值分布到一些“桶”或箱中。由于分箱方法考察近邻的值,因此它进行局部光滑;
  • 对于用箱均值光滑,箱中每一个值都被替换为箱中的均值;类似地,还有用箱中位数光滑
  • 对于用箱边界光滑,给定箱中的最大和最小值同样是箱边界,箱中的每一个值都替换为最近的边界值。

例,将数据 4 ,   8 ,   15 ,   21 ,   21 ,   24 ,   25 ,   28 ,   34 4,\ 8,\ 15,\ 21,\ 21,\ 24,\ 25,\ 28,\ 34 4, 8, 15, 21, 21, 24, 25, 28, 34 分箱。

image-20220810152342676
回归(regression)
  • 用一个函数拟合数据来光滑数据。
离群点分析(outlier analysis)
  • 通过聚类等方法来检测离群点并移除。聚类将类似的值组织成群或“簇”。直观地,落在簇集合之外的值视作离群点。
image-20220812102725293

数据清理作为一个过程

偏差检测(discrepancy detection)
  • 利用元数据(值域、取值范围、趋势、分布);
  • 检查是否存在字段过载;
  • 检查唯一性原则、连续性原则、空值原则;
  • 使用数据清洗工具、数据审计工具。

3.3 数据集成

实体识别问题

  • 例如,A.customer_idB.cust_number 是否指相同属性;
  • 来自多个信息源的现实世界的等价实体如何匹配。

冗余和相关分析

  • 一个属性(例如,年收入)如果能够由另一个或另一组属性“导出”,则这个属性有可能是冗余的。

  • 有些冗余可以被相关分析检测到。给定两个属性,这种分析可以根据可用的数据,度量一个属性能在多大程度上蕴含另一个。对于标称数据,我们使用 χ 2 \chi^2 χ2 检验;对于数值属性,我们使用相关系数(correlation coefficient)和协方差(covariance),它们都评估一个属性的值如何随另一个变化。

标称数据的 χ 2 \chi^2 χ2 相关检验

假设有两个属性 A ,   B A,\ B A, B A A A c c c 个不同值 a 1 ,   a 2 , ⋯   ,   a c a_1,\ a_2,\cdots,\ a_c a1, a2,, ac B B B r r r 个不同值 b 1 ,   b 2 , ⋯   ,   b r b_1,\ b_2,\cdots,\ b_r b1, b2,, br。用 A A A B B B 描述的数据元组可以用一个相依表显示,其中 A A A c c c 个值构成列, B B B r r r 个值构成行。令 ( A i ,   B j ) (A_i,\ B_j) (Ai, Bj) 表示属性 A A A 取值 a i a_i ai、属性 B B B 取值 b j b_j bj 的联合事件,即 ( A = a i ,   B = b j ) (A=a_i,\ B=b_j) (A=ai, B=bj)。每个可能的 ( A i ,   B j ) (A_i,\ B_j) (Ai, Bj) 联合事件都在表中有自己的单元。 χ 2 \chi^2 χ2 值( P e a r s o n   χ 2 Pearson\ \chi^2 Pearson χ2 统计量)可以用下式计算:
χ 2 = ∑ i = 1 c ∑ j = 1 r ( o i j − e i j ) 2 e i j (3.1) \chi^2=\sum_{i=1}^c\sum_{j=1}^r\frac{{(o_{ij}-e_{ij})}^2}{e_{ij}} \tag{3.1} χ2=i=1cj=1reij(oijeij)2(3.1)
其中, o i j o_{ij} oij 是联合事件 ( A i ,   B j ) (A_i,\ B_j) (Ai, Bj)观测频度(即实际计数),而 e i j e_{ij} eij ( A i ,   B j ) (A_i,\ B_j) (Ai, Bj)期望频度,可以用下式计算:
e i j = c o u n t ( A = a i ) × c o u n t ( B = b j ) n (3.2) e_{ij}=\frac{count(A=a_i)\times count(B=b_j)}{n} \tag{3.2} eij=ncount(A=ai)×count(B=bj)(3.2)
其中, n n n 是数据元组的个数, c o u n t ( A = a i ) count(A=a_i) count(A=ai) A A A 上具有值 a i a_i ai 的元组个数,而 c o u n t ( B = b j ) count(B=b_j) count(B=bj) B B B 上具有值 b j b_j bj 的元组个数。 ( 3.1 ) (3.1) (3.1) 式中的和在所有 r × c r\times c r×c 个单元上计算。注意, χ 2 \chi^2 χ2 值贡献最大的单元是其实际计数与期望计数很不同的单元

χ 2 \chi^2 χ2 统计检验假设 A A A B B B 是独立的。检验基于显著水平,具有自由度 ( r − 1 ) × ( c − 1 ) (r-1)\times (c-1) (r1)×(c1)

合计
小说250(90)200(360)450
非小说50(210)1000(840)1050
合计30012001500

利用 ( 3.2 ) (3.2) (3.2) 式,我们可以验证每个单元的期望频率。例如,单元 ( 男,小说 ) (男,小说) (男,小说) 的期望频率是 e 11 = c o u n t ( 男 ) × c o u n t ( 小说 ) n = 300 × 450 1500 = 90 e_{11}=\frac{count(男)\times count(小说)}{n}=\frac{300\times 450}{1500}=90 e11=ncount()×count(小说)=1500300×450=90,其他类似可得。使用计算 χ 2 \chi^2 χ2 ( 3.1 ) (3.1) (3.1) 式,可以得到 χ 2 = ( 250 − 90 ) 2 90 + ( 50 − 210 ) 2 210 + ( 200 − 360 ) 2 360 + ( 1000 − 840 ) 2 840 = 284.44 + 121.90 + 71.11 + 30.48 = 507.93 \chi^2=\frac{{(250-90)}^2}{90}+\frac{{(50-210)}^2}{210}+\frac{{(200-360)}^2}{360}+\frac{{(1000-840)}^2}{840}=284.44+121.90+71.11+30.48=507.93 χ2=90(25090)2+210(50210)2+360(200360)2+840(1000840)2=284.44+121.90+71.11+30.48=507.93

对于这个 2 × 2 2\times2 2×2 的表,自由度 ( 2 − 1 ) ( 2 − 1 ) = 1 (2-1)(2-1)=1 (21)(21)=1。对于自由度 1 1 1,在 0.001 0.001 0.001 的置信水平下,拒绝假设的值式 10.828 10.828 10.828。因为 507.93 > 10.828 507.93>10.828 507.93>10.828,所以我们可以拒绝性别阅读偏好独立的假设,并断言对于给定的人群,这两个属性式(强)相关的。

数值数据的相关系数

对于数值数据,我们可以通过计算属性 A A A B B B相关系数(又称Pearson积矩系数),估计这两个属性的相关度 r A , B r_{A,B} rA,B
r A , B = ∑ i = 1 n ( a i − A ˉ ) ( b i − B ˉ ) n σ A σ B = ∑ i = 1 n ( a i b i ) − n A ˉ B ˉ n σ A σ B (3.3) r_{A,B} =\frac{\sum_{i=1}^n(a_i-\bar A)(b_i-\bar B)}{n\sigma_A\sigma_B} =\frac{\sum_{i=1}^n(a_ib_i)-n\bar{A} \bar{B}}{n\sigma_A\sigma_B} \tag{3.3} rA,B=nσAσBi=1n(aiAˉ)(biBˉ)=nσAσBi=1n(aibi)nAˉBˉ(3.3)
其中, n n n 是数据元组的个数, a i a_i ai b i b_i bi 分别是元组 i i i A A A B B B 上的值, A ˉ \bar A Aˉ B ˉ \bar B Bˉ 分别是 A A A B B B 的均值, σ A \sigma_A σA σ B \sigma_B σB 分别是 A A A B B B 的标准差, ∑ i = 1 n ( a i b i ) \sum_{i=1}^n(a_ib_i) i=1n(aibi) A B AB AB 叉积和(即对于每个元组, A A A 的值乘以该元组 B B B 的值)。

注意, − 1 ≤ r A , B ≤ + 1 -1\le r_{A,B}\le +1 1rA,B+1。① r A , B > 0 r_{A,B}>0 rA,B>0,则 A A A B B B 是正相关的;② r A , B < 0 r_{A,B}<0 rA,B<0,则 A A A B B B 是负相关的;③ r A , B = 0 r_{A,B}=0 rA,B=0,则 A A A B B B独立的。该值越大,相关性越强(即每个属性蕴含另一个的可能性越大)。因此,一个较高的 r A , B r_{A,B} rA,B 值表明 A   o r   B A\ or\ B A or B 可以作为冗余删除。

image-20220812164205918
数值数据的协方差

考虑两个数值属性 A A A B B B n n n 次观测的集合 { ( a 1 , b 1 ) ,   ⋯   ,   ( a n , b n ) } \{(a_1,b_1),\ \cdots,\ (a_n,b_n)\} {(a1,b1), , (an,bn)} A A A B B B 的均值又分别称为 A A A B B B期望值,即
E ( A ) = A ˉ = ∑ i = 1 n a i n ,   E ( B ) = B ˉ = ∑ i = 1 n b i n . E(A)=\bar A=\frac{\sum_{i=1}^na_i}{n},\ E(B)=\bar B=\frac{\sum_{i=1}^nb_i}{n}. E(A)=Aˉ=ni=1nai, E(B)=Bˉ=ni=1nbi.
A A A B B B协方差(covariance)定义为:
C o v ( A , B ) = E ( ( A − A ˉ ) ( B − B ˉ ) ) = ∑ i = 1 n ( a i − A ˉ ) ( b i − B ˉ ) n (3.4) Cov(A,B)=E((A-\bar A)(B-\bar B))=\frac{\sum_{i=1}^n(a_i-\bar A)(b_i-\bar B)}{n} \tag{3.4} Cov(A,B)=E((AAˉ)(BBˉ))=ni=1n(aiAˉ)(biBˉ)(3.4)
容易得到:
r A , B = C o v ( A , B ) σ A σ B (3.5) r_{A,B}=\frac{Cov(A,B)}{\sigma_A\sigma_B} \tag{3.5} rA,B=σAσBCov(A,B)(3.5)

C o v ( A , B ) = E ( A ⋅ B ) − A ˉ B ˉ (3.6) Cov(A,B)=E(A\cdot B)-\bar A \bar B \tag{3.6} Cov(A,B)=E(AB)AˉBˉ(3.6)

元组重复

除了检测属性间的冗余外,还应当在元组级检测重复(例如,对于给定的唯一数据实体,存在两个或多个相同的元组)。

数据值冲突的检测与处理

来自不同数据源的属性值可能不同。这可能是因为表示、尺度或编码不同。

3.4 数据归约

数据归约策略概述

维归约(dimensionality reduction)

减少所考虑的随机变量或属性的个数。方法包括:

  • 小波变换;
  • 主成分分析;

它们把元数据变换或投影到较小的空间;

  • 属性子集选择;

这种方法将不相关、弱相关或冗余的属性或维检测出来并删除。

数量归约(numerosity reduction)

参数方法:

  • 回归和对数-线性模型;

非参数方法:

  • 直方图;
  • 聚类;
  • 抽样;
  • 数据立方体聚集。
数据压缩(data compression)

使用变换,以便得到原数据的归约或“压缩”表示。如果原数据能够从压缩后的数据重构,而不损失信息,则称该数据归约是无损的。如果我们只能近似重构原数据,则该数据归约称为有损的

小波变换

  • 一种线性信号处理技术,可用于处理多维数据。实际应用包括指纹图像压缩、计算机视觉、时间序列数据分析和数据清理;
  • 离散小波变换(DWT)关键在于小波变换后的数据可以截断。仅存放一部分最强的小波系数,就能保留近似的压缩数据;
  • 与离散傅里叶变换(DFT)相比,DWT是一种更好的有损压缩。即,对于给定数据的向量,在DWT和DFT保留相同数目系数的情况下,DWT能提供更准确的数据近似、需要的空间比DFT小、局部性更好有助于保留局部细节。

主成分分析

  • 搜索最能代表数据的向量;
  • 创建一个替换的、较小的变量集“组合”属性的基本要素;
  • 常常揭示先前未曾察觉的联系。

属性子集选择

通过删除不相关或冗余的属性(或维)减少数据量。该方法的目标是找出最小属性集,使得数据类的概率分布尽可能地接近使用所有属性得到的原分布。该方法还减少了出现在发现模式上的属性数目,使得模式更易于理解。

属性子集选择的启发式方法
image-20220814171053926
逐步向前选择

由空属性集作为归约集开,确定原属性集中最好的属性,并将它添加到归约集中。在其后的每一次迭代,将剩下的原属性集中最好的属性添加到该集合中。

逐步向后删除

由整个属性集开始,在每一步中,删除属性集中最差的属性。

逐步向前选择和逐步向后删除的组合

由整个属性集开始,在每一步中,删除属性集中最差的属性,同时选择一个最好的属性。

决策树归纳

当决策树归纳用于属性子集选择时,由给定的数据构造决策树。不出现在树中的所有属性假定是不相关的。出现在树中的属性形成归约后的属性子集。

在某些情况下,我们可能基于其他属性创建一些新属性。这种属性构造可以帮助提高准确性和对高维数据结构的理解。

回归和对数线性模型:参数化数据归约

在(简单)线性回归中,对数据建模,使之拟合到一条直线。例如,可以用以下公式,将随机变量 y y y(因变量)表示为另一随机变量 x x x(自变量)的线性函数,
y = w x + b (3.7) y=wx+b \tag{3.7} y=wx+b(3.7)
其中,假定 y y y 的方差是常量。在数据挖掘中, x x x y y y 是数值数据库属性。系数 w w w b b b(回归系数)分别为直线的斜率和 y y y 轴截距。

对数线性模型(log-linear model)近似离散的多维概率分布。给定 n n n 维元组集合,我们可以把每个元组看作 n n n 维空间的点。对于离散属性集,可以使用对数线性模型,基于维组合的一个较小的子集,估计多维空间中每个点的概率。这使得高维数据空间可以有较低维空间构造。

直方图

直方图使用分箱来近似数据分布。如果每个桶指代别单个属性值/频率对,则该桶称为单值桶。通常,同表示给定属性的一个连续区间。

有一些划分规则,包括下面这些:

  • 等宽:在等宽直方图中,每个通道宽度区间是一致的;
  • 等频(或等深):在等频直方图中,每个桶的频率大致相同(即,每个桶呆滞包含相同个数的邻近数据样本)。

对于近似稀疏和稠密数据,以及高倾斜和均匀的数据,直方图都是非常有效的。

聚类

基于相似性将数据集划分为群或簇,并且仅存储聚类表示(例如,质心和直径)。

抽样

使用数据小得多的随机样本(子集)表示大型数据集。

假定大型数据集 D D D 包含 N N N 个元组。常用的抽样方法如下所示:

s s s 个样本的无放回简单随机抽样( SRSWOR \text{SRSWOR} SRSWOR

D D D N N N 个元组中抽取 s s s 个样本( s < N s<N s<N),其中 D D D 中任意元组被抽取的概率均为 1 / N 1/N 1/N,即所有元组的抽取是等可能的。

s s s 个样本的有放回简单随机抽样( SRSWR \text{SRSWR} SRSWR

该方法类似于 SRSWOR \text{SRSWOR} SRSWOR,不同之处在于当一个元组从 D D D 中抽取后,记录它,然后放回原处。

簇抽样

将数据集进行分区,从每个分区中按比例抽取样本;例如,对全年级按照班级抽样。

分层抽样

将数据集按某属性划分为 “层”,对每一层抽样。例如,按照年龄抽样。当数据倾斜时抽样可以具有代表性。

image-20220825152352429

采用抽样进行数据归约的优点:得到样本的花费正比例于样本集的大小 s s s,而不是数据集的大小 N N N。因此,抽样的复杂度可能亚线性(sublinear)于数据的大小。其他数据归约技术至少需哟完全扫描 D D D。对于固定的样本大小,抽样的复杂度仅随数据的维数 n n n 线性得增加;而其他技术,如直方图,复杂度随 n n n 呈指数增长。

数据立方体聚集

3.5 数据变化与数据离散化

数据变换策略概述

  • 光滑(smoothing):去掉数据中的噪声。这类技术如分箱、聚类;
  • 属性构造(特征构造):由给定属性构造新的属性;
  • 聚集:对数据进行汇总或聚集。如聚集月销售量来计算年销售量;
  • 规范化:将数据按比例缩放,使其落入特定区间,如 − 1.0 ∼ 1.0 -1.0\sim 1.0 1.01.0 0.0 ∼ 1.0 0.0\sim 1.0 0.01.0
  • 离散化:将数值的原始值用区间标签代替,如年轻人、中年人、老年人;
  • 由标称数据产生概念分层:属性,如 s t r e e t street street,可以泛化到较高的概念层,如 c i t y city city c o u n t r y country country

通过规范化变换数据

最小-最大规范化

最小-最大规范化对原始数据进行线性变换。假设 m i n A min_A minA m a x A max_A maxA 分别为属性 A A A 的最小值和最大值。最小-最大规范化通过计算
v i ′ = v i − m i n A m a x A − m i n A ( n e w _ m a x A − n e w _ m i n A ) + n e w _ m i n A (3.8) v'_i=\frac{v_i-min_A}{max_A-min_A}(new\_max_A-new\_min_A)+new\_min_A \tag{3.8} vi=maxAminAviminA(new_maxAnew_minA)+new_minA(3.8)
A A A 的值 v i v_i vi 映射到区间 [ n e w _ m i n A , n e w _ m a x A ] [new\_min_A,new\_max_A] [new_minA,new_maxA] 中的 v i ′ v_i^{'} vi

最小-最大规范化保持原始数据之间的联系。如果今后输入实例落在 A A A 的原数据值域之外,则该方法将面临 “越界” 错误。

z z z 分数( z − s c o r e z-score zscore)规范化

或零均值规范化,属性 A ˉ \bar A Aˉ 的值基于 A A A 的均值和标准差规范化。 A A A 的值 v i v_i vi 被规范化为 v i v_i vi,由下式计算:
v i ′ = v i − A ˉ σ A (3.9) v'_i=\frac{v_i-\bar A}{\sigma_A} \tag{3.9} vi=σAviAˉ(3.9)
其中, A ˉ \bar A Aˉ σ A \sigma_A σA 分别是属性 A A A 的均值和标准差。

小数定标

假设 A A A 的取值由 − 986 ∼ 917 -986\sim 917 986917 A A A 的最大绝对值为 986 986 986。因此,为使用小数定标规范化,我们用 1000 1000 1000(即 j = 3 j=3 j=3)除每个值。因此, − 986 -986 986 被规范化为 − 0.986 -0.986 0.986,而 917 917 917 被规范化为 0.917 0.917 0.917

数据离散化

离散化:将连续属性的范围划分为区间,区间的标签可用于替换实际数据值。通过离散化可以减少数据量。

三种可以离散化的属性:

  • 名称,例如名字、颜色;
  • 序数,有序集合中的值,如等级;
  • 数字。
离散化方法
分箱

等宽

  • 将范围划分为 N N N 个长度相等的区间;
  • 如果 A A A B B B 是该属性的最低值和最高值,则区间的宽度将为 W = ( B – A ) / n W =(B–A)/n W=(BA)/n
  • 最简单明了,但异常值可能会导致分区不合理;
  • 不能较好的处理倾斜数据。

等深

  • 将数据分为 N N N 个区间,每个区间包含大约相同数量的样本;
  • 合理的数据划分,但不好处理区间的类别标签。
聚类
  • 将数据按照某一属性 A A A 划分为簇,聚类算法可以用来离散化数值 A A A
  • 遵循自底向上的无监督划分。
决策树
  • 构建决策树进行离散化,见第八章;
  • 自顶向下进行有监督划分。
相关性分析
  • 基于相关性度量(如 χ 2 \chi^2 χ2 系数)进行数据划分;
  • 自底向上的无监督划分。

标称数据的概念分层产生

  • 将地理位置、工作类别和商品类型等属性进行概念分层;
  • 概念层次可以由领域专家和/或数据仓库设计者明确指定;
  • 可以根据数量自动形成概念层次。
image-20220825231827446
  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
数据预处理中的自定义转换是指将数据集中的原始数据按照一定的规则进行处理,以便于后续的模型训练和应用。C++作为一门强类型语言,提供了丰富的数据类型和操作函数,可以非常方便地实现数据预处理中的自定义转换。下面以一个简单的案例来演示如何使用C++实现数据预处理中的自定义转换。 假设我们有一个包含学生信息的数据集,其中每个学生的信息包括姓名、年龄、性别与成绩四个属性。现在我们要对这个数据集进行处理,将每个学生的成绩按照以下规则转换为一个0~5的整数: - 小于60分的成绩转换为0 - 60~69分的成绩转换为1 - 70~79分的成绩转换为2 - 80~89分的成绩转换为3 - 90~99分的成绩转换为4 - 100分的成绩转换为5 下面是一个使用C++实现的解决方案: ```c++ #include <iostream> #include <vector> #include <string> using namespace std; // 定义一个结构体,表示学生信息 struct Student { string name; int age; char gender; int score; }; // 自定义转换函数,将成绩转换为0~5的整数 int score_transform(int score) { if (score < 60) { return 0; } else if (score < 70) { return 1; } else if (score < 80) { return 2; } else if (score < 90) { return 3; } else if (score < 100) { return 4; } else { return 5; } } int main() { // 定义一个学生信息列表 vector<Student> students = { {"张三", 18, 'M', 75}, {"李四", 19, 'F', 68}, {"王五", 20, 'M', 92}, {"赵六", 21, 'F', 85} }; // 遍历学生信息列表,将成绩转换为整数 for (auto& student : students) { student.score = score_transform(student.score); } // 输出转换后的学生信息列表 for (auto& student : students) { cout << student.name << " " << student.age << " " << student.gender << " " << student.score << endl; } return 0; } ``` 在上面的代码中,我们首先定义了一个包含学生信息的结构体`Student`,并且定义了一个自定义转换函数`score_transform`,用于将成绩转换为整数。然后我们定义了一个学生信息列表`students`,并且遍历该列表,将每个学生的成绩按照自定义转换函数进行转换。最后我们输出转换后的学生信息列表。 需要注意的是,在实际应用中,我们可能需要进行更加复杂的自定义转换,例如对数据进行归一化、标准化、降维等处理。C++提供了丰富的函数库和工具,可以帮助我们实现这些复杂的自定义转换。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值