我将为您详细介绍如何使用Statsmodels进行主成分分析(PCA)。

Statsmodels PCA 基础用法
安装和导入库
# 安装所需库 # pip install statsmodels pandas numpy matplotlib import pandas as pd import numpy as np import matplotlib.pyplot as plt from statsmodels.multivariate.pca import PCA import seaborn as sns # 设置中文字体 plt.rcParams['font.sans-serif'] = ['SimHei'] plt.rcParams['axes.unicode_minus'] = False
创建示例数据
# 创建示例数据集
np.random.seed(42)
n_samples = 100
# 生成具有相关性的数据
X1 = np.random.normal(0, 1, n_samples)
X2 = X1 * 0.7 + np.random.normal(0, 0.5, n_samples)
X3 = X1 * 0.5 + X2 * 0.3 + np.random.normal(0, 0.3, n_samples)
X4 = np.random.normal(0, 2, n_samples)
X5 = X4 * 0.6 + np.random.normal(0, 0.4, n_samples)
# 创建DataFrame
data = pd.DataFrame({
'变量1': X1,
'变量2': X2,
'变量3': X3,
'变量4': X4,
'变量5': X5
})
print("数据集前5行:")
print(data.head())
print("\n数据集形状:", data.shape)
执行PCA分析
# 方法1:标准化数据后进行PCA
pca_standardized = PCA(data, standardize=True, ncomp=5)
# 方法2:不标准化数据(适用于相同量纲的数据)
# pca_raw = PCA(data, standardize=False, ncomp=5)
print("=== PCA 分析结果 ===")
print(f"解释方差比例:\n{pca_standardized.rsquare}")
print(f"\n累计解释方差比例:\n{np.cumsum(pca_standardized.rsquare)}")
主成分载荷和得分
# 载荷矩阵(主成分与原始变量的关系)
loadings = pca_standardized.loadings
print("主成分载荷矩阵:")
print(pd.DataFrame(
loadings,
index=data.columns,
columns=[f'PC{i+1}' for i in range(loadings.shape[1])]
).round(3))
# 主成分得分
scores = pca_standardized.scores
print("\n前5个样本的主成分得分:")
print(pd.DataFrame(
scores[:5, :],
columns=[f'PC{i+1}' for i in range(scores.shape[1])]
).round(3))
可视化分析结果
# 设置图形样式
fig, axes = plt.subplots(2, 2, figsize=(12, 10))
# 图1:碎石图(解释方差)
explained_var = pca_standardized.rsquare
axes[0, 0].bar(range(1, len(explained_var)+1), explained_var, alpha=0.7)
axes[0, 0].plot(range(1, len(explained_var)+1), explained_var, 'ro-', linewidth=2)
axes[0, 0].set_xlabel('主成分')
axes[0, 0].set_ylabel('解释方差比例')
axes[0, 0].set_title('碎石图 - 各主成分解释方差')
axes[0, 0].grid(True, alpha=0.3)
# 图2:累计解释方差
cum_var = np.cumsum(explained_var)
axes[0, 1].plot(range(1, len(cum_var)+1), cum_var, 'bo-', linewidth=2)
axes[0, 1].axhline(y=0.8, color='r', linestyle='--', alpha=0.7, label='80% 阈值')
axes[0, 1].axhline(y=0.9, color='g', linestyle='--', alpha=0.7, label='90% 阈值')
axes[0, 1].set_xlabel('主成分数量')
axes[0, 1].set_ylabel('累计解释方差比例')
axes[0, 1].set_title('累计解释方差图')
axes[0, 1].legend()
axes[0, 1].grid(True, alpha=0.3)
# 图3:载荷图
loadings_df = pd.DataFrame(loadings[:, :2],
index=data.columns,
columns=['PC1', 'PC2'])
axes[1, 0].scatter(loadings_df['PC1'], loadings_df['PC2'], alpha=0.7)
for i, label in enumerate(loadings_df.index):
axes[1, 0].annotate(label,
(loadings_df['PC1'].iloc[i], loadings_df['PC2'].iloc[i]),
fontsize=9)
axes[1, 0].axhline(y=0, color='gray', linestyle='-', alpha=0.3)
axes[1, 0].axvline(x=0, color='gray', linestyle='-', alpha=0.3)
axes[1, 0].set_xlabel('第一主成分 (PC1)')
axes[1, 0].set_ylabel('第二主成分 (PC2)')
axes[1, 0].set_title('载荷图 - 变量在主成分上的投影')
axes[1, 0].grid(True, alpha=0.3)
# 图4:得分图
axes[1, 1].scatter(scores[:, 0], scores[:, 1], alpha=0.6)
axes[1, 1].set_xlabel('第一主成分得分')
axes[1, 1].set_ylabel('第二主成分得分')
axes[1, 1].set_title('得分图 - 样本在PC1和PC2上的投影')
axes[1, 1].axhline(y=0, color='gray', linestyle='-', alpha=0.3)
axes[1, 1].axvline(x=0, color='gray', linestyle='-', alpha=0.3)
axes[1, 1].grid(True, alpha=0.3)
plt.tight_layout()
plt.show()
实际案例:鸢尾花数据集
from sklearn.datasets import load_iris
# 加载鸢尾花数据集
iris = load_iris()
iris_data = pd.DataFrame(iris.data, columns=iris.feature_names)
iris_target = iris.target
print("鸢尾花数据集示例:")
print(iris_data.head())
# 执行PCA
pca_iris = PCA(iris_data, standardize=True, ncomp=4)
# 可视化结果
fig, axes = plt.subplots(1, 2, figsize=(12, 5))
# 碎石图
explained_var_iris = pca_iris.rsquare
axes[0].bar(range(1, len(explained_var_iris)+1), explained_var_iris, alpha=0.7)
axes[0].plot(range(1, len(explained_var_iris)+1), explained_var_iris, 'ro-')
axes[0].set_xlabel('主成分')
axes[0].set_ylabel('解释方差比例')
axes[0].set_title('鸢尾花数据集 - PCA碎石图')
axes[0].grid(True, alpha=0.3)
# 得分图(按类别着色)
scores_iris = pca_iris.scores
scatter = axes[1].scatter(scores_iris[:, 0], scores_iris[:, 1],
c=iris_target, cmap='viridis', alpha=0.7)
axes[1].set_xlabel('第一主成分')
axes[1].set_ylabel('第二主成分')
axes[1].set_title('鸢尾花数据集 - PCA得分图')
plt.colorbar(scatter, ax=axes[1])
plt.tight_layout()
plt.show()
# 显示载荷矩阵
print("\n鸢尾花数据集的载荷矩阵:")
loadings_iris = pca_iris.loadings
loadings_iris_df = pd.DataFrame(
loadings_iris[:, :3],
index=iris.feature_names,
columns=[f'PC{i+1}' for i in range(3)]
)
print(loadings_iris_df.round(3))
选择主成分数量的方法
def select_components(pca_obj, threshold=0.8):
"""
根据累计解释方差比例选择主成分数量
"""
cum_var = np.cumsum(pca_obj.rsquare)
n_components = np.argmax(cum_var >= threshold) + 1
return n_components, cum_var
# 选择主成分
n_comp, cum_var = select_components(pca_standardized)
print(f"解释80%方差需要的主成分数量: {n_comp}")
print(f"各主成分累计解释方差:\n{cum_var}")
# 使用选定的主成分数重新运行PCA
pca_optimized = PCA(data, standardize=True, ncomp=n_comp)
print(f"\n优化后的主成分数量: {pca_optimized.ncomp}")
print(f"解释方差比例: {pca_optimized.rsquare}")
完整函数封装
def complete_pca_analysis(data, standardize=True, threshold=0.8):
"""
完整的PCA分析函数
参数:
data: DataFrame, 输入数据
standardize: bool, 是否标准化
threshold: float, 解释方差阈值
返回:
PCA对象和主要结果
"""
# 执行PCA
pca = PCA(data, standardize=standardize)
# 选择主成分数量
cum_var = np.cumsum(pca.rsquare)
n_optimal = np.argmax(cum_var >= threshold) + 1
# 使用优化后的主成分数重新运行
pca_optimal = PCA(data, standardize=standardize, ncomp=n_optimal)
results = {
'pca_object': pca_optimal,
'optimal_components': n_optimal,
'explained_variance': pca_optimal.rsquare,
'cumulative_variance': cum_var,
'loadings': pca_optimal.loadings,
'scores': pca_optimal.scores,
'sdev': pca_optimal.sdev
}
return results
# 使用示例
results = complete_pca_analysis(data)
print(f"最优主成分数量: {results['optimal_components']}")
print(f"解释方差: {results['explained_variance'].round(4)}")
- 数据标准化:使用
standardize=True处理不同量纲的变量 - 主成分选择:通常选择累计解释方差达到80%-90%的主成分数量
- 解释结果:
- 载荷矩阵显示变量与主成分的关系
- 得分矩阵显示样本在主成分上的投影
- 可视化:碎石图、载荷图、得分图是常用的诊断工具
Statsmodels的PCA实现提供了详细的统计信息,适合需要深入分析的应用场景。
版权声明:NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播