scitex 2.0.0__py2.py3-none-any.whl → 2.1.0__py2.py3-none-any.whl
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.
- scitex/__init__.py +53 -15
- scitex/__main__.py +72 -26
- scitex/__version__.py +1 -1
- scitex/_sh.py +145 -23
- scitex/ai/__init__.py +30 -16
- scitex/ai/_gen_ai/_Anthropic.py +5 -7
- scitex/ai/_gen_ai/_BaseGenAI.py +2 -2
- scitex/ai/_gen_ai/_DeepSeek.py +10 -2
- scitex/ai/_gen_ai/_Google.py +2 -2
- scitex/ai/_gen_ai/_Llama.py +2 -2
- scitex/ai/_gen_ai/_OpenAI.py +2 -2
- scitex/ai/_gen_ai/_PARAMS.py +51 -65
- scitex/ai/_gen_ai/_Perplexity.py +2 -2
- scitex/ai/_gen_ai/__init__.py +25 -14
- scitex/ai/_gen_ai/_format_output_func.py +4 -4
- scitex/ai/classification/{classifier_server.py → Classifier.py} +5 -5
- scitex/ai/classification/CrossValidationExperiment.py +374 -0
- scitex/ai/classification/__init__.py +43 -4
- scitex/ai/classification/reporters/_BaseClassificationReporter.py +281 -0
- scitex/ai/classification/reporters/_ClassificationReporter.py +773 -0
- scitex/ai/classification/reporters/_MultiClassificationReporter.py +406 -0
- scitex/ai/classification/reporters/_SingleClassificationReporter.py +1834 -0
- scitex/ai/classification/reporters/__init__.py +11 -0
- scitex/ai/classification/reporters/reporter_utils/_Plotter.py +1028 -0
- scitex/ai/classification/reporters/reporter_utils/__init__.py +80 -0
- scitex/ai/classification/reporters/reporter_utils/aggregation.py +457 -0
- scitex/ai/classification/reporters/reporter_utils/data_models.py +313 -0
- scitex/ai/classification/reporters/reporter_utils/reporting.py +1056 -0
- scitex/ai/classification/reporters/reporter_utils/storage.py +221 -0
- scitex/ai/classification/reporters/reporter_utils/validation.py +395 -0
- scitex/ai/classification/timeseries/_TimeSeriesBlockingSplit.py +568 -0
- scitex/ai/classification/timeseries/_TimeSeriesCalendarSplit.py +688 -0
- scitex/ai/classification/timeseries/_TimeSeriesMetadata.py +139 -0
- scitex/ai/classification/timeseries/_TimeSeriesSlidingWindowSplit.py +1716 -0
- scitex/ai/classification/timeseries/_TimeSeriesSlidingWindowSplit_v01-not-using-n_splits.py +1685 -0
- scitex/ai/classification/timeseries/_TimeSeriesStrategy.py +84 -0
- scitex/ai/classification/timeseries/_TimeSeriesStratifiedSplit.py +610 -0
- scitex/ai/classification/timeseries/__init__.py +39 -0
- scitex/ai/classification/timeseries/_normalize_timestamp.py +436 -0
- scitex/ai/clustering/_umap.py +2 -2
- scitex/ai/feature_extraction/vit.py +1 -0
- scitex/ai/feature_selection/__init__.py +30 -0
- scitex/ai/feature_selection/feature_selection.py +364 -0
- scitex/ai/loss/multi_task_loss.py +1 -1
- scitex/ai/metrics/__init__.py +51 -4
- scitex/ai/metrics/_calc_bacc.py +61 -0
- scitex/ai/metrics/_calc_bacc_from_conf_mat.py +38 -0
- scitex/ai/metrics/_calc_clf_report.py +78 -0
- scitex/ai/metrics/_calc_conf_mat.py +93 -0
- scitex/ai/metrics/_calc_feature_importance.py +183 -0
- scitex/ai/metrics/_calc_mcc.py +61 -0
- scitex/ai/metrics/_calc_pre_rec_auc.py +116 -0
- scitex/ai/metrics/_calc_roc_auc.py +110 -0
- scitex/ai/metrics/_calc_seizure_prediction_metrics.py +490 -0
- scitex/ai/metrics/{silhoute_score_block.py → _calc_silhouette_score.py} +15 -8
- scitex/ai/metrics/_normalize_labels.py +83 -0
- scitex/ai/plt/__init__.py +47 -8
- scitex/ai/plt/{_conf_mat.py → _plot_conf_mat.py} +158 -87
- scitex/ai/plt/_plot_feature_importance.py +323 -0
- scitex/ai/plt/_plot_learning_curve.py +345 -0
- scitex/ai/plt/_plot_optuna_study.py +225 -0
- scitex/ai/plt/_plot_pre_rec_curve.py +290 -0
- scitex/ai/plt/_plot_roc_curve.py +255 -0
- scitex/ai/training/{learning_curve_logger.py → _LearningCurveLogger.py} +197 -213
- scitex/ai/training/__init__.py +2 -2
- scitex/ai/utils/grid_search.py +3 -3
- scitex/benchmark/__init__.py +52 -0
- scitex/benchmark/benchmark.py +400 -0
- scitex/benchmark/monitor.py +370 -0
- scitex/benchmark/profiler.py +297 -0
- scitex/browser/__init__.py +48 -0
- scitex/browser/automation/CookieHandler.py +216 -0
- scitex/browser/automation/__init__.py +7 -0
- scitex/browser/collaboration/__init__.py +55 -0
- scitex/browser/collaboration/auth_helpers.py +94 -0
- scitex/browser/collaboration/collaborative_agent.py +136 -0
- scitex/browser/collaboration/credential_manager.py +188 -0
- scitex/browser/collaboration/interactive_panel.py +400 -0
- scitex/browser/collaboration/persistent_browser.py +170 -0
- scitex/browser/collaboration/shared_session.py +383 -0
- scitex/browser/collaboration/standard_interactions.py +246 -0
- scitex/browser/collaboration/visual_feedback.py +181 -0
- scitex/browser/core/BrowserMixin.py +326 -0
- scitex/browser/core/ChromeProfileManager.py +446 -0
- scitex/browser/core/__init__.py +9 -0
- scitex/browser/debugging/__init__.py +18 -0
- scitex/browser/debugging/_browser_logger.py +657 -0
- scitex/browser/debugging/_highlight_element.py +143 -0
- scitex/browser/debugging/_show_grid.py +154 -0
- scitex/browser/interaction/__init__.py +24 -0
- scitex/browser/interaction/click_center.py +149 -0
- scitex/browser/interaction/click_with_fallbacks.py +206 -0
- scitex/browser/interaction/close_popups.py +498 -0
- scitex/browser/interaction/fill_with_fallbacks.py +209 -0
- scitex/browser/pdf/__init__.py +14 -0
- scitex/browser/pdf/click_download_for_chrome_pdf_viewer.py +200 -0
- scitex/browser/pdf/detect_chrome_pdf_viewer.py +198 -0
- scitex/browser/remote/CaptchaHandler.py +434 -0
- scitex/browser/remote/ZenRowsAPIClient.py +347 -0
- scitex/browser/remote/ZenRowsBrowserManager.py +570 -0
- scitex/browser/remote/__init__.py +11 -0
- scitex/browser/stealth/HumanBehavior.py +344 -0
- scitex/browser/stealth/StealthManager.py +1008 -0
- scitex/browser/stealth/__init__.py +9 -0
- scitex/browser/template.py +122 -0
- scitex/capture/__init__.py +110 -0
- scitex/capture/__main__.py +25 -0
- scitex/capture/capture.py +848 -0
- scitex/capture/cli.py +233 -0
- scitex/capture/gif.py +344 -0
- scitex/capture/mcp_server.py +961 -0
- scitex/capture/session.py +70 -0
- scitex/capture/utils.py +705 -0
- scitex/cli/__init__.py +17 -0
- scitex/cli/cloud.py +447 -0
- scitex/cli/main.py +42 -0
- scitex/cli/scholar.py +280 -0
- scitex/context/_suppress_output.py +5 -3
- scitex/db/__init__.py +30 -3
- scitex/db/__main__.py +75 -0
- scitex/db/_check_health.py +381 -0
- scitex/db/_delete_duplicates.py +25 -386
- scitex/db/_inspect.py +335 -114
- scitex/db/_inspect_optimized.py +301 -0
- scitex/db/{_PostgreSQL.py → _postgresql/_PostgreSQL.py} +3 -3
- scitex/db/{_PostgreSQLMixins → _postgresql/_PostgreSQLMixins}/_BackupMixin.py +1 -1
- scitex/db/{_PostgreSQLMixins → _postgresql/_PostgreSQLMixins}/_BatchMixin.py +1 -1
- scitex/db/{_PostgreSQLMixins → _postgresql/_PostgreSQLMixins}/_BlobMixin.py +1 -1
- scitex/db/{_PostgreSQLMixins → _postgresql/_PostgreSQLMixins}/_ConnectionMixin.py +1 -1
- scitex/db/{_PostgreSQLMixins → _postgresql/_PostgreSQLMixins}/_MaintenanceMixin.py +1 -1
- scitex/db/{_PostgreSQLMixins → _postgresql/_PostgreSQLMixins}/_QueryMixin.py +1 -1
- scitex/db/{_PostgreSQLMixins → _postgresql/_PostgreSQLMixins}/_SchemaMixin.py +1 -1
- scitex/db/{_PostgreSQLMixins → _postgresql/_PostgreSQLMixins}/_TransactionMixin.py +1 -1
- scitex/db/_postgresql/__init__.py +6 -0
- scitex/db/_sqlite3/_SQLite3.py +210 -0
- scitex/db/_sqlite3/_SQLite3Mixins/_ArrayMixin.py +581 -0
- scitex/db/_sqlite3/_SQLite3Mixins/_ArrayMixin_v01-need-_hash-col.py +517 -0
- scitex/db/{_SQLite3Mixins → _sqlite3/_SQLite3Mixins}/_BatchMixin.py +1 -1
- scitex/db/_sqlite3/_SQLite3Mixins/_BlobMixin.py +281 -0
- scitex/db/_sqlite3/_SQLite3Mixins/_ColumnMixin.py +548 -0
- scitex/db/_sqlite3/_SQLite3Mixins/_ColumnMixin_v01-indentation-issues.py +583 -0
- scitex/db/{_SQLite3Mixins → _sqlite3/_SQLite3Mixins}/_ConnectionMixin.py +29 -13
- scitex/db/_sqlite3/_SQLite3Mixins/_GitMixin.py +583 -0
- scitex/db/{_SQLite3Mixins → _sqlite3/_SQLite3Mixins}/_ImportExportMixin.py +1 -1
- scitex/db/{_SQLite3Mixins → _sqlite3/_SQLite3Mixins}/_IndexMixin.py +1 -1
- scitex/db/{_SQLite3Mixins → _sqlite3/_SQLite3Mixins}/_MaintenanceMixin.py +2 -1
- scitex/db/{_SQLite3Mixins → _sqlite3/_SQLite3Mixins}/_QueryMixin.py +37 -10
- scitex/db/{_SQLite3Mixins → _sqlite3/_SQLite3Mixins}/_RowMixin.py +46 -6
- scitex/db/{_SQLite3Mixins → _sqlite3/_SQLite3Mixins}/_TableMixin.py +56 -10
- scitex/db/{_SQLite3Mixins → _sqlite3/_SQLite3Mixins}/_TransactionMixin.py +1 -1
- scitex/db/{_SQLite3Mixins → _sqlite3/_SQLite3Mixins}/__init__.py +14 -2
- scitex/db/_sqlite3/__init__.py +7 -0
- scitex/db/_sqlite3/_delete_duplicates.py +274 -0
- scitex/decorators/__init__.py +2 -0
- scitex/decorators/_cache_disk.py +13 -5
- scitex/decorators/_cache_disk_async.py +49 -0
- scitex/decorators/_deprecated.py +175 -10
- scitex/decorators/_timeout.py +1 -1
- scitex/dev/_analyze_code_flow.py +2 -2
- scitex/dict/_DotDict.py +73 -15
- scitex/dict/_DotDict_v01-not-handling-recursive-instantiations.py +442 -0
- scitex/dict/_DotDict_v02-not-serializing-Path-object.py +446 -0
- scitex/dict/__init__.py +2 -0
- scitex/dict/_flatten.py +27 -0
- scitex/dsp/_crop.py +2 -2
- scitex/dsp/_demo_sig.py +2 -2
- scitex/dsp/_detect_ripples.py +2 -2
- scitex/dsp/_hilbert.py +2 -2
- scitex/dsp/_listen.py +6 -6
- scitex/dsp/_modulation_index.py +2 -2
- scitex/dsp/_pac.py +1 -1
- scitex/dsp/_psd.py +2 -2
- scitex/dsp/_resample.py +2 -1
- scitex/dsp/_time.py +3 -2
- scitex/dsp/_wavelet.py +3 -2
- scitex/dsp/add_noise.py +2 -2
- scitex/dsp/example.py +1 -0
- scitex/dsp/filt.py +10 -9
- scitex/dsp/template.py +3 -2
- scitex/dsp/utils/_differential_bandpass_filters.py +1 -1
- scitex/dsp/utils/pac.py +2 -2
- scitex/dt/_normalize_timestamp.py +432 -0
- scitex/errors.py +572 -0
- scitex/gen/_DimHandler.py +2 -2
- scitex/gen/__init__.py +37 -7
- scitex/gen/_deprecated_close.py +80 -0
- scitex/gen/_deprecated_start.py +26 -0
- scitex/gen/_detect_environment.py +152 -0
- scitex/gen/_detect_notebook_path.py +169 -0
- scitex/gen/_embed.py +6 -2
- scitex/gen/_get_notebook_path.py +257 -0
- scitex/gen/_less.py +1 -1
- scitex/gen/_list_packages.py +2 -2
- scitex/gen/_norm.py +44 -9
- scitex/gen/_norm_cache.py +269 -0
- scitex/gen/_src.py +3 -5
- scitex/gen/_title_case.py +3 -3
- scitex/io/__init__.py +28 -6
- scitex/io/_glob.py +13 -7
- scitex/io/_load.py +108 -21
- scitex/io/_load_cache.py +303 -0
- scitex/io/_load_configs.py +40 -15
- scitex/io/{_H5Explorer.py → _load_modules/_H5Explorer.py} +80 -17
- scitex/io/_load_modules/_ZarrExplorer.py +114 -0
- scitex/io/_load_modules/_bibtex.py +207 -0
- scitex/io/_load_modules/_hdf5.py +53 -178
- scitex/io/_load_modules/_json.py +5 -3
- scitex/io/_load_modules/_pdf.py +871 -16
- scitex/io/_load_modules/_sqlite3.py +15 -0
- scitex/io/_load_modules/_txt.py +41 -12
- scitex/io/_load_modules/_yaml.py +4 -3
- scitex/io/_load_modules/_zarr.py +126 -0
- scitex/io/_save.py +429 -171
- scitex/io/_save_modules/__init__.py +6 -0
- scitex/io/_save_modules/_bibtex.py +194 -0
- scitex/io/_save_modules/_csv.py +8 -4
- scitex/io/_save_modules/_excel.py +174 -15
- scitex/io/_save_modules/_hdf5.py +251 -226
- scitex/io/_save_modules/_image.py +1 -3
- scitex/io/_save_modules/_json.py +49 -4
- scitex/io/_save_modules/_listed_dfs_as_csv.py +1 -3
- scitex/io/_save_modules/_listed_scalars_as_csv.py +1 -3
- scitex/io/_save_modules/_tex.py +277 -0
- scitex/io/_save_modules/_yaml.py +42 -3
- scitex/io/_save_modules/_zarr.py +160 -0
- scitex/io/utils/__init__.py +20 -0
- scitex/io/utils/h5_to_zarr.py +616 -0
- scitex/linalg/_geometric_median.py +6 -2
- scitex/{gen/_tee.py → logging/_Tee.py} +43 -84
- scitex/logging/__init__.py +122 -0
- scitex/logging/_config.py +158 -0
- scitex/logging/_context.py +103 -0
- scitex/logging/_formatters.py +128 -0
- scitex/logging/_handlers.py +64 -0
- scitex/logging/_levels.py +35 -0
- scitex/logging/_logger.py +163 -0
- scitex/logging/_print_capture.py +95 -0
- scitex/ml/__init__.py +69 -0
- scitex/{ai/genai/anthropic.py → ml/_gen_ai/_Anthropic.py} +13 -19
- scitex/{ai/genai/base_genai.py → ml/_gen_ai/_BaseGenAI.py} +5 -5
- scitex/{ai/genai/deepseek.py → ml/_gen_ai/_DeepSeek.py} +11 -16
- scitex/{ai/genai/google.py → ml/_gen_ai/_Google.py} +7 -15
- scitex/{ai/genai/groq.py → ml/_gen_ai/_Groq.py} +1 -8
- scitex/{ai/genai/llama.py → ml/_gen_ai/_Llama.py} +3 -16
- scitex/{ai/genai/openai.py → ml/_gen_ai/_OpenAI.py} +3 -3
- scitex/{ai/genai/params.py → ml/_gen_ai/_PARAMS.py} +51 -65
- scitex/{ai/genai/perplexity.py → ml/_gen_ai/_Perplexity.py} +3 -14
- scitex/ml/_gen_ai/__init__.py +43 -0
- scitex/{ai/genai/calc_cost.py → ml/_gen_ai/_calc_cost.py} +1 -1
- scitex/{ai/genai/format_output_func.py → ml/_gen_ai/_format_output_func.py} +4 -4
- scitex/{ai/genai/genai_factory.py → ml/_gen_ai/_genai_factory.py} +8 -8
- scitex/ml/activation/__init__.py +8 -0
- scitex/ml/activation/_define.py +11 -0
- scitex/{ai/classifier_server.py → ml/classification/Classifier.py} +5 -5
- scitex/ml/classification/CrossValidationExperiment.py +374 -0
- scitex/ml/classification/__init__.py +46 -0
- scitex/ml/classification/reporters/_BaseClassificationReporter.py +281 -0
- scitex/ml/classification/reporters/_ClassificationReporter.py +773 -0
- scitex/ml/classification/reporters/_MultiClassificationReporter.py +406 -0
- scitex/ml/classification/reporters/_SingleClassificationReporter.py +1834 -0
- scitex/ml/classification/reporters/__init__.py +11 -0
- scitex/ml/classification/reporters/reporter_utils/_Plotter.py +1028 -0
- scitex/ml/classification/reporters/reporter_utils/__init__.py +80 -0
- scitex/ml/classification/reporters/reporter_utils/aggregation.py +457 -0
- scitex/ml/classification/reporters/reporter_utils/data_models.py +313 -0
- scitex/ml/classification/reporters/reporter_utils/reporting.py +1056 -0
- scitex/ml/classification/reporters/reporter_utils/storage.py +221 -0
- scitex/ml/classification/reporters/reporter_utils/validation.py +395 -0
- scitex/ml/classification/timeseries/_TimeSeriesBlockingSplit.py +568 -0
- scitex/ml/classification/timeseries/_TimeSeriesCalendarSplit.py +688 -0
- scitex/ml/classification/timeseries/_TimeSeriesMetadata.py +139 -0
- scitex/ml/classification/timeseries/_TimeSeriesSlidingWindowSplit.py +1716 -0
- scitex/ml/classification/timeseries/_TimeSeriesSlidingWindowSplit_v01-not-using-n_splits.py +1685 -0
- scitex/ml/classification/timeseries/_TimeSeriesStrategy.py +84 -0
- scitex/ml/classification/timeseries/_TimeSeriesStratifiedSplit.py +610 -0
- scitex/ml/classification/timeseries/__init__.py +39 -0
- scitex/ml/classification/timeseries/_normalize_timestamp.py +436 -0
- scitex/ml/clustering/__init__.py +11 -0
- scitex/ml/clustering/_pca.py +115 -0
- scitex/ml/clustering/_umap.py +376 -0
- scitex/ml/feature_extraction/__init__.py +56 -0
- scitex/ml/feature_extraction/vit.py +149 -0
- scitex/ml/feature_selection/__init__.py +30 -0
- scitex/ml/feature_selection/feature_selection.py +364 -0
- scitex/ml/loss/_L1L2Losses.py +34 -0
- scitex/ml/loss/__init__.py +12 -0
- scitex/ml/loss/multi_task_loss.py +47 -0
- scitex/ml/metrics/__init__.py +56 -0
- scitex/ml/metrics/_calc_bacc.py +61 -0
- scitex/ml/metrics/_calc_bacc_from_conf_mat.py +38 -0
- scitex/ml/metrics/_calc_clf_report.py +78 -0
- scitex/ml/metrics/_calc_conf_mat.py +93 -0
- scitex/ml/metrics/_calc_feature_importance.py +183 -0
- scitex/ml/metrics/_calc_mcc.py +61 -0
- scitex/ml/metrics/_calc_pre_rec_auc.py +116 -0
- scitex/ml/metrics/_calc_roc_auc.py +110 -0
- scitex/ml/metrics/_calc_seizure_prediction_metrics.py +490 -0
- scitex/ml/metrics/_calc_silhouette_score.py +503 -0
- scitex/ml/metrics/_normalize_labels.py +83 -0
- scitex/ml/optim/Ranger_Deep_Learning_Optimizer/__init__.py +0 -0
- scitex/ml/optim/Ranger_Deep_Learning_Optimizer/ranger/__init__.py +3 -0
- scitex/ml/optim/Ranger_Deep_Learning_Optimizer/ranger/ranger.py +207 -0
- scitex/ml/optim/Ranger_Deep_Learning_Optimizer/ranger/ranger2020.py +238 -0
- scitex/ml/optim/Ranger_Deep_Learning_Optimizer/ranger/ranger913A.py +215 -0
- scitex/ml/optim/Ranger_Deep_Learning_Optimizer/ranger/rangerqh.py +184 -0
- scitex/ml/optim/Ranger_Deep_Learning_Optimizer/setup.py +24 -0
- scitex/ml/optim/__init__.py +13 -0
- scitex/ml/optim/_get_set.py +31 -0
- scitex/ml/optim/_optimizers.py +71 -0
- scitex/ml/plt/__init__.py +60 -0
- scitex/ml/plt/_plot_conf_mat.py +663 -0
- scitex/ml/plt/_plot_feature_importance.py +323 -0
- scitex/ml/plt/_plot_learning_curve.py +345 -0
- scitex/ml/plt/_plot_optuna_study.py +225 -0
- scitex/ml/plt/_plot_pre_rec_curve.py +290 -0
- scitex/ml/plt/_plot_roc_curve.py +255 -0
- scitex/ml/sk/__init__.py +11 -0
- scitex/ml/sk/_clf.py +58 -0
- scitex/ml/sk/_to_sktime.py +100 -0
- scitex/ml/sklearn/__init__.py +26 -0
- scitex/ml/sklearn/clf.py +58 -0
- scitex/ml/sklearn/to_sktime.py +100 -0
- scitex/{ai/training/early_stopping.py → ml/training/_EarlyStopping.py} +1 -2
- scitex/{ai → ml/training}/_LearningCurveLogger.py +198 -242
- scitex/ml/training/__init__.py +7 -0
- scitex/ml/utils/__init__.py +22 -0
- scitex/ml/utils/_check_params.py +50 -0
- scitex/ml/utils/_default_dataset.py +46 -0
- scitex/ml/utils/_format_samples_for_sktime.py +26 -0
- scitex/ml/utils/_label_encoder.py +134 -0
- scitex/ml/utils/_merge_labels.py +22 -0
- scitex/ml/utils/_sliding_window_data_augmentation.py +11 -0
- scitex/ml/utils/_under_sample.py +51 -0
- scitex/ml/utils/_verify_n_gpus.py +16 -0
- scitex/ml/utils/grid_search.py +148 -0
- scitex/nn/_BNet.py +15 -9
- scitex/nn/_Filters.py +2 -2
- scitex/nn/_ModulationIndex.py +2 -2
- scitex/nn/_PAC.py +1 -1
- scitex/nn/_Spectrogram.py +12 -3
- scitex/nn/__init__.py +9 -10
- scitex/path/__init__.py +18 -0
- scitex/path/_clean.py +4 -0
- scitex/path/_find.py +9 -4
- scitex/path/_symlink.py +348 -0
- scitex/path/_version.py +4 -3
- scitex/pd/__init__.py +2 -0
- scitex/pd/_get_unique.py +99 -0
- scitex/plt/__init__.py +114 -5
- scitex/plt/_subplots/_AxesWrapper.py +1 -3
- scitex/plt/_subplots/_AxisWrapper.py +7 -3
- scitex/plt/_subplots/_AxisWrapperMixins/_AdjustmentMixin.py +47 -13
- scitex/plt/_subplots/_AxisWrapperMixins/_MatplotlibPlotMixin.py +160 -2
- scitex/plt/_subplots/_AxisWrapperMixins/_SeabornMixin.py +26 -4
- scitex/plt/_subplots/_AxisWrapperMixins/_UnitAwareMixin.py +322 -0
- scitex/plt/_subplots/_AxisWrapperMixins/__init__.py +1 -0
- scitex/plt/_subplots/_FigWrapper.py +62 -6
- scitex/plt/_subplots/_export_as_csv.py +43 -27
- scitex/plt/_subplots/_export_as_csv_formatters/__init__.py +5 -4
- scitex/plt/_subplots/_export_as_csv_formatters/_format_annotate.py +81 -0
- scitex/plt/_subplots/_export_as_csv_formatters/_format_bar.py +1 -3
- scitex/plt/_subplots/_export_as_csv_formatters/_format_barh.py +20 -5
- scitex/plt/_subplots/_export_as_csv_formatters/_format_boxplot.py +1 -3
- scitex/plt/_subplots/_export_as_csv_formatters/_format_contour.py +1 -3
- scitex/plt/_subplots/_export_as_csv_formatters/_format_errorbar.py +35 -18
- scitex/plt/_subplots/_export_as_csv_formatters/_format_eventplot.py +1 -3
- scitex/plt/_subplots/_export_as_csv_formatters/_format_fill.py +1 -3
- scitex/plt/_subplots/_export_as_csv_formatters/_format_fill_between.py +1 -3
- scitex/plt/_subplots/_export_as_csv_formatters/_format_hist.py +1 -3
- scitex/plt/_subplots/_export_as_csv_formatters/_format_imshow.py +1 -3
- scitex/plt/_subplots/_export_as_csv_formatters/_format_imshow2d.py +1 -3
- scitex/plt/_subplots/_export_as_csv_formatters/_format_plot.py +15 -3
- scitex/plt/_subplots/_export_as_csv_formatters/_format_plot_box.py +1 -3
- scitex/plt/_subplots/_export_as_csv_formatters/_format_plot_conf_mat.py +1 -3
- scitex/plt/_subplots/_export_as_csv_formatters/_format_plot_ecdf.py +1 -3
- scitex/plt/_subplots/_export_as_csv_formatters/_format_plot_fillv.py +1 -3
- scitex/plt/_subplots/_export_as_csv_formatters/_format_plot_heatmap.py +1 -3
- scitex/plt/_subplots/_export_as_csv_formatters/_format_plot_image.py +1 -3
- scitex/plt/_subplots/_export_as_csv_formatters/_format_plot_joyplot.py +1 -3
- scitex/plt/_subplots/_export_as_csv_formatters/_format_plot_kde.py +1 -3
- scitex/plt/_subplots/_export_as_csv_formatters/_format_plot_line.py +1 -3
- scitex/plt/_subplots/_export_as_csv_formatters/_format_plot_mean_ci.py +1 -3
- scitex/plt/_subplots/_export_as_csv_formatters/_format_plot_mean_std.py +1 -3
- scitex/plt/_subplots/_export_as_csv_formatters/_format_plot_median_iqr.py +1 -3
- scitex/plt/_subplots/_export_as_csv_formatters/_format_plot_raster.py +1 -3
- scitex/plt/_subplots/_export_as_csv_formatters/_format_plot_rectangle.py +1 -3
- scitex/plt/_subplots/_export_as_csv_formatters/_format_plot_scatter.py +35 -0
- scitex/plt/_subplots/_export_as_csv_formatters/_format_plot_scatter_hist.py +1 -3
- scitex/plt/_subplots/_export_as_csv_formatters/_format_plot_shaded_line.py +1 -3
- scitex/plt/_subplots/_export_as_csv_formatters/_format_plot_violin.py +1 -3
- scitex/plt/_subplots/_export_as_csv_formatters/_format_scatter.py +6 -4
- scitex/plt/_subplots/_export_as_csv_formatters/_format_sns_barplot.py +1 -3
- scitex/plt/_subplots/_export_as_csv_formatters/_format_sns_boxplot.py +1 -3
- scitex/plt/_subplots/_export_as_csv_formatters/_format_sns_heatmap.py +1 -3
- scitex/plt/_subplots/_export_as_csv_formatters/_format_sns_histplot.py +1 -3
- scitex/plt/_subplots/_export_as_csv_formatters/_format_sns_jointplot.py +1 -3
- scitex/plt/_subplots/_export_as_csv_formatters/_format_sns_kdeplot.py +1 -3
- scitex/plt/_subplots/_export_as_csv_formatters/_format_sns_lineplot.py +1 -3
- scitex/plt/_subplots/_export_as_csv_formatters/_format_sns_pairplot.py +1 -3
- scitex/plt/_subplots/_export_as_csv_formatters/_format_sns_scatterplot.py +1 -3
- scitex/plt/_subplots/_export_as_csv_formatters/_format_sns_stripplot.py +1 -3
- scitex/plt/_subplots/_export_as_csv_formatters/_format_sns_swarmplot.py +1 -3
- scitex/plt/_subplots/_export_as_csv_formatters/_format_sns_violinplot.py +1 -3
- scitex/plt/_subplots/_export_as_csv_formatters/_format_text.py +60 -0
- scitex/plt/_subplots/_export_as_csv_formatters/_format_violin.py +1 -3
- scitex/plt/_subplots/_export_as_csv_formatters/_format_violinplot.py +1 -3
- scitex/plt/_subplots/_export_as_csv_formatters/test_formatters.py +1 -3
- scitex/plt/_subplots/_export_as_csv_formatters.py +56 -59
- scitex/plt/ax/_style/_hide_spines.py +1 -3
- scitex/plt/ax/_style/_rotate_labels.py +180 -76
- scitex/plt/ax/_style/_rotate_labels_v01.py +248 -0
- scitex/plt/ax/_style/_set_meta.py +11 -4
- scitex/plt/ax/_style/_set_supxyt.py +3 -3
- scitex/plt/ax/_style/_set_xyt.py +3 -3
- scitex/plt/ax/_style/_share_axes.py +2 -2
- scitex/plt/color/__init__.py +4 -4
- scitex/plt/color/{_get_colors_from_cmap.py → _get_colors_from_conf_matap.py} +7 -7
- scitex/plt/utils/_configure_mpl.py +99 -86
- scitex/plt/utils/_histogram_utils.py +1 -3
- scitex/plt/utils/_is_valid_axis.py +1 -3
- scitex/plt/utils/_scitex_config.py +1 -0
- scitex/repro/__init__.py +75 -0
- scitex/{reproduce → repro}/_gen_ID.py +1 -1
- scitex/{reproduce → repro}/_gen_timestamp.py +1 -1
- scitex/repro_rng/_RandomStateManager.py +590 -0
- scitex/repro_rng/_RandomStateManager_v01-no-verbose-options.py +414 -0
- scitex/repro_rng/__init__.py +39 -0
- scitex/reproduce/__init__.py +25 -13
- scitex/reproduce/_hash_array.py +22 -0
- scitex/resource/_get_processor_usages.py +4 -4
- scitex/resource/_get_specs.py +2 -2
- scitex/resource/_log_processor_usages.py +2 -2
- scitex/rng/_RandomStateManager.py +590 -0
- scitex/rng/_RandomStateManager_v01-no-verbose-options.py +414 -0
- scitex/rng/__init__.py +39 -0
- scitex/scholar/__init__.py +309 -19
- scitex/scholar/__main__.py +319 -0
- scitex/scholar/auth/ScholarAuthManager.py +308 -0
- scitex/scholar/auth/__init__.py +12 -0
- scitex/scholar/auth/core/AuthenticationGateway.py +473 -0
- scitex/scholar/auth/core/BrowserAuthenticator.py +386 -0
- scitex/scholar/auth/core/StrategyResolver.py +309 -0
- scitex/scholar/auth/core/__init__.py +16 -0
- scitex/scholar/auth/gateway/_OpenURLLinkFinder.py +120 -0
- scitex/scholar/auth/gateway/_OpenURLResolver.py +209 -0
- scitex/scholar/auth/gateway/__init__.py +38 -0
- scitex/scholar/auth/gateway/_resolve_functions.py +101 -0
- scitex/scholar/auth/providers/BaseAuthenticator.py +166 -0
- scitex/scholar/auth/providers/EZProxyAuthenticator.py +484 -0
- scitex/scholar/auth/providers/OpenAthensAuthenticator.py +619 -0
- scitex/scholar/auth/providers/ShibbolethAuthenticator.py +686 -0
- scitex/scholar/auth/providers/__init__.py +18 -0
- scitex/scholar/auth/session/AuthCacheManager.py +189 -0
- scitex/scholar/auth/session/SessionManager.py +159 -0
- scitex/scholar/auth/session/__init__.py +11 -0
- scitex/scholar/auth/sso/BaseSSOAutomator.py +373 -0
- scitex/scholar/auth/sso/OpenAthensSSOAutomator.py +378 -0
- scitex/scholar/auth/sso/SSOAutomator.py +180 -0
- scitex/scholar/auth/sso/UniversityOfMelbourneSSOAutomator.py +380 -0
- scitex/scholar/auth/sso/__init__.py +15 -0
- scitex/scholar/browser/ScholarBrowserManager.py +705 -0
- scitex/scholar/browser/__init__.py +38 -0
- scitex/scholar/browser/utils/__init__.py +13 -0
- scitex/scholar/browser/utils/click_and_wait.py +205 -0
- scitex/scholar/browser/utils/close_unwanted_pages.py +140 -0
- scitex/scholar/browser/utils/wait_redirects.py +732 -0
- scitex/scholar/config/PublisherRules.py +132 -0
- scitex/scholar/config/ScholarConfig.py +126 -0
- scitex/scholar/config/__init__.py +17 -0
- scitex/scholar/core/Paper.py +627 -0
- scitex/scholar/core/Papers.py +722 -0
- scitex/scholar/core/Scholar.py +1975 -0
- scitex/scholar/core/__init__.py +9 -0
- scitex/scholar/impact_factor/ImpactFactorEngine.py +204 -0
- scitex/scholar/impact_factor/__init__.py +20 -0
- scitex/scholar/impact_factor/estimation/ImpactFactorEstimationEngine.py +0 -0
- scitex/scholar/impact_factor/estimation/__init__.py +40 -0
- scitex/scholar/impact_factor/estimation/build_database.py +0 -0
- scitex/scholar/impact_factor/estimation/core/__init__.py +28 -0
- scitex/scholar/impact_factor/estimation/core/cache_manager.py +523 -0
- scitex/scholar/impact_factor/estimation/core/calculator.py +355 -0
- scitex/scholar/impact_factor/estimation/core/journal_matcher.py +428 -0
- scitex/scholar/integration/__init__.py +59 -0
- scitex/scholar/integration/base.py +502 -0
- scitex/scholar/integration/mendeley/__init__.py +22 -0
- scitex/scholar/integration/mendeley/exporter.py +166 -0
- scitex/scholar/integration/mendeley/importer.py +236 -0
- scitex/scholar/integration/mendeley/linker.py +79 -0
- scitex/scholar/integration/mendeley/mapper.py +212 -0
- scitex/scholar/integration/zotero/__init__.py +27 -0
- scitex/scholar/integration/zotero/__main__.py +264 -0
- scitex/scholar/integration/zotero/exporter.py +351 -0
- scitex/scholar/integration/zotero/importer.py +372 -0
- scitex/scholar/integration/zotero/linker.py +415 -0
- scitex/scholar/integration/zotero/mapper.py +286 -0
- scitex/scholar/metadata_engines/ScholarEngine.py +588 -0
- scitex/scholar/metadata_engines/__init__.py +21 -0
- scitex/scholar/metadata_engines/individual/ArXivEngine.py +397 -0
- scitex/scholar/metadata_engines/individual/CrossRefEngine.py +274 -0
- scitex/scholar/metadata_engines/individual/CrossRefLocalEngine.py +263 -0
- scitex/scholar/metadata_engines/individual/OpenAlexEngine.py +350 -0
- scitex/scholar/metadata_engines/individual/PubMedEngine.py +329 -0
- scitex/scholar/metadata_engines/individual/SemanticScholarEngine.py +438 -0
- scitex/scholar/metadata_engines/individual/URLDOIEngine.py +410 -0
- scitex/scholar/metadata_engines/individual/_BaseDOIEngine.py +487 -0
- scitex/scholar/metadata_engines/individual/__init__.py +7 -0
- scitex/scholar/metadata_engines/utils/_PubMedConverter.py +469 -0
- scitex/scholar/metadata_engines/utils/_URLDOIExtractor.py +283 -0
- scitex/scholar/metadata_engines/utils/__init__.py +30 -0
- scitex/scholar/metadata_engines/utils/_metadata2bibtex.py +103 -0
- scitex/scholar/metadata_engines/utils/_standardize_metadata.py +376 -0
- scitex/scholar/pdf_download/ScholarPDFDownloader.py +579 -0
- scitex/scholar/pdf_download/__init__.py +5 -0
- scitex/scholar/pdf_download/strategies/__init__.py +38 -0
- scitex/scholar/pdf_download/strategies/chrome_pdf_viewer.py +376 -0
- scitex/scholar/pdf_download/strategies/direct_download.py +131 -0
- scitex/scholar/pdf_download/strategies/manual_download_fallback.py +167 -0
- scitex/scholar/pdf_download/strategies/manual_download_utils.py +996 -0
- scitex/scholar/pdf_download/strategies/response_body.py +207 -0
- scitex/scholar/pipelines/ScholarPipelineBibTeX.py +364 -0
- scitex/scholar/pipelines/ScholarPipelineParallel.py +478 -0
- scitex/scholar/pipelines/ScholarPipelineSingle.py +767 -0
- scitex/scholar/pipelines/__init__.py +49 -0
- scitex/scholar/storage/BibTeXHandler.py +1018 -0
- scitex/scholar/storage/PaperIO.py +468 -0
- scitex/scholar/storage/ScholarLibrary.py +182 -0
- scitex/scholar/storage/_DeduplicationManager.py +548 -0
- scitex/scholar/storage/_LibraryCacheManager.py +724 -0
- scitex/scholar/storage/_LibraryManager.py +1835 -0
- scitex/scholar/storage/__init__.py +28 -0
- scitex/scholar/url_finder/ScholarURLFinder.py +379 -0
- scitex/scholar/url_finder/__init__.py +7 -0
- scitex/scholar/url_finder/strategies/__init__.py +33 -0
- scitex/scholar/url_finder/strategies/find_pdf_urls_by_direct_links.py +261 -0
- scitex/scholar/url_finder/strategies/find_pdf_urls_by_dropdown.py +67 -0
- scitex/scholar/url_finder/strategies/find_pdf_urls_by_href.py +204 -0
- scitex/scholar/url_finder/strategies/find_pdf_urls_by_navigation.py +256 -0
- scitex/scholar/url_finder/strategies/find_pdf_urls_by_publisher_patterns.py +165 -0
- scitex/scholar/url_finder/strategies/find_pdf_urls_by_zotero_translators.py +163 -0
- scitex/scholar/url_finder/strategies/find_supplementary_urls_by_href.py +70 -0
- scitex/scholar/utils/__init__.py +22 -0
- scitex/scholar/utils/bibtex/__init__.py +9 -0
- scitex/scholar/utils/bibtex/_parse_bibtex.py +71 -0
- scitex/scholar/utils/cleanup/__init__.py +8 -0
- scitex/scholar/utils/cleanup/_cleanup_scholar_processes.py +96 -0
- scitex/scholar/utils/cleanup/cleanup_old_extractions.py +117 -0
- scitex/scholar/utils/text/_TextNormalizer.py +407 -0
- scitex/scholar/utils/text/__init__.py +9 -0
- scitex/scholar/zotero/__init__.py +38 -0
- scitex/session/__init__.py +51 -0
- scitex/session/_lifecycle.py +736 -0
- scitex/session/_manager.py +102 -0
- scitex/session/template.py +122 -0
- scitex/stats/__init__.py +30 -26
- scitex/stats/correct/__init__.py +21 -0
- scitex/stats/correct/_correct_bonferroni.py +551 -0
- scitex/stats/correct/_correct_fdr.py +634 -0
- scitex/stats/correct/_correct_holm.py +548 -0
- scitex/stats/correct/_correct_sidak.py +499 -0
- scitex/stats/descriptive/__init__.py +85 -0
- scitex/stats/descriptive/_circular.py +540 -0
- scitex/stats/descriptive/_describe.py +219 -0
- scitex/stats/descriptive/_nan.py +518 -0
- scitex/stats/descriptive/_real.py +189 -0
- scitex/stats/effect_sizes/__init__.py +41 -0
- scitex/stats/effect_sizes/_cliffs_delta.py +325 -0
- scitex/stats/effect_sizes/_cohens_d.py +342 -0
- scitex/stats/effect_sizes/_epsilon_squared.py +315 -0
- scitex/stats/effect_sizes/_eta_squared.py +302 -0
- scitex/stats/effect_sizes/_prob_superiority.py +296 -0
- scitex/stats/posthoc/__init__.py +19 -0
- scitex/stats/posthoc/_dunnett.py +463 -0
- scitex/stats/posthoc/_games_howell.py +383 -0
- scitex/stats/posthoc/_tukey_hsd.py +367 -0
- scitex/stats/power/__init__.py +19 -0
- scitex/stats/power/_power.py +433 -0
- scitex/stats/template.py +119 -0
- scitex/stats/utils/__init__.py +62 -0
- scitex/stats/utils/_effect_size.py +985 -0
- scitex/stats/utils/_formatters.py +270 -0
- scitex/stats/utils/_normalizers.py +927 -0
- scitex/stats/utils/_power.py +433 -0
- scitex/stats_v01/_EffectSizeCalculator.py +488 -0
- scitex/stats_v01/_StatisticalValidator.py +411 -0
- scitex/stats_v01/__init__.py +60 -0
- scitex/stats_v01/_additional_tests.py +415 -0
- scitex/{stats → stats_v01}/_p2stars.py +19 -5
- scitex/stats_v01/_two_sample_tests.py +141 -0
- scitex/stats_v01/desc/__init__.py +83 -0
- scitex/stats_v01/desc/_circular.py +540 -0
- scitex/stats_v01/desc/_describe.py +219 -0
- scitex/stats_v01/desc/_nan.py +518 -0
- scitex/{stats/desc/_nan.py → stats_v01/desc/_nan_v01-20250920_145731.py} +23 -12
- scitex/stats_v01/desc/_real.py +189 -0
- scitex/stats_v01/tests/__corr_test_optimized.py +221 -0
- scitex/stats_v01/tests/_corr_test_optimized.py +179 -0
- scitex/str/__init__.py +1 -3
- scitex/str/_clean_path.py +6 -2
- scitex/str/_latex_fallback.py +267 -160
- scitex/str/_parse.py +44 -36
- scitex/str/_printc.py +1 -3
- scitex/template/__init__.py +87 -0
- scitex/template/_create_project.py +267 -0
- scitex/template/create_pip_project.py +80 -0
- scitex/template/create_research.py +80 -0
- scitex/template/create_singularity.py +80 -0
- scitex/units.py +291 -0
- scitex/utils/_compress_hdf5.py +14 -3
- scitex/utils/_email.py +21 -2
- scitex/utils/_grid.py +6 -4
- scitex/utils/_notify.py +13 -10
- scitex/utils/_verify_scitex_format.py +589 -0
- scitex/utils/_verify_scitex_format_v01.py +370 -0
- scitex/utils/template.py +122 -0
- scitex/web/_search_pubmed.py +62 -16
- scitex-2.1.0.dist-info/LICENSE +21 -0
- scitex-2.1.0.dist-info/METADATA +677 -0
- scitex-2.1.0.dist-info/RECORD +919 -0
- {scitex-2.0.0.dist-info → scitex-2.1.0.dist-info}/WHEEL +1 -1
- scitex-2.1.0.dist-info/entry_points.txt +3 -0
- scitex/ai/__Classifiers.py +0 -101
- scitex/ai/classification/classification_reporter.py +0 -1137
- scitex/ai/classification/classifiers.py +0 -101
- scitex/ai/classification_reporter.py +0 -1161
- scitex/ai/genai/__init__.py +0 -277
- scitex/ai/genai/anthropic_provider.py +0 -320
- scitex/ai/genai/anthropic_refactored.py +0 -109
- scitex/ai/genai/auth_manager.py +0 -200
- scitex/ai/genai/base_provider.py +0 -291
- scitex/ai/genai/chat_history.py +0 -307
- scitex/ai/genai/cost_tracker.py +0 -276
- scitex/ai/genai/deepseek_provider.py +0 -251
- scitex/ai/genai/google_provider.py +0 -228
- scitex/ai/genai/groq_provider.py +0 -248
- scitex/ai/genai/image_processor.py +0 -250
- scitex/ai/genai/llama_provider.py +0 -214
- scitex/ai/genai/mock_provider.py +0 -127
- scitex/ai/genai/model_registry.py +0 -304
- scitex/ai/genai/openai_provider.py +0 -293
- scitex/ai/genai/perplexity_provider.py +0 -205
- scitex/ai/genai/provider_base.py +0 -302
- scitex/ai/genai/provider_factory.py +0 -370
- scitex/ai/genai/response_handler.py +0 -235
- scitex/ai/layer/_Pass.py +0 -21
- scitex/ai/layer/__init__.py +0 -10
- scitex/ai/layer/_switch.py +0 -8
- scitex/ai/metrics/_bACC.py +0 -51
- scitex/ai/plt/_learning_curve.py +0 -194
- scitex/ai/plt/_optuna_study.py +0 -111
- scitex/ai/plt/aucs/__init__.py +0 -2
- scitex/ai/plt/aucs/example.py +0 -60
- scitex/ai/plt/aucs/pre_rec_auc.py +0 -223
- scitex/ai/plt/aucs/roc_auc.py +0 -246
- scitex/ai/sampling/undersample.py +0 -29
- scitex/db/_SQLite3.py +0 -2136
- scitex/db/_SQLite3Mixins/_BlobMixin.py +0 -229
- scitex/gen/_close.py +0 -222
- scitex/gen/_start.py +0 -451
- scitex/general/__init__.py +0 -5
- scitex/io/_load_modules/_db.py +0 -24
- scitex/life/__init__.py +0 -10
- scitex/life/_monitor_rain.py +0 -49
- scitex/reproduce/_fix_seeds.py +0 -45
- scitex/res/__init__.py +0 -5
- scitex/scholar/_local_search.py +0 -454
- scitex/scholar/_paper.py +0 -244
- scitex/scholar/_pdf_downloader.py +0 -325
- scitex/scholar/_search.py +0 -393
- scitex/scholar/_vector_search.py +0 -370
- scitex/scholar/_web_sources.py +0 -457
- scitex/stats/desc/__init__.py +0 -40
- scitex-2.0.0.dist-info/METADATA +0 -307
- scitex-2.0.0.dist-info/RECORD +0 -572
- scitex-2.0.0.dist-info/licenses/LICENSE +0 -7
- /scitex/ai/{act → activation}/__init__.py +0 -0
- /scitex/ai/{act → activation}/_define.py +0 -0
- /scitex/ai/{early_stopping.py → training/_EarlyStopping.py} +0 -0
- /scitex/db/{_PostgreSQLMixins → _postgresql/_PostgreSQLMixins}/_ImportExportMixin.py +0 -0
- /scitex/db/{_PostgreSQLMixins → _postgresql/_PostgreSQLMixins}/_IndexMixin.py +0 -0
- /scitex/db/{_PostgreSQLMixins → _postgresql/_PostgreSQLMixins}/_RowMixin.py +0 -0
- /scitex/db/{_PostgreSQLMixins → _postgresql/_PostgreSQLMixins}/_TableMixin.py +0 -0
- /scitex/db/{_PostgreSQLMixins → _postgresql/_PostgreSQLMixins}/__init__.py +0 -0
- /scitex/{stats → stats_v01}/_calc_partial_corr.py +0 -0
- /scitex/{stats → stats_v01}/_corr_test_multi.py +0 -0
- /scitex/{stats → stats_v01}/_corr_test_wrapper.py +0 -0
- /scitex/{stats → stats_v01}/_describe_wrapper.py +0 -0
- /scitex/{stats → stats_v01}/_multiple_corrections.py +0 -0
- /scitex/{stats → stats_v01}/_nan_stats.py +0 -0
- /scitex/{stats → stats_v01}/_p2stars_wrapper.py +0 -0
- /scitex/{stats → stats_v01}/_statistical_tests.py +0 -0
- /scitex/{stats/desc/_describe.py → stats_v01/desc/_describe_v01-20250920_145731.py} +0 -0
- /scitex/{stats/desc/_real.py → stats_v01/desc/_real_v01-20250920_145731.py} +0 -0
- /scitex/{stats → stats_v01}/multiple/__init__.py +0 -0
- /scitex/{stats → stats_v01}/multiple/_bonferroni_correction.py +0 -0
- /scitex/{stats → stats_v01}/multiple/_fdr_correction.py +0 -0
- /scitex/{stats → stats_v01}/multiple/_multicompair.py +0 -0
- /scitex/{stats → stats_v01}/tests/__corr_test.py +0 -0
- /scitex/{stats → stats_v01}/tests/__corr_test_multi.py +0 -0
- /scitex/{stats → stats_v01}/tests/__corr_test_single.py +0 -0
- /scitex/{stats → stats_v01}/tests/__init__.py +0 -0
- /scitex/{stats → stats_v01}/tests/_brunner_munzel_test.py +0 -0
- /scitex/{stats → stats_v01}/tests/_nocorrelation_test.py +0 -0
- /scitex/{stats → stats_v01}/tests/_smirnov_grubbs.py +0 -0
- {scitex-2.0.0.dist-info → scitex-2.1.0.dist-info}/top_level.txt +0 -0
|
@@ -0,0 +1,364 @@
|
|
|
1
|
+
#!/usr/bin/env python3
|
|
2
|
+
# -*- coding: utf-8 -*-
|
|
3
|
+
# Timestamp: "2025-10-03 04:30:00 (ywatanabe)"
|
|
4
|
+
# File: feature_selection.py
|
|
5
|
+
|
|
6
|
+
"""
|
|
7
|
+
Feature selection utilities for classification tasks.
|
|
8
|
+
|
|
9
|
+
This module provides comprehensive feature selection and importance analysis:
|
|
10
|
+
- Feature importance extraction from various model types
|
|
11
|
+
- Univariate feature selection (ANOVA F-test, chi2, mutual_info)
|
|
12
|
+
- Model-based feature selection (tree importances, L1 coefficients)
|
|
13
|
+
- Recursive feature elimination (RFE)
|
|
14
|
+
- Cross-fold feature consistency analysis
|
|
15
|
+
- Feature importance aggregation and visualization
|
|
16
|
+
"""
|
|
17
|
+
|
|
18
|
+
from __future__ import annotations
|
|
19
|
+
|
|
20
|
+
import warnings
|
|
21
|
+
from typing import Dict, List, Optional, Tuple, Union
|
|
22
|
+
|
|
23
|
+
import numpy as np
|
|
24
|
+
import pandas as pd
|
|
25
|
+
from sklearn.feature_selection import (
|
|
26
|
+
SelectKBest,
|
|
27
|
+
chi2,
|
|
28
|
+
f_classif,
|
|
29
|
+
mutual_info_classif,
|
|
30
|
+
)
|
|
31
|
+
from sklearn.impute import SimpleImputer
|
|
32
|
+
|
|
33
|
+
|
|
34
|
+
def extract_feature_importance(
|
|
35
|
+
model,
|
|
36
|
+
feature_names: List[str],
|
|
37
|
+
method: str = "auto",
|
|
38
|
+
) -> Optional[Dict[str, float]]:
|
|
39
|
+
"""Extract feature importance from trained model.
|
|
40
|
+
|
|
41
|
+
Args:
|
|
42
|
+
model: Trained classifier
|
|
43
|
+
feature_names: List of feature names
|
|
44
|
+
method: Method to extract importance:
|
|
45
|
+
- "auto": Automatically detect best method
|
|
46
|
+
- "tree": Use feature_importances_ (tree-based models)
|
|
47
|
+
- "coef": Use coefficients (linear models)
|
|
48
|
+
- "permutation": Use permutation importance (any model)
|
|
49
|
+
|
|
50
|
+
Returns:
|
|
51
|
+
Dictionary mapping feature names to importance values,
|
|
52
|
+
or None if extraction fails
|
|
53
|
+
"""
|
|
54
|
+
try:
|
|
55
|
+
# Auto-detect method
|
|
56
|
+
if method == "auto":
|
|
57
|
+
if hasattr(model, "feature_importances_"):
|
|
58
|
+
method = "tree"
|
|
59
|
+
elif hasattr(model, "coef_"):
|
|
60
|
+
method = "coef"
|
|
61
|
+
else:
|
|
62
|
+
warnings.warn(
|
|
63
|
+
f"Model {type(model).__name__} does not support "
|
|
64
|
+
f"feature importance extraction"
|
|
65
|
+
)
|
|
66
|
+
return None
|
|
67
|
+
|
|
68
|
+
# Extract importance
|
|
69
|
+
if method == "tree":
|
|
70
|
+
if not hasattr(model, "feature_importances_"):
|
|
71
|
+
raise ValueError(
|
|
72
|
+
f"Model {type(model).__name__} does not have "
|
|
73
|
+
f"feature_importances_ attribute"
|
|
74
|
+
)
|
|
75
|
+
importances = model.feature_importances_
|
|
76
|
+
|
|
77
|
+
elif method == "coef":
|
|
78
|
+
if not hasattr(model, "coef_"):
|
|
79
|
+
raise ValueError(
|
|
80
|
+
f"Model {type(model).__name__} does not have "
|
|
81
|
+
f"coef_ attribute"
|
|
82
|
+
)
|
|
83
|
+
# Use absolute values for multi-class or single coefficient vector
|
|
84
|
+
coef = model.coef_
|
|
85
|
+
if coef.ndim > 1:
|
|
86
|
+
# Multi-class: average absolute coefficients across classes
|
|
87
|
+
importances = np.mean(np.abs(coef), axis=0)
|
|
88
|
+
else:
|
|
89
|
+
importances = np.abs(coef)
|
|
90
|
+
|
|
91
|
+
elif method == "permutation":
|
|
92
|
+
raise NotImplementedError(
|
|
93
|
+
"Permutation importance requires validation data. "
|
|
94
|
+
"Use extract_permutation_importance() instead."
|
|
95
|
+
)
|
|
96
|
+
|
|
97
|
+
else:
|
|
98
|
+
raise ValueError(f"Unknown method: {method}")
|
|
99
|
+
|
|
100
|
+
# Normalize to sum to 1
|
|
101
|
+
importances = importances / importances.sum()
|
|
102
|
+
|
|
103
|
+
# Create dictionary sorted by importance
|
|
104
|
+
importance_dict = dict(zip(feature_names, importances))
|
|
105
|
+
importance_dict = dict(
|
|
106
|
+
sorted(importance_dict.items(), key=lambda x: x[1], reverse=True)
|
|
107
|
+
)
|
|
108
|
+
|
|
109
|
+
return importance_dict
|
|
110
|
+
|
|
111
|
+
except Exception as e:
|
|
112
|
+
warnings.warn(f"Failed to extract feature importance: {e}")
|
|
113
|
+
return None
|
|
114
|
+
|
|
115
|
+
|
|
116
|
+
def select_features_univariate(
|
|
117
|
+
X_train: np.ndarray,
|
|
118
|
+
y_train: np.ndarray,
|
|
119
|
+
X_val: np.ndarray,
|
|
120
|
+
feature_names: List[str],
|
|
121
|
+
k: int = 10,
|
|
122
|
+
score_func: str = "f_classif",
|
|
123
|
+
impute_strategy: str = "median",
|
|
124
|
+
) -> Tuple[np.ndarray, np.ndarray, List[int], List[str], object]:
|
|
125
|
+
"""Select top k features using univariate statistical tests.
|
|
126
|
+
|
|
127
|
+
This prevents data leakage by:
|
|
128
|
+
1. Fitting the selector only on training data
|
|
129
|
+
2. Transforming validation/test data with the fitted selector
|
|
130
|
+
|
|
131
|
+
Args:
|
|
132
|
+
X_train: Training features
|
|
133
|
+
y_train: Training labels
|
|
134
|
+
X_val: Validation features
|
|
135
|
+
feature_names: List of feature names
|
|
136
|
+
k: Number of features to select
|
|
137
|
+
score_func: Scoring function:
|
|
138
|
+
- "f_classif": ANOVA F-test (default)
|
|
139
|
+
- "chi2": Chi-squared test (requires non-negative features)
|
|
140
|
+
- "mutual_info": Mutual information
|
|
141
|
+
impute_strategy: Strategy for imputing missing values:
|
|
142
|
+
- "median" (default), "mean", "most_frequent", "constant"
|
|
143
|
+
|
|
144
|
+
Returns:
|
|
145
|
+
X_train_selected: Selected training features
|
|
146
|
+
X_val_selected: Selected validation features
|
|
147
|
+
feature_indices: Indices of selected features
|
|
148
|
+
selected_names: Names of selected features
|
|
149
|
+
imputer: Fitted imputer for test data
|
|
150
|
+
"""
|
|
151
|
+
# Map string to function
|
|
152
|
+
score_func_map = {
|
|
153
|
+
"f_classif": f_classif,
|
|
154
|
+
"chi2": chi2,
|
|
155
|
+
"mutual_info": mutual_info_classif,
|
|
156
|
+
}
|
|
157
|
+
|
|
158
|
+
if score_func not in score_func_map:
|
|
159
|
+
raise ValueError(
|
|
160
|
+
f"Unknown score_func: {score_func}. "
|
|
161
|
+
f"Choose from {list(score_func_map.keys())}"
|
|
162
|
+
)
|
|
163
|
+
|
|
164
|
+
score_func_callable = score_func_map[score_func]
|
|
165
|
+
|
|
166
|
+
# Impute NaN values
|
|
167
|
+
imputer = SimpleImputer(strategy=impute_strategy)
|
|
168
|
+
X_train_imputed = imputer.fit_transform(X_train)
|
|
169
|
+
X_val_imputed = imputer.transform(X_val)
|
|
170
|
+
|
|
171
|
+
# Select features
|
|
172
|
+
k_actual = min(k, X_train.shape[1])
|
|
173
|
+
selector = SelectKBest(score_func_callable, k=k_actual)
|
|
174
|
+
X_train_selected = selector.fit_transform(X_train_imputed, y_train)
|
|
175
|
+
X_val_selected = selector.transform(X_val_imputed)
|
|
176
|
+
|
|
177
|
+
# Get selected feature information
|
|
178
|
+
feature_indices = selector.get_support(indices=True).tolist()
|
|
179
|
+
selected_names = [feature_names[i] for i in feature_indices]
|
|
180
|
+
|
|
181
|
+
return (
|
|
182
|
+
X_train_selected,
|
|
183
|
+
X_val_selected,
|
|
184
|
+
feature_indices,
|
|
185
|
+
selected_names,
|
|
186
|
+
imputer,
|
|
187
|
+
)
|
|
188
|
+
|
|
189
|
+
|
|
190
|
+
def analyze_feature_consistency(
|
|
191
|
+
selected_features_per_fold: List[List[str]],
|
|
192
|
+
) -> Dict[str, Union[int, float, Dict[str, int]]]:
|
|
193
|
+
"""Analyze feature selection consistency across CV folds.
|
|
194
|
+
|
|
195
|
+
Args:
|
|
196
|
+
selected_features_per_fold: List of feature lists, one per fold
|
|
197
|
+
|
|
198
|
+
Returns:
|
|
199
|
+
Dictionary containing:
|
|
200
|
+
- "feature_frequency": Dict mapping features to selection count
|
|
201
|
+
- "n_folds": Total number of folds
|
|
202
|
+
- "n_unique_features": Number of unique features selected
|
|
203
|
+
- "consistency_score": Average selection frequency (0-1)
|
|
204
|
+
- "stable_features": Features selected in all folds
|
|
205
|
+
- "unstable_features": Features selected in only one fold
|
|
206
|
+
"""
|
|
207
|
+
if not selected_features_per_fold:
|
|
208
|
+
return {}
|
|
209
|
+
|
|
210
|
+
n_folds = len(selected_features_per_fold)
|
|
211
|
+
|
|
212
|
+
# Count feature occurrences
|
|
213
|
+
all_features = set()
|
|
214
|
+
for features in selected_features_per_fold:
|
|
215
|
+
all_features.update(features)
|
|
216
|
+
|
|
217
|
+
feature_frequency = {f: 0 for f in all_features}
|
|
218
|
+
for features in selected_features_per_fold:
|
|
219
|
+
for f in features:
|
|
220
|
+
feature_frequency[f] += 1
|
|
221
|
+
|
|
222
|
+
# Sort by frequency
|
|
223
|
+
feature_frequency = dict(
|
|
224
|
+
sorted(feature_frequency.items(), key=lambda x: x[1], reverse=True)
|
|
225
|
+
)
|
|
226
|
+
|
|
227
|
+
# Identify stable and unstable features
|
|
228
|
+
stable_features = [
|
|
229
|
+
f for f, count in feature_frequency.items() if count == n_folds
|
|
230
|
+
]
|
|
231
|
+
unstable_features = [
|
|
232
|
+
f for f, count in feature_frequency.items() if count == 1
|
|
233
|
+
]
|
|
234
|
+
|
|
235
|
+
# Calculate consistency score (average selection frequency)
|
|
236
|
+
consistency_score = (
|
|
237
|
+
np.mean(list(feature_frequency.values())) / n_folds
|
|
238
|
+
if feature_frequency
|
|
239
|
+
else 0.0
|
|
240
|
+
)
|
|
241
|
+
|
|
242
|
+
return {
|
|
243
|
+
"feature_frequency": feature_frequency,
|
|
244
|
+
"n_folds": n_folds,
|
|
245
|
+
"n_unique_features": len(all_features),
|
|
246
|
+
"consistency_score": round(consistency_score, 3),
|
|
247
|
+
"stable_features": stable_features,
|
|
248
|
+
"unstable_features": unstable_features,
|
|
249
|
+
}
|
|
250
|
+
|
|
251
|
+
|
|
252
|
+
def aggregate_feature_importances(
|
|
253
|
+
importances_per_fold: List[Dict[str, float]],
|
|
254
|
+
method: str = "mean",
|
|
255
|
+
) -> Dict[str, Dict[str, float]]:
|
|
256
|
+
"""Aggregate feature importances across CV folds.
|
|
257
|
+
|
|
258
|
+
Args:
|
|
259
|
+
importances_per_fold: List of importance dicts, one per fold
|
|
260
|
+
method: Aggregation method:
|
|
261
|
+
- "mean": Average importance across folds
|
|
262
|
+
- "median": Median importance across folds
|
|
263
|
+
- "max": Maximum importance across folds
|
|
264
|
+
|
|
265
|
+
Returns:
|
|
266
|
+
Dictionary containing:
|
|
267
|
+
- "mean": Mean importance per feature
|
|
268
|
+
- "std": Standard deviation per feature
|
|
269
|
+
- "min": Minimum importance per feature
|
|
270
|
+
- "max": Maximum importance per feature
|
|
271
|
+
- "cv": Coefficient of variation (std/mean) per feature
|
|
272
|
+
"""
|
|
273
|
+
if not importances_per_fold:
|
|
274
|
+
return {}
|
|
275
|
+
|
|
276
|
+
# Collect all features
|
|
277
|
+
all_features = set()
|
|
278
|
+
for imp_dict in importances_per_fold:
|
|
279
|
+
all_features.update(imp_dict.keys())
|
|
280
|
+
|
|
281
|
+
# Build matrix: (n_folds, n_features)
|
|
282
|
+
importance_matrix = np.zeros((len(importances_per_fold), len(all_features)))
|
|
283
|
+
feature_list = sorted(list(all_features))
|
|
284
|
+
|
|
285
|
+
for fold_idx, imp_dict in enumerate(importances_per_fold):
|
|
286
|
+
for feat_idx, feat in enumerate(feature_list):
|
|
287
|
+
importance_matrix[fold_idx, feat_idx] = imp_dict.get(feat, 0.0)
|
|
288
|
+
|
|
289
|
+
# Calculate statistics
|
|
290
|
+
mean_importance = importance_matrix.mean(axis=0)
|
|
291
|
+
std_importance = importance_matrix.std(axis=0)
|
|
292
|
+
min_importance = importance_matrix.min(axis=0)
|
|
293
|
+
max_importance = importance_matrix.max(axis=0)
|
|
294
|
+
|
|
295
|
+
# Coefficient of variation (handle division by zero)
|
|
296
|
+
with np.errstate(divide="ignore", invalid="ignore"):
|
|
297
|
+
cv_importance = std_importance / mean_importance
|
|
298
|
+
cv_importance[~np.isfinite(cv_importance)] = 0.0
|
|
299
|
+
|
|
300
|
+
# Create result dictionary
|
|
301
|
+
result = {
|
|
302
|
+
"mean": dict(zip(feature_list, mean_importance)),
|
|
303
|
+
"std": dict(zip(feature_list, std_importance)),
|
|
304
|
+
"min": dict(zip(feature_list, min_importance)),
|
|
305
|
+
"max": dict(zip(feature_list, max_importance)),
|
|
306
|
+
"cv": dict(zip(feature_list, cv_importance)),
|
|
307
|
+
}
|
|
308
|
+
|
|
309
|
+
# Sort each by mean importance
|
|
310
|
+
for key in result:
|
|
311
|
+
result[key] = dict(
|
|
312
|
+
sorted(
|
|
313
|
+
result[key].items(),
|
|
314
|
+
key=lambda x: result["mean"][x[0]],
|
|
315
|
+
reverse=True,
|
|
316
|
+
)
|
|
317
|
+
)
|
|
318
|
+
|
|
319
|
+
return result
|
|
320
|
+
|
|
321
|
+
|
|
322
|
+
def create_feature_importance_dataframe(
|
|
323
|
+
aggregated_importances: Dict[str, Dict[str, float]],
|
|
324
|
+
) -> pd.DataFrame:
|
|
325
|
+
"""Create a formatted DataFrame from aggregated feature importances.
|
|
326
|
+
|
|
327
|
+
Args:
|
|
328
|
+
aggregated_importances: Output from aggregate_feature_importances()
|
|
329
|
+
|
|
330
|
+
Returns:
|
|
331
|
+
DataFrame with columns: feature, mean, std, min, max, cv
|
|
332
|
+
Sorted by mean importance (descending)
|
|
333
|
+
"""
|
|
334
|
+
if not aggregated_importances or "mean" not in aggregated_importances:
|
|
335
|
+
return pd.DataFrame()
|
|
336
|
+
|
|
337
|
+
features = list(aggregated_importances["mean"].keys())
|
|
338
|
+
|
|
339
|
+
df = pd.DataFrame(
|
|
340
|
+
{
|
|
341
|
+
"feature": features,
|
|
342
|
+
"mean": [aggregated_importances["mean"][f] for f in features],
|
|
343
|
+
"std": [aggregated_importances["std"][f] for f in features],
|
|
344
|
+
"min": [aggregated_importances["min"][f] for f in features],
|
|
345
|
+
"max": [aggregated_importances["max"][f] for f in features],
|
|
346
|
+
"cv": [aggregated_importances["cv"][f] for f in features],
|
|
347
|
+
}
|
|
348
|
+
)
|
|
349
|
+
|
|
350
|
+
# Sort by mean importance
|
|
351
|
+
df = df.sort_values("mean", ascending=False).reset_index(drop=True)
|
|
352
|
+
|
|
353
|
+
return df
|
|
354
|
+
|
|
355
|
+
|
|
356
|
+
__all__ = [
|
|
357
|
+
"extract_feature_importance",
|
|
358
|
+
"select_features_univariate",
|
|
359
|
+
"analyze_feature_consistency",
|
|
360
|
+
"aggregate_feature_importances",
|
|
361
|
+
"create_feature_importance_dataframe",
|
|
362
|
+
]
|
|
363
|
+
|
|
364
|
+
# EOF
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
#!/usr/bin/env python3
|
|
2
|
+
# -*- coding: utf-8 -*-
|
|
3
|
+
# Time-stamp: "2024-11-07 18:53:03 (ywatanabe)"
|
|
4
|
+
# File: ./scitex_repo/src/scitex/ai/loss/_L1L2Losses.py
|
|
5
|
+
|
|
6
|
+
import torch
|
|
7
|
+
|
|
8
|
+
|
|
9
|
+
def l1(model, lambda_l1=0.01):
|
|
10
|
+
lambda_l1 = torch.tensor(lambda_l1)
|
|
11
|
+
l1 = torch.tensor(0.0).cuda()
|
|
12
|
+
for param in model.parameters(): # fixme; is this OK?
|
|
13
|
+
l1 += torch.abs(param).sum()
|
|
14
|
+
return l1
|
|
15
|
+
|
|
16
|
+
|
|
17
|
+
def l2(model, lambda_l2=0.01):
|
|
18
|
+
lambda_l2 = torch.tensor(lambda_l2)
|
|
19
|
+
l2 = torch.tensor(0.0).cuda()
|
|
20
|
+
for param in model.parameters(): # fixme; is this OK?
|
|
21
|
+
l2 += torch.norm(param).sum()
|
|
22
|
+
return l2
|
|
23
|
+
|
|
24
|
+
|
|
25
|
+
def elastic(model, alpha=1.0, l1_ratio=0.5):
|
|
26
|
+
assert 0 <= l1_ratio <= 1
|
|
27
|
+
|
|
28
|
+
L1 = l1(model)
|
|
29
|
+
L2 = l2(model)
|
|
30
|
+
|
|
31
|
+
return alpha * (l1_ratio * L1 + (1 - l1_ratio) * L2)
|
|
32
|
+
|
|
33
|
+
|
|
34
|
+
# EOF
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
#!/usr/bin/env python3
|
|
2
|
+
# -*- coding: utf-8 -*-
|
|
3
|
+
# Time-stamp: "2024-11-07 19:07:29 (ywatanabe)"
|
|
4
|
+
# File: ./scitex_repo/src/scitex/ai/loss/MultiTaskLoss.py
|
|
5
|
+
|
|
6
|
+
import numpy as np
|
|
7
|
+
import torch
|
|
8
|
+
import torch.nn as nn
|
|
9
|
+
|
|
10
|
+
from ...repro import fix_seeds
|
|
11
|
+
|
|
12
|
+
|
|
13
|
+
class MultiTaskLoss(nn.Module):
|
|
14
|
+
"""
|
|
15
|
+
# https://openaccess.thecvf.com/content_cvpr_2018/papers/Kendall_Multi-Task_Learning_Using_CVPR_2018_paper.pdf
|
|
16
|
+
|
|
17
|
+
Example:
|
|
18
|
+
are_regression = [False, False]
|
|
19
|
+
mtl = MultiTaskLoss(are_regression)
|
|
20
|
+
losses = [torch.rand(1, requires_grad=True) for _ in range(len(are_regression))]
|
|
21
|
+
loss = mtl(losses)
|
|
22
|
+
print(loss)
|
|
23
|
+
# [tensor([0.4215], grad_fn=<AddBackward0>), tensor([0.6190], grad_fn=<AddBackward0>)]
|
|
24
|
+
"""
|
|
25
|
+
|
|
26
|
+
def __init__(self, are_regression=[False, False], reduction="none"):
|
|
27
|
+
super().__init__()
|
|
28
|
+
fix_seeds(np=np, torch=torch, show=False)
|
|
29
|
+
n_tasks = len(are_regression)
|
|
30
|
+
|
|
31
|
+
self.register_buffer("are_regression", torch.tensor(are_regression))
|
|
32
|
+
|
|
33
|
+
# for the numercal stability, log(variables) are learned.
|
|
34
|
+
self.log_vars = torch.nn.Parameter(torch.zeros(n_tasks))
|
|
35
|
+
self.reduction = reduction
|
|
36
|
+
|
|
37
|
+
def forward(self, losses):
|
|
38
|
+
vars = torch.exp(self.log_vars).type_as(losses[0])
|
|
39
|
+
stds = vars ** (1 / 2)
|
|
40
|
+
coeffs = 1 / ((self.are_regression + 1) * vars)
|
|
41
|
+
scaled_losses = [
|
|
42
|
+
coeffs[i] * losses[i] + torch.log(stds[i]) for i in range(len(losses))
|
|
43
|
+
]
|
|
44
|
+
return scaled_losses
|
|
45
|
+
|
|
46
|
+
|
|
47
|
+
# EOF
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
#!/usr/bin/env python3
|
|
2
|
+
"""Scitex metrics module.
|
|
3
|
+
|
|
4
|
+
Standardized naming convention:
|
|
5
|
+
- calc_* functions: Modern standardized metric calculations
|
|
6
|
+
- Legacy names (bACC, balanced_accuracy, etc.): For backward compatibility
|
|
7
|
+
"""
|
|
8
|
+
|
|
9
|
+
# Modern standardized calc_* functions
|
|
10
|
+
from ._normalize_labels import normalize_labels as _normalize_labels
|
|
11
|
+
from ._calc_bacc import calc_bacc
|
|
12
|
+
from ._calc_mcc import calc_mcc
|
|
13
|
+
from ._calc_conf_mat import calc_conf_mat
|
|
14
|
+
from ._calc_clf_report import calc_clf_report
|
|
15
|
+
from ._calc_roc_auc import calc_roc_auc
|
|
16
|
+
from ._calc_pre_rec_auc import calc_pre_rec_auc
|
|
17
|
+
from ._calc_bacc_from_conf_mat import calc_bacc_from_conf_mat
|
|
18
|
+
from ._calc_seizure_prediction_metrics import (
|
|
19
|
+
calc_seizure_window_prediction_metrics,
|
|
20
|
+
calc_seizure_event_prediction_metrics,
|
|
21
|
+
calc_seizure_prediction_metrics, # backward compat alias
|
|
22
|
+
)
|
|
23
|
+
from ._calc_silhouette_score import (
|
|
24
|
+
calc_silhouette_score_slow,
|
|
25
|
+
calc_silhouette_samples_slow,
|
|
26
|
+
calc_silhouette_score_block,
|
|
27
|
+
calc_silhouette_samples_block,
|
|
28
|
+
)
|
|
29
|
+
from ._calc_feature_importance import (
|
|
30
|
+
calc_feature_importance,
|
|
31
|
+
calc_permutation_importance,
|
|
32
|
+
)
|
|
33
|
+
|
|
34
|
+
__all__ = [
|
|
35
|
+
"calc_bacc",
|
|
36
|
+
"calc_mcc",
|
|
37
|
+
"calc_conf_mat",
|
|
38
|
+
"calc_clf_report",
|
|
39
|
+
"calc_roc_auc",
|
|
40
|
+
"calc_pre_rec_auc",
|
|
41
|
+
"calc_bacc_from_conf_mat",
|
|
42
|
+
"calc_seizure_window_prediction_metrics",
|
|
43
|
+
"calc_seizure_event_prediction_metrics",
|
|
44
|
+
"calc_seizure_prediction_metrics", # backward compat alias
|
|
45
|
+
"calc_silhouette_score_slow",
|
|
46
|
+
"calc_silhouette_samples_slow",
|
|
47
|
+
"calc_silhouette_score_block",
|
|
48
|
+
"calc_silhouette_samples_block",
|
|
49
|
+
"calc_feature_importance",
|
|
50
|
+
"calc_permutation_importance",
|
|
51
|
+
# # Legacy names for backward compatibility
|
|
52
|
+
# "bACC",
|
|
53
|
+
# "balanced_accuracy",
|
|
54
|
+
# "bACC_from_conf_mat",
|
|
55
|
+
# "balanced_accuracy_from_conf_mat",
|
|
56
|
+
]
|
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
#!/usr/bin/env python3
|
|
2
|
+
# -*- coding: utf-8 -*-
|
|
3
|
+
# Timestamp: "2025-10-02 (ywatanabe)"
|
|
4
|
+
# File: /home/ywatanabe/proj/scitex_repo/src/scitex/ml/metrics/_calc_bacc.py
|
|
5
|
+
|
|
6
|
+
"""Calculate balanced accuracy metric."""
|
|
7
|
+
|
|
8
|
+
__FILE__ = __file__
|
|
9
|
+
|
|
10
|
+
from typing import Any, Dict, List, Optional
|
|
11
|
+
import numpy as np
|
|
12
|
+
from sklearn.metrics import balanced_accuracy_score
|
|
13
|
+
from ._normalize_labels import normalize_labels
|
|
14
|
+
|
|
15
|
+
|
|
16
|
+
def calc_bacc(
|
|
17
|
+
y_true: np.ndarray,
|
|
18
|
+
y_pred: np.ndarray,
|
|
19
|
+
labels: Optional[List] = None,
|
|
20
|
+
fold: Optional[int] = None,
|
|
21
|
+
) -> Dict[str, Any]:
|
|
22
|
+
"""
|
|
23
|
+
Calculate balanced accuracy with robust label handling.
|
|
24
|
+
|
|
25
|
+
Parameters
|
|
26
|
+
----------
|
|
27
|
+
y_true : np.ndarray
|
|
28
|
+
True labels (can be str or int)
|
|
29
|
+
y_pred : np.ndarray
|
|
30
|
+
Predicted labels (can be str or int)
|
|
31
|
+
labels : List, optional
|
|
32
|
+
Expected label list
|
|
33
|
+
fold : int, optional
|
|
34
|
+
Fold number for tracking
|
|
35
|
+
|
|
36
|
+
Returns
|
|
37
|
+
-------
|
|
38
|
+
Dict[str, Any]
|
|
39
|
+
{'metric': 'balanced_accuracy', 'value': float, 'fold': int}
|
|
40
|
+
"""
|
|
41
|
+
try:
|
|
42
|
+
y_true_norm, y_pred_norm, label_names, _ = normalize_labels(
|
|
43
|
+
y_true, y_pred, labels
|
|
44
|
+
)
|
|
45
|
+
value = balanced_accuracy_score(y_true_norm, y_pred_norm)
|
|
46
|
+
return {
|
|
47
|
+
"metric": "balanced_accuracy",
|
|
48
|
+
"value": float(value),
|
|
49
|
+
"fold": fold,
|
|
50
|
+
"labels": label_names,
|
|
51
|
+
}
|
|
52
|
+
except Exception as e:
|
|
53
|
+
return {
|
|
54
|
+
"metric": "balanced_accuracy",
|
|
55
|
+
"value": np.nan,
|
|
56
|
+
"fold": fold,
|
|
57
|
+
"error": str(e),
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
|
|
61
|
+
# EOF
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
#!/usr/bin/env python3
|
|
2
|
+
# -*- coding: utf-8 -*-
|
|
3
|
+
# Timestamp: "2025-10-02 (ywatanabe)"
|
|
4
|
+
# File: /home/ywatanabe/proj/scitex_repo/src/scitex/ml/metrics/_calc_bacc_from_conf_mat.py
|
|
5
|
+
|
|
6
|
+
"""Calculate balanced accuracy from confusion matrix."""
|
|
7
|
+
|
|
8
|
+
__FILE__ = __file__
|
|
9
|
+
|
|
10
|
+
import numpy as np
|
|
11
|
+
|
|
12
|
+
|
|
13
|
+
def calc_bacc_from_conf_mat(cm: np.ndarray) -> float:
|
|
14
|
+
"""
|
|
15
|
+
Calculate balanced accuracy from confusion matrix.
|
|
16
|
+
|
|
17
|
+
Parameters
|
|
18
|
+
----------
|
|
19
|
+
cm : np.ndarray
|
|
20
|
+
Confusion matrix
|
|
21
|
+
|
|
22
|
+
Returns
|
|
23
|
+
-------
|
|
24
|
+
float
|
|
25
|
+
Balanced accuracy
|
|
26
|
+
"""
|
|
27
|
+
try:
|
|
28
|
+
per_class = np.diag(cm) / np.sum(cm, axis=1)
|
|
29
|
+
return float(np.nanmean(per_class))
|
|
30
|
+
except:
|
|
31
|
+
return np.nan
|
|
32
|
+
|
|
33
|
+
|
|
34
|
+
# Convenience aliases
|
|
35
|
+
bACC_from_conf_mat = calc_bacc_from_conf_mat
|
|
36
|
+
balanced_accuracy_from_conf_mat = calc_bacc_from_conf_mat
|
|
37
|
+
|
|
38
|
+
# EOF
|
|
@@ -0,0 +1,78 @@
|
|
|
1
|
+
#!/usr/bin/env python3
|
|
2
|
+
# -*- coding: utf-8 -*-
|
|
3
|
+
# Timestamp: "2025-10-02 (ywatanabe)"
|
|
4
|
+
# File: /home/ywatanabe/proj/scitex_repo/src/scitex/ml/metrics/_calc_clf_report.py
|
|
5
|
+
|
|
6
|
+
"""Generate classification report."""
|
|
7
|
+
|
|
8
|
+
__FILE__ = __file__
|
|
9
|
+
|
|
10
|
+
from typing import Any, Dict, List, Optional
|
|
11
|
+
import pandas as pd
|
|
12
|
+
from sklearn.metrics import classification_report
|
|
13
|
+
from ._normalize_labels import normalize_labels
|
|
14
|
+
|
|
15
|
+
|
|
16
|
+
def calc_clf_report(
|
|
17
|
+
y_true,
|
|
18
|
+
y_pred,
|
|
19
|
+
labels: Optional[List] = None,
|
|
20
|
+
fold: Optional[int] = None,
|
|
21
|
+
) -> Dict[str, Any]:
|
|
22
|
+
"""
|
|
23
|
+
Generate classification report with robust label handling.
|
|
24
|
+
|
|
25
|
+
Parameters
|
|
26
|
+
----------
|
|
27
|
+
y_true : np.ndarray
|
|
28
|
+
True labels (can be str or int)
|
|
29
|
+
y_pred : np.ndarray
|
|
30
|
+
Predicted labels (can be str or int)
|
|
31
|
+
labels : List, optional
|
|
32
|
+
Expected label list
|
|
33
|
+
fold : int, optional
|
|
34
|
+
Fold number for tracking
|
|
35
|
+
|
|
36
|
+
Returns
|
|
37
|
+
-------
|
|
38
|
+
Dict[str, Any]
|
|
39
|
+
{
|
|
40
|
+
'metric': 'classification_report',
|
|
41
|
+
'value': pd.DataFrame,
|
|
42
|
+
'fold': int,
|
|
43
|
+
'labels': list
|
|
44
|
+
}
|
|
45
|
+
"""
|
|
46
|
+
try:
|
|
47
|
+
y_true_norm, y_pred_norm, label_names, _ = normalize_labels(
|
|
48
|
+
y_true, y_pred, labels
|
|
49
|
+
)
|
|
50
|
+
|
|
51
|
+
# Get classification report
|
|
52
|
+
report_dict = classification_report(
|
|
53
|
+
y_true_norm,
|
|
54
|
+
y_pred_norm,
|
|
55
|
+
target_names=[str(l) for l in label_names],
|
|
56
|
+
output_dict=True,
|
|
57
|
+
zero_division=0,
|
|
58
|
+
)
|
|
59
|
+
|
|
60
|
+
# Convert to DataFrame
|
|
61
|
+
report_df = pd.DataFrame(report_dict).T
|
|
62
|
+
|
|
63
|
+
return {
|
|
64
|
+
"metric": "classification_report",
|
|
65
|
+
"value": report_df,
|
|
66
|
+
"fold": fold,
|
|
67
|
+
"labels": label_names,
|
|
68
|
+
}
|
|
69
|
+
except Exception as e:
|
|
70
|
+
return {
|
|
71
|
+
"metric": "classification_report",
|
|
72
|
+
"value": None,
|
|
73
|
+
"fold": fold,
|
|
74
|
+
"error": str(e),
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
|
|
78
|
+
# EOF
|