Python之因子分析详细步骤

1.数学原理

1.1数学模型

1.2正交因子模型假设

注意:下面的推导都是基于这一假设。因此,这里的模型都是属于正交因子模型

1.3正交因子模型的协方差结构

1.4各类方差贡献的介绍

       在1.3正交因子模型的协方差结构中,我们介绍了“方差贡献”,下面给出关于“方差贡献”更详细的介绍。

1.5因子表示具有不唯一性

        利用此性质,我们可以选择不同的正交矩阵T_{m\times m},做以下操作: 

 从而获得容易解释的载荷矩阵和因子。

        这一操作被称为“因子旋转”。

因子旋转的类型

       因子载荷的正交变换和伴随的因子正交变换为因子正交旋转

       进一步地, 可以修改正交因子模型, 允许共同因子之间相关, 称这样的变换为因子斜交旋转(bolique rotation)。 如果中的矩阵不是正交阵, 则中的各个公共因子可能相关,但公共因子的方差仍要求等于1。

因子分析中常用的正交旋转和斜交旋转方法:

  • varimax旋转:正交旋转方法, 要求每个因子仅有少数绝对值较大的载荷, 多数载荷接近0。 通过迭代最小化载荷系数的一个二次函数实现。 结果使得每个因子仅与少数原始变量有强相关, 而与其余原始变量近似不相关。
  • quartimax旋转:正交旋转方法, 要求每个原始变量仅与一个公共因子强相关, 而与其余公共因子近似不相关。 不如varimax接受程度高。
  • oblimin旋转:斜交旋转方法, 追求载荷阵中0尽可能多, 设置公共因子之间的相关系数在较小值。
  • promax旋转:斜交旋转方法, 追求载荷阵中0尽可能多, 方法是取正交旋转得到的载荷阵元素的幂次。 要求幂次尽可能低, 公共因子间的相关性尽可能低。

1.6计算因子得分

        在1.1数学模型中,我们建立了如下模型:

因子分析中, 首先要得到因子载荷阵, 对因子进行解释。

其次,可以从数据中估计公共因子的取值(注意公共因子在模型中是不可观测的,或者说是未知的)。 公共因子的取值的估计称为因子得分。 

注意:在模型中,m<p,因此无法得到公共因子的精确值(即:因子得分),只能估计。

      常使用加权最小二乘法估计因子得分。

加权最小二乘法估计因子得分

        得到因子得分后,就可以利用因子得分进行其他分析。

2.Python代码实现

关键的库:factor_analyzer、scipy

下面用这个例子来说明Python中实现因子分析的步骤 

 

2.0导入库和数据

import numpy as np
from numpy.linalg import inv
import pandas as pd
from scipy.stats import zscore
from  factor_analyzer import FactorAnalyzer as FA
from factor_analyzer.factor_analyzer import calculate_bartlett_sphericity  # 用于Bartlett's球状检验
from factor_analyzer.factor_analyzer import calculate_kmo  # 用于KMO检验# 导入数据
data=np.loadtxt("data12_5_1.txt")
print(data)

2.1数据标准化

zscore()

# 数据标准化
data_norm=zscore(data,ddof=1)

对应的数学公式:

2.2Bartlett's球状检验和KMO检验

  1. Bartlett's球状检验:计算巴特利特P值
           若P值<0.05,则说明变量间有相关性,则可因子分析
  2. KMO检验:计算KMO值
           KMO值介于0~1之间,越接近1,说明变量间相关性越强,偏相关性越弱,因子分析的效果越好。
           若KMO值>0.6,说明变量间有相关性,则可因子分析。
# Bartlett's球状检验:计算巴特利特P值
chi_square_value,p_value=calculate_bartlett_sphericity(data_norm)
print("Bartlett's球状检验:\n","卡方值:",chi_square_value,"\nP值(若<0.05,则说明变量间有相关性,则可因子分析):",p_value)# KMO检验:计算KMO值
kmo_all,kmo_model=calculate_kmo(data_norm)
print("\nKMO(KMO值介于0~1之间,越接近1,说明变量间相关性越强,偏相关性越弱,因子分析的效果越好。\n""若KMO值>0.6,说明变量间有相关性,则可因子分析):",kmo_model)

2.3求相关系数矩阵 

np.corrcoef()

# 求相关系数矩阵
r=np.corrcoef(data_norm.T)

对应的数学公式及分析:

2.4求相关系数矩阵的特征值、特征向量,并排序

法一:np.linalg.eig(r)

  • 注意:此法得到的特征值没有按从大到小的顺序排列,需要自行排序
  • 排序的目的:后面需要利用特征值来求累积贡献率,然后利用累积贡献率\geqslant85%来挑选前n个公共因子。只有这样,才能保证挑选出来公共因子,既能代表较多的信息,又数量较少。
# 求相关系数矩阵的特征值、特征向量
eigval,eigvec=np.linalg.eig(r)
print("特征值:\n",eigval)
print("特征向量:\n",eigvec)# 对特征值、特征向量按从大到小排序
address_sort=np.argsort(-eigval)
result_sort=np.zeros(len(eigval))
result_sort[address_sort]=np.arange(0,len(eigval))
result_sort=[int(i) for i in result_sort]
print("特征值从大到小的顺序",result_sort)eigval=eigval[result_sort]
eigvec=eigvec[:,result_sort]
print("排序后的特征值:\n",eigval)
print("排序后的特征向量:\n",eigvec)

 法二:建立一个不旋转的因子分析模型,再利用FA.get_eigenvalues()

注意:此法会得到2组特征值,但只有第一组是需要的,本人不太清楚是为什么

优点:得到的特征值已经按从大到小的顺序排列

fa0=FA(n_factors=len(r),rotation=None)
fa0.fit(data_norm)
val1,val2=fa0.get_eigenvalues()  # 注意:这里会得到2组特征值,但只有第一组是需要的
print("fa0的特征值:\n",val1)

2.5求累积贡献率

contibute_ratio=eigval/sum(eigval)
print("贡献率:\n",contibute_ratio)
print("累积贡献率:\n",np.cumsum(contibute_ratio))

 对应的数学公式及分析:

2.6选公共因子数量

选取累积贡献率达到85%以上的前n个公共因子 

'''由于前3个公共因子的累计贡献率已经超过0.85,
因此认为用3个公共因子 就能较好地进行评价'''
n=3

2.7构建并训练模型

FA(n_factors,rotation)

# 构建模型
fa=FA(n_factors=n,rotation="varimax")
'''FA
参数解读:
n_factors:公共因子数
rotation:因子旋转方式
有以下的选择:
varimax (orthogonal rotation):正交旋转方法,方差最大化
promax (oblique rotation):斜交旋转方法,追求载荷阵中0尽可能多,方法是取正交旋转得到的载荷阵元素的幂次。要求幂次尽可能低,公共因子间的相关性尽可能低。
oblimin (oblique rotation)斜交旋转方法,追求载荷阵中0尽可能多,设置公共因子之间的相关系数在较小值。
oblimax (orthogonal rotation)
quartimin (oblique rotation)
quartimax (orthogonal rotation)正交旋转方法,要求每个原始变量仅与一个公共因子强相关,而与其余公共因子近似不相关。 
equamax (orthogonal rotation)
'''
fa.fit(data_norm)  # 训练模型

2.8因子载荷矩阵

FA.loadings_

factor_load=fa.loadings_
print("因子载荷矩阵:\n",factor_load)

 对应的数学公式及分析:

 2.9求各类方差贡献

# 各因子对总方差贡献
factor_contribute=np.sum(factor_load**2,axis=0)
print("各因子对总方差贡献:\n",factor_contribute)# 共性方差
same_variance=np.sum(factor_load**2,axis=1)# 特殊方差
specific_variance=1-same_variance  # 如果数据已经标准化,则 共性方差+特殊方差=1
print("特殊方差:\n",specific_variance)

2.10求因子得分

法一:自己用矩阵运算

# 求因子得分
ss=inv(np.diag(specific_variance))  # 因子得分函数的一部分
factor_score=data_norm@ss@factor_load@inv(factor_load.T@ss@factor_load)
print("因子得分:\n",factor_score)

法二:FA.transform()

# 计算因子得分
factor_score=fa.transform(data_norm)
print("因子得分:\n",factor_score)

 注意:两种方法求出的因子得分有一些差别,具体原因不明。

对应的数学公式及分析:

      至此,因子分析的步骤已经完成!

      下面用因子得分进行评价

2.11计算评价得分 

# 计算评价得分
evaluate=factor_score@factor_contribute/sum(factor_contribute)  # 以 各因子对总方差贡献 为权重,求因子得分的加权平均,即可得到评价得分
print("评价得分:\n",evaluate)

对应的数学公式及分析:

2.12按评价得分排序 

address_sort=np.argsort(-evaluate)
result_sort=np.zeros(17)
result_sort[address_sort]=np.arange(1,18)
print("排名次序:\n",result_sort)

2.13代码汇总

import numpy as np
from numpy.linalg import inv
import pandas as pd
from scipy.stats import zscore
from  factor_analyzer import FactorAnalyzer as FA
from factor_analyzer.factor_analyzer import calculate_bartlett_sphericity  # 用于Bartlett's球状检验
from factor_analyzer.factor_analyzer import calculate_kmo  # 用于KMO检验# 导入数据
data=np.loadtxt("data12_5_1.txt")
print(data)# 数据标准化
data_norm=zscore(data,ddof=1)# Bartlett's球状检验:计算巴特利特P值
chi_square_value,p_value=calculate_bartlett_sphericity(data_norm)
print("Bartlett's球状检验:\n","卡方值:",chi_square_value,"\nP值(若<0.05,则说明变量间有相关性,则可因子分析):",p_value)# KMO检验:计算KMO值
kmo_all,kmo_model=calculate_kmo(data_norm)
print("\nKMO(KMO值介于0~1之间,越接近1,说明变量间相关性越强,偏相关性越弱,因子分析的效果越好。\n""若KMO值>0.6,说明变量间有相关性,则可因子分析):",kmo_model)# 求相关系数矩阵
r=np.corrcoef(data_norm.T)# 求相关系数矩阵的特征值、特征向量
eigval,eigvec=np.linalg.eig(r)
print("特征值:\n",eigval)
print("特征向量:\n",eigvec)# 对特征值、特征向量按从大到小排序
address_sort=np.argsort(-eigval)
result_sort=np.zeros(len(eigval))
result_sort[address_sort]=np.arange(0,len(eigval))
result_sort=[int(i) for i in result_sort]
print("特征值从大到小的顺序",result_sort)eigval=eigval[result_sort]
eigvec=eigvec[:,result_sort]
print("排序后的特征值:\n",eigval)
print("排序后的特征向量:\n",eigvec)contibute_ratio=eigval/sum(eigval)
print("贡献率:\n",contibute_ratio)
print("累积贡献率:\n",np.cumsum(contibute_ratio))# 用此法也能获得相关系数矩阵的特征值
fa0=FA(n_factors=len(r),rotation=None)
fa0.fit(data_norm)
val1,val2=fa0.get_eigenvalues()  # 注意:这里会得到2组特征值,但只有第一组是需要的?
print("fa0的特征值:\n",val1)'''由于前3个公共因子的累计贡献率已经超过0.85,因此认为用3个公共因子 就能较好地进行评价'''
n=3
# 构建模型
fa=FA(n_factors=n,rotation="varimax")
'''FA
参数解读:
n_factors:公共因子数
rotation:因子旋转方式
有以下的选择:
varimax (orthogonal rotation):正交旋转方法,方差最大化
promax (oblique rotation):斜交旋转方法,追求载荷阵中0尽可能多,方法是取正交旋转得到的载荷阵元素的幂次。要求幂次尽可能低,公共因子间的相关性尽可能低。
oblimin (oblique rotation)斜交旋转方法,追求载荷阵中0尽可能多,设置公共因子之间的相关系数在较小值。
oblimax (orthogonal rotation)
quartimin (oblique rotation)
quartimax (orthogonal rotation)正交旋转方法,要求每个原始变量仅与一个公共因子强相关,而与其余公共因子近似不相关。 
equamax (orthogonal rotation)
'''
fa.fit(data_norm)  # 训练模型factor_load=fa.loadings_
print("因子载荷矩阵:\n",factor_load)# 各因子对总方差贡献
factor_contribute=np.sum(factor_load**2,axis=0)
print("各因子对总方差贡献:\n",factor_contribute)# 共性方差
same_variance=np.sum(factor_load**2,axis=1)
# 特殊方差
specific_variance=1-same_variance  # 如果数据已经标准化,则 共性方差+特殊方差=1
print("特殊方差:\n",specific_variance)# 求因子得分
ss=inv(np.diag(specific_variance))  # 因子得分函数的一部分
factor_score=data_norm@ss@factor_load@inv(factor_load.T@ss@factor_load)
print("因子得分:\n",factor_score)
print("因子得分2:\n",fa.transform(data_norm))# 计算评价得分
evaluate=factor_score@factor_contribute
print("评价得分:\n",evaluate)address_sort=np.argsort(-evaluate)
result_sort=np.zeros(17)
result_sort[address_sort]=np.arange(1,18)
print("排名次序:\n",result_sort)

参考资料

9 因子分析 | 多元统计分析讲义 (pku.edu.cn)

Python数学建模算法与应用 (司守奎,孙玺菁主编)

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/web/62464.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

unity3d—demo(2d人物左右移动发射子弹)

目录 人物代码示例&#xff1a; 子弹代码示例&#xff1a; 总结上面代码&#xff1a; 注意点&#xff1a; 人物代码示例&#xff1a; using System.Collections; using System.Collections.Generic; using UnityEngine;public class PlayerTiao : MonoBehaviour {public f…

echarts使用整理

4、条形分区统计 <div ref"chartsVal1" class"chartsline-div"></div> const chartsVal1 ref(null); const chartsVal1Title ref(运行时间统计);drewCharts2(chartsVal1, chartsVal1Title.value);function drewCharts2(id, title) {const m…

ubuntu下的chattts 学习6:音色固定的学习

魔搭社区 该区提供了随机种子级音乐的试听与下载。 spk torch.load(<PT-FILE-PATH>) params_infer_code {spk_emb: spk, } 略 测试过程&#xff1a; 1.先建一个文件夹&#xff1a;然后从上面的网站上下载了两个。放在里面测试 2 2.测试代码 import ChatTTS impo…

数据集的重要性:如何构建AIGC训练集

文章目录 一、为什么数据集对AIGC如此重要&#xff1f;1. 数据决定模型的知识边界2. 数据质量直接影响生成效果3. 数据集多样性提升模型鲁棒性 二、构建AIGC训练集的关键步骤1. 明确目标任务和生成需求2. 数据源的选择3. 数据清洗与预处理4. 数据标注5. 数据增强 三、针对不同类…

47 基于单片机的书库环境监测

目录 一、主要功能 二、硬件资源 三、程序编程 四、实现现象 一、主要功能 基于51单片机&#xff0c;采用DHT11湿度传感器检测湿度&#xff0c;DS18B20温度传感器检测温度&#xff0c; 采用滑动变阻器连接数模转换器模拟二氧化碳和氧气浓度检测&#xff0c;各项数值通过lc…

【操作系统】每日 3 题(五十五)

✍个人博客&#xff1a;https://blog.csdn.net/Newin2020?typeblog &#x1f4e3;专栏地址&#xff1a;https://blog.csdn.net/newin2020/category_12820365.html &#x1f4da;专栏简介&#xff1a;在这个专栏中&#xff0c;我将会分享操作系统面试中常见的面试题给大家~ ❤️…

MySQL | 尚硅谷 | 第13章_约束

MySQL笔记&#xff1a;第13章_约束 文章目录 MySQL笔记&#xff1a;第13章_约束第13章_约束 1. 约束(constraint)概述1.1 为什么需要约束1.2 什么是约束1.3 约束的分类演示代码 2. 非空约束2.1 作用2.2 关键字2.3 特点2.4 添加非空约束2.5 删除非空约束演示代码 3. 唯一性约束3…

《计算机网络》(408大题)

2009 路由转发和静态路由的计算 子网划分、路由聚合的计算 注&#xff1a;CIDR中的子网号可以全为0或1&#xff0c;但是其主机号不允许。 注&#xff1a; 这里其实是把到互联网的路由当做了一个默认路由&#xff08;当一个目的网络地址与路由表中其他都不匹配时&#xff0c;…

NanoLog起步笔记-6-StaticLogInfo

nonolog起步笔记-6-StaticLogInfo StaticLogInfo文件名和行号文件名和行号的传入log参数 RuntimeLogger::registerInvocationSitelogid为什么只能被赋一次值 reserveAlloc加入消息头finishAlloc返回 StaticLogInfo 写C语言编译前端时&#xff0c;给我印象深刻的一部分是&#…

软件工程 概述

软件 不仅仅是一个程序代码。程序是一个可执行的代码&#xff0c;它提供了一些计算的目的。 软件被认为是集合可执行的程序代码&#xff0c;相关库和文档的软件。当满足一个特定的要求&#xff0c;就被称为软件产品。 工程 是所有有关开发的产品&#xff0c;使用良好定义的&…

Sui 集成 Phantom,生态迎来全新里程碑

作为领先的非托管多链加密&#x1f45b;&#xff0c;Phantom 宣布将支持 Sui 区块链。Sui 将加入 Solana、Bitcoin 和 Ethereum 队伍&#xff0c;成为该 wallet 支持的少数 L1 区块链之一。 此次集成也大幅提升了 Phantom 的互操作性&#xff0c;同时表明 wallet 提供商和应用…

低级爬虫实现-记录HCIP云架构考试

因工作需要考HCIP云架构&#xff08;HCIP-Cloud Service Solution Architect&#xff09;证书, 特意在淘宝上买了题库&#xff0c; 考过了。 事后得知自己被坑了&#xff0c; 多花了几十大洋。 所以想着在授权期内将题库“爬”下来&#xff0c; 共享给大家。 因为整个过程蛮有…

QGroundControl之5-AppSettings.cc

介绍 应用程序设置 Application Settings &#xff0c;这里看下语言选择功能&#xff0c;它是怎么和json文件关联起来的&#xff0c;刚刚看的时候&#xff0c;很是奇怪这么多的json文件作用。 1.AppSettings.cc 文件怎么和App.SettingsGroup.json关联 在AppSettings.cc文件没…

jenkins邮件的配置详解

Jenkins邮件的配置涉及多个步骤和细节,以下是详细的配置指南: 一、前期准备 确定邮件服务:明确Jenkins将要使用的邮件服务,如QQ邮箱、163邮箱、公司邮箱(基于Microsoft 365或Exchange Server)等。获取SMTP配置信息:根据邮件服务类型,获取相应的SMTP服务器地址、端口号…

【ArcGIS微课1000例】0134:ArcGIS Earth实现二维建筑物的三维完美显示

文章目录 一、加载数据二、三维显示三、三维符号化一、加载数据 加载配套实验数据(0134.rar中的建筑物,2d或3d都可以),方法如下:点击添加按钮。 点击【Add Files】,在弹出的Open对话框中,选择建筑物,点击确定,完成添加。 默认二维显示: 二、三维显示 右键建筑物图层…

jupyterlab 增加多个kernel,正确做法

1、背景 需要增加一个kernel然后相当于隔离一个环境 juypterlab Version 3.0.14 2、用conda 安装 例如&#xff0c;你在conda下有一个python 3.12 的环境 py312 ipython kernel install --user --namepy312 如果保持的话&#xff0c;用pip安装相应的包就好 3、检查是否配置好 …

案例-商品列表(组件封装)

标签组件封装 1.双击显示&#xff0c;自动聚焦 2.失去焦点&#xff0c;隐藏输入框 标签一列&#xff0c;不同行的标签内容不同&#xff0c;但是除此之外其他基本一致&#xff0c;所以选择用 标签组件 将这一部分封装为一个组件&#xff0c;需要时组件标签展示。 首先标签处一进…

Python 基础学习(一)

一.基础语法 注释 Python中单行注释以 # 开头&#xff0c;如下&#xff1a; #!/usr/bin/python3# 第一个注释 print ("Hello, Python!") # 第二个注释多行注释可以用多个 # 号&#xff0c;还有 ‘’’ 和 “”"&#xff1a; #!/usr/bin/python3# 第一个注释…

TIM输入捕获---STM

一、简介 IC输入捕获 输入捕获模式下&#xff0c;当通道输入引脚出现指定电平跳变时&#xff0c;当前CNT的值将被锁存在CCR中&#xff0c;可用于测量PWM波形的频率、占空比、脉冲间隔、电平持续时间等参数 每个高级定时器和通用定时器都拥有4个输入捕获通道 可配置为PWMI模…

【Android Studio】学习——网络连接

实验&#xff1a;Android网络连接 文章目录 实验&#xff1a;Android网络连接[toc]实验目标和实验内容&#xff1a;1、掌握Android联网的基本概念&#xff1b;2、能够使用URL connection实现网络连接&#xff1b;3、掌握第三方库的基本概念4、需实现的具体功能 实验结果功能说明…