kernel PCA

PCA不进行分类的动作,而只做做数据预处理,将样本变换到一个容易分类(向最大化方差的方向,principal component axes,投影)的更低维的新的特征空间中。Kernel PCA比PCA多了一步,也即先升维(RBF包括多项式核均是升高到无穷维)再进行投影的动作,因为有些非线性可分的数据集只有在升维的视角下才线性可分。

PCA

  • 均值化的数据: 
    ixi=0
<code class="hljs python has-numbering" style="display: block; padding: 0px; color: inherit; box-sizing: border-box; font-family: 'Source Code Pro', monospace;font-size:undefined; white-space: pre; border-radius: 0px; word-wrap: normal; background: transparent;"><span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;"># python </span>
<span class="hljs-prompt" style="color: rgb(0, 102, 102); box-sizing: border-box;">>>> </span>X-np.mean(X, <span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">0</span>)
                <span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;"># 一个二维矩阵减去一维向量?对,</span>
                <span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;"># 这里用到的技术是numpy中broadcasting(广播机制)</span></code><ul class="pre-numbering" style="box-sizing: border-box; position: absolute; width: 50px; top: 0px; left: 0px; margin: 0px; padding: 6px 0px 40px; border-right-width: 1px; border-right-style: solid; border-right-color: rgb(221, 221, 221); list-style: none; text-align: right; background-color: rgb(238, 238, 238);"><li style="box-sizing: border-box; padding: 0px 5px;">1</li><li style="box-sizing: border-box; padding: 0px 5px;">2</li><li style="box-sizing: border-box; padding: 0px 5px;">3</li><li style="box-sizing: border-box; padding: 0px 5px;">4</li></ul><ul class="pre-numbering" style="box-sizing: border-box; position: absolute; width: 50px; top: 0px; left: 0px; margin: 0px; padding: 6px 0px 40px; border-right-width: 1px; border-right-style: solid; border-right-color: rgb(221, 221, 221); list-style: none; text-align: right; background-color: rgb(238, 238, 238);"><li style="box-sizing: border-box; padding: 0px 5px;">1</li><li style="box-sizing: border-box; padding: 0px 5px;">2</li><li style="box-sizing: border-box; padding: 0px 5px;">3</li><li style="box-sizing: border-box; padding: 0px 5px;">4</li></ul>
  • 样本协方差矩阵(sample-covariance matrix  C ) 

    C=1NixixTi=1NXXT

    其中, X  的每一列表示一个样本(特征向量)

  • 特征分解 

    C=UΛUT=αλαuαuTα

  • projection or transform

yi=UTkxi

1NiyiyTi=1NiUTkxixTiUk=UTk(1NixixTi)Uk=UTkCUk=UTkUΛUUTk=Λk

the projected data are de-correlated in this new axis.

  • 重构 
    yi=UTkxiUkyi=UkUTkxi=xi
<code class="hljs python has-numbering" style="display: block; padding: 0px; color: inherit; box-sizing: border-box; font-family: 'Source Code Pro', monospace;font-size:undefined; white-space: pre; border-radius: 0px; word-wrap: normal; background: transparent;">
<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">import</span> pandas <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">as</span> pd
<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">import</span> numpy <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">as</span> np

df = pd.read_csv(<span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">'https://archive.ics.uci.edu/ml/machine-learning-databases/wine/wine.data'</span>, header=<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">None</span>)
X, y = df.values[:, <span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">1</span>:], df.values[:, <span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">0</span>]

<span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;"># step 1</span>
X -= X.mean(<span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">0</span>)

<span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">## step 2</span>
N = X.shape[<span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">0</span>]
C = X.T.dot(X)/N

<span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">## step 3</span>
Lambda, Q = np.linalg.eig(C)

<span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">## step 4</span>
k = <span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">3</span>
eigen_pairs = [(Lambda[i], Q[:, i]) <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">for</span> i <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">in</span> range(len(Lambda))]
eigen_pairs = sorted(eigen_pairs, reverse=<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">True</span>, key=<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">lambda</span> k: k[<span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">0</span>])
W = np.column_stack((eigen_pairs[i][<span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">1</span>] <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">for</span> i <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">in</span> range(k=<span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">3</span>)))

<span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">## step 5</span>
X_pca = X.dot(W)</code><ul class="pre-numbering" style="box-sizing: border-box; position: absolute; width: 50px; top: 0px; left: 0px; margin: 0px; padding: 6px 0px 40px; border-right-width: 1px; border-right-style: solid; border-right-color: rgb(221, 221, 221); list-style: none; text-align: right; background-color: rgb(238, 238, 238);"><li style="box-sizing: border-box; padding: 0px 5px;">1</li><li style="box-sizing: border-box; padding: 0px 5px;">2</li><li style="box-sizing: border-box; padding: 0px 5px;">3</li><li style="box-sizing: border-box; padding: 0px 5px;">4</li><li style="box-sizing: border-box; padding: 0px 5px;">5</li><li style="box-sizing: border-box; padding: 0px 5px;">6</li><li style="box-sizing: border-box; padding: 0px 5px;">7</li><li style="box-sizing: border-box; padding: 0px 5px;">8</li><li style="box-sizing: border-box; padding: 0px 5px;">9</li><li style="box-sizing: border-box; padding: 0px 5px;">10</li><li style="box-sizing: border-box; padding: 0px 5px;">11</li><li style="box-sizing: border-box; padding: 0px 5px;">12</li><li style="box-sizing: border-box; padding: 0px 5px;">13</li><li style="box-sizing: border-box; padding: 0px 5px;">14</li><li style="box-sizing: border-box; padding: 0px 5px;">15</li><li style="box-sizing: border-box; padding: 0px 5px;">16</li><li style="box-sizing: border-box; padding: 0px 5px;">17</li><li style="box-sizing: border-box; padding: 0px 5px;">18</li><li style="box-sizing: border-box; padding: 0px 5px;">19</li><li style="box-sizing: border-box; padding: 0px 5px;">20</li><li style="box-sizing: border-box; padding: 0px 5px;">21</li><li style="box-sizing: border-box; padding: 0px 5px;">22</li><li style="box-sizing: border-box; padding: 0px 5px;">23</li><li style="box-sizing: border-box; padding: 0px 5px;">24</li><li style="box-sizing: border-box; padding: 0px 5px;">25</li></ul><ul class="pre-numbering" style="box-sizing: border-box; position: absolute; width: 50px; top: 0px; left: 0px; margin: 0px; padding: 6px 0px 40px; border-right-width: 1px; border-right-style: solid; border-right-color: rgb(221, 221, 221); list-style: none; text-align: right; background-color: rgb(238, 238, 238);"><li style="box-sizing: border-box; padding: 0px 5px;">1</li><li style="box-sizing: border-box; padding: 0px 5px;">2</li><li style="box-sizing: border-box; padding: 0px 5px;">3</li><li style="box-sizing: border-box; padding: 0px 5px;">4</li><li style="box-sizing: border-box; padding: 0px 5px;">5</li><li style="box-sizing: border-box; padding: 0px 5px;">6</li><li style="box-sizing: border-box; padding: 0px 5px;">7</li><li style="box-sizing: border-box; padding: 0px 5px;">8</li><li style="box-sizing: border-box; padding: 0px 5px;">9</li><li style="box-sizing: border-box; padding: 0px 5px;">10</li><li style="box-sizing: border-box; padding: 0px 5px;">11</li><li style="box-sizing: border-box; padding: 0px 5px;">12</li><li style="box-sizing: border-box; padding: 0px 5px;">13</li><li style="box-sizing: border-box; padding: 0px 5px;">14</li><li style="box-sizing: border-box; padding: 0px 5px;">15</li><li style="box-sizing: border-box; padding: 0px 5px;">16</li><li style="box-sizing: border-box; padding: 0px 5px;">17</li><li style="box-sizing: border-box; padding: 0px 5px;">18</li><li style="box-sizing: border-box; padding: 0px 5px;">19</li><li style="box-sizing: border-box; padding: 0px 5px;">20</li><li style="box-sizing: border-box; padding: 0px 5px;">21</li><li style="box-sizing: border-box; padding: 0px 5px;">22</li><li style="box-sizing: border-box; padding: 0px 5px;">23</li><li style="box-sizing: border-box; padding: 0px 5px;">24</li><li style="box-sizing: border-box; padding: 0px 5px;">25</li></ul>

Kernel PCA

以 Radial Basis Function(RBF) kernel PCA(不同的核,体现在代码上仅仅是一处细微的差别)为例进行说明:

  • 计算核矩阵(相似度矩阵)  K

Kij=k(x(i),x(j))=exp(γx(i)x(j)2)

这是最为常见的RBF(Rational Basis Function)核函数,也有多项式核: 

Kij=k(x(i),x(j))=(<x(i),x(j)>+θ)p

sigmoid型(hyperbolic tangent)核: 
Kij=k(x(i),x(j))=tanh(η<x(i),x(j)>+θ)

其矩阵形式也即:

K=k(x(1),x(1)),k(x(2),x(1)),,k(x(n),x(1)),k(x(1),x(2)),k(x(2),x(2)),,k(x(n),x(2)),,,,,k(x(1),x(n))k(x(2),x(n))k(x(n),x(n))n×n

  • center the  K

K=K1nKK1n+1nK1n

其中  1n 是  n×n  的元素值全为 1n 矩阵。

  • 对  K 进行特征值分解,获得对应于前  k 个特征值的特征向量。与标准PCA算法不同的是,这里获得特征向量不再是 principal component axes,而已经是全部样本在这些轴上的投影,也即是我们所需的进行降维后的数据了。

这里为了验证核机制的性能,我们在如下的数据集上进行测试:

<code class="hljs avrasm has-numbering" style="display: block; padding: 0px; color: inherit; box-sizing: border-box; font-family: 'Source Code Pro', monospace;font-size:undefined; white-space: pre; border-radius: 0px; word-wrap: normal; background: transparent;">from sklearn<span class="hljs-preprocessor" style="color: rgb(68, 68, 68); box-sizing: border-box;">.datasets</span> import make_moons

<span class="hljs-built_in" style="color: rgb(102, 0, 102); box-sizing: border-box;">X</span>, <span class="hljs-built_in" style="color: rgb(102, 0, 102); box-sizing: border-box;">y</span> = make_moons(n_samples=<span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">200</span>, random_state=<span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">123</span>)
plt<span class="hljs-preprocessor" style="color: rgb(68, 68, 68); box-sizing: border-box;">.scatter</span>(<span class="hljs-built_in" style="color: rgb(102, 0, 102); box-sizing: border-box;">X</span>[<span class="hljs-built_in" style="color: rgb(102, 0, 102); box-sizing: border-box;">y</span>==<span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">0</span>, <span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">0</span>], <span class="hljs-built_in" style="color: rgb(102, 0, 102); box-sizing: border-box;">X</span>[<span class="hljs-built_in" style="color: rgb(102, 0, 102); box-sizing: border-box;">y</span>==<span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">0</span>, <span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">1</span>], colors=<span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">'r'</span>, marker=<span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">'^'</span>, alpha=<span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">.4</span>)
plt<span class="hljs-preprocessor" style="color: rgb(68, 68, 68); box-sizing: border-box;">.scatter</span>(<span class="hljs-built_in" style="color: rgb(102, 0, 102); box-sizing: border-box;">X</span>[<span class="hljs-built_in" style="color: rgb(102, 0, 102); box-sizing: border-box;">y</span>==<span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">1</span>, <span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">0</span>], <span class="hljs-built_in" style="color: rgb(102, 0, 102); box-sizing: border-box;">X</span>[<span class="hljs-built_in" style="color: rgb(102, 0, 102); box-sizing: border-box;">y</span>==<span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">1</span>, <span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">1</span>], colors=<span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">'b'</span>, marker=<span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">'o'</span>, alpha=<span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">.4</span>)</code><ul class="pre-numbering" style="box-sizing: border-box; position: absolute; width: 50px; top: 0px; left: 0px; margin: 0px; padding: 6px 0px 40px; border-right-width: 1px; border-right-style: solid; border-right-color: rgb(221, 221, 221); list-style: none; text-align: right; background-color: rgb(238, 238, 238);"><li style="box-sizing: border-box; padding: 0px 5px;">1</li><li style="box-sizing: border-box; padding: 0px 5px;">2</li><li style="box-sizing: border-box; padding: 0px 5px;">3</li><li style="box-sizing: border-box; padding: 0px 5px;">4</li><li style="box-sizing: border-box; padding: 0px 5px;">5</li></ul><ul class="pre-numbering" style="box-sizing: border-box; position: absolute; width: 50px; top: 0px; left: 0px; margin: 0px; padding: 6px 0px 40px; border-right-width: 1px; border-right-style: solid; border-right-color: rgb(221, 221, 221); list-style: none; text-align: right; background-color: rgb(238, 238, 238);"><li style="box-sizing: border-box; padding: 0px 5px;">1</li><li style="box-sizing: border-box; padding: 0px 5px;">2</li><li style="box-sizing: border-box; padding: 0px 5px;">3</li><li style="box-sizing: border-box; padding: 0px 5px;">4</li><li style="box-sizing: border-box; padding: 0px 5px;">5</li></ul>


 

<code class="hljs python has-numbering" style="display: block; padding: 0px; color: inherit; box-sizing: border-box; font-family: 'Source Code Pro', monospace;font-size:undefined; white-space: pre; border-radius: 0px; word-wrap: normal; background: transparent;"><span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">from</span> scipy.spatial.distance <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">import</span> pdist, squareform

<span class="hljs-function" style="box-sizing: border-box;"><span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">def</span> <span class="hljs-title" style="box-sizing: border-box;">rbf_kpca</span><span class="hljs-params" style="color: rgb(102, 0, 102); box-sizing: border-box;">(X, gamma, k)</span>:</span>
    sq_dist = pdist(X, metric=<span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">'sqeuclidean'</span>)
                            <span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;"># N = X.shape[0]    </span>
                            <span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;"># sq_dist.shape = N*(N-1)/2</span>
    mat_sq_dist = squareform(sq_dist)
                            <span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;"># mat_sq_dist.shape = (N, N)</span>
    <span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;"># step 1</span>
    K = np.exp(-gamma*mat_sq_dist)

    <span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;"># step 2</span>
    N = X.shape[<span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">0</span>]
    one_N = np.ones((N, N))/N
    K = K - one_N.dot(K) - K.dot(one_N) + one_N.dot(K).dot(one_N)

    <span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;"># step 3</span>
    Lambda, Q = np.linalg.eig(K)
    eigen_pairs = [(Lambda[i], Q[:, i]) <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">for</span> i <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">in</span> range(len(Lambda))]
    eigen_pairs = sorted(eigen_pairs, reverse=<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">True</span>, key=<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">lambda</span> k: k[<span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">0</span>])
    <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">return</span> np.column_stack((eigen_pairs[i][<span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">1</span>] <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">for</span> i <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">in</span> range(k)))</code><ul class="pre-numbering" style="box-sizing: border-box; position: absolute; width: 50px; top: 0px; left: 0px; margin: 0px; padding: 6px 0px 40px; border-right-width: 1px; border-right-style: solid; border-right-color: rgb(221, 221, 221); list-style: none; text-align: right; background-color: rgb(238, 238, 238);"><li style="box-sizing: border-box; padding: 0px 5px;">1</li><li style="box-sizing: border-box; padding: 0px 5px;">2</li><li style="box-sizing: border-box; padding: 0px 5px;">3</li><li style="box-sizing: border-box; padding: 0px 5px;">4</li><li style="box-sizing: border-box; padding: 0px 5px;">5</li><li style="box-sizing: border-box; padding: 0px 5px;">6</li><li style="box-sizing: border-box; padding: 0px 5px;">7</li><li style="box-sizing: border-box; padding: 0px 5px;">8</li><li style="box-sizing: border-box; padding: 0px 5px;">9</li><li style="box-sizing: border-box; padding: 0px 5px;">10</li><li style="box-sizing: border-box; padding: 0px 5px;">11</li><li style="box-sizing: border-box; padding: 0px 5px;">12</li><li style="box-sizing: border-box; padding: 0px 5px;">13</li><li style="box-sizing: border-box; padding: 0px 5px;">14</li><li style="box-sizing: border-box; padding: 0px 5px;">15</li><li style="box-sizing: border-box; padding: 0px 5px;">16</li><li style="box-sizing: border-box; padding: 0px 5px;">17</li><li style="box-sizing: border-box; padding: 0px 5px;">18</li><li style="box-sizing: border-box; padding: 0px 5px;">19</li><li style="box-sizing: border-box; padding: 0px 5px;">20</li><li style="box-sizing: border-box; padding: 0px 5px;">21</li></ul><ul class="pre-numbering" style="box-sizing: border-box; position: absolute; width: 50px; top: 0px; left: 0px; margin: 0px; padding: 6px 0px 40px; border-right-width: 1px; border-right-style: solid; border-right-color: rgb(221, 221, 221); list-style: none; text-align: right; background-color: rgb(238, 238, 238);"><li style="box-sizing: border-box; padding: 0px 5px;">1</li><li style="box-sizing: border-box; padding: 0px 5px;">2</li><li style="box-sizing: border-box; padding: 0px 5px;">3</li><li style="box-sizing: border-box; padding: 0px 5px;">4</li><li style="box-sizing: border-box; padding: 0px 5px;">5</li><li style="box-sizing: border-box; padding: 0px 5px;">6</li><li style="box-sizing: border-box; padding: 0px 5px;">7</li><li style="box-sizing: border-box; padding: 0px 5px;">8</li><li style="box-sizing: border-box; padding: 0px 5px;">9</li><li style="box-sizing: border-box; padding: 0px 5px;">10</li><li style="box-sizing: border-box; padding: 0px 5px;">11</li><li style="box-sizing: border-box; padding: 0px 5px;">12</li><li style="box-sizing: border-box; padding: 0px 5px;">13</li><li style="box-sizing: border-box; padding: 0px 5px;">14</li><li style="box-sizing: border-box; padding: 0px 5px;">15</li><li style="box-sizing: border-box; padding: 0px 5px;">16</li><li style="box-sizing: border-box; padding: 0px 5px;">17</li><li style="box-sizing: border-box; padding: 0px 5px;">18</li><li style="box-sizing: border-box; padding: 0px 5px;">19</li><li style="box-sizing: border-box; padding: 0px 5px;">20</li><li style="box-sizing: border-box; padding: 0px 5px;">21</li></ul>

调用:

<code class="hljs fix has-numbering" style="display: block; padding: 0px; color: inherit; box-sizing: border-box; font-family: 'Source Code Pro', monospace;font-size:undefined; white-space: pre; border-radius: 0px; word-wrap: normal; background: transparent;"><span class="hljs-attribute" style="box-sizing: border-box;">X_kpca </span>=<span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;"> rbf_kpca(X, gamma=15, k=2)</span></code><ul class="pre-numbering" style="box-sizing: border-box; position: absolute; width: 50px; top: 0px; left: 0px; margin: 0px; padding: 6px 0px 40px; border-right-width: 1px; border-right-style: solid; border-right-color: rgb(221, 221, 221); list-style: none; text-align: right; background-color: rgb(238, 238, 238);"><li style="box-sizing: border-box; padding: 0px 5px;">1</li></ul><ul class="pre-numbering" style="box-sizing: border-box; position: absolute; width: 50px; top: 0px; left: 0px; margin: 0px; padding: 6px 0px 40px; border-right-width: 1px; border-right-style: solid; border-right-color: rgb(221, 221, 221); list-style: none; text-align: right; background-color: rgb(238, 238, 238);"><li style="box-sizing: border-box; padding: 0px 5px;">1</li></ul>

一个非线性可分的数据集

<code class="hljs mel has-numbering" style="display: block; padding: 0px; color: inherit; box-sizing: border-box; font-family: 'Source Code Pro', monospace;font-size:undefined; white-space: pre; border-radius: 0px; word-wrap: normal; background: transparent;">from sklearn.datasets import make_circles
X, y = make_circles(n_samples=<span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">1000</span>, <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">noise</span>=<span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">.1</span>, factor=<span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">.2</span>, random_state=<span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">123</span>)
plt.scatter(X[y==<span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">0</span>, <span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">0</span>], X[y==<span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">0</span>, <span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">1</span>], <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">color</span>=<span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">'r'</span>, <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">marker</span>=<span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">'^'</span>, alpha=<span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">.4</span>)
plt.scatter(X[y==<span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">1</span>, <span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">0</span>], X[y==<span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">1</span>, <span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">1</span>], <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">color</span>=<span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">'b'</span>, <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">marker</span>=<span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">'o'</span>, alpha=<span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">.4</span>)
plt.show()</code><ul class="pre-numbering" style="box-sizing: border-box; position: absolute; width: 50px; top: 0px; left: 0px; margin: 0px; padding: 6px 0px 40px; border-right-width: 1px; border-right-style: solid; border-right-color: rgb(221, 221, 221); list-style: none; text-align: right; background-color: rgb(238, 238, 238);"><li style="box-sizing: border-box; padding: 0px 5px;">1</li><li style="box-sizing: border-box; padding: 0px 5px;">2</li><li style="box-sizing: border-box; padding: 0px 5px;">3</li><li style="box-sizing: border-box; padding: 0px 5px;">4</li><li style="box-sizing: border-box; padding: 0px 5px;">5</li></ul><ul class="pre-numbering" style="box-sizing: border-box; position: absolute; width: 50px; top: 0px; left: 0px; margin: 0px; padding: 6px 0px 40px; border-right-width: 1px; border-right-style: solid; border-right-color: rgb(221, 221, 221); list-style: none; text-align: right; background-color: rgb(238, 238, 238);"><li style="box-sizing: border-box; padding: 0px 5px;">1</li><li style="box-sizing: border-box; padding: 0px 5px;">2</li><li style="box-sizing: border-box; padding: 0px 5px;">3</li><li style="box-sizing: border-box; padding: 0px 5px;">4</li><li style="box-sizing: border-box; padding: 0px 5px;">5</li></ul>


 

在这样的一个非线性可分的数据集,显然如何找到最大方差的方向都不可能使最后的数据集线性可分。接下来,我们探讨KPCA的核机制是如何工作的,使线性不可分的数据集变得线性可分

应用kernel trick:

<code class="hljs fix has-numbering" style="display: block; padding: 0px; color: inherit; box-sizing: border-box; font-family: 'Source Code Pro', monospace;font-size:undefined; white-space: pre; border-radius: 0px; word-wrap: normal; background: transparent;"><span class="hljs-attribute" style="box-sizing: border-box;">X_kpca </span>=<span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;"> rbf_kpca(X, gamma=15, k=2)</span></code><ul class="pre-numbering" style="box-sizing: border-box; position: absolute; width: 50px; top: 0px; left: 0px; margin: 0px; padding: 6px 0px 40px; border-right-width: 1px; border-right-style: solid; border-right-color: rgb(221, 221, 221); list-style: none; text-align: right; background-color: rgb(238, 238, 238);"><li style="box-sizing: border-box; padding: 0px 5px;">1</li></ul><ul class="pre-numbering" style="box-sizing: border-box; position: absolute; width: 50px; top: 0px; left: 0px; margin: 0px; padding: 6px 0px 40px; border-right-width: 1px; border-right-style: solid; border-right-color: rgb(221, 221, 221); list-style: none; text-align: right; background-color: rgb(238, 238, 238);"><li style="box-sizing: border-box; padding: 0px 5px;">1</li></ul>

可视化:

<code class="hljs rsl has-numbering" style="display: block; padding: 0px; color: inherit; box-sizing: border-box; font-family: 'Source Code Pro', monospace;font-size:undefined; white-space: pre; border-radius: 0px; word-wrap: normal; background: transparent;">fig, ax = plt.subplots(<span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">1</span>, <span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">2</span>, figsize=(<span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">8</span>, <span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">4</span>))

ax[<span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">0</span>].scatter(X_kpca[y==<span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">0</span>, <span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">0</span>], X_kpca[y==<span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">0</span>, <span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">1</span>], <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">color</span>=<span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">'r'</span>, marker=<span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">'^'</span>, alpha=<span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">.4</span>)
ax[<span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">0</span>].scatter(X_kpca[y==<span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">1</span>, <span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">0</span>], X_kpca[y==<span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">1</span>, <span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">1</span>], <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">color</span>=<span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">'b'</span>, marker=<span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">'o'</span>, alpha=<span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">.4</span>)

label_count = np.bincount(y)
                                <span class="hljs-preprocessor" style="color: rgb(68, 68, 68); box-sizing: border-box;"># 统计各类别出现的次数</span>
                                <span class="hljs-preprocessor" style="color: rgb(68, 68, 68); box-sizing: border-box;"># label_count[0] = 500</span>
                                <span class="hljs-preprocessor" style="color: rgb(68, 68, 68); box-sizing: border-box;"># label_count[1] = 500</span>
ax[<span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">1</span>].scatter(X_kpca[y==<span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">0</span>, <span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">0</span>], np.zeros(label_count[<span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">0</span>]), <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">color</span>=<span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">'r'</span>)
ax[<span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">1</span>].scatter(X_kpca[y==<span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">1</span>, <span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">0</span>], np.zeros(label_count[<span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">1</span>]), <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">color</span>=<span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">'b'</span>)
                                <span class="hljs-preprocessor" style="color: rgb(68, 68, 68); box-sizing: border-box;"># y轴置零</span>
                                <span class="hljs-preprocessor" style="color: rgb(68, 68, 68); box-sizing: border-box;"># 投影到x轴</span>
ax[<span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">1</span>].set_ylim([-<span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">1</span>, <span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">1</span>])
ax[<span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">0</span>].set_xlabel(<span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">'PC1'</span>)
ax[<span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">0</span>].set_ylabel(<span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">'PC2'</span>)
ax[<span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">1</span>].set_xlabel(<span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">'PC1'</span>)

plt.show()</code><ul class="pre-numbering" style="box-sizing: border-box; position: absolute; width: 50px; top: 0px; left: 0px; margin: 0px; padding: 6px 0px 40px; border-right-width: 1px; border-right-style: solid; border-right-color: rgb(221, 221, 221); list-style: none; text-align: right; background-color: rgb(238, 238, 238);"><li style="box-sizing: border-box; padding: 0px 5px;">1</li><li style="box-sizing: border-box; padding: 0px 5px;">2</li><li style="box-sizing: border-box; padding: 0px 5px;">3</li><li style="box-sizing: border-box; padding: 0px 5px;">4</li><li style="box-sizing: border-box; padding: 0px 5px;">5</li><li style="box-sizing: border-box; padding: 0px 5px;">6</li><li style="box-sizing: border-box; padding: 0px 5px;">7</li><li style="box-sizing: border-box; padding: 0px 5px;">8</li><li style="box-sizing: border-box; padding: 0px 5px;">9</li><li style="box-sizing: border-box; padding: 0px 5px;">10</li><li style="box-sizing: border-box; padding: 0px 5px;">11</li><li style="box-sizing: border-box; padding: 0px 5px;">12</li><li style="box-sizing: border-box; padding: 0px 5px;">13</li><li style="box-sizing: border-box; padding: 0px 5px;">14</li><li style="box-sizing: border-box; padding: 0px 5px;">15</li><li style="box-sizing: border-box; padding: 0px 5px;">16</li><li style="box-sizing: border-box; padding: 0px 5px;">17</li><li style="box-sizing: border-box; padding: 0px 5px;">18</li><li style="box-sizing: border-box; padding: 0px 5px;">19</li></ul><ul class="pre-numbering" style="box-sizing: border-box; position: absolute; width: 50px; top: 0px; left: 0px; margin: 0px; padding: 6px 0px 40px; border-right-width: 1px; border-right-style: solid; border-right-color: rgb(221, 221, 221); list-style: none; text-align: right; background-color: rgb(238, 238, 238);"><li style="box-sizing: border-box; padding: 0px 5px;">1</li><li style="box-sizing: border-box; padding: 0px 5px;">2</li><li style="box-sizing: border-box; padding: 0px 5px;">3</li><li style="box-sizing: border-box; padding: 0px 5px;">4</li><li style="box-sizing: border-box; padding: 0px 5px;">5</li><li style="box-sizing: border-box; padding: 0px 5px;">6</li><li style="box-sizing: border-box; padding: 0px 5px;">7</li><li style="box-sizing: border-box; padding: 0px 5px;">8</li><li style="box-sizing: border-box; padding: 0px 5px;">9</li><li style="box-sizing: border-box; padding: 0px 5px;">10</li><li style="box-sizing: border-box; padding: 0px 5px;">11</li><li style="box-sizing: border-box; padding: 0px 5px;">12</li><li style="box-sizing: border-box; padding: 0px 5px;">13</li><li style="box-sizing: border-box; padding: 0px 5px;">14</li><li style="box-sizing: border-box; padding: 0px 5px;">15</li><li style="box-sizing: border-box; padding: 0px 5px;">16</li><li style="box-sizing: border-box; padding: 0px 5px;">17</li><li style="box-sizing: border-box; padding: 0px 5px;">18</li><li style="box-sizing: border-box; padding: 0px 5px;">19</li></ul>


 

PCA 与 KPCA 的另一点重要不同

不同在于对数据、样本(当然还是同一类型数据,比如测试样本之于训练样本)的转换方式不同;

标准PCA算法,转换矩阵(transformation matrix  Wd×k )对应于训练样本的协方差矩阵的特征向量,使用  W  可继续作用于新的数据集, x1×dWd×k 。而KPCA, K  的特征向量( Ka=λα  中的  α )即为变换后的样本。 
对于新的样本,我们想要计算: 

ϕ(x)Tv

而特征向量  v=ia(i)ϕ(x(i)) ,则: 

ϕ(x)Tv=ia(i)ϕ(x)Tϕ(x(i))=ia(i)k(x,x(i))

<code class="hljs python has-numbering" style="color: inherit; display: block; padding: 0px; box-sizing: border-box; font-family: 'Source Code Pro', monospace;font-size:undefined; white-space: pre; border-radius: 0px; word-wrap: normal; background-image: initial; background-attachment: initial; background-color: transparent; background-size: initial; background-origin: initial; background-clip: initial; background-position: initial; background-repeat: initial;"><span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">from</span> scipy.spatial.distance <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">import</span> sqdist, squareform

<span class="hljs-function" style="box-sizing: border-box;"><span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">def</span> <span class="hljs-title" style="box-sizing: border-box;">rbf_kpca</span><span class="hljs-params" style="color: rgb(102, 0, 102); box-sizing: border-box;">(X, gamma, k)</span>:</span>
    sq_dists = sqdist(X, metric=<span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">'sqeuclidean'</span>)
    mat_sq_dists = squareform(sq_dists)
    K = np.exp(-gamma*mat_sq_dists)
    N = X.shape[<span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">0</span>]
    one_N = np.ones((N, N))/N
    K = K-one_N.dot(K)-K.dot(one_N)+one_N.dot(K).dot(one_N)
    Lambda, Q = np.linalg.eigh(K)
    alphas = np.column_stack((Q[:, -i]<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">for</span> i <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">in</span> range(<span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">1</span>, <span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">1</span>+k)))
    lambdas = [Lambda[-i] <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">for</span> i <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">in</span> range(<span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">1</span>, k+<span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">1</span>)]
    <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">return</span> alphas, lambdas

<span class="hljs-function" style="box-sizing: border-box;"><span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">def</span> <span class="hljs-title" style="box-sizing: border-box;">proj_new</span><span class="hljs-params" style="color: rgb(102, 0, 102); box-sizing: border-box;">(X_new, X, gamma, alphas, lambdas)</span>:</span>
    k = np.exp(-gamma*np.sum((X-X_new)**<span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">2</span>, <span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">1</span>))
    <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">return</span> k.dot(alphas/lambdas)
                                <span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;"># alphas/lambdas,归一化后的alphas</span>

X, y = make_moons(n_samples=<span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">100</span>, random_state=<span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">123</span>)
                                <span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;"># 设置random_state,为了可重复性</span>
alphas, lambdas = rbf_kpca(X, gamma=<span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">15</span>, k=<span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">1</span>)
X_new = X[<span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">25</span>]
                    <span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;"># 以当前样本的某一样本作为新的样本进行测试</span>
X_proj = proj_new(X_new, X, gamma=<span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">15</span>, alphas, lambdas)
print(alphas[<span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">25</span>])
print(X_proj)
                    <span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;"># [-0.07877284]</span>
                    <span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;"># [-0.07877284]</span></code><code class="hljs python has-numbering" style="color: inherit; display: block; padding: 0px; box-sizing: border-box; font-family: 'Source Code Pro', monospace;font-size:undefined; white-space: pre; border-radius: 0px; word-wrap: normal; background-image: initial; background-attachment: initial; background-color: transparent; background-size: initial; background-origin: initial; background-clip: initial; background-position: initial; background-repeat: initial;"><span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">
</span></code><code class="hljs python has-numbering" style="color: inherit; display: block; padding: 0px; box-sizing: border-box; font-family: 'Source Code Pro', monospace;font-size:undefined; white-space: pre; border-radius: 0px; word-wrap: normal; background-image: initial; background-attachment: initial; background-color: transparent; background-size: initial; background-origin: initial; background-clip: initial; background-position: initial; background-repeat: initial;"><span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">
</span></code><code class="hljs python has-numbering" style="display: block; padding: 0px; box-sizing: border-box; font-family: 'Source Code Pro', monospace;font-size:undefined; white-space: pre; border-radius: 0px; word-wrap: normal; background-image: initial; background-attachment: initial; background-color: transparent; background-size: initial; background-origin: initial; background-clip: initial; background-position: initial; background-repeat: initial;"><span style="color:#880000;">本文转自:<a target=_blank href="http://http://blog.csdn.net/lanchunhui/article/details/50492482">http://blog.csdn.net/lanchunhui/article/details/50492482</a></span></code><ul class="pre-numbering" style="color: rgb(51, 51, 51); box-sizing: border-box; position: absolute; width: 50px; top: 0px; left: 0px; margin: 0px; padding: 6px 0px 40px; border-right-width: 1px; border-right-style: solid; border-right-color: rgb(221, 221, 221); list-style: none; text-align: right; background-color: rgb(238, 238, 238);"><li style="box-sizing: border-box; padding: 0px 5px;">1</li><li style="box-sizing: border-box; padding: 0px 5px;">2</li><li style="box-sizing: border-box; padding: 0px 5px;">3</li><li style="box-sizing: border-box; padding: 0px 5px;">4</li><li style="box-sizing: border-box; padding: 0px 5px;">5</li><li style="box-sizing: border-box; padding: 0px 5px;">6</li><li style="box-sizing: border-box; padding: 0px 5px;">7</li><li style="box-sizing: border-box; padding: 0px 5px;">8</li><li style="box-sizing: border-box; padding: 0px 5px;">9</li><li style="box-sizing: border-box; padding: 0px 5px;">10</li><li style="box-sizing: border-box; padding: 0px 5px;">11</li><li style="box-sizing: border-box; padding: 0px 5px;">12</li><li style="box-sizing: border-box; padding: 0px 5px;">13</li><li style="box-sizing: border-box; padding: 0px 5px;">14</li><li style="box-sizing: border-box; padding: 0px 5px;">15</li><li style="box-sizing: border-box; padding: 0px 5px;">16</li><li style="box-sizing: border-box; padding: 0px 5px;">17</li><li style="box-sizing: border-box; padding: 0px 5px;">18</li><li style="box-sizing: border-box; padding: 0px 5px;">19</li><li style="box-sizing: border-box; padding: 0px 5px;">20</li><li style="box-sizing: border-box; padding: 0px 5px;">21</li><li style="box-sizing: border-box; padding: 0px 5px;">22</li><li style="box-sizing: border-box; padding: 0px 5px;">23</li><li style="box-sizing: border-box; padding: 0px 5px;">24</li><li style="box-sizing: border-box; padding: 0px 5px;">25</li><li style="box-sizing: border-box; padding: 0px 5px;">26</li><li style="box-sizing: border-box; padding: 0px 5px;">27</li><li style="box-sizing: border-box; padding: 0px 5px;">28</li><li style="box-sizing: border-box; padding: 0px 5px;">29</li></ul><div class="save_code tracking-ad" data-mod="popu_249" style="color: rgb(255, 255, 255); box-sizing: border-box; position: absolute; height: 60px; right: 30px; top: 5px; cursor: pointer; z-index: 2;"><a target=_blank style="color: rgb(202, 0, 0); box-sizing: border-box;"><img src="http://static.blog.csdn.net/images/save_snippets.png" style="border: none; box-sizing: border-box; max-width: 100%;" alt="" /></a></div><ul class="pre-numbering" style="color: rgb(51, 51, 51); box-sizing: border-box; position: absolute; width: 50px; top: 0px; left: 0px; margin: 0px; padding: 6px 0px 40px; border-right-width: 1px; border-right-style: solid; border-right-color: rgb(221, 221, 221); list-style: none; text-align: right; background-color: rgb(238, 238, 238);"><li style="box-sizing: border-box; padding: 0px 5px;">1</li><li style="box-sizing: border-box; padding: 0px 5px;">2</li><li style="box-sizing: border-box; padding: 0px 5px;">3</li><li style="box-sizing: border-box; padding: 0px 5px;">4</li><li style="box-sizing: border-box; padding: 0px 5px;">5</li><li style="box-sizing: border-box; padding: 0px 5px;">6</li><li style="box-sizing: border-box; padding: 0px 5px;">7</li><li style="box-sizing: border-box; padding: 0px 5px;">8</li><li style="box-sizing: border-box; padding: 0px 5px;">9</li><li style="box-sizing: border-box; padding: 0px 5px;">10</li><li style="box-sizing: border-box; padding: 0px 5px;">11</li><li style="box-sizing: border-box; padding: 0px 5px;">12</li><li style="box-sizing: border-box; padding: 0px 5px;">13</li><li style="box-sizing: border-box; padding: 0px 5px;">14</li><li style="box-sizing: border-box; padding: 0px 5px;">15</li><li style="box-sizing: border-box; padding: 0px 5px;">16</li><li style="box-sizing: border-box; padding: 0px 5px;">17</li><li style="box-sizing: border-box; padding: 0px 5px;">18</li><li style="box-sizing: border-box; padding: 0px 5px;">19</li><li style="box-sizing: border-box; padding: 0px 5px;">20</li><li style="box-sizing: border-box; padding: 0px 5px;">21</li><li style="box-sizing: border-box; padding: 0px 5px;">22</li><li style="box-sizing: border-box; padding: 0px 5px;">23</li><li style="box-sizing: border-box; padding: 0px 5px;">24</li><li style="box-sizing: border-box; padding: 0px 5px;">25</li><li style="box-sizing: border-box; padding: 0px 5px;">26</li><li style="box-sizing: border-box; padding: 0px 5px;">27</li><li style="box-sizing: border-box; padding: 0px 5px;">28</li><li style="box-sizing: border-box; padding: 0px 5px;">29</li></ul>
  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值