机器学习 | 基本概念与数据预处理和特征工程

文章目录

前言

(1)算法是核心,数据和计算是基础
(2)找准定位。大部分复杂模型的算法设计都是算法工程师在做,而我们需要:分析很多的数据、分析具体的业务、应用常见的算法、特征工程、调参数、优化。

1.学会分析问题,使用机器学习算法的目的,想要算法完成何种任务
2.掌握算法基本思想,学会对问题用相应的算法解决
3.学会利用库或者框架解决问题

一、机器学习的基本概念

X表示特征矩阵,x表示特征

X表示特征张量,深度学习中,标签100%和数据集是分开的

图片[索引,通道数,长,宽]

标签:分类、回归。

监督学习(有标签):从已知的历史数据中进行学习,预测我们渴望了解的东西

无监督学习(无标签):只是告诉算法,这些是数据,你去学学看,告诉我你学到了什么。

半监督学习:强化学习(后续再了解)

模型评价机制(如何判断模型是一个好模型?)

·模型预测效果:线性回归的评估指标之一:SSE
·运算速度:接近或超过人类
·可解释性:向人们解释算法在做什么
·服务于业务:具有商业价值

ground-truth distribution:在有监督学习中,数据是有标注的,以(x, t)的形式出现。其中x是输入数据,t是标注。正确的t标注是ground truth, 错误的标记则不是。

generalization泛化

splitting => train set、test set
train set:训练
val set:调试,修改参数
test set:客户测试

GPU:将军
CPU:皇上

减少过拟合的方法:

更多的数据
控制模型的复杂度:
让模型变得简单
正则化:参数范数接近于0,模型的复杂度就会小。也称weight decay。
Dropout
Data argumentation
Early Stopping
momentum:动量。有个惯性

二、降维

1、模块preprocessing:几乎包含数据预处理的所有内容

(1)模块Impute:填补缺失值专用

(2)模块feature_selection:包含特征选择的各种方法实践

(3)模块deprocessor:包含降维算法

from sklearn.preprocessing import MinMaxScaler
data = [[-1,2],[-0.5,6],[0,10],[1,18]]
import pandas as pd
pd.DataFrame(data)#4行2列
01
0-1.02
1-0.56
20.010
31.018
scaler = MinMaxScaler()#实例化
scaler = scaler.fit(data)#fit在这里的本质是生成min(x),max(x)
result = scaler.transform(data)#通过接口导出结果
result#归一化完毕的矩阵,全部都是【0,1】之间的数据

array([[0. , 0. ],
[0.25, 0.25],
[0.5 , 0.5 ],
[1. , 1. ]])

result_ = scaler.fit_transform(data)#用fit_transform代替fit和transform,使得训练和导出结果一步达成
result_

array([[0. , 0. ],
[0.25, 0.25],
[0.5 , 0.5 ],
[1. , 1. ]])

scaler.inverse_transform(result)#将归一化后的结果逆转

array([[-1. , 2. ],
[-0.5, 6. ],
[ 0. , 10. ],
[ 1. , 18. ]])

#使用MinMaxScalerd的参数feature_range实现将数据归一化到【0,1】以外的范围中
data = [[-1,2],[-0.5,6],[0,10],[1,18]]
scaler = MinMaxScaler(feature_range = [5,10])#实例化,归一化到【5,10】范围内
result = scaler.fit_transform(data)#fit_transform一步导出结果
result

array([[ 5. , 5. ],
[ 6.25, 6.25],
[ 7.5 , 7.5 ],
[10. , 10. ]])

当x中的特征非常多的时候,fit就会报错并表示:数据量太大啦,我计算不了。此时使用partical_fit作为训练接口:scaler = scaler.partial_fit(data)

import numpy as np
X = np.array([[-1,2],[-0.5,6],[0,10],[1,18]])

2、归一化:X - 最小值 / 极差(最大值 - 最小值)

X.min(axis = 0)#按列运算

array([-1., 2.])

X.min(axis = 1)#按行计算

array([-1. , -0.5, 0. , 1. ])

X.max(axis = 0)

array([ 1., 18.])

归一化:

X_nor = (X - X.min(axis = 0))/(X.max(axis = 0)-X.min(axis = 0))
X_nor

array([[0. , 0. ],
[0.25, 0.25],
[0.5 , 0.5 ],
[1. , 1. ]])

逆转为原始数据:

X_returned = X_nor * (X.max(axis = 0) - X.min(axis = 0))+X.min(axis = 0)
X_returned

array([[-1. , 2. ],
[-0.5, 6. ],
[ 0. , 10. ],
[ 1. , 18. ]])

3、标准化即标准正态分布

from sklearn.preprocessing import StandardScaler
data = [[-1,2],[-0.5,6],[0,10],[1,18]]

①fit本质是生成均值和方差

scaler = StandardScaler()#实例化
scaler.fit(data)

StandardScaler()

②查看均值的属性mean_

scaler.mean_

array([-0.125, 9. ])

③查看方差的属性var_

scaler.var_

array([ 0.546875, 35. ])

x_std = scaler.transform(data)#通过接口导出结果
x_std

array([[-1.18321596, -1.18321596],
[-0.50709255, -0.50709255],
[ 0.16903085, 0.16903085],
[ 1.52127766, 1.52127766]])

④用mean()查看均值

x_std.mean()#导出的结果是一个数组

0.0

⑤用std()查看方差

x_std.std()

1.0

scaler.fit_transform(data)#使用fit_transforn(data)一步达成结果
scaler.inverse_transform(x_std)#使用inverse_transform逆转标准化,返回原本数据

array([[-1. , 2. ],
[-0.5, 6. ],
[ 0. , 10. ],
[ 1. , 18. ]])

4、数据预处理常用方法

(1)index_col = 0表示第一列为索引

①.head显示前5行数据

②如果只缺少数条信息,就删掉这些缺失值

③data.info()

④.median() 用中位数进行填补

⑤.dropna(axis = 0)删除所有有缺失值的行 .dropna(axis = 1)删除所有有缺失值的列

⑥参数inplace为True,表示在原数据集上进行修改;为False表示生成一个复制对象,不修改原数据,默认为False。

⑦.classes_查看标签中究竟有多少类别

⑧稀疏矩阵是由0和1构成的矩阵,有很多很多0。对标签做哑变量(onehot编码),在现实中不常见

⑨当有很多特征,很多哑变量时,用.get_feature_names(),运行可以得到特征名称。

⑩pd.concat是pandas里用来“合并两个dataFrame”的功能。若axis=1,表示跨行合并,即将两表左右相连;如果axis=0,表示将两表上下相连

如果要删除某行或某列,可以:data.drop([“要删除的特征名”]),axis=1(对列操作)/axis=0(对行操作)

给列命名,data.column[“”,“”]

.shape (a,b)a表示数据个数,b表示特征个数

模块.类 impute.simpleImputer()

loc[:,a,b]切片 表示从[a,b) 进行切片。
loc[:,a:]表示从a开始切片
loc[:,a]表示取出第a行

三、数据集

Kaggle特点:

1、大数据竞赛平台
2、80万科学家
3、真实数据
4、数据量巨大

UCI特点:

1、收录了360个数据集
2、覆盖科学、生活、经济等领域
3、数据量几十万

scikit-learn特点:

1、数据量小
2、方便学习

四、机器学习算法分类

根据数据标签存在与否的分类

(1)监督学习(Supervised learning)

(包含特征值、目标值)(输入数据有特征有标签,即有标准答案)
分类和回归的界限非常模糊

●分类

k-近邻算法、
贝叶斯分类、
决策树与随机森林、
逻辑回归、
神经网络【分类:目标值离散】【最基础的便是二分类问题,即判断是非,从两个类别中选择一个作为预测结果。】

用于分类的大数据集
●sklearn.datasets.fetch_20newsgroups(data_ home=None,subset=‘train’)
●subset: ‘train’或者’test’all’,可选,选择要加载的数据集.训练集的“训练”,测试集的“测试”,两者的“全部”
●datasets.clear data home(data_ home=None)
●清除目录下的数据

●回归

线性回归、
岭回归【回归:目标值连续】

回归问题在多个领域的广泛应用:
●房价预测,根据某地历史房价数据,进行一个预测
●金融信息,每日股票值
●…
数据来源:1、公司本身就有数据2、合作过来数据3、购买的数据
建立模型:根据数据类型划分应用种类
1、原始数据明确问题做什么
2、数据的基本处理: pd去处理数据(缺失值,合并表……)
3、特征工程(特征进行处理)(重要)(分类、回归)
4、找到合适算法去进行预测
5、模型(模型=算法+数据)的评估,判定效果
若评估合格,则上线使用,以API形式提供。
若评估不合格,则1、换算法参数2、特征工程

●标注隐马尔可夫模型 (不做要求)

支持向量机(support vector machine)、
人工神经网络(neural networks)、
深度神经网络(Deep Neural Networks)

强化学习

经验E是由计算机和环境互动获得的

(1)无监督学习

(包含特征值,不包含目标值)(输入数据有特征无标签,即无标准答案)

●聚类(clustering)k-means
●EM(ExpectationMaximizationalgorithm)
●主成分分析(Principle ComponentAnalysis)

(2)半监督学习(Semi- supervised Learning)

训练数据中一部分有标签,一部分没有标签:少量的标注数据和大量的未标注数据,是更好的机器学习算法

五、API

数据集划分机器学习一般的数据集会划分为两个部分:

训练数据(一般占比75%):用于训练,构建模型
测试数据(一般占比25%):在模型检验时使用,用于评估模型是否有效。

1、数据集划分

sklearn.model_ selection.train_ test_ split

sklearn数据集划分
from sklearn.model_ selection import train_ test_ split

sklearn.datasets.load * ()

●加载获取流行数据集(数据包含在datasets里)。

●sklearn.datasets.fetch_ *(data_ home=None)

获取大规模数据集,需要从网络上下载,函数的第一个参数是data_ home,表示数据集下载的目录。默认是/scikit_ learn_ data/。

sklearn分类数据集,如:加载并返回鸢尾花数据集。
sklearn回归数据集,如:加载并返回波士顿房价/糖尿病数据集。

2、获取数据集返回的类型

●load和fetch返回的数据类型datasets.base.Bunch(字典格式)
●data: 特征数据数组,是[n_ samples * n_features]的二维numpy.ndarray数组
●target: 标签数组,是n_samples的一维numpy.ndarray数组
●DESCR: 数据描述
●feature_ names: 特征名,新闻数据,手写数字、回归数据集没有
●target_ names:标签名

3、数据集进行分割

●sklearn.model_ selection.train_ test_ split( *arrays, **options)
●X数据集的特征值,y数据集的标签值
●test_ size测试集的大小,一般为float
●random_ state:随机数种子,不同的种子会造成不同的随机采样结果。相同的种子采样结果相同。
●return训练集特征值,测试集特征值,训练标签,测试标签(默认随机取)

六、sklearn机器学习算法的实现-估计器

在sklearn中,估计器(estimator)是一个重要的角色,是一类实现了算法的API。

1、调用fitfit(x_train, y_train)
2、y_ predict = predict(x_ test)
3、预测的准确率:score(x_ test, y_ test)

1、用于分类的估计器:

●sklearn.metrics.classification_ report(y_ .true, y_ .pred, target_ names=None)
●y_true: 真实目标值
●y_pred:估计器预测目标值
●target_names: 目标类别名称
●return: 每个类别精确率与召回率

①k-近邻算法

定义:

根据你的“邻居”来推断出你的类别。如果一个样本在特征空间中的k个最相似(即特征空间中最邻近)的样本中的大多数属于某一个类别,则该样本也属于这个类别。

两个样本的距离计算公式,又叫欧氏距离:

a(a1,a2,a3), b(b1,b2,b3)
sqrt[(a1- b1)²+(a2 - b2)²+(a3- b3)²]
相似的样本,特征值之间应该都是相近的。

k值:

K的取值可以为1,2,3……当k值为1时,有一个距离近的邻居;当k值为n时,有n个距离近的邻居。k值取很小时,容易受异常点影响。k值取很大时,邻居越多,容易受K值数量(类别)波动,判断越不准确。

API:

●sklearn.neighbors.KNeighborsClassifier(n_neighbors=5,algorithm=‘auto’)
●n_neighbors: int,可选(默认=5),k_neighbors查询默认使用的邻居数
●algorithm: {‘auto’, ‘ball_ tree’, ‘kd_tree’, ‘brute’}, 可选用于计算最近邻居的算法: 'ball _tree’将会使用BalITree, 'kd_tree’将使用KDTree。'auto’将尝试根据传递给fit方法的值来决定最合适的算法。(不同实现方式影响效率)

数据的处理

1、缩小数据集范围DataFrame.query()
2、处理日期数据pd.to_ datetimepd.DatetimeIndex
3、增加分割的日期数据
4、删除没用的日期数据DataFrame.drop
5、将签到位置少于n个用户的删除
place_ count =data.groupby( 'place_ id").count()
tf=place_count[place_count.row_id>3].reset_index()data=data[data[‘place_ id’]isin(tf.place_id)]

实例流程

1、数据集的处理
2、分割数据集
3、对数据集进行标准化
4、estimator流程进行分类预测

k-近邻算法优缺点

●优点:简单,易于理解,易于实现,无需估计参数,无需训练
●缺点:
(1)懒惰算法,对测试样本分类时的计算量大,内存开销大必须指定K值,K值选择不当则分类精度不能保证。
(2)使用场景:小数据场景,几千~几万样本,具体场景具体业务去测试。

k-近邻算法实现

加快搜索速度——基于算法的改进KDTree,API接口里面有实现。

②朴素贝叶斯

特征独立,计算公式:

在这里插入图片描述
公式分为三个部分:
P©:每个文档类别的概率(某文档类别数/总文档数量)
●P(W|C): 给定类别下特征(被预测文档中出现的词)的概率
计算方法: P(F1|C) = Ni/N (训练文档中去计算)
Ni为该F1词在C类别所有文档中出现的次数
N为所属类别C下的文档所有词出现的次数和
●P(F1,F2,…) 预测文档中每个词的概率

拉普拉斯平滑

如果词频列表里面有很多出现数都为0,很可能计算结果都为零。解决方法:拉普拉斯平滑系数
P(F1|C) =Ni+a
N+am
a为指定的系数,一般为1,m为训练文档中统计出的特征词个数

sklearn朴素贝叶斯实现API

sklearn.naive_ bayes.MultinomialNB
MultinomialNB
sklearn.naive_ bayes.MultinonialNB(alpha= 1.0)
朴素贝叶斯分类
alpha:拉普拉斯平滑系数

朴素贝叶斯案例流程

1、加载20类新闻数据,并进行分割
2、生成文章特征词
3、朴素贝叶斯estimator流程进行预估

训练集误差大,效果肯定不好。不需要调参。

朴素贝叶斯分类优缺点

优点:
●朴素贝叶斯模型发源于古典数学理论,有稳定的分类效率。
●对缺失数据不太敏感,算法也比较简单,常用于文本分类。
●分类准确度高,速度快
缺点:
●由于使用了样本属性独立性的假设,所以如果样本属性有关联时其效果不好。

分类模型的评估

●estimator.score()
●一般最常见使用的是准确率,即预测结果正确的百分比

混淆矩阵
在这里插入图片描述
在这里插入图片描述
其他分类标准,F1-score,反映了模型的稳健型
F1=2TP/(2TP + FN + FP)=2*Precision*Recall/(Precision + Recall)

③sklearn.linear_ model.LogisticRegression逻辑回归

④决策树

认识决策树

决策树思想的来源非常朴素,程序设计中的条件分艾结构就是if- then结构,最早的决策树就是利用这类结构分割数据的一种分类学习方法。信息和消除不确定性是相联系的。

决策树的结构、本地保存

1、sklearn.tree. export_ graphviz() 该函数能够导出DOT格式
tree.export_ .graphviz(estimator,out file=‘tree.dot’,feature_ names=[",'])
2、工具:(能够将dot文件转换为pdf、png)
安装graphviz
ubuntu:sudo apt-get install graphviz
Mac:brew install graphviz
3、运行命令
然后我们运行这个命令
$ dot -Tpng tree.dot -o tree.png

决策树的优缺点以及改进

优点:
●简单的理解和解释,树木可视化。
●需要很少的数据准备,其他技术通常需要数据归一化
缺点:
●决策树学习者可以创建不能很好地推广数据的过于复杂的树,这被称为过拟合。
改进:
● 减枝cart算法(决策树API当中已经实现,随机森林参数调优有相关介绍)随机森林
注:企业重要决策,由于决策树很好的分析能力,在决策过程应用较多。

⑤随机森林

集成学习方法-随机森林
1、什么是随机森林
2、随机森林的过程、优势
3、泰坦尼克号乘客生存分类分析
集成学习方法

集成学习通过建立几个模型组合的来解决单一预测问题。它的工作原理是生成多个分类器/模型,各自独立地学习和作出预测。这些预测最后结合成单预测,因此优于任何一个单分类的做出预测。

什么是随机森林

定义:在机器学习中,随机森林是一个包含多个决策树的分类器,并且其输出的类别是由个别树输出的类别的众数而定。
例如,如果你训练了5个树,其中有4个树的结果是True, 1个数的结果是False,那么最终结果会是True。即,通过投票决定。

为什么要随机抽样训练集?

如果不进行随机抽样,每棵树的训练集都一样,那么最终训练出的树分类结果也是完全一样的。

为什么要有放回地抽样?

如果不是有放回的抽样,那么每棵树的训练样本都是不同的,都是没有交集的,这样每棵树都是“有偏的”,都是绝对“片面的”(当然这样说可能不对),也就是说每棵树训练出来都是有很大的差异的;而随机森林最后分类取决于多棵树(弱分类器)的投票表决。

随机森林API

●class sklearn.ensemble.RandomForestClassifier(n_estimators=10,criterion=‘gini’,max_ depth=None, bootstrap= True, random_ state=None)
●随机森林分类器
●n_ estimators: integer, optional (default= 10)森林里的树木数量120,200,300,500,800,1200
●criteria: string,可选(default =“ini”) 分割特征的测量方法
●max_ depth: integer或None,可选(默认=无)树的最大深度5,8,15,25,30
●max_features="auto”,每个决策树的最大特征数量
●-If “auto”, then imax_ features =sqrt(n_ features).
-If “sqrt”, then imax_ features =sqrt(n features)’ (same as “auto”)
-If “Ilog2”, then ‘max_ features=log2(n_ features).
-If None, then imax_ features=n_ features’.
●bootstrap: boolean, optional (default = True) 是否在构建树时使用放回抽样

随机森林的优点

●在当前所有算法中,具有极好的准确率
●能够有效地运行在大数据集上
●能够处理具有高维特征的输入样本,而且不需要降维
●能够评估各个特征在分类问题上的重要性

随机森林建立多个决策树的过程(N个样本,M个特征)

单个树建立过程:
1、随机在N个样本当中选择一个样本,重复N次,样本有可能重复。
2、随机在M个特征当中选出m个特征。m取值

2、用于回归的估计器:

①sklearn.linearmodel.LinearRegression线性回归

出散点图
线性关系模型

一个通过属性的线性组合来进行预测的函数:
f(x)= W1X1 + W2X2 +…+ WdXd + b
W为权重,b称为偏置项

线性回归

定义:线性回归通过一个或者多个自变量与因变量之间之间进行建模的回归分析。其中可以为一个或多个自变量之间的的线性组合(线性回归的一种)
一元线性回归:涉及到的变量只有一个
多元线性回归:涉及到的变量两个或两个以上
通用公式: h(w)= Wo+ W1x1 + WzX2 +…=WTx
其中w,x为矩阵: w=(w0,w1,w2),X=(1,x1,x2)
用小写字母表示向量,大写字母表示矩阵。
no.dot(a,b)两个矩阵相乘

预测结果与真实值有一定的误差。
算法是优化过程,是一个不断的迭代过程。迭代过程就是去寻找最优的W

loss function损失函数(误差大小)

●yi为第i个训练样本的真实值
●hw(xi)为第i个训练样本特征值组合预测函数
总损失定义:
f(θ)= (hw(x1) -y1)2 + (hw(x2) - y2)2 +…+ (hw(xm) - Ym)2= ∑mi=1(hw(xi) - yi)2又称最小二乘法
LossFunction:input:afunction;output:howbaditis。y=b+w*xcp,所以L(f)=L(b,w),所以LossFunction是衡量参数的好坏。

尽量去减少这个损失( 两种方式)
最小二乘法之正规方程(不做要求)

求解: w=(xTx)-1xTy
[octave:pinv(x’*x)*x’*y]
X为特征值矩阵,y为目标值矩阵
缺点:当特征过于复杂,求解速度太慢

梯度下降
如何找到function?答:梯度下降(Gradient descent).
只有一个变量θ1时,代价函数是一个碗状的二次函数图案。如果有两个变量θ0和θ1,则代价函数是四个角的碗状函数,如下图蓝色图片所示。

最小二乘法之梯度下降(理解过程):我们以单变量中的w0,w1为例子。

梯度下降法(面对训练数据规模十分庞大的任务)让机器自动学习,找到使代价函数最小时θ0和θ1的值。想象我们站在山顶,现在想要下山。我们环顾四周,选择一个合适的方向下山,每走一步,再次环顾四周,寻找下一步该往哪里走。我们迈的步子的大小,下降的快慢,就是学习率α。我们所走的方向,对应一个局部最优解。因为我们在环顾时,很有可能一步偏差就会走一条完全不同的路,所以会有多个局部最优解。当切线斜率是正(positive)时,increase w,else decrease w。这样不断更新W值,找到最小损失对应的W值,使损失最小。
最初用一次函数来拟合训练样本,发现存在误差。误差计算方式为:(1/(2m))∑m(训练样本-直线拟合值)²。所以我们用二次函数来拟合。下图直观地展现了随着w的更新,误差逐渐减小的过程。

我们可能会担心由于起始位置不同,随着梯度下降算法到达的最优点不是一个地方。不用担心。因为由等高线图我们可以看出,无论从哪个方向下降,尽管不在一个位置,但都是位于同一条等高线上,都是最优解。也就是没有全局最优解,只有局部最优解。接下来再用三次函数、四次函数……结果并没有随着参数的增加而优化,出现了overfitting。第二个图是计算偏微分的过程。

所以参数也不是越多越好。对overfitting的理解:你去驾校学车,你记住了很多应试小技巧,比如当后视镜能看到路边的皮卡丘时,就方向盘左转半圈……这样你驾照考试考的很好(训练样本错误率低),但是你真正上路时并不是很会开车(测试结果糟糕)。

②sklearn.linearmodel.Ridge岭回归

七、模型的选择与调优

1、交叉验证(CV):为了让被评估的模型更加准确可信

GridSearchCV

●sklearn.model_ selection.GridSearchCV(estimator, param_ grid=None,cv=None)
●对估计器的指定参数值进行详尽搜索
●estimator:估计器对象
●param_ grid: 估计器参数(dict){“n_ neighbors”:[1,3,5]}
●cv:指定几折交叉验证
●fit: 输入训练数据
●score: 准确率
●结果分析:
●best_score_:在交叉验证中验证的最好结果
●best_ estimator_ :最好的参数模型
●cv_results_:每次交叉验证后的测试集准确率结果和训练集准确率结果

K-近邻网格搜索案例

将前面的k-近邻算法案例改成网格搜索

2、超参数搜索-网格搜索

通常情况下,有很多参数是需要手动指定的(如k-近邻算法中的K值),这种叫 超参数。但是手动过程繁杂,所以需要对模型预设几种超参数组合。每组超参数都采用交叉验证来进行评估。最后选出最优参数组合建立模型。
K值 K=3 K=5 K=7
模型模型1 模型2 模型3
超参数搜索-网格搜索API
●sklearn.modelselection.GridSearchCV


jieba分词

下载:pip3 install jieba
使用:import jieba

….jieba.cut(“我是一个好程序员”)

返回值:词语生成器
对于单个英文字母不提取,因为单个字母对于分类没有帮助。
文本分类、情感分析
文本特征抽取: Count、tf *idf(表示重要性)

Tf :term frequency:词的频率,出现的次数
idf:逆文档频率inverse document frequency log(总文档数量/该词出现的文档数量)
TF-IDF的主要思想是:如果某个词或短语在一篇文章中出现的概率高,并且在其他文章中很少出现,则认为此词或者短语具有很好的类别区分能力,适合用来分类。
TF-IDF作用:用以评估一字词对于一个文件集或一个语料库中的其中一份文件的重要程度。
类: sklearn.feature_ extraction.text.TfidfVectorizer

特征工程的步骤?
1、实例化(实例化的是一个转换器类(Transformer))
2、调用fit_transform(对于文档建立分类词频矩阵,不能同时调用)
数据集→转换后的数据集【fit_transform(X)】
fit_transform():输入数据直接转换
fit():输入数据,计算平均值,方差等等,不做转换
transform():进行数据的转换
fit_transform()=fit()+transform()

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值