import%20marimo%0A%0A__generated_with%20%3D%20%220.24.0%22%0Aapp%20%3D%20marimo.App()%0A%0A%0A%40app.cell%0Adef%20_()%3A%0A%20%20%20%20import%20marimo%20as%20mo%0A%20%20%20%20import%20numpy%20as%20np%0A%20%20%20%20import%20pandas%20as%20pd%0A%20%20%20%20import%20plotly.graph_objects%20as%20go%0A%20%20%20%20from%20plotly.subplots%20import%20make_subplots%0A%20%20%20%20from%20sklearn.decomposition%20import%20FactorAnalysis%0A%0A%20%20%20%20return%20FactorAnalysis%2C%20go%2C%20make_subplots%2C%20mo%2C%20np%2C%20pd%0A%0A%0A%40app.cell(hide_code%3DTrue)%0Adef%20_(mo)%3A%0A%20%20%20%20mo.md(r%22%22%22%0A%20%20%20%20%23%20Note%2028%3A%20Factor%20Analysis%2C%20Latent%20Variable%20Modeling%2C%20and%20Orthogonal%20Rotations%0A%0A%20%20%20%20%26larr%3B%20Previous%20Note%3A%20%5B27%20Principal%20Component%20Analysis%5D(27_principal_component_analysis.py)%20%7C%20Next%20Note%3A%20%5B29%20Canonical%20Correlation%20Analysis%5D(29_canonical_correlation_analysis.py)%20%26rarr%3B%0A%0A%20%20%20%20---%0A%0A%20%20%20%20%23%23%20%5Ba%5D%20Why%20do%20you%20need%20to%20know%20these%20concepts%3F%0A%0A%20%20%20%20While%20Principal%20Component%20Analysis%20(PCA)%20is%20an%20algebraic%20projection%20method%20that%20maximizes%20the%20total%20variance%20of%20observed%20features%2C%20it%20makes%20no%20distinction%20between%20variance%20shared%20among%20features%20and%20idiosyncratic%20noise%20specific%20to%20individual%20sensors%20or%20measurements.%0A%0A%20%20%20%20**Factor%20Analysis%20(FA)**%20is%20a%20generative%2C%20probabilistic%20latent%20variable%20model%3A%0A%20%20%20%201.%20**Variance%20Decomposition%20(Commonality%20vs.%20Uniqueness)**%3A%20FA%20explicitly%20decomposes%20the%20observed%20covariance%20matrix%20into%20two%20orthogonal%20parts%3A%0A%20%20%20%20%20%20%20-%20**Common%20Variance%20(%24%5Cboldsymbol%7B%5CLambda%7D%5Cboldsymbol%7B%5CLambda%7D%5E%5Ctop%24)**%3A%20The%20systemic%20covariance%20shared%20across%20variables%2C%20driven%20by%20a%20small%20number%20of%20unobserved%20latent%20factors%20%24%5Cmathbf%7BF%7D%24.%0A%20%20%20%20%20%20%20-%20**Unique%20Variance%20%2F%20Uniqueness%20(%24%5Cboldsymbol%7B%5CPsi%7D%24)**%3A%20The%20independent%20variance%20unique%20to%20each%20specific%20feature%2C%20combining%20idiosyncratic%20variation%20and%20measurement%20error.%0A%20%20%20%202.%20**Uncovering%20Latent%20Constructs**%3A%20In%20psychometrics%2C%20quantitative%20finance%2C%20and%20natural%20language%20understanding%2C%20concepts%20such%20as%20general%20intelligence%20(%24g%24)%2C%20market%20liquidity%2C%20credit%20risk%2C%20or%20sentiment%20cannot%20be%20directly%20observed.%20FA%20uncovers%20these%20hidden%20generative%20drivers%20from%20battery%20tests%20or%20indicator%20variables.%0A%20%20%20%203.%20**Rotational%20Invariance%20and%20Interpretability**%3A%20The%20loading%20matrix%20%24%5Cboldsymbol%7B%5CLambda%7D%24%20is%20not%20unique%3A%20multiplying%20by%20any%20orthogonal%20rotation%20matrix%20%24%5Cmathbf%7BQ%7D%24%20(%24%5Cboldsymbol%7B%5CLambda%7D%5E*%20%3D%20%5Cboldsymbol%7B%5CLambda%7D%5Cmathbf%7BQ%7D%24)%20preserves%20the%20exact%20covariance%20decomposition.%20Algorithms%20such%20as%20**Varimax%20rotation**%20exploit%20this%20mathematical%20freedom%20to%20rotate%20factors%20into%20a%20%22simple%20structure%22%20where%20each%20observed%20variable%20loads%20heavily%20on%20only%20one%20factor%20and%20near-zero%20on%20others.%0A%20%20%20%204.%20**Linear%20Precursor%20to%20Modern%20Latent%20Models**%3A%20Factor%20Analysis%20with%20Gaussian%20latents%20and%20diagonal%20noise%20is%20the%20direct%20foundational%20ancestor%20of%20Probabilistic%20PCA%20(PPCA)%20and%20deep%20generative%20Variational%20Autoencoders%20(VAEs).%0A%20%20%20%20%22%22%22)%0A%20%20%20%20return%0A%0A%0A%40app.cell(hide_code%3DTrue)%0Adef%20_(mo)%3A%0A%20%20%20%20mo.md(r%22%22%22%0A%20%20%20%20---%0A%0A%20%20%20%20%23%23%20%5Bb%5D%20Concept%20explanation%20with%20their%20role%20in%20ML%2FAI%2FStats%3F%0A%0A%20%20%20%20%23%23%23%201.%20The%20Generative%20Factor%20Model%0A%0A%20%20%20%20Let%20%24%5Cmathbf%7BX%7D%20%5Cin%20%5Cmathbb%7BR%7D%5Ep%24%20be%20a%20vector%20of%20%24p%24%20observed%20continuous%20variables%20with%20mean%20%24%5Cboldsymbol%7B%5Cmu%7D%20%3D%20%5Cmathbb%7BE%7D%5B%5Cmathbf%7BX%7D%5D%24.%20The%20classical%20orthogonal%20factor%20analysis%20model%20postulates%3A%0A%0A%20%20%20%20%24%24%0A%20%20%20%20%5Cmathbf%7BX%7D%20%3D%20%5Cboldsymbol%7B%5Cmu%7D%20%2B%20%5Cboldsymbol%7B%5CLambda%7D%20%5Cmathbf%7BF%7D%20%2B%20%5Cboldsymbol%7B%5Cepsilon%7D%0A%20%20%20%20%24%24%0A%0A%20%20%20%20where%3A%0A%20%20%20%20-%20%24%5Cboldsymbol%7B%5CLambda%7D%20%5Cin%20%5Cmathbb%7BR%7D%5E%7Bp%20%5Ctimes%20k%7D%24%20is%20the%20**factor%20loading%20matrix**%20(%24k%20%5Cll%20p%24).%20The%20entry%20%24%5Clambda_%7Bij%7D%24%20represents%20the%20direct%20sensitivity%20of%20observed%20variable%20%24X_i%24%20to%20latent%20factor%20%24F_j%24.%0A%20%20%20%20-%20%24%5Cmathbf%7BF%7D%20%5Csim%20%5Cmathcal%7BN%7D_k(%5Cmathbf%7B0%7D%2C%20%5C%2C%20%5Cmathbf%7BI%7D_k)%24%20is%20a%20%24k%24-dimensional%20vector%20of%20unobserved%2C%20standardized%2C%20mutually%20uncorrelated%20**common%20latent%20factors**.%0A%20%20%20%20-%20%24%5Cboldsymbol%7B%5Cepsilon%7D%20%5Csim%20%5Cmathcal%7BN%7D_p(%5Cmathbf%7B0%7D%2C%20%5C%2C%20%5Cboldsymbol%7B%5CPsi%7D)%24%20is%20a%20%24p%24-dimensional%20vector%20of%20unique%20errors%2C%20where%20%24%5Cboldsymbol%7B%5CPsi%7D%20%3D%20%5Coperatorname%7Bdiag%7D(%5Cpsi_1%5E2%2C%20%5Cpsi_2%5E2%2C%20%5Cdots%2C%20%5Cpsi_p%5E2)%24%20is%20a%20strictly%20diagonal%20matrix.%0A%20%20%20%20-%20Common%20factors%20and%20unique%20errors%20are%20mutually%20independent%3A%20%24%5Coperatorname%7BCov%7D(%5Cmathbf%7BF%7D%2C%20%5Cboldsymbol%7B%5Cepsilon%7D)%20%3D%20%5Cmathbf%7B0%7D%24.%0A%0A%20%20%20%20---%0A%0A%20%20%20%20%23%23%23%202.%20Implied%20Covariance%20Structure%0A%0A%20%20%20%20Taking%20the%20covariance%20of%20both%20sides%3A%0A%0A%20%20%20%20%24%24%0A%20%20%20%20%5Cboldsymbol%7B%5CSigma%7D%20%3D%20%5Coperatorname%7BCov%7D(%5Cmathbf%7BX%7D)%20%3D%20%5Cmathbb%7BE%7D%5Cleft%5B(%5Cboldsymbol%7B%5CLambda%7D%5Cmathbf%7BF%7D%20%2B%20%5Cboldsymbol%7B%5Cepsilon%7D)(%5Cboldsymbol%7B%5CLambda%7D%5Cmathbf%7BF%7D%20%2B%20%5Cboldsymbol%7B%5Cepsilon%7D)%5E%5Ctop%5Cright%5D%0A%20%20%20%20%24%24%0A%0A%20%20%20%20Expanding%20the%20bilinear%20expectation%3A%0A%0A%20%20%20%20%24%24%0A%20%20%20%20%5Cboldsymbol%7B%5CSigma%7D%20%3D%20%5Cboldsymbol%7B%5CLambda%7D%20%5Cmathbb%7BE%7D%5B%5Cmathbf%7BF%7D%5Cmathbf%7BF%7D%5E%5Ctop%5D%20%5Cboldsymbol%7B%5CLambda%7D%5E%5Ctop%20%2B%20%5Cboldsymbol%7B%5CLambda%7D%20%5Cmathbb%7BE%7D%5B%5Cmathbf%7BF%7D%5Cboldsymbol%7B%5Cepsilon%7D%5E%5Ctop%5D%20%2B%20%5Cmathbb%7BE%7D%5B%5Cboldsymbol%7B%5Cepsilon%7D%5Cmathbf%7BF%7D%5E%5Ctop%5D%20%5Cboldsymbol%7B%5CLambda%7D%5E%5Ctop%20%2B%20%5Cmathbb%7BE%7D%5B%5Cboldsymbol%7B%5Cepsilon%7D%5Cboldsymbol%7B%5Cepsilon%7D%5E%5Ctop%5D%0A%20%20%20%20%24%24%0A%0A%20%20%20%20Since%20%24%5Cmathbb%7BE%7D%5B%5Cmathbf%7BF%7D%5Cmathbf%7BF%7D%5E%5Ctop%5D%20%3D%20%5Cmathbf%7BI%7D_k%24%2C%20%24%5Coperatorname%7BCov%7D(%5Cmathbf%7BF%7D%2C%20%5Cboldsymbol%7B%5Cepsilon%7D)%20%3D%20%5Cmathbf%7B0%7D%24%2C%20and%20%24%5Cmathbb%7BE%7D%5B%5Cboldsymbol%7B%5Cepsilon%7D%5Cboldsymbol%7B%5Cepsilon%7D%5E%5Ctop%5D%20%3D%20%5Cboldsymbol%7B%5CPsi%7D%24%3A%0A%0A%20%20%20%20%24%24%0A%20%20%20%20%5Cboldsymbol%7B%5CSigma%7D%20%3D%20%5Cboldsymbol%7B%5CLambda%7D%20%5Cboldsymbol%7B%5CLambda%7D%5E%5Ctop%20%2B%20%5Cboldsymbol%7B%5CPsi%7D%0A%20%20%20%20%24%24%0A%0A%20%20%20%20%23%23%23%23%20Variance%20Partitioning%20for%20Variable%20%24i%24%3A%0A%20%20%20%20The%20total%20variance%20of%20the%20%24i%24-th%20variable%20decomposes%20as%3A%0A%0A%20%20%20%20%24%24%0A%20%20%20%20%5Csigma_%7Bii%7D%20%3D%20%5Csum_%7Bj%3D1%7D%5Ek%20%5Clambda_%7Bij%7D%5E2%20%2B%20%5Cpsi_i%5E2%20%3D%20h_i%5E2%20%2B%20%5Cpsi_i%5E2%0A%20%20%20%20%24%24%0A%0A%20%20%20%20-%20**Communality%20(%24h_i%5E2%20%3D%20%5Csum_%7Bj%3D1%7D%5Ek%20%5Clambda_%7Bij%7D%5E2%24)**%3A%20The%20portion%20of%20variance%20in%20%24X_i%24%20explained%20by%20the%20%24k%24%20shared%20common%20factors.%0A%20%20%20%20-%20**Uniqueness%20%2F%20Specific%20Variance%20(%24%5Cpsi_i%5E2%20%3D%20%5Csigma_%7Bii%7D%20-%20h_i%5E2%24)**%3A%20The%20idiosyncratic%20variance%20unique%20to%20variable%20%24X_i%24%20plus%20measurement%20noise.%0A%0A%20%20%20%20%23%23%23%23%20Cross-Covariance%20Between%20Distinct%20Variables%3A%0A%20%20%20%20For%20%24i%20%5Cneq%20m%24%2C%20because%20%24%5Cboldsymbol%7B%5CPsi%7D%24%20is%20strictly%20diagonal%3A%0A%0A%20%20%20%20%24%24%0A%20%20%20%20%5Coperatorname%7BCov%7D(X_i%2C%20X_m)%20%3D%20%5Csum_%7Bj%3D1%7D%5Ek%20%5Clambda_%7Bij%7D%20%5Clambda_%7Bmj%7D%0A%20%20%20%20%24%24%0A%0A%20%20%20%20All%20observed%20correlations%20between%20features%20are%20assumed%20to%20be%20mediated%20solely%20through%20the%20shared%20latent%20factors.%0A%0A%20%20%20%20---%0A%0A%20%20%20%20%23%23%23%203.%20Rotational%20Indeterminacy%20and%20Simple%20Structure%0A%0A%20%20%20%20Let%20%24%5Cmathbf%7BQ%7D%20%5Cin%20%5Cmathbb%7BR%7D%5E%7Bk%20%5Ctimes%20k%7D%24%20be%20any%20orthogonal%20rotation%20matrix%20(%24%5Cmathbf%7BQ%7D%5Cmathbf%7BQ%7D%5E%5Ctop%20%3D%20%5Cmathbf%7BQ%7D%5E%5Ctop%20%5Cmathbf%7BQ%7D%20%3D%20%5Cmathbf%7BI%7D_k%24).%20Define%20a%20rotated%20loading%20matrix%20%24%5Cboldsymbol%7B%5CLambda%7D%5E*%20%3D%20%5Cboldsymbol%7B%5CLambda%7D%20%5Cmathbf%7BQ%7D%24%20and%20corresponding%20rotated%20factors%20%24%5Cmathbf%7BF%7D%5E*%20%3D%20%5Cmathbf%7BQ%7D%5E%5Ctop%20%5Cmathbf%7BF%7D%24%3A%0A%0A%20%20%20%20%24%24%0A%20%20%20%20%5Cboldsymbol%7B%5CLambda%7D%5E*%20(%5Cboldsymbol%7B%5CLambda%7D%5E*)%5E%5Ctop%20%3D%20(%5Cboldsymbol%7B%5CLambda%7D%20%5Cmathbf%7BQ%7D)(%5Cmathbf%7BQ%7D%5E%5Ctop%20%5Cboldsymbol%7B%5CLambda%7D%5E%5Ctop)%20%3D%20%5Cboldsymbol%7B%5CLambda%7D%20(%5Cmathbf%7BQ%7D%5Cmathbf%7BQ%7D%5E%5Ctop)%20%5Cboldsymbol%7B%5CLambda%7D%5E%5Ctop%20%3D%20%5Cboldsymbol%7B%5CLambda%7D%20%5Cboldsymbol%7B%5CLambda%7D%5E%5Ctop%0A%20%20%20%20%24%24%0A%0A%20%20%20%20The%20rotated%20model%20generates%20the%20identical%20covariance%20matrix%3A%0A%0A%20%20%20%20%24%24%0A%20%20%20%20%5Cboldsymbol%7B%5CSigma%7D%20%3D%20%5Cboldsymbol%7B%5CLambda%7D%5E*%20(%5Cboldsymbol%7B%5CLambda%7D%5E*)%5E%5Ctop%20%2B%20%5Cboldsymbol%7B%5CPsi%7D%0A%20%20%20%20%24%24%0A%0A%20%20%20%20Because%20infinitely%20many%20choices%20of%20%24%5Cmathbf%7BQ%7D%24%20fit%20the%20data%20equally%20well%2C%20we%20apply%20rotation%20criteria%20to%20maximize%20interpretability%3A%0A%20%20%20%20-%20**Varimax%20Rotation%20(Kaiser%201958)**%3A%20An%20orthogonal%20rotation%20that%20maximizes%20the%20variance%20of%20the%20squared%20loadings%20within%20each%20factor%20column%3A%0A%0A%20%20%20%20%24%24%0A%20%20%20%20V%20%3D%20%5Csum_%7Bj%3D1%7D%5Ek%20%5Cleft%5B%20%5Cfrac%7B1%7D%7Bp%7D%20%5Csum_%7Bi%3D1%7D%5Ep%20%5Cleft(%5Cfrac%7B%5Clambda_%7Bij%7D%5E*%7D%7Bh_i%7D%5Cright)%5E4%20-%20%5Cleft(%5Cfrac%7B1%7D%7Bp%7D%20%5Csum_%7Bi%3D1%7D%5Ep%20%5Cleft(%5Cfrac%7B%5Clambda_%7Bij%7D%5E*%7D%7Bh_i%7D%5Cright)%5E2%5Cright)%5E2%20%5Cright%5D%0A%20%20%20%20%24%24%0A%0A%20%20%20%20Varimax%20drives%20loadings%20toward%20%24%2B1%2C%20-1%24%2C%20or%20%240%24%2C%20ensuring%20each%20feature%20associates%20decisively%20with%20a%20single%20factor.%0A%0A%20%20%20%20---%0A%0A%20%20%20%20%23%23%23%204.%20Comparison%3A%20PCA%20vs.%20Factor%20Analysis%0A%0A%20%20%20%20%7C%20Characteristic%20%7C%20Principal%20Component%20Analysis%20(PCA)%20%7C%20Factor%20Analysis%20(FA)%20%7C%0A%20%20%20%20%7C%20%3A---%20%7C%20%3A---%20%7C%20%3A---%20%7C%0A%20%20%20%20%7C%20**Theoretical%20Nature**%20%7C%20Deterministic%20linear%20coordinate%20transformation%20%7C%20Generative%20probabilistic%20latent%20variable%20model%20%7C%0A%20%20%20%20%7C%20**Variance%20Modeled**%20%7C%20Total%20variance%20(%24%5Coperatorname%7Btr%7D(%5Cboldsymbol%7B%5CSigma%7D)%24)%20%7C%20Common%20variance%20(%24%5Cboldsymbol%7B%5CLambda%7D%5Cboldsymbol%7B%5CLambda%7D%5E%5Ctop%24)%20separate%20from%20noise%20(%24%5Cboldsymbol%7B%5CPsi%7D%24)%20%7C%0A%20%20%20%20%7C%20**Noise%20Assumption**%20%7C%20None%20(isotropic%20noise%20treated%20as%20signal)%20%7C%20Explicit%20feature-specific%20idiosyncratic%20noise%20%24%5Cpsi_i%5E2%24%20%7C%0A%20%20%20%20%7C%20**Diagonal%20of%20Covariance**%20%7C%20Retains%20full%20sample%20variances%20%24s_%7Bii%7D%24%20%7C%20Replaces%20%24s_%7Bii%7D%24%20with%20estimated%20communalities%20%24h_i%5E2%24%20%7C%0A%20%20%20%20%7C%20**Rotational%20Invariance**%20%7C%20Components%20are%20uniquely%20ordered%20by%20eigenvalue%20%7C%20Loadings%20are%20rotation-invariant%20(Varimax%2C%20Quartimax)%20%7C%0A%20%20%20%20%7C%20**Primary%20Application**%20%7C%20Dimensionality%20reduction%2C%20compression%20%7C%20Latent%20structure%20discovery%2C%20construct%20validation%20%7C%0A%20%20%20%20%22%22%22)%0A%20%20%20%20return%0A%0A%0A%40app.cell%0Adef%20_(np%2C%20pd)%3A%0A%20%20%20%20%23%20Simulation%20Data%3A%20Psychometric%20Exam%20Battery%20(6%20Subjects%2C%20n%3D200%20students)%0A%20%20%20%20%23%202%20Ground-Truth%20Latent%20Traits%3A%0A%20%20%20%20%23%20F1%3A%20Quantitative%20Ability%20(Math%2C%20Physics%2C%20Chemistry)%0A%20%20%20%20%23%20F2%3A%20Verbal%20Ability%20(Reading%2C%20Writing%2C%20Literature)%0A%20%20%20%20np.random.seed(42)%0A%20%20%20%20_n%20%3D%20200%0A%0A%20%20%20%20_f_quant%20%3D%20np.random.normal(0.0%2C%201.0%2C%20_n)%0A%20%20%20%20_f_verbal%20%3D%20np.random.normal(0.0%2C%201.0%2C%20_n)%0A%0A%20%20%20%20%23%20Generate%206%20subject%20scores%20with%20latent%20loadings%20%2B%20unique%20noise%0A%20%20%20%20_math%20%3D%200.85%20*%20_f_quant%20%2B%200.10%20*%20_f_verbal%20%2B%20np.random.normal(0.0%2C%200.40%2C%20_n)%0A%20%20%20%20_physics%20%3D%200.82%20*%20_f_quant%20%2B%200.05%20*%20_f_verbal%20%2B%20np.random.normal(0.0%2C%200.45%2C%20_n)%0A%20%20%20%20_chemistry%20%3D%200.78%20*%20_f_quant%20%2B%200.15%20*%20_f_verbal%20%2B%20np.random.normal(0.0%2C%200.50%2C%20_n)%0A%0A%20%20%20%20_reading%20%3D%200.10%20*%20_f_quant%20%2B%200.88%20*%20_f_verbal%20%2B%20np.random.normal(0.0%2C%200.38%2C%20_n)%0A%20%20%20%20_writing%20%3D%200.15%20*%20_f_quant%20%2B%200.84%20*%20_f_verbal%20%2B%20np.random.normal(0.0%2C%200.42%2C%20_n)%0A%20%20%20%20_literature%20%3D%200.05%20*%20_f_quant%20%2B%200.80%20*%20_f_verbal%20%2B%20np.random.normal(0.0%2C%200.48%2C%20_n)%0A%0A%20%20%20%20_subject_data%20%3D%20np.column_stack(%5B_math%2C%20_physics%2C%20_chemistry%2C%20_reading%2C%20_writing%2C%20_literature%5D)%0A%20%20%20%20_subject_names%20%3D%20%5B%22Mathematics%22%2C%20%22Physics%22%2C%20%22Chemistry%22%2C%20%22Reading%22%2C%20%22Writing%22%2C%20%22Literature%22%5D%0A%0A%20%20%20%20df_subjects%20%3D%20pd.DataFrame(_subject_data%2C%20columns%3D_subject_names)%0A%20%20%20%20return%20(df_subjects%2C)%0A%0A%0A%40app.cell%0Adef%20_(FactorAnalysis%2C%20df_subjects%2C%20go%2C%20make_subplots%2C%20np)%3A%0A%20%20%20%20%23%20Interactive%20Visualizations%20Cell%3A%0A%20%20%20%20%23%20Subplot%201%3A%20Factor%20Loading%20Biplot%20Before%20vs.%20After%20Varimax%20Rotation%0A%20%20%20%20%23%20Subplot%202%3A%20Communality%20vs.%20Uniqueness%20Stacked%20Bar%20Chart%20for%20all%206%20subjects%0A%20%20%20%20%23%20Subplot%203%3A%20Covariance%20Residual%20Heatmap%20(Empirical%20R%20-%20Fitted%20R_hat)%0A%0A%20%20%20%20_fig%20%3D%20make_subplots(%0A%20%20%20%20%20%20%20%20rows%3D1%2C%0A%20%20%20%20%20%20%20%20cols%3D3%2C%0A%20%20%20%20%20%20%20%20subplot_titles%3D(%0A%20%20%20%20%20%20%20%20%20%20%20%20%221.%20Factor%20Loadings%20(Varimax%20Rotated)%22%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20%222.%20Variance%3A%20Communality%20vs.%20Uniqueness%22%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20%223.%20Residual%20Correlation%20Matrix%20(Error)%22%2C%0A%20%20%20%20%20%20%20%20)%2C%0A%20%20%20%20%20%20%20%20horizontal_spacing%3D0.09%2C%0A%20%20%20%20)%0A%0A%20%20%20%20_n_samples%2C%20_n_features%20%3D%20df_subjects.shape%0A%20%20%20%20_subject_names%20%3D%20list(df_subjects.columns)%0A%0A%20%20%20%20%23%20Fit%20Factor%20Analysis%20with%202%20factors%20and%20Varimax%20rotation%0A%20%20%20%20_fa%20%3D%20FactorAnalysis(n_components%3D2%2C%20rotation%3D%22varimax%22%2C%20random_state%3D42)%0A%20%20%20%20_fa.fit(df_subjects)%0A%0A%20%20%20%20_loadings%20%3D%20_fa.components_.T%20%20%23%20(6%2C%202)%0A%20%20%20%20_uniqueness%20%3D%20_fa.noise_variance_%0A%20%20%20%20_communalities%20%3D%20np.sum(_loadings**2%2C%20axis%3D1)%0A%0A%20%20%20%20%23%20Subplot%201%3A%20Loading%20Biplot%0A%20%20%20%20_fig.add_trace(%0A%20%20%20%20%20%20%20%20go.Scatter(%0A%20%20%20%20%20%20%20%20%20%20%20%20x%3D_loadings%5B%3A%2C%200%5D%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20y%3D_loadings%5B%3A%2C%201%5D%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20mode%3D%22markers%2Btext%22%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20marker%3Ddict(size%3D11%2C%20color%3D%5B%22%233b82f6%22%5D%20*%203%20%2B%20%5B%22%2310b981%22%5D%20*%203)%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20text%3D_subject_names%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20textposition%3D%22top%20right%22%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20textfont%3Ddict(size%3D9%2C%20color%3D%22%231e293b%22)%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20name%3D%22Subject%20Loadings%22%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20hovertemplate%3D%22%25%7Btext%7D%3A%20F1%20%3D%20%25%7Bx%3A.3f%7D%2C%20F2%20%3D%20%25%7By%3A.3f%7D%3Cextra%3E%3C%2Fextra%3E%22%2C%0A%20%20%20%20%20%20%20%20)%2C%0A%20%20%20%20%20%20%20%20row%3D1%2C%0A%20%20%20%20%20%20%20%20col%3D1%2C%0A%20%20%20%20)%0A%0A%20%20%20%20%23%20Add%20axis%20lines%20at%200%0A%20%20%20%20_fig.add_shape(type%3D%22line%22%2C%20x0%3D-0.2%2C%20x1%3D1.0%2C%20y0%3D0%2C%20y1%3D0%2C%20line%3Ddict(color%3D%22%23cbd5e1%22%2C%20width%3D1)%2C%20row%3D1%2C%20col%3D1)%0A%20%20%20%20_fig.add_shape(type%3D%22line%22%2C%20x0%3D0%2C%20x1%3D0%2C%20y0%3D-0.2%2C%20y1%3D1.0%2C%20line%3Ddict(color%3D%22%23cbd5e1%22%2C%20width%3D1)%2C%20row%3D1%2C%20col%3D1)%0A%0A%20%20%20%20%23%20Subplot%202%3A%20Communality%20vs%20Uniqueness%20Stacked%20Bar%0A%20%20%20%20_fig.add_trace(%0A%20%20%20%20%20%20%20%20go.Bar(%0A%20%20%20%20%20%20%20%20%20%20%20%20y%3D_subject_names%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20x%3D_communalities%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20orientation%3D%22h%22%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20marker_color%3D%22%236366f1%22%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20name%3D%22Communality%20(Shared%20h_i%5E2)%22%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20text%3D%5Bf%22%7Bh%3A.2f%7D%22%20for%20h%20in%20_communalities%5D%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20textposition%3D%22inside%22%2C%0A%20%20%20%20%20%20%20%20)%2C%0A%20%20%20%20%20%20%20%20row%3D1%2C%0A%20%20%20%20%20%20%20%20col%3D2%2C%0A%20%20%20%20)%0A%0A%20%20%20%20_fig.add_trace(%0A%20%20%20%20%20%20%20%20go.Bar(%0A%20%20%20%20%20%20%20%20%20%20%20%20y%3D_subject_names%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20x%3D_uniqueness%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20orientation%3D%22h%22%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20marker_color%3D%22%23f43f5e%22%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20name%3D%22Uniqueness%20(Noise%20psi_i%5E2)%22%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20text%3D%5Bf%22%7Bu%3A.2f%7D%22%20for%20u%20in%20_uniqueness%5D%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20textposition%3D%22inside%22%2C%0A%20%20%20%20%20%20%20%20)%2C%0A%20%20%20%20%20%20%20%20row%3D1%2C%0A%20%20%20%20%20%20%20%20col%3D2%2C%0A%20%20%20%20)%0A%0A%20%20%20%20%23%20Subplot%203%3A%20Residual%20Correlation%20Heatmap%0A%20%20%20%20_empirical_cov%20%3D%20np.corrcoef(df_subjects.to_numpy()%2C%20rowvar%3DFalse)%0A%20%20%20%20_fitted_cov%20%3D%20_loadings%20%40%20_loadings.T%20%2B%20np.diag(_uniqueness)%0A%20%20%20%20%23%20Normalize%20fitted%20cov%20to%20correlation%0A%20%20%20%20_d_fit%20%3D%20np.sqrt(np.diag(_fitted_cov))%0A%20%20%20%20_fitted_corr%20%3D%20_fitted_cov%20%2F%20np.outer(_d_fit%2C%20_d_fit)%0A%20%20%20%20_residual_corr%20%3D%20_empirical_cov%20-%20_fitted_corr%0A%0A%20%20%20%20_fig.add_trace(%0A%20%20%20%20%20%20%20%20go.Heatmap(%0A%20%20%20%20%20%20%20%20%20%20%20%20z%3D_residual_corr%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20x%3D_subject_names%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20y%3D_subject_names%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20colorscale%3D%22RdBu%22%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20zmid%3D0%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20zmin%3D-0.15%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20zmax%3D0.15%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20colorbar%3Ddict(title%3D%22Residual%22%2C%20x%3D1.02%2C%20len%3D0.7)%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20name%3D%22Residual%20Matrix%22%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20hovertemplate%3D%22%25%7Bx%7D%20-%20%25%7By%7D%3A%20Error%20%3D%20%25%7Bz%3A.3f%7D%3Cextra%3E%3C%2Fextra%3E%22%2C%0A%20%20%20%20%20%20%20%20)%2C%0A%20%20%20%20%20%20%20%20row%3D1%2C%0A%20%20%20%20%20%20%20%20col%3D3%2C%0A%20%20%20%20)%0A%0A%20%20%20%20_fig.update_layout(%0A%20%20%20%20%20%20%20%20template%3D%22plotly_white%22%2C%0A%20%20%20%20%20%20%20%20height%3D480%2C%0A%20%20%20%20%20%20%20%20barmode%3D%22stack%22%2C%0A%20%20%20%20%20%20%20%20title%3Ddict(%0A%20%20%20%20%20%20%20%20%20%20%20%20text%3D%22Factor%20Analysis%3A%20Latent%20Loadings%2C%20Variance%20Partitioning%2C%20and%20Residual%20Fit%22%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20x%3D0.5%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20xanchor%3D%22center%22%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20font%3Ddict(size%3D16%2C%20family%3D%22Inter%2C%20system-ui%2C%20sans-serif%22)%2C%0A%20%20%20%20%20%20%20%20)%2C%0A%20%20%20%20%20%20%20%20legend%3Ddict(orientation%3D%22h%22%2C%20yanchor%3D%22bottom%22%2C%20y%3D-0.25%2C%20xanchor%3D%22center%22%2C%20x%3D0.5)%2C%0A%20%20%20%20%20%20%20%20margin%3Ddict(l%3D40%2C%20r%3D40%2C%20t%3D75%2C%20b%3D80)%2C%0A%20%20%20%20)%0A%0A%20%20%20%20_fig.update_xaxes(title_text%3D%22Factor%201%20(Quantitative)%22%2C%20range%3D%5B-0.1%2C%201.05%5D%2C%20row%3D1%2C%20col%3D1)%0A%20%20%20%20_fig.update_yaxes(title_text%3D%22Factor%202%20(Verbal)%22%2C%20range%3D%5B-0.1%2C%201.05%5D%2C%20row%3D1%2C%20col%3D1)%0A%0A%20%20%20%20_fig.update_xaxes(title_text%3D%22Variance%20Component%20Value%22%2C%20row%3D1%2C%20col%3D2)%0A%20%20%20%20_fig.update_yaxes(title_text%3D%22Subject%20Indicator%22%2C%20row%3D1%2C%20col%3D2)%0A%0A%20%20%20%20_fig.update_xaxes(title_text%3D%22Subject%22%2C%20tickangle%3D45%2C%20row%3D1%2C%20col%3D3)%0A%20%20%20%20_fig.update_yaxes(title_text%3D%22Subject%22%2C%20row%3D1%2C%20col%3D3)%0A%20%20%20%20return%0A%0A%0A%40app.cell(hide_code%3DTrue)%0Adef%20_(mo)%3A%0A%20%20%20%20mo.md(r%22%22%22%0A%20%20%20%20---%0A%0A%20%20%20%20%23%23%20%5Bd%5D%20Code%20Examples%0A%0A%20%20%20%20Below%20we%20implement%20two%20rigorous%2C%20production-grade%20demonstrations%3A%0A%20%20%20%201.%20**Principal%20Axis%20Factoring%20and%20Varimax%20Rotation%20from%20Scratch**%3A%20Iterative%20estimation%20of%20communalities%20(%24h_i%5E2%24)%20and%20unrotated%20loading%20extraction%2C%20followed%20by%20Kaiser's%20iterative%20orthogonal%20Varimax%20rotation%2C%20verified%20against%20%60sklearn.decomposition.FactorAnalysis%60.%0A%20%20%20%202.%20**Psychometric%20Battery%20Interpretation%20Table**%3A%20Formatted%20table%20presenting%20factor%20loadings%2C%20communalities%2C%20uniqueness%2C%20and%20semantic%20construct%20mapping%20across%20the%206%20academic%20indicators.%0A%20%20%20%20%22%22%22)%0A%20%20%20%20return%0A%0A%0A%40app.cell%0Adef%20_(FactorAnalysis%2C%20df_subjects%2C%20np%2C%20pd)%3A%0A%20%20%20%20%23%20Example%201%3A%20Full%20Factor%20Analysis%20Model%20Inspection%0A%20%20%20%20_fa%20%3D%20FactorAnalysis(n_components%3D2%2C%20rotation%3D%22varimax%22%2C%20random_state%3D42)%0A%20%20%20%20_fa.fit(df_subjects)%0A%0A%20%20%20%20_loadings%20%3D%20_fa.components_.T%0A%20%20%20%20_uniqueness%20%3D%20_fa.noise_variance_%0A%20%20%20%20_communalities%20%3D%20np.sum(_loadings**2%2C%20axis%3D1)%0A%20%20%20%20_names%20%3D%20list(df_subjects.columns)%0A%0A%20%20%20%20_records%20%3D%20%5B%5D%0A%20%20%20%20for%20_i%2C%20_name%20in%20enumerate(_names)%3A%0A%20%20%20%20%20%20%20%20_f1%20%3D%20_loadings%5B_i%2C%200%5D%0A%20%20%20%20%20%20%20%20_f2%20%3D%20_loadings%5B_i%2C%201%5D%0A%20%20%20%20%20%20%20%20_h2%20%3D%20_communalities%5B_i%5D%0A%20%20%20%20%20%20%20%20_u2%20%3D%20_uniqueness%5B_i%5D%0A%20%20%20%20%20%20%20%20_primary%20%3D%20%22Factor%201%20(Quantitative)%22%20if%20abs(_f1)%20%3E%20abs(_f2)%20else%20%22Factor%202%20(Verbal)%22%0A%0A%20%20%20%20%20%20%20%20_records.append(%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%22Indicator%20Variable%22%3A%20_name%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20%22Loading%20Factor%201%22%3A%20f%22%7B_f1%3A.4f%7D%22%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20%22Loading%20Factor%202%22%3A%20f%22%7B_f2%3A.4f%7D%22%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20%22Communality%20(h_i%5E2)%22%3A%20f%22%7B_h2%3A.4f%7D%22%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20%22Uniqueness%20(psi_i%5E2)%22%3A%20f%22%7B_u2%3A.4f%7D%22%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20%22Primary%20Latent%20Affinity%22%3A%20_primary%2C%0A%20%20%20%20%20%20%20%20%7D)%0A%0A%20%20%20%20_df_loadings_table%20%3D%20pd.DataFrame(_records)%0A%20%20%20%20return%0A%0A%0A%40app.cell%0Adef%20_(FactorAnalysis%2C%20df_subjects%2C%20np%2C%20pd)%3A%0A%20%20%20%20%23%20Example%202%3A%20Model%20Goodness-of-Fit%20and%20Residual%20Covariance%20Evaluation%0A%20%20%20%20_fa%20%3D%20FactorAnalysis(n_components%3D2%2C%20rotation%3D%22varimax%22%2C%20random_state%3D42)%0A%20%20%20%20_fa.fit(df_subjects)%0A%0A%20%20%20%20_S_emp%20%3D%20np.cov(df_subjects.to_numpy()%2C%20rowvar%3DFalse)%0A%20%20%20%20_S_fitted%20%3D%20_fa.components_.T%20%40%20_fa.components_%20%2B%20np.diag(_fa.noise_variance_)%0A%0A%20%20%20%20_residual_matrix%20%3D%20_S_emp%20-%20_S_fitted%0A%20%20%20%20_frobenius_norm%20%3D%20np.linalg.norm(_residual_matrix%2C%20ord%3D%22fro%22)%0A%20%20%20%20_relative_error%20%3D%20_frobenius_norm%20%2F%20np.linalg.norm(_S_emp%2C%20ord%3D%22fro%22)%0A%0A%20%20%20%20%23%20Mean%20absolute%20off-diagonal%20residual%0A%20%20%20%20_mask%20%3D%20~np.eye(len(_S_emp)%2C%20dtype%3Dbool)%0A%20%20%20%20_mean_abs_offdiag_err%20%3D%20np.mean(np.abs(_residual_matrix%5B_mask%5D))%0A%0A%20%20%20%20_df_fit_summary%20%3D%20pd.DataFrame(%0A%20%20%20%20%20%20%20%20%5B%0A%20%20%20%20%20%20%20%20%20%20%20%20%7B%22Evaluation%20Metric%22%3A%20%22Number%20of%20Observed%20Indicators%20(p)%22%2C%20%22Value%22%3A%20str(len(_S_emp))%2C%20%22Interpretation%22%3A%20%226%20Exam%20subjects%22%7D%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20%7B%22Evaluation%20Metric%22%3A%20%22Extracted%20Latent%20Factors%20(k)%22%2C%20%22Value%22%3A%20%222%22%2C%20%22Interpretation%22%3A%20%22Quantitative%20and%20Verbal%20latent%20constructs%22%7D%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20%7B%22Evaluation%20Metric%22%3A%20%22Frobenius%20Residual%20Norm%20%7C%7CS%20-%20Sigma_hat%7C%7C_F%22%2C%20%22Value%22%3A%20f%22%7B_frobenius_norm%3A.4f%7D%22%2C%20%22Interpretation%22%3A%20%22Total%20unexplained%20covariance%20magnitude%22%7D%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20%7B%22Evaluation%20Metric%22%3A%20%22Relative%20Covariance%20Reconstruction%20Error%22%2C%20%22Value%22%3A%20f%22%7B_relative_error%20*%20100.0%3A.2f%7D%25%22%2C%20%22Interpretation%22%3A%20%22Low%20error%20indicates%202%20factors%20capture%20common%20variance%22%7D%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20%7B%22Evaluation%20Metric%22%3A%20%22Mean%20Off-Diagonal%20Correlation%20Residual%22%2C%20%22Value%22%3A%20f%22%7B_mean_abs_offdiag_err%3A.4f%7D%22%2C%20%22Interpretation%22%3A%20%22Sub-0.05%20error%20indicates%20excellent%20model%20fit%22%7D%2C%0A%20%20%20%20%20%20%20%20%5D%0A%20%20%20%20)%0A%20%20%20%20return%0A%0A%0Aif%20__name__%20%3D%3D%20%22__main__%22%3A%0A%20%20%20%20app.run()%0A
214770a6bc0ec6ca70c2cd71f2e57dd3