大家好,欢迎来到IT知识分享网。
第一部分:基本含义
PCA主要用于特征降维。
PCA,全称为主成分分析(Principal Component Analysis),是一种数据降维技术,常用于处理高维数据。其主要目的是通过减少变量数量来简化数据集,同时尽可能保留数据的主要信息。
复杂问题简单化,化繁为简,做事抓住核心,射人先射马,擒贼先擒王
因此最重要的部分就是对“本质”的抓取
第二部分:PCA的核心思想和原理
我们以分类问题为例:
我们投射到x轴和y轴两类,但是如何选用哪一个呢?
我们就需要看哪一个在降维之后任然能够具有很好的区分性,能够尽量体现降维之前数据之间的分布情况和相互关系。
可以看出横轴的比纵轴的要好一点,因为分布比较分散,但是横轴不一定是最好的
最好的投影轴如下:
上面的这条红线在投影之后距离最大。
那么找到的这个红线,就叫“主成分PC”
方差这块如果不是很懂,可以看我博客:机器学习之线性代数基础知识汇总补充(内积)-CSDN博客
最终我们的目标:
就需要:
方差Var(特征1)和Var(特征2)最大,协方差Cov(特征1,特征2)为最小(为0)
优化目标也就是斜线上,从大到小排列,上下两个区域的值都是0
第三部分:PCA求解算法
(1)PCA主要求解步骤
①原始数据矩阵化X后,零均值化
②求协方差矩阵
③求协方差矩阵的特征值和特征向量
对特征值和特征向量不太懂的可以看我的博客:机器学习+线性代数(特征值和特征向量)-CSDN博客
④按特征值从大到小取特征向量前k行组成矩阵w
⑤获取降维后的数据
(2)注意事项
验证集,测试集执行同样的降维
验证集,测试集执行零均值化操作时,均值须来自于训练集
保证训练集,测试集独立同分布一致性(如果不能保证,则可能会出现一种叫做方差漂移的问题)
(3)PCA的主要作用
①有效缓解维度灾难
②数据降噪效果好
③降维后数据特征独立
④无法解决过拟合
(因为它可能舍弃掉的事重要信息,保留下来的是一些没有那么重要的信息,这主要是因为,可能它在训练集上的表现情况体现的是这个特征不重要,但是因为训练样本太少,其实这个特征很重要)
第四部分:PCA算法代码实现(二维到一维)
(1)导包
#第一部分:导包 import numpy as np
(2)创建数据集
#第二部分:创建数据集 import matplotlib.pyplot as plt w, b = 1.8, 2.5 np.random.seed(0) x1 = np.random.rand(100) * 4#仅仅只是代表100个数据(100,) noise = np.random.randn(100) x2 = w * x1 + b + noise#仅仅只是代表100个数据(100,) x = np.vstack([x1, x2]).T#纵向合并转置(100, 2) print(x.shape) plt.scatter(x[:, 0], x[:, 1]) plt.show()
(3)PCA降维
①零均值化
#第三部分:开始进行PCA降维 #3.1零均值化 x -= np.mean(x, axis=0) plt.scatter(x[:, 0], x[:, 1]) plt.show()
②使用PCA降维(包含第三部分中PCA主要求解步骤的2,3,4)
#3.2使用PCA from sklearn.decomposition import PCA pca = PCA(n_components=1)# 指定只提取一个主成分 pca.fit(x) pca.components_#属性返回一个数组,其中包含提取的主成分。 #它将返回形状为 (1, n_features) 的数组,表示选定的主成分的方向向量。 print(pca.components_) #输出结果为:[[0. 0.]]代表第一个主成分的方向向量 #绘制找到的主成分的这条基准线(主成分PC线) plt.scatter(x[:, 0], x[:, 1], s=10) plt.plot( np.array([pca.components_[0][0] * -1, pca.components_[0][0] * 1]) * 5, np.array([pca.components_[0][1] * -1, pca.components_[0][1] * 1]) * 5, c='r' ) plt.show()
③数据降维
#3.3数据降维 x_pca = pca.transform(x) x_pca.shape plt.scatter(x_pca, np.zeros_like(x_pca), s=10) plt.show()
④数据升维还原原先数据图形
#3.4数据升维 x_pca_inv = pca.inverse_transform(x_pca) plt.scatter(x[:, 0], x[:, 1], s=10) plt.scatter(x_pca_inv[:, 0], x_pca_inv[:, 1], s=10, c='r') plt.show()
得到的红线不是连续的这是因为通过上面的降维,往往会损失部分的原有数据特征。
(4)完整pycharm代码实现
#第一部分:导包 import numpy as np #第二部分:创建数据集 import matplotlib.pyplot as plt w, b = 1.8, 2.5 np.random.seed(0) x1 = np.random.rand(100) * 4#仅仅只是代表100个数据(100,) noise = np.random.randn(100) x2 = w * x1 + b + noise#仅仅只是代表100个数据(100,) x = np.vstack([x1, x2]).T#纵向合并转置(100, 2) print(x.shape) plt.scatter(x[:, 0], x[:, 1]) plt.show() #第三部分:开始进行PCA降维 #3.1零均值化 x -= np.mean(x, axis=0) plt.scatter(x[:, 0], x[:, 1]) plt.show() #3.2使用PCA from sklearn.decomposition import PCA pca = PCA(n_components=1)# 指定只提取一个主成分 pca.fit(x) pca.components_#属性返回一个数组,其中包含提取的主成分。 #它将返回形状为 (1, n_features) 的数组,表示选定的主成分的方向向量。 print(pca.components_) #输出结果为:[[0. 0.]]代表第一个主成分的方向向量 #绘制找到的主成分的这条基准线(主成分PC线) plt.scatter(x[:, 0], x[:, 1], s=10) plt.plot( np.array([pca.components_[0][0] * -1, pca.components_[0][0] * 1]) * 5, np.array([pca.components_[0][1] * -1, pca.components_[0][1] * 1]) * 5, c='r' ) plt.show() #3.3数据降维 x_pca = pca.transform(x) x_pca.shape plt.scatter(x_pca, np.zeros_like(x_pca), s=10) plt.show() #3.4数据升维 x_pca_inv = pca.inverse_transform(x_pca) plt.scatter(x[:, 0], x[:, 1], s=10) plt.scatter(x_pca_inv[:, 0], x_pca_inv[:, 1], s=10, c='r') plt.show()
第五部分:基础降维代码实现(高维)
我们这次使用一个更高维的数据集(手写数字数据集):
(1)导包
#第一部分:导包 import numpy as np import matplotlib.pyplot as plt
(2)创建数据集
#第二部分:加载数据集 from sklearn.datasets import load_digits digits = load_digits() x = digits.data y = digits.target x.shape, y.shape
(3)数据集划分
#第三部分:数据集划分 from sklearn.model_selection import train_test_split x_train, x_test, y_train, y_test = train_test_split(x, y, random_state=233)
(4)PCA降维并可视化全部主成分方差权重数据
from sklearn.decomposition import PCA #4.1对所有主成分进行数据效果可视化展示 pca = PCA()#默认的是对所有的主成分进行划分 pca.fit(x_train) #输出每一个特征对应的重要性比例(方差所占的大小权重) print(pca.explained_variance_ratio_)#1.e-01 代表的是15%左右的意思 #画出这些特征权重从0累加到1的过程中的变化大小 ratio_cum = np.cumsum(pca.explained_variance_ratio_) plt.plot(ratio_cum) plt.show()
因此我们就可以看出总共有64个特征,但是光前20个特征的方差权重和就能占比超过90%,也就是说我们可以通过这20维的数据来描述原始数据将近90%的信息。
(6)直接设置保留的特征总数
#4.2直接设置要保留的特征值数目 pca = PCA(20) pca.fit(x_train)
(7)直接设置要保留原始数据的百分比
#4.3直接设置要保留原始数据的百分比 pca = PCA(0.9) pca.fit(x_train) print(pca.n_components_)#输出要达到0.9的原始信息需要的特征数
代表输出要达到0.9的原始信息需要的特征数为21个
(8)模型评估-查看降维后的效果(使用逻辑回归)
#第五部分:查看降维后的效果(使用逻辑回归) from sklearn.linear_model import LogisticRegression clf = LogisticRegression(solver='saga', tol=0.001, max_iter=500, random_state=233)
①没有降维的情况下使用逻辑会的模型评分score以及花费时间
%%time clf.fit(x_train,y_train) clf.score(x_test,y_test) #5.1没有降维的情况下使用逻辑会的模型评分score以及花费时间
注意:这段代码需要在jupyter上面运行,因为含有%%time魔法,pycharm无法运行。
②有降维的情况下使用逻辑会的模型评分score以及花费时间
%%time x_train_pca = pca.transform(x_train) x_test_pca = pca.transform(x_test) clf.fit(x_train_pca, y_train) clf.score(x_test_pca, y_test) #5.2有降维的情况下使用逻辑会的模型评分score以及花费时间
可以看到耗时从979变为405,而准确度只是下降了不到1%
(9)所有代码汇总
注意:由于这个(8)中的代码有%%time,因此这个全部代码不能在pycharm中运行,需要在jupyter notebook中运行:
#第一部分:导包 import numpy as np import matplotlib.pyplot as plt #第二部分:加载数据集 from sklearn.datasets import load_digits from sklearn.decomposition import PCA digits = load_digits() x = digits.data y = digits.target x.shape, y.shape #第三部分:数据集划分 from sklearn.model_selection import train_test_split x_train, x_test, y_train, y_test = train_test_split(x, y, random_state=233) #第四部分:PCA降维 ''' from sklearn.decomposition import PCA #4.1对所有主成分进行数据效果可视化展示 pca = PCA()#默认的是对所有的主成分进行划分 pca.fit(x_train) #输出每一个特征对应的重要性比例(方差所占的大小权重) print(pca.explained_variance_ratio_)#1.e-01 代表的是15%左右的意思 #画出这些特征权重从0累加到1的过程中的变化大小 ratio_cum = np.cumsum(pca.explained_variance_ratio_) plt.plot(ratio_cum) plt.show() ''' ''' #4.2直接设置要保留的特征值数目 pca = PCA(20) pca.fit(x_train) ''' #4.3直接设置要保留原始数据的百分比 pca = PCA(0.9) pca.fit(x_train) print(pca.n_components_)#输出要达到0.9的原始信息需要的特征数 #第五部分:查看降维后的效果(使用逻辑回归) #第五部分:查看降维后的效果(使用逻辑回归) from sklearn.linear_model import LogisticRegression clf = LogisticRegression(solver='saga', tol=0.001, max_iter=500, random_state=233) %%time clf.fit(x_train,y_train) clf.score(x_test,y_test) %%time x_train_pca = pca.transform(x_train) x_test_pca = pca.transform(x_test) clf.fit(x_train_pca, y_train) clf.score(x_test_pca, y_test)
第六部分:PAC在数据降噪中的应用
通过PCA在降维过程中所丢失的数据,(大部分都是噪声数据特征),从而实现数据降噪的效果。
下面我们以手写数据集为例,来探究PAC在数据降噪中的应用:
(1)导包
#第一部分:导包 import numpy as np from matplotlib import pyplot as plt
(2)创建数据集
#第二部分:创建数据集 from sklearn.datasets import load_digits digits = load_digits() x = digits.data y = digits.target x.shape, y.shape
(3)绘制手写数据集图像(绘制前20条数据)
#第三部分:绘制前20条数据 def plot_top20_digits(x): for i in range(20): plt.subplot(4, 5, i + 1) plt.xticks([]) plt.yticks([]) plt.imshow(x[i].reshape(8, 8), cmap=plt.cm.gray_r, interpolation="nearest") plt.show() plot_top20_digits(x)
上面这个就是手写数据集的真实模样(没有加入噪声)
(4)往原始数据(图片)中添加噪声
#第四部分:往原始数据集里添加噪声 np.random.seed(0) x_noise = x + np.random.randn(x.shape[0], x.shape[1]) * 3 plot_top20_digits(x_noise)
(5)使用PCA对噪声数据进行去噪
#第五部分:使用PCA对噪声数据进行去噪 pca=PCA(0.5) pca.fit(x_noise) x_noise_pca = pca.transform(x_noise)#plot_top20_digits(x_noise_pca) x_noise_inv = pca.inverse_transform(x_noise_pca)#它提供了一个尽可能接近原始数据的重构。该过程利用已存储的主成分和均值来重建数据。 plot_top20_digits(x_noise_inv)#然后再把它输出成原先的形式因为x_noise_pca是低维度的,没有办法输出图片
可以看出,去噪后的图像尽管没有之前那么清晰,但是比直接加入噪音的图像已经好很多了。
(6)上述完整pycharm代码
#第一部分:导包 import numpy as np from matplotlib import pyplot as plt #第二部分:创建数据集 from sklearn.datasets import load_digits from sklearn.decomposition import PCA digits = load_digits() x = digits.data y = digits.target x.shape, y.shape #第三部分:绘制前20条数据 def plot_top20_digits(x): for i in range(20): plt.subplot(4, 5, i + 1) plt.xticks([]) plt.yticks([]) plt.imshow(x[i].reshape(8, 8), cmap=plt.cm.gray_r, interpolation="nearest") plt.show() plot_top20_digits(x) #第四部分:往原始数据集里添加噪声 np.random.seed(0) x_noise = x + np.random.randn(x.shape[0], x.shape[1]) * 3 plot_top20_digits(x_noise) #第五部分:使用PCA对噪声数据进行去噪 pca=PCA(0.5) pca.fit(x_noise) x_noise_pca = pca.transform(x_noise)#plot_top20_digits(x_noise_pca) x_noise_inv = pca.inverse_transform(x_noise_pca)#它提供了一个尽可能接近原始数据的重构。该过程利用已存储的主成分和均值来重建数据。 plot_top20_digits(x_noise_inv)#然后再把它输出成原先的形式因为x_noise_pca是低维度的,没有办法输出图片
第七部分:PCA的优缺点和适用条件
(1)优点
- 简单容易计算,易于计算机实现
- 可以有效减少特征选择工作量,降低算法计算成本
- 不要求数据正态分布,无参数限制,不受样本标签限制
- 有效去除噪声,使得数据更加容易使用
(2)缺点
- 非高斯分布情况下,PCA得到的主元可能并非最优
- 特征值分解的来源方法是主成分限制(矩阵必须是方阵)
- 降维后存在信息丢失
- 主成分解释较易随机数较困难
(3)适用条件
- 变量间强相关数据
- 数据压缩,预处理
- 数据降维,噪声去除
- 高维数据探索与可视化
免责声明:本站所有文章内容,图片,视频等均是来源于用户投稿和互联网及文摘转载整编而成,不代表本站观点,不承担相关法律责任。其著作权各归其原作者或其出版社所有。如发现本站有涉嫌抄袭侵权/违法违规的内容,侵犯到您的权益,请在线联系站长,一经查实,本站将立刻删除。 本文来自网络,若有侵权,请联系删除,如若转载,请注明出处:https://haidsoft.com/125239.html