Adaboost介绍

AdaBoost算法与Boosting算法不同,它是使用整个训练集来训练弱学习器,其中训练样本在每次迭代的过程中都会重新被赋予一个权重,在上一个弱学习器错误的基础上进行学习来构建一个更加强大的分类器。下面通过一个图来了解AdaBoost算法的工作过程。

Adaboost算法分析

从图1.1中,我们可以看到adaboost的一个详细的算法过程。Adaboost是一种比较有特点的算法,可以总结如下:

每次迭代改变的是样本的分布,而不是重复采样(re weight)
样本分布的改变取决于样本是否被正确分类 总是分类正确的样本权值低;总是分类错误的样本权值高(通常是边界附近的样本)
最终的结果是弱分类器的加权组合(权值表示该弱分类器的性能)
简单来说,Adaboost有很多优点:

adaboost是一种有很高精度的分类器
可以使用各种方法构建子分类器,adaboost算法提供的是框架
当使用简单分类器时,计算出的结果是可以理解的。而且弱分类器构造极其简单
简单,不用做特征筛选
不用担心overfitting!
总之:adaboost是简单,有效。

Adaboost过程图示

下面我们举一个简单的例子来看看adaboost的实现过程:

图中,“+”和“-”分别表示两种类别,在这个过程中,我们使用水平或者垂直的直线作为分类器,来进行分类。
第一步:

根据分类的正确率,得到一个新的样本分布D2­,一个子分类器h1
其中划圈的样本表示被分错的。在右边的途中,比较大的“+”表示对该样本做了加权。

第二步:


根据分类的正确率,得到一个新的样本分布D3,一个子分类器h2

第三步:

得到一个子分类器h3

整合所有子分类器:

因此可以得到整合的结果,从结果中看,及时简单的分类器,组合起来也能获得很好的分类效果,在例子中所有的。

Adaboost算法的某些特性是非常好的,在我们的报告中,主要介绍adaboost的两个特性。一是训练的错误率上界,随着迭代次数的增加,会逐渐下降;二是adaboost算法即使训练次数很多,也不会出现过拟合的问题。

Adaboost算法流程

假设输入训练数据为:
T={(x1,y1),(x2,y2),(xN,yN)}T=\left\{\left(x_{1}, y_{1}\right),\left(x_{2}, y_{2}\right),\left(x_{N}, y_{N}\right)\right\} T={(x1​,y1​),(x2​,y2​),(xN​,yN​)}其中:xi∈X⊆Rn,yi∈Y=−1,1x_{i} \in X \subseteq R^{n}, \quad y_{i} \in Y=-1,1xi​∈X⊆Rn,yi​∈Y=−1,1 ,迭代次数即若分类器个数为M.
1.初始化训练样本的权值分布为:
D1=(w1,1,w1,2,…,w1,i),w1,i=1N,i=1,2,…,ND_{1}=\left(w_{1,1}, w_{1,2}, \ldots, w_{1, i}\right), w_{1, i}=\frac{1}{N}, i=1,2, \ldots, N D1​=(w1,1​,w1,2​,…,w1,i​),w1,i​=N1​,i=1,2,…,N2.对于m=1,2,…,Mm=1,2, \ldots, Mm=1,2,…,M

a)使用具有权值分布DmD_{m}Dm​的训练数据集进行学习,得到弱分类器Gm(x)G_{m}(x)Gm​(x)
b)计算Gm(x)G_{m}(x)Gm​(x)在训练数据集上的分类误差率:
em=∑i=1Nwm,iI(Gm(xi)≠yi)e_{m}=\sum_{i=1}^{N} w_{m, i} I\left(G_{m}\left(x_{i}\right) \neq y_{i}\right) em​=i=1∑N​wm,i​I(Gm​(xi​)​=yi​)c)计算Gm(x)G_{m}(x)Gm​(x)在强分类器中所占的权重:
αm=12log⁡1−emem\alpha_{m}=\frac{1}{2} \log \frac{1-e_{m}}{e_{m}} αm​=21​logem​1−em​​d)更新训练数据集的权值分布(这里zmz_{m}zm​是归一化因子,为了使样本的概率分布和为1):
wm+1,i=wm,izmexp⁡(−αmyiGm(xi)),i=1,2,…,10zm=∑i=1Nwm,iexp⁡(−αmyiGm(xi))\begin{array}{c} w_{m+1, i}=\frac{w_{m, i}}{z_{m}} \exp \left(-\alpha_{m} y_{i} G_{m}\left(x_{i}\right)\right), i=1,2, \ldots, 10 \\ z_{m}=\sum_{i=1}^{N} w_{m, i} \exp \left(-\alpha_{m} y_{i} G_{m}\left(x_{i}\right)\right) \end{array} wm+1,i​=zm​wm,i​​exp(−αm​yi​Gm​(xi​)),i=1,2,…,10zm​=∑i=1N​wm,i​exp(−αm​yi​Gm​(xi​))​

3.得到最终的分类器为:
F(x)=sign⁡(∑i=1NαmGm(x))F(x)=\operatorname{sign}\left(\sum_{i=1}^{N} \alpha_{m} G_{m}(x)\right) F(x)=sign(i=1∑N​αm​Gm​(x))
整个流程中令人困惑的是:

  • 分类器的权重的确定

下面我们进行证明

假设经过m-1轮迭代,得到弱分类器Fm−1(x)F_{m-1}(x)Fm−1​(x),根据前向分布,有:
Fm(x)=Fm−1(x)+αmGm(x)F_{m}(x)=F_{m-1}(x)+\alpha_{m} G_{m}(x) Fm​(x)=Fm−1​(x)+αm​Gm​(x)AdaBoost的损失函数是指数损失,则有:
Loss =∑i=1Nexp⁡(−yiFm(xi))=∑i=1Nexp⁡(−yi(Fm−1(xi)+αmGm(xi)))\text { Loss }=\sum_{i=1}^{N} \exp \left(-y_{i} F_{m}\left(x_{i}\right)\right)=\sum_{i=1}^{N} \exp \left(-y_{i}\left(F_{m-1}\left(x_{i}\right)+\alpha_{m} G_{m}\left(x_{i}\right)\right)\right)  Loss =i=1∑N​exp(−yi​Fm​(xi​))=i=1∑N​exp(−yi​(Fm−1​(xi​)+αm​Gm​(xi​)))因为Fm−1(x)F_{m-1}(x)Fm−1​(x)是已知的,所以将其移到前面:
Loss⁡=∑i=1Nwm,i~exp⁡(−yiαmGm(xi))\operatorname{Loss}=\sum_{i=1}^{N} \widetilde{w_{m, i}} \exp \left(-y_{i} \alpha_{m} G_{m}\left(x_{i}\right)\right) Loss=i=1∑N​wm,i​​exp(−yi​αm​Gm​(xi​))其中,wm,i~=exp⁡(−yi(Fm−1(x)))\widetilde{w_{m, i}}=\exp \left(-y_{i}\left(F_{m-1}(x)\right)\right)wm,i​​=exp(−yi​(Fm−1​(x)))是每轮迭代的样本权重,证明化简如下:
wm,i~=exp⁡(−yi(Fm−2(xi)+αm−1Gm−1(xi)))\widetilde{w_{m, i}}=\exp \left(-y_{i}\left(F_{m-2}\left(x_{i}\right)+\alpha_{m-1} G_{m-1}\left(x_{i}\right)\right)\right) wm,i​​=exp(−yi​(Fm−2​(xi​)+αm−1​Gm−1​(xi​)))=wm−1,i~exp⁡(−yiαm−1Gm−1(xi))=\widetilde{w_{m-1, i}} \exp \left(-y_{i} \alpha_{m-1} G_{m-1}\left(x_{i}\right)\right) =wm−1,i​​exp(−yi​αm−1​Gm−1​(xi​))继续化简Loss:
Loss=∑i=1Nwm,i~exp⁡(−yiαmGm(xi))L o s s=\sum_{i=1}^{N} \widetilde{w_{m, i}} \exp \left(-y_{i} \alpha_{m} G_{m}\left(x_{i}\right)\right) Loss=i=1∑N​wm,i​​exp(−yi​αm​Gm​(xi​))=∑yi=Gm(xi)wm,i~exp⁡(−αm)+∑yi≠Gm(xi)wm,i~exp⁡(αm)=\sum_{y_{i}=G_{m}\left(x_{i}\right)} \widetilde{w_{m, i}} \exp \left(-\alpha_{m}\right)+\sum_{y_{i} \neq G_{m}\left(x_{i}\right)} \widetilde{w_{m, i}} \exp \left(\alpha_{m}\right) =yi​=Gm​(xi​)∑​wm,i​​exp(−αm​)+yi​​=Gm​(xi​)∑​wm,i​​exp(αm​)=∑i=1Nwm,i~(∑yi=Gm(xi)wm,i~∑i=1Nwm,i~exp⁡(−αm)+∑yi≠Gm(xi)wm,i~∑i=1Nwm,i~exp⁡(αm))=\sum_{i=1}^{N} \widetilde{w_{m, i}}\left(\frac{\sum_{y_{i}=G_{m}\left(x_{i}\right)} \widetilde{w_{m, i}}}{\sum_{i=1}^{N} \widetilde{w_{m, i}}} \exp \left(-\alpha_{m}\right)+\frac{\sum_{y_{i} \neq G_{m}\left(x_{i}\right)} \widetilde{w_{m, i}}}{\sum_{i=1}^{N} \widetilde{w_{m, i}}} \exp \left(\alpha_{m}\right)\right) =i=1∑N​wm,i​​(∑i=1N​wm,i​​∑yi​=Gm​(xi​)​wm,i​​​exp(−αm​)+∑i=1N​wm,i​​∑yi​​=Gm​(xi​)​wm,i​​​exp(αm​))重写Loss:
Loss =∑Ni=1wm,i((1−em)exp⁡(−αm)+emexp⁡(αm))\text { Loss }=\sum_{N}^{i=1} w_{m, i}\left(\left(1-e_{m}\right) \exp \left(-\alpha_{m}\right)+e_{m} \exp \left(\alpha_{m}\right)\right)  Loss =N∑i=1​wm,i​((1−em​)exp(−αm​)+em​exp(αm​))对ama_{m}am​求偏导,并令其为0,则有:
αm=12log⁡1−emem\alpha_{m}=\frac{1}{2} \log \frac{1-e_{m}}{e_{m}} αm​=21​logem​1−em​​

Adaboost算法实例讲解


上表表示是10个一维样本的数据。第一列表示样本的编号,第二列表示样本特征的值,第三列表示样本对应的实际类别,第四列表示的是样本的权重值,第五列表示的是预测的样本,第六列表示预测的类标是否准确,第七列表示的是样本权重更新后的值。根据上面Adaboost的步骤,详细介绍权重的更新过程

(1)计算权重的错误率,预测类标与实际类标相等用0表示,否则用1表示,所以预测错误的样本有三个
ε=ω∗(y^!=y)=0.1∗∑i=110(y^i!=yi)=0.1∗3=0.3\varepsilon=\omega *(\hat{y}!=y)=0.1 * \sum_{i=1}^{10}\left(\hat{y}_{i}!=y_{i}\right)=0.1 * 3=0.3 ε=ω∗(y^​!=y)=0.1∗i=1∑10​(y^​i​!=yi​)=0.1∗3=0.3
(2)计算相关系数
αj=0.5∗log⁡1−εε=0.5∗log⁡1−0.30.3=0.424\alpha_{j}=0.5 * \log \frac{1-\varepsilon}{\varepsilon}=0.5 * \log \frac{1-0.3}{0.3}=0.424 αj​=0.5∗logε1−ε​=0.5∗log0.31−0.3​=0.424
(3)更新权重
ω∗e(−αj∗y^∗y)=ω\omega * e^{\left(-\alpha_{j} * \hat{y} * y\right)}=\omegaω∗e(−αj​∗y^​∗y)=ω(y^表示预测值,y表示实际值)(\hat{y}表示预测值,y表示实际值)(y^​表示预测值,y表示实际值)(ω、y^、y都表示一个所有样本的(10维)向量)(\omega、\hat{y}、y都表示一个所有样本的(10维)向量)(ω、y^​、y都表示一个所有样本的(10维)向量)

单个样本预测错误则更新后的权重为
ω=0.1∗e(−0.424∗(−1)∗1)=0.153或者ω=0.1∗e(−0.424∗1∗(−1))=0.153\omega=0.1 * e^{(-0.424 *(-1) * 1)}=0.153或者\omega=0.1 * e^{(-0.424 * 1 *(-1))}=0.153 ω=0.1∗e(−0.424∗(−1)∗1)=0.153或者ω=0.1∗e(−0.424∗1∗(−1))=0.153单个样本预测错误则更新后的权重为ω=0.1∗e(−0.424∗1∗1)=0.066\omega=0.1 * e^{(-0.424 * 1 * 1)}=0.066 ω=0.1∗e(−0.424∗1∗1)=0.066
(4)权重归一化
∑i=110ωi=7∗0.065+3∗0.153=0.914\sum_{i=1}^{10} \omega_{i}=7^{*} 0.065+3^{*} 0.153=0.914 i=1∑10​ωi​=7∗0.065+3∗0.153=0.914预测正确的权重,归一化后的权重为0.0660.914=0.072\frac{0.066}{0.914}=0.072 0.9140.066​=0.072预测错误的权重,归一化后的权重为0.1530.914=0.167\frac{0.153}{0.914}=0.167 0.9140.153​=0.167通过一轮权重的更新可以发现,之前预测正确的权重由0.1变成了0.072,预测错误的权重由0.1变成了0.167,所以说,权重更新的过程中,会增大预测错误样本的权重,同时也会减小预测正确样本的权重。

Adaboost原理案例举例

import numpy as np
from sklearn.ensemble import AdaBoostClassifier
from sklearn import tree
import matplotlib.pyplot as pltX = np.arange(10).reshape(-1,1)
y = np.array([1,1,1,-1,-1,-1,1,1,1,-1])
display(X,y)
#array([[0],
#       [1],
#       [2],
#       [3],
#       [4],
#       [5],
#       [6],
#       [7],
#       [8],
#       [9]])
#array([ 1,  1,  1, -1, -1, -1,  1,  1,  1, -1])ada = AdaBoostClassifier(n_estimators=3,algorithm="SAMME)
ada.fit(X,y)

迭代过程1

plt.figure(figsize=(9,6))
tree.plot_tree(ada[0])


对于m=1,在权值分布为D1(10个数据,每个数据的权值皆初始化为0.1)的训练数据上,经过计算可得:

  • 阈值v取2.5时误差率为0.3(x < 2.5时取1,x > 2.5时取-1,则6 7 8分错,误差率为0.3)
  • 阈值v取5.5时误差率最低为0.4(x < 5.5时取1,x > 5.5时取-1,则3 4 5 6 7 8皆分错,误差率0.6大于0.5,不可取。故令x > 5.5时取1,x < 5.5时取-1,则0 1 2 9分错,误差率为0.4)
  • 阈值v取8.5时误差率为0.3(x < 8.5时取1,x > 8.5时取-1,则3 4 5分错,误差率为0.3)

可以看到,无论阈值v取2.5,还是8.5,总得分错3个样本,故可任取其中任意一个如2.5,弄成第一个基本分类器为:G1(x)={1,x<2.5−1,x>2.5G_{1}(x)=\left\{\begin{array}{ll} 1, & x<2.5 \\ -1, & x>2.5 \end{array}\right. G1​(x)={1,−1,​x<2.5x>2.5​

y_ = ada[0].predict(X)
y_
#array([ 1,  1,  1, -1, -1, -1, -1, -1, -1, -1])
#真实标签y = array([ 1,  1,  1, -1, -1, -1,  1,  1,  1, -1])#误差率
e1 = np.round(0.1*(y != y_).sum(),4)
e1
#0.3#计算第一棵树的权重
#随机森林中每棵树的权重是一样的
#adaboost提升树中每棵树的权重不同
a1 = np.round(1/2*np.log((1-e1)/e1),4)
a1
#0.4236#样本预测准确:更新的权重
w2 = 0.1*np.e**(-a1*y*y_)
w2 = w2/w2.sum()
np.round(w2,4)
#array([0.0714, 0.0714, 0.0714, 0.0714, 0.0714, 0.0714, 0.1667, 0.1667,
#       0.1667, 0.0714])

从上述第一轮的整个迭代过程可以看出:被误分类样本的权值之和影响误差率,误差率影响基本分类器在最终分类器中所占的权重

分类函数f1(x)= a1*G1(x)= 0.4236G1(x)

迭代过程2

plt.figure(figsize=(9,6))
tree.plot_tree(ada[1])


对于m=2,在权值分布为D2 = (0.0715, 0.0715, 0.0715, 0.0715, 0.0715, 0.0715, 0.1666, 0.1666, 0.1666, 0.0715)的训练数据上,经过计算可得:

  • 阈值v取2.5时误差率为0.1666 * 3(x < 2.5时取1,x > 2.5时取-1,则6 7 8分错,误差率为0.1666 * 3),
  • 阈值v取5.5时误差率最低为0.0715 * 4(x > 5.5时取1,x < 5.5时取-1,则0 1 2 9分错,误差率为0.0715 * 3 + 0.0715),
  • 阈值v取8.5时误差率为0.0715 * 3(x < 8.5时取1,x > 8.5时取-1,则3 4 5分错,误差率为0.0715 * 3)。

所以,阈值v取8.5时误差率最低,故第二个基本分类器为:
G2(x)={1,x<8.5−1,x>8.5G_{2}(x)=\left\{\begin{array}{ll} 1, & x<8.5 \\ -1, & x>8.5 \end{array}\right. G2​(x)={1,−1,​x<8.5x>8.5​

ada[1].predict(X)
#array([ 1,  1,  1,  1,  1,  1,  1,  1,  1, -1])
#真实标签y = array([ 1,  1,  1, -1, -1, -1,  1,  1,  1, -1])e2 = 0.0714*3
e2
#0.2142a2 = np.round(1/2*np.log((1-e2)/e2),4)
a2
#0.6499y_ = ada[1].predict(X)
#样本预测准确:更新的权重
w3 = w2*np.e**(-a2*y*y_)
w3 = w3/w3.sum()
np.round(w3,4)
#array([0.0454, 0.0454, 0.0454, 0.1667, 0.1667, 0.1667, 0.106 , 0.106 ,
#       0.106 , 0.0454])

被分错的样本“ 3 4 5 ”的权值变大,其它被分对的样本的权值变小。

f2(x)=0.4236G1(x) + 0.6496G2(x)

迭代过程3

plt.figure(figsize=(9,6))
tree.plot_tree(ada[2])


对于m=3,在权值分布为D3 = (0.0455, 0.0455, 0.0455, 0.1667, 0.1667, 0.01667, 0.1060, 0.1060, 0.1060, 0.0455)的训练数据上,经过计算可得:

  • 阈值v取2.5时误差率为0.1060 * 3(x < 2.5时取1,x > 2.5时取-1,则6 7 8分错,误差率为0.1060 * 3),
  • 阈值v取5.5时误差率最低为0.0455 * 4(x > 5.5时取1,x < 5.5时取-1,则0 1 2 9分错,误差率为0.0455 * 3 + 0.0715),
  • 阈值v取8.5时误差率为0.1667*3(x < 8.5时取1,x > 8.5时取-1,则3 4 5分错,误差率为0.1667 * 3)。

所以阈值v取5.5时误差率最低,故第三个基本分类器为:
G3(x)={1,x>5.5−1,x<5.5G_{3}(x)=\left\{\begin{array}{cc} 1, & x>5.5 \\ -1, & x<5.5 \end{array}\right. G3​(x)={1,−1,​x>5.5x<5.5​

ada[2].predict(X)
#array([-1, -1, -1, -1, -1, -1,  1,  1,  1,  1])
#真实标签y = array([ 1,  1,  1, -1, -1, -1,  1,  1,  1, -1])e3 = (w3*(y_ != y)).sum()
e3
#0.182a3 = 1/2*np.log((1-e3)/e3)
a3
#0.7514#样本预测准确:更新的权重
y_ = ada[2].predict(X)
w4 = w3*np.e**(-a3*y*y_)
w4 = w4/w4.sum()
np.round(w4,4)
#array([0.125 , 0.125 , 0.125 , 0.1019, 0.1019, 0.1019, 0.0648, 0.0648,
#       0.0648, 0.125 ])

弱分类器合并成强分类器

综上,将上面计算得到的a1、a2、a3各值代入G(x)中,G(x) = sign[f3(x)] = sign[ a1 * G1(x) + a2 * G2(x) + a3 * G3(x) ],得到最终的分类器为:

G(x) = sign[f3(x)] = sign[ 0.4236G1(x) + 0.6496G2(x)+0.7514G3(x) ]

ada.predict(X)
#array([ 1,  1,  1, -1, -1, -1,  1,  1,  1, -1])y_predict = a1*ada[0].predict(X) +  a2*ada[1].predict(X) +a3*ada[2].predict(X)
y_predict
np.sign(y_predict).astype(np.int)
#array([ 1,  1,  1, -1, -1, -1,  1,  1,  1, -1])

Adaboost原理相关推荐

  1. AdaBoost原理说明

    AdaBoost原理说明 文章目录 AdaBoost原理说明 提升方法(Boosting)的基本思想 AdaBoost的推导 AdaBoost的算法流程 AdaBoost的例子 AdaBoost算法的 ...

  2. [机器学习] Adaboost原理及实现

    Boost   Adaboost(adaptive boosting)是一种集成学习算法,基于boosting的框架,因此首先简单说一下boosting算法.boosting算法主要的目的是将&quo ...

  3. 机器学习-分类之AdaBoost原理及实战

    AdaBoost算法 简介 当一个分类器正确率不那么高时,称其为"弱分类器",或者说该分类器的学习方法为"弱学习方法".与之对应的,存在"强分类器&q ...

  4. Adaboost原理和实例

    Adaboost算法原理分析和实例 资源: [1]http://blog.csdn.net/v_july_v/article/details/40718799 [2]http://blog.csdn. ...

  5. Bagging与Boosting算法的原理与区别,Boosting算法之一Adaboost原理与代码实现

    1. Bagging和Boosting的原理与区别 在讲解Boosting之前,必须提一下Bagging算法.两者作为机器学习中集成学习的主要算法,其思想是必须理解和掌握的.总的来说Bagging和B ...

  6. 傻子都能看懂的——详解AdaBoost原理

    之前纠结是否要离开CSDN,最近还是决定留下来继续. 关于Boost 集成学习中有两个重要概念,分别为Bagging和Boost.其中Boost也被称为增强学习或提升法,是一种重要的集成学习方法,它能 ...

  7. Adaboost原理与推导

    https://blog.csdn.net/v_july_v/article/details/40718799

  8. adaboost 算法 原理

    Adaboost 算法 算法简介 (1)adaboost是有监督的分类算法 有监督 无监督的区别,直观来看,区别在于训练集中,是否需要包括因变量Y. 例如: 无监督算法 -- K-means聚类算法, ...

  9. 【机器学习实战】第7章 集成方法(随机森林和 AdaBoost)

    第7章 集成方法 ensemble method 集成方法: ensemble method(元算法: meta algorithm) 概述 概念:是对其他算法进行组合的一种形式. 通俗来说: 当做重 ...

最新文章

  1. Python设计模式-观察者模式
  2. Windows下RabbitMQ安装及注意事项
  3. swift语言和python区别_Swift为什么能成为编程语言中的黑马?
  4. 通过微调JVM Garbage Collector减少Java IDE滞后
  5. 给定两个整数m和n,求出m~n这段连续的整数中所有偶数的平方和以及所有奇数的立方和。
  6. Python中获取当前日期的格式
  7. 如何在家搭建oracle,oracle基本操作,自己亲手做过了
  8. Checkstyle的配置集
  9. Qt C++ QSerialPortInfo的测试
  10. HTML5 学习准备1
  11. UGUI ScrollRect 滑动
  12. 如何优雅的注入Java Agent内存马
  13. 【代码复现问题】apex安装不上+win10分布式训练出问题
  14. Win10系统U盘启动盘制作详解
  15. linux格式化命令,Linux怎么格式化磁盘啊?
  16. MOS开关管额定电流的选择
  17. 张鑫溢:9.21黄金原油独家操作建议指导.
  18. 使用C51单片机实现《两只老虎》
  19. 他,用了8年,从程序员到CTO再到天使投资人蝶变记
  20. Vue项目JSON格式字符串和对象之间的互转

热门文章

  1. 手把手教你怎么撩妹,五分钟读懂!提取于《谈话的力量》
  2. 《银行法律法规》一、经济金融基础知识——2、金融基础知识
  3. 优秀员工的德商,智商,情商课程笔记
  4. 微软的 windows 的发展历程-潮起潮落
  5. Android 智能上拉加载下拉刷新框架之SmartRefreshLayout
  6. 突破网站对Selenium的屏蔽
  7. uni-app页面中使用本地背景图片
  8. unity之使用unet创建局域网游戏
  9. php微信绑定银行卡号,《微信》免输卡号绑定银行卡方法介绍
  10. Java的jdk安装教程: