高中成绩主成分分析

高中成绩主成分分析

“”"
1.导入模块
2.导入数据
3.建立变量的相关系数矩阵ρ
4.求ρ的特征值λ1>λ2>…>λp>0,和特征向量e1,e2,…,ep
5.写出前m个主成分Y1,Y2,…,Ym的表达式
6.计算样本各主成分的得分
7.计算总主成分Y=(λ1Y1+λ2Y2+…+λ1Ym)/(λ1+λ2+…+λm)的综合得分
“”"

1.导入模块

import pandas as pd # 数据分析的模块
import numpy as np # 数据分析的模块
import matplotlib.pyplot as plt # 画图的模块
import seaborn as sns # 画图的模块
from factor_analyzer.factor_analyzer import calculate_bartlett_sphericity # Bartlett’s球状检验
from factor_analyzer.factor_analyzer import calculate_kmo # KMO检验
plt.style.use(‘seaborn-whitegrid’) # 画图的风格
plt.rc(‘font’, **{‘family’: ‘Microsoft YaHei, SimHei’}) # 显示中文字体的模块

2.导入数据

df = pd.read_excel(r’D:\codes\金融大数据挖掘与分析\实验十二 主成分分析\学生成绩表.xls’, usecols=range(1, 10)) # 导入数据,去掉第1列的索引,样本数据
n, p = df.shape # n样本的个数,p属性的个数
df.describe().to_csv(r’D:\codes\金融大数据挖掘与分析\实验十二 主成分分析\describe_data.csv’, encoding=‘gb18030’, index=False) # 查看描述统计信息(最大、最小、平均、中位、四分位、标准差)并保存为csv文件

数据检验

Bartlett’s球状检验

检验总体变量的相关矩阵是否是单位阵(相关系数矩阵对角线的所有元素均为1,所有非对角线上的元素均为零);即检验各个变量是否各自独立。

如果该值较⼤,且其对应的相伴概率值⼩于指定的显著⽔平时,拒绝零假设,表明相关系数矩阵不是单位阵,原有变量之间存在相关性,适合进⾏主成分分析;反之,如果该值较小,原有变量之间不存在相关性,数据不适合进⾏主成分分析。

chi_square_value, p_value = calculate_bartlett_sphericity(df)
print(“Bartlett’s球状检验参数:\n”, chi_square_value, p_value)

KMO检验

检查变量间的相关性和偏相关性,取值在0-1之间;KMO统计量越接近1,变量间的相关性越强,偏相关性越弱,主成分分析的效果越好。

通常取值超0.6开始进行主成分分析

kmo_all, kmo_model = calculate_kmo(df)
print(“KMO检验参数:\n”, kmo_model)

3.建立变量的相关系数矩阵ρ

ρ = df.corr(method=‘pearson’) # 样本相关系数矩阵

print(pd.DataFrame(round(ρ, 2).values)) # 打印保留4位小数的相关系数矩阵

ρ1 = pd.DataFrame(round(ρ, 4).values)
ρ1.to_csv(r’D:\codes\金融大数据挖掘与分析\实验十二 主成分分析\相关系数矩阵.csv’, encoding=‘gb18030’, index=False)

相关系数热力图

sns.heatmap(ρ, annot=True) # annot=True: 显示相关系数矩阵的具体数值

发现变量间相关性都比较高,大于0.7,有做PCA的必要

4.求相关系数矩阵ρ的特征值λ1>λ2>…>λp>0,和特征向量e1,e2,…,ep

λ, e = np.linalg.eig(ρ) # 求特征值λ与特征向量e,特征值默认从大到小排序
e = pd.DataFrame(e) # 特征向量以dataframe显示

特征值的散点图和折线图

plt.scatter(range(1, df.shape[1] + 1), λ)
plt.plot(range(1, df.shape[1] + 1), λ)
plt.title(“Scree Plot”)
plt.xlabel(“Factors”)
plt.ylabel(“Eigenvalue”)
plt.grid() # 显示网格

主成分的贡献率

contr = [] # 主成分的贡献率列表
for i in range(len(λ)):
contri = λ[i] / np.sum(λ) # 贡献率的计算
contr.append(contri) # 添加主成分的贡献率到列表中
contr = pd.DataFrame(contr) # 把列表转换成dataframe

累计贡献率的折线图

plt.plot(np.cumsum(contr), linewidth=3) # 累计贡献率的折线图
plt.xlabel(“主成分的数量”) # X轴标签
plt.ylabel(“累\n积\n贡\n献\n率”, rotation=0, labelpad=20) # Y轴标签
plt.axhline(y=0.8, c=‘r’, ls=‘–’, lw=2) # 保留主成分的临界值
tick_label = [‘第1主成分’, ‘第2主成分’, ‘第3主成分’, ‘第4主成分’, ‘第5主成分’, ‘第6主成分’, ‘第7主成分’]
plt.grid(True) # 画网格线
plt.show()

5.写出前m个主成分Y1,Y2,…,Ym

s = 0 # 累计贡献率
m = 0 # 保留主成分的个数
cr = [] # 贡献率列表
for i in range(len(λ)):
m += 1 # 保留主成分的个数
contri = λ[i] / np.sum(λ) # 第i主成分贡献率
cr.append(contri) # 追加贡献率
s += contri # 累计贡献率值的计算
if s >= 0.8: # 累计贡献率达80%即停止
break
li = pd.DataFrame(λ)[0:m].values # 保留的特征值
cr = pd.DataFrame(cr) # 贡献率,返回的是dataframe
cr[‘cr_sum’] = cr.cumsum() # 添加累计贡献率列
cr[‘特征值’] = li # 添加特征值列

写出主成分的表达式

e = pd.DataFrame(e)
e = e.iloc[:, :m] # 保留的特征值对应的特征向量,返回的是DataFrame
round(e, 4) # 保留4位小数的特征向量
for i in range(m):
print(‘y’ + str(i+1) + ‘=’ + str(round(e.iloc[0, i], 4)) + ‘*X1+’ + str(round(e.iloc[1, i], 4)) + ‘*X2+’ + str(round(e.iloc[2, i], 4)) + ‘*X3+’ + str(round(e.iloc[3, i], 4)) + ‘*X4+’ + str(round(e.iloc[4, i], 4)) + ‘*X5+’ + str(round(e.iloc[5, i], 4)) + ‘*X6+’ + str(round(e.iloc[6, i], 4)) + ‘*X7+’ + str(round(e.iloc[5, i], 4)) + ‘*X8+’ + str(round(e.iloc[6, i], 4)) + ‘*X9’) # 写出主成分的表达式

6.计算样本各主成分的得分

score = pd.DataFrame(np.dot(df, e)) # df乘以e 得到100X3的矩阵,100个学生的3个主成分得分
score = score.rename(columns={0: ‘第1主成分得分’, 1: ‘第2主成分得分’, 2: ‘第3主成分得分’})

7.计算总主成分Y=(λ1Y1+λ2Y2+…+λ1Ym)/(λ1+λ2+…+λm)的综合得分

cr = pd.DataFrame(cr) # 贡献率、累计贡献率、特征值
score_T = np.dot(score, cr.iloc[:, 0]) # 总主成分得分
score_T = pd.DataFrame(score_T)
df1 = pd.read_excel(r’D:\codes\金融大数据挖掘与分析\实验十二 主成分分析\学生成绩表.xls’, usecols=range(0, 1)) # 获得样本的名单
df1 = df1.join(score_T) # 各个样本的总主成分得分
df1 = df1.sort_values(by=0, ascending=False) # 对各个样本总主成分得分降序排列
df1 = df1.rename(columns={0: ‘综合得分’})

print(‘原始数据的前5行:’, df.head())
print(‘相关系数矩阵:’, ρ1)
print(‘特征值:\n’, round(pd.DataFrame(λ), 4))
print(‘特征向量:\n’, round(e, 4))
print(‘保留的主成分个数:’, m)
print(‘保留主成分的贡献率、累计贡献率、特征值:\n’, round(cr, 4))
print(‘各主成分得分:\n’, round(score, 4))
print(‘主成分综合得分:\n’, round(df1, 4))

附录:学生成绩表
100个学生语文、数学、英语、政治、地理、历史、物理、化学、生物的成绩

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值