机器学习西瓜书 学习笔记(二)— 模型评估与选择

经验误差与过拟合

【错误率】E = a m \frac{a}{m} ma ( m: 样本总数 - a: 分类错误的样本数 )
【误差】学习器的实际预测输出与样本的真是输出之间的差异
【训练误差 / 经验误差】学习器在训练集上的误差
【泛化误差】学习器在新样本上的误差
【欠拟合】【过拟合】( ∵ \because P != NP ∴ \therefore 过拟合不可避免)


评估方法(实验估计)

1. 留出法 hold-out / 验证集法 validation set approach
直接将数据集D划分成两个互斥的集合S(训练集)和T(测试集)
* 要保持数据分布的一致性(分层采样)
* 在给定S和T的比例后,不同划分方法结果不同,返回n次随机划分结果的平均值
* S集的比例约 2 3 \frac23 32~ 4 5 \frac45 54
* S大T小时,评估结果方差较大;S小T大时,评估结果偏差较大
* 优:简单,易于实现;缺:每次随机产生的MSE变化大;且只用到了部分数据

# hold out / validation set approach #

library(ISLR) 
# the package for the dataset Auto

set.seed(1)
train=sample(392,196) 
# select a random training set of 196 observations out of the original 392 observations. 

attach(Auto)
# linear regression
lm.fit=lm(mpg~horsepower,data=Auto,subset=train) 
mean((mpg-predict(lm.fit,Auto))[-train]^2) 
# calculate MSE
# the -train index selects only the observations that are not in the training set

# quadratic regression
lm.fit2=lm(mpg~poly(horsepower,2),data=Auto,subset=train)
mean((mpg-predict(lm.fit2,Auto))[-train]^2)

# cubic regression
lm.fit3=lm(mpg~poly(horsepower,3),data=Auto,subset=train)
mean((mpg-predict(lm.fit3,Auto))[-train]^2)

2. 交叉验证法 cross validation (CV)(p次k折交叉验证)
先将数据集D划分为k个大小相似的互斥子集D1, D2, …, Dk, 然后每次用k-1个子集的并集作为训练集,余下的那个子集作为测试集,从而进行k次测试
* 要保持每个子集数据分布的一致性(分层采样)
* k通常为5、10或20
* 在给定k值后,不同划分方法结果不同,返回p次随机划分结果的平均值

# k-fold cross validation #

library(boot)
# the package for the function cv.glm

set.seed(1)
cv.error.10=rep(0,5)
for(i in 1:5){
  glm.fit=glm(mpg~poly(horsepower,i),data=Auto)
  cv.error.10[i]=cv.glm(Auto,glm.fit,K =10)$delta[1] 
}
# k=10 for k-fold CV
cv.error.10

-留一法 LOOCV(m次m折交叉验证)
m个样本用唯一的方式划分为m个子集,每个子集1个样本
* 优:评估结果较为准确(偏差很小);但计算开销大,且方差比 k - fold CV 大

# LOOCV #

library(boot)

# linear regression
glm.fit=glm(mpg~horsepower,data=Auto) 
cv.err=cv.glm(Auto,glm.fit)
cv.err$delta

# the errors of linear and higher-order polynomial regression
cv.error=rep(0,5)
for(i in 1:5){
  glm.fit=glm(mpg~poly(horsepower,i),data=Auto)
  cv.error[i]=cv.glm(Auto,glm.fit)$delta[1]
}
cv.error

3. 自助法 bootstrapping
【自助采样法】给定包含m个样本的数据集D,每次随机从D 中挑选一个样本,将其拷贝放入D’,然后再将该样本放回初始数据集D中,使得该样本在下次采样时仍有可能被采到。重复执行m 次,就可以得到包含m个样本的数据集D’。可以得知在m次采样中,样本始终不被采到的概率取极限为: lim ⁡ m → ∞ ( 1 − 1 m ) m → 1 e ≈ 0.368 \lim_{m\to\infty}{(1-\frac1m)^m}\to\frac1e\approx0.368 limm(1m1)me10.368。通过自助采样,初始样本集D中大约有36.8%的样本没有出现在D’中,于是可以将D’作为训练集,D\D’作为测试集。测试结果称为【外包估计(out-of bag estimate)】
* 适用于测试集小,难以有效划分测试集和训练集的情况(特别是集成学习)
* 但改变了初始数据集的分布,会引入估计偏差(数据量足够时,不常用该方法)

# bootstrapping #
library(boot)

# Estimating the Accuracy of a Statistic of Interest 
# create a function that computes the statistic of interest
alpha.fn=function(data,index){
  X=data$X[index]
  Y=data$Y[index]
  return((var(Y)-cov(X,Y))/(var(X)+var(Y)-2*cov(X,Y)))
}
# use the boot() function to perform the bootstrap by repeatedly sampling observations from the dataset with replacement
boot(Portfolio,alpha.fn,R=1000)

# Estimating the Accuracy of a Linear Regression Model 
boot.fn=function(data,index)
  return(coef(lm(mpg~horsepower,data=data,subset=index)))
boot.fn(Auto,1:392)
boot(Auto,boot.fn,1000)

4. 调参 parameter tuning
ML中的参数类型:①算法的参数(超参数),数目在10以内,由人工设定多个参数候选值后产生模型 ②模型的参数,数目很多,通过学习来产生多个候选模型(深度学习)


性能度量(评价标准)

回归任务

  • 均方误差MSE E ( f ; D ) = 1 m ∑ i = 1 m ( f ( x i ) − y i ) 2 o r E ( f ; D ) = ∫ x ∼ D ( f ( x ) − y ) 2 p ( x ) d x \qquad E(f;D)=\frac1m\sum_{i=1}^{m}(f(\bm{x_i})-y_i)^2 \quad or \quad E(f;\mathcal{D})=\int_{x \sim \mathcal{D}}(f(\bm{x})-y)^2 \mathcal{p}(\bm{x})d\bm{x} E(f;D)=m1i=1m(f(xi)yi)2orE(f;D)=xD(f(x)y)2p(x)dx

分类任务
性能度量

  • 错误率 (error) E ( f ; D ) = 1 m ∑ i = 1 m I ( f ( x i ) ≠ y i ) o r E ( f ; D ) = ∫ x ∼ D I ( f ( x ) ≠ y ) p ( x ) d x E(f;D)=\frac1m \sum_{i=1}^{m}\mathbb{I}(f(\bm{x_i}) \ne y_i)\quad or \quad E(f;\mathcal{D})=\int_{x \sim \mathcal{D}}\mathbb{I}(f(\bm{x})\ne y) \mathcal{p}(\bm{x})d\bm{x} E(f;D)=m1i=1mI(f(xi)=yi)orE(f;D)=xDI(f(x)=y)p(x)dx
  • 精度 (accuracy) a c c ( f ; D ) = 1 m ∑ i = 1 m I ( f ( x i ) = y i ) = 1 − E ( f ; D ) o r E ( f ; D ) = ∫ x ∼ D I ( f ( x ) = y ) p ( x ) d x = 1 − E ( f ; D ) acc(f;D)=\frac1m \sum_{i=1}^{m}\mathbb{I}(f(\bm{x_i}) = y_i)=1-E(f;D) \quad or \quad E(f;\mathcal{D})=\int_{x \sim \mathcal{D}}\mathbb{I}(f(\bm{x})= y) \mathcal{p}(\bm{x})d\bm{x}=1-E(f;\mathcal{D}) acc(f;D)=m1i=1mI(f(xi)=yi)=1E(f;D)orE(f;D)=xDI(f(x)=y)p(x)dx=1E(f;D)
    二分类问题分类结果的混淆矩阵
  • 查准率/准确率 (presicion) P = T P T P + F P P=\frac{TP}{TP+FP} P=TP+FPTP
  • 查全率/召回率 (recall) R = T P T P + F N R=\frac{TP}{TP+FN} R=TP+FNTP
  • 真正例率(true positive rate) ( T P R = R ) \quad(TPR=R) (TPR=R) T P R = T P T P + F N TPR=\frac{TP}{TP+FN} TPR=TP+FNTP
  • 假正例率(false positive rate) F P R = F P T N + F P FPR=\frac{FP}{TN+FP} FPR=TN+FPFP
  • F1 度量 (查准率和查全率的调和平均) F 1 = 2 ⋅ P ⋅ R P + R = 2 ⋅ T P 样 例 总 数 + T P − T N [ 1 F 1 = 1 2 ⋅ ( 1 P + 1 R ) ] F_1 = \frac{\small2·P·R}{\small P+R}=\frac{\small2·TP}{\small样例总数+TP-TN}\qquad[\frac1{F_1}=\frac12·(\frac1P+\frac1R)] F1=P+R2PR=+TPTN2TP[F11=21(P1+R1)]
  • F β \tiny\beta β 度量 (查准率和查全率的加权调和平均) F β = ( 1 + β 2 ) ⋅ P ⋅ R β 2 ⋅ P + R [ 1 F β = 1 1 + β 2 ⋅ ( 1 P + β 2 R ) ] F_\beta= \frac{\small(1+\beta^2)·P·R}{\small \beta^2·P+R}\qquad[\frac1{F_\beta}=\frac1{1+{\beta}^2}·(\frac1P+\frac{\beta^2}R)] Fβ=β2P+R(1+β2)PR[Fβ1=1+β21(P1+Rβ2)]

在n个二分类混淆矩阵上综合考察查准率和查全率

  • 宏查准率 & 宏查全率 & 宏F1 :先在各混淆矩阵上计算Pi和Ri,再计算平均值 m a c r o P = 1 n ∑ i = 1 n P i & m a c r o R = 1 n ∑ i = 1 n R i & m a c r o F 1 = 2 ⋅ m a c r o P ⋅ m a c r o R m a c r o P + m a c r o R macroP=\frac1n\sum_{i=1}^nP_i \quad \& \quad macroR=\frac1n\sum_{i=1}^nR_i \quad \& \quad macroF_1 = \frac{\small2·macroP·macroR}{\small macroP+macroR} macroP=n1i=1nPi&macroR=n1i=1nRi&macroF1=macroP+macroR2macroPmacroR
  • 微查准率 & 微查全率 & 宏F1 :先将各混淆矩阵的对应元素平均,再基于这些平均值计算 m i c r o P = T P ‾ T P ‾ + F P ‾ & m i c r o R = T P ‾ T P ‾ + F N ‾ & m i c r o F 1 = 2 ⋅ m i c r o P ⋅ m i c r o R m i c r o P + m i c r o R microP=\frac{\overline{TP}}{\overline{TP}+\overline{FP}} \quad \& \quad microR=\frac{\overline{TP}}{\overline{TP}+\overline{FN}} \quad \& \quad microF_1 = \frac{\small2·microP·microR}{\small microP+microR} microP=TP+FPTP&microR=TP+FNTP&microF1=microP+microR2microPmicroR

性能曲线

  • P-R曲线:一般而言,查准率和查全率反向变化
    • BEP平衡点 (break-even point):查准率 = 查全率
  • ROC曲线 (受试者工作特征 receiver operating characteristic)
    • 分类阈值 (threshold) / 截断点 (cut point):将样本分为两部分,前一部分判作正例,后一部分判作反例 (看重查准率,截断点靠前;看重查全率,截断点靠后)
    • AUC (area under ROC curve) :ROC曲线下方的面积 - 样本预测的排序质量 A U C ≈ 1 2 ∑ i = 1 m − 1 ( x i + 1 − x i ) ⋅ ( y i + y i + 1 ) \quad AUC\approx \frac12\sum_{i=1}^{m-1}(x_{i+1}-x_i)·(y_i+y_{i+1}) AUC21i=1m1(xi+1xi)(yi+yi+1)
    • 排序损失:ROC曲线上方的面积 ( A U C = 1 − l r a n k AUC=1-l_{rank} AUC=1lrank l r a n k = 1 m + m − ∑ x + ∈ D + ∑ x − ∈ D − ( I ( f ( x + ) < f ( x − ) ) + 1 2 ( I ( f ( x + ) = f ( x − ) ) l_{rank}=\frac1{m^+m^-}\sum_{\bm{x^+}\in D^+}\sum_{\bm{x^-}\in D^-}(\mathbb{I(f(\bm{x^+}})<f(\bm{x^-}))+\frac12(\mathbb{I(f(\bm{x^+}})=f(\bm{x^-})) lrank=m+m1x+D+xD(I(f(x+)<f(x))+21(I(f(x+)=f(x))

非均等代价 (unequal cost - 不同类型错误造成不同损失) 情况下的性能度量

  • 代价矩阵 (cost matrix)
    costij : 将第 i 类样本预测为第 j 类样本的代价(一般 costii = 0)
    重要的是代价比值而不是绝对值
  • 代价敏感错误率 (cost-sensitive error rate) (二分类为例)
    E ( f ; D ; c o s t ) = 1 m ( ∑ x i ∈ D + I ( f ( x i ) ≠ y i ) × c o s t 01 + ∑ x i ∈ D − I ( f ( x i ) ≠ y i ) × c o s t 10 ) E(f;D;cost)=\frac1m(\sum_{\bm{x_i}\in D^+}\mathbb{I}(f(\bm{x_i})\ne y_i)\times cost_{01}+\sum_{\bm{x_i}\in D^-}\mathbb{I}(f(\bm{x_i})\ne y_i)\times cost_{10}) E(f;D;cost)=m1(xiD+I(f(xi)=yi)×cost01+xiDI(f(xi)=yi)×cost10)
  • 代价曲线 (cost curve)
    • 横轴:正例概率代价 (其中 p p p为样例为正例的概率) P ( + ) c o s t = p × c o s t 01 p × c o s t 01 + ( 1 − p ) × c o s t 10 P(+)cost=\frac{p\times cost_{01}}{p\times cost_{01}+(1-p)\times cost_{10}} P(+)cost=p×cost01+(1p)×cost10p×cost01
    • 纵轴:归一化代价 c o s t n o r m = F N R × p × c o s t 01 + F P R × ( 1 − p ) × c o s t 10 p × c o s t 01 + ( 1 − p ) × c o s t 10 cost_{norm}=\frac{FNR\times p\times cost_{01}+FPR\times (1-p)\times cost_{10}}{p\times cost_{01}+(1-p)\times cost_{10}} costnorm=p×cost01+(1p)×cost10FNR×p×cost01+FPR×(1p)×cost10在非均等代价下,ROC曲线不能直接反映出学习器的期望总体代价,而代价曲线可以
      ROC曲线上的每一点对应了代价平面上的一条线段,由此计算期望总体代价

比较检验

假设检验 - 检验单个算法

  • 二项检验:一次留出法估计 - 泛化错误率为 ϵ \epsilon ϵ 的学习器被测得测试错误率为 ϵ ^ \hat\epsilon ϵ^ 的概率:
    P ( ϵ ; ϵ ^ ) = ( m ϵ ^ × m ) ϵ ϵ ^ × m ( 1 − ϵ ) m − ϵ ^ × m ∼ B i n o m i a l ( m , ϵ ) P(\epsilon;\hat\epsilon)= \begin{pmatrix} {m} \\ { \hat\epsilon \times m} \end{pmatrix} \epsilon^{\hat\epsilon \times m(1-\epsilon)^{m-\hat\epsilon \times m}} \sim Binomial(m,\epsilon) P(ϵ;ϵ^)=(mϵ^×m)ϵϵ^×m(1ϵ)mϵ^×mBinomial(m,ϵ) 临界值 ϵ ˉ = max ⁡ ϵ s.t. ∑ i = ϵ 0 × m + 1 m ( m i ) ϵ i ( 1 − ϵ ) m − i < α \bar\epsilon=\max \epsilon \quad \text{s.t.} \quad \sum_{i=\epsilon_0 \times m +1}^{m}\begin{pmatrix}{m}\\{i}\end{pmatrix}\epsilon^i(1-\epsilon)^{m-i} < \alpha ϵˉ=maxϵs.t.i=ϵ0×m+1m(mi)ϵi(1ϵ)mi<α检验过程略

  • t 检验:多次重复留出法 / 交叉验证法 - 得到 k 个测试错误率
    μ = 1 k ∑ i = 1 k ϵ ^ i {\mu = \frac1k\sum_{i=1}^k\hat\epsilon_i } μ=k1i=1kϵ^i σ 2 = 1 k − 1 ∑ i = 1 k ( ϵ ^ i − μ ) 2 {\sigma^2=\frac1{k-1}\sum_{i=1}^k(\hat \epsilon _i-\mu)^2} σ2=k11i=1k(ϵ^iμ)2 τ t = k ( μ − ϵ 0 ) σ ∼ t ( k − 1 ) \tau_t=\frac{\sqrt k(\mu -\epsilon_0)}\sigma \sim t (k-1) τt=σk (μϵ0)t(k1)

交叉验证 t 检验 - k 折交叉验证成对 t 检验 (paired t-tests) - 检验两个算法
-假设:学习器A与B性能相同
-前提:测试错误率均为泛化错误率的独立采样(但实际上会有一定重叠,不完全独立)
-先对每对结果求差,计算出差值的均值和方差
Δ i = ϵ i A − ϵ i B μ = 1 k ∑ i = 1 k Δ i σ 2 = 1 k − 1 ∑ i = 1 k ( Δ i − μ ) 2 \Delta_i=\epsilon_i^A-\epsilon_i^B\qquad {\mu = \frac1k\sum_{i=1}^k\Delta_i } \qquad{\sigma^2=\frac1{k-1}\sum_{i=1}^k(\Delta_i-\mu)^2} Δi=ϵiAϵiBμ=k1i=1kΔiσ2=k11i=1k(Δiμ)2 τ t = ∣ k μ σ ∣ ∼ t ( k − 1 ) \tau_t =\begin{vmatrix}{\frac{\sqrt{k}\mu}\sigma}\end{vmatrix} \sim t(k-1) τt=σk μt(k1)

  • 5 x 2 交叉验证 (5次2折交叉验证)
    -在每次 2 折交叉验证之前随机将数据打乱,使得 5 次交叉验证中的数据划分不重复
    -为缓解测试错误率的非独立性,改变均值和方差的计算方法
    • 第 i 次第 j 折上产生的两对测试错误率的差值
      Δ i j = ϵ i j A − ϵ i j B ( i ∈ { 1 , 2 , 3 , 4 , 5 } , j ∈ { 1 , 2 } ) \Delta_i^j=\epsilon_i^{jA}-\epsilon_i^{jB} \qquad (i\in\{1,2,3,4,5\},j\in\{1,2\}) Δij=ϵijAϵijB(i{1,2,3,4,5},j{1,2})
    • 均值、方差
      μ = 1 2 ( Δ 1 1 + Δ 1 2 ) σ i 2 = ( Δ i 1 − Δ i 1 + Δ i 2 2 ) 2 + ( Δ i 2 − Δ i 1 + Δ i 2 2 ) 2 \mu=\frac12(\Delta_1^1+\Delta_1^2) \qquad \sigma_i^2=(\Delta_i^1-\frac{\Delta_i^1+\Delta_i^2}2)^2+(\Delta_i^2-\frac{\Delta_i^1+\Delta_i^2}2)^2 μ=21(Δ11+Δ12)σi2=(Δi12Δi1+Δi2)2+(Δi22Δi1+Δi2)2
    • 检验量 τ t = ∣ 5 μ ∑ i = 1 5 σ i 2 ∣ ∼ t ( 5 ) \tau_t =\begin{vmatrix}{\frac{\sqrt{5}\mu}{\sqrt {\sum_{i=1}^5\sigma_i^2}}}\end{vmatrix} \sim t(5) τt=i=15σi2 5 μt(5)

McNemar检验 - 留出法检验 - 检验两个算法
-假设:学习器A与B性能相同 - e 01 = e 10 e_{01} = e_{10} e01=e10
-两学习器分类差别列联表 (contingency table): e 00 e_{00} e00: 算法A、B都正确 / e 01 e_{01} e01: 算法B正确,A错误 / e 10 e_{10} e10: 算法A正确,B错误 / e 00 e_{00} e00: 算法A、B都错误
( e 01 + e 10 e_{01} + e_{10} e01+e10通常很小,考虑连续性校正,检验量的分子中有 -1 项 )
∣ e 01 − e 10 ∣ ∼ N τ χ 2 = ( ∣ e 01 − e 10 ∣ − 1 ) 2 e 01 + e 10 ∼ χ 2 ( 1 ) |e_{01} - e_{10}| \sim N \qquad \tau_{\chi^2}=\frac{(|e_{01} - e_{10}|-1)^2}{e_{01} + e_{10}} \sim \chi^2(1) e01e10Nτχ2=e01+e10(e01e101)2χ2(1)

Friedman检验和Nemenyi后续检验- 检验多个算法

  • 利用上述检验过程在 N 数据集上分别对 k 个算法进行两两比较
  • 基于算法排序的 Friedman 检验
    • 算法比较序值表 → \to 平均序值
    • r i r_i ri : 第 i 个算法的平均序值(不考虑平分序值的情况)
    • r i r_i ri 的均值、方差
      μ = k + 1 2 σ 2 = k 2 − 1 12 N \mu = \frac{k+1}{2} \qquad \sigma^2 = \frac{k^2-1}{12N} μ=2k+1σ2=12Nk21
    • 原始 χ 2 \chi^2 χ2检验量 (要求 k 和 N 都较大)
      τ χ 2 = k − 1 k ⋅ 1 σ 2 ∑ i = 1 k ( r i − μ ) 2 = 12 N k ( k + 1 ) ( ∑ i = 1 k r i 2 − k ( k + 1 ) 2 4 ) ∼ χ 2 ( k − 1 ) \tau_{\chi^2}=\frac{k-1}{k}·\frac1{\sigma^2}\sum_{i = 1}^k(r_i-\mu)^2=\frac{12N}{k(k+1)}(\sum_{i=1}^kr_i^2-\frac{k(k+1)^2}4) \sim \chi^2(k-1) τχ2=kk1σ21i=1k(riμ)2=k(k+1)12N(i=1kri24k(k+1)2)χ2(k1)
    • 改进后的F检验量
      τ F = ( N − 1 ) τ χ 2 N ( k − 1 ) − τ χ 2 ∼ F ( k − 1 , ( k − 1 ) ( N − 1 ) ) \tau_{F}=\frac{(N-1)\tau_{\chi^2}}{N(k-1)-\tau_{\chi^2}} \sim F(k-1,(k-1)(N-1)) τF=N(k1)τχ2(N1)τχ2F(k1,(k1)(N1))
  • Nemenyi 后续检验 (post-hoc test) - 进一步区分各算法
    • 前提:“所有算法的性能相同”这个假设被拒绝,即算法的性能显著不同
    • 平均序值差别的临界值域 ( q α q_\alpha qα值见 P43 表 2.7)
      C D = q α k ( k + 1 ) 6 N CD=q_\alpha \sqrt \frac{k(k+1)}{6N} CD=qα6Nk(k+1)
  • Friedman检验图:若两个算法的横线段有交叠,则没有显著差别,否则有。
    如下图,算法A、B无显著差别,但算法A显著优于算法C

偏差和方差

【偏差-方差分解 (decomposition)】 对学习算法的期望泛化错误率进行拆解
【偏差-方差窘境 (dilemma)】 偏差方差反向变化,训练不足时偏差大方差小 (欠拟合);训练充足时偏差小方差大 (过拟合)

  • 期望预测 (以回归任务为例): f ˉ ( x ) = E D [ f ( x ; D ) ] \bar f (\bm x)=\mathbb E_D[f(\bm x;D)] fˉ(x)=ED[f(x;D)]
  • 偏差 (bias):学习算法的期望预测与真实结果的偏离程度(学习算法本身的拟合能力) b i a s 2 ( x ) = ( f ˉ ( x ) − y ) 2 bias^2(\bm x)=(\bar f (\bm x)-y)^2 bias2(x)=(fˉ(x)y)2
  • 方差 (variance):同样大小的训练集的变动所导致的学习性能的变化(数据扰动所造成的影响) v a r ( x ) = E D [ ( f ( x ; D ) − f ˉ ( x ) ) 2 ] var (\bm x)=\mathbb E_D[(f(\bm x;D)-\bar f (\bm x))^2] var(x)=ED[(f(x;D)fˉ(x))2]
  • 噪声 (noise):当前任务上任何学习算法所能达到的期望泛化误差的下界(学习问题本身的难度) ε 2 = E D [ ( y D − y ) 2 ] \varepsilon^2=\mathbb E_D[(y_D-y)^2] ε2=ED[(yDy)2]
    一般假定噪声期望为0,即 E D [ y D − y ] = 0 \mathbb E_D[y_D-y]=0 ED[yDy]=0
  • 期望泛化误差 - 分解成偏差、方差、噪声之和 - 数学证明 E ( f ; D ) = b i a s 2 ( x ) + v a r ( x ) + ε 2 E(f;D)=bias^2(\bm x)+var(\bm x)+\varepsilon^2 E(f;D)=bias2(x)+var(x)+ε2
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值