1. 减去每个变量的平均数
从数据集中减去每个变量的平均数,使数据集以原点为中心。事实证明,在计算协方差矩阵时,这样做是非常有帮助的。
#Importing required libraries
import numpy as np
#Generate a dummy dataset.
X = np.random.randint(10,50,100).reshape(20,5)
# mean Centering the data
X_meaned = X - np.mean(X , axis = 0)
2. 计算协方差矩阵
计算以平均值为中心的数据的协方差矩阵。协方差矩阵是一个方形矩阵,表示各元素之间的协方差。一个元素与自身的协方差只不过是它的方差而已。
# calculating the covariance matrix of the mean-centered data.
cov_mat = np.cov(X_meaned , rowvar = False)
3. 计算特征值和特征向量
现在,计算出协方差矩阵的特征值和特征向量。我们得到的协方差矩阵的特征向量是相互正交的,每个向量代表一个主轴。正交意味着矢量是相互垂直的。一个较高的特征值对应于较高的重要性。因此,具有较高特征值的主轴将是捕捉数据中较高重要性的一个轴。
#Calculating Eigenvalues and Eigenvectors of the covariance matrix
eigen_values , eigen_vectors = np.linalg.eigh(cov_mat)
4. 按降序对特征值进行排序
按照降序排列特征值及其对应的特征向量。
请记住,特征向量矩阵中的每一列都对应着一个主成分,因此,按其特征值的降序排列,将自动按其变化率的降序排列主成分。
因此,在我们重新排列的特征向量矩阵中,第一列将是一个捕捉到最高重要性的主成分。
#sort the eigenvalues in descending order
sorted_index = np.argsort(eigen_values)[::-1]
sorted_eigenvalue = eigen_values[sorted_index]
#similarly sort the eigenvectors
sorted_eigenvectors = eigen_vectors[:,sorted_index]
5. 从重排的特征值矩阵中选择一个子集
根据我们的需要,从重新排列的特征值矩阵中选择一个子集,即number_comp = 2,意味着我们选择了前两个主成分。
# select the first n eigenvectors, n is desired dimension
# of our final reduced data.
n_components = 2 #you can select any number of components.
eigenvector_subset = sorted_eigenvectors[:,0:n_components]
6. 转化数据
最后,通过在特征向量子集的转置和平均中心数据的转置之间进行点积来转换数据。通过转置点积的结果,我们得到的结果是数据从高维降低到低维。
#Transform the data
X_reduced = np.dot(eigenvector_subset.transpose(),X_meaned.transpose()).transpose()
Python中主成分分析的完整代码
现在,让我们通过制作一个函数来组合上面的一切。
import numpy as np
def PCA(X , num_components):
#Step-1
X_meaned = X - np.mean(X , axis = 0)
#Step-2
cov_mat = np.cov(X_meaned , rowvar = False)
#Step-3
eigen_values , eigen_vectors = np.linalg.eigh(cov_mat)
#Step-4
sorted_index = np.argsort(eigen_values)[::-1]
sorted_eigenvalue = eigen_values[sorted_index]
sorted_eigenvectors = eigen_vectors[:,sorted_index]
#Step-5
eigenvector_subset = sorted_eigenvectors[:,0:num_components]
#Step-6
X_reduced = np.dot(eigenvector_subset.transpose() , X_meaned.transpose() ).transpose()
return X_reduced