假设原始数据的维度为d,通过PCA映射之后产生的子空间维度为k(d >= k)。通过PCA降维,我们可以构建出一个d×k维的转换矩阵W,通过矩阵W将原始数据为d维的数据转换到k维数据上。转换之后,第一主身分的方差是最大的,各个主身分之间是不干系的,通过PCA降维之后,每个主身分之间是正交的。主身分对数据值的范围是高度敏感的,以是常日情形下,我们须要先将特色值进行标准化之后,再利用PCA降维技能。PCA算法由以下6个步骤组成:
1、对数据做标准化处理import pandas as pdfrom sklearn.model_selection import train_test_splitfrom sklearn.preprocessing import StandardScalerif __name__ == \"大众__main__\"大众:#获取葡萄酒的数据data = pd.read_csv(\"大众G:/dataset/wine.csv\"大众)#将数据分为x和yx,y = data.ix[:,1:],data.ix[:,0]#将数据分为演习集和测试集train_x,test_x,train,y_test_y = train_test_split(x,y,test_size=0.3,random_state=1)#对特色进行标准化处理std = StandardScaler()train_x_std = std.fit_transform(train_x)test_x_std = std.fit_transform(test_x)2、打算数据的协方差矩阵
通过numpy的cov函数获取数据的协方差矩阵
#获取数据的协方差矩阵cov_mat = np.cov(train_x_std.T)3、打算协方差矩阵的特色值和特色向量
通过numpy的linalg.eig函数获取协方差矩阵的特色值和特色向量,通过特色分解,得到一个包含13个特色值的向量和一个13×13维的特色向量。

#获取特色值和特色向量eigen_vals,eigen_vecs = np.linalg.eig(cov_mat)4、选择与前k个最大特色值对应的特色向量,个中k为新的特色子空间的维度
通过对特色值进行排序,获取前k个特色值。打算单个方差的贡献和累计方差的贡献,方差贡献率是指单个特色值与所有特色值和的比值。
#获取所有特色值的和eigen_sum = sum(eigen_vals)#打算单个特色的贡献方差var_exp = [(i / eigen_sum) for i in sorted(eigen_vals,reverse=True)]#获取累计方差cum_var_exp = np.cumsum(var_exp)#绘图plt.bar(range(1,14),var_exp,alpha=0.5,align=\"大众center\公众,label=\公众累计方差贡献率\"大众)plt.step(range(1,14),cum_var_exp,where=\"大众mid\"大众,label=\公众单个方差贡献率\"大众)plt.ylabel(\"大众方差贡献率\公众)plt.xlabel(\"大众主身分\公众)plt.legend(loc=\"大众best\公众)plt.show()
通过上图各个特色值的方差贡献率可以创造,第一主身分和第二主身分占了60%,下面就取k=2,为了方便后面作图。
5、通过前k个特色向量构建转换矩阵W#获取特色对eigen_pairs = [(np.abs(eigen_vals[i]),eigen_vecs[:,i]) for i in range(len(eigen_vals))]#对特色对进行排序eigen_pairs.sort(reverse=True)#获取映射矩阵WW = np.hstack((eigen_pairs[0][1][:,np.newaxis],eigen_pairs[1][1][:,np.newaxis]))6、将数据维度为k的数据通过转换矩阵W映射到维度为d的空间上
#对演习数据通过映射矩阵W进行转换train_x_std_pca = train_x_std.dot(W)#绘制散点图colors = [\公众r\"大众,\公众b\"大众,\"大众g\公众]markers = [\"大众s\"大众,\"大众x\"大众,\"大众o\公众]for l,c,m in zip(np.unique(train_y),colors,markers):plt.scatter(train_x_std_pca[train_y==l,0],train_x_std_pca[train_y==l,1],c=c,label=l,marker=m)plt.xlabel(\"大众PC1\"大众)plt.ylabel(\"大众PC2\公众)plt.legend(loc=\公众lower left\"大众)plt.show()
通过不雅观察上图可以创造,PC1相对付PC2而言,数据更多的是沿着PC1方向上分布,通过上图展示后,3类数据通过线性分类器就能够很好的区分。
二、通过sklearn来实现PCA降维import pandas as pdfrom sklearn.model_selection import train_test_splitfrom sklearn.preprocessing import StandardScalerimport numpy as npimport matplotlib.pyplot as pltfrom sklearn.linear_model import LogisticRegressionfrom sklearn.decomposition import PCAif __name__ == \"大众__main__\公众:#获取葡萄酒的数据data = pd.read_csv(\公众G:/dataset/wine.csv\"大众)#将数据分为x和yx,y = data.ix[:,1:],data.ix[:,0]#将数据分为演习集和测试集train_x,test_x,train_y,test_y = train_test_split(x,y,test_size=0.3,random_state=1)#对特色进行标准化处理std = StandardScaler()train_x_std = std.fit_transform(train_x)test_x_std = std.fit_transform(test_x)#创建一个PCA模型,并设置降维后的维度为2pca = PCA(n_components=2)logistic = LogisticRegression()train_x_std_pca = pca.fit_transform(train_x_std)test_x_std_pca = pca.fit_transform(test_x_std)logistic.fit(train_x_std_pca,train_y)print(\公众演习集上的准确率:\"大众,logistic.score(train_x_std_pca,train_y))print(\公众测试集上的准确率:\"大众,logistic.score(test_x_std_pca,test_y))
演习集上的准确率: 0.967741935484
测试集上的准确率: 0.925925925926