Skip to content

Commit

Permalink
Create 结构方程.md
Browse files Browse the repository at this point in the history
  • Loading branch information
Hyh996 authored Dec 15, 2024
1 parent cba774b commit 6a60109
Showing 1 changed file with 186 additions and 0 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,186 @@
# 结构方程模型(PoliticalDemocracy)
内容参考自:

https://zhuanlan.zhihu.com/p/22811566

https://pypi.org/project/semopy/2.0.0a5/

---

__实例简介__:以python实现结构方程模型的分析,以经典模型PoliticalDemocracy为例
## 构建模型
以经典模型PoliticalDemocracy为例,按照流程构建模型
(当然,这个案例的模型其实只需要一句:
```python
desc = political_democracy.get_model()
```
就可以直接拿来用,不过为了方便变成可修改的模型,就还是参考文档构建)

![image](https://github.com/user-attachments/assets/fbcad993-3c7a-47ac-ba36-0ee3ec8385dc)

> 这张图取自第一篇参考文档,模型也是根据第一篇参考文档来的
```python
import semopy
data = semopy.examples.holzinger39.get_data()

desc = '''
# 定义测量模型
y1 =~ x1 + x2 + x3
y2 =~ x4 + x5 + x6
y3 =~ x7 + x8 + x9
# 定义结构模型
y1 ~ y2 + y3
y2 ~~ y3
'''

# 将上述文本转化为 semopy 库中的模型
mod = semopy.Model(desc)
```
---
> 以下内容在我的关于semopy库的笔记中有,里面的参数就不做过多赘述了
## 分析模型
### 拟合
> 对数据进行拟合和估计
```python
# 对数据进行拟合和估计
res_opt = mod.fit(data)
estimates = mod.inspect()
print(estimates)
```
### 拟合指数
> 输出所有semopy库中的拟合指数
```python
# 查看拟合指数
calc_stats = semopy.stats.calc_stats(mod)
print(calc_stats)
```
### 整理到excel
```python
import pandas as pd

# 创建一个简单的 DataFrame
df = pd.DataFrame(estimates)
stats = pd.DataFrame(calc_stats)

# 将 DataFrame 导出到 Excel 文件
df.to_excel('output_PoliticalDemocracy_estimates.xlsx', index=False, engine='openpyxl')
stats.to_excel('output_PoliticalDemocracy_stats.xlsx', index=False, engine='openpyxl')
```
这里用到的几个参数:
1. 路径'output_PoliticalDemocracy_estimates.xlsx'确保目标文件可以正确创建。
2. index=False表示在输出文件中不保留数据框的索引。
3. engine='openpyxl'表示使用openpyxl库作为Excel文件的写入引擎。这样可以确保与现有的Excel软件兼容,并且可以更好地处理大型的数据框。

---
## 可视化
### 绘图
```python
# 绘制 Graphviz 图
graw = semopy.semplot(estimates,"tp.png")
print(graw)
```
绘图这里可能是我没有理解所有参数的原因,不能直接输出Graphviz 图。
不过在semopy库的官方文档中确实是用这个方法来绘制(下面这个是官方文档中的案例图):

![image](https://github.com/user-attachments/assets/baf20d71-33bd-4d04-8e3e-bf647a601b2f)

### 网页报告
```python
# 报告
model = semopy.ModelMeans(desc)
model.fit(data)
semopy.report.report(model, "PoliticalDemocracy")
```
---
## 完整实例
### 源代码
```python
import pandas as pd
import semopy

data = semopy.examples.political_democracy.get_data()

desc = '''
# 定义测量模型
ind60 =~ x1 + x2 +x3
dem60 =~ y1 + y2 + y3 + y4
dem65 =~ y5 + y6 + y7 + y8
# 定义结构模型
dem60 ~ ind60
dem65 ~ ind60 + dem60
# 协方差
y1 ~~ y5
y2 ~~ y4 +y6
y3 ~~ y7
y4 ~~ y8
y6 ~~ y8
'''

# 将上述文本转化为 semopy 库中的模型
mod = semopy.Model(desc)

# 对数据进行拟合和估计
res_opt = mod.fit(data)
estimates = mod.inspect()
print(estimates)

# 查看拟合指数
calc_stats = semopy.stats.calc_stats(mod)
print(calc_stats)

# 导出excel表格
# 创建一个简单的 DataFrame
df = pd.DataFrame(estimates)
stats = pd.DataFrame(calc_stats)

# 将 DataFrame 导出到 Excel 文件
df.to_excel('output_PoliticalDemocracy_estimates.xlsx', index=False, engine='openpyxl')
stats.to_excel('output_PoliticalDemocracy_stats.xlsx', index=False, engine='openpyxl')

# 报告
model = semopy.ModelMeans(desc)
model.fit(data)
semopy.report(model, "PoliticalDemocracy")

# 显示 Graphviz 图
graw = semopy.semplot(estimates,"tp.png")
print(graw)
```
## 输出
程序运行打印结果:

![image](https://github.com/user-attachments/assets/80cfa46d-0cd3-4462-be95-9903d9c9f3e4)


excel文件中的拟合数据:

![image](https://github.com/user-attachments/assets/934822dd-49cf-4f74-a8cd-cf3e1e936bd4)

semplot方法输出的"tp.png":

![image](https://github.com/user-attachments/assets/b7eb3164-a903-49bb-962c-b349f21505db)

excel文件中的拟合指数:

![image](https://github.com/user-attachments/assets/648402c2-95bd-4f8c-8b27-f834d09f379e)

__网页报告__
输出的部分HTML截图:

![image](https://github.com/user-attachments/assets/4dbe3d8a-3ed8-4953-8c3b-c099d3ed5ffe)

网页截图1:

![image](https://github.com/user-attachments/assets/306ca9f5-08e9-42d8-bcb7-e68121dd0671)

截图2:

![image](https://github.com/user-attachments/assets/8a077dd0-0852-4b48-a7a3-8fa1dceefb37)

截图3:

![image](https://github.com/user-attachments/assets/e4ae3aa1-c1ae-470a-a2e3-ae048930ee47)



0 comments on commit 6a60109

Please sign in to comment.