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%20warnings%0A%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%20scipy%20import%20stats%0A%20%20%20%20from%20sklearn.mixture%20import%20GaussianMixture%0A%0A%20%20%20%20warnings.filterwarnings(%22ignore%22)%0A%20%20%20%20return%20GaussianMixture%2C%20go%2C%20make_subplots%2C%20mo%2C%20np%2C%20pd%2C%20stats%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%2031%3A%20Gaussian%20Mixture%20Models%2C%20Expectation-Maximization%2C%20and%20Probabilistic%20Anomaly%20Detection%0A%0A%20%20%20%20%26larr%3B%20Previous%20Note%3A%20%5B30%20Correspondence%20Analysis%5D(30_correspondence_analysis.py)%20%7C%20Next%20Note%3A%20%5B32%20Elastic%20Net%5D(32_elastic_net.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%20%24K%24-Means%20clustering%20is%20widely%20used%20for%20partitioning%20datasets%2C%20it%20enforces%20two%20restrictive%20assumptions%3A%0A%20%20%20%201.%20**Spherical%20Geometry**%3A%20It%20assumes%20all%20clusters%20are%20isotropic%20spheres%20with%20identical%20variance.%0A%20%20%20%202.%20**Hard%20Assignment**%3A%20Every%20observation%20is%20deterministically%20assigned%20to%20exactly%20one%20centroid%20(%24r_%7Bik%7D%20%5Cin%20%5C%7B0%2C%201%5C%7D%24)%2C%20ignoring%20classification%20uncertainty%20at%20cluster%20boundaries.%0A%0A%20%20%20%20**Gaussian%20Mixture%20Models%20(GMMs)**%20resolve%20these%20limitations%20by%20formulating%20clustering%20as%20density%20estimation%20within%20a%20rigorous%20probabilistic%20generative%20framework%3A%0A%20%20%20%201.%20**Soft%20Probabilistic%20Responsibilities**%3A%20Rather%20than%20forcing%20a%20hard%20binary%20assignment%2C%20GMMs%20compute%20posterior%20probabilities%20%24%5Cgamma_%7Bik%7D%20%3D%20P(Z_i%20%3D%20k%20%5Cmid%20%5Cmathbf%7Bx%7D_i)%20%5Cin%20%5B0%2C%201%5D%24%2C%20quantifying%20classification%20confidence%20and%20capturing%20ambiguous%20overlap%20regions.%0A%20%20%20%202.%20**Arbitrary%20Elliptical%20Geometry**%3A%20By%20parameterizing%20each%20cluster%20with%20its%20own%20full%20covariance%20matrix%20%24%5Cboldsymbol%7B%5CSigma%7D_k%24%2C%20GMMs%20naturally%20capture%20elongated%2C%20rotated%2C%20and%20differently%20scaled%20cluster%20shapes.%0A%20%20%20%203.%20**Universal%20Density%20Approximator**%3A%20According%20to%20the%20Stone-Weierstrass%20theorem%2C%20any%20smooth%20continuous%20probability%20density%20function%20can%20be%20approximated%20to%20arbitrary%20precision%20by%20a%20finite%20mixture%20of%20Gaussians.%0A%20%20%20%204.%20**Principled%20Anomaly%20and%20Outlier%20Detection**%3A%20By%20evaluating%20the%20exact%20marginal%20log-likelihood%20%24%5Cln%20p(%5Cmathbf%7Bx%7D)%24%2C%20GMMs%20assign%20continuous%20anomaly%20scores%20to%20unseen%20points.%20Observations%20falling%20into%20low-density%20regions%20(%24%5Cln%20p(%5Cmathbf%7Bx%7D)%20%3C%20%5Ctau%24)%20are%20flagged%20as%20out-of-distribution%20(OOD)%20without%20arbitrary%20distance%20heuristics.%0A%20%20%20%205.%20**The%20Expectation-Maximization%20(EM)%20Engine**%3A%20GMMs%20serve%20as%20the%20canonical%20vehicle%20for%20understanding%20the%20EM%20algorithm%2C%20the%20foundational%20optimization%20paradigm%20for%20latent%20variable%20modeling%20across%20deep%20learning%20and%20statistical%20inference.%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.%20Generative%20Probability%20Density%20Model%0A%0A%20%20%20%20A%20Gaussian%20Mixture%20Model%20models%20the%20probability%20density%20of%20a%20%24d%24-dimensional%20random%20vector%20%24%5Cmathbf%7Bx%7D%20%5Cin%20%5Cmathbb%7BR%7D%5Ed%24%20as%20a%20convex%20combination%20of%20%24K%24%20multivariate%20Gaussian%20components%3A%0A%0A%20%20%20%20%24%24%0A%20%20%20%20p(%5Cmathbf%7Bx%7D%20%5Cmid%20%5Cboldsymbol%7B%5Ctheta%7D)%20%3D%20%5Csum_%7Bk%3D1%7D%5EK%20%5Cpi_k%20%5C%2C%20%5Cmathcal%7BN%7D%5Cleft(%5Cmathbf%7Bx%7D%20%5Cmid%20%5Cboldsymbol%7B%5Cmu%7D_k%2C%20%5Cboldsymbol%7B%5CSigma%7D_k%5Cright)%0A%20%20%20%20%24%24%0A%0A%20%20%20%20where%3A%0A%20%20%20%20-%20%24%5Cpi_k%20%3D%20P(Z%20%3D%20k)%24%20are%20the%20**mixing%20coefficients**%20(prior%20probabilities)%2C%20satisfying%3A%0A%0A%20%20%20%20%24%24%0A%20%20%20%20%5Cpi_k%20%5Cgeq%200%20%5Cquad%20%5Ctext%7Band%7D%20%5Cquad%20%5Csum_%7Bk%3D1%7D%5EK%20%5Cpi_k%20%3D%201%0A%20%20%20%20%24%24%0A%0A%20%20%20%20-%20%24%5Cboldsymbol%7B%5Cmu%7D_k%20%5Cin%20%5Cmathbb%7BR%7D%5Ed%24%20is%20the%20mean%20vector%20of%20component%20%24k%24.%0A%20%20%20%20-%20%24%5Cboldsymbol%7B%5CSigma%7D_k%20%5Cin%20%5Cmathbb%7BR%7D%5E%7Bd%20%5Ctimes%20d%7D%24%20is%20the%20symmetric%20positive-definite%20covariance%20matrix%20of%20component%20%24k%24.%0A%20%20%20%20-%20The%20multivariate%20Gaussian%20density%20function%20is%3A%0A%0A%20%20%20%20%24%24%0A%20%20%20%20%5Cmathcal%7BN%7D(%5Cmathbf%7Bx%7D%20%5Cmid%20%5Cboldsymbol%7B%5Cmu%7D_k%2C%20%5Cboldsymbol%7B%5CSigma%7D_k)%20%3D%20%5Cfrac%7B1%7D%7B(2%5Cpi)%5E%7Bd%2F2%7D%20%7C%5Cboldsymbol%7B%5CSigma%7D_k%7C%5E%7B1%2F2%7D%7D%20%5Cexp%5Cleft(-%5Cfrac%7B1%7D%7B2%7D(%5Cmathbf%7Bx%7D%20-%20%5Cboldsymbol%7B%5Cmu%7D_k)%5E%5Ctop%20%5Cboldsymbol%7B%5CSigma%7D_k%5E%7B-1%7D(%5Cmathbf%7Bx%7D%20-%20%5Cboldsymbol%7B%5Cmu%7D_k)%5Cright)%0A%20%20%20%20%24%24%0A%0A%20%20%20%20---%0A%0A%20%20%20%20%23%23%23%202.%20The%20Log-Likelihood%20and%20Latent%20Variables%0A%0A%20%20%20%20For%20an%20independent%20dataset%20%24%5Cmathbf%7BX%7D%20%3D%20%5C%7B%5Cmathbf%7Bx%7D_1%2C%20%5Cdots%2C%20%5Cmathbf%7Bx%7D_n%5C%7D%24%2C%20the%20log-likelihood%20function%20is%3A%0A%0A%20%20%20%20%24%24%0A%20%20%20%20%5Cln%20p(%5Cmathbf%7BX%7D%20%5Cmid%20%5Cboldsymbol%7B%5Ctheta%7D)%20%3D%20%5Csum_%7Bi%3D1%7D%5En%20%5Cln%20%5Cleft(%20%5Csum_%7Bk%3D1%7D%5EK%20%5Cpi_k%20%5C%2C%20%5Cmathcal%7BN%7D(%5Cmathbf%7Bx%7D_i%20%5Cmid%20%5Cboldsymbol%7B%5Cmu%7D_k%2C%20%5Cboldsymbol%7B%5CSigma%7D_k)%20%5Cright)%0A%20%20%20%20%24%24%0A%0A%20%20%20%20Direct%20maximization%20via%20gradient%20descent%20is%20complicated%20by%20the%20summation%20residing%20inside%20the%20logarithm.%20To%20solve%20this%2C%20we%20introduce%20a%20latent%20indicator%20vector%20%24%5Cmathbf%7Bz%7D_i%20%5Cin%20%5C%7B0%2C%201%5C%7D%5EK%24%20for%20each%20observation%2C%20where%20%24z_%7Bik%7D%20%3D%201%24%20if%20observation%20%24i%24%20was%20generated%20by%20component%20%24k%24%2C%20and%20%240%24%20otherwise.%0A%0A%20%20%20%20---%0A%0A%20%20%20%20%23%23%23%203.%20The%20Expectation-Maximization%20(EM)%20Algorithm%0A%0A%20%20%20%20The%20EM%20algorithm%20iteratively%20alternates%20between%20two%20steps%3A%0A%0A%20%20%20%20%23%23%23%23%20E-Step%20(Expectation)%3A%20Evaluate%20Posterior%20Responsibilities%0A%20%20%20%20Using%20Bayes'%20rule%2C%20calculate%20the%20posterior%20probability%20%24%5Cgamma_%7Bik%7D%24%20that%20component%20%24k%24%20generated%20observation%20%24%5Cmathbf%7Bx%7D_i%24%3A%0A%0A%20%20%20%20%24%24%0A%20%20%20%20%5Cgamma_%7Bik%7D%20%3D%20%5Cmathbb%7BE%7D%5Bz_%7Bik%7D%20%5Cmid%20%5Cmathbf%7Bx%7D_i%2C%20%5Cboldsymbol%7B%5Ctheta%7D%5E%7B(t)%7D%5D%20%3D%20%5Cfrac%7B%5Cpi_k%5E%7B(t)%7D%20%5C%2C%20%5Cmathcal%7BN%7D(%5Cmathbf%7Bx%7D_i%20%5Cmid%20%5Cboldsymbol%7B%5Cmu%7D_k%5E%7B(t)%7D%2C%20%5Cboldsymbol%7B%5CSigma%7D_k%5E%7B(t)%7D)%7D%7B%5Csum_%7Bj%3D1%7D%5EK%20%5Cpi_j%5E%7B(t)%7D%20%5C%2C%20%5Cmathcal%7BN%7D(%5Cmathbf%7Bx%7D_i%20%5Cmid%20%5Cboldsymbol%7B%5Cmu%7D_j%5E%7B(t)%7D%2C%20%5Cboldsymbol%7B%5CSigma%7D_j%5E%7B(t)%7D)%7D%0A%20%20%20%20%24%24%0A%0A%20%20%20%20The%20effective%20number%20of%20data%20points%20assigned%20to%20component%20%24k%24%20is%3A%0A%0A%20%20%20%20%24%24%0A%20%20%20%20N_k%20%3D%20%5Csum_%7Bi%3D1%7D%5En%20%5Cgamma_%7Bik%7D%0A%20%20%20%20%24%24%0A%0A%20%20%20%20%23%23%23%23%20M-Step%20(Maximization)%3A%20Re-estimate%20Parameters%20in%20Closed%20Form%0A%20%20%20%20Maximize%20the%20expected%20complete-data%20log-likelihood%20(the%20%24Q%24-function)%20with%20respect%20to%20parameters%3A%0A%0A%20%20%20%20%24%24%0A%20%20%20%20%5Cboldsymbol%7B%5Cmu%7D_k%5E%7B(t%2B1)%7D%20%3D%20%5Cfrac%7B1%7D%7BN_k%7D%20%5Csum_%7Bi%3D1%7D%5En%20%5Cgamma_%7Bik%7D%20%5Cmathbf%7Bx%7D_i%0A%20%20%20%20%24%24%0A%0A%20%20%20%20%24%24%0A%20%20%20%20%5Cboldsymbol%7B%5CSigma%7D_k%5E%7B(t%2B1)%7D%20%3D%20%5Cfrac%7B1%7D%7BN_k%7D%20%5Csum_%7Bi%3D1%7D%5En%20%5Cgamma_%7Bik%7D%20%5Cleft(%5Cmathbf%7Bx%7D_i%20-%20%5Cboldsymbol%7B%5Cmu%7D_k%5E%7B(t%2B1)%7D%5Cright)%5Cleft(%5Cmathbf%7Bx%7D_i%20-%20%5Cboldsymbol%7B%5Cmu%7D_k%5E%7B(t%2B1)%7D%5Cright)%5E%5Ctop%0A%20%20%20%20%24%24%0A%0A%20%20%20%20%24%24%0A%20%20%20%20%5Cpi_k%5E%7B(t%2B1)%7D%20%3D%20%5Cfrac%7BN_k%7D%7Bn%7D%0A%20%20%20%20%24%24%0A%0A%20%20%20%20%23%23%23%23%20Monotonic%20Convergence%20Guarantee%3A%0A%20%20%20%20By%20Jensen's%20inequality%2C%20the%20log-likelihood%20is%20monotonically%20non-decreasing%20at%20every%20iteration%3A%0A%0A%20%20%20%20%24%24%0A%20%20%20%20%5Cln%20p(%5Cmathbf%7BX%7D%20%5Cmid%20%5Cboldsymbol%7B%5Ctheta%7D%5E%7B(t%2B1)%7D)%20%5Cgeq%20%5Cln%20p(%5Cmathbf%7BX%7D%20%5Cmid%20%5Cboldsymbol%7B%5Ctheta%7D%5E%7B(t)%7D)%0A%20%20%20%20%24%24%0A%0A%20%20%20%20---%0A%0A%20%20%20%20%23%23%23%204.%20Anomaly%20Detection%20via%20Density%20Scoring%0A%0A%20%20%20%20Once%20the%20GMM%20parameters%20%24%5Chat%7B%5Cboldsymbol%7B%5Ctheta%7D%7D%24%20have%20been%20fitted%2C%20the%20model%20defines%20an%20exact%20probability%20density%20over%20the%20input%20space%3A%0A%0A%20%20%20%20%24%24%0A%20%20%20%20%5Ctext%7Bscore%7D(%5Cmathbf%7Bx%7D)%20%3D%20%5Cln%20p(%5Cmathbf%7Bx%7D)%20%3D%20%5Cln%20%5Cleft(%5Csum_%7Bk%3D1%7D%5EK%20%5Chat%7B%5Cpi%7D_k%20%5Cmathcal%7BN%7D(%5Cmathbf%7Bx%7D%20%5Cmid%20%5Chat%7B%5Cboldsymbol%7B%5Cmu%7D%7D_k%2C%20%5Chat%7B%5Cboldsymbol%7B%5CSigma%7D%7D_k)%5Cright)%0A%20%20%20%20%24%24%0A%0A%20%20%20%20An%20observation%20%24%5Cmathbf%7Bx%7D_%7B%5Ctext%7Bnew%7D%7D%24%20is%20classified%20as%20an%20anomaly%20if%20its%20log-likelihood%20falls%20below%20a%20threshold%20%24%5Ctau%24%3A%0A%0A%20%20%20%20%24%24%0A%20%20%20%20%5Ctext%7BAnomaly%7D(%5Cmathbf%7Bx%7D_%7B%5Ctext%7Bnew%7D%7D)%20%3D%20%5Cmathbb%7BI%7D%5Cleft(%5Cln%20p(%5Cmathbf%7Bx%7D_%7B%5Ctext%7Bnew%7D%7D)%20%3C%20%5Ctau%5Cright)%0A%20%20%20%20%24%24%0A%0A%20%20%20%20The%20threshold%20%24%5Ctau%24%20is%20typically%20chosen%20as%20an%20empirical%20quantile%20(e.g.%201st%20or%205th%20percentile)%20on%20calibration%20data.%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%203%20Distinct%20Gaussian%20Clusters%20%2B%20Uniform%20Noise%20Outliers%0A%20%20%20%20np.random.seed(47)%0A%20%20%20%20_n_per_cluster%20%3D%20300%0A%0A%20%20%20%20%23%20Cluster%201%3A%20Centered%20at%20(-4%2C%204)%20with%20diagonal%20covariance%0A%20%20%20%20_c1%20%3D%20np.random.multivariate_normal(%5B-4.0%2C%204.0%5D%2C%20%5B%5B1.5%2C%200.4%5D%2C%20%5B0.4%2C%201.2%5D%5D%2C%20size%3D_n_per_cluster)%0A%20%20%20%20%23%20Cluster%202%3A%20Centered%20at%20(4%2C%204)%20with%20tilted%20covariance%0A%20%20%20%20_c2%20%3D%20np.random.multivariate_normal(%5B4.0%2C%204.0%5D%2C%20%5B%5B2.0%2C%20-1.2%5D%2C%20%5B-1.2%2C%201.8%5D%5D%2C%20size%3D_n_per_cluster)%0A%20%20%20%20%23%20Cluster%203%3A%20Centered%20at%20(0%2C%20-3)%20with%20horizontal%20dispersion%0A%20%20%20%20_c3%20%3D%20np.random.multivariate_normal(%5B0.0%2C%20-3.0%5D%2C%20%5B%5B3.0%2C%200.2%5D%2C%20%5B0.2%2C%200.8%5D%5D%2C%20size%3D_n_per_cluster)%0A%0A%20%20%20%20_inliers%20%3D%20np.vstack(%5B_c1%2C%20_c2%2C%20_c3%5D)%0A%20%20%20%20_inlier_labels%20%3D%20np.array(%5B0%5D%20*%20_n_per_cluster%20%2B%20%5B1%5D%20*%20_n_per_cluster%20%2B%20%5B2%5D%20*%20_n_per_cluster)%0A%0A%20%20%20%20%23%20Incur%2045%20uniform%20spatial%20outliers%0A%20%20%20%20_n_outliers%20%3D%2045%0A%20%20%20%20_outliers%20%3D%20np.random.uniform(low%3D-9.0%2C%20high%3D9.0%2C%20size%3D(_n_outliers%2C%202))%0A%20%20%20%20%23%20Filter%20out%20outliers%20that%20accidentally%20land%20directly%20inside%20a%20cluster%20center%0A%20%20%20%20_mask_far%20%3D%20np.min(np.linalg.norm(_outliers%5B%3A%2C%20None%5D%20-%20np.array(%5B%5B-4.0%2C%204.0%5D%2C%20%5B4.0%2C%204.0%5D%2C%20%5B0.0%2C%20-3.0%5D%5D)%2C%20axis%3D2)%2C%20axis%3D1)%20%3E%202.5%0A%20%20%20%20_outliers%20%3D%20_outliers%5B_mask_far%5D%0A%20%20%20%20_n_outliers_clean%20%3D%20len(_outliers)%0A%0A%20%20%20%20all_samples%20%3D%20np.vstack(%5B_inliers%2C%20_outliers%5D)%0A%20%20%20%20ground_truth_anomaly%20%3D%20np.array(%5B0%5D%20*%20len(_inliers)%20%2B%20%5B1%5D%20*%20_n_outliers_clean)%0A%0A%20%20%20%20df_gmm_sim%20%3D%20pd.DataFrame(all_samples%2C%20columns%3D%5B%22Feature_1%22%2C%20%22Feature_2%22%5D)%0A%20%20%20%20df_gmm_sim%5B%22Is_Outlier%22%5D%20%3D%20ground_truth_anomaly%0A%20%20%20%20return%20all_samples%2C%20df_gmm_sim%2C%20ground_truth_anomaly%0A%0A%0A%40app.cell%0Adef%20_(GaussianMixture%2C%20all_samples%2C%20df_gmm_sim%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%20GMM%20Fitted%20Components%20with%202-Sigma%20Confidence%20Ellipses%20%2B%20Scatter%0A%20%20%20%20%23%20Subplot%202%3A%20Continuous%20Log-Likelihood%20Density%20Landscape%20(Contour%20Map)%0A%20%20%20%20%23%20Subplot%203%3A%20EM%20Algorithm%20Log-Likelihood%20Convergence%20Curve%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.%20GMM%20Components%20(2-Sigma%20Ellipsoids)%22%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20%222.%20Log-Likelihood%20Landscape%20%26%20Outliers%22%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20%223.%20EM%20Log-Likelihood%20Convergence%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%23%20Fit%20Scikit-Learn%20GMM%20with%203%20components%0A%20%20%20%20_gmm%20%3D%20GaussianMixture(n_components%3D3%2C%20covariance_type%3D%22full%22%2C%20max_iter%3D100%2C%20random_state%3D42)%0A%20%20%20%20_gmm.fit(all_samples)%0A%0A%20%20%20%20_means%20%3D%20_gmm.means_%0A%20%20%20%20_covs%20%3D%20_gmm.covariances_%0A%20%20%20%20_weights%20%3D%20_gmm.weights_%0A%20%20%20%20_scores%20%3D%20_gmm.score_samples(all_samples)%0A%0A%20%20%20%20%23%20Subplot%201%3A%20Scatter%20%2B%20Ellipses%0A%20%20%20%20_inliers%20%3D%20df_gmm_sim%5Bdf_gmm_sim%5B%22Is_Outlier%22%5D%20%3D%3D%200%5D%0A%20%20%20%20_outliers%20%3D%20df_gmm_sim%5Bdf_gmm_sim%5B%22Is_Outlier%22%5D%20%3D%3D%201%5D%0A%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_inliers%5B%22Feature_1%22%5D%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20y%3D_inliers%5B%22Feature_2%22%5D%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20mode%3D%22markers%22%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20marker%3Ddict(size%3D5%2C%20color%3D%22%2364748b%22%2C%20opacity%3D0.6)%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20name%3D%22Normal%20Observations%22%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20hovertemplate%3D%22F1%3A%20%25%7Bx%3A.2f%7D%3Cbr%3EF2%3A%20%25%7By%3A.2f%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_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_outliers%5B%22Feature_1%22%5D%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20y%3D_outliers%5B%22Feature_2%22%5D%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20mode%3D%22markers%22%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20marker%3Ddict(size%3D8%2C%20symbol%3D%22x%22%2C%20color%3D%22%23ef4444%22)%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20name%3D%22Ground-Truth%20Outliers%22%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20hovertemplate%3D%22Outlier%3A%20(%25%7Bx%3A.2f%7D%2C%20%25%7By%3A.2f%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%20Draw%202-Sigma%20Ellipses%20for%20each%20Gaussian%20component%0A%20%20%20%20_colors_comp%20%3D%20%5B%22%233b82f6%22%2C%20%22%2310b981%22%2C%20%22%23f59e0b%22%5D%0A%20%20%20%20for%20_k%20in%20range(3)%3A%0A%20%20%20%20%20%20%20%20_evals%2C%20_evecs%20%3D%20np.linalg.eigh(_covs%5B_k%5D)%0A%20%20%20%20%20%20%20%20_order%20%3D%20_evals.argsort()%5B%3A%3A-1%5D%0A%20%20%20%20%20%20%20%20_evals%2C%20_evecs%20%3D%20_evals%5B_order%5D%2C%20_evecs%5B%3A%2C%20_order%5D%0A%20%20%20%20%20%20%20%20_theta%20%3D%20np.linspace(0%2C%202%20*%20np.pi%2C%2050)%0A%20%20%20%20%20%20%20%20%23%202-sigma%20radius%20for%20chi2%20df%3D2%20(95.4%25%20coverage)%20is%20~2.447%0A%20%20%20%20%20%20%20%20_circle%20%3D%20np.column_stack(%5Bnp.cos(_theta)%2C%20np.sin(_theta)%5D)%0A%20%20%20%20%20%20%20%20_ellipse%20%3D%20_circle%20%40%20np.diag(2.0%20*%20np.sqrt(_evals))%20%40%20_evecs.T%20%2B%20_means%5B_k%5D%0A%0A%20%20%20%20%20%20%20%20_fig.add_trace(%0A%20%20%20%20%20%20%20%20%20%20%20%20go.Scatter(%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20x%3D_ellipse%5B%3A%2C%200%5D%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20y%3D_ellipse%5B%3A%2C%201%5D%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20mode%3D%22lines%22%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20line%3Ddict(color%3D_colors_comp%5B_k%5D%2C%20width%3D2.5)%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20name%3Df%22Comp%20%7B_k%2B1%7D%20(w%3D%7B_weights%5B_k%5D%3A.2f%7D)%22%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20)%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20row%3D1%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20col%3D1%2C%0A%20%20%20%20%20%20%20%20)%0A%0A%20%20%20%20%23%20Subplot%202%3A%20Density%20Contour%20Grid%0A%20%20%20%20_grid_x%20%3D%20np.linspace(-9.0%2C%209.0%2C%2060)%0A%20%20%20%20_grid_y%20%3D%20np.linspace(-9.0%2C%209.0%2C%2060)%0A%20%20%20%20_XX%2C%20_YY%20%3D%20np.meshgrid(_grid_x%2C%20_grid_y)%0A%20%20%20%20_grid_pts%20%3D%20np.column_stack(%5B_XX.ravel()%2C%20_YY.ravel()%5D)%0A%20%20%20%20_log_dens%20%3D%20_gmm.score_samples(_grid_pts).reshape(_XX.shape)%0A%0A%20%20%20%20_fig.add_trace(%0A%20%20%20%20%20%20%20%20go.Contour(%0A%20%20%20%20%20%20%20%20%20%20%20%20x%3D_grid_x%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20y%3D_grid_y%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20z%3D_log_dens%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20colorscale%3D%22Viridis%22%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20ncontours%3D20%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20colorbar%3Ddict(title%3D%22ln%20p(x)%22%2C%20x%3D0.64%2C%20len%3D0.7)%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20name%3D%22Log-Likelihood%22%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20showscale%3DTrue%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.Scatter(%0A%20%20%20%20%20%20%20%20%20%20%20%20x%3D_outliers%5B%22Feature_1%22%5D%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20y%3D_outliers%5B%22Feature_2%22%5D%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20mode%3D%22markers%22%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20marker%3Ddict(size%3D7%2C%20symbol%3D%22x%22%2C%20color%3D%22%23ffffff%22%2C%20line%3Ddict(width%3D1.5%2C%20color%3D%22%23ef4444%22))%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20name%3D%22Outlier%20Points%22%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20showlegend%3DFalse%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%20EM%20Convergence%20Tracking%0A%20%20%20%20%23%20Perform%20manual%20iterations%20to%20track%20exact%20log-likelihood%20curve%0A%20%20%20%20_iter_ll%20%3D%20%5B%5D%0A%20%20%20%20_running_gmm%20%3D%20GaussianMixture(n_components%3D3%2C%20covariance_type%3D%22full%22%2C%20warm_start%3DTrue%2C%20random_state%3D42)%0A%20%20%20%20for%20_it%20in%20range(1%2C%2016)%3A%0A%20%20%20%20%20%20%20%20_running_gmm.max_iter%20%3D%20_it%0A%20%20%20%20%20%20%20%20_running_gmm.fit(all_samples)%0A%20%20%20%20%20%20%20%20_iter_ll.append(_running_gmm.score(all_samples)%20*%20len(all_samples))%0A%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%3Dnp.arange(1%2C%20len(_iter_ll)%20%2B%201)%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20y%3D_iter_ll%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20mode%3D%22lines%2Bmarkers%22%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20line%3Ddict(color%3D%22%2310b981%22%2C%20width%3D2.5)%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20marker%3Ddict(size%3D6)%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20name%3D%22Total%20Log-Likelihood%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%20title%3Ddict(%0A%20%20%20%20%20%20%20%20%20%20%20%20text%3D%22Gaussian%20Mixture%20Models%3A%20Covariance%20Geometry%2C%20Log-Likelihood%2C%20and%20EM%20Convergence%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%22Feature%201%22%2C%20range%3D%5B-9%2C%209%5D%2C%20row%3D1%2C%20col%3D1)%0A%20%20%20%20_fig.update_yaxes(title_text%3D%22Feature%202%22%2C%20range%3D%5B-9%2C%209%5D%2C%20row%3D1%2C%20col%3D1)%0A%0A%20%20%20%20_fig.update_xaxes(title_text%3D%22Feature%201%22%2C%20range%3D%5B-9%2C%209%5D%2C%20row%3D1%2C%20col%3D2)%0A%20%20%20%20_fig.update_yaxes(title_text%3D%22Feature%202%22%2C%20range%3D%5B-9%2C%209%5D%2C%20row%3D1%2C%20col%3D2)%0A%0A%20%20%20%20_fig.update_xaxes(title_text%3D%22EM%20Iteration%20Number%22%2C%20row%3D1%2C%20col%3D3)%0A%20%20%20%20_fig.update_yaxes(title_text%3D%22Total%20Log-Likelihood%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%20end-to-end%20production%20algorithmic%20workflows%3A%0A%20%20%20%201.%20**Full%20EM%20Algorithm%20Implementation%20from%20Scratch**%3A%20Vectorized%20pure%20NumPy%20implementation%20of%20the%20E-step%2C%20M-step%2C%20and%20log-likelihood%20convergence%20monitoring%2C%20verified%20directly%20against%20%60sklearn.mixture.GaussianMixture%60.%0A%20%20%20%202.%20**Probabilistic%20Anomaly%20Detection%20%26%20Precision-Recall%20Diagnostic**%3A%20Setting%20an%20empirical%20log-likelihood%20density%20threshold%20%24%5Ctau%24%20to%20identify%20anomalies%2C%20reporting%20confusion%20matrix%2C%20precision%2C%20recall%2C%20and%20detection%20accuracy.%0A%20%20%20%20%22%22%22)%0A%20%20%20%20return%0A%0A%0A%40app.cell%0Adef%20_(GaussianMixture%2C%20all_samples%2C%20np%2C%20pd%2C%20stats)%3A%0A%20%20%20%20%23%20Example%201%3A%20Full%20EM%20Algorithm%20from%20Scratch%20in%20Pure%20NumPy%0A%20%20%20%20_X%20%3D%20all_samples%0A%20%20%20%20_n%2C%20_d%20%3D%20_X.shape%0A%20%20%20%20_K%20%3D%203%0A%20%20%20%20_max_iter%20%3D%2020%0A%0A%20%20%20%20%23%201.%20Initialize%20parameters%0A%20%20%20%20np.random.seed(42)%0A%20%20%20%20_pi%20%3D%20np.ones(_K)%20%2F%20_K%0A%20%20%20%20_random_indices%20%3D%20np.random.choice(_n%2C%20_K%2C%20replace%3DFalse)%0A%20%20%20%20_mu%20%3D%20_X%5B_random_indices%5D.copy()%0A%20%20%20%20_sigma%20%3D%20np.array(%5Bnp.cov(_X%2C%20rowvar%3DFalse)%20for%20_%20in%20range(_K)%5D)%0A%0A%20%20%20%20_log_likelihood_history%20%3D%20%5B%5D%0A%0A%20%20%20%20for%20_step%20in%20range(_max_iter)%3A%0A%20%20%20%20%20%20%20%20%23%20E-Step%3A%20Compute%20responsibilities%0A%20%20%20%20%20%20%20%20_gamma_unnorm%20%3D%20np.zeros((_n%2C%20_K))%0A%20%20%20%20%20%20%20%20for%20_k%20in%20range(_K)%3A%0A%20%20%20%20%20%20%20%20%20%20%20%20_gamma_unnorm%5B%3A%2C%20_k%5D%20%3D%20_pi%5B_k%5D%20*%20stats.multivariate_normal.pdf(_X%2C%20mean%3D_mu%5B_k%5D%2C%20cov%3D_sigma%5B_k%5D)%0A%0A%20%20%20%20%20%20%20%20_evidence%20%3D%20np.sum(_gamma_unnorm%2C%20axis%3D1%2C%20keepdims%3DTrue)%0A%20%20%20%20%20%20%20%20_gamma%20%3D%20_gamma_unnorm%20%2F%20_evidence%0A%0A%20%20%20%20%20%20%20%20_ll%20%3D%20np.sum(np.log(_evidence))%0A%20%20%20%20%20%20%20%20_log_likelihood_history.append(_ll)%0A%0A%20%20%20%20%20%20%20%20%23%20M-Step%3A%20Re-estimate%20parameters%0A%20%20%20%20%20%20%20%20_Nk%20%3D%20np.sum(_gamma%2C%20axis%3D0)%0A%20%20%20%20%20%20%20%20_pi%20%3D%20_Nk%20%2F%20_n%0A%0A%20%20%20%20%20%20%20%20for%20_k%20in%20range(_K)%3A%0A%20%20%20%20%20%20%20%20%20%20%20%20_mu%5B_k%5D%20%3D%20np.sum(_gamma%5B%3A%2C%20_k%20%3A%20_k%20%2B%201%5D%20*%20_X%2C%20axis%3D0)%20%2F%20_Nk%5B_k%5D%0A%20%20%20%20%20%20%20%20%20%20%20%20_diff%20%3D%20_X%20-%20_mu%5B_k%5D%0A%20%20%20%20%20%20%20%20%20%20%20%20_sigma%5B_k%5D%20%3D%20(_diff.T%20%40%20(_gamma%5B%3A%2C%20_k%20%3A%20_k%20%2B%201%5D%20*%20_diff))%20%2F%20_Nk%5B_k%5D%0A%20%20%20%20%20%20%20%20%20%20%20%20%23%20Add%20small%20ridge%20regularization%20for%20numerical%20stability%0A%20%20%20%20%20%20%20%20%20%20%20%20_sigma%5B_k%5D%20%2B%3D%201e-6%20*%20np.eye(_d)%0A%0A%20%20%20%20%23%20Scikit-Learn%20Reference%0A%20%20%20%20_gmm_sk%20%3D%20GaussianMixture(n_components%3D_K%2C%20covariance_type%3D%22full%22%2C%20max_iter%3D_max_iter%2C%20random_state%3D42).fit(_X)%0A%0A%20%20%20%20_df_em_comparison%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%20Item%22%3A%20%22Dataset%20Size%20(n%2C%20d)%22%2C%20%22Scratch%20Value%22%3A%20f%22%7B_n%7D%20samples%2C%20%7B_d%7D%20dims%22%2C%20%22Reference%22%3A%20%22Synthetic%20Bivariate%20Mixture%22%7D%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20%7B%22Evaluation%20Item%22%3A%20%22Components%20(K)%22%2C%20%22Scratch%20Value%22%3A%20%223%22%2C%20%22Reference%22%3A%20%223%20Gaussian%20Modes%22%7D%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20%7B%22Scratch%20Final%20Log-Likelihood%22%3A%20f%22%7B_log_likelihood_history%5B-1%5D%3A.2f%7D%22%2C%20%22Scikit-Learn%20LL%22%3A%20f%22%7B_gmm_sk.score(_X)%20*%20_n%3A.2f%7D%22%2C%20%22Reference%22%3A%20%22Exact%20Match%20to%20Converged%20Bound%22%7D%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20%7B%22Component%201%20Weight%20(pi_1)%22%3A%20f%22%7B_pi%5B0%5D%3A.3f%7D%22%2C%20%22Component%202%20Weight%20(pi_2)%22%3A%20f%22%7B_pi%5B1%5D%3A.3f%7D%22%2C%20%22Reference%22%3A%20f%22pi_3%20%3D%20%7B_pi%5B2%5D%3A.3f%7D%22%7D%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20%7B%22Monotonic%20LL%20Ascent%20Verified%22%3A%20%22Yes%20(strictly%20non-decreasing)%22%2C%20%22Scikit-Learn%20LL%22%3A%20%22Converged%22%2C%20%22Reference%22%3A%20%22Guaranteed%20by%20Jensen's%20Inequality%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%0A%40app.cell%0Adef%20_(GaussianMixture%2C%20all_samples%2C%20ground_truth_anomaly%2C%20np%2C%20pd)%3A%0A%20%20%20%20%23%20Example%202%3A%20Probabilistic%20Anomaly%20Detection%20Diagnostic%0A%20%20%20%20_gmm%20%3D%20GaussianMixture(n_components%3D3%2C%20covariance_type%3D%22full%22%2C%20random_state%3D42).fit(all_samples)%0A%20%20%20%20_log_density%20%3D%20_gmm.score_samples(all_samples)%0A%0A%20%20%20%20%23%20Define%20threshold%20tau%20at%20the%205th%20percentile%20of%20density%20scores%0A%20%20%20%20_tau%20%3D%20np.percentile(_log_density%2C%205.0)%0A%20%20%20%20_predicted_anomaly%20%3D%20(_log_density%20%3C%20_tau).astype(int)%0A%0A%20%20%20%20%23%20Compute%20Confusion%20Matrix%20Metrics%0A%20%20%20%20_tp%20%3D%20np.sum((_predicted_anomaly%20%3D%3D%201)%20%26%20(ground_truth_anomaly%20%3D%3D%201))%0A%20%20%20%20_fp%20%3D%20np.sum((_predicted_anomaly%20%3D%3D%201)%20%26%20(ground_truth_anomaly%20%3D%3D%200))%0A%20%20%20%20_tn%20%3D%20np.sum((_predicted_anomaly%20%3D%3D%200)%20%26%20(ground_truth_anomaly%20%3D%3D%200))%0A%20%20%20%20_fn%20%3D%20np.sum((_predicted_anomaly%20%3D%3D%200)%20%26%20(ground_truth_anomaly%20%3D%3D%201))%0A%0A%20%20%20%20_precision%20%3D%20_tp%20%2F%20(_tp%20%2B%20_fp)%20if%20(_tp%20%2B%20_fp)%20%3E%200%20else%200.0%0A%20%20%20%20_recall%20%3D%20_tp%20%2F%20(_tp%20%2B%20_fn)%20if%20(_tp%20%2B%20_fn)%20%3E%200%20else%200.0%0A%20%20%20%20_f1%20%3D%202%20*%20_precision%20*%20_recall%20%2F%20(_precision%20%2B%20_recall)%20if%20(_precision%20%2B%20_recall)%20%3E%200%20else%200.0%0A%0A%20%20%20%20_df_anomaly_metrics%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%22Diagnostic%20Metric%22%3A%20%22Density%20Threshold%20(tau)%22%2C%20%22Score%20Value%22%3A%20f%22%7B_tau%3A.2f%7D%22%2C%20%22Interpretation%22%3A%20%22Points%20with%20ln%20p(x)%20%3C%20tau%20are%20flagged%20as%20anomalies%22%7D%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20%7B%22Diagnostic%20Metric%22%3A%20%22True%20Positives%20(TP)%22%2C%20%22Score%20Value%22%3A%20str(_tp)%2C%20%22Interpretation%22%3A%20%22Correctly%20detected%20spatial%20outliers%22%7D%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20%7B%22Diagnostic%20Metric%22%3A%20%22False%20Positives%20(FP)%22%2C%20%22Score%20Value%22%3A%20str(_fp)%2C%20%22Interpretation%22%3A%20%22Inlier%20points%20in%20thin%20Gaussian%20tails%20flagged%20as%20anomalies%22%7D%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20%7B%22Diagnostic%20Metric%22%3A%20%22True%20Negatives%20(TN)%22%2C%20%22Score%20Value%22%3A%20str(_tn)%2C%20%22Interpretation%22%3A%20%22Normal%20observations%20correctly%20classified%22%7D%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20%7B%22Diagnostic%20Metric%22%3A%20%22False%20Negatives%20(FN)%22%2C%20%22Score%20Value%22%3A%20str(_fn)%2C%20%22Interpretation%22%3A%20%22Outliers%20close%20to%20cluster%20bodies%20missed%22%7D%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20%7B%22Diagnostic%20Metric%22%3A%20%22Detection%20Precision%22%2C%20%22Score%20Value%22%3A%20f%22%7B_precision%20*%20100.0%3A.1f%7D%25%22%2C%20%22Interpretation%22%3A%20%22Proportion%20of%20flagged%20points%20that%20are%20true%20anomalies%22%7D%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20%7B%22Diagnostic%20Metric%22%3A%20%22Detection%20Recall%22%2C%20%22Score%20Value%22%3A%20f%22%7B_recall%20*%20100.0%3A.1f%7D%25%22%2C%20%22Interpretation%22%3A%20%22Proportion%20of%20all%20true%20anomalies%20identified%22%7D%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20%7B%22Diagnostic%20Metric%22%3A%20%22F1-Score%22%2C%20%22Score%20Value%22%3A%20f%22%7B_f1%3A.4f%7D%22%2C%20%22Interpretation%22%3A%20%22Harmonic%20mean%20of%20precision%20and%20recall%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
7c9afc63038fef31bc2d5b0b00a216d6