开启成长之旅!这是我参与「日新计划 12 月更文挑战」的第2天

#降维实操

前言

最近看书看到降维一部分,说实话这一部分一直想写,可是苦于网上解说的初级理论部分过于全面,自己也是无从可写,但看完周志华的机器学习一书中写的降维部分,感觉还是有新的了解的,权当记载一下,文中有什么不对的当地还望大佬们多谅解,谈论我我会及时更改。


线性降维

降维是将数据通过某种数学改换将原始高维属性空间转变为一个低维“子空间”,在此子空间中样本密度大幅提高,间隔核算也变得更为简单,通俗点讲便是联系愈加亲近,练习模型鲁棒性更好。

低维嵌入

这样就引出了我们为什么要将数据降维的原因,实际使命中人们收集或观测的数据样本是高维的,可是与学习使命亲近相关的或许仅仅是某个低维散布,即高维空间中的一个低维“嵌入”,在这个低维嵌入子空间中更简单让模型学习。

多维缩放(MDS)

简介

在原始空间中样本之间的间隔在低维空间中得以坚持即得到“多维缩放”(MDS),其选用欧氏间隔核算原始空间中的间隔,尽可能保存高维空间中的“相似度”信息。

算法描绘

降维干货,一种用于处理特征的方式——后附Python代码例子

推导可见

MDS示例代码

from collections import OrderedDict
from functools import partial
from time import time
import matplotlib.pyplot as plt
from mpl_toolkits.mplot3d import Axes3D
from matplotlib.ticker import NullFormatter
from sklearn import manifold, datasets
Axes3D
n_points = 1000
X, color = datasets.make_s_curve(n_points, random_state=0)
fig = plt.figure()
ax = fig.add_subplot(121, projection='3d')
ax.scatter(X[:, 0], X[:, 1], X[:, 2], c=color, cmap=plt.cm.Spectral)
ax.view_init(4, -72)
methods = OrderedDict()
methods['MDS'] = manifold.MDS(n_components, max_iter=100, n_init=1)
for i, (label, method) in enumerate(methods.items()):
    t0 = time()
    Y = method.fit_transform(X)
    t1 = time()
    print("%s: %.2g sec" % (label, t1 - t0))
    ax = fig.add_subplot(1, 2, 2)
    ax.scatter(Y[:, 0], Y[:, 1], c=color, cmap=plt.cm.Spectral)
    ax.set_title("%s (%.2g sec)" % (label, t1 - t0))
    ax.xaxis.set_major_formatter(NullFormatter())
    ax.yaxis.set_major_formatter(NullFormatter())
    ax.axis('tight')
plt.show()

降维干货,一种用于处理特征的方式——后附Python代码例子

主成分剖析法

简介

主成分剖析(Principal Component Analysis,PCA), 是一种统计办法,通过正交改换将一组可能存在相关性的变量转化为一组线性不相关的变量,转化后的这组变量叫主成分(来源于百度百科)。 主成分剖析法适用于变量间有较强相关性的数据,究竟数据间联系弱的,通过PCA降维后会放弃部分信息,联系可能会更弱,那用降维的意义也就不存在了,其具体作用有两方面:

  1. 放弃此部分信息后能使样本的采样密度增大,正如上面所说:高维数据到低维数据转化后数据间的密度会大大提高;
  2. 当数据受到噪声影响时,最小的特征值所对应的特征向量往往与噪声有关,将它们放弃能够在一定程度上起到去噪的作用;

算法描绘

降维干货,一种用于处理特征的方式——后附Python代码例子

核化线性降维

简介

核化线性降维是非线性降维,是基于核技巧对线性降维办法进行“核化”,例如核主成分剖析(KPCA),优点便是,保存了最主要的特征,核算办法简单,但缺陷也很明显,使用非线性核能够实现非线性降维核算开销极大,直接给我报Memory Error,以下代码请酌情更改输入数据集份额。

PCA和KPCA手写数字体辨认实例代码

from sklearn.model_selection import train_test_split
import pandas as pd
from sklearn.decomposition import KernelPCA
from sklearn.datasets import fetch_openml
mnist = fetch_openml('mnist_784', cache=True)
print(mnist.data.shape)
import matplotlib.pyplot as plt
def display_sample(num):
    image = mnist.data.iloc[num,:].to_numpy().reshape([28,28])
    plt.imshow(image, cmap=plt.get_cmap('gray_r'))
    plt.show()
display_sample(10)
train_img, test_img, train_lbl, test_lbl = train_test_split(
    mnist.data, mnist.target, test_size=0.8, random_state=0)
print(train_img.shape)
print(test_img.shape)
from sklearn.preprocessing import StandardScaler
scaler = StandardScaler()
scaler.fit(train_img)
train_img = scaler.transform(train_img)
test_img = scaler.transform(test_img)
from sklearn.linear_model import LogisticRegression
logisticRegr = LogisticRegression(solver = 'lbfgs',max_iter=1000)
logisticRegr.fit(train_img, train_lbl)
score = logisticRegr.score(test_img, test_lbl)
print(score)
# KPCA
# scikit_kpca = KernelPCA(n_components=2, kernel='rbf', gamma=15)
# X_skernpca = scikit_kpca.fit_transform(train_img)
# plt.scatter(X_skernpca[test_img, 0], X_skernpca[test_img, 1],, marker='^', alpha=0.5)
# plt.scatter(X_skernpca[test_lbl, 0], X_skernpca[test_lbl==1, 1],, marker='o', alpha=0.5)
# plt.xlabel('PC1')
# plt.ylabel('PC2')
# plt.tight_layout()
# plt.show()
# PCA
from sklearn.decomposition import PCA
pca = PCA(0.95)
pca.fit(train_img)
print(pca.n_components_)
train2_img = pca.transform(train_img)
test2_img = pca.transform(test_img)
print(train2_img.shape)
print(train_img.shape)
logisticRegr = LogisticRegression(solver = 'lbfgs',max_iter=1000)
logisticRegr.fit(train2_img, train_lbl)
score = logisticRegr.score(test2_img, test_lbl)
print(score)
#minist数据集及区分份额
#(70000, 784)
#(14000, 784)
#(56000, 784)
#降维前猜测准确率
#0.8843214285714286
#保存特征数量
#293
#降维后数据量对比
#(14000, 293)
#(14000, 784)
#降维后猜测准确率
#0.9033214285714286

流形学习

简介

流形学习是一类借鉴拓扑流形概念的降维办法,“流形”是在部分与欧氏空间同胚的空间,也便是说他在部分具有欧氏空间的性质,能用欧氏间隔来进行间隔核算,用到降维中,即低维流形嵌入到高维空间中,部分依然具有欧氏空间的性质,因此很简单在部分建立降维映射联系,然后在设法将部分映射联系推广到大局,以两种闻名的流形学习办法为例,即非线性降维。

等度量映射(Isomap)

Isomap算法是最早的流形学习办法之一,它是等距映射的缩写。Isomap能够看作是多维标准剖析(MDS)或核主成分剖析的扩展。

简介

Isomap寻求一种更低维度的嵌入,以坚持所有点之间的测地线间隔,究竟如下左图最上面一层到中间一层在三维坐标中不能直接核算直线间隔,这样是不恰当的,需要沿着两层之间的边边连线形成间隔最短的途径,也便是测地线间隔,尽管低维嵌入流形上的测地线间隔不能用高维空间的直线间隔核算,可是能够通过近邻间隔来求近似(图画的不是很好,右图线都是直的嗷,蓝线:近邻间隔,也便是左图三维直线间隔被二维可视化;红线:测地线间隔)

降维干货,一种用于处理特征的方式——后附Python代码例子

算法描绘

降维干货,一种用于处理特征的方式——后附Python代码例子

Isomap示例代码

from collections import OrderedDict
from functools import partial
from time import time
import matplotlib.pyplot as plt
from mpl_toolkits.mplot3d import Axes3D
from matplotlib.ticker import NullFormatter
from sklearn import manifold, datasets
# Next line to silence pyflakes. This import is needed.
Axes3D
n_points = 1000
X, color = datasets.make_s_curve(n_points, random_state=0)
fig = plt.figure()
ax = fig.add_subplot(121, projection='3d')
ax.scatter(X[:, 0], X[:, 1], X[:, 2], c=color, cmap=plt.cm.Spectral)
ax.view_init(4, -72)
methods = OrderedDict()
methods['Isomap'] = manifold.Isomap(n_components=2)
for i, (label, method) in enumerate(methods.items()):
    t0 = time()
    Y = method.fit_transform(X)
    t1 = time()
    print("%s: %.2g sec" % (label, t1 - t0))
    ax = fig.add_subplot(1, 2, 2)
    ax.scatter(Y[:, 0], Y[:, 1], c=color, cmap=plt.cm.Spectral)
    ax.set_title("%s (%.2g sec)" % (label, t1 - t0))
    ax.xaxis.set_major_formatter(NullFormatter())
    ax.yaxis.set_major_formatter(NullFormatter())
    ax.axis('tight')
plt.show()

以S型曲线数据集为例,将三维数据映射到二维平面上,如下图所示:

降维干货,一种用于处理特征的方式——后附Python代码例子

部分线性嵌入(LLE)

简介

部分线性嵌入企图坚持邻域内样本线性联系,意思便是经历过降维后依然在原空间具有该特征。而且LLE能够在sklearn机器学习库中直接调用。

算法描绘:

降维干货,一种用于处理特征的方式——后附Python代码例子

降维干货,一种用于处理特征的方式——后附Python代码例子
式(10.7)

降维干货,一种用于处理特征的方式——后附Python代码例子

式(10.8)

降维干货,一种用于处理特征的方式——后附Python代码例子

式(10.9)

降维干货,一种用于处理特征的方式——后附Python代码例子

式(10.10)

推导进程(感兴趣能够去看看)

LLE示例代码

import matplotlib.pyplot as plt
from mpl_toolkits.mplot3d import Axes3D
Axes3D
from sklearn import manifold, datasets
X, color = datasets.make_swiss_roll(n_samples=1500)
print("Computing LLE embedding")
X_r, err = manifold.locally_linear_embedding(X, n_neighbors=12,
                                             n_components=2)
print("Done. Reconstruction error: %g" % err)
fig = plt.figure()
ax = fig.add_subplot(211, projection='3d')
ax.scatter(X[:, 0], X[:, 1], X[:, 2], c=color, cmap=plt.cm.Spectral)
ax.set_title("Original data")
ax = fig.add_subplot(212)
ax.scatter(X_r[:, 0], X_r[:, 1], c=color, cmap=plt.cm.Spectral)
plt.axis('tight')
plt.xticks([]), plt.yticks([])
plt.title('Projected data')
plt.show()

以swiss(称他为瑞士卷)为例,将三维数据进行二维化:

降维干货,一种用于处理特征的方式——后附Python代码例子

降维干货,一种用于处理特征的方式——后附Python代码例子
式(10.27)
降维干货,一种用于处理特征的方式——后附Python代码例子
式(10.30)