1.数学原理
1.1.【参考博客】
https://www.cnblogs.com/xinyuyang/p/11178676.html
1.2.【精简描述】
PCA实际上是将含有冗余特征的高维空间数据集投影到地位空间中,在保证信息量的同时,对数据集冗余特征进行筛选。而投影的关键就在于确定高维空间向低维空间转换的基向量。而基向量选取的原则则是尽可能的保持投影后的数据的信息量,也就是高维数据投影到低维空间中某个基向量之上以后,数据越分散越好(常用方差衡量数据的分散程度,即相同特征之间方差越大越好)。同时,也应当保证所有基向量之间的耦合程度越小越好(基向量之间是正交的),而不同基向量上投影的线性相关性度量标准则为协方差。(不同特征间的协方差越小越好)
2.PCA流程
【原始矩阵】
A_{m,n}: m表示对象个数,n表示特征个数step 1. 数据预处理:每一个特征列减去其列均值,使得特征列中所有元素之和为0step 2. 求协方差矩阵
B_{n,n} = (A^T·A):1)协方差矩阵对角线元素为特征方差(方差尽可能大); 2)非对角线元素为特征之间的协方差(协方差尽可能小)step 3. 对协方差矩阵进行特征分解:特征值降序,选择前N大特征值对应特征向量组成特征向量组
P_{n,N}step 4. 将原始数据投影到选取的特征向量上:
D_{m,N} = A_{m,n}×P_{n,N}
3.PCA的python实现
3.1.python中PCA接口
from sklearn import decomposition
from sklearn import datasets
import matplotlib.pyplot as plt
def load_data():
"""加载数据"""
digits = datasets.load_digits()
return digits.data, digits.target
# 实例化PCA对象并训练
# 1.PCA()参数说明:
# -n_components: 降维后的主成分数量
# -copy: 表示是否在运算法时,将原始训练数据复制一份
# -whiten: 判断是否白化,即对降维后的每个特征进行归一化
# -random_state: 随机数种子
# 2.PCA()实例对象属性+方法:
# -components_: 返回具有最大方差的成分
# -explained_variance_: 降维后的各主成分的方差值
# -explained_variance_ratio_:返降维后的各主成分的方差值占总方差值的比例,这个比例越大,则越是重要的主成分
# -n_components_:返回所保留的成分个数n
# 2.PCA()对象方法:
# -fit(x):模型训练
# -fit_transform(x): 用X来训练PCA模型,同时返回降维后的数据。
# -inverse_transform(): 将降维后的数据转换成原始数据
# -transform(x): 将数据X转换成降维后的数据。当模型训练好后,对于新输入的数据,都可以用transform方法来降维
def construct_my_pca(x, n_components, random_state=1):
"""构造pca模型"""
pca = decomposition.PCA(n_components=n_components, random_state=random_state)
# pca.fit(x)
# pca.transform(x)
return pca.fit_transform(x)
def draw_figure(x_pca, y):
"""绘图"""
plt.figure(figsize=(10, 10), dpi=100)
plt.scatter(x_pca[:, 0], x_pca[:, 1], c=y)
plt.xlabel("component-1", fontsize=11)
plt.ylabel("component-2", fontsize=11)
plt.show()
def main():
data, label = load_data()
data_pca = construct_my_pca(data, 2, 1)
draw_figure(data_pca, label)
if __name__ == "__main__":
main()
3.2.python结构化实现PCA
from sklearn import decomposition
from sklearn import datasets
import matplotlib.pyplot as plt
import numpy as np
def load_data():
"""加载数据"""
digits = datasets.load_digits()
return digits.data, digits.target
def construct_my_pca(rawData, n_components, random_state=1):
"""构造pca模型"""
try:
# 1.数据预处理
meanVal = np.mean(rawData, axis=0)
x = rawData - meanVal
# 2.计算协方差矩阵[一行代表一个样本]
cov = np.cov(x, rowvar=False)
# 3.计算协方差矩阵的特征值与特征向量
eigVals, eigVects = np.linalg.eig(cov)
eigValIndice = np.argsort(eigVals)
n_eigValIndice = eigValIndice[-1:-(n_components+1):-1]
n_eigVects = eigVects[:, n_eigValIndice]
# 4.生成低维空间数据
res = np.dot(x, n_eigVects)
return res
except Exception as e:
return "this is error!"
def draw_figure(x_pca, y):
"""绘图"""
plt.figure(figsize=(10, 10), dpi=100)
plt.scatter(x_pca[:, 0], x_pca[:, 1], c=y)
plt.xlabel("component-1", fontsize=11)
plt.ylabel("component-2", fontsize=11)
plt.show()
def main():
data, label = load_data()
data_pca = construct_my_pca(data, 2, 1)
draw_figure(data_pca, label)
if __name__ == "__main__":
main()