一、PCA
PCA:主成分分析(Principal Component Analysis)是一种使用线性映射来进行数据降维的方法,同时去除数据的相关性,以最大限度保持原始数据的方差信息。
【1】PCA就是要找出数据最主要的方面来代替原始数据。
【2】PCA通常用于高维数据集的探索和可视化,还可以用作数据的压缩和预处理。
pca主成分求解的过程是:
【1】计算每列的均值
【2】减去平均列值来使得每列的值居中
【3】计算中心矩阵C的协方差矩阵
【4】计算协方差矩阵V的特征分解,产生特征值列表和特征向量列表
【5】特征值表示,以B为列
【6】投影
可以使用其他矩阵分解方法,例如奇异值分解或者SVD。
相关性: 两列一起变化的数量和方向的标准化度量。协方差是跨多个列的相关性的广义和非标准化版本。
协方差矩阵: 给定矩阵的协方差计算,其中每列与包括自身在内的所有其他列的协方差分数。
奇异值: 如果我们要存储很多高清的图片,而又受限于存储空间的限制,在尽可能保证图像可被识别的精度的前提下,我们可以保留奇异值较大的若干项,舍去奇异值较小的项即可。奇异值往往对应着矩阵中隐含的重要信息,且重要性和奇异值大小正相关。
1、什么是维度
维度:共同构造标签的特征。
对于数组和series(回顾numpy和pandas),则使用shape的方式查看。
行与列构建二维表:
【1】数组中的每一张表,都可以是一个特征矩阵或者一个Dataframe,这些结构永远只有一张表,所以一定有行列,其中行是样本,列是特征。
【2】针对每一张表,维度是指样本的数量或者特征的数量,一般无特别说明,指的都是特征的数量。
【3】除了索引之外,一个特征是一维,两个特征是二维,n个特征是n维。
【4】对于图像来说,维度就是图像中特征向量的数量。特征向量可以理解为是坐标轴,一个特征向量定义一条直线,是一维的,两个相互垂直的特征向量定义一个平面,即一个直角坐标系,就是二维。三个相互垂直的特征向量定义一个空间,即一个立体直角坐标系,就是三维。
2、什么是降维
降维:减少特征矩阵中特征的数量
降维目的:算法运算更快,效果更好,提高可视化可能性(因为三维以上的数据可视化的难度大)
它可以被认为是一种投影方法,将具有m列特征的数据投影到具有m或者更少列的子空间中,同时保留原始数据的本质。
PCA方法可以使用线性代数工具来描述和实现。
PCA是应用于数据集的操作,由n * m 矩阵A表示,它导致A的投影,将其称为B。
二、案例:PCA对人脸数据集的降维
# 01 导入库 from sklearn.datasets import fetch_lfw_people from sklearn.decomposition import PCA import matplotlib.pyplot as plt import numpy as np
# 02 实例化数据集 faces = fetch_lfw_people(min_faces_per_person=60) faces.images
faces.images.shape # 得到三维数据 # 1348 # 62:每个图像行上面的特征 #47:每个图像列上面的特征 #62×47指的是像素,即最后图片会呈现出的样子
1348指的是样本数,表示我们调用的数据有1348张图像。
X=faces.data X.shape # (1348, 2914) 此时X变成二维的数据
# 03 特征矩阵的可视化 fig, axes = plt.subplots(4,5 #20个图像 ,figsize=(8,4) ,subplot_kw = {"xticks":[],"yticks":[]} ) axes[0][0].imshow(faces.images[0,:,:]) #画一个图 fig axes axes.shape # 4行5列 axes[0][0].imshow # 得到第一个图像
# 03 特征矩阵的可视化 fig, axes = plt.subplots(4,5 #20个图像 ,figsize=(8,4) ,subplot_kw = {"xticks":[],"yticks":[]} ) axes[0][0].imshow(faces.images[0,:,:]) #画一个图 fig axes axes.shape axes[0][0].imshow axes.flat # 降维 [*axes.flat] enumerate(axes.flat) # 枚举 for i, ax in enumerate(axes.flat): ax.imshow(faces.images[i,:,:] ,cmap="gray" )
# 04 建模降维并提取新的特征空间矩阵 # 2914个特征 pca=PCA(150).fit(X) # 将2914个特征通过PCA进行降维,降维到150个特征,并且使用fit进行实例化 V=pca.components_ # 保存处理好的矩阵 V.shape # 取150个特征(用于图片压缩)
V[0]
# 05 新的特征空间矩阵进行可视化 fig, axes = plt.subplots(3,8,figsize=(8,4),subplot_kw = {"xticks":[],"yticks":[]}) for i, ax in enumerate(axes.flat): ax.imshow(V[i,:].reshape(62,47),cmap="gray")
从1348个特征降到150,可以看到图片的基本轮廓还在,但是已经变模糊了。
PCA在这个案例中的作用:将原来清晰照片当中重要的数据特征提取出来,使之能够做快速的计算。
三、例子
#完整例子 # test classification dataset from sklearn.datasets import make_classification # define dataset X, y = make_classification(n_samples=1000, n_features=20, n_informative=15, n_redundant=5, random_state=7) # summarize the dataset print(X.shape, y.shape) # 1000个样本,20个特征
import pandas as pd testXy=pd.DataFrame(X,y)
# 折线图绘制特征 testXy.plot()
使用逻辑回归LogisticRegression对降维的数据进行验证,观察降到多少维度的时候,能够稳定的保持一定的准确率。
# 使用逻辑回归算法评估 PCA以进行分类 # 在拟合逻辑回归模型的同时对该数据集使用降维。使用 Pipeline,第一步执行 PCA 转换并选择 10 个最重要的维度或组件,然后在这些特征上拟合逻辑回归模型。 # Pipeline:过滤 from numpy import mean from numpy import std from sklearn.datasets import make_classification from sklearn.model_selection import cross_val_score # 交叉验证 from sklearn.model_selection import RepeatedStratifiedKFold from sklearn.pipeline import Pipeline # 管道 from sklearn.decomposition import PCA from sklearn.linear_model import LogisticRegression # 定义数据集 X, y = make_classification(n_samples=1000, n_features=20, n_informative=15, n_redundant=5, random_state=7) # 定义管道pipeline steps = [('pca', PCA(n_components=10)), ('m', LogisticRegression())] model = Pipeline(steps=steps) # 评估模型 cv = RepeatedStratifiedKFold(n_splits=10, n_repeats=3, random_state=1) n_scores = cross_val_score(model, X, y, scoring='accuracy', cv=cv, n_jobs=-1, error_score='raise') # 性能报告 print('Accuracy: %.3f (%.3f)' % (mean(n_scores), std(n_scores)))
# 将 PCA组件数与逻辑回归算法进行比较以进行分类 from numpy import mean from numpy import std import numpy as np from sklearn.datasets import make_classification from sklearn.model_selection import cross_val_score from sklearn.model_selection import RepeatedStratifiedKFold from sklearn.pipeline import Pipeline from sklearn.decomposition import PCA from sklearn.linear_model import LogisticRegression from matplotlib import pyplot # 定义获取数据集函数,原始特征是20 def get_dataset(): X, y = make_classification(n_samples=1000, n_features=20, n_informative=15, n_redundant=5, random_state=7) return X, y # 获取不同特征树下的模型列表进行比较 def get_models(): models = dict() for i in range(1,21): steps = [('pca', PCA(n_components=i)), ('m', LogisticRegression())] models[str(i)] = Pipeline(steps=steps) return models # 通过交叉验证评估模型 def evaluate_model(model, X, y): cv = RepeatedStratifiedKFold(n_splits=10, n_repeats=3, random_state=1) scores = cross_val_score(model, X, y, scoring='accuracy', cv=cv, n_jobs=-1, error_score='raise') return scores # 获取数据集 X, y = get_dataset() # get the models to evaluate models = get_models() # 评估模型并保存结果 results, names = list(), list() for name, model in models.items(): scores = evaluate_model(model, X, y) results.append(scores) names.append(name) print('>%s %.3f (%.3f)' % (name, mean(scores), std(scores))) # 模型绘图以进行比较plot model performance for comparison pyplot.boxplot(results, labels=names, showmeans=True) # pyplot.plot(range(1,21),results,marker='o', linestyle='dashed') pyplot.xticks(rotation=90) pyplot.legend() pyplot.show() # 从图中看出,到15就平稳了,因此=取15
四、PCA对红酒数据可视化
# PCA可视化——在三维空间下 # 以红酒数据为例子 from sklearn.datasets import load_wine winedata = load_wine() X, y = winedata['data'], winedata['target'] print(X.shape) print(y.shape) # 178个样本,13个特征
#选择任意两个特征进行绘图 import matplotlib.pyplot as plt plt.scatter(X[:,1], X[:,2], c=y,s=50) # S代表点的大小 plt.show()
#选择三个特征进行三维数据展示 import matplotlib.pyplot as plt fig,ax=plt.subplots(figsize=(18,7),dpi=90) ax = fig.add_subplot(projection='3d') ax.scatter(X[:,1], X[:,2], X[:,3],c=y,s=45) #三维以上呢? plt.show()
可以看到对于上图中三维的数据,要将点根据颜色区分,显然比二维的难度更大,这也就是降维的目的所在。
from sklearn.decomposition import PCA pca = PCA() Xt = pca.fit_transform(X) #一步到位 plot = plt.scatter(Xt[:,0], Xt[:,1], c=y,s=45) plt.legend(handles=plot.legend_elements()[0], labels=list(winedata['target_names'])) plt.show()
from sklearn.preprocessing import StandardScaler from sklearn.pipeline import Pipeline pca = PCA() pipe = Pipeline([('scaler', StandardScaler()), ('pca', pca)]) #缩放数据 Xt = pipe.fit_transform(X) plot = plt.scatter(Xt[:,0], Xt[:,1], c=y,s=55) plt.legend(handles=plot.legend_elements()[0], labels=list(winedata['target_names'])) plt.show()