当前位置:   article > 正文

机器学习笔记之(6)——数据降维(PCA与SVD)_svd数据降维前需要对数据进行标准化处理么

svd数据降维前需要对数据进行标准化处理么

数据降维(数据压缩)是属于非监督学习的一种,但是其实它也属于一种数据处理的手段。也就是说,通过数据降维,对输入的数据进行降维处理,由此剔除数据中的噪声并通过机器学习算法的性能,用于数据预处理。主要有:主成分分析(PCA)和奇异值分解(SVD)。PCA——通过按照数据方差最大方向调整数据的逼近来达到降维的目的。SVD——是矩阵分解技术中的一种,通过对原始数据的逼近来达到降维的目的。(之前介绍过的监督学习Fisher分类器也可以实现数据的降维)

在低维下,数据更容易进行处理。另外,其相关特征可能在数据中明确地显示出来。也可以起到去除噪声的作用。

使用特征抽取来减少数据集中特征的数量。特征抽取算法会将数据转换或映射到一个新的特征空间。特征抽取可以理解为:在尽可能多地保持相关信息的情况下,对数据进行压缩的一种方法。特征抽取通常用于提高计算效率,同样也可以帮助我们降低“维数灾难”——尤其当模型不适用于正则化处理时。

所谓的降维就是指采用某种映射方法,将原高维空间中的数据点映射到低维度的空间中。在原始的高维空间中,包含冗余信息以及噪声信息,在实际应用中例如图像识别中会造成误差,降低准确率;而通过降维,可以减少信息的冗余、提高识别等的精度,还可以寻求数据内部的本质结构特征。

如果特征维度成千上万,则需要的训练样本的数量几乎不可能满足。而且高维空间距离计算也比较麻烦(大部分机器学习算法都是基于特征距离的计算)。在高维度情形下出现的数据样本稀疏、距离计算困难等问题是所有机器学习方法共同面临的难题,称为“维度灾难”。可以通过数据降维来解决。


PCA:

主成分分析(principal component analysis)。在PCA中,数据从原来的坐标系转换到了新的坐标系,新坐标系的选择是由数据本身决定的。第一个新坐标轴选择的是原始数据中方差最大的方向,第二个新坐标轴的选择和第一个坐标轴正交且具有最大方差的方向。该过程一直重复,重复的次数为原始数据中特征的数目。我们会发现,大部分方差都包含在最前面的几个新坐标轴中。因此,可以忽略余下的坐标轴,即对数据进行了降维处理。

第一个主成分就是从数据差异性最大(即方差最大)的方向提取出来的,第二个主成分则来自于数据差异性次大的方向,并且该方向与第一个主成分方向正交。通过对数据集的协方差矩阵及其特征值分析,可以求得这些主成分的值。一旦得到了协方差矩阵的特征向量,我们就可以保留最大的N个值。这些特征向量也给出了N个最重要特征的真实结构。可以通过将数据乘上这N个特征向量而将它转换到新的空间。

PCA的目标是在高维数据中找到最大方差的方向,并将数据映射到一个维度不大于原始数据的新的子空间上。新特征的坐标是相互正交的,且新的子空间上正交的坐标轴(主成分)可以被解释为方差最大的方向。

对于d维原始特征空间,通过构建一个维度为d*k维的转换矩阵,将样本映射到新的k维特征空间上去(k<d)。



PCA算法步骤如下:

1、对原始d维数据做预处理。包括划分数据集与标准化处理。由于主成分的方向对数据值的范围高度敏感,因此要先对特征值做标准化处理。

2、构造样本的协方差矩阵。d*d维协方差矩阵是沿主对角线对称的,其中d为数据集的维度,此矩阵成对地存储了不同特征之间的协方差。如两个特征,可通过如下公式计算它们之间的协方差:


其中,分别为特征的均值。若对数据集进行了标准化处理,则样本的均值会为0.两个特征之间的协方差如果为正,则它们会同时增减,而一个负的协方差则表示两个特征会朝相反的方向变动。一个包含三个特征的协方差矩阵可以记为:


3、计算协方差矩阵的特征值和相应的特征向量。协方差矩阵的特征向量代表主成分(最大方差方向),而对应的特征值大小就决定了特征向量的重要性。协方差矩阵的特征对计算如下:


特征值为一个标量。

4、选择与前k个最大特征值对应的特征向量,其中k为新特征空间的维度(k<=d)。由于要将数据集压缩到一个新的特征子空间上来实现数据降维,所以只选择那些包含最多信息(方差最大)的特征向量(主成分)组成子集。由于特征值的大小决定了特征向量的重要性,因此需要将特征值按降序排列,感兴趣的是排序在前k个的特征值所对应的特征向量。

特征值的方差贡献率:特征值与所有特征值和的比值:


5、通过前k个特征向量构建映射矩阵W。

6、通过映射矩阵W将d维的输入数据集X转换到新的k维特征子空间。将数据集中的信息转换到新的主成分轴上。



下面给出上述过程的python代码:

  1. ##############################数据的读入、划分、标准化##########################
  2. import pandas as pd
  3. #Python Data Analysis Library 或 pandas 是基于NumPy 的一种工具,该工具是为了解决数据分析任务而创建的。
  4. #Pandas 纳入了大量库和一些标准的数据模型,提供了高效地操作大型数据集所需的工具。
  5. df_wine = pd.read_csv('https://archive.ics.uci.edu/ml/machine-learning-databases/wine/wine.data',header=None)
  6. #读入csv文件,形成一个数据框
  7. #使用葡萄酒数据集
  8. from sklearn.cross_validation import train_test_split
  9. x, y = df_wine.iloc[:, 1:].values, df_wine.iloc[:, 0].values
  10. x_train, x_test, y_train, y_test =train_test_split(x, y, test_size=0.3,stratify=y,random_state=0)
  11. #葡萄酒数据集划分为训练集和测试集,分别占据数据集的70%和30%
  12. #使用单位方差对数据集进行标准化
  13. from sklearn.preprocessing import StandardScaler
  14. sc=StandardScaler()
  15. #注意,当改为from sklearn.preprocessing import StandardScaler as sc时,会报错
  16. # fit_transform() missing 1 required positional argument: 'X'。这就是由于sc没有StandardScaler()而仅仅是StandardScaler
  17. x_train_std=sc.fit_transform(x_train)
  18. x_test_std=sc.fit_transform(x_test)
  19. ##############################构造协方差矩阵、获得特征值与特征向量###############
  20. import numpy as np
  21. cov_mat=np.cov(x_train_std.T)#求数据集的协方差矩阵
  22. #进行特征分解
  23. eigen_vals,eigen_vecs=np.linalg.eig(cov_mat)#用numpy中的linalg.eig函数来计算数据集协方差矩阵的特征对
  24. print('\n特征值 \n%s' % eigen_vals)
  25. #对于此处导入的葡萄酒数据集,可以获得13*13的协方差矩阵和13个特征向量及其对应的特征值。
  26. #eigen_vals为存放了13个特征值的向量。而特征向量以列的方式存储于一个13*13维的矩阵中eigen_vecs。
  27. #########################绘制特征值的方差贡献率图像##############################
  28. tot=sum(eigen_vals)
  29. var_exp=[(i/tot) for i in sorted(eigen_vals,reverse=True)]#用sorted函数进行排序,并用for循环求出各个特征值的方差贡献率,组成一个列表
  30. #使用numpy的cumsum函数计算累计方差,并通过matplotlib的step函数绘制
  31. cum_var_exp=np.cumsum(var_exp)
  32. #画图
  33. import matplotlib.pyplot as plt
  34. ###########下面两句使得图片内可以出现中文
  35. plt.rcParams['font.sans-serif']=['SimHei']
  36. plt.rcParams['axes.unicode_minus'] = False
  37. ###########
  38. plt.bar(range(1, 14), var_exp, alpha=0.5, align='center',label= "单个方差贡献")
  39. plt.step(range(1, 14), cum_var_exp, where='mid',label='累计方差贡献')
  40. plt.ylabel('Explained variance ratio')
  41. plt.xlabel('Principal component index')
  42. plt.legend(loc='best')
  43. plt.tight_layout()
  44. plt.show()
  45. ##########################################特征转换#############################
  46. #按特征值的降序排列特征对:
  47. eigen_pairs=[(np.abs(eigen_vals[i]),eigen_vecs[:,i]) for i in range(len(eigen_vals))]
  48. eigen_pairs.sort(reverse=True)
  49. #接下来选取两个对应的特征值最大的特征向量,这两个值之和占据数据集总体方差的60%(可见特征值的方差贡献率图像)
  50. w=np.hstack((eigen_pairs[0][1][:, np.newaxis],eigen_pairs[1][1][:, np.newaxis]))
  51. #np.hstack用于把几个小数组合并成一个大数组,hstack表示轴1合并。
  52. #hstack的字母h来自于horizontal,表示两个数组是水平的,hstack((a,b))将把b排在a的右边的意思。
  53. #np.newaxis 在使用和功能上等价于 None,其实就是 None 的一个别名。
  54. print('\nW矩阵 \n%s' % w)
  55. print('\n将一个样本转换的PCA的子空间上,得到: \n%s' % x_train_std[0].dot(w))
  56. print('\n样本转换前为: \n%s' % x_train_std[0])
  57. ##将数据集进行特征转换
  58. x_train_pca=x_train_std.dot(w)
  59. #画图
  60. X_train_pca = x_train_std.dot(w)
  61. colors = ['r', 'b', 'g']
  62. markers = ['s', 'x', 'o']
  63. for l, c, m in zip(np.unique(y_train), colors, markers):
  64. plt.scatter(x_train_pca[y_train == l, 0],X_train_pca[y_train == l, 1],c=c, label=l, marker=m)
  65. plt.xlabel('PC 1')
  66. plt.ylabel('PC 2')
  67. plt.legend(loc='lower left')
  68. plt.tight_layout()
  69. plt.show()

结果如下图所示:




上面是给出PCA过程的Python代码,接下来看一下scikit-learn中的PCA类(建议与上面程序结合着理解)

  1. #####################################定义一个画图函数###########################
  2. import numpy as np
  3. import matplotlib.pyplot as plt
  4. from matplotlib.colors import ListedColormap
  5. def plot_decision_regions(X, y, classifier, resolution=0.02):
  6. # setup marker generator and color map
  7. markers = ('s', 'x', 'o', '^', 'v')
  8. colors = ('red', 'blue', 'lightgreen', 'gray', 'cyan')
  9. cmap = ListedColormap(colors[:len(np.unique(y))])
  10. # plot the decision surface
  11. x1_min, x1_max = X[:, 0].min() - 1, X[:, 0].max() + 1
  12. x2_min, x2_max = X[:, 1].min() - 1, X[:, 1].max() + 1
  13. xx1, xx2 = np.meshgrid(np.arange(x1_min, x1_max, resolution),
  14. np.arange(x2_min, x2_max, resolution))
  15. Z = classifier.predict(np.array([xx1.ravel(), xx2.ravel()]).T)
  16. Z = Z.reshape(xx1.shape)
  17. plt.contourf(xx1, xx2, Z, alpha=0.4, cmap=cmap)
  18. plt.xlim(xx1.min(), xx1.max())
  19. plt.ylim(xx2.min(), xx2.max())
  20. # plot class samples
  21. for idx, cl in enumerate(np.unique(y)):
  22. plt.scatter(x=X[y == cl, 0],
  23. y=X[y == cl, 1],
  24. alpha=0.6,
  25. c=cmap(idx),
  26. edgecolor='black',
  27. marker=markers[idx],
  28. label=cl)
  29. ##############################数据的读入、划分、标准化###########################
  30. import pandas as pd
  31. #Python Data Analysis Library 或 pandas 是基于NumPy 的一种工具,该工具是为了解决数据分析任务而创建的。
  32. #Pandas 纳入了大量库和一些标准的数据模型,提供了高效地操作大型数据集所需的工具。
  33. df_wine = pd.read_csv('https://archive.ics.uci.edu/ml/machine-learning-databases/wine/wine.data',header=None)
  34. #读入csv文件,形成一个数据框
  35. #使用葡萄酒数据集
  36. from sklearn.cross_validation import train_test_split
  37. x, y = df_wine.iloc[:, 1:].values, df_wine.iloc[:, 0].values
  38. x_train, x_test, y_train, y_test =train_test_split(x, y, test_size=0.3,stratify=y,random_state=0)
  39. #葡萄酒数据集划分为训练集和测试集,分别占据数据集的70%和30%
  40. #使用单位方差对数据集进行标准化
  41. from sklearn.preprocessing import StandardScaler
  42. sc=StandardScaler()
  43. #注意,当改为from sklearn.preprocessing import StandardScaler as sc时,会报错
  44. # fit_transform() missing 1 required positional argument: 'X'。这就是由于sc没有StandardScaler()而仅仅是StandardScaler
  45. x_train_std=sc.fit_transform(x_train)
  46. x_test_std=sc.fit_transform(x_test)
  47. #####################################使用sklearn中的PCA类#######################
  48. from sklearn.linear_model import LogisticRegression
  49. from sklearn.decomposition import PCA
  50. pca=PCA(n_components=2)#类似于上面的程序,选取两个最大的特征值作为主成分
  51. #做降维处理
  52. x_train_pca=pca.fit_transform(x_train_std)
  53. x_test_pca=pca.transform(x_test_std)
  54. #用逻辑斯蒂回归进行分类(对训练数据进行处理)
  55. lr=LogisticRegression()
  56. lr.fit(x_train_pca,y_train)
  57. plot_decision_regions(x_train_pca,y_train,classifier=lr)
  58. plt.xlabel('PC 1')
  59. plt.ylabel('PC 2')
  60. plt.legend(loc='lower left')
  61. plt.tight_layout()
  62. plt.show()
  63. #用逻辑斯蒂回归进行分类(对测试数据进行处理)
  64. lr=LogisticRegression()
  65. lr.fit(x_train_pca,y_train)
  66. plot_decision_regions(x_test_pca,y_test,classifier=lr)
  67. plt.xlabel('PC 1')
  68. plt.ylabel('PC 2')
  69. plt.legend(loc='lower left')
  70. plt.tight_layout()
  71. plt.show()

结果如下图所示:


比较PCA类与自行实现的PCA分析结果,可以发现,左图为右图沿Y轴对称反转获得。这仅仅是由于特征分析方法不一样而导致,本质上没有区别。


当将主成分由2改为None时,可得到:


当将n_components设置为None时,将按照方差贡献率递减的顺序返回所有主成分。


核主成分分析:

许多机器学习算法都是假定输入数据是线性可分的。降维处理也一样,PCA和LDA都是针对线性可分数据降维。而对于非线性可分的数据要进行降维处理可以使用核技巧的PCA,或称为核PCA。通过使用核PCA可以将非线性可分的数据转换线性可分的低维子空间上(在机器学习笔记5中的核SVM介绍过类似的概念)

线性与非线性可分问题图示如下:


由于本人对于核函数与核技巧理解还不是很深入,下面直接给出书本上的照片(后面有新的体会会及时更新本博文):




下面给出Python代码:

  1. ################################基于RBF核的PCA##################################
  2. from scipy.spatial.distance import pdist, squareform
  3. from scipy import exp
  4. from scipy.linalg import eigh
  5. import numpy as np
  6. def rbf_kernel_pca(X, gamma, n_components):#RBF核函数结合着理论部分来看
  7. """
  8. RBF kernel PCA implementation.
  9. Parameters
  10. ------------
  11. X: {NumPy ndarray}, shape = [n_samples, n_features]
  12. gamma: float
  13. Tuning parameter of the RBF kernel
  14. n_components: int
  15. Number of principal components to return
  16. Returns
  17. ------------
  18. X_pc: {NumPy ndarray}, shape = [n_samples, k_features]
  19. Projected dataset
  20. """
  21. # Calculate pairwise squared Euclidean distances
  22. # in the MxN dimensional dataset.
  23. sq_dists = pdist(X, 'sqeuclidean')
  24. # Convert pairwise distances into a square matrix.
  25. mat_sq_dists = squareform(sq_dists)
  26. # Compute the symmetric kernel matrix.
  27. K = exp(-gamma * mat_sq_dists)
  28. # Center the kernel matrix.
  29. N = K.shape[0]
  30. one_n = np.ones((N, N)) / N
  31. K = K - one_n.dot(K) - K.dot(one_n) + one_n.dot(K).dot(one_n)
  32. # Obtaining eigenpairs from the centered kernel matrix
  33. # scipy.linalg.eigh returns them in ascending order
  34. eigvals, eigvecs = eigh(K)
  35. eigvals, eigvecs = eigvals[::-1], eigvecs[:, ::-1]
  36. # Collect the top k eigenvectors (projected samples)
  37. X_pc = np.column_stack((eigvecs[:, i]
  38. for i in range(n_components)))
  39. return X_pc
  40. ################################分离半月形数据##################################
  41. from sklearn.datasets import make_moons
  42. x, y = make_moons(n_samples=100, random_state=123)
  43. #画出半月形数据
  44. import matplotlib.pyplot as plt
  45. plt.scatter(x[y == 0, 0], x[y == 0, 1], color='red', marker='^', alpha=0.5)
  46. plt.scatter(x[y == 1, 0], x[y == 1, 1], color='blue', marker='o', alpha=0.5)
  47. plt.tight_layout()
  48. plt.show()
  49. #########################先用标准的PCA来进行降维处理#############################
  50. from sklearn.decomposition import PCA
  51. scikit_pca = PCA(n_components=2)
  52. x_spca = scikit_pca.fit_transform(x)
  53. fig, ax = plt.subplots(nrows=1, ncols=2, figsize=(7, 3))
  54. ax[0].scatter(x_spca[y == 0, 0], x_spca[y == 0, 1],color='red', marker='^', alpha=0.5)
  55. ax[0].scatter(x_spca[y == 1, 0], x_spca[y == 1, 1],color='blue', marker='o', alpha=0.5)
  56. ax[1].scatter(x_spca[y == 0, 0], np.zeros((50, 1)) + 0.02, color='red', marker='^', alpha=0.5)
  57. ax[1].scatter(x_spca[y == 1, 0], np.zeros((50, 1)) - 0.02,color='blue', marker='o', alpha=0.5)
  58. ax[0].set_xlabel('PC1')
  59. ax[0].set_ylabel('PC2')
  60. ax[1].set_ylim([-1, 1])
  61. ax[1].set_yticks([])
  62. ax[1].set_xlabel('PC1')
  63. plt.tight_layout()
  64. plt.show()
  65. #########################使用核PCA来进行降维处理#################################
  66. x_kpca = rbf_kernel_pca(x, gamma=15, n_components=2)
  67. fig, ax = plt.subplots(nrows=1,ncols=2, figsize=(7,3))
  68. ax[0].scatter(x_kpca[y==0, 0], x_kpca[y==0, 1],color='red', marker='^', alpha=0.5)
  69. ax[0].scatter(x_kpca[y==1, 0], x_kpca[y==1, 1],color='blue', marker='o', alpha=0.5)
  70. ax[1].scatter(x_kpca[y==0, 0], np.zeros((50,1))+0.02,color='red', marker='^', alpha=0.5)
  71. ax[1].scatter(x_kpca[y==1, 0], np.zeros((50,1))-0.02,color='blue', marker='o', alpha=0.5)
  72. ax[0].set_xlabel('PC1')
  73. ax[0].set_ylabel('PC2')
  74. ax[1].set_ylim([-1, 1])
  75. ax[1].set_yticks([])
  76. ax[1].set_xlabel('PC1')
  77. plt.tight_layout()
  78. plt.show()
  79. ################################分离同心圆数据##################################
  80. from sklearn.datasets import make_circles
  81. X, y = make_circles(n_samples=1000, random_state=123, noise=0.1, factor=0.2)
  82. plt.scatter(X[y == 0, 0], X[y == 0, 1], color='red', marker='^', alpha=0.5)
  83. plt.scatter(X[y == 1, 0], X[y == 1, 1], color='blue', marker='o', alpha=0.5)
  84. plt.tight_layout()
  85. plt.show()
  86. #########################先用标准的PCA来进行降维处理#############################
  87. scikit_pca = PCA(n_components=2)
  88. X_spca = scikit_pca.fit_transform(X)
  89. fig, ax = plt.subplots(nrows=1, ncols=2, figsize=(7, 3))
  90. ax[0].scatter(X_spca[y == 0, 0], X_spca[y == 0, 1],color='red', marker='^', alpha=0.5)
  91. ax[0].scatter(X_spca[y == 1, 0], X_spca[y == 1, 1],color='blue', marker='o', alpha=0.5)
  92. ax[1].scatter(X_spca[y == 0, 0], np.zeros((500, 1)) + 0.02,color='red', marker='^', alpha=0.5)
  93. ax[1].scatter(X_spca[y == 1, 0], np.zeros((500, 1)) - 0.02,color='blue', marker='o', alpha=0.5)
  94. ax[0].set_xlabel('PC1')
  95. ax[0].set_ylabel('PC2')
  96. ax[1].set_ylim([-1, 1])
  97. ax[1].set_yticks([])
  98. ax[1].set_xlabel('PC1')
  99. plt.tight_layout()
  100. plt.show()
  101. #########################使用核PCA来进行降维处理#################################
  102. X_kpca = rbf_kernel_pca(X, gamma=15, n_components=2)
  103. fig, ax = plt.subplots(nrows=1, ncols=2, figsize=(7, 3))
  104. ax[0].scatter(X_kpca[y == 0, 0], X_kpca[y == 0, 1],color='red', marker='^', alpha=0.5)
  105. ax[0].scatter(X_kpca[y == 1, 0], X_kpca[y == 1, 1],color='blue', marker='o', alpha=0.5)
  106. ax[1].scatter(X_kpca[y == 0, 0], np.zeros((500, 1)) + 0.02,color='red', marker='^', alpha=0.5)
  107. ax[1].scatter(X_kpca[y == 1, 0], np.zeros((500, 1)) - 0.02,color='blue', marker='o', alpha=0.5)
  108. ax[0].set_xlabel('PC1')
  109. ax[0].set_ylabel('PC2')
  110. ax[1].set_ylim([-1, 1])
  111. ax[1].set_yticks([])
  112. ax[1].set_xlabel('PC1')
  113. plt.tight_layout()
  114. plt.show()

结果如下图所示:






下面给出使用sklearn中核PCA类来进行处理的Python代码:

  1. ################################分离半月形数据##################################
  2. from sklearn.datasets import make_moons
  3. x, y = make_moons(n_samples=100, random_state=123)
  4. #画出半月形数据
  5. import matplotlib.pyplot as plt
  6. plt.scatter(x[y == 0, 0], x[y == 0, 1], color='red', marker='^', alpha=0.5)
  7. plt.scatter(x[y == 1, 0], x[y == 1, 1], color='blue', marker='o', alpha=0.5)
  8. plt.tight_layout()
  9. plt.show()
  10. #########################核PCA来进行降维处理#############################
  11. from sklearn.decomposition import KernelPCA
  12. KPCA=KernelPCA(n_components=2,kernel='rbf',gamma=15)
  13. x_KPCA=KPCA.fit_transform(x)
  14. #画出结果
  15. import matplotlib.pyplot as plt
  16. import numpy as np
  17. fig, ax = plt.subplots(nrows=1, ncols=2, figsize=(7, 3))
  18. ax[0].scatter(x_KPCA[y == 0, 0], x_KPCA[y == 0, 1],color='red', marker='^', alpha=0.5)
  19. ax[0].scatter(x_KPCA[y == 1, 0], x_KPCA[y == 1, 1],color='blue', marker='o', alpha=0.5)
  20. ax[1].scatter(x_KPCA[y == 0, 0], np.zeros((50, 1)) + 0.02, color='red', marker='^', alpha=0.5)
  21. ax[1].scatter(x_KPCA[y == 1, 0], np.zeros((50, 1)) - 0.02,color='blue', marker='o', alpha=0.5)
  22. ax[0].set_xlabel('PC1')
  23. ax[0].set_ylabel('PC2')
  24. ax[1].set_ylim([-1, 1])
  25. ax[1].set_yticks([])
  26. ax[1].set_xlabel('PC1')
  27. plt.tight_layout()
  28. plt.show()

结果如下图所示:



SVD:

奇异值分解(singular value decomposition,SVD)是一种矩阵分解的技术,是强大的信息提取的工具。SVD的应用场景:隐性语义索引、推荐系统。SVD的数学推导见下图片:


SVD将原始的数据集矩阵Data分解成为如下式所示的形式:


上述分解会构建出一个矩阵,该矩阵只有对角元素,其他元素均为0。另一个惯例就是,该矩阵的对角元素是从大到小排列的。这些对角元素称为奇异值。对应的就是原始数据集矩阵的奇异值。

奇异值就是矩阵特征值的平方根。

由于奇异值分解后的矩阵只有从大到小排列的对角元素。在科学和工程中,一直认为:在某个奇异值的数目(r个)之后,其他的奇异值都置为0。这就意味着数据集中仅有r个重要的特征,而其余特征则都是噪声或冗余特征。

在奇异值跳变的地方选取奇异值(或者,保留矩阵中90%的能量信息。为了计算总能量,可以将所有奇异值求其平方和。于是可以将奇异值的平方和累加到总值的90%为止),那么原始的矩阵就可以用以下结果来近似:


Python中实现奇异值分解的函数如下图所示



此处的Sigma以行向量的形式返回,但实际上它是一个矩阵,只是为了节省空间而已~

给出Python代码如下:

  1. #######################################定义一个数据矩阵#########################
  2. def loadData():
  3. return[[0, 0, 0, 2, 2],
  4. [0, 0, 0, 3, 3],
  5. [0, 0, 0, 1, 1],
  6. [1, 1, 1, 0, 0],
  7. [2, 2, 2, 0, 0],
  8. [5, 5, 5, 0, 0],
  9. [1, 1, 1, 0, 0]]
  10. ##########################################对上面矩阵进行奇异值分解###############
  11. Data=loadData()
  12. import numpy as np
  13. U,Sigma,VT=np.linalg.svd(Data)
  14. print("奇异值")
  15. print(Sigma)#通过打印的结果可以看出,前两个奇异值比后三个奇异值大很多,故此把后三个去掉(在奇异值跳变的地方选)
  16. ######################################重构原始矩阵##############################
  17. Sig=np.mat([[Sigma[0],0],[0,Sigma[1]]])
  18. Data1=U[:,:2]*Sig*VT[:2,:]
  19. print("奇异值分解降维后矩阵")
  20. print(Data1)

结果如下图所示:


感觉对于奇异值分解降维理解还不够深入,接下来我更深入的体会会继续更新本博文


当然~除了以上降维方法以外,还有流形学习降维、多维缩放降维、等度量映射降维、局部线性嵌入等。

主要参考资料如下:

  • 《机器学习实战》
  • 《Python机器学习》
  • 《Python大战机器学习》




声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/小小林熬夜学编程/article/detail/106966
推荐阅读