12 降维
12.1原理
降维解决的问题:
- 缓解维度灾难问题
- 压缩数据的同时让信息损失最小化
- 理解低维度更容易
12.2主生成分析(PCA)
12.2.1 原理
主生成分析(Principal Cpmponent Analysis:PCA)
无监督线性降维,用于数据压缩、消除冗余和消除噪音
X=[[x11 x12 x13 … x1p],
[x21 x22 x23 … x2p],
…
[xn1 xn2 xn3 … xnp]]
=[x1 x2 x3 … xp]
其中xj=[x1j x2j … xnj] ( j=1,2,3,…,p )
主成分分析就是将P个观测变量综合成为P个新的变量(综合变量),即:
F1 =a11x1+a12x2+…+a1pxp
F2 =a21x1+a22x2+…+a2pxp
…
Fp =ap1x1+ap2x2+…+appxp
简写
Fj = aj1x1+aj2x2+…+ajpxp (j=1,2,3,…,p )
Fi 与 Fj 互不相关(ij,i,j= 1,2,3,…,p )
F1的方差 > F2的方差> … >Fp的方差
称为第一主成分F1,为第二主成分F2,…第p主成分Fp
12.2.2类参数、属性和方法
类
class sklearn.decomposition.PCA(n_components=None, *, copy=True, whiten=False, svd_solver='auto', tol=0.0, iterated_power='auto', random_state=None)
属性
属性 |
类别 |
介绍 |
components_ |
ndarray of shape (n_components, n_features) |
特征空间中的主轴,表示数据方差最大的方向。这些成分按方差排序 |
explained_variance_ |
ndarray of shape (n_components,) |
由每个选定的组成部分解释的差异量。等于X的协方差矩阵的最大特征值。版本0.18中的新功能。 |
explained_variance_ratio_ |
ndarray of shape (n_components,) |
由每个所选组成部分解释的方差百分比。如果未设置nè分量,则存储所有分量,比率之和等于1.0 |
singular_values_ |
ndarray of shape (n_components,) |
|
mean_ |
ndarray of shape (n_features,) |
对应于每个选定组件的奇异值。奇异值等于低维空间中n分量变量的2-范数。 |
n_components_ |
int |
组件的估计数量。当n_components设置为'mle'或介于0和1之间的数字(使用svd_solver=='full')时,该数字根据输入数据进行估计。否则它等于参数n_components,如果n_components为None,则等于n_features和n_samples的较小值。 |
n_features_ |
int |
训练数据中的特征数。 |
n_samples_ |
int |
训练数据中的样本数。 |
noise_variance_ |
float |
根据Tipping和Bishop 1999的概率PCA模型估计噪声协方差。参见C.Bishop的“模式识别和机器学习”,12.2.1 p.574或http://www.miketipping.com/papers/met-mppca.pdf。需要计算估计的数据协方差和得分样本。等于X的协方差矩阵的(min(n_features, n_samples) - n_components)最小特征值的平均值 |
方法
fit(X[, y]) |
用X来拟合模型。 |
fit_transform(X[, y]) |
用X拟合模型,对X进行降维。 |
get_covariance() |
用生成模型计算数据协方差。 |
get_params([deep]) |
获取此估计器的参数。 |
get_precision() |
用生成模型计算数据精度矩阵。 |
inverse_transform(X) |
将数据转换回其原始空间。 |
score(X[, y]) |
返回所有样本的平均对数似然。 |
score_samples(X) |
返回每个样本的对数似然。 |
set_params(**params) |
设置此估计器的参数。 |
transform(X) |
对X应用降维。 |
12.2.3散点图与热力分析
Util.py
#画降维散点图 def draw_scatter_for_Dimension_Reduction(self,X,mydata,title,algorithm): # 将3个分类主成分提取出来 X0 = X[mydata.target==0] X1 = X[mydata.target==1] X2 = X[mydata.target==2] #绘制散点图 plt.scatter(X0[:,0],X0[:,1],c='r',s=60,edgecolor='k') plt.scatter(X1[:,0],X1[:,1],c='g',s=60,edgecolor='k') plt.scatter(X2[:,0],X2[:,1],c='b',s=60,edgecolor='k') #设置图注 plt.legend(mydata.target_names,loc='best') plt.xlabel('特征 1') plt.ylabel('特征 2') mytitle = title+algorithm+"散点图“ self.show_pic(mytitle) def draw_Heat_chart(self,pca,mydata,title,algorithm): plt.matshow(pca.components_,cmap='plasma') #纵轴为主成分 plt.yticks([0,1],['特征 1','特征 2']) plt.colorbar() #横轴为原始特征向量 plt.xticks(range(len(mydata.feature_names)),mydata.feature_names,rotation=60,ha='left') mytitletitle = title+algorithm+"热度图" self.show_pic(mytitletitle)
主文件
#降维PCA可视化 def dimension_reduction_for_pca(mydata,title): myutil = util() scaler = StandardScaler() X,y = mydata.data,mydata.target #由于是无监督学习,所以仅对X进行拟合 X_scaled = scaler.fit_transform(X) # 打印处理后的数据形态 print("处理后的数据形态:",X_scaled.shape) # 进行PCA处理 pca = PCA(n_components=2) #降到2类 pca.fit(X_scaled) X_pca = pca.transform(X_scaled) # 打印主成分提取后的数据形态 print("主成分提取后的数据形态:",X_pca.shape) myutil.draw_Heat_chart(pca,mydata,title,'主成分提取(PCA)') #使用主成分绘制热度图 myutil.draw_Heat_chart(pca,mydata,title ,'主成分提取(PCA)')
def call_dimension_reduction_for_pca(): mydatas = [datasets.load_iris(),datasets.load_wine(),datasets.load_breast_cancer()] titles = ["鸢尾花","红酒","乳腺癌"] for (mydata,title) in zip(mydatas,titles): dimension_reduction_for_pca(mydata,title)
输出
处理后的数据形态: (150, 4) 主成分提取后的数据形态: (150, 2) 处理后的数据形态: (178, 13) 主成分提取后的数据形态: (178, 2) 处理后的数据形态: (569, 30) 主成分提取后的数据形态: (569, 2)
12.2.4 案例——特征提取
from sklearn.neural_network import MLPClassifier #特征提取 def pca_for_face(): faces = datasets.fetch_lfw_people(min_faces_per_person=20,resize=0.8) image_shape = faces.images[0].shape #把照片打印出来 fig, axes = plt.subplots(3,4,figsize=(12,9),subplot_kw={'xticks':(),'yticks':()}) for target,image,ax in zip(faces.target,faces.images,axes.ravel()): ax.imshow(image,cmap=plt.cm.gray) ax.set_title(faces.target_names[target]) plt.show()
输出
#用神经网络模型进行训练 X_train,X_test,y_train,y_test = train_test_split(faces.data/255,faces.target,random_state=62) mlp = MLPClassifier(hidden_layer_sizes=[100,100],random_state=62,max_iter=400) mlp.fit(X_train,y_train) print("模型识别准确率:{:.2%}".format(mlp.score(X_test,y_test))) #使用白化功能处理人脸数据 pca = PCA(whiten=True,n_components=0.9,random_state=62).fit(X_train) X_train_whiten = pca.transform(X_train) X_test_whiten = pca.transform(X_test) print("白化后数据形态:{}".format(X_train_whiten.shape)) #使用白化后的神经网络训练 mlp.fit(X_train_whiten,y_train) print("白化后模型识别准确率:{:.2%}".format(mlp.score(X_test_whiten,y_test)))
输出
模型识别准确率:53.84% 白化后数据形态:(2267, 105) 白化后模型识别准确率:57.14%