赞
踩
KNN是通过测量不同特征值之间的距离进行分类。它的的思路是:
如果一个样本在特征空间中的k个最相似(即特征空间中最邻近)的样
本中的大多数属于某一个类别,则该样本也属于这个类别。K通常
是不大于20的整数。KNN算法中,所选择的邻居都是已经正确分
类的对象。该方法在定类决策上只依据最邻近的一个或者几个样本
的类别来决定待分样本所属的类别。
适用于稀有事件的分类问题
如图,绿色圆要被决定赋予哪个类,是红色三角形还是蓝色四方形?如果K=3,由于红色三角形所占比例为2/3,绿色圆将被赋予红色三角形那个类,如果K=5,由于蓝色四方形比例为3/5,因此绿色圆被赋予蓝色四方形类。
from sklearn.neighbors import KNeighborsClassifier
#定义随KNN分类器 参数N为邻居数目
knn = KNeighborsClassifier(n_neighbors=10)
#训练过程 X为特征向量,y为标签数据/向量
knn.fit(X, y)
给定训练样本集 D { ( x 1 , y 1 ) , ( x 2 , y 2 ) , … , ( x m , y m ) } , y ∈ { − 1 , + 1 } D\{(x_1,y_1),(x_2,y_2),\dotsc,(x_m,y_m)\},y\in\{-1,+1\} D{(x1,y1),(x2,y2),…,(xm,ym)},y∈{−1,+1},SVM的基本思想就是基于训练集合 D D D在样本空间中找到一个划分超平面,将不同的类别样本分开。理论上会存在无数个超平面存在,如下图所示。
由于训练集中存在局限性或噪声的因素,训练集外的样本(例如测试集)可能比图中的训练样本更接近两个分类的分割界,通过肉眼观察图中较粗的线受到的影响最小,即具有鲁棒性,泛化能力强。
在样本空间中,划分超平面可以按照如下方程进行描述:
w
T
x
+
b
=
0
w^Tx+b=0
wTx+b=0
其中
w
=
(
w
1
;
w
2
;
…
;
w
d
)
w=(w_1;w_2;\dotsc;w_d)
w=(w1;w2;…;wd)为法向量,决定了超平面的方向;
b
b
b为位移项,决定了超平面与原点之间的距离。因此可以用
(
w
,
b
)
(w,b)
(w,b)来描述一个超平面。样本空间中任意点
x
x
x到超平面
(
w
,
b
)
(w,b)
(w,b)的距离可以写为:
r
=
∣
w
T
x
+
b
∣
∥
w
∥
r= \frac{\left|w^Tx+b \right|}{\left \| w \right \|}
r=∥w∥∣∣wTx+b∣∣
假设超平面
(
w
,
b
)
(w,b)
(w,b)可以将训练样本正确分类,即对于
(
x
i
,
y
i
)
∈
D
(x_i,y_i)\in D
(xi,yi)∈D,若
y
i
=
+
1
y_i=+1
yi=+1,则有
w
T
x
+
b
>
0
w^Tx+b>0
wTx+b>0;若
y
i
=
−
1
y_i=-1
yi=−1,则有
w
T
x
+
b
<
0
w^Tx+b<0
wTx+b<0,令:
{
w
T
x
+
b
⩾
+
1
,
y
i
=
+
1
;
w
T
x
+
b
⩽
−
1
,
y
i
=
−
1.
{wTx+b⩾+1,yi=+1;wTx+b⩽−1,yi=−1.
距离超平面最近的几个训练样本且使上式成立,被称为“支持向量”(support vector),两个异类支持向量到超平面的距离之和为:
γ
=
2
∥
w
∥
\gamma = \frac{2}{\left \| w \right \|}
γ=∥w∥2
该距离被称为“间隔”(margin),即为SVM主要进行工作的区间,对于该二分类问题,在间隔内的为难以区分的类型(因为异类距离很近),如果该类型都可以很好的区分开来,那么间隔外的样本都可以很好的区分开。可以参考下图进行理解。
因此SVM的核心就是如何找到“最大间隔”的划分超平面,也就是要找到能满足上式中约束的参数
w
w
w和
b
b
b,使得
γ
\gamma
γ最大,即
m
a
x
w
,
b
2
∥
w
∥
s
.
t
.
y
i
(
w
T
x
+
b
)
⩾
1
,
i
=
1
,
2
,
…
,
m
maxw,b2‖w‖s.t.yi(wTx+b)⩾1,i=1,2,…,m
为了达到最大化间隔,仅需最大化
∥
w
∥
−
1
\left \| w \right \|^{-1}
∥w∥−1,等价于最小化
∥
w
∥
2
\left \| w \right \|^{2}
∥w∥2;因此支持向量机(Support Vector Machine, 简称为SVM)的基本型。
为了求解线性可分支持向量机的最优化问题,将它作为原始最优化问题,应用拉格朗日对偶性,通过求解对偶问题(dual problem)得到原始问题(primal problem)的最优解。这样做的好处是,一是对偶问题往往更容易求解;二是引入核函数,进而推广到非线性分类问题。
首先引入拉格朗日函数(Lagrange function),对每个不等式约束引进拉格朗日乘子(Lagrange multiplier),函数如下:
L
(
w
,
b
,
α
)
=
1
2
∥
w
∥
2
−
∑
i
=
1
m
α
i
[
(
w
x
i
+
b
)
y
i
−
1
]
L(w,b,\alpha)=\frac{1}{2}\left \| w \right \|^2-\sum_{i=1}^m\alpha_i[(wx_i+b)y_i- 1]
L(w,b,α)=21∥w∥2−i=1∑mαi[(wxi+b)yi−1]
其中
α
=
(
α
1
,
α
2
,
…
,
α
m
)
\alpha=(\alpha_1,\alpha_2,\dotsc,\alpha_m)
α=(α1,α2,…,αm), 最优问题解由鞍点决定,因此符合两个条件:
∂
L
∂
w
=
0
\frac{\partial L}{\partial w}=0
∂w∂L=0
∂
L
∂
b
=
0
\frac{\partial L}{\partial b}=0
∂b∂L=0
可以得到:
w
=
∑
i
=
1
m
a
i
y
i
x
i
w=\sum_{i=1}^m a_iy_ix_i
w=i=1∑maiyixi
带入拉格朗日函数中可消去
w
w
w和
b
b
b,而下式为新的约束条件
0
=
∑
i
=
1
m
a
i
y
i
0=\sum_{i=1}^ma_iy_i
0=i=1∑maiyi
因此最终拉格朗日函数变为:
Q
(
α
)
=
∑
i
N
α
i
−
1
2
∑
i
m
∑
i
m
α
i
α
j
y
i
y
j
x
i
x
j
s
.
t
.
∑
i
=
1
m
a
i
y
i
=
0
,
a
i
⩾
0
,
i
=
1
,
2
,
…
,
m
.
Q(α)=N∑iαi−12m∑im∑iαiαjyiyjxixjs.t.m∑i=1aiyi=0,ai⩾0 ,i=1,2,…,m .
通过上式可解
α
\alpha
α,随后求出
w
w
w和
b
b
b即可得到模型:
f
(
x
)
=
w
T
x
+
b
=
∑
i
=
1
m
a
i
y
i
x
i
T
x
+
b
f(x)=wTx+b=m∑i=1aiyixTix+b
上述过程需满足KKT(Karush-Kuhn-Tucker),即要求
{
a
i
⩾
0
;
y
i
f
(
x
i
)
−
1
⩾
0
;
α
i
(
y
i
f
(
x
i
)
−
1
)
=
0
.
{ai⩾0 ;yif(xi)−1⩾0 ;αi(yif(xi)−1)=0 .
线性不可分问题边界为:
(
w
x
i
+
b
)
y
i
≥
1
−
ξ
i
(wx_i+b)y_i\ge 1-\xi_i
(wxi+b)yi≥1−ξi
支持向量定义为:
(
w
x
s
+
b
)
y
s
=
1
−
ξ
s
(wx_s+b)y_s= 1-\xi_s
(wxs+b)ys=1−ξs
当
ξ
<
0
\xi<0
ξ<0时对应正常情况,当
0
<
ξ
≤
1
0<\xi\le 1
0<ξ≤1是在分类区域内,但是在决策曲面正确的一侧,当
ξ
>
1
\xi>1
ξ>1在决策曲面错误一侧。
我们目标是使得整个超平面上错误目标最小,因此在损失函数之中引入新项:
Φ
(
ξ
)
=
∑
i
U
n
i
t
(
ξ
i
)
(
ξ
i
−
1
)
\Phi(\xi)=\sum_i Unit(\xi_i)(\xi_i-1)
Φ(ξ)=i∑Unit(ξi)(ξi−1)
简化,使得NP完全问题变为可解问题:
Φ
(
ξ
)
=
∑
i
ξ
i
\Phi(\xi)=\sum_i \xi_i
Φ(ξ)=i∑ξi
拉格朗日函数变为:
L
(
w
,
b
,
α
)
=
1
2
∥
w
∥
2
+
C
∑
i
ξ
i
−
∑
i
N
α
i
[
(
w
x
i
+
b
)
y
i
−
1
+
ξ
i
]
L(w,b,\alpha)=\frac{1}{2}\left \| w \right \|^2+C\sum_i \xi_i -\sum_i^N\alpha_i[(wx_i+b)y_i- 1+\xi_i]
L(w,b,α)=21∥w∥2+Ci∑ξi−i∑Nαi[(wxi+b)yi−1+ξi]
ξ
i
≥
0
\xi_i\ge 0
ξi≥0
为了解决线性不可分问题引入核函数:
Q
(
α
)
=
∑
i
N
α
i
−
1
2
∑
i
N
∑
i
N
α
i
α
j
d
i
d
j
k
(
x
i
,
x
j
)
Q(\alpha)=\sum_i^N \alpha_i - \frac 1 2 \sum_i^N \sum_i^N \alpha_i \alpha_j d_i d_j k(x_i, x_j)
Q(α)=i∑Nαi−21i∑Ni∑Nαiαjdidjk(xi,xj)
其中:
支持向量 | k ( x , x i ) k(x, x_i) k(x,xi) | 指定参数 |
---|---|---|
多项式 | ( x T x i ) d (x^T x_i)^d (xTxi)d | d ⩾ 1 d\geqslant1 d⩾1 为多项式的次数,当d=1时退化为线性核 |
高斯核 | e − 1 2 σ 2 ∥ x − x i ∥ 2 e^{-\frac{1}{2\sigma^2}\left \| x-x_i \right \|^2} e−2σ21∥x−xi∥2 | σ > 0 \sigma>0 σ>0为高斯核的带宽 |
from sklearn.svm import SVC
NBM = [SVC(kernel='linear', C=1.0), #其中C即为上文所提到的松弛变量,C越小间隔范围越大
SVC(kernel='rbf', C=1.0, gamma=1.), #gamma为高斯核的带宽
SVC(kernel='poly', C=1.0, degree=3)] #degree为多项式次数
NAME= ["LINEAR","RBF","poly"]
for itr, itrname in zip(NBM, NAME):
#训练过程
print("Training...")
itr.fit(X_train, y_train)
print("Applying...")
y_train_pdt = itr.predict(X_train)
y_pdt = itr.predict(X_test)
贝叶斯公式 + 条件独立假设 = 朴素贝叶斯方法
P
(
Y
∣
X
)
=
P
(
X
∣
Y
)
P
(
Y
)
P
(
X
)
P(Y|X)=\frac{P(X|Y)P(Y)}{P(X)}
P(Y∣X)=P(X)P(X∣Y)P(Y)
其中P(Y)叫做先验概率,P(Y|X)叫做后验概率,P(Y,X)叫做联合概率。
由于计算时具有某特征而属于某类无法直接通过统计得到,比如有十个属性而求相应类概率是比较复杂的,但是反过来求对应类会有那些属性概率则可以通过统计得到,因此需要用到上面所说的概率公式将其转换。当然朴素贝叶斯算法有个更加强的假设,就是属性间相互独立,也就是概率可以进行相乘,这也是“朴素”贝叶斯的来源:
P
(
v
1
,
⋯
,
v
n
∣
x
k
)
=
Π
P
(
v
i
∣
x
k
)
P(v_1,\cdots,v_n|x_k)=\Pi P(v_i|x_k)
P(v1,⋯,vn∣xk)=ΠP(vi∣xk)
当特征属性为连续值时,通常假定其值服从高斯分布(也称正态分布)。离散特征属性多的情况下
p
(
x
1
,
p
,
(
x
2
)
,
…
,
p
(
x
n
)
p(x_1,p,(x_2),\dotsc,p(x_n)
p(x1,p,(x2),…,p(xn)可以取
l
o
g
log
log
from sklearn.naive_bayes import GaussianNB
#定义高斯分类器类
gnb = GaussianNB()
#训练过程
gnb.fit(X, y)
结束上述分类算法的介绍后,需要对数据进行分类,对于分类的结果据需要进入过拟合和欠拟合的概念。
简单来说,集成学习是一种技术框架,其按照不同的思路来组合基础模型,从而达到其利断金的目的。
目前,有三种常见的集成学习框架:bagging,boosting和stacking。国内,南京大学的周志华教授对集成学习有很深入的研究,其在09年发表的一篇概述性论文《Ensemble Learning》对这三种集成学习框架有了明确的定义,概括如下:
模型的偏差是一个相对来说简单的概念:训练出来的模型在训练集上的准确度。
要解释模型的方差,首先需要重新审视模型:模型是随机变量。设样本容量为n的训练集为随机变量的集合 x 1 , x 2 , ⋯ , x n x_1,x_2,\cdots,x_n x1,x2,⋯,xn,那么模型是以这些随机变量为输入的随机变量函数。抽样的随机性带来了模型的随机性。
定义随机变量的值的差异是计算方差的前提条件,通常来说,我们遇到的都是数值型的随机变量,数值之间的差异再明显不过(减法运算)。但是,模型的差异性呢?我们可以理解模型的差异性为模型的结构差异,例如:线性模型中权值向量的差异,树模型中树的结构差异等。在研究模型方差的问题上,我们并不需要对方差进行定量计算,只需要知道其概念即可。
研究模型的方差有什么现实的意义呢?我们认为方差越大的模型越容易过拟合:假设有两个训练集A和B,经过A训练的模型Fa与经过B训练的模型Fb差异很大,这意味着Fa在类A的样本集合上有更好的性能,而Fb反之,这便是我们所说的过拟合现象。
我们常说集成学习框架中的基模型是弱模型,通常来说弱模型是偏差高(在训练集上准确度低)方差小(防止过拟合能力强)的模型。但是,并不是所有集成学习框架中的基模型都是弱模型。bagging和stacking中的基模型为强模型(偏差低方差高),boosting中的基模型为弱模型。
在bagging和boosting框架中,通过计算基模型的期望和方差,我们可以得到模型整体的期望和方差。为了简化模型,我们假设基模型的权重、方差及两两间的相关系数相等。由于bagging和boosting的基模型都是线性组成的,那么有:
假设m个模型对某个变量 x x x预测结果分别为 f 1 , ⋯ , f m f_1,\cdots,f_m f1,⋯,fm,最终预测结果是多个模型加权平均 f = ∑ i m γ i f i f=\sum_i^m \gamma_i f_i f=∑imγifi。假设每个个模型的均值和方差是相等的 μ , σ 2 \mu, \sigma^2 μ,σ2。
E ( f ) = ∑ i m γ i E ( f i ) = ∑ i γ i μ \mathbb{E}(f)=\sum_i^m \gamma_i \mathbb{E}(f_i)=\sum_i \gamma_i \mu E(f)=i∑mγiE(fi)=i∑γiμ
V a r ( f ) = C o v ( ∑ i γ i f i , ∑ j γ j f j ) = m 2 γ 2 σ 2 ρ + m γ 2 σ 2 ( 1 − ρ ) Var(f)=Cov(\sum_i \gamma_i f_i, \sum_j \gamma_j f_j)\\=m^2\gamma^2\sigma^2\rho + m\gamma^2\sigma^2(1-\rho) Var(f)=Cov(i∑γifi,j∑γjfj)=m2γ2σ2ρ+mγ2σ2(1−ρ)
这里 ρ \rho ρ代表相关系数
对于bagging来说,每个基模型的权重等于1/m且期望近似相等(子训练集都是从原训练集中进行子抽样),故我们可以进一步化简得到:
E
(
f
)
=
μ
V
a
r
(
f
)
=
σ
2
ρ
+
σ
2
(
1
−
ρ
)
m
\mathbb{E}(f)=\mu\\ Var(f)=\sigma^2 \rho + \frac{\sigma^2(1-\rho)}{m}
E(f)=μVar(f)=σ2ρ+mσ2(1−ρ)
根据上式我们可以看到,整体模型的期望近似于基模型的期望,这也就意味着整体模型的偏差和基模型的偏差近似。同时,整体模型的方差小于等于基模型的方差(当相关性为1时取等号),随着基模型数(m)的增多,整体模型的方差减少,从而防止过拟合的能力增强,模型的准确度得到提高。但是,模型的准确度一定会无限逼近于1吗?并不一定,当基模型数增加到一定程度时,方差公式第二项的改变对整体方差的作用很小,防止过拟合的能力达到极限,这便是准确度的极限了。另外,在此我们还知道了为什么bagging中的基模型一定要为强模型,否则就会导致整体模型的偏差度低,即准确度低。
Random Forest是典型的基于bagging框架的模型,其在bagging的基础上,进一步降低了模型的方差。Random Fores中基模型是树模型,在树的内部节点分裂过程中,不再是将所有特征,而是随机抽样一部分特征纳入分裂的候选项。这样一来,基模型之间的相关性降低,从而在方差公式中,第一项显著减少,第二项稍微增加,整体方差仍是减少。
对于boosting来说,基模型的训练集抽样是强相关的,那么模型的相关系数近似等于1,故我们也可以针对boosting化简公式为
E
(
f
)
=
∑
i
γ
i
μ
i
V
a
r
(
f
)
=
m
2
γ
2
σ
2
E(f)=\sum_i \gamma_i \mu_i\\ Var(f)=m^2 \gamma^2 \sigma^2
E(f)=i∑γiμiVar(f)=m2γ2σ2
通过观察整体方差的表达式,我们容易发现,若基模型不是弱模型,其方差相对较大,这将导致整体模型的方差很大,即无法达到防止过拟合的效果。因此,boosting框架中的基模型必须为弱模型。
因为基模型为弱模型,导致了每个基模型的准确度都不是很高(因为其在训练集上的准确度不高)。随着基模型数的增多,整体模型的期望值增加,更接近真实值,因此,整体模型的准确度提高。但是准确度一定会无限逼近于1吗?仍然并不一定,因为训练过程中准确度的提高的主要功臣是整体模型在训练集上的准确度提高,而随着训练的进行,整体模型的方差变大,导致防止过拟合的能力变弱,最终导致了准确度反而有所下降。
基于boosting框架的Gradient Tree Boosting模型中基模型也为树模型,同Random Forrest,我们也可以对特征进行随机抽样来使基模型间的相关性降低,从而达到减少方差的效果。
如何衡量基模型的独立性?我们说过,抽样的随机性决定了模型的随机性,如果两个模型的训练集抽样过程不独立,则两个模型则不独立。这时便有一个天大的陷阱在等着我们:bagging中基模型的训练样本都是独立的随机抽样,但是基模型却不独立呢?
我们讨论模型的随机性时,抽样是针对于样本的整体。而bagging中的抽样是针对于训练集(整体的子集),所以并不能称其为对整体的独立随机抽样。那么到底bagging中基模型的相关性体现在哪呢?在知乎问答《为什么说bagging是减少variance,而boosting是减少bias?》中请教用户“过拟合”后,我总结bagging的抽样为两个过程:
样本抽样:整体模型F(X1, X2, …, Xn)中各输入随机变量(X1, X2, …, Xn)对样本的抽样
子抽样:从整体模型F(X1, X2, …, Xn)中随机抽取若干输入随机变量成为基模型的输入随机变量
假若在子抽样的过程中,两个基模型抽取的输入随机变量有一定的重合,那么这两个基模型对整体样本的抽样将不再独立,这时基模型之间便具有了相关性。
- 使用模型的偏差和方差来描述其在训练集上的准确度和防止过拟合的能力
- 对于bagging来说,整体模型的偏差和基模型近似,随着训练的进行,整体模型的方差降低
- 对于boosting来说,整体模型的初始偏差较高,方差较低,随着训练的进行,整体模型的偏差降低(虽然也不幸地伴随着方差增高),当训练过度时,因方差增高,整体模型的准确度反而降低
- 整体模型的偏差和方差与基模型的偏差和方差息息相关
节选自博文:使用sklearn进行集成学习——理论
更多实例请参考
http://scikit-learn.org/stable/modules/ensemble.html
from sklearn.svm import SVC from sklearn.naive_bayes import GaussianNB from sklearn.neighbors import KNeighborsClassifier from sklearn.tree import DecisionTreeClassifier from sklearn.ensemble import AdaBoostClassifier from sklearn.ensemble import RandomForestClassifier import numpy as np from sklearn.externals import joblib from sklearn.decomposition import PCA import time # 示例数据以minist手写数字为例 # 为了加速计算将原先28X28=784个特征降维至36个 train = np.load("data/train.npz") test = np.load("data/test.npz") pca = PCA(n_components=36) X_r = pca.fit(train["images"]).transform(train["images"]) vect_t = np.array([[itr] for itr in range(10)]) X_train = X_r[:6000] y_train = np.dot(train["labels"][:6000], vect_t).ravel().astype("int") X_test = X_r[6000:12000] y_test = np.dot(train["labels"][6000:12000], vect_t).ravel().astype("int") #定义各算法分类器 NBM = [SVC(kernel='linear', C=0.5), SVC(kernel='rbf', C=0.5, gamma='auto'), SVC(kernel='poly', C=0.5, degree=3), KNeighborsClassifier(n_neighbors=11), GaussianNB(), DecisionTreeClassifier(max_depth=15, min_samples_split=5), #防止过拟合将树深设为10 AdaBoostClassifier(DecisionTreeClassifier(max_depth=15, min_samples_split=5), n_estimators=200, learning_rate=0.8),#选择决策树,迭代000次,学习率为0.8 RandomForestClassifier(n_estimators= 200, max_depth=10)] NAME= ["LINEAR","RBF","poly", "KNN_N11", "GNB", "DCT", "Boosting_Ada", "Bagging_RF"] for itr, itrname in zip(NBM, NAME): #训练过程 print("Training...") t1 = time.perf_counter() itr.fit(X_train, y_train) t2 = time.perf_counter() print("Applying...") y_train_pdt = itr.predict(X_train) t3 = time.perf_counter() y_pdt = itr.predict(X_test) # joblib.dump(itr, "model/svm_model"+itrname) dts1 = len(np.where(y_train_pdt==y_train)[0])/len(y_train) dts2 = len(np.where(y_pdt==y_test)[0])/len(y_test) print("训练集:{} 精度:{:.3f}%, 训练时间:{:.2f}s".format(itrname, dts1*100, t2 - t1)) print("测试集:{} 精度:{:.3f}%, 训练时间:{:.2f}s".format(itrname, dts2*100, t3 - t2))
结果:
Training... Applying... 训练集:LINEAR 精度:94.867%, 训练时间:0.49s 测试集:LINEAR 精度:89.900%, 训练时间:0.29s Training... Applying... 训练集:RBF 精度:97.483%, 训练时间:0.88s 测试集:RBF 精度:94.833%, 训练时间:0.84s Training... Applying... 训练集:poly 精度:97.567%, 训练时间:0.86s 测试集:poly 精度:94.550%, 训练时间:0.63s Training... Applying... 训练集:KNN 精度:95.367%, 训练时间:0.05s 测试集:KNN 精度:93.350%, 训练时间:1.83s Training... Applying... 训练集:GNB 精度:87.633%, 训练时间:0.00s 测试集:GNB 精度:84.267%, 训练时间:0.03s Training... Applying... 训练集:DCT 精度:95.733%, 训练时间:0.27s 测试集:DCT 精度:72.850%, 训练时间:0.00s Training... Applying... 训练集:Boosting 精度:100.000%, 训练时间:51.48s 测试集:Boosting 精度:92.650%, 训练时间:0.60s Training... Applying... 训练集:Bagging 精度:98.450%, 训练时间:4.87s 测试集:Bagging 精度:88.483%, 训练时间:0.21s
通过结果可以看出SVM分类器表现的效果比较理想;KNN和朴素贝叶斯分类器由于无需训练因此时间成本非常小,但效果一般;决策树分类器出现了过拟合,需要进行预剪枝来解决过拟合,可以通过设置最大树深以及其他超参;Adaboost使用了决策树作为基本分类器,也出现过拟合的结果,相比单颗决策树整体准确率有所提升,然而由于200次的迭代,付出了巨大的时间代价;最后随机森林也出现了过拟合的结果,说明每个决策树都或多或少存在过拟合的,还需要进一步的调参。
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。