Skip to content

Commit 98233c0

Browse files
committed
updating with chris's feedback
Signed-off-by: Nathaniel <[email protected]>
1 parent 1dcb109 commit 98233c0

File tree

2 files changed

+1141
-1085
lines changed

2 files changed

+1141
-1085
lines changed

examples/case_studies/CFA_SEM.ipynb

Lines changed: 1120 additions & 1079 deletions
Large diffs are not rendered by default.

examples/case_studies/CFA_SEM.myst.md

Lines changed: 21 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@ kernelspec:
2323

2424
> "Evidently, the notions of relevance and dependence are far more basic to human reasoning than the numerical values attached to probability judgments...the language used for representing probabilistic information should allow assertions about dependency relationships to be expressed qualitatively, directly, and explicitly" - Pearl in _Probabilistic Reasoning in Intelligent Systems_ {cite:t}`pearl1985prob`
2525
26-
Measurement data is psychometrics is often derived from a strategically constructed survey aimed at a particular target phenomena. Some intuited, but not yet measured, concept that arguably plays a determining role in human action, motivation or sentiment. The relative “fuzziness” of the subject matter in psychometrics has had a catalyzing effect on the methodological rigour sought in the science.
26+
Measurement data in psychometrics is often derived from a strategically constructed survey aimed at a particular target phenomena. Some intuited, but not yet measured, concept that arguably plays a determining role in human action, motivation or sentiment. The relative “fuzziness” of the subject matter in psychometrics has had a catalyzing effect on the methodological rigour sought in the science.
2727

2828
Survey designs are agonized over for correct tone and rhythm of sentence structure. Measurement scales are doubly checked for reliability and correctness. The literature is consulted and questions are refined. Analysis steps are justified and tested under a wealth of modelling routines. Model architectures are defined and refined to better express the hypothesized structures in the data-generating process. We will see how such due diligence leads to powerful and expressive models that grant us tractability on thorny questions of human affect.
2929

@@ -96,7 +96,7 @@ A measurement model is a key component within the more general structural equati
9696

9797
We'll start by fitting a "simple" CFA model in `PyMC` to demonstrate how the pieces fit together, we'll then expand our focus. Here we ignore the majority of our indicator variables and focus on the idea that there are two latent constructs: (1) Social Self-efficacy and (2) Life Satisfaction.
9898

99-
We're aiming to articulate a mathematical structure where our indicator variables $x_{ij}$ are determined by a latent factor $\text{Ksi}_{j}$ through an estimated factor loading $\lambda_{ij}$. Functionally we have a set of equations with error terms $\psi_i$ for each individual.
99+
We're aiming to articulate a mathematical structure where our indicator variables $x_{ij}$ are determined by a latent factor $\text{Ksi}_{j}$ through an estimated factor loading $\lambda_{ij}$. We keep close to the notation used in Levy and Mislevy's Bayesian Psychometric Modelling. Functionally we have a set of equations with error terms $\psi_i$ for each individual.
100100

101101
$$ x_{1} = \tau_{1} + \lambda_{11}\text{Ksi}_{1} + \psi_{1} \\
102102
x_{2} = \tau_{2} + \lambda_{21}\text{Ksi}_{1} + \psi_{2} \\
@@ -108,7 +108,7 @@ or more compactly
108108

109109
$$ \mathbf{x} = \tau + \Lambda\text{Ksi} + \Psi $$
110110

111-
The goal is to articulate the relationship between the different factors in terms of the covariances between these latent terms and estimate the relationships each latent factor has with the manifest indicator variables. At a high level, we're saying the joint distribution of the observed data can be represented through conditionalisation in the following schema.
111+
We have greek letters to highlight traditional model parameters and use $\text{Ksi}$ to highlight latent constructs as a distinct kind of parameter. The goal is to articulate the relationship between the different factors in terms of the covariances between these latent terms and estimate the relationships each latent factor has with the manifest indicator variables. At a high level, we're saying the joint distribution of the observed data can be represented through conditionalisation in the following schema.
112112

113113
$$p(\mathbf{x_{i}}^{T}.....\mathbf{x_{q}}^{T} | \text{Ksi}, \Psi, \tau, \Lambda) \sim Normal(\tau + \Lambda\cdot \text{Ksi}, \Psi) $$
114114

@@ -190,7 +190,7 @@ We can now see how the covariance structure among the latent constructs is integ
190190
az.summary(idata, var_names=["lambdas1", "lambdas2"])
191191
```
192192

193-
These factor loadings are generally important to interpret in terms of construct validity. Because we've specified one of the indicator variables to be fixed at 1, the other indicators which load on that factor should have a loading coefficient in broadly the same scale as the fixed point indicator that defines the construct scale. We're looking for consistency among the loadings to assess whether the indicators are reliable measures of the construct i.e. if the indicator loadings deviates too far from unit 1 then there is an argument to be made that these indicators don't belong in the same factor construct.
193+
These factor loadings are generally important to interpret in terms of construct validity. Because we've specified one of the indicator variables to be fixed at 1, the other indicators which load on that factor should have a loading coefficient in broadly the same scale as the fixed point indicator that defines the construct scale. We're looking for consistency among the loadings to assess whether the indicators are reliable measures of the construct i.e. if the indicator loadings deviates too far from unit 1 then there is an argument to be made that these indicators don't belong in the same factor construct. The closer the factor loading parameters within a construct are to 1 the better.
194194

195195
```{code-cell} ipython3
196196
idata
@@ -202,6 +202,18 @@ Let's plot the trace diagnostics to validate the sampler has converged well to t
202202
az.plot_trace(idata, var_names=["lambdas1", "lambdas2", "tau", "Psi", "ksi"]);
203203
```
204204

205+
We also examine the energy plot to assess sampling diagnostics. This looks quite healthy.
206+
207+
```{code-cell} ipython3
208+
fig, axs = plt.subplots(1, 2, figsize=(20, 7))
209+
axs = axs.flatten()
210+
az.plot_energy(idata, ax=axs[0])
211+
az.plot_forest(idata, var_names=["lambdas1", "lambdas2"], combined=True, ax=axs[1])
212+
axs[1].set_title("Factor Loading Estimates")
213+
axs[0].set_title("Energy Plot")
214+
axs[1].axvline(1, color="black");
215+
```
216+
205217
### Sampling the Latent Constructs
206218

207219
One thing to highlight in particular about the Bayesian manner of fitting CFA and SEM models is that we now have access to the posterior distribution of the latent quantities. These samples can offer insight into particular individuals in our survey that is harder to glean from the multivariate presentation of the manifest variables.
@@ -282,7 +294,7 @@ Which shows a relatively sound recovery of the observed data.
282294

283295
### Intermediate Cross-Loading Model
284296

285-
The idea of a measurement model is maybe a little opaque when we only see models that fit well. Instead we want to briefly show how an in-apt measurement model gets reflected in the estimated parameters for the factor loadings. Here we specify a measurement model which attempts to couple the `se_social` and `sup_parents` indicators and bundle them into the same factor.
297+
The idea of a measurement model is maybe a little opaque when we only see models that fit well. Instead we want to briefly show how an inappropriate measurement model gets reflected in the estimated parameters for the factor loadings. Here we specify a measurement model which attempts to couple the `se_social` and `sup_parents` indicators and bundle them into the same factor.
286298

287299
```{code-cell} ipython3
288300
coords = {
@@ -387,7 +399,10 @@ This is similarly reflected in the diagnostic energy plots here too.
387399
fig, axs = plt.subplots(1, 2, figsize=(20, 9))
388400
axs = axs.flatten()
389401
az.plot_energy(idata, ax=axs[0])
390-
az.plot_forest(idata, var_names=["lambdas1"], combined=True, ax=axs[1]);
402+
az.plot_forest(idata, var_names=["lambdas1", "lambdas2"], combined=True, ax=axs[1])
403+
axs[1].axvline(1, color="black")
404+
axs[1].set_title("Factor Loadings Estimates")
405+
axs[0].set_title("Energy Plot");
391406
```
392407

393408
This hints at a variety of measurement model misspecification and should force us back to the drawing board. An appropriate measurement model maps the indicator variables to a consistently defined latent construct that plausibly reflects aspects of the realised indicator metrics.

0 commit comments

Comments
 (0)