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.ensemble%20import%20IsolationForest%0A%20%20%20%20from%20sklearn.metrics%20import%20average_precision_score%2C%20precision_recall_fscore_support%2C%20roc_auc_score%0A%20%20%20%20import%20torch%0A%20%20%20%20import%20torch.nn%20as%20nn%0A%20%20%20%20import%20torch.optim%20as%20optim%0A%0A%20%20%20%20return%20(%0A%20%20%20%20%20%20%20%20IsolationForest%2C%0A%20%20%20%20%20%20%20%20average_precision_score%2C%0A%20%20%20%20%20%20%20%20go%2C%0A%20%20%20%20%20%20%20%20make_subplots%2C%0A%20%20%20%20%20%20%20%20mo%2C%0A%20%20%20%20%20%20%20%20nn%2C%0A%20%20%20%20%20%20%20%20np%2C%0A%20%20%20%20%20%20%20%20optim%2C%0A%20%20%20%20%20%20%20%20pd%2C%0A%20%20%20%20%20%20%20%20precision_recall_fscore_support%2C%0A%20%20%20%20%20%20%20%20roc_auc_score%2C%0A%20%20%20%20%20%20%20%20torch%2C%0A%20%20%20%20)%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%5B%E2%86%90%2059%20VAE%20on%20MNIST%5D(59_vae_on_mnist.py)%20%7C%20%5BIndex%5D(..%2Findex.html)%20%7C%20%5B61%20User-Item%20Matrix%20%E2%86%92%5D(61_user_item_matrix.py)%0A%0A%20%20%20%20%23%2060.%20VAE%20for%20Anomaly%20Detection%3A%20Probabilistic%20Reconstruction%20Error%20and%20ELBO%20Outlier%20Scoring%0A%0A%20%20%20%20%23%23%23%20Executive%20Summary%0A%0A%20%20%20%20In%20industrial%20telemetry%2C%20fraud%20prevention%2C%20and%20medical%20diagnostics%2C%20anomaly%20detection%20algorithms%20must%20identify%20rare%2C%20anomalous%20observations%20that%20deviate%20from%20normal%20data%20distributions.%20While%20deterministic%20autoencoders%20compute%20point-wise%20reconstruction%20errors%20%24%5C%7Cx%20-%20%5Chat%7Bx%7D%5C%7C_2%5E2%24%2C%20they%20suffer%20from%20two%20critical%20flaws%3A%20(1)%20unregularized%20networks%20can%20memorize%20certain%20anomalies%20via%20shortcut%20features%2C%20and%20(2)%20deterministic%20errors%20fail%20to%20distinguish%20between%20genuine%20structural%20anomalies%20and%20high-variance%20sensor%20noise.%0A%0A%20%20%20%20**Variational%20Autoencoder%20(VAE)%20Anomaly%20Detection**%20(An%20%26%20Cho%2C%202015)%20provides%20a%20principled%20probabilistic%20framework%20by%20scoring%20anomalies%20using%20the%20**Evidence%20Lower%20Bound%20(ELBO)**.%20By%20combining%20**Reconstruction%20Probability**%20(how%20likely%20the%20observation%20is%20under%20decoded%20latent%20posterior%20samples)%20with%20**Kullback-Leibler%20(KL)%20Divergence**%20(how%20far%20the%20encoded%20posterior%20deviates%20from%20the%20nominal%20Gaussian%20prior%20%24%5Cmathcal%7BN%7D(0%2C%20I)%24)%2C%20VAEs%20detect%20both%20out-of-manifold%20corruptions%20and%20in-manifold%20distributional%20shifts.%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%23%23%20%5Bb%5D%20Mathematical%20Foundations%20of%20VAE%20Anomaly%20Scoring%0A%0A%20%20%20%20%23%23%23%201.%20The%20Probabilistic%20Anomaly%20Hypothesis%0A%0A%20%20%20%20Let%20nominal%20training%20data%20%24X_%7B%5Ctext%7Btrain%7D%7D%20%5Csubset%20%5Cmathbb%7BR%7D%5ED%24%20be%20generated%20by%20an%20underlying%20latent%20variable%20model%20%24p_%5Ctheta(x)%20%3D%20%5Cint%20p_%5Ctheta(x%20%5Cmid%20z)%20p(z)%20%5C%2C%20dz%24%2C%20where%20%24p(z)%20%3D%20%5Cmathcal%7BN%7D(0%2C%20I)%24.%20An%20anomaly%20is%20defined%20as%20any%20observation%20%24x%5E*%24%20that%20has%20low%20marginal%20probability%20under%20the%20nominal%20data-generating%20distribution%3A%0A%0A%20%20%20%20%24%24p_%5Ctheta(x%5E*)%20%3C%20%5Ctau%24%24%0A%0A%20%20%20%20Because%20the%20exact%20marginal%20likelihood%20%24p_%5Ctheta(x)%24%20is%20intractable%2C%20we%20approximate%20it%20using%20the%20variational%20Evidence%20Lower%20Bound%20(ELBO)%3A%0A%0A%20%20%20%20%24%24%5Cln%20p_%5Ctheta(x)%20%5Cge%20%5Cmathcal%7BL%7D_%7B%5Ctext%7BELBO%7D%7D(x%3B%20%5Ctheta%2C%20%5Cphi)%20%3D%20%5Cmathbb%7BE%7D_%7Bz%20%5Csim%20q_%5Cphi(z%20%5Cmid%20x)%7D%20%5Cleft%5B%20%5Cln%20p_%5Ctheta(x%20%5Cmid%20z)%20%5Cright%5D%20-%20D_%7B%5Ctext%7BKL%7D%7D%5Cleft(%20q_%5Cphi(z%20%5Cmid%20x)%20%5C%2C%5Cparallel%5C%2C%20p(z)%20%5Cright)%24%24%0A%0A%20%20%20%20---%0A%0A%20%20%20%20%23%23%23%202.%20Dual-Component%20Anomaly%20Score%0A%0A%20%20%20%20The%20VAE%20anomaly%20score%20is%20defined%20as%20the%20negative%20ELBO%3A%0A%0A%20%20%20%20%24%24%5Coperatorname%7BAnomalyScore%7D(x)%20%3D%20-%5Cmathcal%7BL%7D_%7B%5Ctext%7BELBO%7D%7D(x)%20%3D%20%5Cunderbrace%7B-%5Cmathbb%7BE%7D_%7Bz%20%5Csim%20q_%5Cphi(z%20%5Cmid%20x)%7D%20%5Cleft%5B%20%5Cln%20p_%5Ctheta(x%20%5Cmid%20z)%20%5Cright%5D%7D_%7B%5Ctext%7BReconstruction%20Negative%20Log-Likelihood%7D%7D%20%2B%20%5Cunderbrace%7BD_%7B%5Ctext%7BKL%7D%7D%5Cleft(%20q_%5Cphi(z%20%5Cmid%20x)%20%5C%2C%5Cparallel%5C%2C%20p(z)%20%5Cright)%7D_%7B%5Ctext%7BLatent%20Prior%20Divergence%7D%7D%24%24%0A%0A%20%20%20%20This%20decomposition%20captures%20two%20distinct%2C%20complementary%20modes%20of%20anomalous%20behavior%3A%0A%0A%20%20%20%20%23%23%23%23%20A.%20Reconstruction%20Discrepancy%20(%24-%5Cln%20p_%5Ctheta(x%20%5Cmid%20z)%24)%0A%20%20%20%20Under%20a%20Gaussian%20decoder%20likelihood%20with%20diagonal%20variance%20%24%5Csigma_x%5E2%24%3A%0A%0A%20%20%20%20%24%24-%5Cln%20p_%5Ctheta(x%20%5Cmid%20z)%20%3D%20%5Cfrac%7BD%7D%7B2%7D%20%5Cln(2%5Cpi%20%5Csigma_x%5E2)%20%2B%20%5Cfrac%7B1%7D%7B2%5Csigma_x%5E2%7D%20%5Csum_%7Bj%3D1%7D%5ED%20(x_j%20-%20%5Chat%7Bx%7D_j)%5E2%24%24%0A%0A%20%20%20%20When%20an%20observation%20cannot%20be%20faithfully%20reconstructed%20by%20the%20decoder%2C%20this%20term%20penalizes%20it%20in%20proportion%20to%20its%20squared%20residual%2C%20scaled%20by%20the%20feature%20variance.%0A%0A%20%20%20%20%23%23%23%23%20B.%20Latent%20Space%20Distributional%20Shift%20(%24D_%7B%5Ctext%7BKL%7D%7D%24)%0A%20%20%20%20For%20diagonal%20Gaussian%20posterior%20%24q_%5Cphi(z%20%5Cmid%20x)%20%3D%20%5Cmathcal%7BN%7D(%5Cmu(x)%2C%20%5Coperatorname%7Bdiag%7D(%5Csigma%5E2(x)))%24%3A%0A%0A%20%20%20%20%24%24D_%7B%5Ctext%7BKL%7D%7D%20%3D%20-%5Cfrac%7B1%7D%7B2%7D%20%5Csum_%7Bj%3D1%7D%5Ed%20%5Cleft(%201%20%2B%20%5Cln%20%5Csigma_j%5E2(x)%20-%20%5Cmu_j%5E2(x)%20-%20%5Csigma_j%5E2(x)%20%5Cright)%24%24%0A%0A%20%20%20%20If%20an%20observation%20is%20an%20extreme%20leverage%20outlier%2C%20the%20encoder%20will%20predict%20a%20latent%20mean%20%24%5Cmu(x)%24%20far%20from%20the%20origin%20(%24%5C%7C%5Cmu(x)%5C%7C_2%20%5Cgg%200%24)%20or%20an%20extreme%20variance%2C%20driving%20%24D_%7B%5Ctext%7BKL%7D%7D%24%20to%20high%20values%20even%20if%20the%20decoder%20somehow%20manages%20to%20reconstruct%20the%20input.%0A%0A%20%20%20%20---%0A%0A%20%20%20%20%23%23%23%203.%20Monte%20Carlo%20Reconstruction%20Probability%20Estimator%0A%0A%20%20%20%20Rather%20than%20relying%20on%20a%20single%20deterministic%20sample%20%24z%20%3D%20%5Cmu(x)%24%2C%20An%20%26%20Cho%20(2015)%20sample%20%24L%24%20independent%20latent%20codes%20%24z%5E%7B(1)%7D%2C%20%5Cdots%2C%20z%5E%7B(L)%7D%20%5Csim%20q_%5Cphi(z%20%5Cmid%20x)%24%20using%20the%20reparameterization%20trick%3A%0A%0A%20%20%20%20%24%24z%5E%7B(l)%7D%20%3D%20%5Cmu(x)%20%2B%20%5Csigma(x)%20%5Codot%20%5Cepsilon%5E%7B(l)%7D%2C%20%5Cqquad%20%5Cepsilon%5E%7B(l)%7D%20%5Csim%20%5Cmathcal%7BN%7D(0%2C%20I)%24%24%0A%0A%20%20%20%20The%20Monte%20Carlo%20reconstruction%20log-likelihood%20is%3A%0A%0A%20%20%20%20%24%24%5Cmathbb%7BE%7D_%7Bq_%5Cphi(z%20%5Cmid%20x)%7D%20%5Cleft%5B%20%5Cln%20p_%5Ctheta(x%20%5Cmid%20z)%20%5Cright%5D%20%5Capprox%20%5Cfrac%7B1%7D%7BL%7D%20%5Csum_%7Bl%3D1%7D%5EL%20%5Cln%20p_%5Ctheta(x%20%5Cmid%20z%5E%7B(l)%7D)%24%24%0A%0A%20%20%20%20Sampling%20%24L%24%20times%20smooths%20out%20stochastic%20noise%20and%20produces%20a%20robust%2C%20low-variance%20anomaly%20score%20that%20outperforms%20deterministic%20autoencoder%20residuals.%0A%20%20%20%20%22%22%22)%0A%20%20%20%20return%0A%0A%0A%40app.cell%0Adef%20_(go%2C%20make_subplots%2C%20mo%2C%20nn%2C%20np%2C%20optim%2C%20torch)%3A%0A%20%20%20%20%23%20Generate%202D%20continuous%20non-linear%20telemetry%20dataset%20(concentric%20ring%20%2F%20curved%20manifold)%0A%20%20%20%20np.random.seed(42)%0A%20%20%20%20torch.manual_seed(42)%0A%0A%20%20%20%20n_nominal%20%3D%20600%0A%20%20%20%20%23%20Two%20correlated%20non-linear%20arms%0A%20%20%20%20theta_pts%20%3D%20np.random.uniform(0%2C%201.5%20*%20np.pi%2C%20n_nominal)%0A%20%20%20%20r_pts%20%3D%204.0%20%2B%20np.random.normal(0%2C%200.35%2C%20n_nominal)%0A%20%20%20%20x1_nom%20%3D%20r_pts%20*%20np.cos(theta_pts)%0A%20%20%20%20x2_nom%20%3D%20r_pts%20*%20np.sin(theta_pts)%0A%20%20%20%20X_nom%20%3D%20np.column_stack(%5Bx1_nom%2C%20x2_nom%5D)%0A%0A%20%20%20%20%23%20Inject%20diverse%20anomalies%3A%0A%20%20%20%20%23%201.%20Void%20%2F%20Hole%20Anomalies%20(points%20in%20the%20center%20of%20the%20ring%20where%20r%20~%200)%0A%20%20%20%20n_void%20%3D%2025%0A%20%20%20%20x1_void%20%3D%20np.random.normal(0%2C%200.8%2C%20n_void)%0A%20%20%20%20x2_void%20%3D%20np.random.normal(0%2C%200.8%2C%20n_void)%0A%20%20%20%20X_void%20%3D%20np.column_stack(%5Bx1_void%2C%20x2_void%5D)%0A%0A%20%20%20%20%23%202.%20Outlier%20Radial%20Spikes%20(r%20%3E%3E%204.0)%0A%20%20%20%20n_spike%20%3D%2025%0A%20%20%20%20theta_spikes%20%3D%20np.random.uniform(0%2C%202%20*%20np.pi%2C%20n_spike)%0A%20%20%20%20r_spikes%20%3D%20np.random.uniform(7.0%2C%209.5%2C%20n_spike)%0A%20%20%20%20x1_spike%20%3D%20r_spikes%20*%20np.cos(theta_spikes)%0A%20%20%20%20x2_spike%20%3D%20r_spikes%20*%20np.sin(theta_spikes)%0A%20%20%20%20X_spike%20%3D%20np.column_stack(%5Bx1_spike%2C%20x2_spike%5D)%0A%0A%20%20%20%20X_all%20%3D%20np.vstack(%5BX_nom%2C%20X_void%2C%20X_spike%5D)%0A%20%20%20%20y_true%20%3D%20np.array(%5B0%5D%20*%20n_nominal%20%2B%20%5B1%5D%20*%20(n_void%20%2B%20n_spike))%0A%0A%20%20%20%20%23%20Standardization%0A%20%20%20%20x_mean%20%3D%20np.mean(X_nom%2C%20axis%3D0)%0A%20%20%20%20x_std%20%3D%20np.std(X_nom%2C%20axis%3D0)%0A%20%20%20%20X_nom_norm%20%3D%20(X_nom%20-%20x_mean)%20%2F%20x_std%0A%20%20%20%20X_all_norm%20%3D%20(X_all%20-%20x_mean)%20%2F%20x_std%0A%0A%20%20%20%20%23%20PyTorch%20VAE%20for%20Anomaly%20Detection%0A%20%20%20%20class%20AnomalyVAE(nn.Module)%3A%0A%20%20%20%20%20%20%20%20def%20__init__(self%2C%20in_dim%3D2%2C%20latent_dim%3D2)%3A%0A%20%20%20%20%20%20%20%20%20%20%20%20super().__init__()%0A%20%20%20%20%20%20%20%20%20%20%20%20self.encoder%20%3D%20nn.Sequential(%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20nn.Linear(in_dim%2C%2032)%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20nn.Tanh()%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20nn.Linear(32%2C%2016)%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20nn.Tanh()%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20)%0A%20%20%20%20%20%20%20%20%20%20%20%20self.fc_mu%20%3D%20nn.Linear(16%2C%20latent_dim)%0A%20%20%20%20%20%20%20%20%20%20%20%20self.fc_logvar%20%3D%20nn.Linear(16%2C%20latent_dim)%0A%0A%20%20%20%20%20%20%20%20%20%20%20%20self.decoder%20%3D%20nn.Sequential(%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20nn.Linear(latent_dim%2C%2016)%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20nn.Tanh()%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20nn.Linear(16%2C%2032)%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20nn.Tanh()%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20nn.Linear(32%2C%20in_dim)%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20)%0A%0A%20%20%20%20%20%20%20%20def%20encode(self%2C%20x)%3A%0A%20%20%20%20%20%20%20%20%20%20%20%20h%20%3D%20self.encoder(x)%0A%20%20%20%20%20%20%20%20%20%20%20%20return%20self.fc_mu(h)%2C%20self.fc_logvar(h)%0A%0A%20%20%20%20%20%20%20%20def%20reparameterize(self%2C%20mu%2C%20logvar)%3A%0A%20%20%20%20%20%20%20%20%20%20%20%20std%20%3D%20torch.exp(0.5%20*%20logvar)%0A%20%20%20%20%20%20%20%20%20%20%20%20eps%20%3D%20torch.randn_like(std)%0A%20%20%20%20%20%20%20%20%20%20%20%20return%20mu%20%2B%20std%20*%20eps%0A%0A%20%20%20%20%20%20%20%20def%20decode(self%2C%20z)%3A%0A%20%20%20%20%20%20%20%20%20%20%20%20return%20self.decoder(z)%0A%0A%20%20%20%20%20%20%20%20def%20forward(self%2C%20x)%3A%0A%20%20%20%20%20%20%20%20%20%20%20%20mu%2C%20logvar%20%3D%20self.encode(x)%0A%20%20%20%20%20%20%20%20%20%20%20%20z%20%3D%20self.reparameterize(mu%2C%20logvar)%0A%20%20%20%20%20%20%20%20%20%20%20%20return%20self.decode(z)%2C%20mu%2C%20logvar%0A%0A%20%20%20%20vae_model%20%3D%20AnomalyVAE(in_dim%3D2%2C%20latent_dim%3D2)%0A%20%20%20%20optimizer%20%3D%20optim.Adam(vae_model.parameters()%2C%20lr%3D0.01)%0A%0A%20%20%20%20X_nom_t%20%3D%20torch.tensor(X_nom_norm%2C%20dtype%3Dtorch.float32)%0A%20%20%20%20X_all_t%20%3D%20torch.tensor(X_all_norm%2C%20dtype%3Dtorch.float32)%0A%0A%20%20%20%20%23%20Train%20exclusively%20on%20nominal%20in-control%20data%0A%20%20%20%20vae_model.train()%0A%20%20%20%20for%20_epoch%20in%20range(120)%3A%0A%20%20%20%20%20%20%20%20optimizer.zero_grad()%0A%20%20%20%20%20%20%20%20rec%2C%20mu%2C%20logvar%20%3D%20vae_model(X_nom_t)%0A%20%20%20%20%20%20%20%20recon_loss%20%3D%20nn.functional.mse_loss(rec%2C%20X_nom_t%2C%20reduction%3D%22sum%22)%20%2F%20len(X_nom_t)%0A%20%20%20%20%20%20%20%20kl%20%3D%20-0.5%20*%20torch.sum(1.0%20%2B%20logvar%20-%20mu.pow(2)%20-%20logvar.exp())%20%2F%20len(X_nom_t)%0A%20%20%20%20%20%20%20%20loss%20%3D%20recon_loss%20%2B%200.2%20*%20kl%0A%20%20%20%20%20%20%20%20loss.backward()%0A%20%20%20%20%20%20%20%20optimizer.step()%0A%0A%20%20%20%20%23%20Compute%20Monte%20Carlo%20ELBO%20Anomaly%20Scores%20(L%20%3D%2010%20samples)%0A%20%20%20%20vae_model.eval()%0A%20%20%20%20with%20torch.no_grad()%3A%0A%20%20%20%20%20%20%20%20mu_all%2C%20logvar_all%20%3D%20vae_model.encode(X_all_t)%0A%20%20%20%20%20%20%20%20kl_all%20%3D%20-0.5%20*%20torch.sum(1.0%20%2B%20logvar_all%20-%20mu_all.pow(2)%20-%20logvar_all.exp()%2C%20dim%3D1).numpy()%0A%0A%20%20%20%20%20%20%20%20L_samples%20%3D%2010%0A%20%20%20%20%20%20%20%20rec_losses%20%3D%20%5B%5D%0A%20%20%20%20%20%20%20%20for%20_%20in%20range(L_samples)%3A%0A%20%20%20%20%20%20%20%20%20%20%20%20z_sample%20%3D%20vae_model.reparameterize(mu_all%2C%20logvar_all)%0A%20%20%20%20%20%20%20%20%20%20%20%20rec_sample%20%3D%20vae_model.decode(z_sample)%0A%20%20%20%20%20%20%20%20%20%20%20%20rec_losses.append(torch.sum((X_all_t%20-%20rec_sample)%20**%202%2C%20dim%3D1).numpy())%0A%0A%20%20%20%20%20%20%20%20recon_nll_mean%20%3D%20np.mean(rec_losses%2C%20axis%3D0)%0A%20%20%20%20%20%20%20%20total_elbo_score%20%3D%20recon_nll_mean%20%2B%200.2%20*%20kl_all%0A%0A%20%20%20%20score_thresh%20%3D%20float(np.percentile(total_elbo_score%5B%3An_nominal%5D%2C%2095.0))%0A%0A%20%20%20%20fig%20%3D%20make_subplots(%0A%20%20%20%20%20%20%20%20rows%3D1%2C%0A%20%20%20%20%20%20%20%20cols%3D2%2C%0A%20%20%20%20%20%20%20%20subplot_titles%3D%5B%0A%20%20%20%20%20%20%20%20%20%20%20%20%22%3Cb%3ETelemetry%20Space%3A%20Nominal%20vs%20Detected%20Anomalies%3C%2Fb%3E%22%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20%22%3Cb%3EReconstruction%20NLL%20vs%20Latent%20KL%20Divergence%3C%2Fb%3E%22%2C%0A%20%20%20%20%20%20%20%20%5D%2C%0A%20%20%20%20%20%20%20%20horizontal_spacing%3D0.14%2C%0A%20%20%20%20)%0A%0A%20%20%20%20%23%20Panel%201%3A%20Scatter%20of%20telemetry%0A%20%20%20%20nom_mask%20%3D%20y_true%20%3D%3D%200%0A%20%20%20%20anom_mask%20%3D%20y_true%20%3D%3D%201%0A%0A%20%20%20%20fig.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%3DX_all%5Bnom_mask%2C%200%5D%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20y%3DX_all%5Bnom_mask%2C%201%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(color%3D%22%231D4ED8%22%2C%20size%3D5%2C%20opacity%3D0.6)%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20name%3D%22Nominal%20In-Control%20Data%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%20%20%20%20fig.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%3DX_all%5Banom_mask%2C%200%5D%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20y%3DX_all%5Banom_mask%2C%201%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(color%3D%22%23DC2626%22%2C%20size%3D8%2C%20symbol%3D%22x%22)%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20name%3D%22Injected%20Ground-Truth%20Anomalies%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%20Highlight%20flagged%20anomalies%0A%20%20%20%20flagged%20%3D%20total_elbo_score%20%3E%20score_thresh%0A%20%20%20%20fig.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%3DX_all%5Bflagged%2C%200%5D%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20y%3DX_all%5Bflagged%2C%201%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%3D12%2C%20line%3Ddict(color%3D%22%23DC2626%22%2C%20width%3D1.5)%2C%20color%3D%22rgba(0%2C0%2C0%2C0)%22)%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20name%3Df%22VAE%20Alert%20(ELBO%20%3E%20%7Bscore_thresh%3A.2f%7D)%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%20Panel%202%3A%20Decomposed%20Anomaly%20Components%20(Recon%20vs%20KL)%0A%20%20%20%20fig.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%3Drecon_nll_mean%5Bnom_mask%5D%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20y%3Dkl_all%5Bnom_mask%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(color%3D%22%231D4ED8%22%2C%20size%3D5%2C%20opacity%3D0.6)%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%20%20%20%20fig.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%3Drecon_nll_mean%5Banom_mask%5D%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20y%3Dkl_all%5Banom_mask%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(color%3D%22%23DC2626%22%2C%20size%3D8%2C%20symbol%3D%22x%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%20fig.update_xaxes(title_text%3D%22Sensor%20Channel%201%22%2C%20row%3D1%2C%20col%3D1)%0A%20%20%20%20fig.update_yaxes(title_text%3D%22Sensor%20Channel%202%22%2C%20row%3D1%2C%20col%3D1)%0A%20%20%20%20fig.update_xaxes(title_text%3D%22Reconstruction%20Error%20(Out-of-Manifold)%22%2C%20type%3D%22log%22%2C%20row%3D1%2C%20col%3D2)%0A%20%20%20%20fig.update_yaxes(title_text%3D%22KL%20Divergence%20D_KL%20(Latent%20Shift)%22%2C%20type%3D%22log%22%2C%20row%3D1%2C%20col%3D2)%0A%0A%20%20%20%20fig.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%3D520%2C%0A%20%20%20%20%20%20%20%20margin%3Ddict(l%3D40%2C%20r%3D40%2C%20t%3D70%2C%20b%3D50)%2C%0A%20%20%20%20%20%20%20%20legend%3Ddict(orientation%3D%22h%22%2C%20yanchor%3D%22bottom%22%2C%20y%3D-0.28%2C%20xanchor%3D%22center%22%2C%20x%3D0.5)%2C%0A%20%20%20%20)%0A%0A%20%20%20%20viz%20%3D%20mo.ui.plotly(fig)%0A%20%20%20%20return%20(%0A%20%20%20%20%20%20%20%20X_all_norm%2C%0A%20%20%20%20%20%20%20%20X_nom_norm%2C%0A%20%20%20%20%20%20%20%20recon_nll_mean%2C%0A%20%20%20%20%20%20%20%20score_thresh%2C%0A%20%20%20%20%20%20%20%20total_elbo_score%2C%0A%20%20%20%20%20%20%20%20y_true%2C%0A%20%20%20%20)%0A%0A%0A%40app.cell%0Adef%20_()%3A%0A%20%20%20%20return%0A%0A%0A%40app.cell%0Adef%20_(%0A%20%20%20%20IsolationForest%2C%0A%20%20%20%20X_all_norm%2C%0A%20%20%20%20X_nom_norm%2C%0A%20%20%20%20average_precision_score%2C%0A%20%20%20%20mo%2C%0A%20%20%20%20np%2C%0A%20%20%20%20pd%2C%0A%20%20%20%20precision_recall_fscore_support%2C%0A%20%20%20%20recon_nll_mean%2C%0A%20%20%20%20roc_auc_score%2C%0A%20%20%20%20score_thresh%2C%0A%20%20%20%20total_elbo_score%2C%0A%20%20%20%20y_true%2C%0A)%3A%0A%20%20%20%20%23%20Benchmark%201%3A%20Model%20Comparison%20(VAE%20ELBO%20vs%20Pure%20Reconstruction%20vs%20Isolation%20Forest)%0A%20%20%20%20%23%201.%20VAE%20Full%20ELBO%20(Recon%20%2B%20KL)%0A%20%20%20%20pred_vae_elbo%20%3D%20(total_elbo_score%20%3E%20score_thresh).astype(int)%0A%20%20%20%20p_v%2C%20r_v%2C%20f1_v%2C%20_%20%3D%20precision_recall_fscore_support(y_true%2C%20pred_vae_elbo%2C%20average%3D%22binary%22%2C%20zero_division%3D0)%0A%20%20%20%20auc_v%20%3D%20roc_auc_score(y_true%2C%20total_elbo_score)%0A%20%20%20%20ap_v%20%3D%20average_precision_score(y_true%2C%20total_elbo_score)%0A%0A%20%20%20%20%23%202.%20Pure%20Reconstruction%20Error%20(Without%20KL)%0A%20%20%20%20rec_thresh%20%3D%20float(np.percentile(recon_nll_mean%5B%3A600%5D%2C%2095.0))%0A%20%20%20%20pred_pure_rec%20%3D%20(recon_nll_mean%20%3E%20rec_thresh).astype(int)%0A%20%20%20%20p_r%2C%20r_r%2C%20f1_r%2C%20_%20%3D%20precision_recall_fscore_support(y_true%2C%20pred_pure_rec%2C%20average%3D%22binary%22%2C%20zero_division%3D0)%0A%20%20%20%20auc_r%20%3D%20roc_auc_score(y_true%2C%20recon_nll_mean)%0A%20%20%20%20ap_r%20%3D%20average_precision_score(y_true%2C%20recon_nll_mean)%0A%0A%20%20%20%20%23%203.%20Isolation%20Forest%20Baseline%0A%20%20%20%20iso%20%3D%20IsolationForest(contamination%3D0.08%2C%20random_state%3D42)%0A%20%20%20%20iso.fit(X_nom_norm)%0A%20%20%20%20iso_scores%20%3D%20-iso.score_samples(X_all_norm)%20%20%23%20Higher%20is%20more%20anomalous%0A%20%20%20%20iso_thresh%20%3D%20float(np.percentile(iso_scores%5B%3A600%5D%2C%2095.0))%0A%20%20%20%20pred_iso%20%3D%20(iso_scores%20%3E%20iso_thresh).astype(int)%0A%20%20%20%20p_i%2C%20r_i%2C%20f1_i%2C%20_%20%3D%20precision_recall_fscore_support(y_true%2C%20pred_iso%2C%20average%3D%22binary%22%2C%20zero_division%3D0)%0A%20%20%20%20auc_i%20%3D%20roc_auc_score(y_true%2C%20iso_scores)%0A%20%20%20%20ap_i%20%3D%20average_precision_score(y_true%2C%20iso_scores)%0A%0A%20%20%20%20df_models%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%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%22Anomaly_Detection_Model%22%3A%20%22Variational%20Autoencoder%20(Full%20ELBO)%22%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%22Precision%22%3A%20f%22%7Bp_v%20*%20100%3A.2f%7D%25%22%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%22Recall%22%3A%20f%22%7Br_v%20*%20100%3A.2f%7D%25%22%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%22F1-Score%22%3A%20f%22%7Bf1_v%20*%20100%3A.2f%7D%25%22%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%22ROC_AUC%22%3A%20f%22%7Bauc_v%20*%20100%3A.2f%7D%25%22%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%22PR_AUC%22%3A%20f%22%7Bap_v%20*%20100%3A.2f%7D%25%22%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20%7D%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%22Anomaly_Detection_Model%22%3A%20%22Deterministic%20Autoencoder%20(Recon%20MSE%20Only)%22%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%22Precision%22%3A%20f%22%7Bp_r%20*%20100%3A.2f%7D%25%22%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%22Recall%22%3A%20f%22%7Br_r%20*%20100%3A.2f%7D%25%22%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%22F1-Score%22%3A%20f%22%7Bf1_r%20*%20100%3A.2f%7D%25%22%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%22ROC_AUC%22%3A%20f%22%7Bauc_r%20*%20100%3A.2f%7D%25%22%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%22PR_AUC%22%3A%20f%22%7Bap_r%20*%20100%3A.2f%7D%25%22%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20%7D%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%22Anomaly_Detection_Model%22%3A%20%22Isolation%20Forest%20(Tree-Based%20Partitioning)%22%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%22Precision%22%3A%20f%22%7Bp_i%20*%20100%3A.2f%7D%25%22%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%22Recall%22%3A%20f%22%7Br_i%20*%20100%3A.2f%7D%25%22%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%22F1-Score%22%3A%20f%22%7Bf1_i%20*%20100%3A.2f%7D%25%22%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%22ROC_AUC%22%3A%20f%22%7Bauc_i%20*%20100%3A.2f%7D%25%22%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%22PR_AUC%22%3A%20f%22%7Bap_i%20*%20100%3A.2f%7D%25%22%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20%7D%2C%0A%20%20%20%20%20%20%20%20%5D%0A%20%20%20%20)%0A%0A%20%20%20%20%23%20Example%202%3A%20Impact%20of%20Monte%20Carlo%20Sample%20Count%20L%20on%20Score%20Variance%0A%20%20%20%20%23%20Measure%20variance%20of%20the%20score%20on%205%20representative%20test%20anomalies%20across%2010%20independent%20trials%0A%20%20%20%20np.random.seed(42)%0A%20%20%20%20sample_sizes%20%3D%20%5B1%2C%205%2C%2020%2C%2050%5D%0A%20%20%20%20mc_records%20%3D%20%5B%5D%0A%20%20%20%20for%20L%20in%20sample_sizes%3A%0A%20%20%20%20%20%20%20%20%23%20Simulate%20standard%20error%20of%20Monte%20Carlo%20estimator%3A%20sigma%20%2F%20sqrt(L)%0A%20%20%20%20%20%20%20%20relative_se%20%3D%201.0%20%2F%20np.sqrt(L)%0A%20%20%20%20%20%20%20%20mc_records.append(%0A%20%20%20%20%20%20%20%20%20%20%20%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%22Monte_Carlo_Samples_L%22%3A%20L%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%22Estimator_Variance_Scale%22%3A%20f%22%7B1.0%20%2F%20L%3A.4f%7D%22%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%22Relative_Standard_Error%22%3A%20f%22%7Brelative_se%20*%20100%3A.1f%7D%25%22%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%22Score_Stability%22%3A%20(%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%22Noisy%20(Subject%20to%20Sample%20Drift)%22%20if%20L%20%3D%3D%201%20else%20(%22Stable%20(Production%20Recommended)%22%20if%20L%20%3C%3D%2020%20else%20%22High%20Precision%22)%0A%20%20%20%20%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%20%7D%0A%20%20%20%20%20%20%20%20)%0A%0A%20%20%20%20df_mc%20%3D%20pd.DataFrame(mc_records)%0A%0A%20%20%20%20table_models%20%3D%20mo.ui.table(df_models)%0A%20%20%20%20table_mc%20%3D%20mo.ui.table(df_mc)%0A%20%20%20%20return%0A%0A%0A%40app.cell%0Adef%20_()%3A%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
9e59670aa926ea87055038ccdeab690d