前期已经学了如何建立变量之间的相关关系及如何分类,接下来要分析如果变量太多,或可以通过降维再进行分析,就要用到降维技术:主成分分析。
案例比较少,我们拿鸢尾花和拉面
的经典案例来做分析。
主成分分析:将多个变量融合成一个变量,使得变量的个数大大降低,并且能够将有相关关系的几个指标合并为1个,消除变量之间的多重共线性。
举例如下,x1,x2,x3这三个自变量中,只有x1的变化能解释y1的变化:
主成分分析主要分析有方差的,即有变动的,没有方差的无法解释因变量。
案例一:分析的样本为鸢尾花,已知鸢尾花数据是4维的,共三类样本,使用PCA实现对鸢尾花数据进行降维,实现在二维平面上的可视化。
import matplotlib.pyplot as plt
import sklearn.decomposition as dp
from sklearn.datasets.base import load_iris
x,y=load_iris(return_X_y=True) #加载数据,x表示数据集中的属性数据,y表示数据标签
pca=dp.PCA(n_components=2) #加载pca算法,设置降维后主成分数目为2
reduced_x=pca.fit_transform(x) #对原始数据进行降维,保存在reduced_x中
red_x,red_y=[],[]
blue_x,blue_y=[],[]
green_x,green_y=[],[]
for i in range(len(reduced_x)): #按鸢尾花的类别将降维后的数据点保存在不同的表表中
if y[i]==0:
red_x.append(reduced_x[i][0])
red_y.append(reduced_x[i][1])
elif y[i]==1:
blue_x.append(reduced_x[i][0])
blue_y.append(reduced_x[i][1])
else:
green_x.append(reduced_x[i][0])
green_y.append(reduced_x[i][1])
plt.scatter(red_x,red_y,c='r',marker='x')
plt.scatter(blue_x,blue_y,c='b',marker='D')
plt.scatter(green_x,green_y,c='g',marker='.')
plt.show()
案例二:拉面案例来自CSDN这个博主的文章
(#版权声明:本文为CSDN博主「波纹疾走」的原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接及本声明。 #原文链接:https://blog.csdn.net/weixin_40173577/article/details/85814614)
1、先导入所需要的数据和安装包
import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
#中文文字显示问题
from pylab import mpl
# 指定默认字体
mpl.rcParams['font.sans-serif'] = ['FangSong']
# 解决保存图像是负号'-'显示为方块的问题
mpl.rcParams['axes.unicode_minus'] = False
from sklearn.decomposition import PCA
df_org = pd.read_excel("拉面.xlsx", sheet_name="拉面")
2、数据中心化
df_std = (df_org - df_org.mean())/df_org.std()
#数据中心化
3、求相关系数
df_corr = df_std.corr()
df_corr
#求相关系数
4、求协方差的特征值和特征向量
eig_value,eig_vector=np.linalg.eig(df_corr)
#特征值
#特征值排序
eig=pd.DataFrame({"eig_value":eig_value})
eig=eig.sort_values(by=["eig_value"], ascending=False)
#获取累积贡献度
eig["eig_cum"] = (eig["eig_value"]/eig["eig_value"].sum()).cumsum()
#合并入特征向量
eig=eig.merge(pd.DataFrame(eig_vector).T, left_index=True, right_index=True)
eig
5、提取主成分,假设要求累积贡献度要达到70%,则取2个主成分
#提取主成分
#假设要求累积贡献度要达到70%,则取2个主成分
#成分得分系数矩阵(因子载荷矩阵法)
loading = eig.iloc[:2,2:].T
loading["vars"]=df_std.columns
loading
6、将样本投影到选取的特征向量上
plt.plot(loading[0],loading[1], "o")
xmin ,xmax = loading[0].min(), loading[0].max()
ymin, ymax = loading[1].min(), loading[1].max()
dx = (xmax - xmin) * 0.2
dy = (ymax - ymin) * 0.2
plt.xlim(xmin - dx, xmax + dx)
plt.ylim(ymin - dy, ymax + dy)
plt.xlabel('第1主成分')
plt.ylabel('第2主成分')
for x, y,z in zip(loading[0], loading[1], loading["vars"]):
plt.text(x, y+0.1, z, ha='center', va='bottom', fontsize=13)
plt.grid(True)
plt.show()
#影响力与正负数无关,只看绝对值。
#可以看到 变量中【汤】对第1主成分影响较大;【配料】对第2主成分影响略大于【面】。
plt.plot(score[0],score[1], "o")
xmin ,xmax = score[0].min(), score[0].max()
ymin, ymax = score[1].min(), score[1].max()
dx = (xmax - xmin) * 0.2
dy = (ymax - ymin) * 0.2
plt.xlim(xmin - dx, xmax + dx)
plt.ylim(ymin - dy, ymax + dy)
plt.xlabel('第1主成分')
plt.ylabel('第2主成分')
for x, y,z in zip(score[0], score[1], score.index):
plt.text(x, y+0.1, z, ha='center', va='bottom', fontsize=13)
plt.grid(True)
plt.show()
结论:由于第1主成分的所有系数都是负值,所以其得分负向越大,该数据对应的第1主成分得分越高。 #可以看到4号数据第1主成分得分最高,说明它的【汤】最受欢迎;同理,1号数据第2主成分得分最高,其【配料】评价最高。