机器学习常用算法归详细纳整理


作者:进击的西西弗斯
本文链接:https://blog.csdn.net/qq_42216093/article/details/116434557
版权声明:本文为作者原创文章,未经作者同意禁止转载或盗用



(没写完,持续更新中)



文章目录



一、机器学习及其算法分类


在这里插入图片描述


高清原图链接:https://img-blog.csdnimg.cn/20210505230045263.png


1.介绍

机器学习(Machine Learning) 是实现人工智能(Artificial Intelligence,AI) 的一个重要途径途径。机器学习主要是设计和分析一些让计算机可以自动“学习”的算法,它是一类从数据中自动分析获得规律,并利用规律对未知数据进行预测的算法。在近30多年已发展为一门多领域交叉学科,涉及概率论、统计学、逼近论、凸分析、计算复杂性理论等多门学科。



2.算法分类

1).监督学习(Supervised Learning)

监督学习是从有结果标签的样本数据中学习、训练、构建出一个预测模型,使其有能力对新的样本数据进行结果预测,预测的准确率越高,模型越良好。即:给定数据学习,预测新数据的结果。

主要算法类型:
(1).回归
(2).分类

特点:
(1).目标明确
(2).需要带标签的训练数据
(3).效果容易评估


2).无监督学习(Unsupervised Learning)

无监督学习是一种从无结果标签的样本数据中发掘其潜在的信息和结构的一种算法。即:给定数据,寻找隐藏的信息和结构

主要算法类型:
(1).降维
(2).聚类

特点:
(1).没有一个准确的目标
(2).不需要给数据打标签
(3).不易量化效果


3).半监督学习(Semi-supervised Learning)

半监督学习属于无监督学习和监督学习之间


4).强化学习(Reinforcement Learning)

机器为了达成目标,随着环境的变动,而逐步调整其行为,并评估每一个行动之后所到的回馈是正向的或负向的。



3.应用领域

机器学习已广泛应用于数据挖掘、机器视觉、自然语言处理、生物特征识别、搜索引擎、医学诊断、检测信用卡欺诈、证券市场分析、DNA序列测序、语音和手写识别、战略游戏和机器人等领域。




二、监督学习常用算法


1.线性回归(Linear Regression)


1).介绍

线性回归是机器学习中最基础、最常用的算法之一。它利用线性函数对一个或多个自变量和因变量之间关系进行建模。建模过程就是使用数据点来寻找最佳拟合线。线性回归分为两种类型:单变量线性回归(Linear Regression with One Variable),一个自变量和一个结果变量,能在二维平面可视化;和 多变量线性回归(Linear Regression with Multiple Variables),至少两组自变量。

有一点需要注意,“线性回归”中的“线性”指的是因变量关于参数是线性的,而不是关于自变量,比如模型: Y i = β 1 X i + β 2 X i 2 + ε i Y_{i}=\beta_{1} X_{i}+\beta_{2} X_{i}^{2}+\varepsilon_{i} Yi=β1Xi+β2Xi2+εi,因变量对于参数 β 1 \beta_{1} β1 β 2 \beta_{2} β2 是线性的,但对于自变量 X i X_{i} Xi来说就是非线性的,这任然是一个线性回归模型。

  • 优点:线性回归的理解与解释都十分直观,并且还能通过正则化来降低过拟合的风险。另外,线性模型很容易使用随机梯度下降和新数据更新模型权重。
  • 缺点:面对样本属性数量(维度)较大的复杂模型时,会因为计算量过大而无能为力,比如图像识别问题。

2).单变量线性回归模型构建


预测函数(hypothesis)
h θ ( x ) = θ 0 + θ 1 x h_{\theta}(x)=\theta_{0}+\theta_{1} x hθ(x)=θ0+θ1x
这是用来拟合样本数据点的拟合线,我们的目标是找到最优的 θ 0 \theta_{0} θ0 θ 1 \theta_{1} θ1使得拟合效果最好。


损失函数(Loss Function )
L ( i ) = h θ ( x ( i ) ) − y ( i ) L^{(i)}=h_{\theta}\left(x^{(i)}\right)-y^{(i)} L(i)=hθ(x(i))y(i)
这是单个样本预测结果和正确结果的误差值。


代价函数(Cost Function )

J ( θ 1 , θ 2 ) = 1 2 m ∑ i = 1 m ( h θ ( x ( i ) ) − y ( i ) ) 2 J\left(\theta_{1}, \theta_{2}\right)=\frac{1}{2 m} \sum_{i=1}^{m}\left(h_{\theta}\left(x^{(i)}\right)-y^{(i)}\right)^{2} J(θ1,θ2)=2m1i=1m(hθ(x(i))y(i))2

代价函数是关于参数 θ \theta θ的函数,是所有样本正确结果和预测结果的误差的平均,用来衡量评估模型的好坏,一般情况下它的值越小则模型越好。


3).梯度下降算法(Gradient descent algorithm)


这是构建机器学习模型时用来优化代价函数值的最经典的算法。以上面的单变量线性回归为例,先给 θ 0 \theta_{0} θ0 θ 1 \theta_{1} θ1取一个初始值,通常取0、0,然后不断重复下面的迭代步骤同步更新 θ 0 \theta_{0} θ0 θ 1 \theta_{1} θ1的值:
 temp  0 : = θ 0 − α ∂ ∂ θ 0 J ( θ 0 , θ 1 )  temp  1 : = θ 1 − α ∂ ∂ θ 1 J ( θ 0 , θ 1 ) θ 0 : =  temp  0 θ 1 : =  temp  1 \begin{array}{l} \text { temp } 0:=\theta_{0}-\alpha \frac{\partial}{\partial \theta_{0}} J\left(\theta_{0}, \theta_{1}\right) \\ \text { temp } 1:=\theta_{1}-\alpha \frac{\partial}{\partial \theta_{1}} J\left(\theta_{0}, \theta_{1}\right) \\ \theta_{0}:=\text { temp } 0 \\ \theta_{1}:=\text { temp } 1 \end{array}  temp 0:=θ0αθ0J(θ0,θ1) temp 1:=θ1αθ1J(θ0,θ1)θ0:= temp 0θ1:= temp 1

其中, α \alpha α是学习率(learning rate),影响每次迭代更新参数的步长,需要根据实际情况进行赋值,学习率如果太小则需要花费过多的时间来收敛,学习率如果太大则在最小值附近震荡却无法收敛到最小值。

迭代过程会使得代价函数 J ( θ 0 , θ 1 ) J\left(\theta_{0}, \theta_{1}\right) J(θ0,θ1) 的值不断向最小值收敛,最终达到局部最小值(注意:是局部最小值而非全局最小值,初始 θ 0 \theta_{0} θ0 θ 1 \theta_{1} θ1的值会影响“下山”的方向,最终可能得到不同的收敛结果,如下图:)

不过这里不用担心,对于线性回归,它们的代价函数图像并非上面那样,线性回归的代价函数图像总是一个凸函数(convex function),如下图,它并没有“局部最优解”,它只有一个“全局最优解”。


4).正规方程法:

不同于梯度下降法,该方法可以更简单直接地求解出预测函数的参数。例如,对于线性回归方程:
h 0 ( x ) = θ 0 + θ 1 x h_{0}(x)=\theta_{0}+\theta_{1} x h0(x)=θ0+θ1x

已知样本数据如下:

可以看出,样本数量m=4,属性n=4,那么参数 θ \theta θ就是一个5维向量(n+1,增加一个常数项 x 0 x_{0} x0),该向量的求解方法如下图,将每组自变量向量组合成矩阵,前面加上代表常数项的向量 x 0 x_{0} x0 x 0 x_{0} x0内每个值都为1,组成的这个矩阵我们称为X,然后每个样本结果值组成的向量为y,那么最终,参数向量 θ = ( X T X ) − 1 X T y \theta=\left(X^{T} X\right)^{-1} X^{T} y θ=(XTX)1XTy

使用正规方程法时,需要注意:

(1).矩阵( X T X X^TX XTX)不可逆

可能原因:所求参数大于样本数。
措施 :增加样本数。

可能原因:特征值太多。
措施 :删除一些冗余的特征值。

(2).样本量n太大

矩阵求逆的计算复杂度为 O ( n 3 ) O(n^3) O(n3),当样本量太大时,计算量过大,此时,不建议采用正规方程法。

(3).函数太复杂

此时无法使用正规方程法。


5).过度拟合(Overfitting)问题及解决方法

在机器学习模型构建时,过拟合是指过于精确和严格地匹配每一个样本数据,导致得到了参数过多或者结构过于复杂的模型,虽然该模型能对已有样本数据进行偏差极小(甚至0偏差)的“完美“拟合,但是它的 泛化能力(Generalization) 很差,无法用来预测新的数据样本。发生过拟合时,模型的偏差小而方差大。过拟合的本质是训练算法从统计噪声中不自觉获取了信息并表达在了模型结构的参数当中。

解决方法:

(1).增加样本的数量(易受现实条件限制)

(2).减少特征变量的数量(缺点:同时可能会丢失一些有用的信息)

(3).正则化(推荐):

如下图右侧的过拟合现象,假如我们既想保留全部的参数,又不希望过拟合,那么我们可以通过给高次项的参数 θ 3 \theta_{3} θ3和参数 θ 4 \theta_{4} θ4加上一个惩罚系数(这里取了1000),当我们优化代价函数值到最小的过程,参数 θ 3 \theta_{3} θ3 θ 4 \theta_{4} θ4就会被迫变得很小,从而减小了 θ 3 \theta_{3} θ3 θ 4 \theta_{4} θ4对于最终模型拟合起到的权重作用,解决了过拟合问题。

081951300032292

但是对于更复杂的问题,可能有成百上千个特征参数,我们并不知道应该缩放哪些特征参数、应该缩放多大比例,这个时候常规的正则化方法是:在代价函数最后加上一个正则项 λ ∑ j = 1 n θ j 2 \lambda \sum_{j=1}^{n} \theta_{j}^{2} λj=1nθj2,对全体特征参数进行收缩,通常这种方法非常有效,每个特征参数都会以各自的比例收缩,最终预测函数的图像会变得相对光滑,模型复杂度会降低,不会再出现过拟合问题。

正则项中 λ \lambda λ的作用是控制我们的模型在两个目标之间的平衡关系:第一个目标是模型要尽可能好地拟合训练数据集,第二个目标是模型要尽可能简单,从而防止过拟合。也就是说,参数 λ \lambda λ可以控制我们的模型在“欠拟合”和“过拟合”之间的一个平衡位置,尽可能地实现“恰当拟合”。

在线性回归中,通常正则化的代价函数形式如下:
J ( θ ) = − 1 m [ ∑ i = 1 m y ( i ) log ⁡ h θ ( x ( i ) ) + ( 1 − y ( i ) ) log ⁡ ( 1 − h θ ( x ( i ) ) ) ] + λ 2 m ∑ j = 1 n θ j {J(\theta)}=-\frac{1}{m}\left[\sum_{i=1}^{m} y^{(i)} \log h_{\theta}\left(x^{(i)}\right)+\left(1-y^{(i)}\right) \log \left(1-h_{\theta}\left(x^{(i)}\right)\right)\right]+\frac{\lambda}{2 m} \sum_{j=1}^{n} \theta_{j} J(θ)=m1[i=1my(i)loghθ(x(i))+(1y(i))log(1hθ(x(i)))]+2mλj=1nθj



2.回归树(Regression Tree)


回归树(回归决策树,决策树的一种)通过将数据集重复分割为不同的分支而实现分层学习,分割的标准是最大化每一次分离的信息增益。这种分支结构让回归树很自然地学习到非线性关系。


单一的回归树往往是不够用的,可以利用集成学习中的boosting框架对回归树进行改良升级,如 梯度提升树(Gradient Boost Decision Tree) 就是集成了许多独立训练的树。这种算法的主要思想就是组合多个弱学习算法而成为一种强学习算法。

  • 优点:决策树能学习非线性关系,对异常值也具有很强的鲁棒性。集成学习在实践中表现非常好,其经常赢得许多经典的(非深度学习)机器学习竞赛。

  • 缺点:无约束的,单棵树很容易过拟合,因为单棵树可以保留分支(不剪枝),并直到其记住了训练数据。集成方法可以削弱这一缺点的影响。



3.逻辑回归(Logistic Regression)


1).介绍

逻辑回归是解决分类问题最基础、最经典的算法,通常用于二分类(只有两种标签结果),通过估计预测事件发生的可能性来推断是否发生,从而进行二分类。比如某用户购买某商品的可能性,某病人患有某种疾病的可能性,以及某广告被用户点击的可能性等。有一点要注意:虽然名叫“逻辑回归”,但它并不属于回归,而是一种分类算法。

与线性回归的联系: 逻辑回归与线性回归都是一种广义线性模型(generalized linear model)。逻辑回归假设因变量 y 服从伯努利分布,故使用极大似然法作为参数估计方法;而线性回归假设因变量 y 服从高斯分布,故使用最小二乘法作为参数估计方法。 因此它们有很多相同之处,去除Sigmoid联系函数的话,逻辑回归算法就是一个线性回归。可以说,逻辑回归是以线性回归为理论支持的,但是逻辑回归通过Sigmoid联系函数引入了非线性因素,从而可以轻松处理0/1分类问题。


2).模型构建

预测函数(hypothesis):

h θ ( x ) = g ( θ T x ) h_{\theta}(x)=g\left(\theta^{T} x\right) hθ(x)=g(θTx)

其中,函数 g ( z ) g(z) g(z)名为Sigmoid函数,又名逻辑函数(Logistic function),形式如下:

g ( z ) = 1 1 + e − z g(z)=\frac{1}{1+e^{-z}} g(z)=1+ez1

Sigmoid函数的图像:



之所以使用Sigmoid而不是线性函数,是因为:

  • 我们要预测事物发生的可能性,这个概率值的范围是(0,1),恰好符合Sigmoid函数结果范围,而线性回归得到的结果范围是 ( − ∞ , + ∞ ) (-\infty,+\infty) (,+),虽然也可以通过设定阈值来进行二分类,但是无法给出一个能表示可能性大小的数值结果。
  • 如果样本中有偏离中心较远的离散值,那么使用线性回归拟合数据就会有很大的偏差,如下图所示,在这种情况下,如果使用S形函数Sigmoid就可以很好地解决该问题。


对于逻辑回归,我们希望最终要预测的结果是:

P ( y = 1 ∣ x ; θ ) = g ( θ T x ) = 1 1 + e − θ T x P(y=1 \mid x ; \theta)=g\left(\theta^{T} x\right)=\frac{1}{1+e^{-\theta^{T} x}} P(y=1x;θ)=g(θTx)=1+eθTx1

也就是在给定 x x x θ \theta θ 的条件下 y = 1 y=1 y=1的概率。一般情况选择0.5作为判定”是或否“的阈值,实际应用根据情况选择不同阈值,如果对正例的判别准确性要求高,可以选择阈值大一些,反之可以选择阈值小一些。


3).决策边界(Decision Boundary)

如下图,决策边界是两种样本类型分界的直线(或曲线、超平面),处于决策边界上的点刚好满足 h θ ( x ) = 0.5 h_{\theta}(x)=0.5 hθ(x)=0.5(刚好达到判定阈值),又因 g ( z ) = 1 1 + e − θ T x g(z)=\frac{1}{1+e^{-\theta^{T} x}} g(z)=1+eθTx1,故此时 θ T x = 0 \theta^{T} x = 0 θTx=0,在这个例子中决策边界为 − 3 + x 1 + x 2 = 0 -3+x_{1}+x_{2}=0 3+x1+x2=0,这条直线将图像分成了 y = 1 y=1 y=1的上部区域和 y = 0 y=0 y=0的下部区域。


注意:决策边界由预测函数唯一决定,是预测函数的属性,而不是由样本数据决定。一旦预测函数确定,决策边界也就唯一确定。


除了线性决策边界,还有非线性,如下图,该例的决策边界是圆形曲线: − 1 + x 1 2 + x 2 2 = 0 -1+x_{1}^{2}+x_{2}^{2}=0 1+x12+x22=0


4).代价函数(Cost Function )

J ( θ ) = − 1 m [ ∑ i = 1 m ( y ( i ) log ⁡ h θ ( x ( i ) ) + ( 1 − y ( i ) ) log ⁡ ( 1 − h θ ( x ( i ) ) ) ] J(\theta)=-\frac{1}{m}\left[\sum_{i=1}^{m}\left(y^{(i)} \log h_{\theta}\left(x^{(i)}\right)+\left(1-y^{(i)}\right) \log \left(1-h_{\theta}\left(x^{(i)}\right)\right)\right]\right. J(θ)=m1[i=1m(y(i)loghθ(x(i))+(1y(i))log(1hθ(x(i)))]

根据以上代价函数表达式,对于单个样本点:

Cost ⁡ ( h θ ( x ) , y ) = { − log ⁡ ( h θ ( x ) )  if  y = 1 − log ⁡ ( 1 − h θ ( x ) )  if  y = 0 \operatorname{Cost}\left(h_{\theta}(x), y\right)=\left\{\begin{aligned} -\log \left(h_{\theta}(x)\right) & \text { if } y=1 \\ -\log \left(1-h_{\theta}(x)\right) & \text { if } y=0 \end{aligned}\right. Cost(hθ(x),y)={log(hθ(x))log(1hθ(x)) if y=1 if y=0

特点:当 y = 1 y=1 y=1时, Cost ⁡ ( h θ ( x ) , y ) = − log ⁡ ( h θ ( x ) ) \operatorname{Cost}\left(h_{\theta}(x), y\right)=-\log \left(h_{\theta}(x)\right) Cost(hθ(x),y)=log(hθ(x)),该函数图像如下

此时,由于正确结果 y = 1 y=1 y=1,如果我们模型的预测结果 h θ ( x ) h_{\theta}(x) hθ(x)趋近于1,那么模型预测是正确的,代价函数值趋近于0,合理;而相反的,如果我们模型的预测结果趋近于0,也就是得出了与正确结果”1“相反的错误结果”0“,此时模型预测结果越趋近于错误结果”0“,代价函数值就越来越大,直到趋近于正无穷,这是因为”犯错“是要付出”代价“的,我们会使用一个代价数值来”惩罚“模型,错的越严重,这个惩罚它的代价数值就越大。
(当 y = 0 y=0 y=0时同理)

代价函数的正则化:

J ( θ ) = − 1 m [ ∑ i = 1 m ( y ( i ) log ⁡ h θ ( x ( i ) ) + ( 1 − y ( i ) ) log ⁡ ( 1 − h θ ( x ( i ) ) ) ] + λ 2 m ∑ j = 1 n θ j 2 J(\theta)=-\frac{1}{m}\left[\sum_{i=1}^{m}\left(y^{(i)} \log h_{\theta}\left(x^{(i)}\right)+\left(1-y^{(i)}\right) \log \left(1-h_{\theta}\left(x^{(i)}\right)\right)\right]\right. + \frac{\lambda}{2 m} \sum_{j=1}^{n} \theta_{j}^{2} J(θ)=m1[i=1m(y(i)loghθ(x(i))+(1y(i))log(1hθ(x(i)))]+2mλj=1nθj2

代价函数值的优化:

常用的方法还是梯度下降,通过下面的公式不断迭代更新参数 θ \theta θ,直到代价函数值收敛到最小:

θ j : = θ j − α ∂ ∂ θ j J ( θ ) \theta_{j}:=\theta_{j}-\alpha \frac{\partial}{\partial \theta_{j}} J(\theta) θj:=θjαθjJ(θ)



4.神经网络(Neural Network)


1).介绍

人工神经网络(Artificial Neural Network,ANN),简称神经网络(Neural Network,NN),是一种模仿生物神经网络的结构和功能的数学模型,结构由输入层、隐藏层、输出层的神经元互相连接而成,是一种具备学习能力的自适应系统,能够用来处理复杂的机器学习分类问题,比如图像识别和语音识别。

早在上个世纪(20世纪)中期就已经有很多神经网络方面的研究,但在后来发展停滞了很长时间,主要原因是当时的计算机算力不足。在2000年左右,随着计算机技术的成熟,神经网络迎来了迅猛发展。


2).模型理解

神经网络之所以能够解决复杂的分类问题,可以从下面简单例子来理解,如下图,第一个神经网络能处理逻辑运算“与”,第二个神经网络能处理逻辑运算“非”,第三个神经网络能处理逻辑运算“或”,然后,我们将前面三个神经网络嵌套,组成在下面第四个神经网络,此时,这个较复杂的神经网络就能够处理逻辑运算“异或”了。可以想象,如果将更多的神经网络嵌套,形成神经元更多更复杂的结构,便可以处理更复杂的问题。


3).如何使用神经网络解决多元分类问题

如果输出层只有单个神经元,则只能进行二分类(Sigmoid逻辑函数,是或否),要进行多元分类,则需要输出层有更多的神经元。如下图,为了识别四类图像:行人、小汽车、摩托车、卡车,我们神经网络的输出层有四个相应的神经元,因此,我们的输出结果将会是一个四维向量,从而进行多元分类。

4).代价函数

J ( Θ ) = − 1 m [ ∑ i = 1 m ∑ k = 1 K y k ( i ) log ⁡ ( h Θ ( x ( i ) ) ) k + ( 1 − y k ( i ) ) log ⁡ ( 1 − ( h Θ ( x ( i ) ) ) k ) ] + λ 2 m ∑ l = 1 L − 1 ∑ i = 1 s l ∑ j = 1 s l + 1 ( Θ j i ( l ) ) 2 \begin{aligned} J(\Theta)=&-\frac{1}{m}\left[\sum_{i=1}^{m} \sum_{k=1}^{K} y_{k}^{(i)} \log \left(h_{\Theta}\left(x^{(i)}\right)\right)_{k}+\left(1-y_{k}^{(i)}\right) \log \left(1-\left(h_{\Theta}\left(x^{(i)}\right)\right)_{k}\right)\right] \\ &+\frac{\lambda}{2 m} \sum_{l=1}^{L-1} \sum_{i=1}^{s_{l}} \sum_{j=1}^{s_{l+1}}\left(\Theta_{j i}^{(l)}\right)^{2} \end{aligned} J(Θ)=m1[i=1mk=1Kyk(i)log(hΘ(x(i)))k+(1yk(i))log(1(hΘ(x(i)))k)]+2mλl=1L1i=1slj=1sl+1(Θji(l))2

其中,K表示输出层神经元个数,也就是该神经网络是用来处理K元分类的。


5).反向传播算法(Backpropagation,BP)

反向传播算法是用来优化神经网络模型的主流经典算法。由于神经网络是具有复杂的多层结构,不能直接使用梯度下降等方法来优化代价函数,而必须要结合反向传播算法来训练神经网络模型。

下图是反向传播算法的步骤。反向传播算法其中有很多细节,涉及到的数学证明非常复杂,而关于该算法的原理也较难理解,即便机器学习领域权威吴恩达前辈,也表示偶尔也会不清楚自己构建的反向传播神经网络内部“到底在做什么”,只是感觉“最终得出的结果很良好”。但是该算法在很多人多年实践中的效果确实很良好。

6).随机初始化

对于参数 Θ \Theta Θ(也就是权重)的初始取值,由于神经网络结构的特殊性,不能像回归模型中全设为0然后迭代更新,如果这么做,会发生“对称权重现象”,也就是每次迭代所有的权重值都是相等的。因此在神经网络模型中,参数 Θ \Theta Θ一般使用随机初始化方法:

对于每一个 Θ i j ( l ) \Theta_{i j}^{(l)} Θij(l),在区间 [ − ϵ , ϵ ] [-\epsilon, \epsilon] [ϵ,ϵ]中取一个随机数值作为 Θ i j ( l ) \Theta_{i j}^{(l)} Θij(l)的初始值


7).模型选择、样本数据集划分

(通常情况)

  • 训练集(Training Set)占60%:
    训练机器学习模型,并分别使用不同的模型参数来学习数据,得到各个相应的模型结果。
  • 交叉验证集(Cross Validation Set,cv)占20%:
    作为新的样本数据,对训练集得到的不同模型进行验证,计算预测误差,评比后得到结果最优的模型以及相应的模型参数。
  • 测试集(Test Set)占20%:
    作为新的样本数据,对交叉验证得到的最优模型进行泛化能力测试,预测准确率越高,模型越良好。



三、无监督学习常用算法


1.主成分分析(Principal Component Analysis,PCA)


1).介绍

主成分分析是一种常用的简化数据集的算法。它通过正交变换,把数据投影到一个新的坐标系中,此时,第一个坐标轴的方向为全体数据投影方差最大(最分散)的方向,也称为第一主成分,第二个坐标轴的方向为方差第二大的方向,也称为第二主成分,依次类推。从而减少数据集的维数,同时保留数据集中对方差贡献最大的特征。



2).算法步骤(将n维数据降到k维)

(1).均值标准化(Mean Normalization)和特征缩放(Feature Scaling)

对于 m m m n n n 维数据 x ( 1 ) , x ( 2 ) , … , x ( m ) x^{(1)}, x^{(2)}, \ldots, x^{(m)} x(1),x(2),,x(m) ,计算:

x ( i ) = x ( i ) − 1 m ∑ i = 1 m x ( i ) x^{(i)} = x^{(i)}-\frac{1}{m} \sum_{i=1}^{m} x^{(i)} x(i)=x(i)m1i=1mx(i)

这是均值标准化,使每个样本数据(向量)的均值为0,从而保证所有样本数据都平移到了坐标系中心位置附近。如果特征向量之间属性关系差别较大,则还需进行特征缩放:

x ( i ) = x ( i ) s x^{(i)} =\frac{x^{(i)}}{s} x(i)=sx(i)

其中, s s s为相应的样本数据的标准差

(2).计算协方差矩阵(Covariance Matrix)

S i g m a = 1 m ⋅ X ⋅ ( X ) T Sigma=\frac{1}{m} \cdot X^{} \cdot (X)^{T} Sigma=m1X(X)T

X X X 是样本数据组成的 n × m n \times m n×m 维矩阵,得到的 S i g m a Sigma Sigma是一个 n × n n\times n n×n 的矩阵

(3).计算特征向量

特征向量也就是矩阵 S i g m a Sigma Sigma的正交基向量,这些正交基向量组成了数据降维后的新坐标系。通常在编程中,特征向量的计算可以通过计算奇异值分解(svd) 来得到:

 svd (Sigma)  = [ U , S , V ] \text { svd (Sigma) }=[\mathrm{U}, \mathrm{S}, \mathrm{V}]  svd (Sigma) =[U,S,V]

其中,得到的矩阵 U U U 就是以特征向量为列而组成的矩阵,这里它是一个 n × n n \times n n×n 的矩阵。
U = [ ∣ ∣ ∣ u ( 1 ) u ( 2 ) … u ( n ) ∣ ∣ ∣ ] ∈ R n × n U=\left[\begin{array}{cccc} \mid & \mid & & \mid \\ u^{(1)} & u^{(2)} & \ldots & u^{(n)} \\ \mid & \mid & & \mid \end{array}\right] \in \mathbb{R}^{n \times n} U=u(1)u(2)u(n)Rn×n

(4).计算数据降到 k k k维的结果

对于奇异值分解得到的矩阵 U U U,取前 k k k 列组成新的矩阵 U n × k U_{n\times k} Un×k,由此得数据降到 k k k维的结果矩阵 z z z
z = U n × k ⋅ X z = U_{n\times k} \cdot X z=Un×kX

(5).主成分数量 k k k的选择

对于奇异值分解得到的矩阵 S S S,它是一个对角矩阵(主对角线以外元素都为0):
S = [ S 11 ⋯ 0 ⋮ S 22 ⋮ S 33 ⋱ 0 ⋯ S n n ] S=\left[\begin{array}{ccccc} S_{11} & & & \cdots & 0 \\ \vdots & S_{22} & & & \vdots \\ & & S_{33} & & \\ & & & \ddots \\ 0& \cdots & & & S_{n n} \end{array}\right] S=S110S22S330Snn

假如我们要使降到 k k k维后的数据保留99%的差异性,那么 k k k的最小值的计算方法为:

对于 k = 1 , 2 , 3 , … , n k=1,2,3,…,n k=1,2,3,,n,从 k = 1 k=1 k=1开始逐个计算下面不等式是否成立:
1 − ∑ i = 1 k S i i ∑ i = 1 n S i i ⩽ 0.01 1-\frac{\sum_{i =1}^{k} S_{ii}}{\sum_{i=1}^{n} S_{ii}} \leqslant 0.01 1i=1nSiii=1kSii0.01
(其中, ∑ i = 1 k S i i {\sum_{i =1}^{k} S_{ii}} i=1kSii表示对矩阵 S S S主对角线前 k k k个值求和)

当上述不等式成立时的 k k k值就是能够保留原始数据99%差异性的最小维度 k k k值。





2.K均值聚类(K-means Clustering)


1).介绍

聚类(Clustering)是按照某个特定标准(如距离)把样本数据集分割成不同的簇类,使得同一个簇内的各个样本数据的相似性尽可能大,簇与簇之间的数据差异性尽可能大,也即要使同一类的数据尽可能聚集到一起,不同类数据尽量分离。

K均值聚类算法是一种迭代求解的聚类分析算法,它按照样本数据之间的距离大小(常用欧式距离),通过反复迭代,将样本数据集划分为K个簇类,最终使每个簇内的点尽可能靠近,簇之间尽可能远离。


2).算法步骤

(1).随机选取K个点作为初始的聚类中心。

(2).对数据集划分簇类,根据各样本数据点与每个聚类中心的距离,把各个样本数据分配给距离最近的聚类中心。

(3).重新计算每个簇类的聚类中心。

(4).重复(2)、(3)步骤直到聚类中心不再发生变化




5.随机森林和集成学习


1). 概述

随机森林(Random Forests,RF),是由多棵决策树构成的集成算法,用来做分类预测,属于有监督学习,其输出的类别是由每个树输出类别的众数而定。当今在业内有着极为广泛的应用场景,从市场营销到医疗保健保险,再到用户画像和广告推荐算法,性能强大且应用广泛。



2). 信息论和决策树

这部分是背景知识,涉及一些基础理论知识,不想深入了解的话可以跳过,不影响后续算法实现

(1). 信息论原理

什么是信息?信息就是用来消除不确定性的度量。信息论是为解决信息传递问题而建立的理论,是数据挖掘的基础理论之一。一个信息传递系统是由发送端(信源)和接收端(信宿)以及通信通道(信道)三者组成,信息传递过程中所消除的不确定性越大,那么所传递的信息量就越大。

在信息开始传递之前,接收端(信宿)对于信源的状态有着不确定性,这种不确定性叫做先验不确定性。在通信之后,这种不确定性会被减少或消除,一般情况下,干扰(噪音)会对传递的信息造成破坏,因此先验不确定性不能被完全消除,只能部分消除,也就是说,通信完成后信宿还任然具有一定程度的不确定性,这就是后验不确定性。显然,后验不确定性总要小于先验不确定性,如果两者相等,说明信宿根本没有接受到任何信息。

将其应用在数据挖掘中,对于一个分类问题而言,每一个属性的值都会为它的分类结果提供一定的信息,在没有得知任何属性的数据之前,我们对于分类结果是完全不确定的,然后每得到一个属性的值都会消除一定的不确定性,直到得知所有属性取值之后,我们对于分类结果便基本上可以确定了。

(2). 信息熵

信息熵是自信息的平均值,它反映信源 U ( u 1 , u 2 , ⋯ u r ) U\left(u_{1}, u_{2}, \cdots u_{r}\right) U(u1,u2,ur)中所有信息在发出前的平均不确定性。公式为:
H ( U ) = ∑ i P ( u i ) log ⁡ 1 P ( u i ) = − ∑ i P ( u i ) log ⁡ P ( u i ) H(U)=\sum_{i} P\left(u_{i}\right) \log \frac{1}{P\left(u_{i}\right)}=-\sum_{i} P\left(u_{i}\right) \log P\left(u_{i}\right) H(U)=iP(ui)logP(ui)1=iP(ui)logP(ui)

(3). 条件熵

条件熵表示在接收端收到信息 V ( v 1 , v 2 , ⋯ v r ) V\left(v_{1}, v_{2}, \cdots v_{r}\right) V(v1,v2,vr)后,对于信源 U ( u 1 , u 2 , ⋯ u r ) U\left(u_{1}, u_{2}, \cdots u_{r}\right) U(u1,u2,ur)尚存在的不确定性,这种不确定性是由于干扰(噪音)造成的。条件熵公式为:
H ( U ∣ V ) = ∑ j P ( v j ) ∑ i P ( u i ∣ v j ) log ⁡ 1 P ( u i ∣ v j ) {H(U \mid V)}=\sum_{j} P\left(v_{j}\right) \sum_{i} P\left(u_{i} \mid v_{j}\right) \log \frac{1}{P\left(u_{i} \mid v_{j}\right)} H(UV)=jP(vj)iP(uivj)logP(uivj)1

信息论原理是数据挖掘的基础理论之一,一般用于解决数据的分类问题。具体而言,就是在已知各样本类别的数据中,找出确定类别的关键条件属性。求关键属性的方法,是先计算各个条件属性的信息量,再从中选出信息量最大的属性,信息量的计算是利用信息论原理中的公式。

(4). 互信息与信息增益

互信息 I ( U ∣ V ) {I(U \mid V)} I(UV)又叫信息增益,是信息熵与条件熵的差值,它代表最后接受到信息 V V V后所获得的信源 U U U的信息量,也就是最终不确定性的消除量。公式为:
I ( U , V ) = H ( U ) − H ( U ∣ V ) I(U, V)=H(U)-H(U \mid V) I(U,V)=H(U)H(UV)

(5). 决策树

决策树(Decision Tree)是数据挖掘中的一种预测模型,由每个样本的属性分析归纳而产生。它是以样本的属性作为结点,以属性的取值作为分支的树结构,越靠近根结点的属性是全体样本中信息量越大的属性,信息量大小的计算方法通常是信息增益或基尼系数。

决策树是对全体样本数据的高度概括,不但能够准确识别现有样本的类别,也能对新样本的类别作出有效的预测。决策树的算法实现有多种类型,如ID3、C4.5、IBLE、CART等。


3). 集成学习

”团结就是力量“,这句话很好地表达了机器学习领域中强大的集成学习的基本思想。集成学习方法都是建立在一个假设上:将多个模型组合在一起通常可以产生更强大的模型。

在集成学习中,我们会训练多个模型(通常称为”弱学习器“)解决相同的问题,并将它们结合起来以获得更好的结果。最重要的假设是:当弱模型被正确组合时,我们可以得到更精确或更鲁棒的模型。

集成学习的方法有很多种,最常用的是Bgging(袋装法)Boosting(提升法),随机森林所使用的是bagging方法。

Bagging

Bagging可以认为是一种平均法,简单来说,就是所有算法进行相互独立训练得到各自的模型,然后再进行投票选择最好的模型。步骤如下:

  1. 对于给定的训练样本S,每轮从训练样本S中采用有放回抽样(Booststraping)的方式抽取M个训练样本,共进行n轮,得到了n个样本集合,需要注意的是这里的n个训练集之间是相互独立的。

  2. 在获取了样本集合之后,每次使用一个样本集合得到一个预测模型,对于n个样本集合来说,我们总共可以得到n个预测模型。

  3. 如果我们需要解决的是分类问题,那么我们可以对前面得到的n个模型采用投票的方式得到分类的结果,对于回归问题来说,我们可以采用计算模型均值的方法来作为最终预测的结果。

Boosting

不同于Bagging的并行,Boosting算法训练过程为阶梯状,基模型按次序一一进行训练,基模型的训练集按照某种策略每次都进行一定的转化。对所有基模型预测的结果进行线性综合产生最终的预测结果。步骤如下:

  1. 它首先令每个样本拥有相同的权重值(1/n,用来计算误差率或准确率,其他算法中这个权值不会改变),构建一个弱分类器。
  2. 改变样本的权值分布:在这个分类器中分错的样本权值增大,分对的样本权值减小;计算这个分类器的误差率:误差率越小,该分类器的权值越大。
  3. 根据改变权值分布后的样本数据构建一个新的弱分类器。
  4. 重复2、3步骤,直到到达预定的学习器数量或预定的预测精度。

直观理解:boosting的每一步总是更关注于分错的样本,使它们再下一步更容易被分对,同时误差率越小的分类器的权值越大,使得最后线性组合以后更优的分类器拥有更大的发言权,而不是像随机森林一样每个分类器发言权相同。

下面这张图对Ada-boost做了恰当的解释:

  • Box 1: 你可以看到我们假设所有的数据点有相同的权重(正号、负号的大小都一样),并用一个决策树桩D1将它们分为两部分。我们可以看到这个决策树桩将其中的三个正号标记的数据点分类错误,因此我们将这三个点赋予更大的权重交由下一个预测树桩进行分类。
  • Box 2: 在这里你可以看到三个未被正确分类的(+)号的点的权重变大。在这种情况下,第二个决策树桩D2试图将这三个错误的点准确的分类,但是这又引起新的分类错误,将三个(-)号标记的点识别错误,因此在下一次分类中,这三个(-)号标记的点被赋予更大的权重。
  • Box 3: 在这里三个被错误分类的(-)号标记的点被赋予更大的权重,利用决策树桩D3进行新的分类,这时候又产生了新的分类错误,图中用小圆圈圈起来的一个负号点和两个正号点
  • Box 4: 在这里,我们将D1、D2和D3三个决策器组合起来形成一个复杂的规则,你可以看到这个组合后的决策器比它们任何一个弱分类器表现的都足够好。

该原理可同样用于回归算法。它在不同权重的训练数据集上生成一系列的弱学习器,最开始的时候所有的数据拥有相同的权重,对于第一个分类器没有正确分类的点则在下一个决策器中的权重将会加大,作为一个迭代的过程,直到分类器数量达到预定值或预测精度达到预定值。大多数情况下,我们在AdaBoost中使用decision stamps。但是如果它可以接受带有权重的训练集,我们也可以使用其他任何的机器学习算法作为基础学习器。我们可以使用AdaBoost算法解决分类和回归问题。


4). 随机森林

简而言之,随机森林就是用随机的方式建立一个森林,里面有很多的决策树,每一棵决策树之间是没有关联的。当有一个新的输入样本进入的时候,就让森林中的每一棵决策树分别进行预测,得到该样本的类别预测结果,最终,森林中所有树的预测结果是哪一类的最多,就作为最终预测结果。随机森林既可以处理离散型变量,也可以处理连续型变量。

算法步骤
  1. 假设训练集大小为N,对于每棵决策树而言,随机且有放回地从训练集中的抽取N个训练样本,作为该决策树的训练集进行训练
  2. 假设每个样本有M个属性,在决策树的每个节点需要分裂时,随机从这M个属性中选取出m个属性,满足条件m << M。然后从这m个属性中采用某种策略(比如说信息增益)来选择1个属性作为该节点的分裂属性。
  3. 每棵树都尽最大程度的生长,并且没有剪枝过程
直观理解

随机森林算法得到的森林中的每一棵都是很弱的,但是大家组合起来就很厉害。可以这样比喻随机森林算法:每一棵决策树就是一个精通于某一个窄领域的专家(因为我们从M个feature中选择m让每一棵决策树进行学习),这样在随机森林中就有了很多个精通不同领域的专家,对一个新的问题(新的输入数据),可以用不同的角度去看待它,最终由各个专家,投票得到结果。而这正是群体智慧的力量,同时,由于每个专家相互独立(每棵树的训练数据是有放回抽样),所以不容易产生overfitting。

算法优点
  • 两个随机性的引入,使得随机森林不容易陷入过拟合
  • 两个随机性加上集成学习的方法使得随机森林有很好的抗噪能力,在缺失值比较多或者噪音比较大的数据集任然能有良好表现
  • 能够处理高维度(feature很多)的数据,并且不用做特征选择,对数据集的适应能力强:既能处理离散型数据,也能处理连续型数据,数据集无需标准化
  • 训练速度比较快,容易做成并行方法
  • 对于不平衡的数据集来说,它可以平衡误差。



四、机器学习模型常用评估方法和指标



1. 学习曲线


学习曲线是一种用来检测机器学习算法运行是否正常,或者改进算法模型的有效工具。它以横轴表示训练集的样本数量,纵轴表示误差(代价函数的大小,越大预测准确率越低),在同一个坐标图上,分别绘制出训练集的代价函数随样本数递增的波动曲线和交叉验证集的代价函数随样本数递增的变化曲线。


(1).低偏差、低方差(恰当拟合)的学习曲线:

特点:

  • 随着训练样本数的增加,训练集误差曲线缓慢上升,验证集误差曲线缓慢下降。
  • 最终它们逐渐趋于水平,且保持一个较近的间隔。

(2).高偏差(欠拟合)的学习曲线:

特点:

  • 随着训练样本数的增加,训练集误差曲线迅速上升(因为模型对数据样本的拟合能力很差),验证集误差曲线迅速下降。
  • 然后它们迅速水平(因为拟合能力太差,只需很少的样本就已经达到拟合极限,之后基本不再变化),且它们水平后的位置对应的误差值极大。
  • 对于这类高偏差的欠拟合模型,继续扩增样本数量无法改善模型的预测能力。

(3).高方差(过拟合)的学习曲线:

特点:

  • 随着训练样本数的增加,训练集误差曲线极为缓慢地上升(因为拟合能力“过强”,所以始终能以极小的误差来拟合样本数据),验证集误差曲线极为缓慢地下降(因为过度拟合导致预测新数据能力始终很差),且它们之间长期保持很大的间隔。
  • 对这类高方差的过拟合模型,继续扩增样本量能够改善模型的预测能力,且当样本量非常非常大时,两条误差曲线的间隔会收敛为一个较小的正常值,此时模型能够达到恰当拟合状态。


2.评价指标


在机器学习分类问题中,如果样本数据类别不平衡,会影响模型的识别精度并且降低许多性能指标的表现,因此通常需要考虑多个度量标准,从不同的角度来全面地评估分类器的性能表现。


1). 混淆矩阵(Confusion Matrix)

混淆矩阵(Confusion Matrix)是用来构建各个不同评价指标的最基础的概念

  • TP(True Positives):预测为正、实际为正的样本数

  • FN(False Negatives):预测为负、实际为正的样本数

  • FP(False Positives):预测为正、实际为负的样本数

  • TN(True Negatives):预测为负、实际为负的样本数

根据混淆矩阵可以推导出以下评价指标:


2). 准确率(Accuracy,ACC)

准确率表示预测正确的结果数占总样本数的比率,是最常用的评价指标,但在样本不均衡的情况下评价效果不好。
A C C = T P + T N P + N = T P + T N T P + T N + F P + F N A C C=\frac{T P+T N}{P+N}=\frac{T P+T N}{T P+T N+F P+F N} ACC=P+NTP+TN=TP+TN+FP+FNTP+TN
scikit-learn 实现如下:

from sklearn.metrics import accuracy_score

accuracy = accuracy_score(y_true, y_pred)

3). 精确率(Positive Predictive Value,PPV)和召回率(True Positive Rate,TPR)

精确率(查准率)表示表示预测为正的样本中实际也为正的比率;召回率(查全率)表示实际为正的样本中预测也为正的比率。
 Precision  = P P V = T P T P + F P \text { Precision }=P P V=\frac{T P}{T P+F P}  Precision =PPV=TP+FPTP

 Recall  = T P R = T P P = T P T P + F N \text { Recall }=T P R=\frac{T P}{P}=\frac{T P}{T P+F N}  Recall =TPR=PTP=TP+FNTP

精确率高则说明查的准,误检率低;召回率高则说明查的全,漏检率低。比如在检索系统中,精确率就是使用浏览器搜索关键字时,检索出来的条目有多少是准确的、是用户需要的,召回率则是所有准确的条目中有多少被成功的检索出来了。总之,召回率是尽可能的把正样本都查找出来;而精确率尽可能地保证预测的正确率。通常,这是一对相互矛盾的指标,比如当模型想要提升召回率这个指标时,就会倾向于将结果预测为正样本,然而这将会导致不少的负样本被误判为正样本,从而导致精确率降低,反之亦然。因此通常在不同的业务需求环境之下,会采取不同的侧重。

scikit-learn 实现如下:

from sklearn.metrics import accuracy_score

accuracy = accuracy_score(y_true=y_test, y_pred=y_pred)

from sklearn.metrics import recall_score

recall = recall_score(y_true=y_test, y_pred=y_pred)

4). F1分数

F1 分数是召回率和精准率的调和平均值
F 1 = 2 1  Recall  + 1  Precision  = 2  Recall  ×  Precision   Recall  +  Precision  F_{1}=\frac{2}{\frac{1}{\text { Recall }}+\frac{1}{\text { Precision }}}=2 \frac{\text { Recall } \times \text { Precision }}{\text { Recall }+\text { Precision }} F1= Recall 1+ Precision 12=2 Recall + Precision  Recall × Precision 
scikit-learn 实现如下:

from sklearn.metrics import f1_score

f1 = f1_score(y_true=y_test, y_pred=y_pred)

5). PR曲线(Precision-Recall曲线)

P-R曲线是通过将分类阈值从高到低逐渐调整,产生的精确率和召回率的值对应的点描绘而成的曲线,其横轴是召回率,纵轴是精确率。P-R曲线上一个点的含义是,在该阈值之下的分类模型对应的召回率和精确率。

P-R 曲线越靠近右上方说明该模型预测性能越好。在对不同模型进行比较时,若一个模型的PR曲线被另一个模型的PR曲线完全包住则说明后者的性能优于前者,若模型的PR曲线发生了交叉,则无法直接判断哪个模型更好,此时常用平衡点进行比较,它是查准率=查全率时的取值。


6). ROC曲线(Receiver Operating Characteristic)

ROC曲线,即受试者工作特性曲线,其来源于医学领域,起源于军事领域。ROC曲线的纵轴为真阳性率(TPR),表示实际为正的样本中预测为正的比率;横轴为假阳性率(FPR),表示实际为负的样本中预测为正的比率。跟P-R曲线相似,ROC曲线也是通过不断调整分类阈值来逐步产生不同的点,最后再将这些点连接起来形成ROC曲线。
F P R = F P T N + F P F P R=\frac{F P}{T N+F P} FPR=TN+FPFP

T P R = T P T P + F N T P R=\frac{T P}{T P+F N} TPR=TP+FNTP

截屏2021-08-08 下午4.32.16

通常,ROC曲线越靠近左上角,说明模型预测性能越好。如果两个模型的ROC曲线交叉,难以直观得出结论,这时可以通过计算ROC曲线下方的面积(AUC)来比较模型优劣。


7). PR曲线和ROC曲线的比较和选择

两者之间最显著的一个差异是,ROC曲线对于样本类别不平衡有着很强的鲁棒性,如下图,当正负样本的分布变化的时候,ROC曲线能够保持不变,而PR曲线则会发生剧烈变化。

1102791-20181226105734428-906065004

这一特性使得ROC曲线下面积AUC的值能保持稳定,AUC 值的意义相当于一个概率值,表示随机挑选一个正样本以及一个负样本,当前的分类算法根据计算得到的Score值将这个正样本排在负样本前面的概率。因此,AUC值实际上反映了模型的 rank 能力,AUC值越大,当前的分类算法越有可能将正样本排在负样本前面。因此ROC曲线在某些场景下很适用,如 CTR 点击通过率排序,实际上便是在考验模型的排序能力。除此之外,CTR 中存在着样本不均衡的问题,正负样本比例通常会大于 1:100,如果采用 PR 曲线,则会导致 AUC 发生剧变,无法较好反映模型效果。

然而在有些场景下,比如信用卡欺诈检测,我们会更关注 precision 和 recall,比如说如果要求预测出为欺诈的人尽可能准确,那么就是要提高 precision;而如果要尽可能多地预测出潜在的欺诈人群,那么就是要提高 recall。一般来说,提高二分类的阈值就能提高precision,降低阈值就能提高 recall,这时便可观察 PR 曲线,得到最优的阈值。


总结

  1. ROC曲线兼顾正样本与负样本,所以适用于评估分类器的整体性能(通常是计算AUC,表示模型的rank性能),相比而言PR曲线主要聚焦于正样本。
  2. 如果有多份数据且存在不同的类别分布。比如信用卡欺诈问题中每个月正例和负例的比例可能都不相同,这时候如果只想单纯地比较分类器的性能且剔除类别分布改变的影响,则ROC曲线比较适合,因为类别分布改变可能使得PR曲线发生变化时好时坏,这种时候难以进行模型比较;反之,如果想测试不同类别分布下对分类器的性能的影响,则PR曲线比较适合。
  3. 如果想要评估在相同的类别分布下正例的预测情况,则宜选PR曲线。类别不平衡问题中,ROC曲线通常会给出一个乐观的效果估计,所以大部分时候还是PR曲线更好。
  4. 最后可以根据具体的应用,在曲线上找到最优的点,得到相对应的precision,recall,f1 score等指标,去调整模型的阈值,从而得到一个符合具体应用场景的模型。
  • 0
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

进击的西西弗斯

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值