一、PCA主成分分析原理
1.降维的作用:(为什么会有这些作用?)
(1)降低时间的复杂度和空间复杂度
(2)节省了提取不必要特征的开销
(3)去掉数据集中夹杂的噪音
(4)较简单的模型在小数据集上有更强的鲁棒性
(5)当数据能有较少的特征进行解释,我们可以更好地解释数据,是的我们可以提取知识
(6)实现数据的可视化
2、降维的目的
用来进行特征选择和特征提取。
①特征选择:选择重要的特征子集,删除其余特征;
②特征提取:由原始特征形成的较少的新特征。
3.将样本投影到某一维上,新的坐标的选择方式:找到第一个坐标,数据集在该坐标的方差最大(方差最大也就是我们在这个数据维度上能更好地区分不同类型的数据),然后找到第二个坐标,该坐标与原来的坐标正交。该过程会一直的重复,直到新坐标的数目和原来的特征个数相同,这时候我们会发现数据的大部分方差都在前面几个坐标上表示,这些新的维度就是我们所说的主成分。
(1)PCA的基本思想:寻找数据的主轴方向,由主轴构成一个新的坐标系,这里的维数可以比原维数低,然后数据由原坐标系向新坐标系投影,这个投影的过程就是降维的过程。
缺陷是降维处理后的两个组成的特征的物理特性未知。
(2)PCA算法的过程
①将原始数据中的每一个样本都用向量表示,把所有样本组合起来构成样本矩阵,通常对样本矩阵进行中心化处理,得到中心化样本矩阵。
②求中心化后的样本矩阵的协方差;
③求协方差矩阵的特征值和特征向量;
④将求出的特征值按从大到小的顺序排列,并将其对应的特征向量按照此顺序组合成一个映射矩阵,根据指定的PCA保留的特征个数取出映射矩阵的前n行或者前n列作为最终的映射矩阵;
⑤用映射矩阵对数据进行映射,达到数据降维的目的。
二.数据预处理
import numpy as np
import pandas as pd
import matplotlib.pylab as plt
iris_data = pd.read_csv('iris.csv')
print(iris_data.head())
#切分
x = iris_data.iloc[:,0:4].as_matrix() #提取第0-3列
y = iris_data.iloc[:,4].as_matrix() #提取第4列
三.数据标准化
#标准化
from sklearn.preprocessing import StandardScaler
#计算训练集的平均值和标准差,以便测试数据集使用相同的变换。
#import scale 零均值单位方差 scaler.mean_ scaler.std_
X_std = StandardScaler().fit_transform(x)
四.协方差
X_std = StandardScaler().fit_transform(x)
#协方差
mean_vec = np.mean(X_std, axis = 0) #均值
cov_mat = (X_std - mean_vec).T.dot((X_std - mean_vec))/(X_std.shape[0] - 1)
print('Covariance matrix \n%s'% cov_mat)
print('NumPy Covariance matrix \n%s'% np.cov(X_std.T))#numpy更简单
五.特征值和特征向量
#特征值和特征向量的提取
cov_mat = np.cov(X_std.T)#协方差矩阵
eig_vals,eig_vecs = np.linalg.eig(cov_mat)
print('Eigenvectors \n%s' % eig_vecs) #特征向量
print('\nEigenvalues \n%s' % eig_vals) #特征值 表示特征向量的重要程度
#特征值与特征向量一一对应
eig_pairs = [(np.abs(eig_vals[i]),eig_vecs[:,i]) for i in range(len(eig_vals))]
print(eig_pairs)
#特征值从高到低排序
#eig_pairs.sort(key = lambda x:x[0],reverse = True)
print('Eigenvalues in descending order:')
for i in eig_pairs:
print(i[0])
#特征值归一化
tot = sum(eig_vals)
var_exp = [(i / tot)*100 for i in sorted(eig_vals,reverse = True)]
cum_var_exp = np.cumsum(var_exp)
特征向量是:
特征值:
特征值与特征向量的对应:
六.特征值的可视化
#特征值的可视化
plt.figure(figsize = (6,4))
plt.bar(range(4),var_exp,alpha = 0.5,align = 'center',label = 'individual explained variance')
plt.step(range(4),cum_var_exp,where = 'mid',label = 'cumulative explained variance')
plt.ylabel('Explained variance ratio')
plt.xlabel('Principle components')
plt.legend(loc = 'best')
plt.tight_layout()
plt.show()
结果如下:
七.降维
#取两个特征值最大的对应的两个向量构成映射矩阵
matrix_w = np.hstack((eig_pairs[0][1].reshape(4,1),#hstack按列顺序将数组堆叠,元组形式
eig_pairs[1][1].reshape(4,1)))
#降维
Y = X_std.dot(matrix_w)#取两数的乘积
PCA降维处理后,选取特征值最大的两个特征向量:
PCA降维处理后的两个组成的特征
八.效果对比
#没有做降维处理,随机取两个特征
#没有做降维处理,随机取两个特征
plt.figure(figsize = (6,4))
for lab,col in zip(('Iris-setosa','Iris-versicolor','Iris-virginica'),('blue','red','green')):
plt.scatter(x[y == lab,0],x[y == lab,1],label = lab,c = col)
plt.xlabel('sepal_len')
plt.ylabel('sepal_wid')
plt.legend(loc = 'best')
plt.tight_layout()
plt.show()
结果如下:
#PCA降维处理后的两个组成的特征
#PCA降维处理后的两个组成的特征
plt.figure(figsize = (6,4))
for lab,col in zip(('Iris-setosa','Iris-versicolor','Iris-virginica'),('blue','red','green')):
plt.scatter(Y[y == lab,0],Y[y == lab,1],label = lab,c = col)
plt.xlabel('Principal Component_1')
plt.ylabel('Principal Component_2')
plt.legend(loc = 'lower center')
plt.tight_layout()
plt.show()
结果如下:
完整代码:
import numpy as np
import pandas as pd
import matplotlib.pylab as plt
iris_data = pd.read_csv('iris.csv')
print(iris_data.head())
#切分
x = iris_data.iloc[:,0:4].as_matrix() #提取第0-3列
y = iris_data.iloc[:,4].as_matrix() #提取第4列
#标准化
from sklearn.preprocessing import StandardScaler
#计算训练集的平均值和标准差,以便测试数据集使用相同的变换。
#import scale 零均值单位方差 scaler.mean_ scaler.std_
X_std = StandardScaler().fit_transform(x)
#协方差
mean_vec = np.mean(X_std, axis = 0) #均值
cov_mat = (X_std - mean_vec).T.dot((X_std - mean_vec))/(X_std.shape[0] - 1)
print('Covariance matrix \n%s'% cov_mat)
print('NumPy Covariance matrix \n%s'% np.cov(X_std.T))#numpy更简单
#特征值和特征向量
cov_mat = np.cov(X_std.T)#协方差矩阵
eig_vals,eig_vecs = np.linalg.eig(cov_mat)
print('Eigenvectors \n%s' % eig_vecs) #特征向量
print('\nEigenvalues \n%s' % eig_vals) #特征值 表示特征向量的重要程度
#特征值与特征向量一一对应
eig_pairs = [(np.abs(eig_vals[i]),eig_vecs[:,i]) for i in range(len(eig_vals))]
print(eig_pairs)
#特征值从高到低排序
#eig_pairs.sort(key = lambda x:x[0],reverse = True)
print('Eigenvalues in descending order:')
for i in eig_pairs:
print(i[0])
#特征值归一化
tot = sum(eig_vals)
var_exp = [(i / tot)*100 for i in sorted(eig_vals,reverse = True)]
cum_var_exp = np.cumsum(var_exp)
#特征值的可视化
plt.figure(figsize = (6,4))
plt.bar(range(4),var_exp,alpha = 0.5,align = 'center',label = 'individual explained variance')
plt.step(range(4),cum_var_exp,where = 'mid',label = 'cumulative explained variance')
plt.ylabel('Explained variance ratio')
plt.xlabel('Principle components')
plt.legend(loc = 'best')
plt.tight_layout()
plt.show()
#取两个特征值最大的对应的两个向量构成映射矩阵
matrix_w = np.hstack((eig_pairs[0][1].reshape(4,1),#hstack按列顺序将数组堆叠,元组形式
eig_pairs[1][1].reshape(4,1)))
#降维
Y = X_std.dot(matrix_w)#取两数的乘积
#效果对比
#没有做降维处理,随机取两个特征
plt.figure(figsize = (6,4))
for lab,col in zip(('Iris-setosa','Iris-versicolor','Iris-virginica'),('blue','red','green')):
plt.scatter(x[y == lab,0],x[y == lab,1],label = lab,c = col)
plt.xlabel('sepal_len')
plt.ylabel('sepal_wid')
plt.legend(loc = 'best')
plt.tight_layout()
plt.show()
#PCA降维处理后的两个组成的特征
plt.figure(figsize = (6,4))
for lab,col in zip(('Iris-setosa','Iris-versicolor','Iris-virginica'),('blue','red','green')):
plt.scatter(Y[y == lab,0],Y[y == lab,1],label = lab,c = col)
plt.xlabel('Principal Component_1')
plt.ylabel('Principal Component_2')
plt.legend(loc = 'lower center')
plt.tight_layout()
plt.show()