主成分分析PCA通用代码(输出world报告)

在这里插入图片描述

这段代码的功能是进行主成分分析(PCA),并将分析结果生成一个详细的报告文档。以下是该代码的主要步骤和功能介绍:

  1. 数据读取与预处理

    • 代码首先从Excel文件中读取数据,删除缺失值,并提取所有特征列。
    • 对数据进行标准化处理,使得不同特征的数据具有相同的尺度。
  2. KMO检验与Bartlett’s球形度检验

    • 计算KMO值和Bartlett’s球形度检验值,用于判断数据是否适合进行主成分分析。
  3. 主成分分析(PCA)

    • 使用PCA对标准化后的数据进行降维,提取出各主成分的特征根、方差解释率以及累积方差解释率。
    • 计算因子载荷系数,衡量各变量在主成分中的贡献。
  4. 生成分析报告

    • 在文档中添加KMO检验与Bartlett’s检验结果的描述。
    • 创建并填充总方差解释表格,展示各主成分对方差的解释程度。
    • 插入碎石图,用于确定主成分的数量。
    • 创建因子载荷系数表,并生成相应的热力图,展示各主成分中隐变量的重要性。
    • 最后,创建成分矩阵表,展示原始变量在各主成分上的贡献率。
  5. 保存文档

    • 最终将生成的分析报告保存为Word文档,文件名为“主成分分析报告.docx”。

输入格式:每一行为一个样本,每一列为一个指标数据

import pandas as pd
from sklearn.preprocessing import StandardScaler
from sklearn.decomposition import PCA
from scipy.stats import bartlett
import numpy as np
from docx import Document
from docx.shared import Pt, Inches
from docx.oxml.ns import qn
from docx.oxml import OxmlElement
import matplotlib.pyplot as plt
import seaborn as sns

# 设置中文字体和负号显示
plt.rcParams['font.sans-serif'] = ['SimHei']  # 设置中文字体为黑体
plt.rcParams['axes.unicode_minus'] = False  # 解决负号'-'显示为方块的问题

# 读取Excel数据
data = pd.read_excel('版本2_异常值替换为平均值_附件1.xlsx')  # 替换为您的数据文件
data = data.dropna()  # 清除缺失值
features = data.columns.tolist()

# 数据标准化
scaler = StandardScaler()
data_scaled = scaler.fit_transform(data)

# KMO检验
def calculate_kmo(data):
    data_corr = np.corrcoef(data.T)
    data_inv = np.linalg.inv(data_corr)
    kmo = np.sum(data_corr * data_inv) / (np.sum(data_corr**2) - np.sum(np.diag(data_corr)**2))
    return kmo

# Bartlett's球形度检验
def calculate_bartlett_sphericity(data):
    n, p = data.shape
    correlation_matrix = np.corrcoef(data.T)
    chi2, p_value = bartlett(*[np.array(data[:, i]) for i in range(p)])
    return chi2, p_value

kmo_value = calculate_kmo(data_scaled)
chi_square_value, p_value = calculate_bartlett_sphericity(data_scaled)

# 主成分分析(PCA)
pca = PCA(n_components=min(data_scaled.shape))
pca.fit(data_scaled)
explained_variance = pca.explained_variance_
explained_variance_ratio = pca.explained_variance_ratio_
cumulative_variance = np.cumsum(explained_variance_ratio)

# 因子载荷系数
loadings = pca.components_.T * np.sqrt(explained_variance)

# 碎石图
plt.figure(figsize=(10, 6))
plt.plot(range(1, len(explained_variance) + 1), explained_variance, marker='o')
plt.title('碎石图')
plt.xlabel('主成分数量')
plt.ylabel('特征根')
plt.grid()
plt.savefig('scree_plot.png', bbox_inches='tight')
plt.close()

# 创建Word文档
doc = Document()

# 设置文档的字体为中文
style = doc.styles['Normal']
font = style.font
font.name = '宋体'
font.size = Pt(12)
rFonts = style.element.rPr.rFonts
rFonts.set(qn('w:eastAsia'), '宋体')

# 文档标题
doc.add_heading('主成分分析报告', 0)

# KMO检验和Bartlett's检验结果
doc.add_heading('KMO检验和Bartlett的检验', level=1)
doc.add_paragraph(f"KMO值: {round(kmo_value, 3)}")
doc.add_paragraph(f"Bartlett球形度检验近似卡方: {round(chi_square_value, 3)}")
doc.add_paragraph(f"df: {data_scaled.shape[1] * (data_scaled.shape[1] - 1) / 2}")
doc.add_paragraph(f"P值: {p_value:.3f}")
doc.add_paragraph("注:***、**、*分别代表1%、5%、10%的显著性水平")
doc.add_paragraph("图表说明:上表展示了KMO检验和Bartlett球形检验的结果,用来分析是否可以进行主成分分析。")

# 总方差解释表格
doc.add_heading('总方差解释', level=1)
table = doc.add_table(rows=len(explained_variance) + 1, cols=4)
table.style = 'Table Grid'

# 设置表头字体加粗
hdr_cells = table.rows[0].cells
hdr_cells[0].text = '成分'
hdr_cells[1].text = '特征根'
hdr_cells[2].text = '方差解释率(%)'
hdr_cells[3].text = '累积方差解释率(%)'
for cell in hdr_cells:
    cell.paragraphs[0].runs[0].bold = True

# 填充表格数据
for i in range(len(explained_variance)):
    row_cells = table.rows[i + 1].cells  # 注意这里从第1行开始填充数据,第0行是表头
    row_cells[0].text = str(i + 1)
    row_cells[1].text = f"{explained_variance[i]:.3f}"
    row_cells[2].text = f"{explained_variance_ratio[i] * 100:.3f}"
    row_cells[3].text = f"{cumulative_variance[i] * 100:.3f}"

doc.add_paragraph("图表说明:上表为总方差解释表格,展示了主成分对变量解释的贡献率。")

# 插入碎石图
doc.add_heading('碎石图', level=1)
doc.add_paragraph("图表说明:碎石图用于确认需要选择的主成分个数。")
doc.add_picture('scree_plot.png', width=Inches(6.0))

# 因子载荷系数表
doc.add_heading('因子载荷系数表', level=1)
loadings_df = pd.DataFrame(loadings, columns=[f'主成分{i+1}' for i in range(len(explained_variance))], index=data.columns)
loadings_df = loadings_df.round(3)
table = doc.add_table(rows=loadings_df.shape[0] + 1, cols=loadings_df.shape[1] + 1)
table.style = 'Table Grid'

# 设置表头
hdr_cells = table.rows[0].cells
hdr_cells[0].text = '特征'
for i in range(loadings_df.shape[1]):
    hdr_cells[i + 1].text = f'主成分{i + 1}'
for cell in hdr_cells:
    cell.paragraphs[0].runs[0].bold = True

# 填充表格数据
for i, feature in enumerate(loadings_df.index):
    row_cells = table.rows[i + 1].cells  # 注意这里从第1行开始填充数据,第0行是表头
    row_cells[0].text = feature
    for j in range(loadings_df.shape[1]):
        row_cells[j + 1].text = f"{loadings_df.iloc[i, j]:.3f}"

doc.add_paragraph("图表说明:因子载荷系数表展示了每个主成分中隐变量的重要性。")

# 因子载荷矩阵热力图
plt.figure(figsize=(10, 8))
sns.heatmap(loadings_df, annot=True, cmap='coolwarm', fmt='.3f', linewidths=.5)
plt.title('因子载荷矩阵热力图')
plt.savefig('factor_loading_heatmap.png', bbox_inches='tight')
plt.close()

doc.add_heading('因子载荷矩阵热力图', level=1)
doc.add_paragraph("图表说明:上图展示了因子载荷系数的热力图。")
doc.add_picture('factor_loading_heatmap.png', width=Inches(6.0))

# 成分矩阵表
doc.add_heading('成分矩阵表', level=1)
components_df = pd.DataFrame(pca.components_.T, columns=[f'成分{i+1}' for i in range(len(explained_variance))], index=data.columns)
components_df = components_df.round(3)
table = doc.add_table(rows=components_df.shape[0] + 1, cols=components_df.shape[1] + 1)
table.style = 'Table Grid'

# 设置表头
hdr_cells = table.rows[0].cells
hdr_cells[0].text = '特征'
for i in range(components_df.shape[1]):
    hdr_cells[i + 1].text = f'成分{i + 1}'
for cell in hdr_cells:
    cell.paragraphs[0].runs[0].bold = True

# 填充表格数据
for i, feature in enumerate(components_df.index):
    row_cells = table.rows[i + 1].cells  # 注意这里从第1行开始填充数据,第0行是表头
    row_cells[0].text = feature
    for j in range(components_df.shape[1]):
        row_cells[j + 1].text = f"{components_df.iloc[i, j]:.3f}"

doc.add_paragraph("图表说明:成分矩阵表展示了原始变量在各个主成分上的贡献率。")

# 保存Word文档
doc.save('主成分分析报告.docx')
print("PCA分析报告已保存至 '主成分分析报告.docx'")

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

BenChuat

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值