process-improve 1.82.0__tar.gz → 1.83.2__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {process_improve-1.82.0 → process_improve-1.83.2}/PKG-INFO +1 -1
- {process_improve-1.82.0 → process_improve-1.83.2}/pyproject.toml +1 -1
- {process_improve-1.82.0 → process_improve-1.83.2}/pyproject.toml.orig +1 -1
- {process_improve-1.82.0 → process_improve-1.83.2}/src/process_improve/multivariate/_mbpls.py +131 -29
- {process_improve-1.82.0 → process_improve-1.83.2}/src/process_improve/multivariate/_pca.py +20 -12
- {process_improve-1.82.0 → process_improve-1.83.2}/README.md +0 -0
- {process_improve-1.82.0 → process_improve-1.83.2}/src/process_improve/__init__.py +0 -0
- {process_improve-1.82.0 → process_improve-1.83.2}/src/process_improve/_extras.py +0 -0
- {process_improve-1.82.0 → process_improve-1.83.2}/src/process_improve/_linalg.py +0 -0
- {process_improve-1.82.0 → process_improve-1.83.2}/src/process_improve/_random.py +0 -0
- {process_improve-1.82.0 → process_improve-1.83.2}/src/process_improve/_remote_data.py +0 -0
- {process_improve-1.82.0 → process_improve-1.83.2}/src/process_improve/batch/__init__.py +0 -0
- {process_improve-1.82.0 → process_improve-1.83.2}/src/process_improve/batch/_batch_monitor.py +0 -0
- {process_improve-1.82.0 → process_improve-1.83.2}/src/process_improve/batch/_batch_pca.py +0 -0
- {process_improve-1.82.0 → process_improve-1.83.2}/src/process_improve/batch/_batch_plots.py +0 -0
- {process_improve-1.82.0 → process_improve-1.83.2}/src/process_improve/batch/_batch_pls.py +0 -0
- {process_improve-1.82.0 → process_improve-1.83.2}/src/process_improve/batch/_common.py +0 -0
- {process_improve-1.82.0 → process_improve-1.83.2}/src/process_improve/batch/_online.py +0 -0
- {process_improve-1.82.0 → process_improve-1.83.2}/src/process_improve/batch/alignment_helpers.py +0 -0
- {process_improve-1.82.0 → process_improve-1.83.2}/src/process_improve/batch/control.py +0 -0
- {process_improve-1.82.0 → process_improve-1.83.2}/src/process_improve/batch/data_input.py +0 -0
- {process_improve-1.82.0 → process_improve-1.83.2}/src/process_improve/batch/datasets.py +0 -0
- {process_improve-1.82.0 → process_improve-1.83.2}/src/process_improve/batch/features.py +0 -0
- {process_improve-1.82.0 → process_improve-1.83.2}/src/process_improve/batch/plotting.py +0 -0
- {process_improve-1.82.0 → process_improve-1.83.2}/src/process_improve/batch/preprocessing.py +0 -0
- {process_improve-1.82.0 → process_improve-1.83.2}/src/process_improve/batch/tools.py +0 -0
- {process_improve-1.82.0 → process_improve-1.83.2}/src/process_improve/bivariate/__init__.py +0 -0
- {process_improve-1.82.0 → process_improve-1.83.2}/src/process_improve/bivariate/_elbow_peak.py +0 -0
- {process_improve-1.82.0 → process_improve-1.83.2}/src/process_improve/bivariate/methods.py +0 -0
- {process_improve-1.82.0 → process_improve-1.83.2}/src/process_improve/bivariate/tools.py +0 -0
- {process_improve-1.82.0 → process_improve-1.83.2}/src/process_improve/chemistry/__init__.py +0 -0
- {process_improve-1.82.0 → process_improve-1.83.2}/src/process_improve/chemistry/preprocessing.py +0 -0
- {process_improve-1.82.0 → process_improve-1.83.2}/src/process_improve/config.py +0 -0
- {process_improve-1.82.0 → process_improve-1.83.2}/src/process_improve/datasets/batch/batch-fake-data.csv +0 -0
- {process_improve-1.82.0 → process_improve-1.83.2}/src/process_improve/datasets/batch/details.txt +0 -0
- {process_improve-1.82.0 → process_improve-1.83.2}/src/process_improve/datasets/batch/dryer.csv +0 -0
- {process_improve-1.82.0 → process_improve-1.83.2}/src/process_improve/datasets/batch/nylon.csv +0 -0
- {process_improve-1.82.0 → process_improve-1.83.2}/src/process_improve/datasets/experiments/boilingpot.csv +0 -0
- {process_improve-1.82.0 → process_improve-1.83.2}/src/process_improve/datasets/experiments/golf.csv +0 -0
- {process_improve-1.82.0 → process_improve-1.83.2}/src/process_improve/datasets/experiments/pollutant.csv +0 -0
- {process_improve-1.82.0 → process_improve-1.83.2}/src/process_improve/datasets/experiments/solar.csv +0 -0
- {process_improve-1.82.0 → process_improve-1.83.2}/src/process_improve/datasets/experiments/test_doe1.csv +0 -0
- {process_improve-1.82.0 → process_improve-1.83.2}/src/process_improve/datasets/monitoring/batch-yield-and-purity.csv +0 -0
- {process_improve-1.82.0 → process_improve-1.83.2}/src/process_improve/datasets/monitoring/rubber-colour.csv +0 -0
- {process_improve-1.82.0 → process_improve-1.83.2}/src/process_improve/datasets/multivariate/LDPE/C.csv +0 -0
- {process_improve-1.82.0 → process_improve-1.83.2}/src/process_improve/datasets/multivariate/LDPE/Hotellings_T2_A3.csv +0 -0
- {process_improve-1.82.0 → process_improve-1.83.2}/src/process_improve/datasets/multivariate/LDPE/Hotellings_T2_A6.csv +0 -0
- {process_improve-1.82.0 → process_improve-1.83.2}/src/process_improve/datasets/multivariate/LDPE/LDPE.csv +0 -0
- {process_improve-1.82.0 → process_improve-1.83.2}/src/process_improve/datasets/multivariate/LDPE/P.csv +0 -0
- {process_improve-1.82.0 → process_improve-1.83.2}/src/process_improve/datasets/multivariate/LDPE/R.csv +0 -0
- {process_improve-1.82.0 → process_improve-1.83.2}/src/process_improve/datasets/multivariate/LDPE/T.csv +0 -0
- {process_improve-1.82.0 → process_improve-1.83.2}/src/process_improve/datasets/multivariate/LDPE/U.csv +0 -0
- {process_improve-1.82.0 → process_improve-1.83.2}/src/process_improve/datasets/multivariate/LDPE/W.csv +0 -0
- {process_improve-1.82.0 → process_improve-1.83.2}/src/process_improve/datasets/multivariate/LDPE/Yhat_A6.csv +0 -0
- {process_improve-1.82.0 → process_improve-1.83.2}/src/process_improve/datasets/multivariate/cheddar-cheese.csv +0 -0
- {process_improve-1.82.0 → process_improve-1.83.2}/src/process_improve/datasets/multivariate/dtu-pectin/NOTICE +0 -0
- {process_improve-1.82.0 → process_improve-1.83.2}/src/process_improve/datasets/multivariate/dtu-pectin/extraction1.csv +0 -0
- {process_improve-1.82.0 → process_improve-1.83.2}/src/process_improve/datasets/multivariate/dtu-pectin/extraction2.csv +0 -0
- {process_improve-1.82.0 → process_improve-1.83.2}/src/process_improve/datasets/multivariate/dtu-pectin/extraction3.csv +0 -0
- {process_improve-1.82.0 → process_improve-1.83.2}/src/process_improve/datasets/multivariate/dtu-pectin/ftir1.csv +0 -0
- {process_improve-1.82.0 → process_improve-1.83.2}/src/process_improve/datasets/multivariate/dtu-pectin/ftir2.csv +0 -0
- {process_improve-1.82.0 → process_improve-1.83.2}/src/process_improve/datasets/multivariate/dtu-pectin/ftir3.csv +0 -0
- {process_improve-1.82.0 → process_improve-1.83.2}/src/process_improve/datasets/multivariate/kamyr.csv +0 -0
- {process_improve-1.82.0 → process_improve-1.83.2}/src/process_improve/datasets/multivariate/solvents.csv +0 -0
- {process_improve-1.82.0 → process_improve-1.83.2}/src/process_improve/datasets/multivariate/tablet-spectra.csv +0 -0
- {process_improve-1.82.0 → process_improve-1.83.2}/src/process_improve/datasets/multivariate/tpls-pyphi/SOURCE +0 -0
- {process_improve-1.82.0 → process_improve-1.83.2}/src/process_improve/datasets/multivariate/tpls-pyphi/formulas_Group1.csv +0 -0
- {process_improve-1.82.0 → process_improve-1.83.2}/src/process_improve/datasets/multivariate/tpls-pyphi/formulas_Group2.csv +0 -0
- {process_improve-1.82.0 → process_improve-1.83.2}/src/process_improve/datasets/multivariate/tpls-pyphi/formulas_Group3.csv +0 -0
- {process_improve-1.82.0 → process_improve-1.83.2}/src/process_improve/datasets/multivariate/tpls-pyphi/formulas_Group4.csv +0 -0
- {process_improve-1.82.0 → process_improve-1.83.2}/src/process_improve/datasets/multivariate/tpls-pyphi/formulas_Group5.csv +0 -0
- {process_improve-1.82.0 → process_improve-1.83.2}/src/process_improve/datasets/multivariate/tpls-pyphi/process_conditions.csv +0 -0
- {process_improve-1.82.0 → process_improve-1.83.2}/src/process_improve/datasets/multivariate/tpls-pyphi/properties_Group1.csv +0 -0
- {process_improve-1.82.0 → process_improve-1.83.2}/src/process_improve/datasets/multivariate/tpls-pyphi/properties_Group2.csv +0 -0
- {process_improve-1.82.0 → process_improve-1.83.2}/src/process_improve/datasets/multivariate/tpls-pyphi/properties_Group3.csv +0 -0
- {process_improve-1.82.0 → process_improve-1.83.2}/src/process_improve/datasets/multivariate/tpls-pyphi/properties_Group4.csv +0 -0
- {process_improve-1.82.0 → process_improve-1.83.2}/src/process_improve/datasets/multivariate/tpls-pyphi/properties_Group5.csv +0 -0
- {process_improve-1.82.0 → process_improve-1.83.2}/src/process_improve/datasets/multivariate/tpls-pyphi/quality_indicators.csv +0 -0
- {process_improve-1.82.0 → process_improve-1.83.2}/src/process_improve/experiments/__init__.py +0 -0
- {process_improve-1.82.0 → process_improve-1.83.2}/src/process_improve/experiments/_analyses/__init__.py +0 -0
- {process_improve-1.82.0 → process_improve-1.83.2}/src/process_improve/experiments/_analyses/_shared.py +0 -0
- {process_improve-1.82.0 → process_improve-1.83.2}/src/process_improve/experiments/_analyses/box_cox.py +0 -0
- {process_improve-1.82.0 → process_improve-1.83.2}/src/process_improve/experiments/_analyses/curvature.py +0 -0
- {process_improve-1.82.0 → process_improve-1.83.2}/src/process_improve/experiments/_analyses/diagnostics.py +0 -0
- {process_improve-1.82.0 → process_improve-1.83.2}/src/process_improve/experiments/_analyses/lack_of_fit.py +0 -0
- {process_improve-1.82.0 → process_improve-1.83.2}/src/process_improve/experiments/_analyses/lenth.py +0 -0
- {process_improve-1.82.0 → process_improve-1.83.2}/src/process_improve/experiments/_analyses/model_selection.py +0 -0
- {process_improve-1.82.0 → process_improve-1.83.2}/src/process_improve/experiments/_analyses/ols_extractors.py +0 -0
- {process_improve-1.82.0 → process_improve-1.83.2}/src/process_improve/experiments/_analyses/prediction.py +0 -0
- {process_improve-1.82.0 → process_improve-1.83.2}/src/process_improve/experiments/_desirability.py +0 -0
- {process_improve-1.82.0 → process_improve-1.83.2}/src/process_improve/experiments/_lm.py +0 -0
- {process_improve-1.82.0 → process_improve-1.83.2}/src/process_improve/experiments/_moment_aberration.py +0 -0
- {process_improve-1.82.0 → process_improve-1.83.2}/src/process_improve/experiments/_tools/__init__.py +0 -0
- {process_improve-1.82.0 → process_improve-1.83.2}/src/process_improve/experiments/_tools/analyze_experiment.py +0 -0
- {process_improve-1.82.0 → process_improve-1.83.2}/src/process_improve/experiments/_tools/augment_design.py +0 -0
- {process_improve-1.82.0 → process_improve-1.83.2}/src/process_improve/experiments/_tools/create_factorial_design.py +0 -0
- {process_improve-1.82.0 → process_improve-1.83.2}/src/process_improve/experiments/_tools/doe_knowledge.py +0 -0
- {process_improve-1.82.0 → process_improve-1.83.2}/src/process_improve/experiments/_tools/evaluate_design.py +0 -0
- {process_improve-1.82.0 → process_improve-1.83.2}/src/process_improve/experiments/_tools/fit_linear_model.py +0 -0
- {process_improve-1.82.0 → process_improve-1.83.2}/src/process_improve/experiments/_tools/generate_design.py +0 -0
- {process_improve-1.82.0 → process_improve-1.83.2}/src/process_improve/experiments/_tools/optimize_responses.py +0 -0
- {process_improve-1.82.0 → process_improve-1.83.2}/src/process_improve/experiments/_tools/recommend_strategy.py +0 -0
- {process_improve-1.82.0 → process_improve-1.83.2}/src/process_improve/experiments/_tools/trade_off_table.py +0 -0
- {process_improve-1.82.0 → process_improve-1.83.2}/src/process_improve/experiments/_tools/visualize_doe.py +0 -0
- {process_improve-1.82.0 → process_improve-1.83.2}/src/process_improve/experiments/analysis.py +0 -0
- {process_improve-1.82.0 → process_improve-1.83.2}/src/process_improve/experiments/augment.py +0 -0
- {process_improve-1.82.0 → process_improve-1.83.2}/src/process_improve/experiments/datasets.py +0 -0
- {process_improve-1.82.0 → process_improve-1.83.2}/src/process_improve/experiments/designs.py +0 -0
- {process_improve-1.82.0 → process_improve-1.83.2}/src/process_improve/experiments/designs_factorial.py +0 -0
- {process_improve-1.82.0 → process_improve-1.83.2}/src/process_improve/experiments/designs_mixture.py +0 -0
- {process_improve-1.82.0 → process_improve-1.83.2}/src/process_improve/experiments/designs_omars.py +0 -0
- {process_improve-1.82.0 → process_improve-1.83.2}/src/process_improve/experiments/designs_omars_ilp.py +0 -0
- {process_improve-1.82.0 → process_improve-1.83.2}/src/process_improve/experiments/designs_optimal.py +0 -0
- {process_improve-1.82.0 → process_improve-1.83.2}/src/process_improve/experiments/designs_response_surface.py +0 -0
- {process_improve-1.82.0 → process_improve-1.83.2}/src/process_improve/experiments/designs_screening.py +0 -0
- {process_improve-1.82.0 → process_improve-1.83.2}/src/process_improve/experiments/designs_utils.py +0 -0
- {process_improve-1.82.0 → process_improve-1.83.2}/src/process_improve/experiments/evaluate.py +0 -0
- {process_improve-1.82.0 → process_improve-1.83.2}/src/process_improve/experiments/factor.py +0 -0
- {process_improve-1.82.0 → process_improve-1.83.2}/src/process_improve/experiments/knowledge/__init__.py +0 -0
- {process_improve-1.82.0 → process_improve-1.83.2}/src/process_improve/experiments/knowledge/api.py +0 -0
- {process_improve-1.82.0 → process_improve-1.83.2}/src/process_improve/experiments/knowledge/data/concepts.yaml +0 -0
- {process_improve-1.82.0 → process_improve-1.83.2}/src/process_improve/experiments/knowledge/data/decision_rules.yaml +0 -0
- {process_improve-1.82.0 → process_improve-1.83.2}/src/process_improve/experiments/knowledge/data/design_types.yaml +0 -0
- {process_improve-1.82.0 → process_improve-1.83.2}/src/process_improve/experiments/knowledge/data/diagnostics.yaml +0 -0
- {process_improve-1.82.0 → process_improve-1.83.2}/src/process_improve/experiments/knowledge/engine.py +0 -0
- {process_improve-1.82.0 → process_improve-1.83.2}/src/process_improve/experiments/knowledge/models.py +0 -0
- {process_improve-1.82.0 → process_improve-1.83.2}/src/process_improve/experiments/models.py +0 -0
- {process_improve-1.82.0 → process_improve-1.83.2}/src/process_improve/experiments/omars.py +0 -0
- {process_improve-1.82.0 → process_improve-1.83.2}/src/process_improve/experiments/omars_trade_off.py +0 -0
- {process_improve-1.82.0 → process_improve-1.83.2}/src/process_improve/experiments/optimal.py +0 -0
- {process_improve-1.82.0 → process_improve-1.83.2}/src/process_improve/experiments/optimization.py +0 -0
- {process_improve-1.82.0 → process_improve-1.83.2}/src/process_improve/experiments/simulations.py +0 -0
- {process_improve-1.82.0 → process_improve-1.83.2}/src/process_improve/experiments/strategy/__init__.py +0 -0
- {process_improve-1.82.0 → process_improve-1.83.2}/src/process_improve/experiments/strategy/budget.py +0 -0
- {process_improve-1.82.0 → process_improve-1.83.2}/src/process_improve/experiments/strategy/domain_templates.py +0 -0
- {process_improve-1.82.0 → process_improve-1.83.2}/src/process_improve/experiments/strategy/engine.py +0 -0
- {process_improve-1.82.0 → process_improve-1.83.2}/src/process_improve/experiments/strategy/models.py +0 -0
- {process_improve-1.82.0 → process_improve-1.83.2}/src/process_improve/experiments/structures.py +0 -0
- {process_improve-1.82.0 → process_improve-1.83.2}/src/process_improve/experiments/tools.py +0 -0
- {process_improve-1.82.0 → process_improve-1.83.2}/src/process_improve/experiments/trade_off.py +0 -0
- {process_improve-1.82.0 → process_improve-1.83.2}/src/process_improve/experiments/visualization/__init__.py +0 -0
- {process_improve-1.82.0 → process_improve-1.83.2}/src/process_improve/experiments/visualization/api.py +0 -0
- {process_improve-1.82.0 → process_improve-1.83.2}/src/process_improve/experiments/visualization/plots/__init__.py +0 -0
- {process_improve-1.82.0 → process_improve-1.83.2}/src/process_improve/experiments/visualization/plots/cube_plot.py +0 -0
- {process_improve-1.82.0 → process_improve-1.83.2}/src/process_improve/experiments/visualization/plots/design_quality.py +0 -0
- {process_improve-1.82.0 → process_improve-1.83.2}/src/process_improve/experiments/visualization/plots/diagnostics.py +0 -0
- {process_improve-1.82.0 → process_improve-1.83.2}/src/process_improve/experiments/visualization/plots/effects.py +0 -0
- {process_improve-1.82.0 → process_improve-1.83.2}/src/process_improve/experiments/visualization/plots/optimization_plots.py +0 -0
- {process_improve-1.82.0 → process_improve-1.83.2}/src/process_improve/experiments/visualization/plots/registry.py +0 -0
- {process_improve-1.82.0 → process_improve-1.83.2}/src/process_improve/experiments/visualization/plots/significance.py +0 -0
- {process_improve-1.82.0 → process_improve-1.83.2}/src/process_improve/experiments/visualization/plots/square_plot.py +0 -0
- {process_improve-1.82.0 → process_improve-1.83.2}/src/process_improve/experiments/visualization/plots/surfaces.py +0 -0
- {process_improve-1.82.0 → process_improve-1.83.2}/src/process_improve/interactions.py +0 -0
- {process_improve-1.82.0 → process_improve-1.83.2}/src/process_improve/mcp_server.py +0 -0
- {process_improve-1.82.0 → process_improve-1.83.2}/src/process_improve/monitoring/__init__.py +0 -0
- {process_improve-1.82.0 → process_improve-1.83.2}/src/process_improve/monitoring/control_charts.py +0 -0
- {process_improve-1.82.0 → process_improve-1.83.2}/src/process_improve/monitoring/metrics.py +0 -0
- {process_improve-1.82.0 → process_improve-1.83.2}/src/process_improve/monitoring/tools.py +0 -0
- {process_improve-1.82.0 → process_improve-1.83.2}/src/process_improve/multivariate/__init__.py +0 -0
- {process_improve-1.82.0 → process_improve-1.83.2}/src/process_improve/multivariate/_adaptive.py +0 -0
- {process_improve-1.82.0 → process_improve-1.83.2}/src/process_improve/multivariate/_base.py +0 -0
- {process_improve-1.82.0 → process_improve-1.83.2}/src/process_improve/multivariate/_common.py +0 -0
- {process_improve-1.82.0 → process_improve-1.83.2}/src/process_improve/multivariate/_diagnostics.py +0 -0
- {process_improve-1.82.0 → process_improve-1.83.2}/src/process_improve/multivariate/_limits.py +0 -0
- {process_improve-1.82.0 → process_improve-1.83.2}/src/process_improve/multivariate/_mbpca.py +0 -0
- {process_improve-1.82.0 → process_improve-1.83.2}/src/process_improve/multivariate/_nipals.py +0 -0
- {process_improve-1.82.0 → process_improve-1.83.2}/src/process_improve/multivariate/_null.py +0 -0
- {process_improve-1.82.0 → process_improve-1.83.2}/src/process_improve/multivariate/_opls.py +0 -0
- {process_improve-1.82.0 → process_improve-1.83.2}/src/process_improve/multivariate/_pca_pls.py +0 -0
- {process_improve-1.82.0 → process_improve-1.83.2}/src/process_improve/multivariate/_pls.py +0 -0
- {process_improve-1.82.0 → process_improve-1.83.2}/src/process_improve/multivariate/_preprocessing.py +0 -0
- {process_improve-1.82.0 → process_improve-1.83.2}/src/process_improve/multivariate/_projection.py +0 -0
- {process_improve-1.82.0 → process_improve-1.83.2}/src/process_improve/multivariate/_resampling.py +0 -0
- {process_improve-1.82.0 → process_improve-1.83.2}/src/process_improve/multivariate/_tpls.py +0 -0
- {process_improve-1.82.0 → process_improve-1.83.2}/src/process_improve/multivariate/methods.py +0 -0
- {process_improve-1.82.0 → process_improve-1.83.2}/src/process_improve/multivariate/plots.py +0 -0
- {process_improve-1.82.0 → process_improve-1.83.2}/src/process_improve/multivariate/tools.py +0 -0
- {process_improve-1.82.0 → process_improve-1.83.2}/src/process_improve/py.typed +0 -0
- {process_improve-1.82.0 → process_improve-1.83.2}/src/process_improve/recipes.py +0 -0
- {process_improve-1.82.0 → process_improve-1.83.2}/src/process_improve/regression/__init__.py +0 -0
- {process_improve-1.82.0 → process_improve-1.83.2}/src/process_improve/regression/_robust_regression.py +0 -0
- {process_improve-1.82.0 → process_improve-1.83.2}/src/process_improve/regression/methods.py +0 -0
- {process_improve-1.82.0 → process_improve-1.83.2}/src/process_improve/regression/tools.py +0 -0
- {process_improve-1.82.0 → process_improve-1.83.2}/src/process_improve/sensory/__init__.py +0 -0
- {process_improve-1.82.0 → process_improve-1.83.2}/src/process_improve/sensory/analysis.py +0 -0
- {process_improve-1.82.0 → process_improve-1.83.2}/src/process_improve/sensory/designed.py +0 -0
- {process_improve-1.82.0 → process_improve-1.83.2}/src/process_improve/sensory/diagnostics.py +0 -0
- {process_improve-1.82.0 → process_improve-1.83.2}/src/process_improve/sensory/ingest.py +0 -0
- {process_improve-1.82.0 → process_improve-1.83.2}/src/process_improve/sensory/mam.py +0 -0
- {process_improve-1.82.0 → process_improve-1.83.2}/src/process_improve/sensory/panel.py +0 -0
- {process_improve-1.82.0 → process_improve-1.83.2}/src/process_improve/sensory/recipes.py +0 -0
- {process_improve-1.82.0 → process_improve-1.83.2}/src/process_improve/sensory/tools.py +0 -0
- {process_improve-1.82.0 → process_improve-1.83.2}/src/process_improve/sensory/validation.py +0 -0
- {process_improve-1.82.0 → process_improve-1.83.2}/src/process_improve/simulation/__init__.py +0 -0
- {process_improve-1.82.0 → process_improve-1.83.2}/src/process_improve/simulation/batch.py +0 -0
- {process_improve-1.82.0 → process_improve-1.83.2}/src/process_improve/simulation/context.py +0 -0
- {process_improve-1.82.0 → process_improve-1.83.2}/src/process_improve/simulation/model.py +0 -0
- {process_improve-1.82.0 → process_improve-1.83.2}/src/process_improve/simulation/recipes.py +0 -0
- {process_improve-1.82.0 → process_improve-1.83.2}/src/process_improve/simulation/tools.py +0 -0
- {process_improve-1.82.0 → process_improve-1.83.2}/src/process_improve/tool_safety.py +0 -0
- {process_improve-1.82.0 → process_improve-1.83.2}/src/process_improve/tool_spec.py +0 -0
- {process_improve-1.82.0 → process_improve-1.83.2}/src/process_improve/univariate/__init__.py +0 -0
- {process_improve-1.82.0 → process_improve-1.83.2}/src/process_improve/univariate/metrics.py +0 -0
- {process_improve-1.82.0 → process_improve-1.83.2}/src/process_improve/univariate/tools.py +0 -0
- {process_improve-1.82.0 → process_improve-1.83.2}/src/process_improve/visualization/__init__.py +0 -0
- {process_improve-1.82.0 → process_improve-1.83.2}/src/process_improve/visualization/adapters/__init__.py +0 -0
- {process_improve-1.82.0 → process_improve-1.83.2}/src/process_improve/visualization/adapters/base.py +0 -0
- {process_improve-1.82.0 → process_improve-1.83.2}/src/process_improve/visualization/adapters/echarts_adapter.py +0 -0
- {process_improve-1.82.0 → process_improve-1.83.2}/src/process_improve/visualization/adapters/plotly_adapter.py +0 -0
- {process_improve-1.82.0 → process_improve-1.83.2}/src/process_improve/visualization/charts/__init__.py +0 -0
- {process_improve-1.82.0 → process_improve-1.83.2}/src/process_improve/visualization/charts/boxplot.py +0 -0
- {process_improve-1.82.0 → process_improve-1.83.2}/src/process_improve/visualization/colors.py +0 -0
- {process_improve-1.82.0 → process_improve-1.83.2}/src/process_improve/visualization/raincloud.py +0 -0
- {process_improve-1.82.0 → process_improve-1.83.2}/src/process_improve/visualization/spec.py +0 -0
- {process_improve-1.82.0 → process_improve-1.83.2}/src/process_improve/visualization/themes.py +0 -0
- {process_improve-1.82.0 → process_improve-1.83.2}/src/process_improve/visualization/tools.py +0 -0
- {process_improve-1.82.0 → process_improve-1.83.2}/src/process_improve/visualization/types.py +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: process-improve
|
|
3
|
-
Version: 1.
|
|
3
|
+
Version: 1.83.2
|
|
4
4
|
Summary: Designed Experiments; Latent Variables (PCA, PLS, multivariate methods with missing data); Process Monitoring; Batch data analysis.
|
|
5
5
|
Keywords: Designed Experiments,Latent Variables,PCA,PLS,Multivariate Data Analysis,Batch data analysis
|
|
6
6
|
Author: Kevin Dunn
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
[project]
|
|
2
2
|
name = "process-improve"
|
|
3
|
-
version = "1.
|
|
3
|
+
version = "1.83.2"
|
|
4
4
|
description = "Designed Experiments; Latent Variables (PCA, PLS, multivariate methods with missing data); Process Monitoring; Batch data analysis."
|
|
5
5
|
readme = "README.md"
|
|
6
6
|
license = "MIT"
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
[project]
|
|
2
2
|
name = "process-improve"
|
|
3
|
-
version = "1.
|
|
3
|
+
version = "1.83.2"
|
|
4
4
|
description = 'Designed Experiments; Latent Variables (PCA, PLS, multivariate methods with missing data); Process Monitoring; Batch data analysis.'
|
|
5
5
|
readme = "README.md"
|
|
6
6
|
license = "MIT"
|
{process_improve-1.82.0 → process_improve-1.83.2}/src/process_improve/multivariate/_mbpls.py
RENAMED
|
@@ -39,6 +39,63 @@ except ImportError: # pragma: no cover - exercised via env-without-plotly
|
|
|
39
39
|
logger = logging.getLogger(__name__)
|
|
40
40
|
|
|
41
41
|
|
|
42
|
+
def _stacked_super_weights(
|
|
43
|
+
block_weights: dict[str, np.ndarray],
|
|
44
|
+
super_weight: np.ndarray,
|
|
45
|
+
sqrt_kb: dict[str, float],
|
|
46
|
+
block_names: Sequence[str],
|
|
47
|
+
) -> np.ndarray:
|
|
48
|
+
r"""Give the super score's weight on every variable, stacked over the blocks in ``block_names`` order.
|
|
49
|
+
|
|
50
|
+
Written out over the variables rather than over the blocks,
|
|
51
|
+
|
|
52
|
+
.. math::
|
|
53
|
+
t_i = \frac{1}{\mathbf{w}_s' \mathbf{w}_s} \sum_b w_{s,b}
|
|
54
|
+
\frac{\mathbf{x}_{ib}' \mathbf{w}_b}{\sqrt{K_b}}
|
|
55
|
+
= \frac{\mathbf{x}_i' \mathbf{g}}{\mathbf{w}_s' \mathbf{w}_s},
|
|
56
|
+
\qquad
|
|
57
|
+
\mathbf{g} = \big[\, w_{s,b}\, \mathbf{w}_b / \sqrt{K_b} \,\big]_b
|
|
58
|
+
|
|
59
|
+
the super score is one linear combination of all the variables of all the blocks.
|
|
60
|
+
``g`` is that combination.
|
|
61
|
+
"""
|
|
62
|
+
return np.concatenate([super_weight[b] * block_weights[name] / sqrt_kb[name] for b, name in enumerate(block_names)])
|
|
63
|
+
|
|
64
|
+
|
|
65
|
+
def _pooled_super_score(
|
|
66
|
+
x_def: dict[str, np.ndarray],
|
|
67
|
+
stacked_weights: np.ndarray,
|
|
68
|
+
super_weight: np.ndarray,
|
|
69
|
+
block_names: Sequence[str],
|
|
70
|
+
) -> np.ndarray:
|
|
71
|
+
r"""Score every row by one masked regression of the whole row onto the stacked weights.
|
|
72
|
+
|
|
73
|
+
The alternative is to score each block on its own and add the per-block scores up. On a
|
|
74
|
+
complete row the two give the same number, but they part company as soon as a row has missing
|
|
75
|
+
cells: a block observed in one variable out of twenty still hands a score built on that one
|
|
76
|
+
variable into the sum, weighted as though it were as well determined as the others. Regressing
|
|
77
|
+
the whole row at once instead lets every cell the row does have carry its share, wherever in
|
|
78
|
+
the blocks that cell sits.
|
|
79
|
+
|
|
80
|
+
The ratio is rescaled by :math:`\mathbf{g}'\mathbf{g}` so a complete row reproduces the
|
|
81
|
+
weighted sum of block scores exactly, which is what leaves every complete-data model
|
|
82
|
+
unchanged. A row with nothing observed under a non-zero weight has no score: it comes back
|
|
83
|
+
as NaN.
|
|
84
|
+
"""
|
|
85
|
+
stacked_x = np.hstack([x_def[name] for name in block_names])
|
|
86
|
+
observed = ~np.isnan(stacked_x)
|
|
87
|
+
numerator = np.nan_to_num(stacked_x) @ stacked_weights
|
|
88
|
+
denominator = observed @ (stacked_weights**2)
|
|
89
|
+
scale = float(stacked_weights @ stacked_weights) / _nz(float(super_weight @ super_weight))
|
|
90
|
+
usable = denominator > 0
|
|
91
|
+
return np.where(usable, numerator / np.where(usable, denominator, 1.0) * scale, np.nan)
|
|
92
|
+
|
|
93
|
+
|
|
94
|
+
def _rows_with_data(values: np.ndarray) -> np.ndarray:
|
|
95
|
+
"""Report, for each row, whether it has at least one observed cell."""
|
|
96
|
+
return np.any(~np.isnan(values), axis=1)
|
|
97
|
+
|
|
98
|
+
|
|
42
99
|
class MBPLS(_HotellingsT2LimitMixin, RegressorMixin, BaseEstimator):
|
|
43
100
|
r"""Multi-block PLS (hierarchical / superblock formulation).
|
|
44
101
|
|
|
@@ -75,6 +132,14 @@ class MBPLS(_HotellingsT2LimitMixin, RegressorMixin, BaseEstimator):
|
|
|
75
132
|
complete (slower than ``"dense"`` but produces equivalent
|
|
76
133
|
results).
|
|
77
134
|
|
|
135
|
+
With missing data the super score of each row is estimated by one masked regression of
|
|
136
|
+
the whole row onto the stacked block weights, rather than by adding up a score per block.
|
|
137
|
+
The two are the same number on a complete row, so no fitted model changes; on an
|
|
138
|
+
incomplete row the pooled form lets every observed cell carry its share, wherever in the
|
|
139
|
+
blocks it sits, instead of letting a block seen in one variable speak as loudly as a block
|
|
140
|
+
seen in twenty. A row with nothing observed in one block is therefore still scored, from
|
|
141
|
+
the blocks it does have; only a row observed in no block at all is refused.
|
|
142
|
+
|
|
78
143
|
missing_data_settings : dict or None, default=None
|
|
79
144
|
Settings for the iterative ``"nipals"`` path. Keys: ``md_tol``
|
|
80
145
|
(convergence tolerance on the score-vector change between
|
|
@@ -101,7 +166,8 @@ class MBPLS(_HotellingsT2LimitMixin, RegressorMixin, BaseEstimator):
|
|
|
101
166
|
y_preproc_ : MCUVScaler
|
|
102
167
|
Preprocessor used on Y.
|
|
103
168
|
super_scores_ : pd.DataFrame, shape (n_samples, n_components)
|
|
104
|
-
Super-block (consensus) X-scores ``T``.
|
|
169
|
+
Super-block (consensus) X-scores ``T``. Finite for every row that has at least one
|
|
170
|
+
observed cell, in any block.
|
|
105
171
|
super_y_scores_ : pd.DataFrame, shape (n_samples, n_components)
|
|
106
172
|
Super-block Y-scores ``U``.
|
|
107
173
|
super_weights_ : pd.DataFrame, shape (n_blocks, n_components)
|
|
@@ -114,7 +180,9 @@ class MBPLS(_HotellingsT2LimitMixin, RegressorMixin, BaseEstimator):
|
|
|
114
180
|
Variable-importance in projection for each X-block, indexed by
|
|
115
181
|
block name.
|
|
116
182
|
block_scores_ : dict[str, pd.DataFrame]
|
|
117
|
-
Per-block X-scores ``t_b``, each shape ``(n_samples, n_components)``.
|
|
183
|
+
Per-block X-scores ``t_b``, each shape ``(n_samples, n_components)``. NaN for a row with
|
|
184
|
+
nothing observed in that block: the block has no score of its own there, and reporting
|
|
185
|
+
zero would place the row at the block's average instead.
|
|
118
186
|
block_weights_ : dict[str, pd.DataFrame]
|
|
119
187
|
Per-block X-weights ``w_b``, each shape ``(K_b, n_components)``.
|
|
120
188
|
Each column has unit norm.
|
|
@@ -122,7 +190,8 @@ class MBPLS(_HotellingsT2LimitMixin, RegressorMixin, BaseEstimator):
|
|
|
122
190
|
Per-block X-loadings ``p_b`` (used for deflation), each shape
|
|
123
191
|
``(K_b, n_components)``.
|
|
124
192
|
block_spe_ : dict[str, pd.DataFrame]
|
|
125
|
-
Per-block squared prediction error per sample and component.
|
|
193
|
+
Per-block squared prediction error per sample and component. NaN where the row has
|
|
194
|
+
nothing observed in that block, for the same reason as ``block_scores_``.
|
|
126
195
|
block_hotellings_t2_ : dict[str, pd.DataFrame]
|
|
127
196
|
Per-block cumulative Hotelling's T^2 per sample and component.
|
|
128
197
|
block_vip_ : dict[str, pd.Series]
|
|
@@ -306,10 +375,12 @@ class MBPLS(_HotellingsT2LimitMixin, RegressorMixin, BaseEstimator):
|
|
|
306
375
|
raise ValueError("Tolerance should not be too large.")
|
|
307
376
|
if not settings["md_tol"] > epsqrt**1.95:
|
|
308
377
|
raise ValueError("Tolerance must exceed machine precision.")
|
|
309
|
-
# Degeneracy guards
|
|
310
|
-
#
|
|
311
|
-
#
|
|
312
|
-
#
|
|
378
|
+
# Degeneracy guards. A column with nothing in it leaves the masked NIPALS denominator
|
|
379
|
+
# at zero for that variable's loading, so it is refused. A *row* with nothing in one
|
|
380
|
+
# block is allowed: the super score is estimated from the cells that row has in the
|
|
381
|
+
# other blocks, which is the multiblock case of an observation missing one whole
|
|
382
|
+
# analysis. Only a row with nothing observed in any block carries no information at
|
|
383
|
+
# all, and that one is refused.
|
|
313
384
|
for name in self.block_names_:
|
|
314
385
|
values = X[name].values
|
|
315
386
|
col_all_nan = np.all(np.isnan(values), axis=0)
|
|
@@ -318,13 +389,15 @@ class MBPLS(_HotellingsT2LimitMixin, RegressorMixin, BaseEstimator):
|
|
|
318
389
|
raise ValueError(
|
|
319
390
|
f"Block '{name}' has columns with all values missing: {bad}. Drop these columns before fitting."
|
|
320
391
|
)
|
|
321
|
-
|
|
322
|
-
|
|
323
|
-
|
|
324
|
-
|
|
325
|
-
|
|
326
|
-
|
|
327
|
-
|
|
392
|
+
observed_anywhere = np.zeros(n_samples, dtype=bool)
|
|
393
|
+
for name in self.block_names_:
|
|
394
|
+
observed_anywhere |= _rows_with_data(X[name].values)
|
|
395
|
+
if not np.all(observed_anywhere):
|
|
396
|
+
bad_rows = np.where(~observed_anywhere)[0].tolist()
|
|
397
|
+
raise ValueError(
|
|
398
|
+
f"Rows at positions {bad_rows} have all values missing in every X-block. "
|
|
399
|
+
"Drop these observations or impute them before fitting."
|
|
400
|
+
)
|
|
328
401
|
y_values = y.values
|
|
329
402
|
y_col_all_nan = np.all(np.isnan(y_values), axis=0)
|
|
330
403
|
if np.any(y_col_all_nan):
|
|
@@ -348,6 +421,9 @@ class MBPLS(_HotellingsT2LimitMixin, RegressorMixin, BaseEstimator):
|
|
|
348
421
|
|
|
349
422
|
# Algorithmic block weighting: X_b / sqrt(K_b)
|
|
350
423
|
sqrt_kb = {name: float(np.sqrt(self.block_widths_[name])) for name in self.block_names_}
|
|
424
|
+
# A row with nothing observed in a block has no score *for that block*; it still has a
|
|
425
|
+
# super score, estimated from the blocks it does have.
|
|
426
|
+
block_has_data = {name: _rows_with_data(x_blocks_pp[name]) for name in self.block_names_}
|
|
351
427
|
|
|
352
428
|
# Storage (numpy arrays during fit; wrapped in pandas at the end)
|
|
353
429
|
super_scores_np = np.zeros((n_samples, n_components))
|
|
@@ -425,7 +501,7 @@ class MBPLS(_HotellingsT2LimitMixin, RegressorMixin, BaseEstimator):
|
|
|
425
501
|
t_b = quick_regress(x_def[name], w_b.reshape(-1, 1)).flatten() / sqrt_kb[name]
|
|
426
502
|
local_w[name] = w_b
|
|
427
503
|
local_t[name] = t_b
|
|
428
|
-
t_b_summary[:, b_idx] = t_b
|
|
504
|
+
t_b_summary[:, b_idx] = np.where(block_has_data[name], t_b, np.nan)
|
|
429
505
|
else:
|
|
430
506
|
for b_idx, name in enumerate(self.block_names_):
|
|
431
507
|
w_b = x_def[name].T @ u_a / _nz(float(u_a @ u_a))
|
|
@@ -435,9 +511,25 @@ class MBPLS(_HotellingsT2LimitMixin, RegressorMixin, BaseEstimator):
|
|
|
435
511
|
local_t[name] = t_b
|
|
436
512
|
t_b_summary[:, b_idx] = t_b
|
|
437
513
|
|
|
438
|
-
|
|
514
|
+
if algo == "nipals":
|
|
515
|
+
# Masked, so a block this row has nothing in does not vote on the super weight.
|
|
516
|
+
w_s = quick_regress(t_b_summary, u_a.reshape(-1, 1)).flatten()
|
|
517
|
+
else:
|
|
518
|
+
w_s = t_b_summary.T @ u_a / _nz(float(u_a @ u_a))
|
|
439
519
|
w_s = w_s / _nz(float(np.linalg.norm(w_s)))
|
|
440
|
-
|
|
520
|
+
# One masked regression of the whole row onto the stacked weights, rather than a
|
|
521
|
+
# weighted sum of per-block scores: identical on complete rows, and on a row with
|
|
522
|
+
# missing cells it uses every cell the row has instead of one score per block.
|
|
523
|
+
t_super = _pooled_super_score(
|
|
524
|
+
x_def,
|
|
525
|
+
_stacked_super_weights(local_w, w_s, sqrt_kb, self.block_names_),
|
|
526
|
+
w_s,
|
|
527
|
+
self.block_names_,
|
|
528
|
+
)
|
|
529
|
+
# A row observed only where the weights are zero has no score for this component:
|
|
530
|
+
# place it at the centre so the iteration stays finite. The guard above has already
|
|
531
|
+
# refused a row with nothing observed anywhere.
|
|
532
|
+
t_super = np.nan_to_num(t_super)
|
|
441
533
|
if algo == "nipals":
|
|
442
534
|
t_super_col = t_super.reshape(-1, 1)
|
|
443
535
|
c_a = quick_regress(y_def, t_super_col).flatten()
|
|
@@ -468,7 +560,7 @@ class MBPLS(_HotellingsT2LimitMixin, RegressorMixin, BaseEstimator):
|
|
|
468
560
|
x_def[name] = x_def[name] - np.outer(t_super, p_b)
|
|
469
561
|
block_loadings_np[name][:, a] = p_b
|
|
470
562
|
block_weights_np[name][:, a] = local_w[name]
|
|
471
|
-
block_scores_np[name][:, a] = local_t[name]
|
|
563
|
+
block_scores_np[name][:, a] = np.where(block_has_data[name], local_t[name], np.nan)
|
|
472
564
|
y_def = y_def - np.outer(t_super, c_a)
|
|
473
565
|
|
|
474
566
|
super_scores_np[:, a] = t_super
|
|
@@ -490,7 +582,9 @@ class MBPLS(_HotellingsT2LimitMixin, RegressorMixin, BaseEstimator):
|
|
|
490
582
|
1 - ssq_remain_per_var / np.where(ssq_x_init_per_var[name] > 0, ssq_x_init_per_var[name], 1.0),
|
|
491
583
|
np.nan,
|
|
492
584
|
)
|
|
493
|
-
block_spe_np[name][:, a] = np.
|
|
585
|
+
block_spe_np[name][:, a] = np.where(
|
|
586
|
+
block_has_data[name], np.sqrt(np.nansum(x_def[name] ** 2, axis=1)), np.nan
|
|
587
|
+
)
|
|
494
588
|
ssq_y_remain_per_var = np.nansum(y_def**2, axis=0)
|
|
495
589
|
r2_y_cum[a] = 1 - np.sum(ssq_y_remain_per_var) / ssq_y_init if ssq_y_init > 0 else np.nan
|
|
496
590
|
r2_y_var_cum[:, a] = np.where(
|
|
@@ -694,10 +788,13 @@ class MBPLS(_HotellingsT2LimitMixin, RegressorMixin, BaseEstimator):
|
|
|
694
788
|
|
|
695
789
|
sqrt_kb = {name: float(np.sqrt(self.block_widths_[name])) for name in self.block_names_}
|
|
696
790
|
for a in range(int(component) - 1):
|
|
697
|
-
|
|
698
|
-
|
|
791
|
+
w_s = self.super_weights_.values[:, a]
|
|
792
|
+
weights = {name: self.block_weights_[name].values[:, a] for name in self.block_names_}
|
|
793
|
+
t_super = np.nan_to_num(
|
|
794
|
+
_pooled_super_score(
|
|
795
|
+
x_def, _stacked_super_weights(weights, w_s, sqrt_kb, self.block_names_), w_s, self.block_names_
|
|
796
|
+
)
|
|
699
797
|
)
|
|
700
|
-
t_super = t_b_row @ self.super_weights_.values[:, a]
|
|
701
798
|
for name in self.block_names_:
|
|
702
799
|
p_b = self.block_loadings_[name].values[:, a]
|
|
703
800
|
x_def[name] = x_def[name] - np.outer(t_super, p_b)
|
|
@@ -974,19 +1071,24 @@ class MBPLS(_HotellingsT2LimitMixin, RegressorMixin, BaseEstimator):
|
|
|
974
1071
|
block_scores: dict[str, np.ndarray] = {name: np.zeros((n_new, n_components)) for name in self.block_names_}
|
|
975
1072
|
|
|
976
1073
|
x_def = {name: x_pp[name].copy() for name in self.block_names_}
|
|
1074
|
+
block_has_data = {name: _rows_with_data(x_pp[name]) for name in self.block_names_}
|
|
977
1075
|
for a in range(n_components):
|
|
978
|
-
|
|
979
|
-
for
|
|
1076
|
+
weights = {}
|
|
1077
|
+
for name in self.block_names_:
|
|
980
1078
|
w_b = self.block_weights_[name].values[:, a]
|
|
981
|
-
|
|
982
|
-
|
|
983
|
-
|
|
1079
|
+
weights[name] = w_b
|
|
1080
|
+
t_b = quick_regress(x_def[name], w_b.reshape(-1, 1)).flatten() / sqrt_kb[name]
|
|
1081
|
+
block_scores[name][:, a] = np.where(block_has_data[name], t_b, np.nan)
|
|
984
1082
|
w_s = self.super_weights_.values[:, a]
|
|
985
|
-
|
|
1083
|
+
# The same pooled regression the fit uses, so a projected score matches a fitted one.
|
|
1084
|
+
t_super = _pooled_super_score(
|
|
1085
|
+
x_def, _stacked_super_weights(weights, w_s, sqrt_kb, self.block_names_), w_s, self.block_names_
|
|
1086
|
+
)
|
|
986
1087
|
super_scores[:, a] = t_super
|
|
1088
|
+
t_super_finite = np.nan_to_num(t_super)
|
|
987
1089
|
for name in self.block_names_:
|
|
988
1090
|
p_b = self.block_loadings_[name].values[:, a]
|
|
989
|
-
x_def[name] = x_def[name] - np.outer(
|
|
1091
|
+
x_def[name] = x_def[name] - np.outer(t_super_finite, p_b)
|
|
990
1092
|
|
|
991
1093
|
component_names = list(range(1, n_components + 1))
|
|
992
1094
|
super_scores_df = pd.DataFrame(super_scores, index=sample_index, columns=component_names)
|
|
@@ -156,6 +156,10 @@ def _pca_ekf_press( # noqa: PLR0913, PLR0915, PLR0912, C901
|
|
|
156
156
|
X = np.asarray(X, dtype=float)
|
|
157
157
|
n, p = X.shape
|
|
158
158
|
rng = np.random.default_rng(random_state)
|
|
159
|
+
# A cell the caller never measured has no true value to predict, so it is
|
|
160
|
+
# never held out and never scored. It still has to be filled for the SVD,
|
|
161
|
+
# which cannot see a NaN, so EM imputes it alongside the held-out cells.
|
|
162
|
+
observed = ~np.isnan(X)
|
|
159
163
|
|
|
160
164
|
total_folds = n_folds * n_repeats
|
|
161
165
|
# NaN, not zero: a fold that holds out no cells has no PRESS, and leaving
|
|
@@ -176,20 +180,21 @@ def _pca_ekf_press( # noqa: PLR0913, PLR0915, PLR0912, C901
|
|
|
176
180
|
press_input_units = np.zeros(max_components)
|
|
177
181
|
fold_counter = 0
|
|
178
182
|
|
|
179
|
-
|
|
183
|
+
observed_positions = np.flatnonzero(observed)
|
|
184
|
+
n_cells = observed_positions.size
|
|
180
185
|
fold_size = n_cells // n_folds
|
|
181
186
|
|
|
182
187
|
for _ in range(n_repeats):
|
|
183
|
-
# Assign cells to folds via a balanced random permutation
|
|
184
|
-
# fold has ~
|
|
185
|
-
# same row).
|
|
188
|
+
# Assign the observed cells to folds via a balanced random permutation
|
|
189
|
+
# so every fold has ~n_cells/n_folds cells (not all the same column,
|
|
190
|
+
# not the same row). Unmeasured cells stay at -1 and match no fold.
|
|
186
191
|
perm = rng.permutation(n_cells)
|
|
187
|
-
|
|
192
|
+
flat_fold = np.full(n * p, -1, dtype=np.int64)
|
|
188
193
|
for k in range(n_folds):
|
|
189
194
|
start = k * fold_size
|
|
190
195
|
end = (k + 1) * fold_size if k < n_folds - 1 else n_cells
|
|
191
|
-
|
|
192
|
-
fold =
|
|
196
|
+
flat_fold[observed_positions[perm[start:end]]] = k
|
|
197
|
+
fold = flat_fold.reshape(n, p)
|
|
193
198
|
|
|
194
199
|
for k in range(n_folds):
|
|
195
200
|
mask = fold == k # (n, p) bool, True where the cell is held out
|
|
@@ -203,8 +208,11 @@ def _pca_ekf_press( # noqa: PLR0913, PLR0915, PLR0912, C901
|
|
|
203
208
|
# scales the matrix it fits, and recomputes nothing inside EM.
|
|
204
209
|
col_centre = np.zeros(p)
|
|
205
210
|
col_scale = np.ones(p)
|
|
211
|
+
# Held out this fold, or never measured: both are unknown to the
|
|
212
|
+
# fit and both are filled by EM below. Only ``mask`` is scored.
|
|
213
|
+
impute = mask | ~observed
|
|
206
214
|
for j in range(p):
|
|
207
|
-
in_fold = X[~
|
|
215
|
+
in_fold = X[~impute[:, j], j]
|
|
208
216
|
if in_fold.size > 1:
|
|
209
217
|
col_centre[j] = float(in_fold.mean())
|
|
210
218
|
if scale_inside_folds:
|
|
@@ -218,7 +226,7 @@ def _pca_ekf_press( # noqa: PLR0913, PLR0915, PLR0912, C901
|
|
|
218
226
|
# ``scale_inside_folds=True``, and the same value under False).
|
|
219
227
|
Xtr = X.copy()
|
|
220
228
|
for j in range(p):
|
|
221
|
-
m_j =
|
|
229
|
+
m_j = impute[:, j]
|
|
222
230
|
if m_j.any():
|
|
223
231
|
Xtr[m_j, j] = col_centre[j]
|
|
224
232
|
|
|
@@ -239,7 +247,7 @@ def _pca_ekf_press( # noqa: PLR0913, PLR0915, PLR0912, C901
|
|
|
239
247
|
# re-expressed in different units dominates the norm and changes
|
|
240
248
|
# how many EM iterations are taken (#546). Under
|
|
241
249
|
# scale_inside_folds=False the divisor is 1 throughout.
|
|
242
|
-
prev_held = Xa[
|
|
250
|
+
prev_held = Xa[impute] / np.broadcast_to(col_scale, X.shape)[impute]
|
|
243
251
|
for _iteration in range(n_iter):
|
|
244
252
|
if scale_inside_folds:
|
|
245
253
|
# Centre and scale by the FIXED in-fold constants; the
|
|
@@ -260,8 +268,8 @@ def _pca_ekf_press( # noqa: PLR0913, PLR0915, PLR0912, C901
|
|
|
260
268
|
rank = min(a, S.shape[0])
|
|
261
269
|
recon_centred = (Xc @ Vt[:rank].T) @ Vt[:rank]
|
|
262
270
|
recon = recon_centred + col_mean
|
|
263
|
-
Xa[
|
|
264
|
-
held = Xa[
|
|
271
|
+
Xa[impute] = recon[impute]
|
|
272
|
+
held = Xa[impute] / np.broadcast_to(col_scale, X.shape)[impute]
|
|
265
273
|
delta = np.linalg.norm(held - prev_held)
|
|
266
274
|
scale = max(1.0, float(np.linalg.norm(prev_held)))
|
|
267
275
|
if delta < tol * scale:
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{process_improve-1.82.0 → process_improve-1.83.2}/src/process_improve/batch/_batch_monitor.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{process_improve-1.82.0 → process_improve-1.83.2}/src/process_improve/batch/alignment_helpers.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{process_improve-1.82.0 → process_improve-1.83.2}/src/process_improve/batch/preprocessing.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
{process_improve-1.82.0 → process_improve-1.83.2}/src/process_improve/bivariate/_elbow_peak.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{process_improve-1.82.0 → process_improve-1.83.2}/src/process_improve/chemistry/preprocessing.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
{process_improve-1.82.0 → process_improve-1.83.2}/src/process_improve/datasets/batch/details.txt
RENAMED
|
File without changes
|
{process_improve-1.82.0 → process_improve-1.83.2}/src/process_improve/datasets/batch/dryer.csv
RENAMED
|
File without changes
|
{process_improve-1.82.0 → process_improve-1.83.2}/src/process_improve/datasets/batch/nylon.csv
RENAMED
|
File without changes
|
|
File without changes
|
{process_improve-1.82.0 → process_improve-1.83.2}/src/process_improve/datasets/experiments/golf.csv
RENAMED
|
File without changes
|
|
File without changes
|
{process_improve-1.82.0 → process_improve-1.83.2}/src/process_improve/datasets/experiments/solar.csv
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{process_improve-1.82.0 → process_improve-1.83.2}/src/process_improve/experiments/__init__.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{process_improve-1.82.0 → process_improve-1.83.2}/src/process_improve/experiments/_analyses/lenth.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{process_improve-1.82.0 → process_improve-1.83.2}/src/process_improve/experiments/_desirability.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
{process_improve-1.82.0 → process_improve-1.83.2}/src/process_improve/experiments/_tools/__init__.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|