xplia 1.0.1__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.
- venv/Lib/site-packages/_distutils_hack/__init__.py +222 -0
- venv/Lib/site-packages/_distutils_hack/override.py +1 -0
- venv/Lib/site-packages/pip/__init__.py +13 -0
- venv/Lib/site-packages/pip/__main__.py +24 -0
- venv/Lib/site-packages/pip/__pip-runner__.py +50 -0
- venv/Lib/site-packages/pip/_internal/__init__.py +19 -0
- venv/Lib/site-packages/pip/_internal/build_env.py +311 -0
- venv/Lib/site-packages/pip/_internal/cache.py +292 -0
- venv/Lib/site-packages/pip/_internal/cli/__init__.py +4 -0
- venv/Lib/site-packages/pip/_internal/cli/autocompletion.py +171 -0
- venv/Lib/site-packages/pip/_internal/cli/base_command.py +236 -0
- venv/Lib/site-packages/pip/_internal/cli/cmdoptions.py +1074 -0
- venv/Lib/site-packages/pip/_internal/cli/command_context.py +27 -0
- venv/Lib/site-packages/pip/_internal/cli/main.py +79 -0
- venv/Lib/site-packages/pip/_internal/cli/main_parser.py +134 -0
- venv/Lib/site-packages/pip/_internal/cli/parser.py +294 -0
- venv/Lib/site-packages/pip/_internal/cli/progress_bars.py +68 -0
- venv/Lib/site-packages/pip/_internal/cli/req_command.py +508 -0
- venv/Lib/site-packages/pip/_internal/cli/spinners.py +159 -0
- venv/Lib/site-packages/pip/_internal/cli/status_codes.py +6 -0
- venv/Lib/site-packages/pip/_internal/commands/__init__.py +132 -0
- venv/Lib/site-packages/pip/_internal/commands/cache.py +222 -0
- venv/Lib/site-packages/pip/_internal/commands/check.py +54 -0
- venv/Lib/site-packages/pip/_internal/commands/completion.py +121 -0
- venv/Lib/site-packages/pip/_internal/commands/configuration.py +282 -0
- venv/Lib/site-packages/pip/_internal/commands/debug.py +199 -0
- venv/Lib/site-packages/pip/_internal/commands/download.py +147 -0
- venv/Lib/site-packages/pip/_internal/commands/freeze.py +108 -0
- venv/Lib/site-packages/pip/_internal/commands/hash.py +59 -0
- venv/Lib/site-packages/pip/_internal/commands/help.py +41 -0
- venv/Lib/site-packages/pip/_internal/commands/index.py +139 -0
- venv/Lib/site-packages/pip/_internal/commands/inspect.py +92 -0
- venv/Lib/site-packages/pip/_internal/commands/install.py +778 -0
- venv/Lib/site-packages/pip/_internal/commands/list.py +368 -0
- venv/Lib/site-packages/pip/_internal/commands/search.py +174 -0
- venv/Lib/site-packages/pip/_internal/commands/show.py +189 -0
- venv/Lib/site-packages/pip/_internal/commands/uninstall.py +113 -0
- venv/Lib/site-packages/pip/_internal/commands/wheel.py +183 -0
- venv/Lib/site-packages/pip/_internal/configuration.py +381 -0
- venv/Lib/site-packages/pip/_internal/distributions/__init__.py +21 -0
- venv/Lib/site-packages/pip/_internal/distributions/base.py +39 -0
- venv/Lib/site-packages/pip/_internal/distributions/installed.py +23 -0
- venv/Lib/site-packages/pip/_internal/distributions/sdist.py +150 -0
- venv/Lib/site-packages/pip/_internal/distributions/wheel.py +34 -0
- venv/Lib/site-packages/pip/_internal/exceptions.py +733 -0
- venv/Lib/site-packages/pip/_internal/index/__init__.py +2 -0
- venv/Lib/site-packages/pip/_internal/index/collector.py +505 -0
- venv/Lib/site-packages/pip/_internal/index/package_finder.py +1029 -0
- venv/Lib/site-packages/pip/_internal/index/sources.py +223 -0
- venv/Lib/site-packages/pip/_internal/locations/__init__.py +467 -0
- venv/Lib/site-packages/pip/_internal/locations/_distutils.py +173 -0
- venv/Lib/site-packages/pip/_internal/locations/_sysconfig.py +213 -0
- venv/Lib/site-packages/pip/_internal/locations/base.py +81 -0
- venv/Lib/site-packages/pip/_internal/main.py +12 -0
- venv/Lib/site-packages/pip/_internal/metadata/__init__.py +127 -0
- venv/Lib/site-packages/pip/_internal/metadata/_json.py +84 -0
- venv/Lib/site-packages/pip/_internal/metadata/base.py +688 -0
- venv/Lib/site-packages/pip/_internal/metadata/importlib/__init__.py +4 -0
- venv/Lib/site-packages/pip/_internal/metadata/importlib/_compat.py +55 -0
- venv/Lib/site-packages/pip/_internal/metadata/importlib/_dists.py +224 -0
- venv/Lib/site-packages/pip/_internal/metadata/importlib/_envs.py +188 -0
- venv/Lib/site-packages/pip/_internal/metadata/pkg_resources.py +270 -0
- venv/Lib/site-packages/pip/_internal/models/__init__.py +2 -0
- venv/Lib/site-packages/pip/_internal/models/candidate.py +34 -0
- venv/Lib/site-packages/pip/_internal/models/direct_url.py +237 -0
- venv/Lib/site-packages/pip/_internal/models/format_control.py +80 -0
- venv/Lib/site-packages/pip/_internal/models/index.py +28 -0
- venv/Lib/site-packages/pip/_internal/models/installation_report.py +53 -0
- venv/Lib/site-packages/pip/_internal/models/link.py +581 -0
- venv/Lib/site-packages/pip/_internal/models/scheme.py +31 -0
- venv/Lib/site-packages/pip/_internal/models/search_scope.py +132 -0
- venv/Lib/site-packages/pip/_internal/models/selection_prefs.py +51 -0
- venv/Lib/site-packages/pip/_internal/models/target_python.py +110 -0
- venv/Lib/site-packages/pip/_internal/models/wheel.py +92 -0
- venv/Lib/site-packages/pip/_internal/network/__init__.py +2 -0
- venv/Lib/site-packages/pip/_internal/network/auth.py +561 -0
- venv/Lib/site-packages/pip/_internal/network/cache.py +69 -0
- venv/Lib/site-packages/pip/_internal/network/download.py +186 -0
- venv/Lib/site-packages/pip/_internal/network/lazy_wheel.py +210 -0
- venv/Lib/site-packages/pip/_internal/network/session.py +519 -0
- venv/Lib/site-packages/pip/_internal/network/utils.py +96 -0
- venv/Lib/site-packages/pip/_internal/network/xmlrpc.py +60 -0
- venv/Lib/site-packages/pip/_internal/operations/__init__.py +0 -0
- venv/Lib/site-packages/pip/_internal/operations/build/__init__.py +0 -0
- venv/Lib/site-packages/pip/_internal/operations/build/build_tracker.py +124 -0
- venv/Lib/site-packages/pip/_internal/operations/build/metadata.py +39 -0
- venv/Lib/site-packages/pip/_internal/operations/build/metadata_editable.py +41 -0
- venv/Lib/site-packages/pip/_internal/operations/build/metadata_legacy.py +74 -0
- venv/Lib/site-packages/pip/_internal/operations/build/wheel.py +37 -0
- venv/Lib/site-packages/pip/_internal/operations/build/wheel_editable.py +46 -0
- venv/Lib/site-packages/pip/_internal/operations/build/wheel_legacy.py +102 -0
- venv/Lib/site-packages/pip/_internal/operations/check.py +187 -0
- venv/Lib/site-packages/pip/_internal/operations/freeze.py +255 -0
- venv/Lib/site-packages/pip/_internal/operations/install/__init__.py +2 -0
- venv/Lib/site-packages/pip/_internal/operations/install/editable_legacy.py +46 -0
- venv/Lib/site-packages/pip/_internal/operations/install/wheel.py +740 -0
- venv/Lib/site-packages/pip/_internal/operations/prepare.py +743 -0
- venv/Lib/site-packages/pip/_internal/pyproject.py +179 -0
- venv/Lib/site-packages/pip/_internal/req/__init__.py +92 -0
- venv/Lib/site-packages/pip/_internal/req/constructors.py +506 -0
- venv/Lib/site-packages/pip/_internal/req/req_file.py +552 -0
- venv/Lib/site-packages/pip/_internal/req/req_install.py +874 -0
- venv/Lib/site-packages/pip/_internal/req/req_set.py +119 -0
- venv/Lib/site-packages/pip/_internal/req/req_uninstall.py +650 -0
- venv/Lib/site-packages/pip/_internal/resolution/__init__.py +0 -0
- venv/Lib/site-packages/pip/_internal/resolution/base.py +20 -0
- venv/Lib/site-packages/pip/_internal/resolution/legacy/__init__.py +0 -0
- venv/Lib/site-packages/pip/_internal/resolution/legacy/resolver.py +600 -0
- venv/Lib/site-packages/pip/_internal/resolution/resolvelib/__init__.py +0 -0
- venv/Lib/site-packages/pip/_internal/resolution/resolvelib/base.py +141 -0
- venv/Lib/site-packages/pip/_internal/resolution/resolvelib/candidates.py +555 -0
- venv/Lib/site-packages/pip/_internal/resolution/resolvelib/factory.py +730 -0
- venv/Lib/site-packages/pip/_internal/resolution/resolvelib/found_candidates.py +155 -0
- venv/Lib/site-packages/pip/_internal/resolution/resolvelib/provider.py +255 -0
- venv/Lib/site-packages/pip/_internal/resolution/resolvelib/reporter.py +80 -0
- venv/Lib/site-packages/pip/_internal/resolution/resolvelib/requirements.py +165 -0
- venv/Lib/site-packages/pip/_internal/resolution/resolvelib/resolver.py +299 -0
- venv/Lib/site-packages/pip/_internal/self_outdated_check.py +242 -0
- venv/Lib/site-packages/pip/_internal/utils/__init__.py +0 -0
- venv/Lib/site-packages/pip/_internal/utils/_jaraco_text.py +109 -0
- venv/Lib/site-packages/pip/_internal/utils/_log.py +38 -0
- venv/Lib/site-packages/pip/_internal/utils/appdirs.py +52 -0
- venv/Lib/site-packages/pip/_internal/utils/compat.py +63 -0
- venv/Lib/site-packages/pip/_internal/utils/compatibility_tags.py +165 -0
- venv/Lib/site-packages/pip/_internal/utils/datetime.py +11 -0
- venv/Lib/site-packages/pip/_internal/utils/deprecation.py +120 -0
- venv/Lib/site-packages/pip/_internal/utils/direct_url_helpers.py +87 -0
- venv/Lib/site-packages/pip/_internal/utils/egg_link.py +72 -0
- venv/Lib/site-packages/pip/_internal/utils/encoding.py +36 -0
- venv/Lib/site-packages/pip/_internal/utils/entrypoints.py +84 -0
- venv/Lib/site-packages/pip/_internal/utils/filesystem.py +153 -0
- venv/Lib/site-packages/pip/_internal/utils/filetypes.py +27 -0
- venv/Lib/site-packages/pip/_internal/utils/glibc.py +88 -0
- venv/Lib/site-packages/pip/_internal/utils/hashes.py +151 -0
- venv/Lib/site-packages/pip/_internal/utils/inject_securetransport.py +35 -0
- venv/Lib/site-packages/pip/_internal/utils/logging.py +348 -0
- venv/Lib/site-packages/pip/_internal/utils/misc.py +735 -0
- venv/Lib/site-packages/pip/_internal/utils/models.py +39 -0
- venv/Lib/site-packages/pip/_internal/utils/packaging.py +57 -0
- venv/Lib/site-packages/pip/_internal/utils/setuptools_build.py +146 -0
- venv/Lib/site-packages/pip/_internal/utils/subprocess.py +260 -0
- venv/Lib/site-packages/pip/_internal/utils/temp_dir.py +246 -0
- venv/Lib/site-packages/pip/_internal/utils/unpacking.py +257 -0
- venv/Lib/site-packages/pip/_internal/utils/urls.py +62 -0
- venv/Lib/site-packages/pip/_internal/utils/virtualenv.py +104 -0
- venv/Lib/site-packages/pip/_internal/utils/wheel.py +136 -0
- venv/Lib/site-packages/pip/_internal/vcs/__init__.py +15 -0
- venv/Lib/site-packages/pip/_internal/vcs/bazaar.py +112 -0
- venv/Lib/site-packages/pip/_internal/vcs/git.py +526 -0
- venv/Lib/site-packages/pip/_internal/vcs/mercurial.py +163 -0
- venv/Lib/site-packages/pip/_internal/vcs/subversion.py +324 -0
- venv/Lib/site-packages/pip/_internal/vcs/versioncontrol.py +705 -0
- venv/Lib/site-packages/pip/_internal/wheel_builder.py +355 -0
- venv/Lib/site-packages/pip/_vendor/__init__.py +120 -0
- venv/Lib/site-packages/pip/_vendor/cachecontrol/__init__.py +18 -0
- venv/Lib/site-packages/pip/_vendor/cachecontrol/_cmd.py +61 -0
- venv/Lib/site-packages/pip/_vendor/cachecontrol/adapter.py +137 -0
- venv/Lib/site-packages/pip/_vendor/cachecontrol/cache.py +65 -0
- venv/Lib/site-packages/pip/_vendor/cachecontrol/caches/__init__.py +9 -0
- venv/Lib/site-packages/pip/_vendor/cachecontrol/caches/file_cache.py +188 -0
- venv/Lib/site-packages/pip/_vendor/cachecontrol/caches/redis_cache.py +39 -0
- venv/Lib/site-packages/pip/_vendor/cachecontrol/compat.py +32 -0
- venv/Lib/site-packages/pip/_vendor/cachecontrol/controller.py +439 -0
- venv/Lib/site-packages/pip/_vendor/cachecontrol/filewrapper.py +111 -0
- venv/Lib/site-packages/pip/_vendor/cachecontrol/heuristics.py +139 -0
- venv/Lib/site-packages/pip/_vendor/cachecontrol/serialize.py +190 -0
- venv/Lib/site-packages/pip/_vendor/cachecontrol/wrapper.py +33 -0
- venv/Lib/site-packages/pip/_vendor/certifi/__init__.py +4 -0
- venv/Lib/site-packages/pip/_vendor/certifi/__main__.py +12 -0
- venv/Lib/site-packages/pip/_vendor/certifi/core.py +108 -0
- venv/Lib/site-packages/pip/_vendor/chardet/__init__.py +115 -0
- venv/Lib/site-packages/pip/_vendor/chardet/big5freq.py +386 -0
- venv/Lib/site-packages/pip/_vendor/chardet/big5prober.py +47 -0
- venv/Lib/site-packages/pip/_vendor/chardet/chardistribution.py +261 -0
- venv/Lib/site-packages/pip/_vendor/chardet/charsetgroupprober.py +106 -0
- venv/Lib/site-packages/pip/_vendor/chardet/charsetprober.py +147 -0
- venv/Lib/site-packages/pip/_vendor/chardet/cli/__init__.py +0 -0
- venv/Lib/site-packages/pip/_vendor/chardet/cli/chardetect.py +112 -0
- venv/Lib/site-packages/pip/_vendor/chardet/codingstatemachine.py +90 -0
- venv/Lib/site-packages/pip/_vendor/chardet/codingstatemachinedict.py +19 -0
- venv/Lib/site-packages/pip/_vendor/chardet/cp949prober.py +49 -0
- venv/Lib/site-packages/pip/_vendor/chardet/enums.py +85 -0
- venv/Lib/site-packages/pip/_vendor/chardet/escprober.py +102 -0
- venv/Lib/site-packages/pip/_vendor/chardet/escsm.py +261 -0
- venv/Lib/site-packages/pip/_vendor/chardet/eucjpprober.py +102 -0
- venv/Lib/site-packages/pip/_vendor/chardet/euckrfreq.py +196 -0
- venv/Lib/site-packages/pip/_vendor/chardet/euckrprober.py +47 -0
- venv/Lib/site-packages/pip/_vendor/chardet/euctwfreq.py +388 -0
- venv/Lib/site-packages/pip/_vendor/chardet/euctwprober.py +47 -0
- venv/Lib/site-packages/pip/_vendor/chardet/gb2312freq.py +284 -0
- venv/Lib/site-packages/pip/_vendor/chardet/gb2312prober.py +47 -0
- venv/Lib/site-packages/pip/_vendor/chardet/hebrewprober.py +316 -0
- venv/Lib/site-packages/pip/_vendor/chardet/jisfreq.py +325 -0
- venv/Lib/site-packages/pip/_vendor/chardet/johabfreq.py +2382 -0
- venv/Lib/site-packages/pip/_vendor/chardet/johabprober.py +47 -0
- venv/Lib/site-packages/pip/_vendor/chardet/jpcntx.py +238 -0
- venv/Lib/site-packages/pip/_vendor/chardet/langbulgarianmodel.py +4649 -0
- venv/Lib/site-packages/pip/_vendor/chardet/langgreekmodel.py +4397 -0
- venv/Lib/site-packages/pip/_vendor/chardet/langhebrewmodel.py +4380 -0
- venv/Lib/site-packages/pip/_vendor/chardet/langhungarianmodel.py +4649 -0
- venv/Lib/site-packages/pip/_vendor/chardet/langrussianmodel.py +5725 -0
- venv/Lib/site-packages/pip/_vendor/chardet/langthaimodel.py +4380 -0
- venv/Lib/site-packages/pip/_vendor/chardet/langturkishmodel.py +4380 -0
- venv/Lib/site-packages/pip/_vendor/chardet/latin1prober.py +147 -0
- venv/Lib/site-packages/pip/_vendor/chardet/macromanprober.py +162 -0
- venv/Lib/site-packages/pip/_vendor/chardet/mbcharsetprober.py +95 -0
- venv/Lib/site-packages/pip/_vendor/chardet/mbcsgroupprober.py +57 -0
- venv/Lib/site-packages/pip/_vendor/chardet/mbcssm.py +661 -0
- venv/Lib/site-packages/pip/_vendor/chardet/metadata/__init__.py +0 -0
- venv/Lib/site-packages/pip/_vendor/chardet/metadata/languages.py +352 -0
- venv/Lib/site-packages/pip/_vendor/chardet/resultdict.py +16 -0
- venv/Lib/site-packages/pip/_vendor/chardet/sbcharsetprober.py +162 -0
- venv/Lib/site-packages/pip/_vendor/chardet/sbcsgroupprober.py +88 -0
- venv/Lib/site-packages/pip/_vendor/chardet/sjisprober.py +105 -0
- venv/Lib/site-packages/pip/_vendor/chardet/universaldetector.py +362 -0
- venv/Lib/site-packages/pip/_vendor/chardet/utf1632prober.py +225 -0
- venv/Lib/site-packages/pip/_vendor/chardet/utf8prober.py +82 -0
- venv/Lib/site-packages/pip/_vendor/chardet/version.py +9 -0
- venv/Lib/site-packages/pip/_vendor/colorama/__init__.py +7 -0
- venv/Lib/site-packages/pip/_vendor/colorama/ansi.py +102 -0
- venv/Lib/site-packages/pip/_vendor/colorama/ansitowin32.py +277 -0
- venv/Lib/site-packages/pip/_vendor/colorama/initialise.py +121 -0
- venv/Lib/site-packages/pip/_vendor/colorama/tests/__init__.py +1 -0
- venv/Lib/site-packages/pip/_vendor/colorama/tests/ansi_test.py +76 -0
- venv/Lib/site-packages/pip/_vendor/colorama/tests/ansitowin32_test.py +294 -0
- venv/Lib/site-packages/pip/_vendor/colorama/tests/initialise_test.py +189 -0
- venv/Lib/site-packages/pip/_vendor/colorama/tests/isatty_test.py +57 -0
- venv/Lib/site-packages/pip/_vendor/colorama/tests/utils.py +49 -0
- venv/Lib/site-packages/pip/_vendor/colorama/tests/winterm_test.py +131 -0
- venv/Lib/site-packages/pip/_vendor/colorama/win32.py +180 -0
- venv/Lib/site-packages/pip/_vendor/colorama/winterm.py +195 -0
- venv/Lib/site-packages/pip/_vendor/distlib/__init__.py +23 -0
- venv/Lib/site-packages/pip/_vendor/distlib/compat.py +1116 -0
- venv/Lib/site-packages/pip/_vendor/distlib/database.py +1350 -0
- venv/Lib/site-packages/pip/_vendor/distlib/index.py +508 -0
- venv/Lib/site-packages/pip/_vendor/distlib/locators.py +1300 -0
- venv/Lib/site-packages/pip/_vendor/distlib/manifest.py +393 -0
- venv/Lib/site-packages/pip/_vendor/distlib/markers.py +152 -0
- venv/Lib/site-packages/pip/_vendor/distlib/metadata.py +1076 -0
- venv/Lib/site-packages/pip/_vendor/distlib/resources.py +358 -0
- venv/Lib/site-packages/pip/_vendor/distlib/scripts.py +437 -0
- venv/Lib/site-packages/pip/_vendor/distlib/util.py +1932 -0
- venv/Lib/site-packages/pip/_vendor/distlib/version.py +739 -0
- venv/Lib/site-packages/pip/_vendor/distlib/wheel.py +1082 -0
- venv/Lib/site-packages/pip/_vendor/distro/__init__.py +54 -0
- venv/Lib/site-packages/pip/_vendor/distro/__main__.py +4 -0
- venv/Lib/site-packages/pip/_vendor/distro/distro.py +1399 -0
- venv/Lib/site-packages/pip/_vendor/idna/__init__.py +44 -0
- venv/Lib/site-packages/pip/_vendor/idna/codec.py +112 -0
- venv/Lib/site-packages/pip/_vendor/idna/compat.py +13 -0
- venv/Lib/site-packages/pip/_vendor/idna/core.py +400 -0
- venv/Lib/site-packages/pip/_vendor/idna/idnadata.py +2151 -0
- venv/Lib/site-packages/pip/_vendor/idna/intranges.py +54 -0
- venv/Lib/site-packages/pip/_vendor/idna/package_data.py +2 -0
- venv/Lib/site-packages/pip/_vendor/idna/uts46data.py +8600 -0
- venv/Lib/site-packages/pip/_vendor/msgpack/__init__.py +57 -0
- venv/Lib/site-packages/pip/_vendor/msgpack/exceptions.py +48 -0
- venv/Lib/site-packages/pip/_vendor/msgpack/ext.py +193 -0
- venv/Lib/site-packages/pip/_vendor/msgpack/fallback.py +1010 -0
- venv/Lib/site-packages/pip/_vendor/packaging/__about__.py +26 -0
- venv/Lib/site-packages/pip/_vendor/packaging/__init__.py +25 -0
- venv/Lib/site-packages/pip/_vendor/packaging/_manylinux.py +301 -0
- venv/Lib/site-packages/pip/_vendor/packaging/_musllinux.py +136 -0
- venv/Lib/site-packages/pip/_vendor/packaging/_structures.py +61 -0
- venv/Lib/site-packages/pip/_vendor/packaging/markers.py +304 -0
- venv/Lib/site-packages/pip/_vendor/packaging/requirements.py +146 -0
- venv/Lib/site-packages/pip/_vendor/packaging/specifiers.py +802 -0
- venv/Lib/site-packages/pip/_vendor/packaging/tags.py +487 -0
- venv/Lib/site-packages/pip/_vendor/packaging/utils.py +136 -0
- venv/Lib/site-packages/pip/_vendor/packaging/version.py +504 -0
- venv/Lib/site-packages/pip/_vendor/pkg_resources/__init__.py +3361 -0
- venv/Lib/site-packages/pip/_vendor/platformdirs/__init__.py +566 -0
- venv/Lib/site-packages/pip/_vendor/platformdirs/__main__.py +53 -0
- venv/Lib/site-packages/pip/_vendor/platformdirs/android.py +210 -0
- venv/Lib/site-packages/pip/_vendor/platformdirs/api.py +223 -0
- venv/Lib/site-packages/pip/_vendor/platformdirs/macos.py +91 -0
- venv/Lib/site-packages/pip/_vendor/platformdirs/unix.py +223 -0
- venv/Lib/site-packages/pip/_vendor/platformdirs/version.py +4 -0
- venv/Lib/site-packages/pip/_vendor/platformdirs/windows.py +255 -0
- venv/Lib/site-packages/pip/_vendor/pygments/__init__.py +82 -0
- venv/Lib/site-packages/pip/_vendor/pygments/__main__.py +17 -0
- venv/Lib/site-packages/pip/_vendor/pygments/cmdline.py +668 -0
- venv/Lib/site-packages/pip/_vendor/pygments/console.py +70 -0
- venv/Lib/site-packages/pip/_vendor/pygments/filter.py +71 -0
- venv/Lib/site-packages/pip/_vendor/pygments/filters/__init__.py +940 -0
- venv/Lib/site-packages/pip/_vendor/pygments/formatter.py +124 -0
- venv/Lib/site-packages/pip/_vendor/pygments/formatters/__init__.py +158 -0
- venv/Lib/site-packages/pip/_vendor/pygments/formatters/_mapping.py +23 -0
- venv/Lib/site-packages/pip/_vendor/pygments/formatters/bbcode.py +108 -0
- venv/Lib/site-packages/pip/_vendor/pygments/formatters/groff.py +170 -0
- venv/Lib/site-packages/pip/_vendor/pygments/formatters/html.py +989 -0
- venv/Lib/site-packages/pip/_vendor/pygments/formatters/img.py +645 -0
- venv/Lib/site-packages/pip/_vendor/pygments/formatters/irc.py +154 -0
- venv/Lib/site-packages/pip/_vendor/pygments/formatters/latex.py +521 -0
- venv/Lib/site-packages/pip/_vendor/pygments/formatters/other.py +161 -0
- venv/Lib/site-packages/pip/_vendor/pygments/formatters/pangomarkup.py +83 -0
- venv/Lib/site-packages/pip/_vendor/pygments/formatters/rtf.py +146 -0
- venv/Lib/site-packages/pip/_vendor/pygments/formatters/svg.py +188 -0
- venv/Lib/site-packages/pip/_vendor/pygments/formatters/terminal.py +127 -0
- venv/Lib/site-packages/pip/_vendor/pygments/formatters/terminal256.py +338 -0
- venv/Lib/site-packages/pip/_vendor/pygments/lexer.py +943 -0
- venv/Lib/site-packages/pip/_vendor/pygments/lexers/__init__.py +362 -0
- venv/Lib/site-packages/pip/_vendor/pygments/lexers/_mapping.py +559 -0
- venv/Lib/site-packages/pip/_vendor/pygments/lexers/python.py +1198 -0
- venv/Lib/site-packages/pip/_vendor/pygments/modeline.py +43 -0
- venv/Lib/site-packages/pip/_vendor/pygments/plugin.py +88 -0
- venv/Lib/site-packages/pip/_vendor/pygments/regexopt.py +91 -0
- venv/Lib/site-packages/pip/_vendor/pygments/scanner.py +104 -0
- venv/Lib/site-packages/pip/_vendor/pygments/sphinxext.py +217 -0
- venv/Lib/site-packages/pip/_vendor/pygments/style.py +197 -0
- venv/Lib/site-packages/pip/_vendor/pygments/styles/__init__.py +103 -0
- venv/Lib/site-packages/pip/_vendor/pygments/token.py +213 -0
- venv/Lib/site-packages/pip/_vendor/pygments/unistring.py +153 -0
- venv/Lib/site-packages/pip/_vendor/pygments/util.py +330 -0
- venv/Lib/site-packages/pip/_vendor/pyparsing/__init__.py +322 -0
- venv/Lib/site-packages/pip/_vendor/pyparsing/actions.py +217 -0
- venv/Lib/site-packages/pip/_vendor/pyparsing/common.py +432 -0
- venv/Lib/site-packages/pip/_vendor/pyparsing/core.py +6115 -0
- venv/Lib/site-packages/pip/_vendor/pyparsing/diagram/__init__.py +656 -0
- venv/Lib/site-packages/pip/_vendor/pyparsing/exceptions.py +299 -0
- venv/Lib/site-packages/pip/_vendor/pyparsing/helpers.py +1100 -0
- venv/Lib/site-packages/pip/_vendor/pyparsing/results.py +796 -0
- venv/Lib/site-packages/pip/_vendor/pyparsing/testing.py +331 -0
- venv/Lib/site-packages/pip/_vendor/pyparsing/unicode.py +361 -0
- venv/Lib/site-packages/pip/_vendor/pyparsing/util.py +284 -0
- venv/Lib/site-packages/pip/_vendor/pyproject_hooks/__init__.py +23 -0
- venv/Lib/site-packages/pip/_vendor/pyproject_hooks/_compat.py +8 -0
- venv/Lib/site-packages/pip/_vendor/pyproject_hooks/_impl.py +330 -0
- venv/Lib/site-packages/pip/_vendor/pyproject_hooks/_in_process/__init__.py +18 -0
- venv/Lib/site-packages/pip/_vendor/pyproject_hooks/_in_process/_in_process.py +353 -0
- venv/Lib/site-packages/pip/_vendor/requests/__init__.py +182 -0
- venv/Lib/site-packages/pip/_vendor/requests/__version__.py +14 -0
- venv/Lib/site-packages/pip/_vendor/requests/_internal_utils.py +50 -0
- venv/Lib/site-packages/pip/_vendor/requests/adapters.py +538 -0
- venv/Lib/site-packages/pip/_vendor/requests/api.py +157 -0
- venv/Lib/site-packages/pip/_vendor/requests/auth.py +315 -0
- venv/Lib/site-packages/pip/_vendor/requests/certs.py +24 -0
- venv/Lib/site-packages/pip/_vendor/requests/compat.py +67 -0
- venv/Lib/site-packages/pip/_vendor/requests/cookies.py +561 -0
- venv/Lib/site-packages/pip/_vendor/requests/exceptions.py +141 -0
- venv/Lib/site-packages/pip/_vendor/requests/help.py +131 -0
- venv/Lib/site-packages/pip/_vendor/requests/hooks.py +33 -0
- venv/Lib/site-packages/pip/_vendor/requests/models.py +1034 -0
- venv/Lib/site-packages/pip/_vendor/requests/packages.py +16 -0
- venv/Lib/site-packages/pip/_vendor/requests/sessions.py +833 -0
- venv/Lib/site-packages/pip/_vendor/requests/status_codes.py +128 -0
- venv/Lib/site-packages/pip/_vendor/requests/structures.py +99 -0
- venv/Lib/site-packages/pip/_vendor/requests/utils.py +1094 -0
- venv/Lib/site-packages/pip/_vendor/resolvelib/__init__.py +26 -0
- venv/Lib/site-packages/pip/_vendor/resolvelib/compat/__init__.py +0 -0
- venv/Lib/site-packages/pip/_vendor/resolvelib/compat/collections_abc.py +6 -0
- venv/Lib/site-packages/pip/_vendor/resolvelib/providers.py +133 -0
- venv/Lib/site-packages/pip/_vendor/resolvelib/reporters.py +43 -0
- venv/Lib/site-packages/pip/_vendor/resolvelib/resolvers.py +547 -0
- venv/Lib/site-packages/pip/_vendor/resolvelib/structs.py +170 -0
- venv/Lib/site-packages/pip/_vendor/rich/__init__.py +177 -0
- venv/Lib/site-packages/pip/_vendor/rich/__main__.py +274 -0
- venv/Lib/site-packages/pip/_vendor/rich/_cell_widths.py +451 -0
- venv/Lib/site-packages/pip/_vendor/rich/_emoji_codes.py +3610 -0
- venv/Lib/site-packages/pip/_vendor/rich/_emoji_replace.py +32 -0
- venv/Lib/site-packages/pip/_vendor/rich/_export_format.py +76 -0
- venv/Lib/site-packages/pip/_vendor/rich/_extension.py +10 -0
- venv/Lib/site-packages/pip/_vendor/rich/_fileno.py +24 -0
- venv/Lib/site-packages/pip/_vendor/rich/_inspect.py +270 -0
- venv/Lib/site-packages/pip/_vendor/rich/_log_render.py +94 -0
- venv/Lib/site-packages/pip/_vendor/rich/_loop.py +43 -0
- venv/Lib/site-packages/pip/_vendor/rich/_null_file.py +69 -0
- venv/Lib/site-packages/pip/_vendor/rich/_palettes.py +309 -0
- venv/Lib/site-packages/pip/_vendor/rich/_pick.py +17 -0
- venv/Lib/site-packages/pip/_vendor/rich/_ratio.py +160 -0
- venv/Lib/site-packages/pip/_vendor/rich/_spinners.py +482 -0
- venv/Lib/site-packages/pip/_vendor/rich/_stack.py +16 -0
- venv/Lib/site-packages/pip/_vendor/rich/_timer.py +19 -0
- venv/Lib/site-packages/pip/_vendor/rich/_win32_console.py +662 -0
- venv/Lib/site-packages/pip/_vendor/rich/_windows.py +72 -0
- venv/Lib/site-packages/pip/_vendor/rich/_windows_renderer.py +56 -0
- venv/Lib/site-packages/pip/_vendor/rich/_wrap.py +56 -0
- venv/Lib/site-packages/pip/_vendor/rich/abc.py +33 -0
- venv/Lib/site-packages/pip/_vendor/rich/align.py +311 -0
- venv/Lib/site-packages/pip/_vendor/rich/ansi.py +240 -0
- venv/Lib/site-packages/pip/_vendor/rich/bar.py +94 -0
- venv/Lib/site-packages/pip/_vendor/rich/box.py +517 -0
- venv/Lib/site-packages/pip/_vendor/rich/cells.py +154 -0
- venv/Lib/site-packages/pip/_vendor/rich/color.py +622 -0
- venv/Lib/site-packages/pip/_vendor/rich/color_triplet.py +38 -0
- venv/Lib/site-packages/pip/_vendor/rich/columns.py +187 -0
- venv/Lib/site-packages/pip/_vendor/rich/console.py +2633 -0
- venv/Lib/site-packages/pip/_vendor/rich/constrain.py +37 -0
- venv/Lib/site-packages/pip/_vendor/rich/containers.py +167 -0
- venv/Lib/site-packages/pip/_vendor/rich/control.py +225 -0
- venv/Lib/site-packages/pip/_vendor/rich/default_styles.py +190 -0
- venv/Lib/site-packages/pip/_vendor/rich/diagnose.py +37 -0
- venv/Lib/site-packages/pip/_vendor/rich/emoji.py +96 -0
- venv/Lib/site-packages/pip/_vendor/rich/errors.py +34 -0
- venv/Lib/site-packages/pip/_vendor/rich/file_proxy.py +57 -0
- venv/Lib/site-packages/pip/_vendor/rich/filesize.py +89 -0
- venv/Lib/site-packages/pip/_vendor/rich/highlighter.py +232 -0
- venv/Lib/site-packages/pip/_vendor/rich/json.py +140 -0
- venv/Lib/site-packages/pip/_vendor/rich/jupyter.py +101 -0
- venv/Lib/site-packages/pip/_vendor/rich/layout.py +443 -0
- venv/Lib/site-packages/pip/_vendor/rich/live.py +375 -0
- venv/Lib/site-packages/pip/_vendor/rich/live_render.py +113 -0
- venv/Lib/site-packages/pip/_vendor/rich/logging.py +289 -0
- venv/Lib/site-packages/pip/_vendor/rich/markup.py +246 -0
- venv/Lib/site-packages/pip/_vendor/rich/measure.py +151 -0
- venv/Lib/site-packages/pip/_vendor/rich/padding.py +141 -0
- venv/Lib/site-packages/pip/_vendor/rich/pager.py +34 -0
- venv/Lib/site-packages/pip/_vendor/rich/palette.py +100 -0
- venv/Lib/site-packages/pip/_vendor/rich/panel.py +308 -0
- venv/Lib/site-packages/pip/_vendor/rich/pretty.py +994 -0
- venv/Lib/site-packages/pip/_vendor/rich/progress.py +1702 -0
- venv/Lib/site-packages/pip/_vendor/rich/progress_bar.py +224 -0
- venv/Lib/site-packages/pip/_vendor/rich/prompt.py +376 -0
- venv/Lib/site-packages/pip/_vendor/rich/protocol.py +42 -0
- venv/Lib/site-packages/pip/_vendor/rich/region.py +10 -0
- venv/Lib/site-packages/pip/_vendor/rich/repr.py +149 -0
- venv/Lib/site-packages/pip/_vendor/rich/rule.py +130 -0
- venv/Lib/site-packages/pip/_vendor/rich/scope.py +86 -0
- venv/Lib/site-packages/pip/_vendor/rich/screen.py +54 -0
- venv/Lib/site-packages/pip/_vendor/rich/segment.py +739 -0
- venv/Lib/site-packages/pip/_vendor/rich/spinner.py +137 -0
- venv/Lib/site-packages/pip/_vendor/rich/status.py +132 -0
- venv/Lib/site-packages/pip/_vendor/rich/style.py +796 -0
- venv/Lib/site-packages/pip/_vendor/rich/styled.py +42 -0
- venv/Lib/site-packages/pip/_vendor/rich/syntax.py +948 -0
- venv/Lib/site-packages/pip/_vendor/rich/table.py +1002 -0
- venv/Lib/site-packages/pip/_vendor/rich/terminal_theme.py +153 -0
- venv/Lib/site-packages/pip/_vendor/rich/text.py +1307 -0
- venv/Lib/site-packages/pip/_vendor/rich/theme.py +115 -0
- venv/Lib/site-packages/pip/_vendor/rich/themes.py +5 -0
- venv/Lib/site-packages/pip/_vendor/rich/traceback.py +756 -0
- venv/Lib/site-packages/pip/_vendor/rich/tree.py +251 -0
- venv/Lib/site-packages/pip/_vendor/six.py +998 -0
- venv/Lib/site-packages/pip/_vendor/tenacity/__init__.py +608 -0
- venv/Lib/site-packages/pip/_vendor/tenacity/_asyncio.py +94 -0
- venv/Lib/site-packages/pip/_vendor/tenacity/_utils.py +76 -0
- venv/Lib/site-packages/pip/_vendor/tenacity/after.py +51 -0
- venv/Lib/site-packages/pip/_vendor/tenacity/before.py +46 -0
- venv/Lib/site-packages/pip/_vendor/tenacity/before_sleep.py +71 -0
- venv/Lib/site-packages/pip/_vendor/tenacity/nap.py +43 -0
- venv/Lib/site-packages/pip/_vendor/tenacity/retry.py +272 -0
- venv/Lib/site-packages/pip/_vendor/tenacity/stop.py +103 -0
- venv/Lib/site-packages/pip/_vendor/tenacity/tornadoweb.py +59 -0
- venv/Lib/site-packages/pip/_vendor/tenacity/wait.py +228 -0
- venv/Lib/site-packages/pip/_vendor/tomli/__init__.py +11 -0
- venv/Lib/site-packages/pip/_vendor/tomli/_parser.py +691 -0
- venv/Lib/site-packages/pip/_vendor/tomli/_re.py +107 -0
- venv/Lib/site-packages/pip/_vendor/tomli/_types.py +10 -0
- venv/Lib/site-packages/pip/_vendor/typing_extensions.py +3072 -0
- venv/Lib/site-packages/pip/_vendor/urllib3/__init__.py +102 -0
- venv/Lib/site-packages/pip/_vendor/urllib3/_collections.py +337 -0
- venv/Lib/site-packages/pip/_vendor/urllib3/_version.py +2 -0
- venv/Lib/site-packages/pip/_vendor/urllib3/connection.py +572 -0
- venv/Lib/site-packages/pip/_vendor/urllib3/connectionpool.py +1132 -0
- venv/Lib/site-packages/pip/_vendor/urllib3/contrib/__init__.py +0 -0
- venv/Lib/site-packages/pip/_vendor/urllib3/contrib/_appengine_environ.py +36 -0
- venv/Lib/site-packages/pip/_vendor/urllib3/contrib/_securetransport/__init__.py +0 -0
- venv/Lib/site-packages/pip/_vendor/urllib3/contrib/_securetransport/bindings.py +519 -0
- venv/Lib/site-packages/pip/_vendor/urllib3/contrib/_securetransport/low_level.py +397 -0
- venv/Lib/site-packages/pip/_vendor/urllib3/contrib/appengine.py +314 -0
- venv/Lib/site-packages/pip/_vendor/urllib3/contrib/ntlmpool.py +130 -0
- venv/Lib/site-packages/pip/_vendor/urllib3/contrib/pyopenssl.py +518 -0
- venv/Lib/site-packages/pip/_vendor/urllib3/contrib/securetransport.py +921 -0
- venv/Lib/site-packages/pip/_vendor/urllib3/contrib/socks.py +216 -0
- venv/Lib/site-packages/pip/_vendor/urllib3/exceptions.py +323 -0
- venv/Lib/site-packages/pip/_vendor/urllib3/fields.py +274 -0
- venv/Lib/site-packages/pip/_vendor/urllib3/filepost.py +98 -0
- venv/Lib/site-packages/pip/_vendor/urllib3/packages/__init__.py +0 -0
- venv/Lib/site-packages/pip/_vendor/urllib3/packages/backports/__init__.py +0 -0
- venv/Lib/site-packages/pip/_vendor/urllib3/packages/backports/makefile.py +51 -0
- venv/Lib/site-packages/pip/_vendor/urllib3/packages/backports/weakref_finalize.py +155 -0
- venv/Lib/site-packages/pip/_vendor/urllib3/packages/six.py +1076 -0
- venv/Lib/site-packages/pip/_vendor/urllib3/poolmanager.py +537 -0
- venv/Lib/site-packages/pip/_vendor/urllib3/request.py +170 -0
- venv/Lib/site-packages/pip/_vendor/urllib3/response.py +879 -0
- venv/Lib/site-packages/pip/_vendor/urllib3/util/__init__.py +49 -0
- venv/Lib/site-packages/pip/_vendor/urllib3/util/connection.py +149 -0
- venv/Lib/site-packages/pip/_vendor/urllib3/util/proxy.py +57 -0
- venv/Lib/site-packages/pip/_vendor/urllib3/util/queue.py +22 -0
- venv/Lib/site-packages/pip/_vendor/urllib3/util/request.py +137 -0
- venv/Lib/site-packages/pip/_vendor/urllib3/util/response.py +107 -0
- venv/Lib/site-packages/pip/_vendor/urllib3/util/retry.py +620 -0
- venv/Lib/site-packages/pip/_vendor/urllib3/util/ssl_.py +495 -0
- venv/Lib/site-packages/pip/_vendor/urllib3/util/ssl_match_hostname.py +159 -0
- venv/Lib/site-packages/pip/_vendor/urllib3/util/ssltransport.py +221 -0
- venv/Lib/site-packages/pip/_vendor/urllib3/util/timeout.py +271 -0
- venv/Lib/site-packages/pip/_vendor/urllib3/util/url.py +435 -0
- venv/Lib/site-packages/pip/_vendor/urllib3/util/wait.py +152 -0
- venv/Lib/site-packages/pip/_vendor/webencodings/__init__.py +342 -0
- venv/Lib/site-packages/pip/_vendor/webencodings/labels.py +231 -0
- venv/Lib/site-packages/pip/_vendor/webencodings/mklabels.py +59 -0
- venv/Lib/site-packages/pip/_vendor/webencodings/tests.py +153 -0
- venv/Lib/site-packages/pip/_vendor/webencodings/x_user_defined.py +325 -0
- venv/Lib/site-packages/pip/py.typed +4 -0
- venv/Lib/site-packages/pkg_resources/__init__.py +3296 -0
- venv/Lib/site-packages/pkg_resources/_vendor/__init__.py +0 -0
- venv/Lib/site-packages/pkg_resources/_vendor/appdirs.py +608 -0
- venv/Lib/site-packages/pkg_resources/_vendor/importlib_resources/__init__.py +36 -0
- venv/Lib/site-packages/pkg_resources/_vendor/importlib_resources/_adapters.py +170 -0
- venv/Lib/site-packages/pkg_resources/_vendor/importlib_resources/_common.py +104 -0
- venv/Lib/site-packages/pkg_resources/_vendor/importlib_resources/_compat.py +98 -0
- venv/Lib/site-packages/pkg_resources/_vendor/importlib_resources/_itertools.py +35 -0
- venv/Lib/site-packages/pkg_resources/_vendor/importlib_resources/_legacy.py +121 -0
- venv/Lib/site-packages/pkg_resources/_vendor/importlib_resources/abc.py +137 -0
- venv/Lib/site-packages/pkg_resources/_vendor/importlib_resources/readers.py +122 -0
- venv/Lib/site-packages/pkg_resources/_vendor/importlib_resources/simple.py +116 -0
- venv/Lib/site-packages/pkg_resources/_vendor/jaraco/__init__.py +0 -0
- venv/Lib/site-packages/pkg_resources/_vendor/jaraco/context.py +213 -0
- venv/Lib/site-packages/pkg_resources/_vendor/jaraco/functools.py +525 -0
- venv/Lib/site-packages/pkg_resources/_vendor/jaraco/text/__init__.py +599 -0
- venv/Lib/site-packages/pkg_resources/_vendor/more_itertools/__init__.py +4 -0
- venv/Lib/site-packages/pkg_resources/_vendor/more_itertools/more.py +4316 -0
- venv/Lib/site-packages/pkg_resources/_vendor/more_itertools/recipes.py +698 -0
- venv/Lib/site-packages/pkg_resources/_vendor/packaging/__about__.py +26 -0
- venv/Lib/site-packages/pkg_resources/_vendor/packaging/__init__.py +25 -0
- venv/Lib/site-packages/pkg_resources/_vendor/packaging/_manylinux.py +301 -0
- venv/Lib/site-packages/pkg_resources/_vendor/packaging/_musllinux.py +136 -0
- venv/Lib/site-packages/pkg_resources/_vendor/packaging/_structures.py +61 -0
- venv/Lib/site-packages/pkg_resources/_vendor/packaging/markers.py +304 -0
- venv/Lib/site-packages/pkg_resources/_vendor/packaging/requirements.py +146 -0
- venv/Lib/site-packages/pkg_resources/_vendor/packaging/specifiers.py +802 -0
- venv/Lib/site-packages/pkg_resources/_vendor/packaging/tags.py +487 -0
- venv/Lib/site-packages/pkg_resources/_vendor/packaging/utils.py +136 -0
- venv/Lib/site-packages/pkg_resources/_vendor/packaging/version.py +504 -0
- venv/Lib/site-packages/pkg_resources/_vendor/pyparsing/__init__.py +331 -0
- venv/Lib/site-packages/pkg_resources/_vendor/pyparsing/actions.py +207 -0
- venv/Lib/site-packages/pkg_resources/_vendor/pyparsing/common.py +424 -0
- venv/Lib/site-packages/pkg_resources/_vendor/pyparsing/core.py +5814 -0
- venv/Lib/site-packages/pkg_resources/_vendor/pyparsing/diagram/__init__.py +642 -0
- venv/Lib/site-packages/pkg_resources/_vendor/pyparsing/exceptions.py +267 -0
- venv/Lib/site-packages/pkg_resources/_vendor/pyparsing/helpers.py +1088 -0
- venv/Lib/site-packages/pkg_resources/_vendor/pyparsing/results.py +760 -0
- venv/Lib/site-packages/pkg_resources/_vendor/pyparsing/testing.py +331 -0
- venv/Lib/site-packages/pkg_resources/_vendor/pyparsing/unicode.py +352 -0
- venv/Lib/site-packages/pkg_resources/_vendor/pyparsing/util.py +235 -0
- venv/Lib/site-packages/pkg_resources/_vendor/zipp.py +329 -0
- venv/Lib/site-packages/pkg_resources/extern/__init__.py +76 -0
- venv/Lib/site-packages/setuptools/__init__.py +247 -0
- venv/Lib/site-packages/setuptools/_deprecation_warning.py +7 -0
- venv/Lib/site-packages/setuptools/_distutils/__init__.py +24 -0
- venv/Lib/site-packages/setuptools/_distutils/_collections.py +56 -0
- venv/Lib/site-packages/setuptools/_distutils/_functools.py +20 -0
- venv/Lib/site-packages/setuptools/_distutils/_macos_compat.py +12 -0
- venv/Lib/site-packages/setuptools/_distutils/_msvccompiler.py +572 -0
- venv/Lib/site-packages/setuptools/_distutils/archive_util.py +280 -0
- venv/Lib/site-packages/setuptools/_distutils/bcppcompiler.py +408 -0
- venv/Lib/site-packages/setuptools/_distutils/ccompiler.py +1220 -0
- venv/Lib/site-packages/setuptools/_distutils/cmd.py +436 -0
- venv/Lib/site-packages/setuptools/_distutils/command/__init__.py +25 -0
- venv/Lib/site-packages/setuptools/_distutils/command/_framework_compat.py +55 -0
- venv/Lib/site-packages/setuptools/_distutils/command/bdist.py +157 -0
- venv/Lib/site-packages/setuptools/_distutils/command/bdist_dumb.py +144 -0
- venv/Lib/site-packages/setuptools/_distutils/command/bdist_rpm.py +615 -0
- venv/Lib/site-packages/setuptools/_distutils/command/build.py +153 -0
- venv/Lib/site-packages/setuptools/_distutils/command/build_clib.py +208 -0
- venv/Lib/site-packages/setuptools/_distutils/command/build_ext.py +787 -0
- venv/Lib/site-packages/setuptools/_distutils/command/build_py.py +407 -0
- venv/Lib/site-packages/setuptools/_distutils/command/build_scripts.py +173 -0
- venv/Lib/site-packages/setuptools/_distutils/command/check.py +151 -0
- venv/Lib/site-packages/setuptools/_distutils/command/clean.py +76 -0
- venv/Lib/site-packages/setuptools/_distutils/command/config.py +377 -0
- venv/Lib/site-packages/setuptools/_distutils/command/install.py +814 -0
- venv/Lib/site-packages/setuptools/_distutils/command/install_data.py +84 -0
- venv/Lib/site-packages/setuptools/_distutils/command/install_egg_info.py +91 -0
- venv/Lib/site-packages/setuptools/_distutils/command/install_headers.py +45 -0
- venv/Lib/site-packages/setuptools/_distutils/command/install_lib.py +238 -0
- venv/Lib/site-packages/setuptools/_distutils/command/install_scripts.py +61 -0
- venv/Lib/site-packages/setuptools/_distutils/command/py37compat.py +31 -0
- venv/Lib/site-packages/setuptools/_distutils/command/register.py +319 -0
- venv/Lib/site-packages/setuptools/_distutils/command/sdist.py +531 -0
- venv/Lib/site-packages/setuptools/_distutils/command/upload.py +205 -0
- venv/Lib/site-packages/setuptools/_distutils/config.py +139 -0
- venv/Lib/site-packages/setuptools/_distutils/core.py +291 -0
- venv/Lib/site-packages/setuptools/_distutils/cygwinccompiler.py +364 -0
- venv/Lib/site-packages/setuptools/_distutils/debug.py +5 -0
- venv/Lib/site-packages/setuptools/_distutils/dep_util.py +96 -0
- venv/Lib/site-packages/setuptools/_distutils/dir_util.py +243 -0
- venv/Lib/site-packages/setuptools/_distutils/dist.py +1286 -0
- venv/Lib/site-packages/setuptools/_distutils/errors.py +127 -0
- venv/Lib/site-packages/setuptools/_distutils/extension.py +248 -0
- venv/Lib/site-packages/setuptools/_distutils/fancy_getopt.py +470 -0
- venv/Lib/site-packages/setuptools/_distutils/file_util.py +249 -0
- venv/Lib/site-packages/setuptools/_distutils/filelist.py +371 -0
- venv/Lib/site-packages/setuptools/_distutils/log.py +80 -0
- venv/Lib/site-packages/setuptools/_distutils/msvc9compiler.py +832 -0
- venv/Lib/site-packages/setuptools/_distutils/msvccompiler.py +695 -0
- venv/Lib/site-packages/setuptools/_distutils/py38compat.py +8 -0
- venv/Lib/site-packages/setuptools/_distutils/py39compat.py +22 -0
- venv/Lib/site-packages/setuptools/_distutils/spawn.py +109 -0
- venv/Lib/site-packages/setuptools/_distutils/sysconfig.py +558 -0
- venv/Lib/site-packages/setuptools/_distutils/text_file.py +287 -0
- venv/Lib/site-packages/setuptools/_distutils/unixccompiler.py +401 -0
- venv/Lib/site-packages/setuptools/_distutils/util.py +513 -0
- venv/Lib/site-packages/setuptools/_distutils/version.py +358 -0
- venv/Lib/site-packages/setuptools/_distutils/versionpredicate.py +175 -0
- venv/Lib/site-packages/setuptools/_entry_points.py +86 -0
- venv/Lib/site-packages/setuptools/_imp.py +82 -0
- venv/Lib/site-packages/setuptools/_importlib.py +47 -0
- venv/Lib/site-packages/setuptools/_itertools.py +23 -0
- venv/Lib/site-packages/setuptools/_path.py +29 -0
- venv/Lib/site-packages/setuptools/_reqs.py +19 -0
- venv/Lib/site-packages/setuptools/_vendor/__init__.py +0 -0
- venv/Lib/site-packages/setuptools/_vendor/importlib_metadata/__init__.py +1047 -0
- venv/Lib/site-packages/setuptools/_vendor/importlib_metadata/_adapters.py +68 -0
- venv/Lib/site-packages/setuptools/_vendor/importlib_metadata/_collections.py +30 -0
- venv/Lib/site-packages/setuptools/_vendor/importlib_metadata/_compat.py +71 -0
- venv/Lib/site-packages/setuptools/_vendor/importlib_metadata/_functools.py +104 -0
- venv/Lib/site-packages/setuptools/_vendor/importlib_metadata/_itertools.py +73 -0
- venv/Lib/site-packages/setuptools/_vendor/importlib_metadata/_meta.py +48 -0
- venv/Lib/site-packages/setuptools/_vendor/importlib_metadata/_text.py +99 -0
- venv/Lib/site-packages/setuptools/_vendor/importlib_resources/__init__.py +36 -0
- venv/Lib/site-packages/setuptools/_vendor/importlib_resources/_adapters.py +170 -0
- venv/Lib/site-packages/setuptools/_vendor/importlib_resources/_common.py +104 -0
- venv/Lib/site-packages/setuptools/_vendor/importlib_resources/_compat.py +98 -0
- venv/Lib/site-packages/setuptools/_vendor/importlib_resources/_itertools.py +35 -0
- venv/Lib/site-packages/setuptools/_vendor/importlib_resources/_legacy.py +121 -0
- venv/Lib/site-packages/setuptools/_vendor/importlib_resources/abc.py +137 -0
- venv/Lib/site-packages/setuptools/_vendor/importlib_resources/readers.py +122 -0
- venv/Lib/site-packages/setuptools/_vendor/importlib_resources/simple.py +116 -0
- venv/Lib/site-packages/setuptools/_vendor/jaraco/__init__.py +0 -0
- venv/Lib/site-packages/setuptools/_vendor/jaraco/context.py +213 -0
- venv/Lib/site-packages/setuptools/_vendor/jaraco/functools.py +525 -0
- venv/Lib/site-packages/setuptools/_vendor/jaraco/text/__init__.py +599 -0
- venv/Lib/site-packages/setuptools/_vendor/more_itertools/__init__.py +4 -0
- venv/Lib/site-packages/setuptools/_vendor/more_itertools/more.py +3824 -0
- venv/Lib/site-packages/setuptools/_vendor/more_itertools/recipes.py +620 -0
- venv/Lib/site-packages/setuptools/_vendor/ordered_set.py +488 -0
- venv/Lib/site-packages/setuptools/_vendor/packaging/__about__.py +26 -0
- venv/Lib/site-packages/setuptools/_vendor/packaging/__init__.py +25 -0
- venv/Lib/site-packages/setuptools/_vendor/packaging/_manylinux.py +301 -0
- venv/Lib/site-packages/setuptools/_vendor/packaging/_musllinux.py +136 -0
- venv/Lib/site-packages/setuptools/_vendor/packaging/_structures.py +61 -0
- venv/Lib/site-packages/setuptools/_vendor/packaging/markers.py +304 -0
- venv/Lib/site-packages/setuptools/_vendor/packaging/requirements.py +146 -0
- venv/Lib/site-packages/setuptools/_vendor/packaging/specifiers.py +802 -0
- venv/Lib/site-packages/setuptools/_vendor/packaging/tags.py +487 -0
- venv/Lib/site-packages/setuptools/_vendor/packaging/utils.py +136 -0
- venv/Lib/site-packages/setuptools/_vendor/packaging/version.py +504 -0
- venv/Lib/site-packages/setuptools/_vendor/pyparsing/__init__.py +331 -0
- venv/Lib/site-packages/setuptools/_vendor/pyparsing/actions.py +207 -0
- venv/Lib/site-packages/setuptools/_vendor/pyparsing/common.py +424 -0
- venv/Lib/site-packages/setuptools/_vendor/pyparsing/core.py +5814 -0
- venv/Lib/site-packages/setuptools/_vendor/pyparsing/diagram/__init__.py +642 -0
- venv/Lib/site-packages/setuptools/_vendor/pyparsing/exceptions.py +267 -0
- venv/Lib/site-packages/setuptools/_vendor/pyparsing/helpers.py +1088 -0
- venv/Lib/site-packages/setuptools/_vendor/pyparsing/results.py +760 -0
- venv/Lib/site-packages/setuptools/_vendor/pyparsing/testing.py +331 -0
- venv/Lib/site-packages/setuptools/_vendor/pyparsing/unicode.py +352 -0
- venv/Lib/site-packages/setuptools/_vendor/pyparsing/util.py +235 -0
- venv/Lib/site-packages/setuptools/_vendor/tomli/__init__.py +11 -0
- venv/Lib/site-packages/setuptools/_vendor/tomli/_parser.py +691 -0
- venv/Lib/site-packages/setuptools/_vendor/tomli/_re.py +107 -0
- venv/Lib/site-packages/setuptools/_vendor/tomli/_types.py +10 -0
- venv/Lib/site-packages/setuptools/_vendor/typing_extensions.py +2296 -0
- venv/Lib/site-packages/setuptools/_vendor/zipp.py +329 -0
- venv/Lib/site-packages/setuptools/archive_util.py +213 -0
- venv/Lib/site-packages/setuptools/build_meta.py +511 -0
- venv/Lib/site-packages/setuptools/command/__init__.py +12 -0
- venv/Lib/site-packages/setuptools/command/alias.py +78 -0
- venv/Lib/site-packages/setuptools/command/bdist_egg.py +457 -0
- venv/Lib/site-packages/setuptools/command/bdist_rpm.py +40 -0
- venv/Lib/site-packages/setuptools/command/build.py +146 -0
- venv/Lib/site-packages/setuptools/command/build_clib.py +101 -0
- venv/Lib/site-packages/setuptools/command/build_ext.py +383 -0
- venv/Lib/site-packages/setuptools/command/build_py.py +368 -0
- venv/Lib/site-packages/setuptools/command/develop.py +193 -0
- venv/Lib/site-packages/setuptools/command/dist_info.py +142 -0
- venv/Lib/site-packages/setuptools/command/easy_install.py +2312 -0
- venv/Lib/site-packages/setuptools/command/editable_wheel.py +844 -0
- venv/Lib/site-packages/setuptools/command/egg_info.py +763 -0
- venv/Lib/site-packages/setuptools/command/install.py +139 -0
- venv/Lib/site-packages/setuptools/command/install_egg_info.py +63 -0
- venv/Lib/site-packages/setuptools/command/install_lib.py +122 -0
- venv/Lib/site-packages/setuptools/command/install_scripts.py +70 -0
- venv/Lib/site-packages/setuptools/command/py36compat.py +134 -0
- venv/Lib/site-packages/setuptools/command/register.py +18 -0
- venv/Lib/site-packages/setuptools/command/rotate.py +64 -0
- venv/Lib/site-packages/setuptools/command/saveopts.py +22 -0
- venv/Lib/site-packages/setuptools/command/sdist.py +210 -0
- venv/Lib/site-packages/setuptools/command/setopt.py +149 -0
- venv/Lib/site-packages/setuptools/command/test.py +251 -0
- venv/Lib/site-packages/setuptools/command/upload.py +17 -0
- venv/Lib/site-packages/setuptools/command/upload_docs.py +213 -0
- venv/Lib/site-packages/setuptools/config/__init__.py +35 -0
- venv/Lib/site-packages/setuptools/config/_apply_pyprojecttoml.py +377 -0
- venv/Lib/site-packages/setuptools/config/_validate_pyproject/__init__.py +34 -0
- venv/Lib/site-packages/setuptools/config/_validate_pyproject/error_reporting.py +318 -0
- venv/Lib/site-packages/setuptools/config/_validate_pyproject/extra_validations.py +36 -0
- venv/Lib/site-packages/setuptools/config/_validate_pyproject/fastjsonschema_exceptions.py +51 -0
- venv/Lib/site-packages/setuptools/config/_validate_pyproject/fastjsonschema_validations.py +1035 -0
- venv/Lib/site-packages/setuptools/config/_validate_pyproject/formats.py +259 -0
- venv/Lib/site-packages/setuptools/config/expand.py +462 -0
- venv/Lib/site-packages/setuptools/config/pyprojecttoml.py +493 -0
- venv/Lib/site-packages/setuptools/config/setupcfg.py +762 -0
- venv/Lib/site-packages/setuptools/dep_util.py +25 -0
- venv/Lib/site-packages/setuptools/depends.py +176 -0
- venv/Lib/site-packages/setuptools/discovery.py +600 -0
- venv/Lib/site-packages/setuptools/dist.py +1222 -0
- venv/Lib/site-packages/setuptools/errors.py +58 -0
- venv/Lib/site-packages/setuptools/extension.py +148 -0
- venv/Lib/site-packages/setuptools/extern/__init__.py +76 -0
- venv/Lib/site-packages/setuptools/glob.py +167 -0
- venv/Lib/site-packages/setuptools/installer.py +104 -0
- venv/Lib/site-packages/setuptools/launch.py +36 -0
- venv/Lib/site-packages/setuptools/logging.py +36 -0
- venv/Lib/site-packages/setuptools/monkey.py +165 -0
- venv/Lib/site-packages/setuptools/msvc.py +1703 -0
- venv/Lib/site-packages/setuptools/namespaces.py +107 -0
- venv/Lib/site-packages/setuptools/package_index.py +1126 -0
- venv/Lib/site-packages/setuptools/py34compat.py +13 -0
- venv/Lib/site-packages/setuptools/sandbox.py +530 -0
- venv/Lib/site-packages/setuptools/unicode_utils.py +42 -0
- venv/Lib/site-packages/setuptools/version.py +6 -0
- venv/Lib/site-packages/setuptools/wheel.py +222 -0
- venv/Lib/site-packages/setuptools/windows_support.py +29 -0
- xplia/__init__.py +72 -0
- xplia/api/__init__.py +432 -0
- xplia/api/fastapi_app.py +453 -0
- xplia/cli.py +321 -0
- xplia/compliance/__init__.py +39 -0
- xplia/compliance/ai_act.py +538 -0
- xplia/compliance/compliance_checker.py +511 -0
- xplia/compliance/compliance_report.py +236 -0
- xplia/compliance/expert_review/__init__.py +18 -0
- xplia/compliance/expert_review/evaluation_criteria.py +209 -0
- xplia/compliance/expert_review/integration.py +270 -0
- xplia/compliance/expert_review/trust_expert_evaluator.py +379 -0
- xplia/compliance/explanation_rights.py +45 -0
- xplia/compliance/formatters/__init__.py +35 -0
- xplia/compliance/formatters/csv_formatter.py +179 -0
- xplia/compliance/formatters/html_formatter.py +689 -0
- xplia/compliance/formatters/html_trust_formatter.py +147 -0
- xplia/compliance/formatters/json_formatter.py +107 -0
- xplia/compliance/formatters/pdf_formatter.py +641 -0
- xplia/compliance/formatters/pdf_trust_formatter.py +309 -0
- xplia/compliance/formatters/trust_formatter_mixin.py +267 -0
- xplia/compliance/formatters/xml_formatter.py +173 -0
- xplia/compliance/gdpr.py +803 -0
- xplia/compliance/hipaa.py +134 -0
- xplia/compliance/report_base.py +205 -0
- xplia/compliance/report_generator.py +820 -0
- xplia/compliance/translations.py +299 -0
- xplia/core/__init__.py +98 -0
- xplia/core/base.py +391 -0
- xplia/core/config.py +297 -0
- xplia/core/factory.py +416 -0
- xplia/core/model_adapters/__init__.py +47 -0
- xplia/core/model_adapters/base.py +160 -0
- xplia/core/model_adapters/pytorch_adapter.py +339 -0
- xplia/core/model_adapters/sklearn_adapter.py +215 -0
- xplia/core/model_adapters/tensorflow_adapter.py +280 -0
- xplia/core/model_adapters/xgboost_adapter.py +295 -0
- xplia/core/optimizations.py +322 -0
- xplia/core/performance/__init__.py +57 -0
- xplia/core/performance/cache_manager.py +502 -0
- xplia/core/performance/memory_optimizer.py +465 -0
- xplia/core/performance/parallel_executor.py +327 -0
- xplia/core/registry.py +1234 -0
- xplia/explainers/__init__.py +70 -0
- xplia/explainers/__init__updated.py +62 -0
- xplia/explainers/adaptive/__init__.py +24 -0
- xplia/explainers/adaptive/explainer_selector.py +405 -0
- xplia/explainers/adaptive/explanation_quality.py +395 -0
- xplia/explainers/adaptive/fusion_strategies.py +297 -0
- xplia/explainers/adaptive/meta_explainer.py +320 -0
- xplia/explainers/adversarial/__init__.py +21 -0
- xplia/explainers/adversarial/adversarial_xai.py +678 -0
- xplia/explainers/anchor_explainer.py +1769 -0
- xplia/explainers/attention_explainer.py +996 -0
- xplia/explainers/bayesian/__init__.py +8 -0
- xplia/explainers/bayesian/bayesian_explainer.py +127 -0
- xplia/explainers/bias/__init__.py +17 -0
- xplia/explainers/bias/advanced_bias_detection.py +934 -0
- xplia/explainers/calibration/__init__.py +26 -0
- xplia/explainers/calibration/audience_adapter.py +376 -0
- xplia/explainers/calibration/audience_profiles.py +372 -0
- xplia/explainers/calibration/calibration_metrics.py +299 -0
- xplia/explainers/calibration/explanation_calibrator.py +460 -0
- xplia/explainers/causal/__init__.py +19 -0
- xplia/explainers/causal/causal_inference.py +669 -0
- xplia/explainers/certified/__init__.py +21 -0
- xplia/explainers/certified/certified_explanations.py +619 -0
- xplia/explainers/continual/__init__.py +8 -0
- xplia/explainers/continual/continual_explainer.py +102 -0
- xplia/explainers/counterfactual_explainer.py +804 -0
- xplia/explainers/counterfactuals/__init__.py +17 -0
- xplia/explainers/counterfactuals/advanced_counterfactuals.py +259 -0
- xplia/explainers/expert_evaluator.py +538 -0
- xplia/explainers/feature_importance_explainer.py +376 -0
- xplia/explainers/federated/__init__.py +17 -0
- xplia/explainers/federated/federated_xai.py +664 -0
- xplia/explainers/generative/__init__.py +15 -0
- xplia/explainers/generative/generative_explainer.py +243 -0
- xplia/explainers/gradient_explainer.py +3590 -0
- xplia/explainers/graph/__init__.py +26 -0
- xplia/explainers/graph/gnn_explainer.py +638 -0
- xplia/explainers/graph/molecular_explainer.py +438 -0
- xplia/explainers/lime_explainer.py +1580 -0
- xplia/explainers/llm/__init__.py +23 -0
- xplia/explainers/llm/llm_explainability.py +737 -0
- xplia/explainers/metalearning/__init__.py +15 -0
- xplia/explainers/metalearning/metalearning_explainer.py +276 -0
- xplia/explainers/moe/__init__.py +8 -0
- xplia/explainers/moe/moe_explainer.py +108 -0
- xplia/explainers/multimodal/__init__.py +30 -0
- xplia/explainers/multimodal/base.py +262 -0
- xplia/explainers/multimodal/diffusion_explainer.py +608 -0
- xplia/explainers/multimodal/foundation_model_explainer.py +323 -0
- xplia/explainers/multimodal/registry.py +139 -0
- xplia/explainers/multimodal/text_image_explainer.py +381 -0
- xplia/explainers/multimodal/vision_language_explainer.py +608 -0
- xplia/explainers/nas/__init__.py +5 -0
- xplia/explainers/nas/nas_explainer.py +65 -0
- xplia/explainers/neuralodes/__init__.py +5 -0
- xplia/explainers/neuralodes/neuralode_explainer.py +64 -0
- xplia/explainers/neurosymbolic/__init__.py +8 -0
- xplia/explainers/neurosymbolic/neurosymbolic_explainer.py +97 -0
- xplia/explainers/partial_dependence_explainer.py +509 -0
- xplia/explainers/privacy/__init__.py +21 -0
- xplia/explainers/privacy/differential_privacy_xai.py +624 -0
- xplia/explainers/quantum/__init__.py +5 -0
- xplia/explainers/quantum/quantum_explainer.py +79 -0
- xplia/explainers/recommender/__init__.py +8 -0
- xplia/explainers/recommender/recsys_explainer.py +124 -0
- xplia/explainers/reinforcement/__init__.py +15 -0
- xplia/explainers/reinforcement/rl_explainer.py +173 -0
- xplia/explainers/shap_explainer.py +2238 -0
- xplia/explainers/streaming/__init__.py +19 -0
- xplia/explainers/streaming/streaming_xai.py +703 -0
- xplia/explainers/timeseries/__init__.py +15 -0
- xplia/explainers/timeseries/timeseries_explainer.py +252 -0
- xplia/explainers/trust/__init__.py +24 -0
- xplia/explainers/trust/confidence_report.py +368 -0
- xplia/explainers/trust/fairwashing.py +489 -0
- xplia/explainers/trust/uncertainty.py +453 -0
- xplia/explainers/unified_explainer.py +566 -0
- xplia/explainers/unified_explainer_utils.py +309 -0
- xplia/integrations/__init__.py +3 -0
- xplia/integrations/mlflow_integration.py +331 -0
- xplia/integrations/wandb_integration.py +375 -0
- xplia/plugins/__init__.py +36 -0
- xplia/plugins/example_visualizer.py +11 -0
- xplia/utils/__init__.py +18 -0
- xplia/utils/performance.py +119 -0
- xplia/utils/validation.py +109 -0
- xplia/visualizations/__init__.py +31 -0
- xplia/visualizations/base.py +256 -0
- xplia/visualizations/boxplot_chart.py +224 -0
- xplia/visualizations/charts_impl.py +65 -0
- xplia/visualizations/gauge_chart.py +211 -0
- xplia/visualizations/gradient_viz.py +117 -0
- xplia/visualizations/heatmap_chart.py +173 -0
- xplia/visualizations/histogram_chart.py +176 -0
- xplia/visualizations/line_chart.py +100 -0
- xplia/visualizations/pie_chart.py +134 -0
- xplia/visualizations/radar_chart.py +154 -0
- xplia/visualizations/registry.py +76 -0
- xplia/visualizations/sankey_chart.py +190 -0
- xplia/visualizations/scatter_chart.py +252 -0
- xplia/visualizations/table_chart.py +263 -0
- xplia/visualizations/treemap_chart.py +216 -0
- xplia/visualizations.py +535 -0
- xplia/visualizers/__init__.py +87 -0
- xplia/visualizers/base_visualizer.py +294 -0
- xplia-1.0.1.dist-info/METADATA +685 -0
- xplia-1.0.1.dist-info/RECORD +870 -0
- xplia-1.0.1.dist-info/WHEEL +5 -0
- xplia-1.0.1.dist-info/entry_points.txt +2 -0
- xplia-1.0.1.dist-info/licenses/LICENSE +21 -0
- xplia-1.0.1.dist-info/top_level.txt +2 -0
|
@@ -0,0 +1,996 @@
|
|
|
1
|
+
"""
|
|
2
|
+
AttentionExplainer pour XPLIA
|
|
3
|
+
=============================
|
|
4
|
+
|
|
5
|
+
Ce module implémente l'AttentionExplainer qui permet de visualiser et d'interpréter
|
|
6
|
+
les mécanismes d'attention dans les modèles de deep learning comme les Transformers,
|
|
7
|
+
les LSTM et autres architectures avec des mécanismes d'attention.
|
|
8
|
+
"""
|
|
9
|
+
|
|
10
|
+
import logging
|
|
11
|
+
import numpy as np
|
|
12
|
+
import pandas as pd
|
|
13
|
+
from datetime import datetime
|
|
14
|
+
from typing import List, Dict, Union, Optional, Tuple, Any, Callable
|
|
15
|
+
|
|
16
|
+
from ..core.base import ExplainerBase
|
|
17
|
+
from ..core.registry import register_explainer
|
|
18
|
+
from ..core.models import ExplanationResult, FeatureImportance
|
|
19
|
+
from ..core.enums import ExplainabilityMethod, AudienceLevel
|
|
20
|
+
from ..core.metadata import ModelMetadata
|
|
21
|
+
|
|
22
|
+
@register_explainer
|
|
23
|
+
class AttentionExplainer(ExplainerBase):
|
|
24
|
+
"""
|
|
25
|
+
Explainer qui extrait et interprète les mécanismes d'attention dans les modèles de deep learning.
|
|
26
|
+
|
|
27
|
+
Cet explainer est conçu pour fonctionner avec des modèles qui utilisent des mécanismes d'attention,
|
|
28
|
+
comme les Transformers (BERT, GPT, etc.), les modèles LSTM avec attention, et d'autres architectures
|
|
29
|
+
similaires. Il peut extraire les poids d'attention et les convertir en scores d'importance pour
|
|
30
|
+
les tokens ou les caractéristiques d'entrée.
|
|
31
|
+
|
|
32
|
+
Attributs:
|
|
33
|
+
_model: Modèle à expliquer
|
|
34
|
+
_framework: Framework du modèle ('tensorflow', 'pytorch', 'huggingface')
|
|
35
|
+
_attention_layer_names: Noms des couches d'attention à extraire
|
|
36
|
+
_tokenizer: Tokenizer pour les modèles de NLP (optionnel)
|
|
37
|
+
_aggregation_method: Méthode d'agrégation des poids d'attention ('mean', 'max', 'sum', 'last')
|
|
38
|
+
_head_importance: Importance relative des différentes têtes d'attention (optionnel)
|
|
39
|
+
_layer_importance: Importance relative des différentes couches (optionnel)
|
|
40
|
+
_feature_names: Noms des caractéristiques ou tokens
|
|
41
|
+
_metadata: Métadonnées du modèle
|
|
42
|
+
"""
|
|
43
|
+
|
|
44
|
+
def __init__(self, model, tokenizer=None, framework=None, attention_layer_names=None,
|
|
45
|
+
aggregation_method='mean', head_importance=None, layer_importance=None,
|
|
46
|
+
feature_names=None):
|
|
47
|
+
"""
|
|
48
|
+
Initialise l'AttentionExplainer.
|
|
49
|
+
|
|
50
|
+
Args:
|
|
51
|
+
model: Modèle à expliquer avec mécanismes d'attention
|
|
52
|
+
tokenizer: Tokenizer pour les modèles de NLP (optionnel)
|
|
53
|
+
framework: Framework du modèle ('tensorflow', 'pytorch', 'huggingface')
|
|
54
|
+
attention_layer_names: Noms des couches d'attention à extraire (si None, tente de les détecter)
|
|
55
|
+
aggregation_method: Méthode d'agrégation des poids d'attention ('mean', 'max', 'sum', 'last')
|
|
56
|
+
head_importance: Importance relative des différentes têtes d'attention (optionnel)
|
|
57
|
+
layer_importance: Importance relative des différentes couches (optionnel)
|
|
58
|
+
feature_names: Noms des caractéristiques ou tokens (optionnel)
|
|
59
|
+
"""
|
|
60
|
+
super().__init__()
|
|
61
|
+
|
|
62
|
+
# Modèle et framework
|
|
63
|
+
self._model = model
|
|
64
|
+
self._framework = framework or self._detect_framework()
|
|
65
|
+
|
|
66
|
+
# Tokenizer pour les modèles NLP
|
|
67
|
+
self._tokenizer = tokenizer
|
|
68
|
+
|
|
69
|
+
# Couches d'attention
|
|
70
|
+
self._attention_layer_names = attention_layer_names
|
|
71
|
+
|
|
72
|
+
# Méthode d'agrégation
|
|
73
|
+
self._aggregation_method = aggregation_method
|
|
74
|
+
|
|
75
|
+
# Importance des têtes et des couches
|
|
76
|
+
self._head_importance = head_importance
|
|
77
|
+
self._layer_importance = layer_importance
|
|
78
|
+
|
|
79
|
+
# Noms des caractéristiques
|
|
80
|
+
self._feature_names = feature_names
|
|
81
|
+
|
|
82
|
+
# Métadonnées du modèle
|
|
83
|
+
self._metadata = None
|
|
84
|
+
|
|
85
|
+
# Logger
|
|
86
|
+
self._logger = logging.getLogger(__name__)
|
|
87
|
+
|
|
88
|
+
def explain_instance(self, instance, **kwargs) -> ExplanationResult:
|
|
89
|
+
"""
|
|
90
|
+
Génère une explication basée sur les mécanismes d'attention pour une instance spécifique.
|
|
91
|
+
|
|
92
|
+
Args:
|
|
93
|
+
instance: Instance à expliquer (texte, séquence de tokens, ou tenseur d'entrée)
|
|
94
|
+
**kwargs: Paramètres additionnels
|
|
95
|
+
input_type: Type d'entrée ('text', 'tokens', 'tensor')
|
|
96
|
+
attention_threshold: Seuil pour filtrer les poids d'attention faibles (défaut: 0.05)
|
|
97
|
+
max_length: Longueur maximale pour les séquences (défaut: 512)
|
|
98
|
+
batch_size: Taille du batch pour l'inférence (défaut: 1)
|
|
99
|
+
include_special_tokens: Inclure les tokens spéciaux dans l'explication (défaut: False)
|
|
100
|
+
audience_level: Niveau d'audience (TECHNICAL, BUSINESS, PUBLIC)
|
|
101
|
+
|
|
102
|
+
Returns:
|
|
103
|
+
ExplanationResult: Résultat standardisé de l'explication
|
|
104
|
+
"""
|
|
105
|
+
# Paramètres
|
|
106
|
+
audience_level = kwargs.get('audience_level', AudienceLevel.TECHNICAL)
|
|
107
|
+
input_type = kwargs.get('input_type', 'text' if isinstance(instance, str) else 'tensor')
|
|
108
|
+
attention_threshold = kwargs.get('attention_threshold', 0.05)
|
|
109
|
+
max_length = kwargs.get('max_length', 512)
|
|
110
|
+
batch_size = kwargs.get('batch_size', 1)
|
|
111
|
+
include_special_tokens = kwargs.get('include_special_tokens', False)
|
|
112
|
+
|
|
113
|
+
# Tracer l'action
|
|
114
|
+
self.add_audit_record("explain_instance", {
|
|
115
|
+
"input_type": input_type,
|
|
116
|
+
"audience_level": audience_level.value if isinstance(audience_level, AudienceLevel) else audience_level,
|
|
117
|
+
"attention_threshold": attention_threshold,
|
|
118
|
+
"max_length": max_length
|
|
119
|
+
})
|
|
120
|
+
|
|
121
|
+
try:
|
|
122
|
+
# Préparer l'entrée selon le type
|
|
123
|
+
prepared_input, tokens = self._prepare_input(instance, input_type, max_length)
|
|
124
|
+
|
|
125
|
+
# Extraire les poids d'attention
|
|
126
|
+
attention_weights = self._extract_attention_weights(prepared_input, batch_size)
|
|
127
|
+
|
|
128
|
+
# Agréger les poids d'attention
|
|
129
|
+
aggregated_attention = self._aggregate_attention_weights(
|
|
130
|
+
attention_weights,
|
|
131
|
+
method=self._aggregation_method,
|
|
132
|
+
head_importance=self._head_importance,
|
|
133
|
+
layer_importance=self._layer_importance
|
|
134
|
+
)
|
|
135
|
+
|
|
136
|
+
# Convertir les poids d'attention en importances de caractéristiques
|
|
137
|
+
feature_importances = self._convert_attention_to_importances(
|
|
138
|
+
aggregated_attention,
|
|
139
|
+
tokens,
|
|
140
|
+
threshold=attention_threshold,
|
|
141
|
+
include_special_tokens=include_special_tokens
|
|
142
|
+
)
|
|
143
|
+
|
|
144
|
+
# Extraire les métadonnées du modèle
|
|
145
|
+
if not self._metadata:
|
|
146
|
+
self._extract_metadata()
|
|
147
|
+
|
|
148
|
+
# Créer le résultat d'explication
|
|
149
|
+
result = ExplanationResult(
|
|
150
|
+
method=ExplainabilityMethod.ATTENTION,
|
|
151
|
+
model_metadata=self._metadata,
|
|
152
|
+
feature_importances=feature_importances,
|
|
153
|
+
raw_explanation={
|
|
154
|
+
"attention_weights": self._convert_attention_to_serializable(attention_weights),
|
|
155
|
+
"aggregated_attention": aggregated_attention.tolist() if isinstance(aggregated_attention, np.ndarray) else aggregated_attention,
|
|
156
|
+
"tokens": tokens,
|
|
157
|
+
"input_type": input_type
|
|
158
|
+
},
|
|
159
|
+
audience_level=audience_level
|
|
160
|
+
)
|
|
161
|
+
|
|
162
|
+
return result
|
|
163
|
+
|
|
164
|
+
except Exception as e:
|
|
165
|
+
self._logger.error(f"Erreur lors de l'extraction des mécanismes d'attention: {str(e)}")
|
|
166
|
+
raise RuntimeError(f"Échec de l'explication par attention: {str(e)}")
|
|
167
|
+
|
|
168
|
+
def explain(self, X, y=None, **kwargs) -> ExplanationResult:
|
|
169
|
+
"""
|
|
170
|
+
Génère des explications basées sur les mécanismes d'attention pour un ensemble de données.
|
|
171
|
+
Pour les explications par attention, cette méthode sélectionne un échantillon
|
|
172
|
+
représentatif et génère des explications pour chaque instance.
|
|
173
|
+
|
|
174
|
+
Args:
|
|
175
|
+
X: Données d'entrée à expliquer (textes, séquences de tokens, ou tenseurs)
|
|
176
|
+
y: Valeurs cibles réelles (optionnel)
|
|
177
|
+
**kwargs: Paramètres additionnels
|
|
178
|
+
max_instances: Nombre maximum d'instances à expliquer
|
|
179
|
+
sampling_strategy: Stratégie d'échantillonnage ('random', 'stratified', 'diverse')
|
|
180
|
+
input_type: Type d'entrée ('text', 'tokens', 'tensor')
|
|
181
|
+
|
|
182
|
+
Returns:
|
|
183
|
+
ExplanationResult: Résultat standardisé de l'explication
|
|
184
|
+
"""
|
|
185
|
+
# Paramètres
|
|
186
|
+
audience_level = kwargs.get('audience_level', AudienceLevel.TECHNICAL)
|
|
187
|
+
max_instances = kwargs.get('max_instances', 5)
|
|
188
|
+
sampling_strategy = kwargs.get('sampling_strategy', 'random')
|
|
189
|
+
input_type = kwargs.get('input_type', 'text' if isinstance(X[0], str) else 'tensor')
|
|
190
|
+
|
|
191
|
+
# Tracer l'action
|
|
192
|
+
self.add_audit_record("explain", {
|
|
193
|
+
"n_samples": len(X),
|
|
194
|
+
"audience_level": audience_level.value if isinstance(audience_level, AudienceLevel) else audience_level,
|
|
195
|
+
"max_instances": max_instances,
|
|
196
|
+
"sampling_strategy": sampling_strategy,
|
|
197
|
+
"input_type": input_type
|
|
198
|
+
})
|
|
199
|
+
|
|
200
|
+
try:
|
|
201
|
+
# Échantillonner des instances représentatives
|
|
202
|
+
sampled_indices = self._sample_instances(X, y, max_instances, sampling_strategy)
|
|
203
|
+
sampled_instances = [X[i] for i in sampled_indices]
|
|
204
|
+
|
|
205
|
+
# Générer des explications pour chaque instance échantillonnée
|
|
206
|
+
all_feature_importances = []
|
|
207
|
+
all_attention_weights = []
|
|
208
|
+
all_tokens = []
|
|
209
|
+
|
|
210
|
+
for instance in sampled_instances:
|
|
211
|
+
# Utiliser explain_instance pour chaque instance
|
|
212
|
+
instance_result = self.explain_instance(
|
|
213
|
+
instance,
|
|
214
|
+
input_type=input_type,
|
|
215
|
+
audience_level=audience_level,
|
|
216
|
+
**kwargs
|
|
217
|
+
)
|
|
218
|
+
|
|
219
|
+
# Collecter les résultats
|
|
220
|
+
all_feature_importances.append(instance_result.feature_importances)
|
|
221
|
+
all_attention_weights.append(instance_result.raw_explanation["attention_weights"])
|
|
222
|
+
all_tokens.append(instance_result.raw_explanation["tokens"])
|
|
223
|
+
|
|
224
|
+
# Agréger les importances de caractéristiques
|
|
225
|
+
if input_type == 'text':
|
|
226
|
+
# Pour le texte, on ne peut pas agréger directement car les tokens sont différents
|
|
227
|
+
aggregated_importances = self._aggregate_text_importances(all_feature_importances)
|
|
228
|
+
else:
|
|
229
|
+
# Pour les tenseurs ou tokens pré-définis, on peut agréger directement
|
|
230
|
+
feature_names = self._feature_names or [f"feature_{i}" for i in range(len(all_feature_importances[0]))]
|
|
231
|
+
aggregated_importances = self._aggregate_feature_importances(all_feature_importances, feature_names)
|
|
232
|
+
|
|
233
|
+
# Extraire les métadonnées du modèle
|
|
234
|
+
if not self._metadata:
|
|
235
|
+
self._extract_metadata()
|
|
236
|
+
|
|
237
|
+
# Créer le résultat d'explication
|
|
238
|
+
result = ExplanationResult(
|
|
239
|
+
method=ExplainabilityMethod.ATTENTION,
|
|
240
|
+
model_metadata=self._metadata,
|
|
241
|
+
feature_importances=aggregated_importances,
|
|
242
|
+
raw_explanation={
|
|
243
|
+
"sampled_instances": sampled_indices,
|
|
244
|
+
"all_attention_weights": all_attention_weights,
|
|
245
|
+
"all_tokens": all_tokens,
|
|
246
|
+
"input_type": input_type
|
|
247
|
+
},
|
|
248
|
+
audience_level=audience_level
|
|
249
|
+
)
|
|
250
|
+
|
|
251
|
+
return result
|
|
252
|
+
|
|
253
|
+
except Exception as e:
|
|
254
|
+
self._logger.error(f"Erreur lors de l'extraction des mécanismes d'attention: {str(e)}")
|
|
255
|
+
raise RuntimeError(f"Échec de l'explication par attention: {str(e)}")
|
|
256
|
+
|
|
257
|
+
def _detect_framework(self):
|
|
258
|
+
"""
|
|
259
|
+
Détecte automatiquement le framework du modèle.
|
|
260
|
+
|
|
261
|
+
Returns:
|
|
262
|
+
str: Framework détecté ('tensorflow', 'pytorch', 'huggingface')
|
|
263
|
+
"""
|
|
264
|
+
model_module = self._model.__module__.split('.')[0].lower()
|
|
265
|
+
|
|
266
|
+
if model_module in ['tensorflow', 'tf', 'keras']:
|
|
267
|
+
return 'tensorflow'
|
|
268
|
+
elif model_module in ['torch', 'pytorch']:
|
|
269
|
+
return 'pytorch'
|
|
270
|
+
elif model_module in ['transformers']:
|
|
271
|
+
return 'huggingface'
|
|
272
|
+
else:
|
|
273
|
+
# Essayer de détecter par les attributs
|
|
274
|
+
if hasattr(self._model, 'layers'):
|
|
275
|
+
return 'tensorflow'
|
|
276
|
+
elif hasattr(self._model, 'modules'):
|
|
277
|
+
return 'pytorch'
|
|
278
|
+
else:
|
|
279
|
+
self._logger.warning("Impossible de détecter automatiquement le framework. "
|
|
280
|
+
"Utilisation du framework par défaut: 'tensorflow'.")
|
|
281
|
+
return 'tensorflow'
|
|
282
|
+
|
|
283
|
+
def _prepare_input(self, instance, input_type, max_length):
|
|
284
|
+
"""
|
|
285
|
+
Prépare l'entrée pour l'extraction des poids d'attention.
|
|
286
|
+
|
|
287
|
+
Args:
|
|
288
|
+
instance: Instance à expliquer
|
|
289
|
+
input_type: Type d'entrée ('text', 'tokens', 'tensor')
|
|
290
|
+
max_length: Longueur maximale pour les séquences
|
|
291
|
+
|
|
292
|
+
Returns:
|
|
293
|
+
tuple: (entrée préparée, liste de tokens)
|
|
294
|
+
"""
|
|
295
|
+
if input_type == 'text':
|
|
296
|
+
# Vérifier si un tokenizer est disponible
|
|
297
|
+
if self._tokenizer is None:
|
|
298
|
+
raise ValueError("Un tokenizer est requis pour traiter les entrées textuelles.")
|
|
299
|
+
|
|
300
|
+
# Tokenizer le texte selon le framework
|
|
301
|
+
if self._framework == 'huggingface':
|
|
302
|
+
# Pour les modèles Hugging Face
|
|
303
|
+
encoding = self._tokenizer(instance, return_tensors="pt" if self._framework == 'pytorch' else "tf",
|
|
304
|
+
max_length=max_length, truncation=True, padding='max_length')
|
|
305
|
+
tokens = self._tokenizer.convert_ids_to_tokens(encoding['input_ids'][0])
|
|
306
|
+
return encoding, tokens
|
|
307
|
+
|
|
308
|
+
elif self._framework == 'tensorflow':
|
|
309
|
+
# Pour les modèles TensorFlow/Keras
|
|
310
|
+
import tensorflow as tf
|
|
311
|
+
tokens = self._tokenizer.texts_to_sequences([instance])[0]
|
|
312
|
+
if max_length:
|
|
313
|
+
from tensorflow.keras.preprocessing.sequence import pad_sequences
|
|
314
|
+
tokens = pad_sequences([tokens], maxlen=max_length, padding='post')[0]
|
|
315
|
+
token_strings = [self._tokenizer.index_word.get(t, '[UNK]') for t in tokens]
|
|
316
|
+
return tf.constant([tokens]), token_strings
|
|
317
|
+
|
|
318
|
+
elif self._framework == 'pytorch':
|
|
319
|
+
# Pour les modèles PyTorch
|
|
320
|
+
import torch
|
|
321
|
+
if hasattr(self._tokenizer, 'encode'):
|
|
322
|
+
tokens = self._tokenizer.encode(instance, max_length=max_length, truncation=True)
|
|
323
|
+
token_strings = [self._tokenizer.decode([t]) for t in tokens]
|
|
324
|
+
return torch.tensor([tokens]), token_strings
|
|
325
|
+
else:
|
|
326
|
+
# Tokenizer personnalisé
|
|
327
|
+
tokens = self._tokenizer(instance)
|
|
328
|
+
return torch.tensor([tokens]), tokens
|
|
329
|
+
|
|
330
|
+
elif input_type == 'tokens':
|
|
331
|
+
# Déjà tokenisé
|
|
332
|
+
if self._framework == 'tensorflow':
|
|
333
|
+
import tensorflow as tf
|
|
334
|
+
return tf.constant([instance]), instance
|
|
335
|
+
elif self._framework == 'pytorch':
|
|
336
|
+
import torch
|
|
337
|
+
return torch.tensor([instance]), instance
|
|
338
|
+
else:
|
|
339
|
+
return instance, instance
|
|
340
|
+
|
|
341
|
+
elif input_type == 'tensor':
|
|
342
|
+
# Déjà sous forme de tenseur
|
|
343
|
+
# Générer des noms de tokens génériques
|
|
344
|
+
if hasattr(instance, 'shape'):
|
|
345
|
+
seq_length = instance.shape[-1]
|
|
346
|
+
else:
|
|
347
|
+
seq_length = len(instance)
|
|
348
|
+
tokens = [f"token_{i}" for i in range(seq_length)]
|
|
349
|
+
return instance, tokens
|
|
350
|
+
|
|
351
|
+
else:
|
|
352
|
+
raise ValueError(f"Type d'entrée non supporté: {input_type}")
|
|
353
|
+
|
|
354
|
+
def _extract_attention_weights(self, prepared_input, batch_size=1):
|
|
355
|
+
"""
|
|
356
|
+
Extrait les poids d'attention du modèle.
|
|
357
|
+
|
|
358
|
+
Args:
|
|
359
|
+
prepared_input: Entrée préparée pour le modèle
|
|
360
|
+
batch_size: Taille du batch pour l'inférence
|
|
361
|
+
|
|
362
|
+
Returns:
|
|
363
|
+
dict: Poids d'attention extraits
|
|
364
|
+
"""
|
|
365
|
+
# Selon le framework, extraire les poids d'attention de manière différente
|
|
366
|
+
if self._framework == 'huggingface':
|
|
367
|
+
return self._extract_huggingface_attention(prepared_input)
|
|
368
|
+
elif self._framework == 'tensorflow':
|
|
369
|
+
return self._extract_tensorflow_attention(prepared_input, batch_size)
|
|
370
|
+
elif self._framework == 'pytorch':
|
|
371
|
+
return self._extract_pytorch_attention(prepared_input, batch_size)
|
|
372
|
+
else:
|
|
373
|
+
raise ValueError(f"Framework non supporté pour l'extraction d'attention: {self._framework}")
|
|
374
|
+
|
|
375
|
+
def _extract_huggingface_attention(self, prepared_input):
|
|
376
|
+
"""
|
|
377
|
+
Extrait les poids d'attention d'un modèle Hugging Face.
|
|
378
|
+
|
|
379
|
+
Args:
|
|
380
|
+
prepared_input: Entrée préparée pour le modèle
|
|
381
|
+
|
|
382
|
+
Returns:
|
|
383
|
+
dict: Poids d'attention extraits
|
|
384
|
+
"""
|
|
385
|
+
# Utiliser l'option output_attentions=True pour les modèles Hugging Face
|
|
386
|
+
outputs = self._model(**prepared_input, output_attentions=True)
|
|
387
|
+
|
|
388
|
+
# Les poids d'attention sont généralement dans le champ 'attentions'
|
|
389
|
+
attention_weights = outputs.attentions
|
|
390
|
+
|
|
391
|
+
# Convertir en format standard
|
|
392
|
+
result = {
|
|
393
|
+
'num_layers': len(attention_weights),
|
|
394
|
+
'num_heads': attention_weights[0].shape[1],
|
|
395
|
+
'attention_weights': []
|
|
396
|
+
}
|
|
397
|
+
|
|
398
|
+
# Traiter chaque couche
|
|
399
|
+
for layer_idx, layer_attention in enumerate(attention_weights):
|
|
400
|
+
# Convertir en numpy pour la sérialisation
|
|
401
|
+
if hasattr(layer_attention, 'detach'):
|
|
402
|
+
layer_attention = layer_attention.detach().cpu().numpy()
|
|
403
|
+
elif hasattr(layer_attention, 'numpy'):
|
|
404
|
+
layer_attention = layer_attention.numpy()
|
|
405
|
+
|
|
406
|
+
# Ajouter à la liste des poids
|
|
407
|
+
result['attention_weights'].append({
|
|
408
|
+
'layer': layer_idx,
|
|
409
|
+
'weights': layer_attention[0] # Premier élément du batch
|
|
410
|
+
})
|
|
411
|
+
|
|
412
|
+
return result
|
|
413
|
+
|
|
414
|
+
def _extract_tensorflow_attention(self, prepared_input, batch_size):
|
|
415
|
+
"""
|
|
416
|
+
Extrait les poids d'attention d'un modèle TensorFlow/Keras.
|
|
417
|
+
|
|
418
|
+
Args:
|
|
419
|
+
prepared_input: Entrée préparée pour le modèle
|
|
420
|
+
batch_size: Taille du batch pour l'inférence
|
|
421
|
+
|
|
422
|
+
Returns:
|
|
423
|
+
dict: Poids d'attention extraits
|
|
424
|
+
"""
|
|
425
|
+
import tensorflow as tf
|
|
426
|
+
|
|
427
|
+
# Créer un modèle pour extraire les sorties des couches d'attention
|
|
428
|
+
if self._attention_layer_names:
|
|
429
|
+
# Utiliser les noms de couches spécifiés
|
|
430
|
+
attention_layers = [layer for layer in self._model.layers
|
|
431
|
+
if any(name in layer.name for name in self._attention_layer_names)]
|
|
432
|
+
else:
|
|
433
|
+
# Essayer de détecter automatiquement les couches d'attention
|
|
434
|
+
attention_layers = [layer for layer in self._model.layers
|
|
435
|
+
if 'attention' in layer.name.lower()]
|
|
436
|
+
|
|
437
|
+
# Si aucune couche d'attention n'est trouvée, essayer de trouver des couches avec des têtes d'attention
|
|
438
|
+
if not attention_layers:
|
|
439
|
+
for layer in self._model.layers:
|
|
440
|
+
if hasattr(layer, 'attention_heads') or hasattr(layer, 'num_heads'):
|
|
441
|
+
attention_layers.append(layer)
|
|
442
|
+
|
|
443
|
+
if not attention_layers:
|
|
444
|
+
raise ValueError("Aucune couche d'attention détectée dans le modèle.")
|
|
445
|
+
|
|
446
|
+
# Créer un modèle pour extraire les sorties des couches d'attention
|
|
447
|
+
attention_outputs = [layer.output for layer in attention_layers]
|
|
448
|
+
attention_model = tf.keras.Model(inputs=self._model.input, outputs=attention_outputs)
|
|
449
|
+
|
|
450
|
+
# Faire une prédiction pour obtenir les poids d'attention
|
|
451
|
+
attention_values = attention_model.predict(prepared_input, batch_size=batch_size)
|
|
452
|
+
|
|
453
|
+
# Convertir en liste si un seul élément
|
|
454
|
+
if not isinstance(attention_values, list):
|
|
455
|
+
attention_values = [attention_values]
|
|
456
|
+
|
|
457
|
+
# Créer le résultat
|
|
458
|
+
result = {
|
|
459
|
+
'num_layers': len(attention_values),
|
|
460
|
+
'num_heads': self._get_num_heads(attention_layers[0]) if attention_layers else 1,
|
|
461
|
+
'attention_weights': []
|
|
462
|
+
}
|
|
463
|
+
|
|
464
|
+
# Traiter chaque couche
|
|
465
|
+
for layer_idx, layer_attention in enumerate(attention_values):
|
|
466
|
+
# Pour les modèles avec plusieurs têtes d'attention
|
|
467
|
+
if len(layer_attention.shape) >= 4: # [batch, seq_len, seq_len, num_heads]
|
|
468
|
+
weights = layer_attention[0] # Premier élément du batch
|
|
469
|
+
else: # [batch, seq_len, seq_len]
|
|
470
|
+
weights = layer_attention[0, :, :, np.newaxis] # Ajouter une dimension pour les têtes
|
|
471
|
+
|
|
472
|
+
result['attention_weights'].append({
|
|
473
|
+
'layer': layer_idx,
|
|
474
|
+
'weights': weights
|
|
475
|
+
})
|
|
476
|
+
|
|
477
|
+
return result
|
|
478
|
+
|
|
479
|
+
def _extract_pytorch_attention(self, prepared_input, batch_size):
|
|
480
|
+
"""
|
|
481
|
+
Extrait les poids d'attention d'un modèle PyTorch.
|
|
482
|
+
|
|
483
|
+
Args:
|
|
484
|
+
prepared_input: Entrée préparée pour le modèle
|
|
485
|
+
batch_size: Taille du batch pour l'inférence
|
|
486
|
+
|
|
487
|
+
Returns:
|
|
488
|
+
dict: Poids d'attention extraits
|
|
489
|
+
"""
|
|
490
|
+
import torch
|
|
491
|
+
|
|
492
|
+
# Mettre le modèle en mode évaluation
|
|
493
|
+
self._model.eval()
|
|
494
|
+
|
|
495
|
+
# Enregistrer les hooks pour capturer les poids d'attention
|
|
496
|
+
attention_maps = []
|
|
497
|
+
hooks = []
|
|
498
|
+
|
|
499
|
+
def get_attention_hook(name):
|
|
500
|
+
def hook(module, input, output):
|
|
501
|
+
# Capturer les poids d'attention
|
|
502
|
+
if isinstance(output, tuple):
|
|
503
|
+
# Certains modules retournent (output, attention_weights)
|
|
504
|
+
for item in output:
|
|
505
|
+
if isinstance(item, torch.Tensor) and 'attention' in name.lower():
|
|
506
|
+
attention_maps.append(item.detach())
|
|
507
|
+
else:
|
|
508
|
+
attention_maps.append(output.detach())
|
|
509
|
+
return hook
|
|
510
|
+
|
|
511
|
+
# Attacher les hooks aux modules d'attention
|
|
512
|
+
for name, module in self._model.named_modules():
|
|
513
|
+
if self._attention_layer_names:
|
|
514
|
+
# Utiliser les noms de modules spécifiés
|
|
515
|
+
if any(pattern in name for pattern in self._attention_layer_names):
|
|
516
|
+
hooks.append(module.register_forward_hook(get_attention_hook(name)))
|
|
517
|
+
else:
|
|
518
|
+
# Détection automatique des modules d'attention
|
|
519
|
+
if 'attention' in name.lower() or hasattr(module, 'num_attention_heads'):
|
|
520
|
+
hooks.append(module.register_forward_hook(get_attention_hook(name)))
|
|
521
|
+
|
|
522
|
+
if not attention_maps:
|
|
523
|
+
raise ValueError("Aucun poids d'attention capturé. Vérifiez les noms des couches d'attention.")
|
|
524
|
+
|
|
525
|
+
# Faire une prédiction pour déclencher les hooks
|
|
526
|
+
with torch.no_grad():
|
|
527
|
+
_ = self._model(prepared_input)
|
|
528
|
+
|
|
529
|
+
# Supprimer les hooks
|
|
530
|
+
for hook in hooks:
|
|
531
|
+
hook.remove()
|
|
532
|
+
|
|
533
|
+
# Vérifier si des poids d'attention ont été capturés
|
|
534
|
+
if not attention_maps:
|
|
535
|
+
raise ValueError("Aucun poids d'attention capturé. Vérifiez les noms des couches d'attention.")
|
|
536
|
+
|
|
537
|
+
# Créer le résultat
|
|
538
|
+
result = {
|
|
539
|
+
'num_layers': len(attention_maps),
|
|
540
|
+
'num_heads': attention_maps[0].shape[1] if len(attention_maps[0].shape) > 3 else 1,
|
|
541
|
+
'attention_weights': []
|
|
542
|
+
}
|
|
543
|
+
|
|
544
|
+
# Traiter chaque couche
|
|
545
|
+
for layer_idx, layer_attention in enumerate(attention_maps):
|
|
546
|
+
# Convertir en numpy
|
|
547
|
+
layer_attention = layer_attention.cpu().numpy()
|
|
548
|
+
|
|
549
|
+
# Pour les modèles avec plusieurs têtes d'attention
|
|
550
|
+
if len(layer_attention.shape) >= 4: # [batch, num_heads, seq_len, seq_len]
|
|
551
|
+
weights = layer_attention[0] # Premier élément du batch
|
|
552
|
+
else: # [batch, seq_len, seq_len]
|
|
553
|
+
weights = layer_attention[0, :, :, np.newaxis] # Ajouter une dimension pour les têtes
|
|
554
|
+
|
|
555
|
+
result['attention_weights'].append({
|
|
556
|
+
'layer': layer_idx,
|
|
557
|
+
'weights': weights
|
|
558
|
+
})
|
|
559
|
+
|
|
560
|
+
return result
|
|
561
|
+
|
|
562
|
+
def _aggregate_attention_weights(self, attention_weights, method='mean', head_importance=None, layer_importance=None):
|
|
563
|
+
"""
|
|
564
|
+
Agrège les poids d'attention de plusieurs couches et têtes.
|
|
565
|
+
|
|
566
|
+
Args:
|
|
567
|
+
attention_weights: Poids d'attention extraits
|
|
568
|
+
method: Méthode d'agrégation ('mean', 'max', 'sum', 'last')
|
|
569
|
+
head_importance: Importance relative des différentes têtes d'attention
|
|
570
|
+
layer_importance: Importance relative des différentes couches
|
|
571
|
+
|
|
572
|
+
Returns:
|
|
573
|
+
numpy.ndarray: Poids d'attention agrégés
|
|
574
|
+
"""
|
|
575
|
+
num_layers = attention_weights['num_layers']
|
|
576
|
+
|
|
577
|
+
# Initialiser les poids agrégés
|
|
578
|
+
if num_layers == 0:
|
|
579
|
+
return np.array([])
|
|
580
|
+
|
|
581
|
+
# Récupérer les dimensions de la première couche
|
|
582
|
+
first_layer = attention_weights['attention_weights'][0]['weights']
|
|
583
|
+
|
|
584
|
+
# Pour les modèles avec plusieurs têtes d'attention
|
|
585
|
+
if len(first_layer.shape) == 3: # [num_heads, seq_len, seq_len]
|
|
586
|
+
num_heads = first_layer.shape[0]
|
|
587
|
+
seq_len = first_layer.shape[1]
|
|
588
|
+
else: # [seq_len, seq_len]
|
|
589
|
+
num_heads = 1
|
|
590
|
+
seq_len = first_layer.shape[0]
|
|
591
|
+
|
|
592
|
+
# Normaliser les importances des têtes et des couches si fournies
|
|
593
|
+
if head_importance is not None:
|
|
594
|
+
head_importance = np.array(head_importance)
|
|
595
|
+
head_importance = head_importance / head_importance.sum()
|
|
596
|
+
else:
|
|
597
|
+
head_importance = np.ones(num_heads) / num_heads
|
|
598
|
+
|
|
599
|
+
if layer_importance is not None:
|
|
600
|
+
layer_importance = np.array(layer_importance)
|
|
601
|
+
layer_importance = layer_importance / layer_importance.sum()
|
|
602
|
+
else:
|
|
603
|
+
layer_importance = np.ones(num_layers) / num_layers
|
|
604
|
+
|
|
605
|
+
# Agréger selon la méthode spécifiée
|
|
606
|
+
if method == 'last':
|
|
607
|
+
# Utiliser uniquement la dernière couche
|
|
608
|
+
last_layer = attention_weights['attention_weights'][-1]['weights']
|
|
609
|
+
if len(last_layer.shape) == 3: # [num_heads, seq_len, seq_len]
|
|
610
|
+
# Pondérer les têtes d'attention
|
|
611
|
+
weighted_heads = np.zeros((seq_len, seq_len))
|
|
612
|
+
for h in range(num_heads):
|
|
613
|
+
weighted_heads += head_importance[h] * last_layer[h]
|
|
614
|
+
return weighted_heads
|
|
615
|
+
else:
|
|
616
|
+
return last_layer
|
|
617
|
+
else:
|
|
618
|
+
# Initialiser le tenseur pour stocker les poids agrégés
|
|
619
|
+
aggregated = np.zeros((seq_len, seq_len))
|
|
620
|
+
|
|
621
|
+
# Agréger toutes les couches et têtes
|
|
622
|
+
for l, layer_data in enumerate(attention_weights['attention_weights']):
|
|
623
|
+
layer_weights = layer_data['weights']
|
|
624
|
+
|
|
625
|
+
# Pondérer les têtes d'attention
|
|
626
|
+
if len(layer_weights.shape) == 3: # [num_heads, seq_len, seq_len]
|
|
627
|
+
layer_aggregated = np.zeros((seq_len, seq_len))
|
|
628
|
+
for h in range(num_heads):
|
|
629
|
+
layer_aggregated += head_importance[h] * layer_weights[h]
|
|
630
|
+
else:
|
|
631
|
+
layer_aggregated = layer_weights
|
|
632
|
+
|
|
633
|
+
# Appliquer la pondération de la couche
|
|
634
|
+
aggregated += layer_importance[l] * layer_aggregated
|
|
635
|
+
|
|
636
|
+
return aggregated
|
|
637
|
+
|
|
638
|
+
def _convert_attention_to_importances(self, aggregated_attention, tokens, threshold=0.05, include_special_tokens=False):
|
|
639
|
+
"""
|
|
640
|
+
Convertit les poids d'attention agrégés en importances de caractéristiques.
|
|
641
|
+
|
|
642
|
+
Args:
|
|
643
|
+
aggregated_attention: Poids d'attention agrégés
|
|
644
|
+
tokens: Liste des tokens
|
|
645
|
+
threshold: Seuil pour filtrer les poids d'attention faibles
|
|
646
|
+
include_special_tokens: Inclure les tokens spéciaux dans l'explication
|
|
647
|
+
|
|
648
|
+
Returns:
|
|
649
|
+
list: Liste d'objets FeatureImportance
|
|
650
|
+
"""
|
|
651
|
+
# Vérifier si les dimensions correspondent
|
|
652
|
+
if aggregated_attention.shape[0] != len(tokens):
|
|
653
|
+
self._logger.warning(f"Dimensions incompatibles: {aggregated_attention.shape[0]} vs {len(tokens)}. "
|
|
654
|
+
f"Troncature appliquée.")
|
|
655
|
+
min_len = min(aggregated_attention.shape[0], len(tokens))
|
|
656
|
+
aggregated_attention = aggregated_attention[:min_len, :min_len]
|
|
657
|
+
tokens = tokens[:min_len]
|
|
658
|
+
|
|
659
|
+
# Calculer l'importance de chaque token (somme des poids d'attention entrants)
|
|
660
|
+
token_importances = aggregated_attention.sum(axis=0)
|
|
661
|
+
|
|
662
|
+
# Normaliser les importances
|
|
663
|
+
if token_importances.sum() > 0:
|
|
664
|
+
token_importances = token_importances / token_importances.sum()
|
|
665
|
+
|
|
666
|
+
# Créer les objets FeatureImportance
|
|
667
|
+
importances = []
|
|
668
|
+
for i, token in enumerate(tokens):
|
|
669
|
+
# Filtrer les tokens spéciaux si demandé
|
|
670
|
+
if not include_special_tokens and (token.startswith('[') and token.endswith(']')):
|
|
671
|
+
continue
|
|
672
|
+
|
|
673
|
+
# Filtrer les tokens avec une importance inférieure au seuil
|
|
674
|
+
if token_importances[i] >= threshold:
|
|
675
|
+
importances.append(FeatureImportance(
|
|
676
|
+
feature_name=token,
|
|
677
|
+
importance=float(token_importances[i]),
|
|
678
|
+
std=0.0, # Pas d'écart-type pour une seule instance
|
|
679
|
+
additional_info={
|
|
680
|
+
'position': i,
|
|
681
|
+
'attention_in': float(aggregated_attention[:, i].sum()),
|
|
682
|
+
'attention_out': float(aggregated_attention[i, :].sum())
|
|
683
|
+
}
|
|
684
|
+
))
|
|
685
|
+
|
|
686
|
+
# Trier par importance décroissante
|
|
687
|
+
importances.sort(key=lambda x: x.importance, reverse=True)
|
|
688
|
+
|
|
689
|
+
return importances
|
|
690
|
+
|
|
691
|
+
def _convert_attention_to_serializable(self, attention_weights):
|
|
692
|
+
"""
|
|
693
|
+
Convertit les poids d'attention en format sérialisable.
|
|
694
|
+
|
|
695
|
+
Args:
|
|
696
|
+
attention_weights: Poids d'attention extraits
|
|
697
|
+
|
|
698
|
+
Returns:
|
|
699
|
+
dict: Poids d'attention en format sérialisable
|
|
700
|
+
"""
|
|
701
|
+
result = {
|
|
702
|
+
'num_layers': attention_weights['num_layers'],
|
|
703
|
+
'num_heads': attention_weights['num_heads'],
|
|
704
|
+
'attention_weights': []
|
|
705
|
+
}
|
|
706
|
+
|
|
707
|
+
for layer_data in attention_weights['attention_weights']:
|
|
708
|
+
result['attention_weights'].append({
|
|
709
|
+
'layer': layer_data['layer'],
|
|
710
|
+
'weights': layer_data['weights'].tolist() if isinstance(layer_data['weights'], np.ndarray) else layer_data['weights']
|
|
711
|
+
})
|
|
712
|
+
|
|
713
|
+
return result
|
|
714
|
+
|
|
715
|
+
def _extract_metadata(self):
|
|
716
|
+
"""
|
|
717
|
+
Extrait les métadonnées du modèle pour la traçabilité et la conformité réglementaire.
|
|
718
|
+
"""
|
|
719
|
+
# Initialiser les métadonnées
|
|
720
|
+
self._metadata = {
|
|
721
|
+
'model_type': self._detect_model_type(),
|
|
722
|
+
'task_type': self._detect_task_type(),
|
|
723
|
+
'framework': self._framework,
|
|
724
|
+
'attention_layers': self._attention_layer_names if self._attention_layer_names else 'auto-detected',
|
|
725
|
+
'aggregation_method': self._aggregation_method,
|
|
726
|
+
'model_name': self._get_model_name(),
|
|
727
|
+
'timestamp': datetime.now().isoformat(),
|
|
728
|
+
'explainer_version': '1.0.0',
|
|
729
|
+
'explainer_config': {
|
|
730
|
+
'include_special_tokens': self._include_special_tokens,
|
|
731
|
+
'attention_threshold': self._attention_threshold
|
|
732
|
+
}
|
|
733
|
+
}
|
|
734
|
+
|
|
735
|
+
def _detect_model_type(self):
|
|
736
|
+
"""
|
|
737
|
+
Détecte le type de modèle (transformer, RNN, etc.).
|
|
738
|
+
|
|
739
|
+
Returns:
|
|
740
|
+
str: Type de modèle détecté
|
|
741
|
+
"""
|
|
742
|
+
# Vérifier le nom du modèle ou de ses modules
|
|
743
|
+
model_name = str(self._model.__class__.__name__).lower()
|
|
744
|
+
model_module = self._model.__module__.lower()
|
|
745
|
+
|
|
746
|
+
if any(name in model_name for name in ['bert', 'gpt', 'transformer', 't5', 'roberta', 'xlm', 'xlnet', 'distil']):
|
|
747
|
+
return 'transformer'
|
|
748
|
+
elif any(name in model_name for name in ['lstm', 'gru', 'rnn']):
|
|
749
|
+
return 'rnn'
|
|
750
|
+
elif 'attention' in model_name:
|
|
751
|
+
return 'attention-based'
|
|
752
|
+
elif 'transformers' in model_module:
|
|
753
|
+
return 'transformer'
|
|
754
|
+
else:
|
|
755
|
+
# Essayer de détecter par les attributs
|
|
756
|
+
if hasattr(self._model, 'transformer') or hasattr(self._model, 'encoder') and hasattr(self._model.encoder, 'layer'):
|
|
757
|
+
return 'transformer'
|
|
758
|
+
elif hasattr(self._model, 'lstm') or hasattr(self._model, 'gru'):
|
|
759
|
+
return 'rnn'
|
|
760
|
+
else:
|
|
761
|
+
return 'unknown'
|
|
762
|
+
|
|
763
|
+
def _detect_task_type(self):
|
|
764
|
+
"""
|
|
765
|
+
Détecte le type de tâche (classification, génération de texte, etc.).
|
|
766
|
+
|
|
767
|
+
Returns:
|
|
768
|
+
str: Type de tâche détecté
|
|
769
|
+
"""
|
|
770
|
+
# Vérifier le nom du modèle ou de ses modules
|
|
771
|
+
model_name = str(self._model.__class__.__name__).lower()
|
|
772
|
+
|
|
773
|
+
if any(name in model_name for name in ['classifier', 'classification']):
|
|
774
|
+
return 'classification'
|
|
775
|
+
elif any(name in model_name for name in ['regressor', 'regression']):
|
|
776
|
+
return 'regression'
|
|
777
|
+
elif any(name in model_name for name in ['generator', 'gpt', 'llm', 'decoder']):
|
|
778
|
+
return 'text_generation'
|
|
779
|
+
elif any(name in model_name for name in ['encoder', 'bert', 'embedding']):
|
|
780
|
+
return 'embedding'
|
|
781
|
+
elif any(name in model_name for name in ['seq2seq', 't5', 'translation']):
|
|
782
|
+
return 'sequence_to_sequence'
|
|
783
|
+
else:
|
|
784
|
+
# Vérifier la structure de sortie du modèle
|
|
785
|
+
if hasattr(self._model, 'config'):
|
|
786
|
+
if hasattr(self._model.config, 'num_labels'):
|
|
787
|
+
return 'classification' if self._model.config.num_labels > 1 else 'regression'
|
|
788
|
+
elif hasattr(self._model.config, 'is_decoder') and self._model.config.is_decoder:
|
|
789
|
+
return 'text_generation'
|
|
790
|
+
elif hasattr(self._model.config, 'is_encoder_decoder') and self._model.config.is_encoder_decoder:
|
|
791
|
+
return 'sequence_to_sequence'
|
|
792
|
+
|
|
793
|
+
# Par défaut, supposer qu'il s'agit d'un modèle de langage
|
|
794
|
+
return 'language_model'
|
|
795
|
+
|
|
796
|
+
def _get_model_name(self):
|
|
797
|
+
"""
|
|
798
|
+
Récupère le nom du modèle.
|
|
799
|
+
|
|
800
|
+
Returns:
|
|
801
|
+
str: Nom du modèle
|
|
802
|
+
"""
|
|
803
|
+
# Essayer de récupérer le nom du modèle depuis la configuration
|
|
804
|
+
if hasattr(self._model, 'config') and hasattr(self._model.config, 'name_or_path'):
|
|
805
|
+
return self._model.config.name_or_path
|
|
806
|
+
elif hasattr(self._model, 'name'):
|
|
807
|
+
return self._model.name
|
|
808
|
+
else:
|
|
809
|
+
# Utiliser le nom de la classe comme fallback
|
|
810
|
+
return self._model.__class__.__name__
|
|
811
|
+
|
|
812
|
+
def _get_num_heads(self, layer):
|
|
813
|
+
"""
|
|
814
|
+
Récupère le nombre de têtes d'attention d'une couche.
|
|
815
|
+
|
|
816
|
+
Args:
|
|
817
|
+
layer: Couche d'attention
|
|
818
|
+
|
|
819
|
+
Returns:
|
|
820
|
+
int: Nombre de têtes d'attention
|
|
821
|
+
"""
|
|
822
|
+
# Essayer de récupérer le nombre de têtes d'attention
|
|
823
|
+
if hasattr(layer, 'num_heads'):
|
|
824
|
+
return layer.num_heads
|
|
825
|
+
elif hasattr(layer, 'num_attention_heads'):
|
|
826
|
+
return layer.num_attention_heads
|
|
827
|
+
elif hasattr(layer, 'attention_heads'):
|
|
828
|
+
return layer.attention_heads
|
|
829
|
+
else:
|
|
830
|
+
# Valeur par défaut
|
|
831
|
+
return 1
|
|
832
|
+
|
|
833
|
+
def _sample_instances(self, X, y=None, max_instances=5, strategy='random'):
|
|
834
|
+
"""
|
|
835
|
+
Échantillonne des instances représentatives pour l'explication globale.
|
|
836
|
+
|
|
837
|
+
Args:
|
|
838
|
+
X: Données d'entrée
|
|
839
|
+
y: Valeurs cibles (optionnel)
|
|
840
|
+
max_instances: Nombre maximum d'instances à échantillonner
|
|
841
|
+
strategy: Stratégie d'échantillonnage ('random', 'stratified', 'diverse')
|
|
842
|
+
|
|
843
|
+
Returns:
|
|
844
|
+
list: Indices des instances échantillonnées
|
|
845
|
+
"""
|
|
846
|
+
n_samples = len(X)
|
|
847
|
+
max_instances = min(max_instances, n_samples)
|
|
848
|
+
|
|
849
|
+
if strategy == 'random':
|
|
850
|
+
# Échantillonnage aléatoire
|
|
851
|
+
return np.random.choice(n_samples, size=max_instances, replace=False).tolist()
|
|
852
|
+
|
|
853
|
+
elif strategy == 'stratified' and y is not None:
|
|
854
|
+
# Échantillonnage stratifié par classe
|
|
855
|
+
try:
|
|
856
|
+
from sklearn.model_selection import StratifiedShuffleSplit
|
|
857
|
+
|
|
858
|
+
# Vérifier si y est catégoriel
|
|
859
|
+
unique_y = np.unique(y)
|
|
860
|
+
if len(unique_y) < n_samples / 10: # Heuristique pour détecter les variables catégorielles
|
|
861
|
+
sss = StratifiedShuffleSplit(n_splits=1, test_size=max_instances, random_state=42)
|
|
862
|
+
for _, test_idx in sss.split(X, y):
|
|
863
|
+
return test_idx.tolist()
|
|
864
|
+
except (ImportError, ValueError):
|
|
865
|
+
self._logger.warning("L'échantillonnage stratifié a échoué, utilisation de l'échantillonnage aléatoire.")
|
|
866
|
+
|
|
867
|
+
elif strategy == 'diverse':
|
|
868
|
+
# Échantillonnage divers basé sur k-means
|
|
869
|
+
try:
|
|
870
|
+
# Pour le texte, on ne peut pas utiliser k-means directement
|
|
871
|
+
if isinstance(X[0], str):
|
|
872
|
+
return np.random.choice(n_samples, size=max_instances, replace=False).tolist()
|
|
873
|
+
|
|
874
|
+
# Pour les tenseurs ou tokens pré-définis
|
|
875
|
+
from sklearn.cluster import KMeans
|
|
876
|
+
|
|
877
|
+
# Convertir en tableau numpy si nécessaire
|
|
878
|
+
X_array = np.array(X)
|
|
879
|
+
if len(X_array.shape) > 2:
|
|
880
|
+
# Aplatir les tenseurs pour k-means
|
|
881
|
+
X_array = X_array.reshape(X_array.shape[0], -1)
|
|
882
|
+
|
|
883
|
+
# Appliquer k-means
|
|
884
|
+
kmeans = KMeans(n_clusters=max_instances, random_state=42, n_init=10)
|
|
885
|
+
kmeans.fit(X_array)
|
|
886
|
+
|
|
887
|
+
# Sélectionner l'instance la plus proche de chaque centre
|
|
888
|
+
closest_indices = []
|
|
889
|
+
for center in kmeans.cluster_centers_:
|
|
890
|
+
distances = np.linalg.norm(X_array - center, axis=1)
|
|
891
|
+
closest_idx = np.argmin(distances)
|
|
892
|
+
closest_indices.append(closest_idx)
|
|
893
|
+
|
|
894
|
+
return closest_indices
|
|
895
|
+
except (ImportError, ValueError):
|
|
896
|
+
self._logger.warning("L'échantillonnage divers a échoué, utilisation de l'échantillonnage aléatoire.")
|
|
897
|
+
|
|
898
|
+
# Fallback sur l'échantillonnage aléatoire
|
|
899
|
+
return np.random.choice(n_samples, size=max_instances, replace=False).tolist()
|
|
900
|
+
|
|
901
|
+
def _aggregate_text_importances(self, all_feature_importances):
|
|
902
|
+
"""
|
|
903
|
+
Agrège les importances de caractéristiques pour des textes différents.
|
|
904
|
+
|
|
905
|
+
Args:
|
|
906
|
+
all_feature_importances: Liste des importances de caractéristiques pour chaque instance
|
|
907
|
+
|
|
908
|
+
Returns:
|
|
909
|
+
list: Importances de caractéristiques agrégées
|
|
910
|
+
"""
|
|
911
|
+
# Collecter tous les tokens uniques avec leurs importances
|
|
912
|
+
token_importances = {}
|
|
913
|
+
|
|
914
|
+
for instance_importances in all_feature_importances:
|
|
915
|
+
for feature in instance_importances:
|
|
916
|
+
token = feature.feature_name
|
|
917
|
+
importance = feature.importance
|
|
918
|
+
|
|
919
|
+
if token in token_importances:
|
|
920
|
+
token_importances[token]['sum'] += importance
|
|
921
|
+
token_importances[token]['count'] += 1
|
|
922
|
+
token_importances[token]['values'].append(importance)
|
|
923
|
+
else:
|
|
924
|
+
token_importances[token] = {
|
|
925
|
+
'sum': importance,
|
|
926
|
+
'count': 1,
|
|
927
|
+
'values': [importance]
|
|
928
|
+
}
|
|
929
|
+
|
|
930
|
+
# Calculer les moyennes et écarts-types
|
|
931
|
+
aggregated_importances = []
|
|
932
|
+
for token, data in token_importances.items():
|
|
933
|
+
mean_importance = data['sum'] / data['count']
|
|
934
|
+
std_importance = np.std(data['values']) if len(data['values']) > 1 else 0.0
|
|
935
|
+
|
|
936
|
+
aggregated_importances.append(FeatureImportance(
|
|
937
|
+
feature_name=token,
|
|
938
|
+
importance=float(mean_importance),
|
|
939
|
+
std=float(std_importance),
|
|
940
|
+
additional_info={
|
|
941
|
+
'occurrence_count': data['count'],
|
|
942
|
+
'min_importance': float(min(data['values'])),
|
|
943
|
+
'max_importance': float(max(data['values']))
|
|
944
|
+
}
|
|
945
|
+
))
|
|
946
|
+
|
|
947
|
+
# Trier par importance décroissante
|
|
948
|
+
aggregated_importances.sort(key=lambda x: x.importance, reverse=True)
|
|
949
|
+
|
|
950
|
+
return aggregated_importances
|
|
951
|
+
|
|
952
|
+
def _aggregate_feature_importances(self, all_feature_importances, feature_names):
|
|
953
|
+
"""
|
|
954
|
+
Agrège les importances de caractéristiques pour des instances avec les mêmes caractéristiques.
|
|
955
|
+
|
|
956
|
+
Args:
|
|
957
|
+
all_feature_importances: Liste des importances de caractéristiques pour chaque instance
|
|
958
|
+
feature_names: Noms des caractéristiques
|
|
959
|
+
|
|
960
|
+
Returns:
|
|
961
|
+
list: Importances de caractéristiques agrégées
|
|
962
|
+
"""
|
|
963
|
+
# Initialiser les tableaux pour stocker les importances
|
|
964
|
+
n_features = len(feature_names)
|
|
965
|
+
importance_values = np.zeros((len(all_feature_importances), n_features))
|
|
966
|
+
|
|
967
|
+
# Remplir le tableau d'importances
|
|
968
|
+
for i, instance_importances in enumerate(all_feature_importances):
|
|
969
|
+
for j, feature_name in enumerate(feature_names):
|
|
970
|
+
# Trouver l'importance correspondante
|
|
971
|
+
for feature in instance_importances:
|
|
972
|
+
if feature.feature_name == feature_name:
|
|
973
|
+
importance_values[i, j] = feature.importance
|
|
974
|
+
break
|
|
975
|
+
|
|
976
|
+
# Calculer les moyennes et écarts-types
|
|
977
|
+
mean_importances = np.mean(importance_values, axis=0)
|
|
978
|
+
std_importances = np.std(importance_values, axis=0)
|
|
979
|
+
|
|
980
|
+
# Créer les objets FeatureImportance
|
|
981
|
+
aggregated_importances = []
|
|
982
|
+
for i, feature_name in enumerate(feature_names):
|
|
983
|
+
aggregated_importances.append(FeatureImportance(
|
|
984
|
+
feature_name=feature_name,
|
|
985
|
+
importance=float(mean_importances[i]),
|
|
986
|
+
std=float(std_importances[i]),
|
|
987
|
+
additional_info={
|
|
988
|
+
'min_importance': float(np.min(importance_values[:, i])),
|
|
989
|
+
'max_importance': float(np.max(importance_values[:, i]))
|
|
990
|
+
}
|
|
991
|
+
))
|
|
992
|
+
|
|
993
|
+
# Trier par importance décroissante
|
|
994
|
+
aggregated_importances.sort(key=lambda x: x.importance, reverse=True)
|
|
995
|
+
|
|
996
|
+
return aggregated_importances
|