目录
方法一:自己按照原理编写
1.1 代码
## pca特征降维
# 导入相关模块
import numpy as np
import seaborn as sns
import matplotlib.pyplot as plt
from numpy.linalg import eig
from sklearn.datasets import load_iris
# 导入数据
iris = load_iris() # 150*4的矩阵,4个特征,行是个数,列是特征
X = iris.data
k = 2 #选取贡献最大的前2个特征作为主成分,根据实际情况灵活选取
# Standardize by remove average通过去除平均值进行标准化
X = X - X.mean(axis=0)
# Calculate covariance matrix:计算协方差矩阵:
X_cov = np.cov(X.T, ddof=0)
# Calculate eigenvalues and eigenvectors of covariance matrix
# 计算协方差矩阵的特征值和特征向量
eigenvalues, eigenvectors = eig(X_cov)
# top k large eigenvectors选取前k个特征向量
klarge_index = eigenvalues.argsort()[-k:][::-1]
k_eigenvectors = eigenvectors[klarge_index]
# X和k个特征向量进行点乘
X_pca = np.dot(X, k_eigenvectors.T)
1.2 可视化贡献率
## 绘制贡献率图像
tot=sum(eigenvalues) # 计算特征值的和
var_exp=[(i / tot) for i in sorted(eigenvalues,reverse=True)] # 按照降序排列特征值,并计算贡献率
cum_var_exp=np.cumsum(var_exp) #累计贡献度
plt.bar(range(1,len(var_exp)+1),var_exp,alpha=0.5,align='center',label='individual var') # 绘制柱状图,
plt.step(range(1,len(var_exp)+1),cum_var_exp,where='mid',label='cumulative var') # 绘制阶梯图
plt.ylabel('variance rtion') # 纵坐标
plt.xlabel('principal components') # 横坐标
plt.legend(loc='best') # 图例位置,右下角
plt.show()
参考:https://blog.csdn.net/qq_36108664/article/details/107850006
方法二:调用库
注意:这里的方法必须建立在标准化的基础
上,不然很容易得到的主成分转换系数与原数据相乘不等于拟合值
2.1 导入库
import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
from sklearn.decomposition import PCA #从机器学习包中导入主成分分析函数
from sklearn.preprocessing import StandardScaler
%matplotlib inline
2.2 标准化
#导入数据集
df = pd.read_csv('./iris.csv', names=['sepal length','sepal width','petal length','petal width','target'])
df.head()
#标准化
features = ['sepal length', 'sepal width', 'petal length', 'petal width']
# Separating out the features
x = df.loc[:, features].values
# Separating out the target
y = df.loc[:,['target']].values
# Standardizing the features
x = StandardScaler().fit_transform(x)
# 查看标准化之后的数据
pd.DataFrame(data = x, columns = features).head()
查看标准化的结果
2.3 按照原始维度进行一次PCA,得到贡献率进行筛选维度
pca = PCA(n_components=4)
principalComponents = pca.fit_transform(x) #训练模型,并得到主成分变量
#绘制成图
## 绘制贡献率图像
var_exp=pca.explained_variance_ratio_ #获得贡献率
np.set_printoptions(suppress=True) #当suppress=True,表示小数不需要以科学计数法的形式输出
print('各主成分贡献率:',var_exp)
cum_var_exp=np.cumsum(var_exp) #累计贡献度
print('各主成分累积贡献率:',cum_var_exp)
plt.bar(range(1,len(var_exp)+1),var_exp,alpha=0.5,align='center',label='individual var') # 绘制柱状图,
plt.step(range(1,len(var_exp)+1),cum_var_exp,where='mid',label='cumulative var') # 绘制阶梯图
# 设置刻度值的字体
#ax=plt.subplot(111) #注意:一般都在ax中设置,不在plot中设置,这个是用来设置多个子图的位置,
#labels = ax.get_xticklabels() + ax.get_yticklabels()
#[label.set_fontname('Times New Roman') for label in labels]
font = {'family': 'Times New Roman',
'weight': 'normal'
}
plt.ylabel('variance rtion', font) # 纵坐标
plt.xlabel('principal components', font) # 横坐标
para1=[1,2,3,4,5,6,7,8,9]
plt.xticks(para1,para1)
plt.legend(loc='right', prop = font) # 图例位置,右下角
plt.show()
2.4 使用PCA进行降维到2维, 并查看降维后的结果
# 进行降维
pca = PCA(n_components=2)
principalComponents = pca.fit_transform(x)
# 查看降维后的数据
principalDf = pd.DataFrame(data=principalComponents, columns=['principal component 1', 'principal component 2'])
finalDf = pd.concat([principalDf, df[['target']]], axis = 1)
finalDf.head(5)
2.5 检验使用x和转换系数相乘后是否是降维后的拟合数据值
这一步就是之前说的为什么必须进行数据标准化的原因,因为不进行标准化,小编尝试这里的结果是检验不通过的!
(np.dot(x[0],pca.components_[0]), np.dot(x[0],pca.components_[1]))
输出(-2.2645417283949003, 0.5057039027737843)
由于之前已经进行过标准化,所以这里是检验通过的。
2.6 转换系数的可视化
# 对系数进行可视化
import seaborn as sns
df_cm = pd.DataFrame(np.abs(pca.components_), columns=df.columns[:-1])
plt.figure(figsize = (12,6))
ax = sns.heatmap(df_cm, annot=True, cmap="BuPu")
# 设置y轴的字体的大小
ax.yaxis.set_tick_params(labelsize=15)
ax.xaxis.set_tick_params(labelsize=15)
plt.title('PCA', fontsize='xx-large')
# Set y-axis label
plt.savefig('factorAnalysis.png', dpi=200)
这样就能从图中看出新的变量与原始变量之间的相关性。
2.7 数据降维可视化
fig = plt.figure(figsize = (8,8))
ax = fig.add_subplot(1,1,1)
ax.set_xlabel('Principal Component 1', fontsize = 15)
ax.set_ylabel('Principal Component 2', fontsize = 15)
ax.set_title('2 Component PCA', fontsize = 20)
targets = ['Iris-setosa', 'Iris-versicolor', 'Iris-virginica']
colors = ['r', 'g', 'b']
for target, color in zip(targets,colors):
indicesToKeep = finalDf['target'] == target
# 选择某个label下的数据进行绘制
ax.scatter(finalDf.loc[indicesToKeep, 'principal component 1']
, finalDf.loc[indicesToKeep, 'principal component 2']
, c = color
, s = 50)
ax.legend(targets)
ax.grid()
与因子分析(FA)比较
主成分分析是构造原始变量的组合为新变量;因子分析是原始变量的拆解为若干因子
使用FA的系数矩阵如下所示, 可以看到每一个系数大小差都会变得更加大, 大的变得更大, 小的变得更小, 这样使得新的变量被解释起来会更加容易。
参考:https://mathpretty.com/10998.html#%E4%BD%BF%E7%94%A8PCA%E9%99%8D%E7%BB%B4