diff --git a/.github/workflows/emscripten.yml b/.github/workflows/emscripten.yml index 47e54f6125638..6ed68496de8b2 100644 --- a/.github/workflows/emscripten.yml +++ b/.github/workflows/emscripten.yml @@ -72,7 +72,9 @@ jobs: CIBW_PLATFORM: pyodide SKLEARN_SKIP_OPENMP_TEST: "true" SKLEARN_SKIP_NETWORK_TESTS: 1 - CIBW_TEST_REQUIRES: "pytest pandas" + # Temporary work-around to avoid joblib 1.5.0 until there is a joblib + # release with https://github.com/joblib/joblib/pull/1721 + CIBW_TEST_REQUIRES: "pytest pandas joblib!=1.5.0" # -s pytest argument is needed to avoid an issue in pytest output capturing with Pyodide CIBW_TEST_COMMAND: "python -m pytest -svra --pyargs sklearn --durations 20 --showlocals" diff --git a/README.rst b/README.rst index 4f4741a090dee..5885bce67baa7 100644 --- a/README.rst +++ b/README.rst @@ -11,7 +11,7 @@ .. |Codecov| image:: https://codecov.io/gh/scikit-learn/scikit-learn/branch/main/graph/badge.svg?token=Pk8G9gg3y9 :target: https://codecov.io/gh/scikit-learn/scikit-learn -.. |Nightly wheels| image:: https://github.com/scikit-learn/scikit-learn/workflows/Wheel%20builder/badge.svg?event=schedule +.. |Nightly wheels| image:: https://github.com/scikit-learn/scikit-learn/actions/workflows/wheels.yml/badge.svg?event=schedule :target: https://github.com/scikit-learn/scikit-learn/actions?query=workflow%3A%22Wheel+builder%22+event%3Aschedule .. |Ruff| image:: https://img.shields.io/badge/code%20style-ruff-000000.svg @@ -176,22 +176,36 @@ Documentation Communication ~~~~~~~~~~~~~ -- Mailing list: https://mail.python.org/mailman/listinfo/scikit-learn -- Logos & Branding: https://github.com/scikit-learn/scikit-learn/tree/main/doc/logos -- Blog: https://blog.scikit-learn.org -- Calendar: https://blog.scikit-learn.org/calendar/ -- Stack Overflow: https://stackoverflow.com/questions/tagged/scikit-learn -- GitHub Discussions: https://github.com/scikit-learn/scikit-learn/discussions -- Website: https://scikit-learn.org -- LinkedIn: https://www.linkedin.com/company/scikit-learn -- Bluesky: https://bsky.app/profile/scikit-learn.org -- Mastodon: https://mastodon.social/@sklearn@fosstodon.org -- YouTube: https://www.youtube.com/channel/UCJosFjYm0ZYVUARxuOZqnnw/playlists -- Facebook: https://www.facebook.com/scikitlearnofficial/ -- Instagram: https://www.instagram.com/scikitlearnofficial/ -- TikTok: https://www.tiktok.com/@scikit.learn -- Discord: https://discord.gg/h9qyrK8Jc8 +Main Channels +^^^^^^^^^^^^^ +- **Website**: https://scikit-learn.org +- **Blog**: https://blog.scikit-learn.org +- **Mailing list**: https://mail.python.org/mailman/listinfo/scikit-learn + +Developer & Support +^^^^^^^^^^^^^^^^^^^^^^ + +- **GitHub Discussions**: https://github.com/scikit-learn/scikit-learn/discussions +- **Stack Overflow**: https://stackoverflow.com/questions/tagged/scikit-learn +- **Discord**: https://discord.gg/h9qyrK8Jc8 + +Social Media Platforms +^^^^^^^^^^^^^^^^^^^^^^ + +- **LinkedIn**: https://www.linkedin.com/company/scikit-learn +- **YouTube**: https://www.youtube.com/channel/UCJosFjYm0ZYVUARxuOZqnnw/playlists +- **Facebook**: https://www.facebook.com/scikitlearnofficial/ +- **Instagram**: https://www.instagram.com/scikitlearnofficial/ +- **TikTok**: https://www.tiktok.com/@scikit.learn +- **Bluesky**: https://bsky.app/profile/scikit-learn.org +- **Mastodon**: https://mastodon.social/@sklearn@fosstodon.org + +Resources +^^^^^^^^^ + +- **Calendar**: https://blog.scikit-learn.org/calendar/ +- **Logos & Branding**: https://github.com/scikit-learn/scikit-learn/tree/main/doc/logos Citation ~~~~~~~~ diff --git a/azure-pipelines.yml b/azure-pipelines.yml index 804214f97808a..a36daf39b50db 100644 --- a/azure-pipelines.yml +++ b/azure-pipelines.yml @@ -84,7 +84,6 @@ jobs: ) matrix: pylatest_free_threaded: - PYTHON_GIL: '0' DISTRIB: 'conda-free-threaded' LOCK_FILE: './build_tools/azure/pylatest_free_threaded_linux-64_conda.lock' COVERAGE: 'false' diff --git a/build_tools/azure/debian_32bit_lock.txt b/build_tools/azure/debian_32bit_lock.txt index 051a8b8ef7e48..c7b8cbceccacb 100644 --- a/build_tools/azure/debian_32bit_lock.txt +++ b/build_tools/azure/debian_32bit_lock.txt @@ -4,17 +4,17 @@ # # pip-compile --output-file=build_tools/azure/debian_32bit_lock.txt build_tools/azure/debian_32bit_requirements.txt # -coverage[toml]==7.8.0 +coverage[toml]==7.8.2 # via pytest-cov -cython==3.0.12 +cython==3.1.1 # via -r build_tools/azure/debian_32bit_requirements.txt iniconfig==2.1.0 # via pytest -joblib==1.5.0 +joblib==1.5.1 # via -r build_tools/azure/debian_32bit_requirements.txt -meson==1.8.0 +meson==1.8.1 # via meson-python -meson-python==0.17.1 +meson-python==0.18.0 # via -r build_tools/azure/debian_32bit_requirements.txt ninja==1.11.1.4 # via -r build_tools/azure/debian_32bit_requirements.txt @@ -23,7 +23,7 @@ packaging==25.0 # meson-python # pyproject-metadata # pytest -pluggy==1.5.0 +pluggy==1.6.0 # via pytest pyproject-metadata==0.9.1 # via meson-python diff --git a/build_tools/azure/install.sh b/build_tools/azure/install.sh index c009e2972036e..9ae67f8db5e29 100755 --- a/build_tools/azure/install.sh +++ b/build_tools/azure/install.sh @@ -67,17 +67,7 @@ python_environment_install_and_activate() { fi # Install additional packages on top of the lock-file in specific cases - if [[ "$DISTRIB" == "conda-free-threaded" ]]; then - # TODO: we install scipy with pip. When there is a conda-forge package, - # we can update build_tools/update_environments_and_lock_files.py and - # remove the line below - pip install scipy --only-binary :all: - # TODO: we install cython 3.1 alpha from pip. When there is a conda-forge package, - # we can update build_tools/update_environments_and_lock_files.py and - # remove the line below - pip install --pre cython --only-binary :all: - - elif [[ "$DISTRIB" == "conda-pip-scipy-dev" ]]; then + if [[ "$DISTRIB" == "conda-pip-scipy-dev" ]]; then echo "Installing development dependency wheels" dev_anaconda_url=https://pypi.anaconda.org/scientific-python-nightly-wheels/simple dev_packages="numpy scipy pandas Cython" diff --git a/build_tools/azure/pylatest_conda_forge_mkl_linux-64_conda.lock b/build_tools/azure/pylatest_conda_forge_mkl_linux-64_conda.lock index 9b452e7ecba3d..b53cd9ad6a1a7 100644 --- a/build_tools/azure/pylatest_conda_forge_mkl_linux-64_conda.lock +++ b/build_tools/azure/pylatest_conda_forge_mkl_linux-64_conda.lock @@ -1,6 +1,6 @@ # Generated by conda-lock. # platform: linux-64 -# input_hash: 15de7a0d1a0d046ada825ffa5ad3547c790bf903bd5d9b03e7c0e9a6a62c680d +# input_hash: f524d159a11a0a80ead3448f16255169f24edde269f6b81e8e28453bc4f7fc53 @EXPLICIT https://conda.anaconda.org/conda-forge/noarch/font-ttf-dejavu-sans-mono-2.37-hab24e00_0.tar.bz2#0c96522c6bdaed4b1566d11387caaf45 https://conda.anaconda.org/conda-forge/noarch/font-ttf-inconsolata-3.000-h77eed37_0.tar.bz2#34893075a5c9e55cdafac56607368fc6 @@ -15,26 +15,26 @@ https://conda.anaconda.org/conda-forge/noarch/ca-certificates-2025.4.26-hbd8a1cb https://conda.anaconda.org/conda-forge/noarch/fonts-conda-forge-1-0.tar.bz2#f766549260d6815b0c52253f1fb1bb29 https://conda.anaconda.org/conda-forge/linux-64/ld_impl_linux-64-2.43-h712a8e2_4.conda#01f8d123c96816249efd255a31ad7712 https://conda.anaconda.org/conda-forge/linux-64/libglvnd-1.7.0-ha4b6fd6_2.conda#434ca7e50e40f4918ab701e3facd59a0 -https://conda.anaconda.org/conda-forge/linux-64/llvm-openmp-20.1.4-h024ca30_0.conda#4fc395cda27912a7d904b86b5dbf3a4d +https://conda.anaconda.org/conda-forge/linux-64/llvm-openmp-20.1.5-h024ca30_0.conda#86f58be65a51d62ccc06cacfd83ff987 https://conda.anaconda.org/conda-forge/linux-64/_openmp_mutex-4.5-3_kmp_llvm.conda#ee5c2118262e30b972bc0b4db8ef0ba5 https://conda.anaconda.org/conda-forge/noarch/fonts-conda-ecosystem-1-0.tar.bz2#fee5683a3f04bd15cbd8318b096a27ab https://conda.anaconda.org/conda-forge/linux-64/libegl-1.7.0-ha4b6fd6_2.conda#c151d5eb730e9b7480e6d48c0fc44048 https://conda.anaconda.org/conda-forge/linux-64/libopengl-1.7.0-ha4b6fd6_2.conda#7df50d44d4a14d6c31a2c54f2cd92157 -https://conda.anaconda.org/conda-forge/linux-64/libgcc-14.2.0-h767d61c_2.conda#ef504d1acbd74b7cc6849ef8af47dd03 +https://conda.anaconda.org/conda-forge/linux-64/libgcc-15.1.0-h767d61c_2.conda#ea8ac52380885ed41c1baa8f1d6d2b93 https://conda.anaconda.org/conda-forge/linux-64/alsa-lib-1.2.14-hb9d3cd8_0.conda#76df83c2a9035c54df5d04ff81bcc02d -https://conda.anaconda.org/conda-forge/linux-64/aws-c-common-0.12.2-hb9d3cd8_0.conda#bd52f376d1d34d7823a7bf0773be86e8 +https://conda.anaconda.org/conda-forge/linux-64/aws-c-common-0.12.3-hb9d3cd8_0.conda#8448031a22c697fac3ed98d69e8a9160 https://conda.anaconda.org/conda-forge/linux-64/c-ares-1.34.5-hb9d3cd8_0.conda#f7f0d6cc2dc986d42ac2689ec88192be https://conda.anaconda.org/conda-forge/linux-64/libbrotlicommon-1.1.0-hb9d3cd8_2.conda#41b599ed2b02abcfdd84302bff174b23 -https://conda.anaconda.org/conda-forge/linux-64/libdeflate-1.23-h86f0d12_0.conda#27fe770decaf469a53f3e3a6d593067f +https://conda.anaconda.org/conda-forge/linux-64/libdeflate-1.24-h86f0d12_0.conda#64f0c503da58ec25ebd359e4d990afa8 https://conda.anaconda.org/conda-forge/linux-64/libexpat-2.7.0-h5888daf_0.conda#db0bfbe7dd197b68ad5f30333bae6ce0 https://conda.anaconda.org/conda-forge/linux-64/libffi-3.4.6-h2dba641_1.conda#ede4673863426c0883c0063d853bbd85 -https://conda.anaconda.org/conda-forge/linux-64/libgcc-ng-14.2.0-h69a702a_2.conda#a2222a6ada71fb478682efe483ce0f92 -https://conda.anaconda.org/conda-forge/linux-64/libgfortran5-14.2.0-hf1ad2bd_2.conda#556a4fdfac7287d349b8f09aba899693 +https://conda.anaconda.org/conda-forge/linux-64/libgcc-ng-15.1.0-h69a702a_2.conda#ddca86c7040dd0e73b2b69bd7833d225 +https://conda.anaconda.org/conda-forge/linux-64/libgfortran5-15.1.0-hcea5267_2.conda#01de444988ed960031dbe84cf4f9b1fc https://conda.anaconda.org/conda-forge/linux-64/libiconv-1.18-h4ce23a2_1.conda#e796ff8ddc598affdf7c173d6145f087 https://conda.anaconda.org/conda-forge/linux-64/libjpeg-turbo-3.1.0-hb9d3cd8_0.conda#9fa334557db9f63da6c9285fd2a48638 -https://conda.anaconda.org/conda-forge/linux-64/liblzma-5.8.1-hb9d3cd8_0.conda#0e87378639676987af32fee53ba32258 +https://conda.anaconda.org/conda-forge/linux-64/liblzma-5.8.1-hb9d3cd8_1.conda#a76fd702c93cd2dfd89eff30a5fd45a8 https://conda.anaconda.org/conda-forge/linux-64/libntlm-1.8-hb9d3cd8_0.conda#7c7927b404672409d9917d49bff5f2d6 -https://conda.anaconda.org/conda-forge/linux-64/libstdcxx-14.2.0-h8f9b012_2.conda#a78c856b6dc6bf4ea8daeb9beaaa3fb0 +https://conda.anaconda.org/conda-forge/linux-64/libstdcxx-15.1.0-h8f9b012_2.conda#1cb1c67961f6dd257eae9e9691b341aa https://conda.anaconda.org/conda-forge/linux-64/libutf8proc-2.10.0-h4c51ac1_0.conda#aeccfff2806ae38430638ffbb4be9610 https://conda.anaconda.org/conda-forge/linux-64/libuv-1.50.0-hb9d3cd8_0.conda#771ee65e13bc599b0b62af5359d80169 https://conda.anaconda.org/conda-forge/linux-64/libwebp-base-1.5.0-h851e524_0.conda#63f790534398730f59e1b899c3644d4a @@ -45,13 +45,12 @@ https://conda.anaconda.org/conda-forge/linux-64/pthread-stubs-0.4-hb9d3cd8_1002. https://conda.anaconda.org/conda-forge/linux-64/xorg-libice-1.1.2-hb9d3cd8_0.conda#fb901ff28063514abb6046c9ec2c4a45 https://conda.anaconda.org/conda-forge/linux-64/xorg-libxau-1.0.12-hb9d3cd8_0.conda#f6ebe2cb3f82ba6c057dde5d9debe4f7 https://conda.anaconda.org/conda-forge/linux-64/xorg-libxdmcp-1.1.5-hb9d3cd8_0.conda#8035c64cb77ed555e3f150b7b3972480 -https://conda.anaconda.org/conda-forge/linux-64/aws-c-cal-0.9.0-hada3f3f_0.conda#05a965f6def53dbcb5217945eb0b3689 -https://conda.anaconda.org/conda-forge/linux-64/aws-c-compression-0.3.1-hc2d532b_4.conda#4cc4dcd582b2f087d62c70b2d6daa59f -https://conda.anaconda.org/conda-forge/linux-64/aws-c-sdkutils-0.2.3-hc2d532b_4.conda#15a1f6fb713b4cd3fee74588b996a846 -https://conda.anaconda.org/conda-forge/linux-64/aws-checksums-0.2.7-hc2d532b_0.conda#398521f53e58db246658e7cff56d669f +https://conda.anaconda.org/conda-forge/linux-64/aws-c-cal-0.9.0-h5e3027f_1.conda#220588a5c6c9341a39d9e399848e5554 +https://conda.anaconda.org/conda-forge/linux-64/aws-c-compression-0.3.1-hafb2847_5.conda#e96cc668c0f9478f5771b37d57f90386 +https://conda.anaconda.org/conda-forge/linux-64/aws-c-sdkutils-0.2.3-hafb2847_5.conda#51ffa5a303e8256dcb176f14d78887b4 +https://conda.anaconda.org/conda-forge/linux-64/aws-checksums-0.2.7-hafb2847_1.conda#6d28d50637fac4f081a0903b4b33d56d https://conda.anaconda.org/conda-forge/linux-64/bzip2-1.0.8-h4bc722e_7.conda#62ee74e96c5ebb0af99386de58cf9553 https://conda.anaconda.org/conda-forge/linux-64/double-conversion-3.3.1-h5888daf_0.conda#bfd56492d8346d669010eccafe0ba058 -https://conda.anaconda.org/conda-forge/linux-64/expat-2.7.0-h5888daf_0.conda#d6845ae4dea52a2f90178bf1829a21f8 https://conda.anaconda.org/conda-forge/linux-64/gflags-2.2.2-h5888daf_1005.conda#d411fc29e338efb48c5fd4576d71d881 https://conda.anaconda.org/conda-forge/linux-64/keyutils-1.6.1-h166bdaf_0.tar.bz2#30186d27e2c9fa62b45fb1476b7200e3 https://conda.anaconda.org/conda-forge/linux-64/lerc-4.0.0-h0aef613_1.conda#9344155d33912347b37f0ae6c410a835 @@ -61,28 +60,27 @@ https://conda.anaconda.org/conda-forge/linux-64/libbrotlienc-1.1.0-hb9d3cd8_2.co https://conda.anaconda.org/conda-forge/linux-64/libedit-3.1.20250104-pl5321h7949ede_0.conda#c277e0a4d549b03ac1e9d6cbbe3d017b https://conda.anaconda.org/conda-forge/linux-64/libev-4.33-hd590300_2.conda#172bf1cd1ff8629f2b1179945ed45055 https://conda.anaconda.org/conda-forge/linux-64/libevent-2.1.12-hf998b51_1.conda#a1cfcc585f0c42bf8d5546bb1dfb668d -https://conda.anaconda.org/conda-forge/linux-64/libgfortran-14.2.0-h69a702a_2.conda#fb54c4ea68b460c278d26eea89cfbcc3 +https://conda.anaconda.org/conda-forge/linux-64/libgfortran-15.1.0-h69a702a_2.conda#f92e6e0a3c0c0c85561ef61aa59d555d https://conda.anaconda.org/conda-forge/linux-64/libmpdec-4.0.0-h4bc722e_0.conda#aeb98fdeb2e8f25d43ef71fbacbeec80 https://conda.anaconda.org/conda-forge/linux-64/libpciaccess-0.18-hd590300_0.conda#48f4330bfcd959c3cfb704d424903c82 https://conda.anaconda.org/conda-forge/linux-64/libpng-1.6.47-h943b412_0.conda#55199e2ae2c3651f6f9b2a447b47bdc9 -https://conda.anaconda.org/conda-forge/linux-64/libsqlite-3.49.1-hee588c1_2.conda#962d6ac93c30b1dfc54c9cccafd1003e +https://conda.anaconda.org/conda-forge/linux-64/libsqlite-3.49.2-hee588c1_0.conda#93048463501053a00739215ea3f36324 https://conda.anaconda.org/conda-forge/linux-64/libssh2-1.11.1-hcf80075_0.conda#eecce068c7e4eddeb169591baac20ac4 -https://conda.anaconda.org/conda-forge/linux-64/libstdcxx-ng-14.2.0-h4852527_2.conda#c75da67f045c2627f59e6fcb5f4e3a9b +https://conda.anaconda.org/conda-forge/linux-64/libstdcxx-ng-15.1.0-h4852527_2.conda#9d2072af184b5caa29492bf2344597bb https://conda.anaconda.org/conda-forge/linux-64/libuuid-2.38.1-h0b41bf4_0.conda#40b61aab5c7ba9ff276c41cfffe6b80b https://conda.anaconda.org/conda-forge/linux-64/libxcb-1.17.0-h8a09558_0.conda#92ed62436b625154323d40d5f2f11dd7 https://conda.anaconda.org/conda-forge/linux-64/lz4-c-1.10.0-h5888daf_1.conda#9de5350a85c4a20c685259b889aa6393 -https://conda.anaconda.org/conda-forge/linux-64/mysql-common-9.2.0-h266115a_0.conda#db22a0962c953e81a2a679ecb1fc6027 https://conda.anaconda.org/conda-forge/linux-64/ninja-1.12.1-hff21bea_1.conda#2322531904f27501ee19847b87ba7c64 https://conda.anaconda.org/conda-forge/linux-64/pixman-0.46.0-h29eaf8c_0.conda#d2f1c87d4416d1e7344cf92b1aaee1c4 https://conda.anaconda.org/conda-forge/linux-64/readline-8.2-h8c095d6_2.conda#283b96675859b20a825f8fa30f311446 -https://conda.anaconda.org/conda-forge/linux-64/s2n-1.5.17-hba75a32_0.conda#dbb899164b5451c34969e67a35ca17a9 +https://conda.anaconda.org/conda-forge/linux-64/s2n-1.5.18-h763c568_1.conda#0bf75253494a85260575e23c3b29db90 https://conda.anaconda.org/conda-forge/linux-64/sleef-3.8-h1b44611_0.conda#aec4dba5d4c2924730088753f6fa164b https://conda.anaconda.org/conda-forge/linux-64/snappy-1.2.1-h8bd8927_1.conda#3b3e64af585eadfb52bb90b553db5edf https://conda.anaconda.org/conda-forge/linux-64/tk-8.6.13-noxft_h4845f30_101.conda#d453b98d9c83e71da0741bb0ff4d76bc https://conda.anaconda.org/conda-forge/linux-64/wayland-1.23.1-h3e06ad9_1.conda#a37843723437ba75f42c9270ffe800b1 https://conda.anaconda.org/conda-forge/linux-64/zlib-1.3.1-hb9d3cd8_2.conda#c9f075ab2f33b3bbee9e62d4ad0a6cd8 https://conda.anaconda.org/conda-forge/linux-64/zstd-1.5.7-hb8e6e7a_2.conda#6432cb5d4ac0046c3ac0a8a0f95842f9 -https://conda.anaconda.org/conda-forge/linux-64/aws-c-io-0.18.1-h1a9f769_2.conda#19221489bff45371c13b983848f79a24 +https://conda.anaconda.org/conda-forge/linux-64/aws-c-io-0.19.0-h7962f60_2.conda#7a4be9867bab106d87febec673094a9e https://conda.anaconda.org/conda-forge/linux-64/brotli-bin-1.1.0-hb9d3cd8_2.conda#c63b5e52939e795ba8d26e35d767a843 https://conda.anaconda.org/conda-forge/linux-64/glog-0.7.1-hbabe93e_0.conda#ff862eebdfeb2fd048ae9dc92510baca https://conda.anaconda.org/conda-forge/linux-64/gmp-6.3.0-hac33072_2.conda#c94a5994ef49749880a8139cf9afcbe1 @@ -92,14 +90,13 @@ https://conda.anaconda.org/conda-forge/linux-64/krb5-1.21.3-h659f571_0.conda#3f4 https://conda.anaconda.org/conda-forge/linux-64/libcrc32c-1.1.2-h9c3ff4c_0.tar.bz2#c965a5aa0d5c1c37ffc62dff36e28400 https://conda.anaconda.org/conda-forge/linux-64/libdrm-2.4.124-hb9d3cd8_0.conda#8bc89311041d7fcb510238cf0848ccae https://conda.anaconda.org/conda-forge/linux-64/libfreetype6-2.13.3-h48d6fc4_1.conda#3c255be50a506c50765a93a6644f32fe -https://conda.anaconda.org/conda-forge/linux-64/libgfortran-ng-14.2.0-h69a702a_2.conda#4056c857af1a99ee50589a941059ec55 +https://conda.anaconda.org/conda-forge/linux-64/libgfortran-ng-15.1.0-h69a702a_2.conda#a483a87b71e974bb75d1b9413d4436dd https://conda.anaconda.org/conda-forge/linux-64/libnghttp2-1.64.0-h161d5f1_0.conda#19e57602824042dfd0446292ef90488b https://conda.anaconda.org/conda-forge/linux-64/libprotobuf-5.29.3-h501fc15_1.conda#edb86556cf4a0c133e7932a1597ff236 https://conda.anaconda.org/conda-forge/linux-64/libre2-11-2024.07.02-hba17884_3.conda#545e93a513c10603327c76c15485e946 https://conda.anaconda.org/conda-forge/linux-64/libthrift-0.21.0-h0e7cc3e_0.conda#dcb95c0a98ba9ff737f7ae482aef7833 -https://conda.anaconda.org/conda-forge/linux-64/libtiff-4.7.0-hd9ff511_4.conda#6c1028898cf3a2032d9af46689e1b81a -https://conda.anaconda.org/conda-forge/linux-64/mysql-libs-9.2.0-he0572af_0.conda#93340b072c393d23c4700a1d40565dca -https://conda.anaconda.org/conda-forge/linux-64/pcre2-10.44-hc749103_2.conda#31614c73d7b103ef76faa4d83d261d34 +https://conda.anaconda.org/conda-forge/linux-64/libtiff-4.7.0-hf01ce69_5.conda#e79a094918988bb1807462cd42c83962 +https://conda.anaconda.org/conda-forge/linux-64/pcre2-10.45-hc749103_0.conda#b90bece58b4c2bf25969b70f3be42d25 https://conda.anaconda.org/conda-forge/linux-64/python-3.13.3-hf636f53_101_cp313.conda#10622e12d649154af0bd76bcf33a7c5c https://conda.anaconda.org/conda-forge/linux-64/qhull-2020.2-h434a139_5.conda#353823361b1d27eb3960efb076dfcaf6 https://conda.anaconda.org/conda-forge/linux-64/xcb-util-0.4.1-hb711507_2.conda#8637c3e5821654d0edf97e2b0404b443 @@ -108,40 +105,39 @@ https://conda.anaconda.org/conda-forge/linux-64/xcb-util-renderutil-0.3.10-hb711 https://conda.anaconda.org/conda-forge/linux-64/xcb-util-wm-0.4.2-hb711507_0.conda#608e0ef8256b81d04456e8d211eee3e8 https://conda.anaconda.org/conda-forge/linux-64/xorg-libsm-1.2.6-he73a12e_0.conda#1c74ff8c35dcadf952a16f752ca5aa49 https://conda.anaconda.org/conda-forge/linux-64/xorg-libx11-1.8.12-h4f16b4b_0.conda#db038ce880f100acc74dba10302b5630 -https://conda.anaconda.org/conda-forge/linux-64/aws-c-event-stream-0.5.4-hc5e5e9e_7.conda#eb339cb6cd7c881b3f0e7910e99c261b -https://conda.anaconda.org/conda-forge/linux-64/aws-c-http-0.10.0-h6884c39_0.conda#76a0f88aeb377e0eee84d48ac65ca747 +https://conda.anaconda.org/conda-forge/linux-64/aws-c-event-stream-0.5.4-h2dcaabb_9.conda#2f2ffcdfeabac698297fce1259e51a2a +https://conda.anaconda.org/conda-forge/linux-64/aws-c-http-0.10.1-hb50fa74_1.conda#2bb746bfe603e4949d99404b25c639ea https://conda.anaconda.org/conda-forge/linux-64/brotli-1.1.0-hb9d3cd8_2.conda#98514fe74548d768907ce7a13f680e8f https://conda.anaconda.org/conda-forge/noarch/colorama-0.4.6-pyhd8ed1ab_1.conda#962b9857ee8e7018c22f2776ffa0b2d7 https://conda.anaconda.org/conda-forge/noarch/cpython-3.13.3-py313hd8ed1ab_101.conda#904a822cbd380adafb9070debf8579a8 https://conda.anaconda.org/conda-forge/noarch/cycler-0.12.1-pyhd8ed1ab_1.conda#44600c4667a319d67dbe0681fc0bc833 https://conda.anaconda.org/conda-forge/linux-64/cyrus-sasl-2.1.27-h54b06d7_7.conda#dce22f70b4e5a407ce88f2be046f4ceb -https://conda.anaconda.org/conda-forge/linux-64/cython-3.0.12-py313h5dec8f5_0.conda#24a42a0c1cc33743e33572d63d489b54 -https://conda.anaconda.org/conda-forge/noarch/exceptiongroup-1.2.2-pyhd8ed1ab_1.conda#a16662747cdeb9abbac74d0057cc976e +https://conda.anaconda.org/conda-forge/linux-64/cython-3.1.1-py313h5dec8f5_1.conda#f114755cdd37627732b1884b7b15d4b5 https://conda.anaconda.org/conda-forge/noarch/execnet-2.1.1-pyhd8ed1ab_1.conda#a71efeae2c160f6789900ba2631a2c90 https://conda.anaconda.org/conda-forge/noarch/filelock-3.18.0-pyhd8ed1ab_0.conda#4547b39256e296bb758166893e909a7c -https://conda.anaconda.org/conda-forge/noarch/fsspec-2025.3.2-pyhd8ed1ab_0.conda#9c40692c3d24c7aaf335f673ac09d308 +https://conda.anaconda.org/conda-forge/noarch/fsspec-2025.5.1-pyhd8ed1ab_0.conda#2d2c9ef879a7e64e2dc657b09272c2b6 https://conda.anaconda.org/conda-forge/noarch/iniconfig-2.0.0-pyhd8ed1ab_1.conda#6837f3eff7dcea42ecd714ce1ac2b108 https://conda.anaconda.org/conda-forge/linux-64/kiwisolver-1.4.7-py313h33d0bda_0.conda#9862d13a5e466273d5a4738cffcb8d6c https://conda.anaconda.org/conda-forge/linux-64/lcms2-2.17-h717163a_0.conda#000e85703f0fd9594c81710dd5066471 https://conda.anaconda.org/conda-forge/linux-64/libcups-2.3.3-h4637d8d_4.conda#d4529f4dff3057982a7617c7ac58fde3 https://conda.anaconda.org/conda-forge/linux-64/libcurl-8.13.0-h332b0f4_0.conda#cbdc92ac0d93fe3c796e36ad65c7905c https://conda.anaconda.org/conda-forge/linux-64/libfreetype-2.13.3-ha770c72_1.conda#51f5be229d83ecd401fb369ab96ae669 -https://conda.anaconda.org/conda-forge/linux-64/libglib-2.84.1-h2ff4ddf_0.conda#0305434da649d4fb48a425e588b79ea6 +https://conda.anaconda.org/conda-forge/linux-64/libglib-2.84.2-h3618099_0.conda#072ab14a02164b7c0c089055368ff776 https://conda.anaconda.org/conda-forge/linux-64/libglx-1.7.0-ha4b6fd6_2.conda#c8013e438185f33b13814c5c488acd5c https://conda.anaconda.org/conda-forge/linux-64/libhiredis-1.0.2-h2cc385e_0.tar.bz2#b34907d3a81a3cd8095ee83d174c074a -https://conda.anaconda.org/conda-forge/linux-64/libxml2-2.13.7-h4bc477f_1.conda#ad1f1f8238834cd3c88ceeaee8da444a +https://conda.anaconda.org/conda-forge/linux-64/libxml2-2.13.8-h4bc477f_0.conda#14dbe05b929e329dbaa6f2d0aa19466d https://conda.anaconda.org/conda-forge/linux-64/markupsafe-3.0.2-py313h8060acc_1.conda#21b62c55924f01b6eef6827167b46acb -https://conda.anaconda.org/conda-forge/noarch/meson-1.8.0-pyh29332c3_0.conda#8e25221b702272394b86b0f4d7217f77 +https://conda.anaconda.org/conda-forge/noarch/meson-1.8.1-pyhe01879c_0.conda#f3cccd9a6ce5331ae33f69ade5529162 https://conda.anaconda.org/conda-forge/linux-64/mpfr-4.2.1-h90cbb55_3.conda#2eeb50cab6652538eee8fc0bc3340c81 https://conda.anaconda.org/conda-forge/noarch/mpmath-1.3.0-pyhd8ed1ab_1.conda#3585aa87c43ab15b167b574cd73b057b https://conda.anaconda.org/conda-forge/noarch/munkres-1.1.4-pyh9f0ad1d_0.tar.bz2#2ba8498c1018c1e9c61eb99b973dfe19 https://conda.anaconda.org/conda-forge/noarch/networkx-3.4.2-pyh267e887_2.conda#fd40bf7f7f4bc4b647dc8512053d9873 https://conda.anaconda.org/conda-forge/linux-64/openjpeg-2.5.3-h5fbd93e_0.conda#9e5816bc95d285c115a3ebc2f8563564 -https://conda.anaconda.org/conda-forge/linux-64/orc-2.1.1-h17f744e_1.conda#cfe9bc267c22b6d53438eff187649d43 +https://conda.anaconda.org/conda-forge/linux-64/orc-2.1.2-h17f744e_0.conda#ef7f9897a244b2023a066c22a1089ce4 https://conda.anaconda.org/conda-forge/noarch/packaging-25.0-pyh29332c3_1.conda#58335b26c38bf4a20f399384c33cbcf9 https://conda.anaconda.org/conda-forge/noarch/pip-25.1.1-pyh145f28c_0.conda#01384ff1639c6330a0924791413b8714 -https://conda.anaconda.org/conda-forge/noarch/pluggy-1.5.0-pyhd8ed1ab_1.conda#e9dcbce5f45f9ee500e728ae58b605b6 -https://conda.anaconda.org/conda-forge/noarch/pybind11-global-2.13.6-pyh415d2e4_2.conda#120541563e520d12d8e39abd7de9092c +https://conda.anaconda.org/conda-forge/noarch/pluggy-1.6.0-pyhd8ed1ab_0.conda#7da7ccd349dbf6487a7778579d2bb971 +https://conda.anaconda.org/conda-forge/noarch/pybind11-global-2.13.6-pyh217bc35_3.conda#730a5284e26d6bdb73332dafb26aec82 https://conda.anaconda.org/conda-forge/noarch/pyparsing-3.2.3-pyhd8ed1ab_1.conda#513d3c262ee49b54a8fec85c5bc99764 https://conda.anaconda.org/conda-forge/noarch/python-tzdata-2025.2-pyhd8ed1ab_0.conda#88476ae6ebd24f39261e0854ac244f33 https://conda.anaconda.org/conda-forge/noarch/pytz-2025.2-pyhd8ed1ab_0.conda#bc8e3267d44011051f2eb14d22fb0960 @@ -151,35 +147,36 @@ https://conda.anaconda.org/conda-forge/noarch/six-1.17.0-pyhd8ed1ab_0.conda#a451 https://conda.anaconda.org/conda-forge/noarch/threadpoolctl-3.6.0-pyhecae5ae_0.conda#9d64911b31d57ca443e9f1e36b04385f https://conda.anaconda.org/conda-forge/noarch/toml-0.10.2-pyhd8ed1ab_1.conda#b0dd904de08b7db706167240bf37b164 https://conda.anaconda.org/conda-forge/noarch/tomli-2.2.1-pyhd8ed1ab_1.conda#ac944244f1fed2eb49bae07193ae8215 -https://conda.anaconda.org/conda-forge/linux-64/tornado-6.4.2-py313h536fd9c_0.conda#5f5cbdd527d2e74e270d8b6255ba714f +https://conda.anaconda.org/conda-forge/linux-64/tornado-6.5.1-py313h536fd9c_0.conda#e9434a5155db25c38ade26f71a2f5a48 https://conda.anaconda.org/conda-forge/noarch/typing_extensions-4.13.2-pyh29332c3_0.conda#83fc6ae00127671e301c9f44254c31b8 https://conda.anaconda.org/conda-forge/linux-64/xcb-util-image-0.4.0-hb711507_2.conda#a0901183f08b6c7107aab109733a3c91 https://conda.anaconda.org/conda-forge/linux-64/xkeyboard-config-2.44-hb9d3cd8_0.conda#7c91bfc90672888259675ad2ad28af9c https://conda.anaconda.org/conda-forge/linux-64/xorg-libxext-1.3.6-hb9d3cd8_0.conda#febbab7d15033c913d53c7a2c102309d https://conda.anaconda.org/conda-forge/linux-64/xorg-libxfixes-6.0.1-hb9d3cd8_0.conda#4bdb303603e9821baf5fe5fdff1dc8f8 https://conda.anaconda.org/conda-forge/linux-64/xorg-libxrender-0.9.12-hb9d3cd8_0.conda#96d57aba173e878a2089d5638016dc5e -https://conda.anaconda.org/conda-forge/linux-64/aws-c-auth-0.9.0-h9a6e2ae_4.conda#a948110dbbde6491c62815643a96d589 -https://conda.anaconda.org/conda-forge/linux-64/aws-c-mqtt-0.12.3-hef6a231_4.conda#fd1d89d79c8287e6bcb2a529292f537a +https://conda.anaconda.org/conda-forge/linux-64/aws-c-auth-0.9.0-h59ae206_7.conda#ca157ee18f02c33646d975995631b39e +https://conda.anaconda.org/conda-forge/linux-64/aws-c-mqtt-0.13.0-h35de22e_3.conda#df3ea458761b3fdf9e6eb7d8a38c121a https://conda.anaconda.org/conda-forge/linux-64/azure-core-cpp-1.14.0-h5cfcd09_0.conda#0a8838771cc2e985cd295e01ae83baf1 https://conda.anaconda.org/conda-forge/linux-64/ccache-4.11.3-h80c52d3_0.conda#eb517c6a2b960c3ccb6f1db1005f063a -https://conda.anaconda.org/conda-forge/linux-64/coverage-7.8.0-py313h8060acc_0.conda#375064d30e709bf7c1d4580e70aaea61 -https://conda.anaconda.org/conda-forge/linux-64/dbus-1.13.6-h5008d03_3.tar.bz2#ecfff944ba3960ecb334b9a2663d708d -https://conda.anaconda.org/conda-forge/linux-64/fonttools-4.57.0-py313h8060acc_0.conda#76b3a3367ac578a7cc43f4b7814e7e87 +https://conda.anaconda.org/conda-forge/linux-64/coverage-7.8.2-py313h8060acc_0.conda#b278629953bd3424060870fca744de4a +https://conda.anaconda.org/conda-forge/linux-64/dbus-1.16.2-h3c4dab8_0.conda#679616eb5ad4e521c83da4650860aba7 +https://conda.anaconda.org/conda-forge/noarch/exceptiongroup-1.3.0-pyhd8ed1ab_0.conda#72e42d28960d875c7654614f8b50939a +https://conda.anaconda.org/conda-forge/linux-64/fonttools-4.58.0-py313h8060acc_0.conda#0bf58a605826e69e1c6b28f35f83ea32 https://conda.anaconda.org/conda-forge/linux-64/freetype-2.13.3-ha770c72_1.conda#9ccd736d31e0c6e41f54e704e5312811 https://conda.anaconda.org/conda-forge/noarch/jinja2-3.1.6-pyhd8ed1ab_0.conda#446bd6c8cb26050d528881df495ce646 -https://conda.anaconda.org/conda-forge/noarch/joblib-1.5.0-pyhd8ed1ab_0.conda#3d7257f0a61c9aa4ffa3e324a887416b +https://conda.anaconda.org/conda-forge/noarch/joblib-1.5.1-pyhd8ed1ab_0.conda#fb1c14694de51a476ce8636d92b6f42c https://conda.anaconda.org/conda-forge/linux-64/libgl-1.7.0-ha4b6fd6_2.conda#928b8be80851f5d8ffb016f9c81dae7a https://conda.anaconda.org/conda-forge/linux-64/libgrpc-1.71.0-h8e591d7_1.conda#c3cfd72cbb14113abee7bbd86f44ad69 https://conda.anaconda.org/conda-forge/linux-64/libhwloc-2.11.2-default_h0d58e46_1001.conda#804ca9e91bcaea0824a341d55b1684f2 -https://conda.anaconda.org/conda-forge/linux-64/libllvm20-20.1.4-he9d0ab4_0.conda#96c33bbd084ef2b2463503fb7f1482ae -https://conda.anaconda.org/conda-forge/linux-64/libxkbcommon-1.9.1-h65c71a3_0.conda#6e45090fe0eec179ecc8041a3a3fc9f8 +https://conda.anaconda.org/conda-forge/linux-64/libllvm20-20.1.5-he9d0ab4_0.conda#8d2f5a2f019bd76ccba5eb771852d411 +https://conda.anaconda.org/conda-forge/linux-64/libxkbcommon-1.10.0-h65c71a3_0.conda#fedf6bfe5d21d21d2b1785ec00a8889a https://conda.anaconda.org/conda-forge/linux-64/libxslt-1.1.39-h76b75d6_0.conda#e71f31f8cfb0a91439f2086fc8aa0461 https://conda.anaconda.org/conda-forge/linux-64/mpc-1.3.1-h24ddda3_1.conda#aa14b9a5196a6d8dd364164b7ce56acf -https://conda.anaconda.org/conda-forge/linux-64/openldap-2.6.9-he970967_0.conda#ca2de8bbdc871bce41dbf59e51324165 +https://conda.anaconda.org/conda-forge/linux-64/openldap-2.6.10-he970967_0.conda#2e5bf4f1da39c0b32778561c3c4e5878 +https://conda.anaconda.org/conda-forge/linux-64/pillow-11.2.1-py313h8db990d_0.conda#91b00afee98d72d29dc3d1c1ab0008d7 https://conda.anaconda.org/conda-forge/linux-64/prometheus-cpp-1.3.0-ha5d0236_0.conda#a83f6a2fdc079e643237887a37460668 -https://conda.anaconda.org/conda-forge/noarch/pybind11-2.13.6-pyh1ec8472_2.conda#8088a5e7b2888c780738c3130f2a969d +https://conda.anaconda.org/conda-forge/noarch/pybind11-2.13.6-pyhc790b64_3.conda#1594696beebf1ecb6d29a1136f859a74 https://conda.anaconda.org/conda-forge/noarch/pyproject-metadata-0.9.1-pyhd8ed1ab_0.conda#22ae7c6ea81e0c8661ef32168dda929b -https://conda.anaconda.org/conda-forge/noarch/pytest-8.3.5-pyhd8ed1ab_0.conda#c3c9316209dec74a705a36797970c6be https://conda.anaconda.org/conda-forge/noarch/python-dateutil-2.9.0.post0-pyhff2d567_1.conda#5ba79d7c71f03c678c8ead841f347d6e https://conda.anaconda.org/conda-forge/noarch/python-gil-3.13.3-h4df99d1_101.conda#82c2641f2f0f513f7d2d1b847a2588e3 https://conda.anaconda.org/conda-forge/noarch/typing-extensions-4.13.2-h0e9735f_0.conda#568ed1300869dca0ba09fb750cda5dbb @@ -191,58 +188,59 @@ https://conda.anaconda.org/conda-forge/linux-64/xorg-libxi-1.8.2-hb9d3cd8_0.cond https://conda.anaconda.org/conda-forge/linux-64/xorg-libxrandr-1.5.4-hb9d3cd8_0.conda#2de7f99d6581a4a7adbff607b5c278ca https://conda.anaconda.org/conda-forge/linux-64/xorg-libxxf86vm-1.1.6-hb9d3cd8_0.conda#5efa5fa6243a622445fdfd72aee15efa https://conda.anaconda.org/conda-forge/noarch/_python_abi3_support-1.0-hd8ed1ab_2.conda#aaa2a381ccc56eac91d63b6c1240312f -https://conda.anaconda.org/conda-forge/linux-64/aws-c-s3-0.7.16-h7dfd680_1.conda#d8870015dbf8a8bb44832f4c330bf044 +https://conda.anaconda.org/conda-forge/linux-64/aws-c-s3-0.7.17-h50d7d24_2.conda#701bf42db0ec5de1e56b66ae0638d20b https://conda.anaconda.org/conda-forge/linux-64/azure-identity-cpp-1.10.0-h113e628_0.conda#73f73f60854f325a55f1d31459f2ab73 https://conda.anaconda.org/conda-forge/linux-64/azure-storage-common-cpp-12.8.0-h736e048_1.conda#13de36be8de3ae3f05ba127631599213 https://conda.anaconda.org/conda-forge/linux-64/fontconfig-2.15.0-h7e30c49_1.conda#8f5b0b297b59e1ac160ad4beec99dbee https://conda.anaconda.org/conda-forge/linux-64/gmpy2-2.2.1-py313h11186cd_0.conda#54d020e0eaacf1e99bfb2410b9aa2e5e -https://conda.anaconda.org/conda-forge/linux-64/libclang-cpp20.1-20.1.4-default_h1df26ce_0.conda#96f8d5b2e94c9ba4fef19f1adf068a15 -https://conda.anaconda.org/conda-forge/linux-64/libclang13-20.1.4-default_he06ed0a_0.conda#2d933632c8004be47deb2be61bf013be +https://conda.anaconda.org/conda-forge/linux-64/libclang-cpp20.1-20.1.5-default_h1df26ce_1.conda#330b1dadfa7c3205a01fa9599fabe808 +https://conda.anaconda.org/conda-forge/linux-64/libclang13-20.1.5-default_he06ed0a_1.conda#12117145218e7e1a528c8396ed803058 https://conda.anaconda.org/conda-forge/linux-64/libgoogle-cloud-2.36.0-hc4361e1_1.conda#ae36e6296a8dd8e8a9a8375965bf6398 https://conda.anaconda.org/conda-forge/linux-64/libopentelemetry-cpp-1.20.0-hd1b1c89_0.conda#e1185384cc23e3bbf85486987835df94 -https://conda.anaconda.org/conda-forge/linux-64/libpq-17.4-h27ae623_1.conda#37fba334855ef3b51549308e61ed7a3d -https://conda.anaconda.org/conda-forge/noarch/meson-python-0.17.1-pyh70fd9c4_1.conda#7a02679229c6c2092571b4c025055440 +https://conda.anaconda.org/conda-forge/linux-64/libpq-17.5-h27ae623_0.conda#6458be24f09e1b034902ab44fe9de908 +https://conda.anaconda.org/conda-forge/noarch/meson-python-0.18.0-pyh70fd9c4_0.conda#576c04b9d9f8e45285fb4d9452c26133 https://conda.anaconda.org/conda-forge/linux-64/optree-0.15.0-py313h33d0bda_0.conda#151f92ff0806c7c700419c8b8cf7cb4b -https://conda.anaconda.org/conda-forge/linux-64/pillow-11.1.0-py313h8db990d_0.conda#1e86810c6c3fb6d6aebdba26564eb2e8 -https://conda.anaconda.org/conda-forge/noarch/pytest-cov-6.1.1-pyhd8ed1ab_0.conda#1e35d8f975bc0e984a19819aa91c440a -https://conda.anaconda.org/conda-forge/noarch/pytest-xdist-3.6.1-pyhd8ed1ab_1.conda#59aad4fb37cabc0bacc73cf344612ddd +https://conda.anaconda.org/conda-forge/noarch/pytest-8.3.5-pyhd8ed1ab_0.conda#c3c9316209dec74a705a36797970c6be https://conda.anaconda.org/conda-forge/linux-64/tbb-2021.13.0-hceb3a55_1.conda#ba7726b8df7b9d34ea80e82b097a4893 https://conda.anaconda.org/conda-forge/linux-64/xorg-libxtst-1.2.5-hb9d3cd8_3.conda#7bbe9a0cc0df0ac5f5a8ad6d6a11af2f -https://conda.anaconda.org/conda-forge/linux-64/aws-crt-cpp-0.32.4-h0cee55f_2.conda#bc519b9909ef60e85ef2d59cd9542a0f +https://conda.anaconda.org/conda-forge/linux-64/aws-crt-cpp-0.32.5-h2811929_3.conda#c38733af13b256b8893a6af0d2a1d346 https://conda.anaconda.org/conda-forge/linux-64/azure-storage-blobs-cpp-12.13.0-h3cf044e_1.conda#7eb66060455c7a47d9dcdbfa9f46579b https://conda.anaconda.org/conda-forge/linux-64/cairo-1.18.4-h3394656_0.conda#09262e66b19567aff4f592fb53b28760 https://conda.anaconda.org/conda-forge/linux-64/libgoogle-cloud-storage-2.36.0-h0121fbd_1.conda#a0f7588c1f0a26d550e7bae4fb49427a https://conda.anaconda.org/conda-forge/linux-64/mkl-2024.2.2-ha957f24_16.conda#1459379c79dda834673426504d52b319 +https://conda.anaconda.org/conda-forge/noarch/pytest-cov-6.1.1-pyhd8ed1ab_0.conda#1e35d8f975bc0e984a19819aa91c440a +https://conda.anaconda.org/conda-forge/noarch/pytest-xdist-3.6.1-pyhd8ed1ab_1.conda#59aad4fb37cabc0bacc73cf344612ddd https://conda.anaconda.org/conda-forge/noarch/sympy-1.14.0-pyh2585a3b_105.conda#8c09fac3785696e1c477156192d64b91 -https://conda.anaconda.org/conda-forge/linux-64/aws-sdk-cpp-1.11.510-h5b777a2_6.conda#2fd0b0d4cc7fc86024b2965feedd628a +https://conda.anaconda.org/conda-forge/linux-64/aws-sdk-cpp-1.11.510-hffe9a0f_8.conda#4cd13ac60fb622ab49dfe949f2cd3051 https://conda.anaconda.org/conda-forge/linux-64/azure-storage-files-datalake-cpp-12.12.0-ha633028_1.conda#7c1980f89dd41b097549782121a73490 -https://conda.anaconda.org/conda-forge/linux-64/harfbuzz-11.1.0-h3beb420_0.conda#95e3bb97f9cdc251c0c68640e9c10ed3 +https://conda.anaconda.org/conda-forge/linux-64/harfbuzz-11.2.1-h3beb420_0.conda#0e6e192d4b3d95708ad192d957cf3163 https://conda.anaconda.org/conda-forge/linux-64/libblas-3.9.0-31_hfdb39a5_mkl.conda#bdf4a57254e8248222cb631db4393ff1 https://conda.anaconda.org/conda-forge/linux-64/mkl-devel-2024.2.2-ha770c72_16.conda#140891ea14285fc634353b31e9e40a95 -https://conda.anaconda.org/conda-forge/linux-64/libarrow-20.0.0-h27f8bab_0_cpu.conda#6dacb4d072204ce0fd13835759418872 +https://conda.anaconda.org/conda-forge/linux-64/libarrow-20.0.0-hebdba27_3_cpu.conda#5be86a1b5f496f82c7dfeb0dbe19ef03 https://conda.anaconda.org/conda-forge/linux-64/libcblas-3.9.0-31_h372d94f_mkl.conda#2a06a6c16b45bd3d10002927ca204b67 https://conda.anaconda.org/conda-forge/linux-64/liblapack-3.9.0-31_hc41d3b0_mkl.conda#10d012ddd7cc1c7ff9093d4974a34e53 -https://conda.anaconda.org/conda-forge/linux-64/qt6-main-6.9.0-h6441bc3_1.conda#4029a8dcb1d97ea241dbe5abfda1fad6 -https://conda.anaconda.org/conda-forge/linux-64/libarrow-acero-20.0.0-hcb10f89_0_cpu.conda#025bf09c4f59e6f5d9a6a4b82dd5894f +https://conda.anaconda.org/conda-forge/linux-64/qt6-main-6.9.0-h0384650_3.conda#8aa69e15597a205fd6f81781fe62c232 +https://conda.anaconda.org/conda-forge/linux-64/libarrow-acero-20.0.0-hcb10f89_3_cpu.conda#679cd6bb558cd6565d98ad66af6ff6ed https://conda.anaconda.org/conda-forge/linux-64/liblapacke-3.9.0-31_hbc6e62b_mkl.conda#562026e418363dc346ad5a9e18cce73c -https://conda.anaconda.org/conda-forge/linux-64/libparquet-20.0.0-h081d1f1_0_cpu.conda#4ad62607dd9f9902e0bd3d91c5bbce58 +https://conda.anaconda.org/conda-forge/linux-64/libparquet-20.0.0-h081d1f1_3_cpu.conda#f15cc1214c08019be884e3defd93e000 https://conda.anaconda.org/conda-forge/linux-64/libtorch-2.7.0-cpu_mkl_hf6ddc5a_100.conda#6bdda0b10852c6d03b030bab7ec251f0 -https://conda.anaconda.org/conda-forge/linux-64/numpy-2.2.5-py313h17eae1a_0.conda#6ceeff9ed72e54e4a2f9a1c88f47bdde +https://conda.anaconda.org/conda-forge/linux-64/numpy-2.2.6-py313h17eae1a_0.conda#7a2d2f9adecd86ed5c29c2115354f615 https://conda.anaconda.org/conda-forge/linux-64/pyarrow-core-20.0.0-py313he5f92c8_0_cpu.conda#2afdef63d9fbc2cd0e52f8e8f3472404 https://conda.anaconda.org/conda-forge/linux-64/pyside6-6.9.0-py313h5f61773_0.conda#f51f25ec8fcbf777f8b186bb5deeed40 https://conda.anaconda.org/conda-forge/noarch/array-api-strict-2.3.1-pyhd8ed1ab_0.conda#11107d0aeb8c590a34fee0894909816b https://conda.anaconda.org/conda-forge/linux-64/blas-devel-3.9.0-31_hcf00494_mkl.conda#368c93bde87a67d24a74de15bf4c49fd https://conda.anaconda.org/conda-forge/linux-64/contourpy-1.3.2-py313h33d0bda_0.conda#5dc81fffe102f63045225007a33d6199 -https://conda.anaconda.org/conda-forge/linux-64/libarrow-dataset-20.0.0-hcb10f89_0_cpu.conda#ebdbd9d4522b4106246866054f7520bf +https://conda.anaconda.org/conda-forge/linux-64/libarrow-dataset-20.0.0-hcb10f89_3_cpu.conda#0e84685fdecbd83666dd73292cc7d05a https://conda.anaconda.org/conda-forge/linux-64/pandas-2.2.3-py313ha87cce1_3.conda#6248b529e537b1d4cb5ab3ef7f537795 -https://conda.anaconda.org/conda-forge/linux-64/polars-1.27.1-py39h2a4a510_3.conda#fba08963eaa1f954480045d033d1221e +https://conda.anaconda.org/conda-forge/linux-64/polars-default-1.30.0-py39hfac2b71_0.conda#cd33cf1e631b4d766858c90e333b4832 https://conda.anaconda.org/conda-forge/linux-64/pytorch-2.7.0-cpu_mkl_py313_hea9ba1b_100.conda#3c2ce6a304aa827f1e3cc21f7df9190d https://conda.anaconda.org/conda-forge/linux-64/scipy-1.15.2-py313h86fcf2b_0.conda#ca68acd9febc86448eeed68d0c6c8643 https://conda.anaconda.org/conda-forge/noarch/scipy-doctest-1.7.1-pyh29332c3_0.conda#d3b3b7b88385648eff6ae39694692f27 https://conda.anaconda.org/conda-forge/linux-64/blas-2.131-mkl.conda#9bb865b7e01104255ca54e61a58ded15 -https://conda.anaconda.org/conda-forge/linux-64/libarrow-substrait-20.0.0-h1bed206_0_cpu.conda#1763dd016d6eee48e2bb29382f8d1562 -https://conda.anaconda.org/conda-forge/linux-64/matplotlib-base-3.10.1-py313h129903b_0.conda#4e23b3fabf434b418e0d9c6975a6453f +https://conda.anaconda.org/conda-forge/linux-64/libarrow-substrait-20.0.0-h1bed206_3_cpu.conda#c4d2a874f1ca439fb3c2a17060d6b911 +https://conda.anaconda.org/conda-forge/linux-64/matplotlib-base-3.10.3-py313h129903b_0.conda#4f8816d006b1c155ec416bcf7ff6cee2 +https://conda.anaconda.org/conda-forge/linux-64/polars-1.30.0-default_h1443d73_0.conda#19698b29e8544d2dd615699826037039 https://conda.anaconda.org/conda-forge/linux-64/pyamg-5.2.1-py313hf0ab243_1.conda#4c769bf3858f424cb2ecf952175ec600 https://conda.anaconda.org/conda-forge/linux-64/pytorch-cpu-2.7.0-cpu_mkl_hc60beec_100.conda#20b3051f55ad823a27818dfa46a41c8f -https://conda.anaconda.org/conda-forge/linux-64/matplotlib-3.10.1-py313h78bf25f_0.conda#d0c80dea550ca97fc0710b2ecef919ba +https://conda.anaconda.org/conda-forge/linux-64/matplotlib-3.10.3-py313h78bf25f_0.conda#cc9324e614a297fdf23439d887d3513d https://conda.anaconda.org/conda-forge/linux-64/pyarrow-20.0.0-py313h78bf25f_0.conda#6b8d388845ce750fe2ad8436669182f3 diff --git a/build_tools/azure/pylatest_conda_forge_mkl_osx-64_conda.lock b/build_tools/azure/pylatest_conda_forge_mkl_osx-64_conda.lock index 4def307b28f84..c91fc7eae1452 100644 --- a/build_tools/azure/pylatest_conda_forge_mkl_osx-64_conda.lock +++ b/build_tools/azure/pylatest_conda_forge_mkl_osx-64_conda.lock @@ -1,6 +1,6 @@ # Generated by conda-lock. # platform: osx-64 -# input_hash: b4e9eb0fbe1a7a6d067e4f4b43ca9e632309794c2a76d5c254ce023cb2fa2d99 +# input_hash: cee22335ff0a429180f2d8eeb31943f2646e3e653f1197f57ba6e39fc9659b05 @EXPLICIT https://conda.anaconda.org/conda-forge/noarch/libgfortran-devel_osx-64-13.3.0-h297be85_105.conda#c4967f8e797d0ffef3c5650fcdc2cdb5 https://conda.anaconda.org/conda-forge/osx-64/mkl-include-2023.2.0-h6bab518_50500.conda#835abb8ded5e26f23ea6996259c7972e @@ -11,17 +11,17 @@ https://conda.anaconda.org/conda-forge/osx-64/bzip2-1.0.8-hfdf4475_7.conda#7ed43 https://conda.anaconda.org/conda-forge/noarch/ca-certificates-2025.4.26-hbd8a1cb_0.conda#95db94f75ba080a22eb623590993167b https://conda.anaconda.org/conda-forge/osx-64/icu-75.1-h120a0e1_0.conda#d68d48a3060eb5abdc1cdc8e2a3a5966 https://conda.anaconda.org/conda-forge/osx-64/libbrotlicommon-1.1.0-h00291cd_2.conda#58f2c4bdd56c46cc7451596e4ae68e0b -https://conda.anaconda.org/conda-forge/osx-64/libcxx-20.1.4-hf95d169_0.conda#9a38a63cfe950dd3e1b3adfcba731d3a -https://conda.anaconda.org/conda-forge/osx-64/libdeflate-1.23-hcc1b750_0.conda#5d3507f22dda24f7d9a79325ad313e44 +https://conda.anaconda.org/conda-forge/osx-64/libcxx-20.1.5-hf95d169_0.conda#9dde68cee0a231b19e189954ac29027b +https://conda.anaconda.org/conda-forge/osx-64/libdeflate-1.24-hcc1b750_0.conda#f0a46c359722a3e84deb05cd4072d153 https://conda.anaconda.org/conda-forge/osx-64/libexpat-2.7.0-h240833e_0.conda#026d0a1056ba2a3dbbea6d4b08188676 https://conda.anaconda.org/conda-forge/osx-64/libffi-3.4.6-h281671d_1.conda#4ca9ea59839a9ca8df84170fab4ceb41 https://conda.anaconda.org/conda-forge/osx-64/libiconv-1.18-h4b5e92a_1.conda#6283140d7b2b55b6b095af939b71b13f https://conda.anaconda.org/conda-forge/osx-64/libjpeg-turbo-3.1.0-h6e16a3a_0.conda#87537967e6de2f885a9fcebd42b7cb10 -https://conda.anaconda.org/conda-forge/osx-64/liblzma-5.8.1-hd471939_0.conda#8e1197f652c67e87a9ece738d82cef4f +https://conda.anaconda.org/conda-forge/osx-64/liblzma-5.8.1-hd471939_1.conda#f87e8821e0e38a4140a7ed4f52530053 https://conda.anaconda.org/conda-forge/osx-64/libmpdec-4.0.0-hfdf4475_0.conda#ed625b2e59dff82859c23dd24774156b https://conda.anaconda.org/conda-forge/osx-64/libwebp-base-1.5.0-h6cf52b4_0.conda#5e0cefc99a231ac46ba21e27ae44689f https://conda.anaconda.org/conda-forge/osx-64/libzlib-1.3.1-hd23fc13_2.conda#003a54a4e32b02f7355b50a837e699da -https://conda.anaconda.org/conda-forge/osx-64/llvm-openmp-20.1.4-ha54dae1_0.conda#985619d7704847d30346abb6feeb8351 +https://conda.anaconda.org/conda-forge/osx-64/llvm-openmp-20.1.5-ha54dae1_0.conda#7b6a67507141ea93541943f0c011a872 https://conda.anaconda.org/conda-forge/osx-64/ncurses-6.5-h0622a9a_3.conda#ced34dd9929f491ca6dab6a2927aff25 https://conda.anaconda.org/conda-forge/osx-64/pthread-stubs-0.4-h00291cd_1002.conda#8bcf980d2c6b17094961198284b8e862 https://conda.anaconda.org/conda-forge/osx-64/xorg-libxau-1.0.12-h6e16a3a_0.conda#4cf40e60b444d56512a64f39d12c20bd @@ -34,7 +34,7 @@ https://conda.anaconda.org/conda-forge/osx-64/libbrotlienc-1.1.0-h00291cd_2.cond https://conda.anaconda.org/conda-forge/osx-64/libcxx-devel-18.1.8-h7c275be_8.conda#a9513c41f070a9e2d5c370ba5d6c0c00 https://conda.anaconda.org/conda-forge/osx-64/libgfortran5-14.2.0-h58528f3_105.conda#94560312ff3c78225bed62ab59854c31 https://conda.anaconda.org/conda-forge/osx-64/libpng-1.6.47-h3c4a55f_0.conda#8461ab86d2cdb76d6e971aab225be73f -https://conda.anaconda.org/conda-forge/osx-64/libsqlite-3.49.1-hdb6dae5_2.conda#1819e770584a7e83a81541d8253cbabe +https://conda.anaconda.org/conda-forge/osx-64/libsqlite-3.49.2-hdb6dae5_0.conda#9377ba1ade655ea3fc831b456f4a2351 https://conda.anaconda.org/conda-forge/osx-64/libxcb-1.17.0-hf1f96e2_0.conda#bbeca862892e2898bdb45792a61c4afc https://conda.anaconda.org/conda-forge/osx-64/libxml2-2.14.2-h8c082e5_0.conda#4adac80accf99fa253f0620444ad01fb https://conda.anaconda.org/conda-forge/osx-64/mkl-2023.2.0-h54c2260_50500.conda#0a342ccdc79e4fcd359245ac51941e7b @@ -51,7 +51,7 @@ https://conda.anaconda.org/conda-forge/osx-64/libblas-3.9.0-20_osx64_mkl.conda#1 https://conda.anaconda.org/conda-forge/osx-64/libfreetype6-2.13.3-h40dfd5c_1.conda#c76e6f421a0e95c282142f820835e186 https://conda.anaconda.org/conda-forge/osx-64/libgfortran-14.2.0-hef36b68_105.conda#6b27baf030f5d6603713c7e72d3f6b9a https://conda.anaconda.org/conda-forge/osx-64/libllvm18-18.1.8-default_h3571c67_5.conda#01dd8559b569ad39b64fef0a61ded1e9 -https://conda.anaconda.org/conda-forge/osx-64/libtiff-4.7.0-hb77a491_4.conda#b36d793dd65b28e3aeaa3a77abe71678 +https://conda.anaconda.org/conda-forge/osx-64/libtiff-4.7.0-h1167cee_5.conda#fc84af14a09e779f1d37ab1d16d5c4e2 https://conda.anaconda.org/conda-forge/osx-64/mkl-devel-2023.2.0-h694c41f_50500.conda#1b4d0235ef253a1e19459351badf4f9f https://conda.anaconda.org/conda-forge/osx-64/mpfr-4.2.1-haed47dc_3.conda#d511e58aaaabfc23136880d9956fa7a6 https://conda.anaconda.org/conda-forge/osx-64/python-3.13.3-h534c281_101_cp313.conda#ebcc7c42561d8d8b01477020b63218c0 @@ -59,66 +59,67 @@ https://conda.anaconda.org/conda-forge/osx-64/sigtool-0.1.3-h88f4db0_0.tar.bz2#f https://conda.anaconda.org/conda-forge/osx-64/brotli-1.1.0-h00291cd_2.conda#2db0c38a7f2321c5bdaf32b181e832c7 https://conda.anaconda.org/conda-forge/noarch/colorama-0.4.6-pyhd8ed1ab_1.conda#962b9857ee8e7018c22f2776ffa0b2d7 https://conda.anaconda.org/conda-forge/noarch/cycler-0.12.1-pyhd8ed1ab_1.conda#44600c4667a319d67dbe0681fc0bc833 -https://conda.anaconda.org/conda-forge/osx-64/cython-3.0.12-py313h9efc8c2_0.conda#ddace7cae5c3073c031ad08ef01881da -https://conda.anaconda.org/conda-forge/noarch/exceptiongroup-1.2.2-pyhd8ed1ab_1.conda#a16662747cdeb9abbac74d0057cc976e +https://conda.anaconda.org/conda-forge/osx-64/cython-3.1.1-py313h9efc8c2_1.conda#b94bca8fec5fbaa69375656928e05c1d https://conda.anaconda.org/conda-forge/noarch/execnet-2.1.1-pyhd8ed1ab_1.conda#a71efeae2c160f6789900ba2631a2c90 https://conda.anaconda.org/conda-forge/noarch/iniconfig-2.0.0-pyhd8ed1ab_1.conda#6837f3eff7dcea42ecd714ce1ac2b108 https://conda.anaconda.org/conda-forge/osx-64/kiwisolver-1.4.7-py313h0c4e38b_0.conda#c37fceab459e104e77bb5456e219fc37 https://conda.anaconda.org/conda-forge/osx-64/lcms2-2.17-h72f5680_0.conda#bf210d0c63f2afb9e414a858b79f0eaa https://conda.anaconda.org/conda-forge/osx-64/ld64_osx-64-951.9-h33512f0_6.conda#6cd120f5c9dae65b858e1fad2b7959a0 https://conda.anaconda.org/conda-forge/osx-64/libcblas-3.9.0-20_osx64_mkl.conda#51089a4865eb4aec2bc5c7468bd07f9f -https://conda.anaconda.org/conda-forge/osx-64/libclang-cpp18.1-18.1.8-default_h3571c67_9.conda#ef1a444913775b76f3391431967090a9 +https://conda.anaconda.org/conda-forge/osx-64/libclang-cpp18.1-18.1.8-default_h3571c67_10.conda#bf6753267e6f848f369c5bc2373dddd6 https://conda.anaconda.org/conda-forge/osx-64/libfreetype-2.13.3-h694c41f_1.conda#07c8d3fbbe907f32014b121834b36dd5 https://conda.anaconda.org/conda-forge/osx-64/libhiredis-1.0.2-h2beb688_0.tar.bz2#524282b2c46c9dedf051b3bc2ae05494 https://conda.anaconda.org/conda-forge/osx-64/liblapack-3.9.0-20_osx64_mkl.conda#58f08e12ad487fac4a08f90ff0b87aec https://conda.anaconda.org/conda-forge/osx-64/llvm-tools-18-18.1.8-default_h3571c67_5.conda#4391981e855468ced32ca1940b3d7613 -https://conda.anaconda.org/conda-forge/noarch/meson-1.8.0-pyh29332c3_0.conda#8e25221b702272394b86b0f4d7217f77 +https://conda.anaconda.org/conda-forge/noarch/meson-1.8.1-pyhe01879c_0.conda#f3cccd9a6ce5331ae33f69ade5529162 https://conda.anaconda.org/conda-forge/osx-64/mpc-1.3.1-h9d8efa1_1.conda#0520855aaae268ea413d6bc913f1384c https://conda.anaconda.org/conda-forge/noarch/munkres-1.1.4-pyh9f0ad1d_0.tar.bz2#2ba8498c1018c1e9c61eb99b973dfe19 https://conda.anaconda.org/conda-forge/osx-64/openjpeg-2.5.3-h7fd6d84_0.conda#025c711177fc3309228ca1a32374458d https://conda.anaconda.org/conda-forge/noarch/packaging-25.0-pyh29332c3_1.conda#58335b26c38bf4a20f399384c33cbcf9 https://conda.anaconda.org/conda-forge/noarch/pip-25.1.1-pyh145f28c_0.conda#01384ff1639c6330a0924791413b8714 -https://conda.anaconda.org/conda-forge/noarch/pluggy-1.5.0-pyhd8ed1ab_1.conda#e9dcbce5f45f9ee500e728ae58b605b6 +https://conda.anaconda.org/conda-forge/noarch/pluggy-1.6.0-pyhd8ed1ab_0.conda#7da7ccd349dbf6487a7778579d2bb971 https://conda.anaconda.org/conda-forge/noarch/pyparsing-3.2.3-pyhd8ed1ab_1.conda#513d3c262ee49b54a8fec85c5bc99764 https://conda.anaconda.org/conda-forge/noarch/python-tzdata-2025.2-pyhd8ed1ab_0.conda#88476ae6ebd24f39261e0854ac244f33 https://conda.anaconda.org/conda-forge/noarch/pytz-2025.2-pyhd8ed1ab_0.conda#bc8e3267d44011051f2eb14d22fb0960 -https://conda.anaconda.org/conda-forge/noarch/setuptools-80.1.0-pyhff2d567_0.conda#f6f72d0837c79eaec77661be43e8a691 +https://conda.anaconda.org/conda-forge/noarch/setuptools-80.8.0-pyhff2d567_0.conda#ea075e94dc0106c7212128b6a25bbc4c https://conda.anaconda.org/conda-forge/noarch/six-1.17.0-pyhd8ed1ab_0.conda#a451d576819089b0d672f18768be0f65 https://conda.anaconda.org/conda-forge/noarch/threadpoolctl-3.6.0-pyhecae5ae_0.conda#9d64911b31d57ca443e9f1e36b04385f https://conda.anaconda.org/conda-forge/noarch/toml-0.10.2-pyhd8ed1ab_1.conda#b0dd904de08b7db706167240bf37b164 https://conda.anaconda.org/conda-forge/noarch/tomli-2.2.1-pyhd8ed1ab_1.conda#ac944244f1fed2eb49bae07193ae8215 -https://conda.anaconda.org/conda-forge/osx-64/tornado-6.4.2-py313h63b0ddb_0.conda#74a3a14f82dc65fa19f4fd4e2eb8da93 +https://conda.anaconda.org/conda-forge/osx-64/tornado-6.5.1-py313h63b0ddb_0.conda#7554d07cbe64f41c73a403e99bccf3c6 +https://conda.anaconda.org/conda-forge/noarch/typing_extensions-4.13.2-pyh29332c3_0.conda#83fc6ae00127671e301c9f44254c31b8 https://conda.anaconda.org/conda-forge/osx-64/ccache-4.11.3-h33566b8_0.conda#b65cad834bd6c1f660c101cca09430bf -https://conda.anaconda.org/conda-forge/osx-64/clang-18-18.1.8-default_h3571c67_9.conda#e29d8d2866f15f3b167938cc0e775b2f -https://conda.anaconda.org/conda-forge/osx-64/coverage-7.8.0-py313h717bdf5_0.conda#1215b56c8d9915318d1714cbd004035f -https://conda.anaconda.org/conda-forge/osx-64/fonttools-4.57.0-py313h717bdf5_0.conda#190b8625dd6c38afe4f10e3be50122e4 +https://conda.anaconda.org/conda-forge/osx-64/clang-18-18.1.8-default_h3571c67_10.conda#62e1cd0882dad47d6a6878ad037f7b9d +https://conda.anaconda.org/conda-forge/osx-64/coverage-7.8.2-py313h717bdf5_0.conda#73eb83ea3d00f06bf78e242cca5e8e44 +https://conda.anaconda.org/conda-forge/noarch/exceptiongroup-1.3.0-pyhd8ed1ab_0.conda#72e42d28960d875c7654614f8b50939a +https://conda.anaconda.org/conda-forge/osx-64/fonttools-4.58.0-py313h717bdf5_0.conda#35452b432b5255dcdb2d751f1eb4087e https://conda.anaconda.org/conda-forge/osx-64/freetype-2.13.3-h694c41f_1.conda#126dba1baf5030cb6f34533718924577 https://conda.anaconda.org/conda-forge/osx-64/gfortran_impl_osx-64-13.3.0-hbf5bf67_105.conda#f56a107c8d1253346d01785ecece7977 -https://conda.anaconda.org/conda-forge/noarch/joblib-1.5.0-pyhd8ed1ab_0.conda#3d7257f0a61c9aa4ffa3e324a887416b +https://conda.anaconda.org/conda-forge/noarch/joblib-1.5.1-pyhd8ed1ab_0.conda#fb1c14694de51a476ce8636d92b6f42c https://conda.anaconda.org/conda-forge/osx-64/ld64-951.9-h4e51db5_6.conda#45bf526d53b1bc95bc0b932a91a41576 https://conda.anaconda.org/conda-forge/osx-64/liblapacke-3.9.0-20_osx64_mkl.conda#124ae8e384268a8da66f1d64114a1eda https://conda.anaconda.org/conda-forge/osx-64/llvm-tools-18.1.8-default_h3571c67_5.conda#cc07ff74d2547da1f1452c42b67bafd6 -https://conda.anaconda.org/conda-forge/osx-64/numpy-2.2.5-py313hc518a0f_0.conda#eba644ccc203cfde2fa1f450f528c70d +https://conda.anaconda.org/conda-forge/osx-64/numpy-2.2.6-py313hc518a0f_0.conda#7b80c7ace05b1b9d7ec6f55130776988 +https://conda.anaconda.org/conda-forge/osx-64/pillow-11.2.1-py313h0c4f865_0.conda#b4647eda8779d0e5d25cc8c9b124b303 https://conda.anaconda.org/conda-forge/noarch/pyproject-metadata-0.9.1-pyhd8ed1ab_0.conda#22ae7c6ea81e0c8661ef32168dda929b -https://conda.anaconda.org/conda-forge/noarch/pytest-8.3.5-pyhd8ed1ab_0.conda#c3c9316209dec74a705a36797970c6be https://conda.anaconda.org/conda-forge/noarch/python-dateutil-2.9.0.post0-pyhff2d567_1.conda#5ba79d7c71f03c678c8ead841f347d6e https://conda.anaconda.org/conda-forge/osx-64/blas-devel-3.9.0-20_osx64_mkl.conda#cc3260179093918b801e373c6e888e02 https://conda.anaconda.org/conda-forge/osx-64/cctools_osx-64-1010.6-hd19c6af_6.conda#4694e9e497454a8ce5b9fb61e50d9c5d -https://conda.anaconda.org/conda-forge/osx-64/clang-18.1.8-default_h576c50e_9.conda#266e7e8fa2190df09e6f236571c91511 +https://conda.anaconda.org/conda-forge/osx-64/clang-18.1.8-default_h576c50e_10.conda#350a10c62423982b0c80a043b9921c00 https://conda.anaconda.org/conda-forge/osx-64/contourpy-1.3.2-py313ha0b1807_0.conda#2c2d1f840df1c512b34e0537ef928169 -https://conda.anaconda.org/conda-forge/noarch/meson-python-0.17.1-pyh70fd9c4_1.conda#7a02679229c6c2092571b4c025055440 +https://conda.anaconda.org/conda-forge/noarch/meson-python-0.18.0-pyh70fd9c4_0.conda#576c04b9d9f8e45285fb4d9452c26133 https://conda.anaconda.org/conda-forge/osx-64/pandas-2.2.3-py313h2e7108f_3.conda#5c37fc7549913fc4895d7d2e097091ed -https://conda.anaconda.org/conda-forge/osx-64/pillow-11.1.0-py313h0c4f865_0.conda#11b4dd7a814202f2a0b655420f1c1c3a -https://conda.anaconda.org/conda-forge/noarch/pytest-cov-6.1.1-pyhd8ed1ab_0.conda#1e35d8f975bc0e984a19819aa91c440a -https://conda.anaconda.org/conda-forge/noarch/pytest-xdist-3.6.1-pyhd8ed1ab_1.conda#59aad4fb37cabc0bacc73cf344612ddd +https://conda.anaconda.org/conda-forge/noarch/pytest-8.3.5-pyhd8ed1ab_0.conda#c3c9316209dec74a705a36797970c6be https://conda.anaconda.org/conda-forge/osx-64/scipy-1.15.2-py313h7e69c36_0.conda#53c23f87aedf2d139d54c88894c8a07f https://conda.anaconda.org/conda-forge/osx-64/blas-2.120-mkl.conda#b041a7677a412f3d925d8208936cb1e2 https://conda.anaconda.org/conda-forge/osx-64/cctools-1010.6-ha66f10e_6.conda#a126dcde2752751ac781b67238f7fac4 -https://conda.anaconda.org/conda-forge/osx-64/clangxx-18.1.8-default_heb2e8d1_9.conda#4ba6bd39da787a7306eba77555e86dd3 -https://conda.anaconda.org/conda-forge/osx-64/matplotlib-base-3.10.1-py313he981572_0.conda#45a80d45944fbc43f081d719b23bf366 +https://conda.anaconda.org/conda-forge/osx-64/clangxx-18.1.8-default_heb2e8d1_10.conda#c39251c90faf5ba495d9f9ef88d7563e +https://conda.anaconda.org/conda-forge/osx-64/matplotlib-base-3.10.3-py313he981572_0.conda#91c22969c0974f2f23470d517774d457 https://conda.anaconda.org/conda-forge/osx-64/pyamg-5.2.1-py313h0322a6a_1.conda#4bda5182eeaef3d2017a2ec625802e1a +https://conda.anaconda.org/conda-forge/noarch/pytest-cov-6.1.1-pyhd8ed1ab_0.conda#1e35d8f975bc0e984a19819aa91c440a +https://conda.anaconda.org/conda-forge/noarch/pytest-xdist-3.6.1-pyhd8ed1ab_1.conda#59aad4fb37cabc0bacc73cf344612ddd https://conda.anaconda.org/conda-forge/noarch/compiler-rt_osx-64-18.1.8-hf2b8a54_1.conda#76f906e6bdc58976c5593f650290ae20 -https://conda.anaconda.org/conda-forge/osx-64/matplotlib-3.10.1-py313habf4b1d_0.conda#81ea3344e4fc2066a38199a64738ca6b +https://conda.anaconda.org/conda-forge/osx-64/matplotlib-3.10.3-py313habf4b1d_0.conda#c1043254f405998ece984e5f66a10943 https://conda.anaconda.org/conda-forge/osx-64/compiler-rt-18.1.8-h1020d70_1.conda#bc1714a1e73be18e411cff30dc1fe011 https://conda.anaconda.org/conda-forge/osx-64/clang_impl_osx-64-18.1.8-h6a44ed1_24.conda#5224d53acc2604a86d790f664d7fcbc4 https://conda.anaconda.org/conda-forge/osx-64/clang_osx-64-18.1.8-h7e5c614_24.conda#24e1a9c1296772ec45bfcd6a0d855fa5 diff --git a/build_tools/azure/pylatest_conda_mkl_no_openmp_osx-64_conda.lock b/build_tools/azure/pylatest_conda_mkl_no_openmp_osx-64_conda.lock index ed4af051f10c6..7be311177e65f 100644 --- a/build_tools/azure/pylatest_conda_mkl_no_openmp_osx-64_conda.lock +++ b/build_tools/azure/pylatest_conda_mkl_no_openmp_osx-64_conda.lock @@ -1,6 +1,6 @@ # Generated by conda-lock. # platform: osx-64 -# input_hash: 037fecf9454db91c21c8a57ee632e7221447f0bcfd9a5850dfcd6d727a30b086 +# input_hash: cc639ea0beeaceb46e2ad729ba559d5d5e746b8f6ff522bc718109af6265069c @EXPLICIT https://repo.anaconda.com/pkgs/main/osx-64/blas-1.0-mkl.conda#cb2c87e85ac8e0ceae776d26d4214c8a https://repo.anaconda.com/pkgs/main/osx-64/bzip2-1.0.8-h6c40b1e_6.conda#96224786021d0765ce05818fa3c59bdb @@ -53,7 +53,7 @@ https://repo.anaconda.com/pkgs/main/osx-64/pytz-2024.1-py312hecd8cb5_0.conda#2b2 https://repo.anaconda.com/pkgs/main/osx-64/setuptools-78.1.1-py312hecd8cb5_0.conda#76b66b96a1564cb76011408c1eb8df3e https://repo.anaconda.com/pkgs/main/osx-64/six-1.17.0-py312hecd8cb5_0.conda#aadd782bc06426887ae0835eedd98ceb https://repo.anaconda.com/pkgs/main/noarch/toml-0.10.2-pyhd3eb1b0_0.conda#cda05f5f6d8509529d1a2743288d197a -https://repo.anaconda.com/pkgs/main/osx-64/tornado-6.4.2-py312h46256e1_0.conda#6b41d7d8a2bf93ae3fc512202b14a9ec +https://repo.anaconda.com/pkgs/main/osx-64/tornado-6.5-py312h46256e1_0.conda#7e82973ed53e71854971e7b3922fad24 https://repo.anaconda.com/pkgs/main/osx-64/unicodedata2-15.1.0-py312h46256e1_1.conda#4a7fd1dec7277c8ab71aa11aa08df86b https://repo.anaconda.com/pkgs/main/osx-64/wheel-0.45.1-py312hecd8cb5_0.conda#fafb8687668467d8624d2ddd0909bce9 https://repo.anaconda.com/pkgs/main/osx-64/fonttools-4.55.3-py312h46256e1_0.conda#f7680dd6b8b1c2f8aab17cf6630c6deb @@ -75,8 +75,8 @@ https://repo.anaconda.com/pkgs/main/osx-64/numexpr-2.8.7-py312hac873b0_0.conda#6 https://repo.anaconda.com/pkgs/main/osx-64/scipy-1.11.4-py312h81688c2_0.conda#7d57b4c21a9261f97fa511e0940c5d93 https://repo.anaconda.com/pkgs/main/osx-64/pandas-2.2.3-py312h6d0c2b6_0.conda#84ce5b8ec4a986d13a5df17811f556a2 https://repo.anaconda.com/pkgs/main/osx-64/pyamg-5.2.1-py312h1962661_0.conda#58881950d4ce74c9302b56961f97a43c -# pip cython @ https://files.pythonhosted.org/packages/e6/6c/3be501a6520a93449b1e7e6f63e598ec56f3b5d1bc7ad14167c72a22ddf7/Cython-3.0.12-cp312-cp312-macosx_10_9_x86_64.whl#sha256=fe030d4a00afb2844f5f70896b7f2a1a0d7da09bf3aa3d884cbe5f73fff5d310 -# pip meson @ https://files.pythonhosted.org/packages/df/d7/f1c8acf0e597d4d07532f519780ee6e11ba285a9b092f18706b4c9118331/meson-1.8.0-py3-none-any.whl#sha256=472b7b25da286447333d32872b82d1c6f1a34024fb8ee017d7308056c25fec1f +# pip cython @ https://files.pythonhosted.org/packages/78/06/83ff82381319ff68ae46f9dd3024b1d5101997e81a8e955811525b6f934b/cython-3.1.1-cp312-cp312-macosx_10_13_x86_64.whl#sha256=9d7dc0e4d0cd491fac679a61e9ede348c64ca449f99a284f9a01851aa1dbc7f6 +# pip meson @ https://files.pythonhosted.org/packages/46/77/726b14be352aa6911e206ca7c4d95c5be49660604dfee0bfed0fc75823e5/meson-1.8.1-py3-none-any.whl#sha256=374bbf71247e629475fc10b0bd2ef66fc418c2d8f4890572f74de0f97d0d42da # pip threadpoolctl @ https://files.pythonhosted.org/packages/32/d5/f9a850d79b0851d1d4ef6456097579a9005b31fea68726a4ae5f2d82ddd9/threadpoolctl-3.6.0-py3-none-any.whl#sha256=43a0b8fd5a2928500110039e43a5eed8480b918967083ea48dc3ab9f13c4a7fb # pip pyproject-metadata @ https://files.pythonhosted.org/packages/7e/b1/8e63033b259e0a4e40dd1ec4a9fee17718016845048b43a36ec67d62e6fe/pyproject_metadata-0.9.1-py3-none-any.whl#sha256=ee5efde548c3ed9b75a354fc319d5afd25e9585fa918a34f62f904cc731973ad -# pip meson-python @ https://files.pythonhosted.org/packages/7d/ec/40c0ddd29ef4daa6689a2b9c5ced47d5b58fa54ae149b19e9a97f4979c8c/meson_python-0.17.1-py3-none-any.whl#sha256=30a75c52578ef14aff8392677b09c39346e0a24d2b2c6204b8ed30583c11269c +# pip meson-python @ https://files.pythonhosted.org/packages/28/58/66db620a8a7ccb32633de9f403fe49f1b63c68ca94e5c340ec5cceeb9821/meson_python-0.18.0-py3-none-any.whl#sha256=3b0fe051551cc238f5febb873247c0949cd60ded556efa130aa57021804868e2 diff --git a/build_tools/azure/pylatest_free_threaded_environment.yml b/build_tools/azure/pylatest_free_threaded_environment.yml index b947f31beb14a..8980bfce4adaf 100644 --- a/build_tools/azure/pylatest_free_threaded_environment.yml +++ b/build_tools/azure/pylatest_free_threaded_environment.yml @@ -6,6 +6,8 @@ channels: dependencies: - python-freethreading - numpy + - scipy + - cython - joblib - threadpoolctl - pytest diff --git a/build_tools/azure/pylatest_free_threaded_linux-64_conda.lock b/build_tools/azure/pylatest_free_threaded_linux-64_conda.lock index 39b5e6021d170..a75f20be093c2 100644 --- a/build_tools/azure/pylatest_free_threaded_linux-64_conda.lock +++ b/build_tools/azure/pylatest_free_threaded_linux-64_conda.lock @@ -1,58 +1,61 @@ # Generated by conda-lock. # platform: linux-64 -# input_hash: a4b2a317ef7733b7244b987f8b6b61126b9e647153cd112ba9565ae8eb5558e8 +# input_hash: b76364b5635e8c36a0fc0777955b5664a336ba94ac96f3ade7aad842ab7e15c5 @EXPLICIT https://conda.anaconda.org/conda-forge/linux-64/_libgcc_mutex-0.1-conda_forge.tar.bz2#d7c89558ba9fa0495403155b64376d81 -https://conda.anaconda.org/conda-forge/linux-64/python_abi-3.13-5_cp313t.conda#ea4c21b96e8280414d9e243da0ec3201 +https://conda.anaconda.org/conda-forge/noarch/python_abi-3.13-7_cp313t.conda#df81edcc11a1176315e8226acab83eec https://conda.anaconda.org/conda-forge/noarch/tzdata-2025b-h78e105d_0.conda#4222072737ccff51314b5ece9c7d6f5a https://conda.anaconda.org/conda-forge/noarch/ca-certificates-2025.4.26-hbd8a1cb_0.conda#95db94f75ba080a22eb623590993167b https://conda.anaconda.org/conda-forge/linux-64/ld_impl_linux-64-2.43-h712a8e2_4.conda#01f8d123c96816249efd255a31ad7712 -https://conda.anaconda.org/conda-forge/linux-64/libgomp-14.2.0-h767d61c_2.conda#06d02030237f4d5b3d9a7e7d348fe3c6 +https://conda.anaconda.org/conda-forge/linux-64/libgomp-15.1.0-h767d61c_2.conda#fbe7d535ff9d3a168c148e07358cd5b1 https://conda.anaconda.org/conda-forge/linux-64/_openmp_mutex-4.5-2_gnu.tar.bz2#73aaf86a425cc6e73fcf236a5a46396d -https://conda.anaconda.org/conda-forge/linux-64/libgcc-14.2.0-h767d61c_2.conda#ef504d1acbd74b7cc6849ef8af47dd03 +https://conda.anaconda.org/conda-forge/linux-64/libgcc-15.1.0-h767d61c_2.conda#ea8ac52380885ed41c1baa8f1d6d2b93 https://conda.anaconda.org/conda-forge/linux-64/libexpat-2.7.0-h5888daf_0.conda#db0bfbe7dd197b68ad5f30333bae6ce0 https://conda.anaconda.org/conda-forge/linux-64/libffi-3.4.6-h2dba641_1.conda#ede4673863426c0883c0063d853bbd85 -https://conda.anaconda.org/conda-forge/linux-64/libgcc-ng-14.2.0-h69a702a_2.conda#a2222a6ada71fb478682efe483ce0f92 -https://conda.anaconda.org/conda-forge/linux-64/libgfortran5-14.2.0-hf1ad2bd_2.conda#556a4fdfac7287d349b8f09aba899693 -https://conda.anaconda.org/conda-forge/linux-64/liblzma-5.8.1-hb9d3cd8_0.conda#0e87378639676987af32fee53ba32258 -https://conda.anaconda.org/conda-forge/linux-64/libstdcxx-14.2.0-h8f9b012_2.conda#a78c856b6dc6bf4ea8daeb9beaaa3fb0 +https://conda.anaconda.org/conda-forge/linux-64/libgcc-ng-15.1.0-h69a702a_2.conda#ddca86c7040dd0e73b2b69bd7833d225 +https://conda.anaconda.org/conda-forge/linux-64/libgfortran5-15.1.0-hcea5267_2.conda#01de444988ed960031dbe84cf4f9b1fc +https://conda.anaconda.org/conda-forge/linux-64/liblzma-5.8.1-hb9d3cd8_1.conda#a76fd702c93cd2dfd89eff30a5fd45a8 +https://conda.anaconda.org/conda-forge/linux-64/libstdcxx-15.1.0-h8f9b012_2.conda#1cb1c67961f6dd257eae9e9691b341aa https://conda.anaconda.org/conda-forge/linux-64/libzlib-1.3.1-hb9d3cd8_2.conda#edb0dca6bc32e4f4789199455a1dbeb8 https://conda.anaconda.org/conda-forge/linux-64/ncurses-6.5-h2d0b736_3.conda#47e340acb35de30501a76c7c799c41d7 https://conda.anaconda.org/conda-forge/linux-64/openssl-3.5.0-h7b32b05_1.conda#de356753cfdbffcde5bb1e86e3aa6cd0 https://conda.anaconda.org/conda-forge/linux-64/bzip2-1.0.8-h4bc722e_7.conda#62ee74e96c5ebb0af99386de58cf9553 -https://conda.anaconda.org/conda-forge/linux-64/libgfortran-14.2.0-h69a702a_2.conda#fb54c4ea68b460c278d26eea89cfbcc3 +https://conda.anaconda.org/conda-forge/linux-64/libgfortran-15.1.0-h69a702a_2.conda#f92e6e0a3c0c0c85561ef61aa59d555d https://conda.anaconda.org/conda-forge/linux-64/libmpdec-4.0.0-h4bc722e_0.conda#aeb98fdeb2e8f25d43ef71fbacbeec80 -https://conda.anaconda.org/conda-forge/linux-64/libsqlite-3.49.1-hee588c1_2.conda#962d6ac93c30b1dfc54c9cccafd1003e -https://conda.anaconda.org/conda-forge/linux-64/libstdcxx-ng-14.2.0-h4852527_2.conda#c75da67f045c2627f59e6fcb5f4e3a9b +https://conda.anaconda.org/conda-forge/linux-64/libsqlite-3.49.2-hee588c1_0.conda#93048463501053a00739215ea3f36324 +https://conda.anaconda.org/conda-forge/linux-64/libstdcxx-ng-15.1.0-h4852527_2.conda#9d2072af184b5caa29492bf2344597bb https://conda.anaconda.org/conda-forge/linux-64/libuuid-2.38.1-h0b41bf4_0.conda#40b61aab5c7ba9ff276c41cfffe6b80b https://conda.anaconda.org/conda-forge/linux-64/ninja-1.12.1-hff21bea_1.conda#2322531904f27501ee19847b87ba7c64 https://conda.anaconda.org/conda-forge/linux-64/readline-8.2-h8c095d6_2.conda#283b96675859b20a825f8fa30f311446 https://conda.anaconda.org/conda-forge/linux-64/tk-8.6.13-noxft_h4845f30_101.conda#d453b98d9c83e71da0741bb0ff4d76bc https://conda.anaconda.org/conda-forge/linux-64/zstd-1.5.7-hb8e6e7a_2.conda#6432cb5d4ac0046c3ac0a8a0f95842f9 -https://conda.anaconda.org/conda-forge/linux-64/libgfortran-ng-14.2.0-h69a702a_2.conda#4056c857af1a99ee50589a941059ec55 +https://conda.anaconda.org/conda-forge/linux-64/libgfortran-ng-15.1.0-h69a702a_2.conda#a483a87b71e974bb75d1b9413d4436dd https://conda.anaconda.org/conda-forge/linux-64/libopenblas-0.3.29-pthreads_h94d23a6_0.conda#0a4d0252248ef9a0f88f2ba8b8a08e12 https://conda.anaconda.org/conda-forge/linux-64/python-3.13.3-h4724d56_1_cp313t.conda#8193603fe48ace3d8801cfb246f44491 https://conda.anaconda.org/conda-forge/noarch/colorama-0.4.6-pyhd8ed1ab_1.conda#962b9857ee8e7018c22f2776ffa0b2d7 https://conda.anaconda.org/conda-forge/noarch/cpython-3.13.3-py313hd8ed1ab_1.conda#6ba9ba47b91b7758cb963d0f0eaf3422 -https://conda.anaconda.org/conda-forge/noarch/exceptiongroup-1.2.2-pyhd8ed1ab_1.conda#a16662747cdeb9abbac74d0057cc976e +https://conda.anaconda.org/conda-forge/noarch/cython-3.1.1-pyh2c78169_101.conda#f085516359786c4fea51bf05227ef3d2 https://conda.anaconda.org/conda-forge/noarch/execnet-2.1.1-pyhd8ed1ab_1.conda#a71efeae2c160f6789900ba2631a2c90 https://conda.anaconda.org/conda-forge/noarch/iniconfig-2.0.0-pyhd8ed1ab_1.conda#6837f3eff7dcea42ecd714ce1ac2b108 https://conda.anaconda.org/conda-forge/linux-64/libblas-3.9.0-31_h59b9bed_openblas.conda#728dbebd0f7a20337218beacffd37916 https://conda.anaconda.org/conda-forge/linux-64/libhiredis-1.0.2-h2cc385e_0.tar.bz2#b34907d3a81a3cd8095ee83d174c074a -https://conda.anaconda.org/conda-forge/noarch/meson-1.8.0-pyh29332c3_0.conda#8e25221b702272394b86b0f4d7217f77 +https://conda.anaconda.org/conda-forge/noarch/meson-1.8.1-pyhe01879c_0.conda#f3cccd9a6ce5331ae33f69ade5529162 https://conda.anaconda.org/conda-forge/noarch/packaging-25.0-pyh29332c3_1.conda#58335b26c38bf4a20f399384c33cbcf9 https://conda.anaconda.org/conda-forge/noarch/pip-25.1.1-pyh145f28c_0.conda#01384ff1639c6330a0924791413b8714 -https://conda.anaconda.org/conda-forge/noarch/pluggy-1.5.0-pyhd8ed1ab_1.conda#e9dcbce5f45f9ee500e728ae58b605b6 -https://conda.anaconda.org/conda-forge/noarch/setuptools-80.1.0-pyhff2d567_0.conda#f6f72d0837c79eaec77661be43e8a691 +https://conda.anaconda.org/conda-forge/noarch/pluggy-1.6.0-pyhd8ed1ab_0.conda#7da7ccd349dbf6487a7778579d2bb971 +https://conda.anaconda.org/conda-forge/noarch/setuptools-80.8.0-pyhff2d567_0.conda#ea075e94dc0106c7212128b6a25bbc4c https://conda.anaconda.org/conda-forge/noarch/threadpoolctl-3.6.0-pyhecae5ae_0.conda#9d64911b31d57ca443e9f1e36b04385f https://conda.anaconda.org/conda-forge/noarch/tomli-2.2.1-pyhd8ed1ab_1.conda#ac944244f1fed2eb49bae07193ae8215 +https://conda.anaconda.org/conda-forge/noarch/typing_extensions-4.13.2-pyh29332c3_0.conda#83fc6ae00127671e301c9f44254c31b8 https://conda.anaconda.org/conda-forge/linux-64/ccache-4.11.3-h80c52d3_0.conda#eb517c6a2b960c3ccb6f1db1005f063a -https://conda.anaconda.org/conda-forge/noarch/joblib-1.5.0-pyhd8ed1ab_0.conda#3d7257f0a61c9aa4ffa3e324a887416b +https://conda.anaconda.org/conda-forge/noarch/exceptiongroup-1.3.0-pyhd8ed1ab_0.conda#72e42d28960d875c7654614f8b50939a +https://conda.anaconda.org/conda-forge/noarch/joblib-1.5.1-pyhd8ed1ab_0.conda#fb1c14694de51a476ce8636d92b6f42c https://conda.anaconda.org/conda-forge/linux-64/libcblas-3.9.0-31_he106b2a_openblas.conda#abb32c727da370c481a1c206f5159ce9 https://conda.anaconda.org/conda-forge/linux-64/liblapack-3.9.0-31_h7ac8fdf_openblas.conda#452b98eafe050ecff932f0ec832dd03f https://conda.anaconda.org/conda-forge/noarch/pyproject-metadata-0.9.1-pyhd8ed1ab_0.conda#22ae7c6ea81e0c8661ef32168dda929b -https://conda.anaconda.org/conda-forge/noarch/pytest-8.3.5-pyhd8ed1ab_0.conda#c3c9316209dec74a705a36797970c6be https://conda.anaconda.org/conda-forge/noarch/python-freethreading-3.13.3-h92d6c8b_1.conda#4fa25290aec662a01642ba4b3c0ff5c1 -https://conda.anaconda.org/conda-forge/noarch/meson-python-0.17.1-pyh70fd9c4_1.conda#7a02679229c6c2092571b4c025055440 -https://conda.anaconda.org/conda-forge/linux-64/numpy-2.2.5-py313h103f029_0.conda#7dcbd568d6f8a4ffba5ace28915f1230 +https://conda.anaconda.org/conda-forge/noarch/meson-python-0.18.0-pyh70fd9c4_0.conda#576c04b9d9f8e45285fb4d9452c26133 +https://conda.anaconda.org/conda-forge/linux-64/numpy-2.2.6-py313h103f029_0.conda#7ae0a483b2cbbdf15d8429eb38f74a9e +https://conda.anaconda.org/conda-forge/noarch/pytest-8.3.5-pyhd8ed1ab_0.conda#c3c9316209dec74a705a36797970c6be https://conda.anaconda.org/conda-forge/noarch/pytest-xdist-3.6.1-pyhd8ed1ab_1.conda#59aad4fb37cabc0bacc73cf344612ddd +https://conda.anaconda.org/conda-forge/linux-64/scipy-1.15.2-py313h7f7b39c_0.conda#65f0c403e4324062633e648933f20a2e diff --git a/build_tools/azure/pylatest_pip_openblas_pandas_linux-64_conda.lock b/build_tools/azure/pylatest_pip_openblas_pandas_linux-64_conda.lock index edffbc7d70f46..81a109c63758c 100644 --- a/build_tools/azure/pylatest_pip_openblas_pandas_linux-64_conda.lock +++ b/build_tools/azure/pylatest_pip_openblas_pandas_linux-64_conda.lock @@ -1,6 +1,6 @@ # Generated by conda-lock. # platform: linux-64 -# input_hash: 830b1d953ebfc9e46b73f639e733ee09b5171952cf987981d569b1d5abd16292 +# input_hash: 50f16a0198b6eb575a737fee25051b52a644d72f5fca26bd661651a85fcb6a07 @EXPLICIT https://repo.anaconda.com/pkgs/main/linux-64/_libgcc_mutex-0.1-main.conda#c3473ff8bdb3d124ed5ff11ec380d6f9 https://repo.anaconda.com/pkgs/main/linux-64/ca-certificates-2025.2.25-h06a4308_0.conda#495015d24da8ad929e3ae2d18571016d @@ -32,31 +32,31 @@ https://repo.anaconda.com/pkgs/main/noarch/pip-25.1-pyhc872135_2.conda#2778327d2 # pip babel @ https://files.pythonhosted.org/packages/b7/b8/3fe70c75fe32afc4bb507f75563d39bc5642255d1d94f1f23604725780bf/babel-2.17.0-py3-none-any.whl#sha256=4d0b53093fdfb4b21c92b5213dba5a1b23885afa8383709427046b21c366e5f2 # pip certifi @ https://files.pythonhosted.org/packages/4a/7e/3db2bd1b1f9e95f7cddca6d6e75e2f2bd9f51b1246e546d88addca0106bd/certifi-2025.4.26-py3-none-any.whl#sha256=30350364dfe371162649852c63336a15c70c6510c2ad5015b21c2345311805f3 # pip charset-normalizer @ https://files.pythonhosted.org/packages/e2/28/ffc026b26f441fc67bd21ab7f03b313ab3fe46714a14b516f931abe1a2d8/charset_normalizer-3.4.2-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl#sha256=6c9379d65defcab82d07b2a9dfbfc2e95bc8fe0ebb1b176a3190230a3ef0e07c -# pip coverage @ https://files.pythonhosted.org/packages/cb/74/2f8cc196643b15bc096d60e073691dadb3dca48418f08bc78dd6e899383e/coverage-7.8.0-cp313-cp313-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl#sha256=5aaeb00761f985007b38cf463b1d160a14a22c34eb3f6a39d9ad6fc27cb73008 +# pip coverage @ https://files.pythonhosted.org/packages/89/60/f5f50f61b6332451520e6cdc2401700c48310c64bc2dd34027a47d6ab4ca/coverage-7.8.2-cp313-cp313-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl#sha256=dc67994df9bcd7e0150a47ef41278b9e0a0ea187caba72414b71dc590b99a108 # pip cycler @ https://files.pythonhosted.org/packages/e7/05/c19819d5e3d95294a6f5947fb9b9629efb316b96de511b418c53d245aae6/cycler-0.12.1-py3-none-any.whl#sha256=85cef7cff222d8644161529808465972e51340599459b8ac3ccbac5a854e0d30 -# pip cython @ https://files.pythonhosted.org/packages/a8/30/7f48207ea13dab46604db0dd388e807d53513ba6ad1c34462892072f8f8c/Cython-3.0.12-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl#sha256=879ae9023958d63c0675015369384642d0afb9c9d1f3473df9186c42f7a9d265 +# pip cython @ https://files.pythonhosted.org/packages/ca/90/9fe8b93fa239b4871252274892c232415f53d5af0859c4a6ac9b1cbf9950/cython-3.1.1-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl#sha256=7da069ca769903c5dee56c5f7ab47b2b7b91030eee48912630db5f4f3ec5954a # pip docutils @ https://files.pythonhosted.org/packages/8f/d7/9322c609343d929e75e7e5e6255e614fcc67572cfd083959cdef3b7aad79/docutils-0.21.2-py3-none-any.whl#sha256=dafca5b9e384f0e419294eb4d2ff9fa826435bf15f15b7bd45723e8ad76811b2 # pip execnet @ https://files.pythonhosted.org/packages/43/09/2aea36ff60d16dd8879bdb2f5b3ee0ba8d08cbbdcdfe870e695ce3784385/execnet-2.1.1-py3-none-any.whl#sha256=26dee51f1b80cebd6d0ca8e74dd8745419761d3bef34163928cbebbdc4749fdc -# pip fonttools @ https://files.pythonhosted.org/packages/f8/ad/c25116352f456c0d1287545a7aa24e98987b6d99c5b0456c4bd14321f20f/fonttools-4.57.0-cp313-cp313-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl#sha256=4dea5893b58d4637ffa925536462ba626f8a1b9ffbe2f5c272cdf2c6ebadb817 +# pip fonttools @ https://files.pythonhosted.org/packages/60/49/aaecb1b3cea2b9b9c7cea6240d6bc8090feb5489a6fbf93cb68003be979b/fonttools-4.58.0-cp313-cp313-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl#sha256=2ceef6f6ab58061a811967e3e32e630747fcb823dcc33a9a2c80e2d0d17cb292 # pip idna @ https://files.pythonhosted.org/packages/76/c6/c88e154df9c4e1a2a66ccf0005a88dfb2650c1dffb6f5ce603dfbd452ce3/idna-3.10-py3-none-any.whl#sha256=946d195a0d259cbba61165e88e65941f16e9b36ea6ddb97f00452bae8b1287d3 # pip imagesize @ https://files.pythonhosted.org/packages/ff/62/85c4c919272577931d407be5ba5d71c20f0b616d31a0befe0ae45bb79abd/imagesize-1.4.1-py2.py3-none-any.whl#sha256=0d8d18d08f840c19d0ee7ca1fd82490fdc3729b7ac93f49870406ddde8ef8d8b # pip iniconfig @ https://files.pythonhosted.org/packages/2c/e1/e6716421ea10d38022b952c159d5161ca1193197fb744506875fbb87ea7b/iniconfig-2.1.0-py3-none-any.whl#sha256=9deba5723312380e77435581c6bf4935c94cbfab9b1ed33ef8d238ea168eb760 -# pip joblib @ https://files.pythonhosted.org/packages/da/d3/13ee227a148af1c693654932b8b0b02ed64af5e1f7406d56b088b57574cd/joblib-1.5.0-py3-none-any.whl#sha256=206144b320246485b712fc8cc51f017de58225fa8b414a1fe1764a7231aca491 +# pip joblib @ https://files.pythonhosted.org/packages/7d/4f/1195bbac8e0c2acc5f740661631d8d750dc38d4a32b23ee5df3cde6f4e0d/joblib-1.5.1-py3-none-any.whl#sha256=4719a31f054c7d766948dcd83e9613686b27114f190f717cec7eaa2084f8a74a # pip kiwisolver @ https://files.pythonhosted.org/packages/8f/e9/6a7d025d8da8c4931522922cd706105aa32b3291d1add8c5427cdcd66e63/kiwisolver-1.4.8-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl#sha256=a5ce1e481a74b44dd5e92ff03ea0cb371ae7a0268318e202be06c8f04f4f1246 # pip markupsafe @ https://files.pythonhosted.org/packages/0c/91/96cf928db8236f1bfab6ce15ad070dfdd02ed88261c2afafd4b43575e9e9/MarkupSafe-3.0.2-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl#sha256=15ab75ef81add55874e7ab7055e9c397312385bd9ced94920f2802310c930396 -# pip meson @ https://files.pythonhosted.org/packages/df/d7/f1c8acf0e597d4d07532f519780ee6e11ba285a9b092f18706b4c9118331/meson-1.8.0-py3-none-any.whl#sha256=472b7b25da286447333d32872b82d1c6f1a34024fb8ee017d7308056c25fec1f +# pip meson @ https://files.pythonhosted.org/packages/46/77/726b14be352aa6911e206ca7c4d95c5be49660604dfee0bfed0fc75823e5/meson-1.8.1-py3-none-any.whl#sha256=374bbf71247e629475fc10b0bd2ef66fc418c2d8f4890572f74de0f97d0d42da # pip networkx @ https://files.pythonhosted.org/packages/b9/54/dd730b32ea14ea797530a4479b2ed46a6fb250f682a9cfb997e968bf0261/networkx-3.4.2-py3-none-any.whl#sha256=df5d4365b724cf81b8c6a7312509d0c22386097011ad1abe274afd5e9d3bbc5f # pip ninja @ https://files.pythonhosted.org/packages/eb/7a/455d2877fe6cf99886849c7f9755d897df32eaf3a0fba47b56e615f880f7/ninja-1.11.1.4-py3-none-manylinux_2_12_x86_64.manylinux2010_x86_64.whl#sha256=096487995473320de7f65d622c3f1d16c3ad174797602218ca8c967f51ec38a0 -# pip numpy @ https://files.pythonhosted.org/packages/aa/fc/ebfd32c3e124e6a1043e19c0ab0769818aa69050ce5589b63d05ff185526/numpy-2.2.5-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl#sha256=2ba321813a00e508d5421104464510cc962a6f791aa2fca1c97b1e65027da80d +# pip numpy @ https://files.pythonhosted.org/packages/19/49/4df9123aafa7b539317bf6d342cb6d227e49f7a35b99c287a6109b13dd93/numpy-2.2.6-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl#sha256=1bc23a79bfabc5d056d106f9befb8d50c31ced2fbc70eedb8155aec74a45798f # pip packaging @ https://files.pythonhosted.org/packages/20/12/38679034af332785aac8774540895e234f4d07f7545804097de4b666afd8/packaging-25.0-py3-none-any.whl#sha256=29572ef2b1f17581046b3a2227d5c611fb25ec70ca1ba8554b24b0e69331a484 # pip pillow @ https://files.pythonhosted.org/packages/13/eb/2552ecebc0b887f539111c2cd241f538b8ff5891b8903dfe672e997529be/pillow-11.2.1-cp313-cp313-manylinux_2_28_x86_64.whl#sha256=ad275964d52e2243430472fc5d2c2334b4fc3ff9c16cb0a19254e25efa03a155 -# pip pluggy @ https://files.pythonhosted.org/packages/88/5f/e351af9a41f866ac3f1fac4ca0613908d9a41741cfcf2228f4ad853b697d/pluggy-1.5.0-py3-none-any.whl#sha256=44e1ad92c8ca002de6377e165f3e0f1be63266ab4d554740532335b9d75ea669 +# pip pluggy @ https://files.pythonhosted.org/packages/54/20/4d324d65cc6d9205fabedc306948156824eb9f0ee1633355a8f7ec5c66bf/pluggy-1.6.0-py3-none-any.whl#sha256=e920276dd6813095e9377c0bc5566d94c932c33b27a3e3945d8389c374dd4746 # pip pygments @ https://files.pythonhosted.org/packages/8a/0b/9fcc47d19c48b59121088dd6da2488a49d5f72dacf8262e2790a1d2c7d15/pygments-2.19.1-py3-none-any.whl#sha256=9ea1544ad55cecf4b8242fab6dd35a93bbce657034b0611ee383099054ab6d8c # pip pyparsing @ https://files.pythonhosted.org/packages/05/e7/df2285f3d08fee213f2d041540fa4fc9ca6c2d44cf36d3a035bf2a8d2bcc/pyparsing-3.2.3-py3-none-any.whl#sha256=a749938e02d6fd0b59b356ca504a24982314bb090c383e3cf201c95ef7e2bfcf # pip pytz @ https://files.pythonhosted.org/packages/81/c4/34e93fe5f5429d7570ec1fa436f1986fb1f00c3e0f43a589fe2bbcd22c3f/pytz-2025.2-py2.py3-none-any.whl#sha256=5ddf76296dd8c44c26eb8f4b6f35488f3ccbf6fbbd7adee0b7262d43f0ec2f00 # pip roman-numerals-py @ https://files.pythonhosted.org/packages/53/97/d2cbbaa10c9b826af0e10fdf836e1bf344d9f0abb873ebc34d1f49642d3f/roman_numerals_py-3.1.0-py3-none-any.whl#sha256=9da2ad2fb670bcf24e81070ceb3be72f6c11c440d73bd579fbeca1e9f330954c # pip six @ https://files.pythonhosted.org/packages/b7/ce/149a00dd41f10bc29e5921b496af8b574d8413afcd5e30dfa0ed46c2cc5e/six-1.17.0-py2.py3-none-any.whl#sha256=4721f391ed90541fddacab5acf947aa0d3dc7d27b2e1e8eda2be8970586c3274 -# pip snowballstemmer @ https://files.pythonhosted.org/packages/ed/dc/c02e01294f7265e63a7315fe086dd1df7dacb9f840a804da846b96d01b96/snowballstemmer-2.2.0-py2.py3-none-any.whl#sha256=c8e1716e83cc398ae16824e5572ae04e0d9fc2c6b985fb0f900f5f0c96ecba1a +# pip snowballstemmer @ https://files.pythonhosted.org/packages/c8/78/3565d011c61f5a43488987ee32b6f3f656e7f107ac2782dd57bdd7d91d9a/snowballstemmer-3.0.1-py3-none-any.whl#sha256=6cd7b3897da8d6c9ffb968a6781fa6532dce9c3618a4b127d920dab764a19064 # pip sphinxcontrib-applehelp @ https://files.pythonhosted.org/packages/5d/85/9ebeae2f76e9e77b952f4b274c27238156eae7979c5421fba91a28f4970d/sphinxcontrib_applehelp-2.0.0-py3-none-any.whl#sha256=4cd3f0ec4ac5dd9c17ec65e9ab272c9b867ea77425228e68ecf08d6b28ddbdb5 # pip sphinxcontrib-devhelp @ https://files.pythonhosted.org/packages/35/7a/987e583882f985fe4d7323774889ec58049171828b58c2217e7f79cdf44e/sphinxcontrib_devhelp-2.0.0-py3-none-any.whl#sha256=aefb8b83854e4b0998877524d1029fd3e6879210422ee3780459e28a1f03a8a2 # pip sphinxcontrib-htmlhelp @ https://files.pythonhosted.org/packages/0a/7b/18a8c0bcec9182c05a0b3ec2a776bba4ead82750a55ff798e8d406dae604/sphinxcontrib_htmlhelp-2.1.0-py3-none-any.whl#sha256=166759820b47002d22914d64a075ce08f4c46818e17cfc9470a9786b759b19f8 @@ -76,16 +76,16 @@ https://repo.anaconda.com/pkgs/main/noarch/pip-25.1-pyhc872135_2.conda#2778327d2 # pip pytest @ https://files.pythonhosted.org/packages/30/3d/64ad57c803f1fa1e963a7946b6e0fea4a70df53c1a7fed304586539c2bac/pytest-8.3.5-py3-none-any.whl#sha256=c69214aa47deac29fad6c2a4f590b9c4a9fdb16a403176fe154b79c0b4d4d820 # pip python-dateutil @ https://files.pythonhosted.org/packages/ec/57/56b9bcc3c9c6a792fcbaf139543cee77261f3651ca9da0c93f5c1221264b/python_dateutil-2.9.0.post0-py2.py3-none-any.whl#sha256=a8b2bc7bffae282281c8140a97d3aa9c14da0b136dfe83f850eea9a5f7470427 # pip requests @ https://files.pythonhosted.org/packages/f9/9b/335f9764261e915ed497fcdeb11df5dfd6f7bf257d4a6a2a686d80da4d54/requests-2.32.3-py3-none-any.whl#sha256=70761cfe03c773ceb22aa2f671b4757976145175cdfca038c02654d061d6dcc6 -# pip scipy @ https://files.pythonhosted.org/packages/03/5a/fc34bf1aa14dc7c0e701691fa8685f3faec80e57d816615e3625f28feb43/scipy-1.15.2-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl#sha256=fb530e4794fc8ea76a4a21ccb67dea33e5e0e60f07fc38a49e821e1eae3b71a0 -# pip tifffile @ https://files.pythonhosted.org/packages/6e/be/10d23cfd4078fbec6aba768a357eff9e70c0b6d2a07398425985c524ad2a/tifffile-2025.3.30-py3-none-any.whl#sha256=0ed6eee7b66771db2d1bfc42262a51b01887505d35539daef118f4ff8c0f629c +# pip scipy @ https://files.pythonhosted.org/packages/b5/09/c5b6734a50ad4882432b6bb7c02baf757f5b2f256041da5df242e2d7e6b6/scipy-1.15.3-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl#sha256=c9deabd6d547aee2c9a81dee6cc96c6d7e9a9b1953f74850c179f91fdc729cb7 +# pip tifffile @ https://files.pythonhosted.org/packages/f5/34/59df6d47b6a8203e1db8f9a0585faf4cd68918e4a860f3bcb57909b6099f/tifffile-2025.5.24-py3-none-any.whl#sha256=2d913e41356425a2eeb4dc06dcc7286193cfa65ae1dedb5f51f04f60cf06713d # pip lightgbm @ https://files.pythonhosted.org/packages/42/86/dabda8fbcb1b00bcfb0003c3776e8ade1aa7b413dff0a2c08f457dace22f/lightgbm-4.6.0-py3-none-manylinux_2_28_x86_64.whl#sha256=cb19b5afea55b5b61cbb2131095f50538bd608a00655f23ad5d25ae3e3bf1c8d -# pip matplotlib @ https://files.pythonhosted.org/packages/51/d0/2bc4368abf766203e548dc7ab57cf7e9c621f1a3c72b516cc7715347b179/matplotlib-3.10.1-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl#sha256=7e496c01441be4c7d5f96d4e40f7fca06e20dcb40e44c8daa2e740e1757ad9e6 -# pip meson-python @ https://files.pythonhosted.org/packages/7d/ec/40c0ddd29ef4daa6689a2b9c5ced47d5b58fa54ae149b19e9a97f4979c8c/meson_python-0.17.1-py3-none-any.whl#sha256=30a75c52578ef14aff8392677b09c39346e0a24d2b2c6204b8ed30583c11269c +# pip matplotlib @ https://files.pythonhosted.org/packages/f5/64/41c4367bcaecbc03ef0d2a3ecee58a7065d0a36ae1aa817fe573a2da66d4/matplotlib-3.10.3-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl#sha256=a80fcccbef63302c0efd78042ea3c2436104c5b1a4d3ae20f864593696364ac7 +# pip meson-python @ https://files.pythonhosted.org/packages/28/58/66db620a8a7ccb32633de9f403fe49f1b63c68ca94e5c340ec5cceeb9821/meson_python-0.18.0-py3-none-any.whl#sha256=3b0fe051551cc238f5febb873247c0949cd60ded556efa130aa57021804868e2 # pip pandas @ https://files.pythonhosted.org/packages/e8/31/aa8da88ca0eadbabd0a639788a6da13bb2ff6edbbb9f29aa786450a30a91/pandas-2.2.3-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl#sha256=f3a255b2c19987fbbe62a9dfd6cff7ff2aa9ccab3fc75218fd4b7530f01efa24 # pip pyamg @ https://files.pythonhosted.org/packages/cd/a7/0df731cbfb09e73979a1a032fc7bc5be0eba617d798b998a0f887afe8ade/pyamg-5.2.1-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl#sha256=6999b351ab969c79faacb81faa74c0fa9682feeff3954979212872a3ee40c298 # pip pytest-cov @ https://files.pythonhosted.org/packages/28/d0/def53b4a790cfb21483016430ed828f64830dd981ebe1089971cd10cab25/pytest_cov-6.1.1-py3-none-any.whl#sha256=bddf29ed2d0ab6f4df17b4c55b0a657287db8684af9c42ea546b21b1041b3dde # pip pytest-xdist @ https://files.pythonhosted.org/packages/6d/82/1d96bf03ee4c0fdc3c0cbe61470070e659ca78dc0086fb88b66c185e2449/pytest_xdist-3.6.1-py3-none-any.whl#sha256=9ed4adfb68a016610848639bb7e02c9352d5d9f03d04809919e2dafc3be4cca7 # pip scikit-image @ https://files.pythonhosted.org/packages/cd/9b/c3da56a145f52cd61a68b8465d6a29d9503bc45bc993bb45e84371c97d94/scikit_image-0.25.2-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl#sha256=b8abd3c805ce6944b941cfed0406d88faeb19bab3ed3d4b50187af55cf24d147 # pip scipy-doctest @ https://files.pythonhosted.org/packages/76/eb/668949f884d5fe8a0d231dcba42c02e7b84626b35ca9072d6283c3aae773/scipy_doctest-1.7.1-py3-none-any.whl#sha256=dece106ec5ac8c595cc6372480d724e68c684450124dd0ddeb6be487ad62b365 -# pip sphinx @ https://files.pythonhosted.org/packages/2f/72/9a437a9dc5393c0eabba447bdb6233a7b02bb23e84975f17ad9a9ca86677/sphinx-8.3.0-py3-none-any.whl#sha256=bd8fcf35ab2c4240b01c74a411c948350a3aebd6aa175579363754ed380d350a +# pip sphinx @ https://files.pythonhosted.org/packages/31/53/136e9eca6e0b9dc0e1962e2c908fbea2e5ac000c2a2fbd9a35797958c48b/sphinx-8.2.3-py3-none-any.whl#sha256=4405915165f13521d875a8c29c8970800a0141c14cc5416a38feca4ea5d9b9c3 # pip numpydoc @ https://files.pythonhosted.org/packages/6c/45/56d99ba9366476cd8548527667f01869279cedb9e66b28eb4dfb27701679/numpydoc-1.8.0-py3-none-any.whl#sha256=72024c7fd5e17375dec3608a27c03303e8ad00c81292667955c6fea7a3ccf541 diff --git a/build_tools/azure/pylatest_pip_scipy_dev_linux-64_conda.lock b/build_tools/azure/pylatest_pip_scipy_dev_linux-64_conda.lock index 068aee47c99a3..4aa3536528c84 100644 --- a/build_tools/azure/pylatest_pip_scipy_dev_linux-64_conda.lock +++ b/build_tools/azure/pylatest_pip_scipy_dev_linux-64_conda.lock @@ -1,6 +1,6 @@ # Generated by conda-lock. # platform: linux-64 -# input_hash: 45bccf0e77c6967a2f49b8c304ef02337f7bd84c59e63221f8c0cb0e75dfe269 +# input_hash: 7555819e95d879c5a5147e6431581e17ffc5d77e8a43b19c8a911821378d2521 @EXPLICIT https://repo.anaconda.com/pkgs/main/linux-64/_libgcc_mutex-0.1-main.conda#c3473ff8bdb3d124ed5ff11ec380d6f9 https://repo.anaconda.com/pkgs/main/linux-64/ca-certificates-2025.2.25-h06a4308_0.conda#495015d24da8ad929e3ae2d18571016d @@ -32,22 +32,22 @@ https://repo.anaconda.com/pkgs/main/noarch/pip-25.1-pyhc872135_2.conda#2778327d2 # pip babel @ https://files.pythonhosted.org/packages/b7/b8/3fe70c75fe32afc4bb507f75563d39bc5642255d1d94f1f23604725780bf/babel-2.17.0-py3-none-any.whl#sha256=4d0b53093fdfb4b21c92b5213dba5a1b23885afa8383709427046b21c366e5f2 # pip certifi @ https://files.pythonhosted.org/packages/4a/7e/3db2bd1b1f9e95f7cddca6d6e75e2f2bd9f51b1246e546d88addca0106bd/certifi-2025.4.26-py3-none-any.whl#sha256=30350364dfe371162649852c63336a15c70c6510c2ad5015b21c2345311805f3 # pip charset-normalizer @ https://files.pythonhosted.org/packages/e2/28/ffc026b26f441fc67bd21ab7f03b313ab3fe46714a14b516f931abe1a2d8/charset_normalizer-3.4.2-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl#sha256=6c9379d65defcab82d07b2a9dfbfc2e95bc8fe0ebb1b176a3190230a3ef0e07c -# pip coverage @ https://files.pythonhosted.org/packages/cb/74/2f8cc196643b15bc096d60e073691dadb3dca48418f08bc78dd6e899383e/coverage-7.8.0-cp313-cp313-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl#sha256=5aaeb00761f985007b38cf463b1d160a14a22c34eb3f6a39d9ad6fc27cb73008 +# pip coverage @ https://files.pythonhosted.org/packages/89/60/f5f50f61b6332451520e6cdc2401700c48310c64bc2dd34027a47d6ab4ca/coverage-7.8.2-cp313-cp313-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl#sha256=dc67994df9bcd7e0150a47ef41278b9e0a0ea187caba72414b71dc590b99a108 # pip docutils @ https://files.pythonhosted.org/packages/8f/d7/9322c609343d929e75e7e5e6255e614fcc67572cfd083959cdef3b7aad79/docutils-0.21.2-py3-none-any.whl#sha256=dafca5b9e384f0e419294eb4d2ff9fa826435bf15f15b7bd45723e8ad76811b2 # pip execnet @ https://files.pythonhosted.org/packages/43/09/2aea36ff60d16dd8879bdb2f5b3ee0ba8d08cbbdcdfe870e695ce3784385/execnet-2.1.1-py3-none-any.whl#sha256=26dee51f1b80cebd6d0ca8e74dd8745419761d3bef34163928cbebbdc4749fdc # pip idna @ https://files.pythonhosted.org/packages/76/c6/c88e154df9c4e1a2a66ccf0005a88dfb2650c1dffb6f5ce603dfbd452ce3/idna-3.10-py3-none-any.whl#sha256=946d195a0d259cbba61165e88e65941f16e9b36ea6ddb97f00452bae8b1287d3 # pip imagesize @ https://files.pythonhosted.org/packages/ff/62/85c4c919272577931d407be5ba5d71c20f0b616d31a0befe0ae45bb79abd/imagesize-1.4.1-py2.py3-none-any.whl#sha256=0d8d18d08f840c19d0ee7ca1fd82490fdc3729b7ac93f49870406ddde8ef8d8b # pip iniconfig @ https://files.pythonhosted.org/packages/2c/e1/e6716421ea10d38022b952c159d5161ca1193197fb744506875fbb87ea7b/iniconfig-2.1.0-py3-none-any.whl#sha256=9deba5723312380e77435581c6bf4935c94cbfab9b1ed33ef8d238ea168eb760 # pip markupsafe @ https://files.pythonhosted.org/packages/0c/91/96cf928db8236f1bfab6ce15ad070dfdd02ed88261c2afafd4b43575e9e9/MarkupSafe-3.0.2-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl#sha256=15ab75ef81add55874e7ab7055e9c397312385bd9ced94920f2802310c930396 -# pip meson @ https://files.pythonhosted.org/packages/df/d7/f1c8acf0e597d4d07532f519780ee6e11ba285a9b092f18706b4c9118331/meson-1.8.0-py3-none-any.whl#sha256=472b7b25da286447333d32872b82d1c6f1a34024fb8ee017d7308056c25fec1f +# pip meson @ https://files.pythonhosted.org/packages/46/77/726b14be352aa6911e206ca7c4d95c5be49660604dfee0bfed0fc75823e5/meson-1.8.1-py3-none-any.whl#sha256=374bbf71247e629475fc10b0bd2ef66fc418c2d8f4890572f74de0f97d0d42da # pip ninja @ https://files.pythonhosted.org/packages/eb/7a/455d2877fe6cf99886849c7f9755d897df32eaf3a0fba47b56e615f880f7/ninja-1.11.1.4-py3-none-manylinux_2_12_x86_64.manylinux2010_x86_64.whl#sha256=096487995473320de7f65d622c3f1d16c3ad174797602218ca8c967f51ec38a0 # pip packaging @ https://files.pythonhosted.org/packages/20/12/38679034af332785aac8774540895e234f4d07f7545804097de4b666afd8/packaging-25.0-py3-none-any.whl#sha256=29572ef2b1f17581046b3a2227d5c611fb25ec70ca1ba8554b24b0e69331a484 -# pip platformdirs @ https://files.pythonhosted.org/packages/6d/45/59578566b3275b8fd9157885918fcd0c4d74162928a5310926887b856a51/platformdirs-4.3.7-py3-none-any.whl#sha256=a03875334331946f13c549dbd8f4bac7a13a50a895a0eb1e8c6a8ace80d40a94 -# pip pluggy @ https://files.pythonhosted.org/packages/88/5f/e351af9a41f866ac3f1fac4ca0613908d9a41741cfcf2228f4ad853b697d/pluggy-1.5.0-py3-none-any.whl#sha256=44e1ad92c8ca002de6377e165f3e0f1be63266ab4d554740532335b9d75ea669 +# pip platformdirs @ https://files.pythonhosted.org/packages/fe/39/979e8e21520d4e47a0bbe349e2713c0aac6f3d853d0e5b34d76206c439aa/platformdirs-4.3.8-py3-none-any.whl#sha256=ff7059bb7eb1179e2685604f4aaf157cfd9535242bd23742eadc3c13542139b4 +# pip pluggy @ https://files.pythonhosted.org/packages/54/20/4d324d65cc6d9205fabedc306948156824eb9f0ee1633355a8f7ec5c66bf/pluggy-1.6.0-py3-none-any.whl#sha256=e920276dd6813095e9377c0bc5566d94c932c33b27a3e3945d8389c374dd4746 # pip pygments @ https://files.pythonhosted.org/packages/8a/0b/9fcc47d19c48b59121088dd6da2488a49d5f72dacf8262e2790a1d2c7d15/pygments-2.19.1-py3-none-any.whl#sha256=9ea1544ad55cecf4b8242fab6dd35a93bbce657034b0611ee383099054ab6d8c # pip roman-numerals-py @ https://files.pythonhosted.org/packages/53/97/d2cbbaa10c9b826af0e10fdf836e1bf344d9f0abb873ebc34d1f49642d3f/roman_numerals_py-3.1.0-py3-none-any.whl#sha256=9da2ad2fb670bcf24e81070ceb3be72f6c11c440d73bd579fbeca1e9f330954c # pip six @ https://files.pythonhosted.org/packages/b7/ce/149a00dd41f10bc29e5921b496af8b574d8413afcd5e30dfa0ed46c2cc5e/six-1.17.0-py2.py3-none-any.whl#sha256=4721f391ed90541fddacab5acf947aa0d3dc7d27b2e1e8eda2be8970586c3274 -# pip snowballstemmer @ https://files.pythonhosted.org/packages/ed/dc/c02e01294f7265e63a7315fe086dd1df7dacb9f840a804da846b96d01b96/snowballstemmer-2.2.0-py2.py3-none-any.whl#sha256=c8e1716e83cc398ae16824e5572ae04e0d9fc2c6b985fb0f900f5f0c96ecba1a +# pip snowballstemmer @ https://files.pythonhosted.org/packages/c8/78/3565d011c61f5a43488987ee32b6f3f656e7f107ac2782dd57bdd7d91d9a/snowballstemmer-3.0.1-py3-none-any.whl#sha256=6cd7b3897da8d6c9ffb968a6781fa6532dce9c3618a4b127d920dab764a19064 # pip sphinxcontrib-applehelp @ https://files.pythonhosted.org/packages/5d/85/9ebeae2f76e9e77b952f4b274c27238156eae7979c5421fba91a28f4970d/sphinxcontrib_applehelp-2.0.0-py3-none-any.whl#sha256=4cd3f0ec4ac5dd9c17ec65e9ab272c9b867ea77425228e68ecf08d6b28ddbdb5 # pip sphinxcontrib-devhelp @ https://files.pythonhosted.org/packages/35/7a/987e583882f985fe4d7323774889ec58049171828b58c2217e7f79cdf44e/sphinxcontrib_devhelp-2.0.0-py3-none-any.whl#sha256=aefb8b83854e4b0998877524d1029fd3e6879210422ee3780459e28a1f03a8a2 # pip sphinxcontrib-htmlhelp @ https://files.pythonhosted.org/packages/0a/7b/18a8c0bcec9182c05a0b3ec2a776bba4ead82750a55ff798e8d406dae604/sphinxcontrib_htmlhelp-2.1.0-py3-none-any.whl#sha256=166759820b47002d22914d64a075ce08f4c46818e17cfc9470a9786b759b19f8 @@ -62,9 +62,9 @@ https://repo.anaconda.com/pkgs/main/noarch/pip-25.1-pyhc872135_2.conda#2778327d2 # pip pytest @ https://files.pythonhosted.org/packages/30/3d/64ad57c803f1fa1e963a7946b6e0fea4a70df53c1a7fed304586539c2bac/pytest-8.3.5-py3-none-any.whl#sha256=c69214aa47deac29fad6c2a4f590b9c4a9fdb16a403176fe154b79c0b4d4d820 # pip python-dateutil @ https://files.pythonhosted.org/packages/ec/57/56b9bcc3c9c6a792fcbaf139543cee77261f3651ca9da0c93f5c1221264b/python_dateutil-2.9.0.post0-py2.py3-none-any.whl#sha256=a8b2bc7bffae282281c8140a97d3aa9c14da0b136dfe83f850eea9a5f7470427 # pip requests @ https://files.pythonhosted.org/packages/f9/9b/335f9764261e915ed497fcdeb11df5dfd6f7bf257d4a6a2a686d80da4d54/requests-2.32.3-py3-none-any.whl#sha256=70761cfe03c773ceb22aa2f671b4757976145175cdfca038c02654d061d6dcc6 -# pip meson-python @ https://files.pythonhosted.org/packages/7d/ec/40c0ddd29ef4daa6689a2b9c5ced47d5b58fa54ae149b19e9a97f4979c8c/meson_python-0.17.1-py3-none-any.whl#sha256=30a75c52578ef14aff8392677b09c39346e0a24d2b2c6204b8ed30583c11269c +# pip meson-python @ https://files.pythonhosted.org/packages/28/58/66db620a8a7ccb32633de9f403fe49f1b63c68ca94e5c340ec5cceeb9821/meson_python-0.18.0-py3-none-any.whl#sha256=3b0fe051551cc238f5febb873247c0949cd60ded556efa130aa57021804868e2 # pip pooch @ https://files.pythonhosted.org/packages/a8/87/77cc11c7a9ea9fd05503def69e3d18605852cd0d4b0d3b8f15bbeb3ef1d1/pooch-1.8.2-py3-none-any.whl#sha256=3529a57096f7198778a5ceefd5ac3ef0e4d06a6ddaf9fc2d609b806f25302c47 # pip pytest-cov @ https://files.pythonhosted.org/packages/28/d0/def53b4a790cfb21483016430ed828f64830dd981ebe1089971cd10cab25/pytest_cov-6.1.1-py3-none-any.whl#sha256=bddf29ed2d0ab6f4df17b4c55b0a657287db8684af9c42ea546b21b1041b3dde # pip pytest-xdist @ https://files.pythonhosted.org/packages/6d/82/1d96bf03ee4c0fdc3c0cbe61470070e659ca78dc0086fb88b66c185e2449/pytest_xdist-3.6.1-py3-none-any.whl#sha256=9ed4adfb68a016610848639bb7e02c9352d5d9f03d04809919e2dafc3be4cca7 -# pip sphinx @ https://files.pythonhosted.org/packages/2f/72/9a437a9dc5393c0eabba447bdb6233a7b02bb23e84975f17ad9a9ca86677/sphinx-8.3.0-py3-none-any.whl#sha256=bd8fcf35ab2c4240b01c74a411c948350a3aebd6aa175579363754ed380d350a +# pip sphinx @ https://files.pythonhosted.org/packages/31/53/136e9eca6e0b9dc0e1962e2c908fbea2e5ac000c2a2fbd9a35797958c48b/sphinx-8.2.3-py3-none-any.whl#sha256=4405915165f13521d875a8c29c8970800a0141c14cc5416a38feca4ea5d9b9c3 # pip numpydoc @ https://files.pythonhosted.org/packages/6c/45/56d99ba9366476cd8548527667f01869279cedb9e66b28eb4dfb27701679/numpydoc-1.8.0-py3-none-any.whl#sha256=72024c7fd5e17375dec3608a27c03303e8ad00c81292667955c6fea7a3ccf541 diff --git a/build_tools/azure/pymin_conda_forge_mkl_win-64_conda.lock b/build_tools/azure/pymin_conda_forge_mkl_win-64_conda.lock index 051a5041f1138..98aa76361cb56 100644 --- a/build_tools/azure/pymin_conda_forge_mkl_win-64_conda.lock +++ b/build_tools/azure/pymin_conda_forge_mkl_win-64_conda.lock @@ -1,6 +1,6 @@ # Generated by conda-lock. # platform: win-64 -# input_hash: b3869076628274fd49d96cadc2692c963f26cbed79ec7498ecbfd50011a55e67 +# input_hash: cc5e2a711eb32773dc46fe159e1c3fe14f4fd07565fc8d3dedf2d748d4f2f694 @EXPLICIT https://conda.anaconda.org/conda-forge/noarch/font-ttf-dejavu-sans-mono-2.37-hab24e00_0.tar.bz2#0c96522c6bdaed4b1566d11387caaf45 https://conda.anaconda.org/conda-forge/noarch/font-ttf-inconsolata-3.000-h77eed37_0.tar.bz2#34893075a5c9e55cdafac56607368fc6 @@ -16,7 +16,7 @@ https://conda.anaconda.org/conda-forge/noarch/fonts-conda-forge-1-0.tar.bz2#f766 https://conda.anaconda.org/conda-forge/win-64/libwinpthread-12.0.0.r4.gg4f2fc60ca-h57928b3_9.conda#08bfa5da6e242025304b206d152479ef https://conda.anaconda.org/conda-forge/win-64/vc14_runtime-14.42.34438-hfd919c2_26.conda#91651a36d31aa20c7ba36299fb7068f4 https://conda.anaconda.org/conda-forge/noarch/fonts-conda-ecosystem-1-0.tar.bz2#fee5683a3f04bd15cbd8318b096a27ab -https://conda.anaconda.org/conda-forge/win-64/libgomp-14.2.0-h1383e82_2.conda#dd6b1ab49e28bcb6154cd131acec985b +https://conda.anaconda.org/conda-forge/win-64/libgomp-15.1.0-h1383e82_2.conda#5fbacaa9b41e294a6966602205b99747 https://conda.anaconda.org/conda-forge/win-64/vc-14.3-h2b53caa_26.conda#d3f0381e38093bde620a8d85f266ae55 https://conda.anaconda.org/conda-forge/win-64/_openmp_mutex-4.5-2_gnu.conda#37e16618af5c4851a3f3d66dd0e11141 https://conda.anaconda.org/conda-forge/win-64/bzip2-1.0.8-h2466b09_7.conda#276e7ffe9ffe39688abc665ef0f45596 @@ -25,13 +25,13 @@ https://conda.anaconda.org/conda-forge/win-64/graphite2-1.3.13-h63175ca_1003.con https://conda.anaconda.org/conda-forge/win-64/icu-75.1-he0c23c2_0.conda#8579b6bb8d18be7c0b27fb08adeeeb40 https://conda.anaconda.org/conda-forge/win-64/lerc-4.0.0-h6470a55_1.conda#c1b81da6d29a14b542da14a36c9fbf3f https://conda.anaconda.org/conda-forge/win-64/libbrotlicommon-1.1.0-h2466b09_2.conda#f7dc9a8f21d74eab46456df301da2972 -https://conda.anaconda.org/conda-forge/win-64/libdeflate-1.23-h76ddb4d_0.conda#34f03138e46543944d4d7f8538048842 +https://conda.anaconda.org/conda-forge/win-64/libdeflate-1.24-h76ddb4d_0.conda#08d988e266c6ae77e03d164b83786dc4 https://conda.anaconda.org/conda-forge/win-64/libexpat-2.7.0-he0c23c2_0.conda#b6f5352fdb525662f4169a0431d2dd7a https://conda.anaconda.org/conda-forge/win-64/libffi-3.4.6-h537db12_1.conda#85d8fa5e55ed8f93f874b3b23ed54ec6 https://conda.anaconda.org/conda-forge/win-64/libiconv-1.18-h135ad9c_1.conda#21fc5dba2cbcd8e5e26ff976a312122c https://conda.anaconda.org/conda-forge/win-64/libjpeg-turbo-3.1.0-h2466b09_0.conda#7c51d27540389de84852daa1cdb9c63c -https://conda.anaconda.org/conda-forge/win-64/liblzma-5.8.1-h2466b09_0.conda#8d5cb0016b645d6688e2ff57c5d51302 -https://conda.anaconda.org/conda-forge/win-64/libsqlite-3.49.1-h67fdade_2.conda#b58b66d4ad1aaf1c2543cbbd6afb1a59 +https://conda.anaconda.org/conda-forge/win-64/liblzma-5.8.1-h2466b09_1.conda#14a1042c163181e143a7522dfb8ad6ab +https://conda.anaconda.org/conda-forge/win-64/libsqlite-3.49.2-h67fdade_0.conda#a3900c97ba9e03332e9a911fe63f7d64 https://conda.anaconda.org/conda-forge/win-64/libwebp-base-1.5.0-h3b0e114_0.conda#33f7313967072c6e6d8f865f5493c7ae https://conda.anaconda.org/conda-forge/win-64/libzlib-1.3.1-h2466b09_2.conda#41fbfac52c601159df6c01f875de31b9 https://conda.anaconda.org/conda-forge/win-64/ninja-1.12.1-hc790b64_1.conda#3974c522f3248d4a93e6940c463d2de7 @@ -42,76 +42,77 @@ https://conda.anaconda.org/conda-forge/win-64/tk-8.6.13-h5226925_1.conda#fc04836 https://conda.anaconda.org/conda-forge/win-64/krb5-1.21.3-hdf4eb48_0.conda#31aec030344e962fbd7dbbbbd68e60a9 https://conda.anaconda.org/conda-forge/win-64/libbrotlidec-1.1.0-h2466b09_2.conda#9bae75ce723fa34e98e239d21d752a7e https://conda.anaconda.org/conda-forge/win-64/libbrotlienc-1.1.0-h2466b09_2.conda#85741a24d97954a991e55e34bc55990b -https://conda.anaconda.org/conda-forge/win-64/libgcc-14.2.0-h1383e82_2.conda#4a74c1461a0ba47a3346c04bdccbe2ad +https://conda.anaconda.org/conda-forge/win-64/libgcc-15.1.0-h1383e82_2.conda#9bedb24480136bfeb81ebc81d4285e70 https://conda.anaconda.org/conda-forge/win-64/libintl-0.22.5-h5728263_3.conda#2cf0cf76cc15d360dfa2f17fd6cf9772 https://conda.anaconda.org/conda-forge/win-64/libpng-1.6.47-h7a4582a_0.conda#ad620e92b82d2948bc019e029c574ebb -https://conda.anaconda.org/conda-forge/win-64/libxml2-2.13.7-h442d1da_1.conda#c14ff7f05e57489df9244917d2b55763 -https://conda.anaconda.org/conda-forge/win-64/pcre2-10.44-h99c9b8b_2.conda#a912b2c4ff0f03101c751aa79a331831 +https://conda.anaconda.org/conda-forge/win-64/libxml2-2.13.8-h442d1da_0.conda#833c2dbc1a5020007b520b044c713ed3 +https://conda.anaconda.org/conda-forge/win-64/pcre2-10.45-h99c9b8b_0.conda#f4c483274001678e129f5cbaf3a8d765 https://conda.anaconda.org/conda-forge/win-64/python-3.10.17-h8c5b53a_0_cpython.conda#0c59918f056ab2e9c7bb45970d32b2ea https://conda.anaconda.org/conda-forge/win-64/zstd-1.5.7-hbeecb71_2.conda#21f56217d6125fb30c3c3f10c786d751 https://conda.anaconda.org/conda-forge/win-64/brotli-bin-1.1.0-h2466b09_2.conda#d22534a9be5771fc58eb7564947f669d https://conda.anaconda.org/conda-forge/noarch/colorama-0.4.6-pyhd8ed1ab_1.conda#962b9857ee8e7018c22f2776ffa0b2d7 https://conda.anaconda.org/conda-forge/noarch/cycler-0.12.1-pyhd8ed1ab_1.conda#44600c4667a319d67dbe0681fc0bc833 -https://conda.anaconda.org/conda-forge/win-64/cython-3.0.12-py310h6bd2d47_0.conda#8b4e32766e91dfad20bdfd9747e66d54 -https://conda.anaconda.org/conda-forge/noarch/exceptiongroup-1.2.2-pyhd8ed1ab_1.conda#a16662747cdeb9abbac74d0057cc976e +https://conda.anaconda.org/conda-forge/win-64/cython-3.1.1-py310h6bd2d47_1.conda#165131d296d24f798fa76a26694d4565 https://conda.anaconda.org/conda-forge/noarch/execnet-2.1.1-pyhd8ed1ab_1.conda#a71efeae2c160f6789900ba2631a2c90 https://conda.anaconda.org/conda-forge/noarch/iniconfig-2.0.0-pyhd8ed1ab_1.conda#6837f3eff7dcea42ecd714ce1ac2b108 https://conda.anaconda.org/conda-forge/win-64/kiwisolver-1.4.7-py310hc19bc0b_0.conda#50d96539497fc7493cbe469fbb6b8b6e -https://conda.anaconda.org/conda-forge/win-64/libclang13-20.1.4-default_h6e92b77_0.conda#80c3ee2ffb5f35f2b6c4b10d636b04fb +https://conda.anaconda.org/conda-forge/win-64/libclang13-20.1.5-default_h6e92b77_1.conda#c5b6c1338035f155d15112a44d2de5f9 https://conda.anaconda.org/conda-forge/win-64/libfreetype6-2.13.3-h0b5ce68_1.conda#a84b7d1a13060a9372bea961a8131dbc -https://conda.anaconda.org/conda-forge/win-64/libglib-2.84.1-h7025463_0.conda#6cbaea9075a4f007eb7d0a90bb9a2a09 +https://conda.anaconda.org/conda-forge/win-64/libglib-2.84.2-hbc94333_0.conda#fee05801cc5db97bec20a5e78fb3905b https://conda.anaconda.org/conda-forge/win-64/libhwloc-2.11.2-default_ha69328c_1001.conda#b87a0ac5ab6495d8225db5dc72dd21cd -https://conda.anaconda.org/conda-forge/win-64/libtiff-4.7.0-h797046b_4.conda#7d938ca70c64c5516767b4eae0a56172 +https://conda.anaconda.org/conda-forge/win-64/libtiff-4.7.0-h05922d8_5.conda#75370aba951b47ec3b5bfe689f1bcf7f https://conda.anaconda.org/conda-forge/win-64/libxslt-1.1.39-h3df6e99_0.conda#279ee338c9b34871d578cb3c7aa68f70 -https://conda.anaconda.org/conda-forge/noarch/meson-1.8.0-pyh29332c3_0.conda#8e25221b702272394b86b0f4d7217f77 +https://conda.anaconda.org/conda-forge/noarch/meson-1.8.1-pyhe01879c_0.conda#f3cccd9a6ce5331ae33f69ade5529162 https://conda.anaconda.org/conda-forge/noarch/munkres-1.1.4-pyh9f0ad1d_0.tar.bz2#2ba8498c1018c1e9c61eb99b973dfe19 https://conda.anaconda.org/conda-forge/noarch/packaging-25.0-pyh29332c3_1.conda#58335b26c38bf4a20f399384c33cbcf9 -https://conda.anaconda.org/conda-forge/noarch/pluggy-1.5.0-pyhd8ed1ab_1.conda#e9dcbce5f45f9ee500e728ae58b605b6 +https://conda.anaconda.org/conda-forge/noarch/pluggy-1.6.0-pyhd8ed1ab_0.conda#7da7ccd349dbf6487a7778579d2bb971 https://conda.anaconda.org/conda-forge/win-64/pthread-stubs-0.4-h0e40799_1002.conda#3c8f2573569bb816483e5cf57efbbe29 https://conda.anaconda.org/conda-forge/noarch/pyparsing-3.2.3-pyhd8ed1ab_1.conda#513d3c262ee49b54a8fec85c5bc99764 -https://conda.anaconda.org/conda-forge/noarch/setuptools-80.1.0-pyhff2d567_0.conda#f6f72d0837c79eaec77661be43e8a691 +https://conda.anaconda.org/conda-forge/noarch/setuptools-80.8.0-pyhff2d567_0.conda#ea075e94dc0106c7212128b6a25bbc4c https://conda.anaconda.org/conda-forge/noarch/six-1.17.0-pyhd8ed1ab_0.conda#a451d576819089b0d672f18768be0f65 https://conda.anaconda.org/conda-forge/noarch/threadpoolctl-3.6.0-pyhecae5ae_0.conda#9d64911b31d57ca443e9f1e36b04385f https://conda.anaconda.org/conda-forge/noarch/toml-0.10.2-pyhd8ed1ab_1.conda#b0dd904de08b7db706167240bf37b164 https://conda.anaconda.org/conda-forge/noarch/tomli-2.2.1-pyhd8ed1ab_1.conda#ac944244f1fed2eb49bae07193ae8215 -https://conda.anaconda.org/conda-forge/win-64/tornado-6.4.2-py310ha8f682b_0.conda#e6819d3a0cae0f1b1838875f858421d1 +https://conda.anaconda.org/conda-forge/win-64/tornado-6.5.1-py310ha8f682b_0.conda#4c8f599990e386f3a0aba3f3bd8608da +https://conda.anaconda.org/conda-forge/noarch/typing_extensions-4.13.2-pyh29332c3_0.conda#83fc6ae00127671e301c9f44254c31b8 https://conda.anaconda.org/conda-forge/win-64/unicodedata2-16.0.0-py310ha8f682b_0.conda#b28aead44c6e19a1fbba7752aa242b34 https://conda.anaconda.org/conda-forge/noarch/wheel-0.45.1-pyhd8ed1ab_1.conda#75cb7132eb58d97896e173ef12ac9986 https://conda.anaconda.org/conda-forge/win-64/xorg-libxau-1.0.12-h0e40799_0.conda#2ffbfae4548098297c033228256eb96e https://conda.anaconda.org/conda-forge/win-64/xorg-libxdmcp-1.1.5-h0e40799_0.conda#8393c0f7e7870b4eb45553326f81f0ff https://conda.anaconda.org/conda-forge/win-64/brotli-1.1.0-h2466b09_2.conda#378f1c9421775dfe644731cb121c8979 -https://conda.anaconda.org/conda-forge/win-64/coverage-7.8.0-py310h38315fa_0.conda#30a825dae940c63c55bca8df4f806f3e -https://conda.anaconda.org/conda-forge/noarch/joblib-1.5.0-pyhd8ed1ab_0.conda#3d7257f0a61c9aa4ffa3e324a887416b +https://conda.anaconda.org/conda-forge/win-64/coverage-7.8.2-py310h38315fa_0.conda#5e09090744ab0b70b2882bc415c0d5ad +https://conda.anaconda.org/conda-forge/noarch/exceptiongroup-1.3.0-pyhd8ed1ab_0.conda#72e42d28960d875c7654614f8b50939a +https://conda.anaconda.org/conda-forge/noarch/joblib-1.5.1-pyhd8ed1ab_0.conda#fb1c14694de51a476ce8636d92b6f42c https://conda.anaconda.org/conda-forge/win-64/lcms2-2.17-hbcf6048_0.conda#3538827f77b82a837fa681a4579e37a1 https://conda.anaconda.org/conda-forge/win-64/libfreetype-2.13.3-h57928b3_1.conda#410ba2c8e7bdb278dfbb5d40220e39d2 https://conda.anaconda.org/conda-forge/win-64/libxcb-1.17.0-h0e4246c_0.conda#a69bbf778a462da324489976c84cfc8c https://conda.anaconda.org/conda-forge/win-64/openjpeg-2.5.3-h4d64b90_0.conda#fc050366dd0b8313eb797ed1ffef3a29 https://conda.anaconda.org/conda-forge/noarch/pip-25.1.1-pyh8b19718_0.conda#32d0781ace05105cc99af55d36cbec7c https://conda.anaconda.org/conda-forge/noarch/pyproject-metadata-0.9.1-pyhd8ed1ab_0.conda#22ae7c6ea81e0c8661ef32168dda929b -https://conda.anaconda.org/conda-forge/noarch/pytest-8.3.5-pyhd8ed1ab_0.conda#c3c9316209dec74a705a36797970c6be https://conda.anaconda.org/conda-forge/noarch/python-dateutil-2.9.0.post0-pyhff2d567_1.conda#5ba79d7c71f03c678c8ead841f347d6e https://conda.anaconda.org/conda-forge/win-64/tbb-2021.13.0-h62715c5_1.conda#9190dd0a23d925f7602f9628b3aed511 -https://conda.anaconda.org/conda-forge/win-64/fonttools-4.57.0-py310h38315fa_0.conda#1f25f742c39582715cc058f5fe451975 +https://conda.anaconda.org/conda-forge/win-64/fonttools-4.58.0-py310h38315fa_0.conda#87b6ddf29c7ee0e327f76c546edb3346 https://conda.anaconda.org/conda-forge/win-64/freetype-2.13.3-h57928b3_1.conda#633504fe3f96031192e40e3e6c18ef06 -https://conda.anaconda.org/conda-forge/noarch/meson-python-0.17.1-pyh70fd9c4_1.conda#7a02679229c6c2092571b4c025055440 +https://conda.anaconda.org/conda-forge/noarch/meson-python-0.18.0-pyh70fd9c4_0.conda#576c04b9d9f8e45285fb4d9452c26133 https://conda.anaconda.org/conda-forge/win-64/mkl-2024.2.2-h66d3029_15.conda#302dff2807f2927b3e9e0d19d60121de -https://conda.anaconda.org/conda-forge/noarch/pytest-cov-6.1.1-pyhd8ed1ab_0.conda#1e35d8f975bc0e984a19819aa91c440a -https://conda.anaconda.org/conda-forge/noarch/pytest-xdist-3.6.1-pyhd8ed1ab_1.conda#59aad4fb37cabc0bacc73cf344612ddd +https://conda.anaconda.org/conda-forge/win-64/pillow-11.2.1-py310h9595edc_0.conda#33d0663d469cc146b5fc68587348f450 +https://conda.anaconda.org/conda-forge/noarch/pytest-8.3.5-pyhd8ed1ab_0.conda#c3c9316209dec74a705a36797970c6be https://conda.anaconda.org/conda-forge/win-64/fontconfig-2.15.0-h765892d_1.conda#9bb0026a2131b09404c59c4290c697cd https://conda.anaconda.org/conda-forge/win-64/libblas-3.9.0-31_h641d27c_mkl.conda#d05563c577fe2f37693a554b3f271e8f https://conda.anaconda.org/conda-forge/win-64/mkl-devel-2024.2.2-h57928b3_15.conda#a85f53093da069c7c657f090e388f3ef -https://conda.anaconda.org/conda-forge/win-64/pillow-11.1.0-py310h9595edc_0.conda#67a38507ac20bd85226fe6dd7ed87462 +https://conda.anaconda.org/conda-forge/noarch/pytest-cov-6.1.1-pyhd8ed1ab_0.conda#1e35d8f975bc0e984a19819aa91c440a +https://conda.anaconda.org/conda-forge/noarch/pytest-xdist-3.6.1-pyhd8ed1ab_1.conda#59aad4fb37cabc0bacc73cf344612ddd https://conda.anaconda.org/conda-forge/win-64/cairo-1.18.4-h5782bbf_0.conda#20e32ced54300292aff690a69c5e7b97 https://conda.anaconda.org/conda-forge/win-64/libcblas-3.9.0-31_h5e41251_mkl.conda#43c100b94ad2607382b0cf0f3a6b0bf3 https://conda.anaconda.org/conda-forge/win-64/liblapack-3.9.0-31_h1aa476e_mkl.conda#40b47ee720a185289760960fc6185750 -https://conda.anaconda.org/conda-forge/win-64/harfbuzz-11.1.0-h8796e6f_0.conda#dcc4a63f231cc52197c558f5e07e0a69 +https://conda.anaconda.org/conda-forge/win-64/harfbuzz-11.2.1-h8796e6f_0.conda#bccea58fbf7910ce868b084f27ffe8bd https://conda.anaconda.org/conda-forge/win-64/liblapacke-3.9.0-31_h845c4fa_mkl.conda#003a2041cb07a7cf698f48dd26301273 -https://conda.anaconda.org/conda-forge/win-64/numpy-2.2.5-py310h4987827_0.conda#19e9c5868faa8046020ce870a9a9d0fc +https://conda.anaconda.org/conda-forge/win-64/numpy-2.2.6-py310h4987827_0.conda#d2596785ac2cf5bab04e2ee9e5d04041 https://conda.anaconda.org/conda-forge/win-64/blas-devel-3.9.0-31_hfb1a452_mkl.conda#0deeb3d9d6f0e56393c55ef382899010 https://conda.anaconda.org/conda-forge/win-64/contourpy-1.3.2-py310hc19bc0b_0.conda#039416813b5290e7d100a05bb4326110 -https://conda.anaconda.org/conda-forge/win-64/qt6-main-6.9.0-h83cda92_1.conda#412f970fc305449b6ee626fe9c6638a8 +https://conda.anaconda.org/conda-forge/win-64/qt6-main-6.9.0-h02ddd7d_3.conda#8aeebdf27e439648236c3eb856ce7777 https://conda.anaconda.org/conda-forge/win-64/scipy-1.15.2-py310h15c175c_0.conda#81798168111d1021e3d815217c444418 https://conda.anaconda.org/conda-forge/win-64/blas-2.131-mkl.conda#1842bfaa4e349875c47bde1d9871bda6 -https://conda.anaconda.org/conda-forge/win-64/matplotlib-base-3.10.1-py310h37e0a56_0.conda#1b78c5c0741473537e39e425ff30ea80 +https://conda.anaconda.org/conda-forge/win-64/matplotlib-base-3.10.3-py310h37e0a56_0.conda#de9ddae6f97b78860c256de480ea1a84 https://conda.anaconda.org/conda-forge/win-64/pyside6-6.9.0-py310hc1b6536_0.conda#e90c8d8a817b5d63b7785d7d18c99ae0 -https://conda.anaconda.org/conda-forge/win-64/matplotlib-3.10.1-py310h5588dad_0.conda#246bfc9ca36dccad2d78a020ab8d2aab +https://conda.anaconda.org/conda-forge/win-64/matplotlib-3.10.3-py310h5588dad_0.conda#103adee33db124a0263d0b4551e232e3 diff --git a/build_tools/azure/pymin_conda_forge_openblas_min_dependencies_linux-64_conda.lock b/build_tools/azure/pymin_conda_forge_openblas_min_dependencies_linux-64_conda.lock index 5d0b23f9e2f41..36f45c7e0dc7e 100644 --- a/build_tools/azure/pymin_conda_forge_openblas_min_dependencies_linux-64_conda.lock +++ b/build_tools/azure/pymin_conda_forge_openblas_min_dependencies_linux-64_conda.lock @@ -1,6 +1,6 @@ # Generated by conda-lock. # platform: linux-64 -# input_hash: fbba4fe2a9e1ebfa6e5d79269f12618306ade6ba86f95bb43c9719cd8dbe0e38 +# input_hash: 41111e5656d9d33f83f1160f643ec4ab314aa8e179923dbe1350c87b0ac2f400 @EXPLICIT https://conda.anaconda.org/conda-forge/noarch/font-ttf-dejavu-sans-mono-2.37-hab24e00_0.tar.bz2#0c96522c6bdaed4b1566d11387caaf45 https://conda.anaconda.org/conda-forge/noarch/font-ttf-inconsolata-3.000-h77eed37_0.tar.bz2#34893075a5c9e55cdafac56607368fc6 @@ -12,27 +12,28 @@ https://conda.anaconda.org/conda-forge/noarch/ca-certificates-2025.4.26-hbd8a1cb https://conda.anaconda.org/conda-forge/noarch/fonts-conda-forge-1-0.tar.bz2#f766549260d6815b0c52253f1fb1bb29 https://conda.anaconda.org/conda-forge/linux-64/ld_impl_linux-64-2.43-h712a8e2_4.conda#01f8d123c96816249efd255a31ad7712 https://conda.anaconda.org/conda-forge/linux-64/libglvnd-1.7.0-ha4b6fd6_2.conda#434ca7e50e40f4918ab701e3facd59a0 -https://conda.anaconda.org/conda-forge/linux-64/llvm-openmp-20.1.4-h024ca30_0.conda#4fc395cda27912a7d904b86b5dbf3a4d +https://conda.anaconda.org/conda-forge/linux-64/llvm-openmp-20.1.5-h024ca30_0.conda#86f58be65a51d62ccc06cacfd83ff987 https://conda.anaconda.org/conda-forge/linux-64/_openmp_mutex-4.5-3_kmp_llvm.conda#ee5c2118262e30b972bc0b4db8ef0ba5 https://conda.anaconda.org/conda-forge/noarch/fonts-conda-ecosystem-1-0.tar.bz2#fee5683a3f04bd15cbd8318b096a27ab https://conda.anaconda.org/conda-forge/linux-64/libegl-1.7.0-ha4b6fd6_2.conda#c151d5eb730e9b7480e6d48c0fc44048 -https://conda.anaconda.org/conda-forge/linux-64/libgcc-14.2.0-h767d61c_2.conda#ef504d1acbd74b7cc6849ef8af47dd03 +https://conda.anaconda.org/conda-forge/linux-64/libopengl-1.7.0-ha4b6fd6_2.conda#7df50d44d4a14d6c31a2c54f2cd92157 +https://conda.anaconda.org/conda-forge/linux-64/libgcc-15.1.0-h767d61c_2.conda#ea8ac52380885ed41c1baa8f1d6d2b93 https://conda.anaconda.org/conda-forge/linux-64/alsa-lib-1.2.14-hb9d3cd8_0.conda#76df83c2a9035c54df5d04ff81bcc02d https://conda.anaconda.org/conda-forge/linux-64/gettext-tools-0.24.1-h5888daf_0.conda#d54305672f0361c2f3886750e7165b5f https://conda.anaconda.org/conda-forge/linux-64/libbrotlicommon-1.1.0-hb9d3cd8_2.conda#41b599ed2b02abcfdd84302bff174b23 -https://conda.anaconda.org/conda-forge/linux-64/libdeflate-1.23-h86f0d12_0.conda#27fe770decaf469a53f3e3a6d593067f +https://conda.anaconda.org/conda-forge/linux-64/libdeflate-1.24-h86f0d12_0.conda#64f0c503da58ec25ebd359e4d990afa8 https://conda.anaconda.org/conda-forge/linux-64/libexpat-2.7.0-h5888daf_0.conda#db0bfbe7dd197b68ad5f30333bae6ce0 https://conda.anaconda.org/conda-forge/linux-64/libffi-3.4.6-h2dba641_1.conda#ede4673863426c0883c0063d853bbd85 -https://conda.anaconda.org/conda-forge/linux-64/libgcc-ng-14.2.0-h69a702a_2.conda#a2222a6ada71fb478682efe483ce0f92 +https://conda.anaconda.org/conda-forge/linux-64/libgcc-ng-15.1.0-h69a702a_2.conda#ddca86c7040dd0e73b2b69bd7833d225 https://conda.anaconda.org/conda-forge/linux-64/libgettextpo-0.24.1-h5888daf_0.conda#2ee6d71b72f75d50581f2f68e965efdb -https://conda.anaconda.org/conda-forge/linux-64/libgfortran5-14.2.0-hf1ad2bd_2.conda#556a4fdfac7287d349b8f09aba899693 +https://conda.anaconda.org/conda-forge/linux-64/libgfortran5-15.1.0-hcea5267_2.conda#01de444988ed960031dbe84cf4f9b1fc https://conda.anaconda.org/conda-forge/linux-64/libiconv-1.18-h4ce23a2_1.conda#e796ff8ddc598affdf7c173d6145f087 https://conda.anaconda.org/conda-forge/linux-64/libjpeg-turbo-3.1.0-hb9d3cd8_0.conda#9fa334557db9f63da6c9285fd2a48638 -https://conda.anaconda.org/conda-forge/linux-64/liblzma-5.8.1-hb9d3cd8_0.conda#0e87378639676987af32fee53ba32258 +https://conda.anaconda.org/conda-forge/linux-64/liblzma-5.8.1-hb9d3cd8_1.conda#a76fd702c93cd2dfd89eff30a5fd45a8 https://conda.anaconda.org/conda-forge/linux-64/libntlm-1.8-hb9d3cd8_0.conda#7c7927b404672409d9917d49bff5f2d6 https://conda.anaconda.org/conda-forge/linux-64/libogg-1.3.5-hd0c01bc_1.conda#68e52064ed3897463c0e958ab5c8f91b https://conda.anaconda.org/conda-forge/linux-64/libopus-1.5.2-hd0c01bc_0.conda#b64523fb87ac6f87f0790f324ad43046 -https://conda.anaconda.org/conda-forge/linux-64/libstdcxx-14.2.0-h8f9b012_2.conda#a78c856b6dc6bf4ea8daeb9beaaa3fb0 +https://conda.anaconda.org/conda-forge/linux-64/libstdcxx-15.1.0-h8f9b012_2.conda#1cb1c67961f6dd257eae9e9691b341aa https://conda.anaconda.org/conda-forge/linux-64/libwebp-base-1.5.0-h851e524_0.conda#63f790534398730f59e1b899c3644d4a https://conda.anaconda.org/conda-forge/linux-64/libzlib-1.3.1-hb9d3cd8_2.conda#edb0dca6bc32e4f4789199455a1dbeb8 https://conda.anaconda.org/conda-forge/linux-64/ncurses-6.5-h2d0b736_3.conda#47e340acb35de30501a76c7c799c41d7 @@ -44,7 +45,6 @@ https://conda.anaconda.org/conda-forge/linux-64/xorg-libxdmcp-1.1.5-hb9d3cd8_0.c https://conda.anaconda.org/conda-forge/linux-64/xorg-libxshmfence-1.3.3-hb9d3cd8_0.conda#9a809ce9f65460195777f2f2116bae02 https://conda.anaconda.org/conda-forge/linux-64/attr-2.5.1-h166bdaf_1.tar.bz2#d9c69a24ad678ffce24c6543a0176b00 https://conda.anaconda.org/conda-forge/linux-64/bzip2-1.0.8-h4bc722e_7.conda#62ee74e96c5ebb0af99386de58cf9553 -https://conda.anaconda.org/conda-forge/linux-64/expat-2.7.0-h5888daf_0.conda#d6845ae4dea52a2f90178bf1829a21f8 https://conda.anaconda.org/conda-forge/linux-64/keyutils-1.6.1-h166bdaf_0.tar.bz2#30186d27e2c9fa62b45fb1476b7200e3 https://conda.anaconda.org/conda-forge/linux-64/lame-3.100-h166bdaf_1003.tar.bz2#a8832b479f93521a9e7b5b743803be51 https://conda.anaconda.org/conda-forge/linux-64/lerc-4.0.0-h0aef613_1.conda#9344155d33912347b37f0ae6c410a835 @@ -54,19 +54,18 @@ https://conda.anaconda.org/conda-forge/linux-64/libbrotlienc-1.1.0-hb9d3cd8_2.co https://conda.anaconda.org/conda-forge/linux-64/libedit-3.1.20250104-pl5321h7949ede_0.conda#c277e0a4d549b03ac1e9d6cbbe3d017b https://conda.anaconda.org/conda-forge/linux-64/libevent-2.1.12-hf998b51_1.conda#a1cfcc585f0c42bf8d5546bb1dfb668d https://conda.anaconda.org/conda-forge/linux-64/libgettextpo-devel-0.24.1-h5888daf_0.conda#8f04c7aae6a46503bc36d1ed5abc8c7c -https://conda.anaconda.org/conda-forge/linux-64/libgfortran-14.2.0-h69a702a_2.conda#fb54c4ea68b460c278d26eea89cfbcc3 +https://conda.anaconda.org/conda-forge/linux-64/libgfortran-15.1.0-h69a702a_2.conda#f92e6e0a3c0c0c85561ef61aa59d555d https://conda.anaconda.org/conda-forge/linux-64/libgpg-error-1.55-h3f2d84a_0.conda#2bd47db5807daade8500ed7ca4c512a4 https://conda.anaconda.org/conda-forge/linux-64/libnsl-2.0.1-hd590300_0.conda#30fd6e37fe21f86f4bd26d6ee73eeec7 https://conda.anaconda.org/conda-forge/linux-64/libpciaccess-0.18-hd590300_0.conda#48f4330bfcd959c3cfb704d424903c82 https://conda.anaconda.org/conda-forge/linux-64/libpng-1.6.47-h943b412_0.conda#55199e2ae2c3651f6f9b2a447b47bdc9 -https://conda.anaconda.org/conda-forge/linux-64/libsqlite-3.49.1-hee588c1_2.conda#962d6ac93c30b1dfc54c9cccafd1003e -https://conda.anaconda.org/conda-forge/linux-64/libstdcxx-ng-14.2.0-h4852527_2.conda#c75da67f045c2627f59e6fcb5f4e3a9b +https://conda.anaconda.org/conda-forge/linux-64/libsqlite-3.49.2-hee588c1_0.conda#93048463501053a00739215ea3f36324 +https://conda.anaconda.org/conda-forge/linux-64/libstdcxx-ng-15.1.0-h4852527_2.conda#9d2072af184b5caa29492bf2344597bb https://conda.anaconda.org/conda-forge/linux-64/libuuid-2.38.1-h0b41bf4_0.conda#40b61aab5c7ba9ff276c41cfffe6b80b https://conda.anaconda.org/conda-forge/linux-64/libxcb-1.17.0-h8a09558_0.conda#92ed62436b625154323d40d5f2f11dd7 https://conda.anaconda.org/conda-forge/linux-64/libxcrypt-4.4.36-hd590300_1.conda#5aa797f8787fe7a17d1b0821485b5adc https://conda.anaconda.org/conda-forge/linux-64/lz4-c-1.10.0-h5888daf_1.conda#9de5350a85c4a20c685259b889aa6393 https://conda.anaconda.org/conda-forge/linux-64/mpg123-1.32.9-hc50e24c_0.conda#c7f302fd11eeb0987a6a5e1f3aed6a21 -https://conda.anaconda.org/conda-forge/linux-64/mysql-common-9.0.1-h266115a_6.conda#94116b69829e90b72d566e64421e1bff https://conda.anaconda.org/conda-forge/linux-64/ninja-1.12.1-hff21bea_1.conda#2322531904f27501ee19847b87ba7c64 https://conda.anaconda.org/conda-forge/linux-64/nspr-4.36-h5888daf_0.conda#de9cd5bca9e4918527b9b72b6e2e1409 https://conda.anaconda.org/conda-forge/linux-64/pixman-0.46.0-h29eaf8c_0.conda#d2f1c87d4416d1e7344cf92b1aaee1c4 @@ -81,12 +80,11 @@ https://conda.anaconda.org/conda-forge/linux-64/libasprintf-devel-0.24.1-h8e693c https://conda.anaconda.org/conda-forge/linux-64/libcap-2.75-h39aace5_0.conda#c44c16d6976d2aebbd65894d7741e67e https://conda.anaconda.org/conda-forge/linux-64/libdrm-2.4.124-hb9d3cd8_0.conda#8bc89311041d7fcb510238cf0848ccae https://conda.anaconda.org/conda-forge/linux-64/libfreetype6-2.13.3-h48d6fc4_1.conda#3c255be50a506c50765a93a6644f32fe -https://conda.anaconda.org/conda-forge/linux-64/libgcrypt-lib-1.11.0-hb9d3cd8_2.conda#e55712ff40a054134d51b89afca57dbc -https://conda.anaconda.org/conda-forge/linux-64/libgfortran-ng-14.2.0-h69a702a_2.conda#4056c857af1a99ee50589a941059ec55 -https://conda.anaconda.org/conda-forge/linux-64/libtiff-4.7.0-hd9ff511_4.conda#6c1028898cf3a2032d9af46689e1b81a +https://conda.anaconda.org/conda-forge/linux-64/libgcrypt-lib-1.11.1-hb9d3cd8_0.conda#8504a291085c9fb809b66cabd5834307 +https://conda.anaconda.org/conda-forge/linux-64/libgfortran-ng-15.1.0-h69a702a_2.conda#a483a87b71e974bb75d1b9413d4436dd +https://conda.anaconda.org/conda-forge/linux-64/libtiff-4.7.0-hf01ce69_5.conda#e79a094918988bb1807462cd42c83962 https://conda.anaconda.org/conda-forge/linux-64/libvorbis-1.3.7-h9c3ff4c_0.tar.bz2#309dec04b70a3cc0f1e84a4013683bc0 -https://conda.anaconda.org/conda-forge/linux-64/mysql-libs-9.0.1-he0572af_6.conda#9802ae6d20982f42c0f5d69008988763 -https://conda.anaconda.org/conda-forge/linux-64/nss-3.110-h159eef7_0.conda#945659af183e87429c8aa7e0be3cc91d +https://conda.anaconda.org/conda-forge/linux-64/nss-3.111-h159eef7_0.conda#311e8370c9db254611ec87250f6370a0 https://conda.anaconda.org/conda-forge/linux-64/pcre2-10.45-hc749103_0.conda#b90bece58b4c2bf25969b70f3be42d25 https://conda.anaconda.org/conda-forge/linux-64/python-3.10.17-hd6af730_0_cpython.conda#7bb89638dae9ce1b8e051d0b721e83c2 https://conda.anaconda.org/conda-forge/linux-64/xcb-util-0.4.1-hb711507_2.conda#8637c3e5821654d0edf97e2b0404b443 @@ -96,12 +94,11 @@ https://conda.anaconda.org/conda-forge/linux-64/xcb-util-wm-0.4.2-hb711507_0.con https://conda.anaconda.org/conda-forge/linux-64/xorg-libsm-1.2.6-he73a12e_0.conda#1c74ff8c35dcadf952a16f752ca5aa49 https://conda.anaconda.org/conda-forge/linux-64/xorg-libx11-1.8.12-h4f16b4b_0.conda#db038ce880f100acc74dba10302b5630 https://conda.anaconda.org/conda-forge/linux-64/brotli-1.1.0-hb9d3cd8_2.conda#98514fe74548d768907ce7a13f680e8f -https://conda.anaconda.org/conda-forge/noarch/certifi-2025.1.31-pyhd8ed1ab_0.conda#c207fa5ac7ea99b149344385a9c0880d +https://conda.anaconda.org/conda-forge/noarch/certifi-2025.4.26-pyhd8ed1ab_0.conda#c33eeaaa33f45031be34cda513df39b6 https://conda.anaconda.org/conda-forge/noarch/colorama-0.4.6-pyhd8ed1ab_1.conda#962b9857ee8e7018c22f2776ffa0b2d7 https://conda.anaconda.org/conda-forge/noarch/cycler-0.12.1-pyhd8ed1ab_1.conda#44600c4667a319d67dbe0681fc0bc833 https://conda.anaconda.org/conda-forge/linux-64/cyrus-sasl-2.1.27-h54b06d7_7.conda#dce22f70b4e5a407ce88f2be046f4ceb https://conda.anaconda.org/conda-forge/linux-64/cython-3.0.10-py310hc6cd4ac_0.conda#bd1d71ee240be36f1d85c86177d6964f -https://conda.anaconda.org/conda-forge/noarch/exceptiongroup-1.2.2-pyhd8ed1ab_1.conda#a16662747cdeb9abbac74d0057cc976e https://conda.anaconda.org/conda-forge/noarch/execnet-2.1.1-pyhd8ed1ab_1.conda#a71efeae2c160f6789900ba2631a2c90 https://conda.anaconda.org/conda-forge/linux-64/gettext-0.24.1-h5888daf_0.conda#c63e7590d4d6f4c85721040ed8b12888 https://conda.anaconda.org/conda-forge/noarch/iniconfig-2.0.0-pyhd8ed1ab_1.conda#6837f3eff7dcea42ecd714ce1ac2b108 @@ -109,26 +106,26 @@ https://conda.anaconda.org/conda-forge/linux-64/kiwisolver-1.4.7-py310h3788b33_0 https://conda.anaconda.org/conda-forge/linux-64/lcms2-2.17-h717163a_0.conda#000e85703f0fd9594c81710dd5066471 https://conda.anaconda.org/conda-forge/linux-64/libcups-2.3.3-h4637d8d_4.conda#d4529f4dff3057982a7617c7ac58fde3 https://conda.anaconda.org/conda-forge/linux-64/libfreetype-2.13.3-ha770c72_1.conda#51f5be229d83ecd401fb369ab96ae669 -https://conda.anaconda.org/conda-forge/linux-64/libglib-2.84.1-h3618099_1.conda#714c97d4ff495ab69d1fdfcadbcae985 +https://conda.anaconda.org/conda-forge/linux-64/libglib-2.84.2-h3618099_0.conda#072ab14a02164b7c0c089055368ff776 https://conda.anaconda.org/conda-forge/linux-64/libglx-1.7.0-ha4b6fd6_2.conda#c8013e438185f33b13814c5c488acd5c https://conda.anaconda.org/conda-forge/linux-64/libhiredis-1.0.2-h2cc385e_0.tar.bz2#b34907d3a81a3cd8095ee83d174c074a https://conda.anaconda.org/conda-forge/linux-64/libopenblas-0.3.25-pthreads_h413a1c8_0.conda#d172b34a443b95f86089e8229ddc9a17 https://conda.anaconda.org/conda-forge/linux-64/libsystemd0-257.4-h4e0b6ca_1.conda#04bcf3055e51f8dde6fab9672fb9fca0 -https://conda.anaconda.org/conda-forge/linux-64/libxml2-2.13.7-h4bc477f_1.conda#ad1f1f8238834cd3c88ceeaee8da444a -https://conda.anaconda.org/conda-forge/noarch/meson-1.8.0-pyh29332c3_0.conda#8e25221b702272394b86b0f4d7217f77 +https://conda.anaconda.org/conda-forge/linux-64/libxml2-2.13.8-h4bc477f_0.conda#14dbe05b929e329dbaa6f2d0aa19466d +https://conda.anaconda.org/conda-forge/noarch/meson-1.8.1-pyhe01879c_0.conda#f3cccd9a6ce5331ae33f69ade5529162 https://conda.anaconda.org/conda-forge/noarch/munkres-1.1.4-pyh9f0ad1d_0.tar.bz2#2ba8498c1018c1e9c61eb99b973dfe19 https://conda.anaconda.org/conda-forge/linux-64/openjpeg-2.5.3-h5fbd93e_0.conda#9e5816bc95d285c115a3ebc2f8563564 https://conda.anaconda.org/conda-forge/noarch/packaging-25.0-pyh29332c3_1.conda#58335b26c38bf4a20f399384c33cbcf9 -https://conda.anaconda.org/conda-forge/noarch/pluggy-1.5.0-pyhd8ed1ab_1.conda#e9dcbce5f45f9ee500e728ae58b605b6 +https://conda.anaconda.org/conda-forge/noarch/pluggy-1.6.0-pyhd8ed1ab_0.conda#7da7ccd349dbf6487a7778579d2bb971 https://conda.anaconda.org/conda-forge/noarch/ply-3.11-pyhd8ed1ab_3.conda#fd5062942bfa1b0bd5e0d2a4397b099e https://conda.anaconda.org/conda-forge/noarch/pyparsing-3.2.3-pyhd8ed1ab_1.conda#513d3c262ee49b54a8fec85c5bc99764 https://conda.anaconda.org/conda-forge/noarch/pytz-2025.2-pyhd8ed1ab_0.conda#bc8e3267d44011051f2eb14d22fb0960 -https://conda.anaconda.org/conda-forge/noarch/setuptools-80.1.0-pyhff2d567_0.conda#f6f72d0837c79eaec77661be43e8a691 +https://conda.anaconda.org/conda-forge/noarch/setuptools-80.8.0-pyhff2d567_0.conda#ea075e94dc0106c7212128b6a25bbc4c https://conda.anaconda.org/conda-forge/noarch/six-1.17.0-pyhd8ed1ab_0.conda#a451d576819089b0d672f18768be0f65 https://conda.anaconda.org/conda-forge/noarch/threadpoolctl-3.1.0-pyh8a188c0_0.tar.bz2#a2995ee828f65687ac5b1e71a2ab1e0c https://conda.anaconda.org/conda-forge/noarch/toml-0.10.2-pyhd8ed1ab_1.conda#b0dd904de08b7db706167240bf37b164 https://conda.anaconda.org/conda-forge/noarch/tomli-2.2.1-pyhd8ed1ab_1.conda#ac944244f1fed2eb49bae07193ae8215 -https://conda.anaconda.org/conda-forge/linux-64/tornado-6.4.2-py310ha75aee5_0.conda#166d59aab40b9c607b4cc21c03924e9d +https://conda.anaconda.org/conda-forge/linux-64/tornado-6.5.1-py310ha75aee5_0.conda#6f3da1072c0c4d2a1beb1e84615f7c9c https://conda.anaconda.org/conda-forge/noarch/typing_extensions-4.13.2-pyh29332c3_0.conda#83fc6ae00127671e301c9f44254c31b8 https://conda.anaconda.org/conda-forge/linux-64/unicodedata2-16.0.0-py310ha75aee5_0.conda#1d7a4b9202cdd10d56ecdd7f6c347190 https://conda.anaconda.org/conda-forge/noarch/wheel-0.45.1-pyhd8ed1ab_1.conda#75cb7132eb58d97896e173ef12ac9986 @@ -138,53 +135,55 @@ https://conda.anaconda.org/conda-forge/linux-64/xorg-libxext-1.3.6-hb9d3cd8_0.co https://conda.anaconda.org/conda-forge/linux-64/xorg-libxfixes-6.0.1-hb9d3cd8_0.conda#4bdb303603e9821baf5fe5fdff1dc8f8 https://conda.anaconda.org/conda-forge/linux-64/xorg-libxrender-0.9.12-hb9d3cd8_0.conda#96d57aba173e878a2089d5638016dc5e https://conda.anaconda.org/conda-forge/linux-64/ccache-4.11.3-h80c52d3_0.conda#eb517c6a2b960c3ccb6f1db1005f063a -https://conda.anaconda.org/conda-forge/linux-64/coverage-7.8.0-py310h89163eb_0.conda#9f7865c17117d16f804b687b498e35fa -https://conda.anaconda.org/conda-forge/linux-64/dbus-1.13.6-h5008d03_3.tar.bz2#ecfff944ba3960ecb334b9a2663d708d -https://conda.anaconda.org/conda-forge/linux-64/fonttools-4.57.0-py310h89163eb_0.conda#34378af82141b3c1725dcdf898b28fc6 +https://conda.anaconda.org/conda-forge/linux-64/coverage-7.8.2-py310h89163eb_0.conda#5ca8ab35287adc83b2d1996e5c2ac14c +https://conda.anaconda.org/conda-forge/linux-64/dbus-1.16.2-h3c4dab8_0.conda#679616eb5ad4e521c83da4650860aba7 +https://conda.anaconda.org/conda-forge/noarch/exceptiongroup-1.3.0-pyhd8ed1ab_0.conda#72e42d28960d875c7654614f8b50939a +https://conda.anaconda.org/conda-forge/linux-64/fonttools-4.58.0-py310h89163eb_0.conda#4532df8a45ab4e37b2cc71186304dd5a https://conda.anaconda.org/conda-forge/linux-64/freetype-2.13.3-ha770c72_1.conda#9ccd736d31e0c6e41f54e704e5312811 -https://conda.anaconda.org/conda-forge/linux-64/glib-tools-2.84.1-h4833e2c_1.conda#418de18c9b79a3d8583d90d27e0937c2 +https://conda.anaconda.org/conda-forge/linux-64/glib-tools-2.84.2-h4833e2c_0.conda#f2ec1facec64147850b7674633978050 https://conda.anaconda.org/conda-forge/noarch/joblib-1.2.0-pyhd8ed1ab_0.tar.bz2#7583652522d71ad78ba536bba06940eb https://conda.anaconda.org/conda-forge/linux-64/libblas-3.9.0-20_linux64_openblas.conda#2b7bb4f7562c8cf334fc2e20c2d28abc https://conda.anaconda.org/conda-forge/linux-64/libflac-1.4.3-h59595ed_0.conda#ee48bf17cc83a00f59ca1494d5646869 https://conda.anaconda.org/conda-forge/linux-64/libgl-1.7.0-ha4b6fd6_2.conda#928b8be80851f5d8ffb016f9c81dae7a -https://conda.anaconda.org/conda-forge/linux-64/libllvm20-20.1.4-he9d0ab4_0.conda#96c33bbd084ef2b2463503fb7f1482ae -https://conda.anaconda.org/conda-forge/linux-64/libxkbcommon-1.9.1-h65c71a3_0.conda#6e45090fe0eec179ecc8041a3a3fc9f8 +https://conda.anaconda.org/conda-forge/linux-64/libllvm20-20.1.5-he9d0ab4_0.conda#8d2f5a2f019bd76ccba5eb771852d411 +https://conda.anaconda.org/conda-forge/linux-64/libxkbcommon-1.10.0-h65c71a3_0.conda#fedf6bfe5d21d21d2b1785ec00a8889a https://conda.anaconda.org/conda-forge/linux-64/openblas-0.3.25-pthreads_h7a3da1a_0.conda#87661673941b5e702275fdf0fc095ad0 -https://conda.anaconda.org/conda-forge/linux-64/openldap-2.6.9-he970967_0.conda#ca2de8bbdc871bce41dbf59e51324165 +https://conda.anaconda.org/conda-forge/linux-64/openldap-2.6.10-he970967_0.conda#2e5bf4f1da39c0b32778561c3c4e5878 +https://conda.anaconda.org/conda-forge/linux-64/pillow-11.2.1-py310h7e6dc6c_0.conda#5645a243d90adb50909b9edc209d84fe https://conda.anaconda.org/conda-forge/noarch/pip-25.1.1-pyh8b19718_0.conda#32d0781ace05105cc99af55d36cbec7c https://conda.anaconda.org/conda-forge/noarch/pyproject-metadata-0.9.1-pyhd8ed1ab_0.conda#22ae7c6ea81e0c8661ef32168dda929b -https://conda.anaconda.org/conda-forge/noarch/pytest-8.3.5-pyhd8ed1ab_0.conda#c3c9316209dec74a705a36797970c6be https://conda.anaconda.org/conda-forge/noarch/python-dateutil-2.9.0.post0-pyhff2d567_1.conda#5ba79d7c71f03c678c8ead841f347d6e -https://conda.anaconda.org/conda-forge/linux-64/sip-6.8.6-py310hf71b8c6_2.conda#a50d1007fecaff3f98b19034a8e0b2e7 +https://conda.anaconda.org/conda-forge/linux-64/sip-6.10.0-py310hf71b8c6_0.conda#2d7e4445be227e8210140b75725689ad +https://conda.anaconda.org/conda-forge/linux-64/xorg-libxcomposite-0.4.6-hb9d3cd8_2.conda#d3c295b50f092ab525ffe3c2aa4b7413 https://conda.anaconda.org/conda-forge/linux-64/xorg-libxdamage-1.1.6-hb9d3cd8_0.conda#b5fcc7172d22516e1f965490e65e33a4 https://conda.anaconda.org/conda-forge/linux-64/xorg-libxxf86vm-1.1.6-hb9d3cd8_0.conda#5efa5fa6243a622445fdfd72aee15efa https://conda.anaconda.org/conda-forge/linux-64/fontconfig-2.15.0-h7e30c49_1.conda#8f5b0b297b59e1ac160ad4beec99dbee -https://conda.anaconda.org/conda-forge/linux-64/glib-2.84.1-h6287aef_1.conda#35012688d30e1b52bff2ba5d1f342a50 +https://conda.anaconda.org/conda-forge/linux-64/glib-2.84.2-h6287aef_0.conda#704648df3a01d4d24bc2c0466b718d63 https://conda.anaconda.org/conda-forge/linux-64/libcblas-3.9.0-20_linux64_openblas.conda#36d486d72ab64ffea932329a1d3729a3 -https://conda.anaconda.org/conda-forge/linux-64/libclang-cpp20.1-20.1.4-default_h1df26ce_0.conda#96f8d5b2e94c9ba4fef19f1adf068a15 -https://conda.anaconda.org/conda-forge/linux-64/libclang13-20.1.4-default_he06ed0a_0.conda#2d933632c8004be47deb2be61bf013be +https://conda.anaconda.org/conda-forge/linux-64/libclang-cpp20.1-20.1.5-default_h1df26ce_1.conda#330b1dadfa7c3205a01fa9599fabe808 +https://conda.anaconda.org/conda-forge/linux-64/libclang13-20.1.5-default_he06ed0a_1.conda#12117145218e7e1a528c8396ed803058 https://conda.anaconda.org/conda-forge/linux-64/liblapack-3.9.0-20_linux64_openblas.conda#6fabc51f5e647d09cc010c40061557e0 -https://conda.anaconda.org/conda-forge/linux-64/libpq-17.4-h27ae623_1.conda#37fba334855ef3b51549308e61ed7a3d +https://conda.anaconda.org/conda-forge/linux-64/libpq-17.5-h27ae623_0.conda#6458be24f09e1b034902ab44fe9de908 https://conda.anaconda.org/conda-forge/linux-64/libsndfile-1.2.2-hc60ed4a_1.conda#ef1910918dd895516a769ed36b5b3a4e https://conda.anaconda.org/conda-forge/noarch/meson-python-0.16.0-pyh0c530f3_0.conda#e16f0dbf502da873be9f9adb0dc52547 -https://conda.anaconda.org/conda-forge/linux-64/pillow-11.1.0-py310h7e6dc6c_0.conda#14d300b9e1504748e70cc6499a7b4d25 -https://conda.anaconda.org/conda-forge/linux-64/pyqt5-sip-12.13.0-py310hf71b8c6_1.conda#0c8cbfbe70f4c8a47b040a14615e6f1f -https://conda.anaconda.org/conda-forge/noarch/pytest-cov-6.1.1-pyhd8ed1ab_0.conda#1e35d8f975bc0e984a19819aa91c440a -https://conda.anaconda.org/conda-forge/noarch/pytest-xdist-3.6.1-pyhd8ed1ab_1.conda#59aad4fb37cabc0bacc73cf344612ddd +https://conda.anaconda.org/conda-forge/linux-64/pyqt5-sip-12.17.0-py310hf71b8c6_0.conda#012465861673a67a30bc8ca6284074f3 +https://conda.anaconda.org/conda-forge/noarch/pytest-8.3.5-pyhd8ed1ab_0.conda#c3c9316209dec74a705a36797970c6be https://conda.anaconda.org/conda-forge/linux-64/cairo-1.18.4-h3394656_0.conda#09262e66b19567aff4f592fb53b28760 https://conda.anaconda.org/conda-forge/linux-64/gstreamer-1.24.11-hc37bda9_0.conda#056d86cacf2b48c79c6a562a2486eb8c https://conda.anaconda.org/conda-forge/linux-64/liblapacke-3.9.0-20_linux64_openblas.conda#05c5862c7dc25e65ba6c471d96429dae https://conda.anaconda.org/conda-forge/linux-64/numpy-1.22.0-py310h454958d_1.tar.bz2#607c66f0cce2986515a8fe9e136b2b57 https://conda.anaconda.org/conda-forge/linux-64/pulseaudio-client-17.0-hac146a9_1.conda#66b1fa9608d8836e25f9919159adc9c6 +https://conda.anaconda.org/conda-forge/noarch/pytest-cov-6.1.1-pyhd8ed1ab_0.conda#1e35d8f975bc0e984a19819aa91c440a +https://conda.anaconda.org/conda-forge/noarch/pytest-xdist-3.6.1-pyhd8ed1ab_1.conda#59aad4fb37cabc0bacc73cf344612ddd https://conda.anaconda.org/conda-forge/linux-64/blas-devel-3.9.0-20_linux64_openblas.conda#9932a1d4e9ecf2d35fb19475446e361e https://conda.anaconda.org/conda-forge/linux-64/gst-plugins-base-1.24.11-h651a532_0.conda#d8d8894f8ced2c9be76dc9ad1ae531ce -https://conda.anaconda.org/conda-forge/linux-64/harfbuzz-11.1.0-h3beb420_0.conda#95e3bb97f9cdc251c0c68640e9c10ed3 +https://conda.anaconda.org/conda-forge/linux-64/harfbuzz-11.2.1-h3beb420_0.conda#0e6e192d4b3d95708ad192d957cf3163 https://conda.anaconda.org/conda-forge/linux-64/matplotlib-base-3.5.0-py310h23f4a51_0.tar.bz2#9911225650b298776c8e8c083b5cacf1 https://conda.anaconda.org/conda-forge/linux-64/pandas-1.4.0-py310hb5077e9_0.tar.bz2#43e920bc9856daa7d8d18fcbfb244c4e https://conda.anaconda.org/conda-forge/linux-64/polars-0.20.30-py310h031f9ce_0.conda#0743f5db9f978b6df92d412935ff8371 https://conda.anaconda.org/conda-forge/linux-64/scipy-1.8.0-py310hea5193d_1.tar.bz2#664d80ddeb51241629b3ada5ea926e4d https://conda.anaconda.org/conda-forge/linux-64/blas-2.120-openblas.conda#c8f6916a81a340650078171b1d852574 https://conda.anaconda.org/conda-forge/linux-64/pyamg-4.2.1-py310h7c3ba0c_0.tar.bz2#89f5a48e1f23b5cf3163a6094903d181 -https://conda.anaconda.org/conda-forge/linux-64/qt-main-5.15.15-h993ce98_3.conda#aa49f5308f39277477d47cd6687eb8f3 -https://conda.anaconda.org/conda-forge/linux-64/pyqt-5.15.10-py310hb3b5edb_1.conda#c370972fc4557cb54d265c9c1f71bd20 +https://conda.anaconda.org/conda-forge/linux-64/qt-main-5.15.15-hea1682b_4.conda#c054d7f22cc719e12c72d454b2328d6c +https://conda.anaconda.org/conda-forge/linux-64/pyqt-5.15.11-py310hf392a12_0.conda#65924d3e57be25342c76530d23d75f0f https://conda.anaconda.org/conda-forge/linux-64/matplotlib-3.5.0-py310hff52083_0.tar.bz2#1b2f3b135d5d9c594b5e0e6150c03b7b diff --git a/build_tools/azure/pymin_conda_forge_openblas_ubuntu_2204_linux-64_conda.lock b/build_tools/azure/pymin_conda_forge_openblas_ubuntu_2204_linux-64_conda.lock index 009d15a7d3713..a3f0d92034d19 100644 --- a/build_tools/azure/pymin_conda_forge_openblas_ubuntu_2204_linux-64_conda.lock +++ b/build_tools/azure/pymin_conda_forge_openblas_ubuntu_2204_linux-64_conda.lock @@ -1,23 +1,23 @@ # Generated by conda-lock. # platform: linux-64 -# input_hash: ec41f4a9538671e542d266b999ea055a685df8323c3c879f7d01fb2c259197cb +# input_hash: 26bb2530999c20f24bbab0f7b6e3545ad84d059a25027cb624997210afc23693 @EXPLICIT https://conda.anaconda.org/conda-forge/linux-64/_libgcc_mutex-0.1-conda_forge.tar.bz2#d7c89558ba9fa0495403155b64376d81 https://conda.anaconda.org/conda-forge/noarch/python_abi-3.10-7_cp310.conda#44e871cba2b162368476a84b8d040b6c https://conda.anaconda.org/conda-forge/noarch/tzdata-2025b-h78e105d_0.conda#4222072737ccff51314b5ece9c7d6f5a https://conda.anaconda.org/conda-forge/noarch/ca-certificates-2025.4.26-hbd8a1cb_0.conda#95db94f75ba080a22eb623590993167b https://conda.anaconda.org/conda-forge/linux-64/ld_impl_linux-64-2.43-h712a8e2_4.conda#01f8d123c96816249efd255a31ad7712 -https://conda.anaconda.org/conda-forge/linux-64/libgomp-14.2.0-h767d61c_2.conda#06d02030237f4d5b3d9a7e7d348fe3c6 +https://conda.anaconda.org/conda-forge/linux-64/libgomp-15.1.0-h767d61c_2.conda#fbe7d535ff9d3a168c148e07358cd5b1 https://conda.anaconda.org/conda-forge/linux-64/_openmp_mutex-4.5-2_gnu.tar.bz2#73aaf86a425cc6e73fcf236a5a46396d -https://conda.anaconda.org/conda-forge/linux-64/libgcc-14.2.0-h767d61c_2.conda#ef504d1acbd74b7cc6849ef8af47dd03 -https://conda.anaconda.org/conda-forge/linux-64/libdeflate-1.23-h86f0d12_0.conda#27fe770decaf469a53f3e3a6d593067f +https://conda.anaconda.org/conda-forge/linux-64/libgcc-15.1.0-h767d61c_2.conda#ea8ac52380885ed41c1baa8f1d6d2b93 +https://conda.anaconda.org/conda-forge/linux-64/libdeflate-1.24-h86f0d12_0.conda#64f0c503da58ec25ebd359e4d990afa8 https://conda.anaconda.org/conda-forge/linux-64/libexpat-2.7.0-h5888daf_0.conda#db0bfbe7dd197b68ad5f30333bae6ce0 https://conda.anaconda.org/conda-forge/linux-64/libffi-3.4.6-h2dba641_1.conda#ede4673863426c0883c0063d853bbd85 -https://conda.anaconda.org/conda-forge/linux-64/libgcc-ng-14.2.0-h69a702a_2.conda#a2222a6ada71fb478682efe483ce0f92 -https://conda.anaconda.org/conda-forge/linux-64/libgfortran5-14.2.0-hf1ad2bd_2.conda#556a4fdfac7287d349b8f09aba899693 +https://conda.anaconda.org/conda-forge/linux-64/libgcc-ng-15.1.0-h69a702a_2.conda#ddca86c7040dd0e73b2b69bd7833d225 +https://conda.anaconda.org/conda-forge/linux-64/libgfortran5-15.1.0-hcea5267_2.conda#01de444988ed960031dbe84cf4f9b1fc https://conda.anaconda.org/conda-forge/linux-64/libjpeg-turbo-3.1.0-hb9d3cd8_0.conda#9fa334557db9f63da6c9285fd2a48638 -https://conda.anaconda.org/conda-forge/linux-64/liblzma-5.8.1-hb9d3cd8_0.conda#0e87378639676987af32fee53ba32258 -https://conda.anaconda.org/conda-forge/linux-64/libstdcxx-14.2.0-h8f9b012_2.conda#a78c856b6dc6bf4ea8daeb9beaaa3fb0 +https://conda.anaconda.org/conda-forge/linux-64/liblzma-5.8.1-hb9d3cd8_1.conda#a76fd702c93cd2dfd89eff30a5fd45a8 +https://conda.anaconda.org/conda-forge/linux-64/libstdcxx-15.1.0-h8f9b012_2.conda#1cb1c67961f6dd257eae9e9691b341aa https://conda.anaconda.org/conda-forge/linux-64/libwebp-base-1.5.0-h851e524_0.conda#63f790534398730f59e1b899c3644d4a https://conda.anaconda.org/conda-forge/linux-64/libzlib-1.3.1-hb9d3cd8_2.conda#edb0dca6bc32e4f4789199455a1dbeb8 https://conda.anaconda.org/conda-forge/linux-64/ncurses-6.5-h2d0b736_3.conda#47e340acb35de30501a76c7c799c41d7 @@ -27,11 +27,11 @@ https://conda.anaconda.org/conda-forge/linux-64/xorg-libxau-1.0.12-hb9d3cd8_0.co https://conda.anaconda.org/conda-forge/linux-64/xorg-libxdmcp-1.1.5-hb9d3cd8_0.conda#8035c64cb77ed555e3f150b7b3972480 https://conda.anaconda.org/conda-forge/linux-64/bzip2-1.0.8-h4bc722e_7.conda#62ee74e96c5ebb0af99386de58cf9553 https://conda.anaconda.org/conda-forge/linux-64/lerc-4.0.0-h0aef613_1.conda#9344155d33912347b37f0ae6c410a835 -https://conda.anaconda.org/conda-forge/linux-64/libgfortran-14.2.0-h69a702a_2.conda#fb54c4ea68b460c278d26eea89cfbcc3 +https://conda.anaconda.org/conda-forge/linux-64/libgfortran-15.1.0-h69a702a_2.conda#f92e6e0a3c0c0c85561ef61aa59d555d https://conda.anaconda.org/conda-forge/linux-64/libnsl-2.0.1-hd590300_0.conda#30fd6e37fe21f86f4bd26d6ee73eeec7 https://conda.anaconda.org/conda-forge/linux-64/libpng-1.6.47-h943b412_0.conda#55199e2ae2c3651f6f9b2a447b47bdc9 -https://conda.anaconda.org/conda-forge/linux-64/libsqlite-3.49.1-hee588c1_2.conda#962d6ac93c30b1dfc54c9cccafd1003e -https://conda.anaconda.org/conda-forge/linux-64/libstdcxx-ng-14.2.0-h4852527_2.conda#c75da67f045c2627f59e6fcb5f4e3a9b +https://conda.anaconda.org/conda-forge/linux-64/libsqlite-3.49.2-hee588c1_0.conda#93048463501053a00739215ea3f36324 +https://conda.anaconda.org/conda-forge/linux-64/libstdcxx-ng-15.1.0-h4852527_2.conda#9d2072af184b5caa29492bf2344597bb https://conda.anaconda.org/conda-forge/linux-64/libuuid-2.38.1-h0b41bf4_0.conda#40b61aab5c7ba9ff276c41cfffe6b80b https://conda.anaconda.org/conda-forge/linux-64/libxcb-1.17.0-h8a09558_0.conda#92ed62436b625154323d40d5f2f11dd7 https://conda.anaconda.org/conda-forge/linux-64/libxcrypt-4.4.36-hd590300_1.conda#5aa797f8787fe7a17d1b0821485b5adc @@ -40,18 +40,17 @@ https://conda.anaconda.org/conda-forge/linux-64/readline-8.2-h8c095d6_2.conda#28 https://conda.anaconda.org/conda-forge/linux-64/tk-8.6.13-noxft_h4845f30_101.conda#d453b98d9c83e71da0741bb0ff4d76bc https://conda.anaconda.org/conda-forge/linux-64/zstd-1.5.7-hb8e6e7a_2.conda#6432cb5d4ac0046c3ac0a8a0f95842f9 https://conda.anaconda.org/conda-forge/linux-64/libfreetype6-2.13.3-h48d6fc4_1.conda#3c255be50a506c50765a93a6644f32fe -https://conda.anaconda.org/conda-forge/linux-64/libgfortran-ng-14.2.0-h69a702a_2.conda#4056c857af1a99ee50589a941059ec55 +https://conda.anaconda.org/conda-forge/linux-64/libgfortran-ng-15.1.0-h69a702a_2.conda#a483a87b71e974bb75d1b9413d4436dd https://conda.anaconda.org/conda-forge/linux-64/libopenblas-0.3.29-pthreads_h94d23a6_0.conda#0a4d0252248ef9a0f88f2ba8b8a08e12 -https://conda.anaconda.org/conda-forge/linux-64/libtiff-4.7.0-hd9ff511_4.conda#6c1028898cf3a2032d9af46689e1b81a +https://conda.anaconda.org/conda-forge/linux-64/libtiff-4.7.0-hf01ce69_5.conda#e79a094918988bb1807462cd42c83962 https://conda.anaconda.org/conda-forge/linux-64/python-3.10.17-hd6af730_0_cpython.conda#7bb89638dae9ce1b8e051d0b721e83c2 https://conda.anaconda.org/conda-forge/noarch/alabaster-1.0.0-pyhd8ed1ab_1.conda#1fd9696649f65fd6611fcdb4ffec738a https://conda.anaconda.org/conda-forge/linux-64/brotli-python-1.1.0-py310hf71b8c6_2.conda#bf502c169c71e3c6ac0d6175addfacc2 -https://conda.anaconda.org/conda-forge/noarch/certifi-2025.1.31-pyhd8ed1ab_0.conda#c207fa5ac7ea99b149344385a9c0880d +https://conda.anaconda.org/conda-forge/noarch/certifi-2025.4.26-pyhd8ed1ab_0.conda#c33eeaaa33f45031be34cda513df39b6 https://conda.anaconda.org/conda-forge/noarch/charset-normalizer-3.4.2-pyhd8ed1ab_0.conda#40fe4284b8b5835a9073a645139f35af https://conda.anaconda.org/conda-forge/noarch/colorama-0.4.6-pyhd8ed1ab_1.conda#962b9857ee8e7018c22f2776ffa0b2d7 -https://conda.anaconda.org/conda-forge/linux-64/cython-3.0.12-py310had8cdd9_0.conda#b630fe36f0b621d23e74872dc4fd2bd7 +https://conda.anaconda.org/conda-forge/linux-64/cython-3.1.1-py310had8cdd9_1.conda#4904cb1ba6e72940ff22a5235554532d https://conda.anaconda.org/conda-forge/noarch/docutils-0.21.2-pyhd8ed1ab_1.conda#24c1ca34138ee57de72a943237cde4cc -https://conda.anaconda.org/conda-forge/noarch/exceptiongroup-1.2.2-pyhd8ed1ab_1.conda#a16662747cdeb9abbac74d0057cc976e https://conda.anaconda.org/conda-forge/noarch/execnet-2.1.1-pyhd8ed1ab_1.conda#a71efeae2c160f6789900ba2631a2c90 https://conda.anaconda.org/conda-forge/noarch/hpack-4.1.0-pyhd8ed1ab_0.conda#0a802cb9888dd14eeefc611f05c40b6e https://conda.anaconda.org/conda-forge/noarch/hyperframe-6.1.0-pyhd8ed1ab_0.conda#8e6923fc12f1fe8f8c4e5c9f343256ac @@ -63,45 +62,46 @@ https://conda.anaconda.org/conda-forge/linux-64/libblas-3.9.0-31_h59b9bed_openbl https://conda.anaconda.org/conda-forge/linux-64/libfreetype-2.13.3-ha770c72_1.conda#51f5be229d83ecd401fb369ab96ae669 https://conda.anaconda.org/conda-forge/linux-64/libhiredis-1.0.2-h2cc385e_0.tar.bz2#b34907d3a81a3cd8095ee83d174c074a https://conda.anaconda.org/conda-forge/linux-64/markupsafe-3.0.2-py310h89163eb_1.conda#8ce3f0332fd6de0d737e2911d329523f -https://conda.anaconda.org/conda-forge/noarch/meson-1.8.0-pyh29332c3_0.conda#8e25221b702272394b86b0f4d7217f77 +https://conda.anaconda.org/conda-forge/noarch/meson-1.8.1-pyhe01879c_0.conda#f3cccd9a6ce5331ae33f69ade5529162 https://conda.anaconda.org/conda-forge/linux-64/openblas-0.3.29-pthreads_h6ec200e_0.conda#7e4d48870b3258bea920d51b7f495a81 https://conda.anaconda.org/conda-forge/linux-64/openjpeg-2.5.3-h5fbd93e_0.conda#9e5816bc95d285c115a3ebc2f8563564 https://conda.anaconda.org/conda-forge/noarch/packaging-25.0-pyh29332c3_1.conda#58335b26c38bf4a20f399384c33cbcf9 -https://conda.anaconda.org/conda-forge/noarch/pluggy-1.5.0-pyhd8ed1ab_1.conda#e9dcbce5f45f9ee500e728ae58b605b6 +https://conda.anaconda.org/conda-forge/noarch/pluggy-1.6.0-pyhd8ed1ab_0.conda#7da7ccd349dbf6487a7778579d2bb971 https://conda.anaconda.org/conda-forge/noarch/pycparser-2.22-pyh29332c3_1.conda#12c566707c80111f9799308d9e265aef https://conda.anaconda.org/conda-forge/noarch/pygments-2.19.1-pyhd8ed1ab_0.conda#232fb4577b6687b2d503ef8e254270c9 https://conda.anaconda.org/conda-forge/noarch/pysocks-1.7.1-pyha55dd90_7.conda#461219d1a5bd61342293efa2c0c90eac https://conda.anaconda.org/conda-forge/noarch/python-tzdata-2025.2-pyhd8ed1ab_0.conda#88476ae6ebd24f39261e0854ac244f33 https://conda.anaconda.org/conda-forge/noarch/pytz-2025.2-pyhd8ed1ab_0.conda#bc8e3267d44011051f2eb14d22fb0960 -https://conda.anaconda.org/conda-forge/noarch/setuptools-80.1.0-pyhff2d567_0.conda#f6f72d0837c79eaec77661be43e8a691 +https://conda.anaconda.org/conda-forge/noarch/setuptools-80.8.0-pyhff2d567_0.conda#ea075e94dc0106c7212128b6a25bbc4c https://conda.anaconda.org/conda-forge/noarch/six-1.17.0-pyhd8ed1ab_0.conda#a451d576819089b0d672f18768be0f65 -https://conda.anaconda.org/conda-forge/noarch/snowballstemmer-2.2.0-pyhd8ed1ab_0.tar.bz2#4d22a9315e78c6827f806065957d566e +https://conda.anaconda.org/conda-forge/noarch/snowballstemmer-3.0.1-pyhd8ed1ab_0.conda#755cf22df8693aa0d1aec1c123fa5863 https://conda.anaconda.org/conda-forge/noarch/sphinxcontrib-jsmath-1.0.1-pyhd8ed1ab_1.conda#fa839b5ff59e192f411ccc7dae6588bb https://conda.anaconda.org/conda-forge/noarch/tabulate-0.9.0-pyhd8ed1ab_2.conda#959484a66b4b76befcddc4fa97c95567 https://conda.anaconda.org/conda-forge/noarch/threadpoolctl-3.6.0-pyhecae5ae_0.conda#9d64911b31d57ca443e9f1e36b04385f https://conda.anaconda.org/conda-forge/noarch/tomli-2.2.1-pyhd8ed1ab_1.conda#ac944244f1fed2eb49bae07193ae8215 +https://conda.anaconda.org/conda-forge/noarch/typing_extensions-4.13.2-pyh29332c3_0.conda#83fc6ae00127671e301c9f44254c31b8 https://conda.anaconda.org/conda-forge/noarch/wheel-0.45.1-pyhd8ed1ab_1.conda#75cb7132eb58d97896e173ef12ac9986 https://conda.anaconda.org/conda-forge/noarch/babel-2.17.0-pyhd8ed1ab_0.conda#0a01c169f0ab0f91b26e77a3301fbfe4 https://conda.anaconda.org/conda-forge/linux-64/ccache-4.11.3-h80c52d3_0.conda#eb517c6a2b960c3ccb6f1db1005f063a https://conda.anaconda.org/conda-forge/linux-64/cffi-1.17.1-py310h8deb56e_0.conda#1fc24a3196ad5ede2a68148be61894f4 -https://conda.anaconda.org/conda-forge/linux-64/freetype-2.13.3-ha770c72_1.conda#9ccd736d31e0c6e41f54e704e5312811 +https://conda.anaconda.org/conda-forge/noarch/exceptiongroup-1.3.0-pyhd8ed1ab_0.conda#72e42d28960d875c7654614f8b50939a https://conda.anaconda.org/conda-forge/noarch/h2-4.2.0-pyhd8ed1ab_0.conda#b4754fb1bdcb70c8fd54f918301582c6 https://conda.anaconda.org/conda-forge/noarch/jinja2-3.1.6-pyhd8ed1ab_0.conda#446bd6c8cb26050d528881df495ce646 -https://conda.anaconda.org/conda-forge/noarch/joblib-1.5.0-pyhd8ed1ab_0.conda#3d7257f0a61c9aa4ffa3e324a887416b +https://conda.anaconda.org/conda-forge/noarch/joblib-1.5.1-pyhd8ed1ab_0.conda#fb1c14694de51a476ce8636d92b6f42c https://conda.anaconda.org/conda-forge/linux-64/libcblas-3.9.0-31_he106b2a_openblas.conda#abb32c727da370c481a1c206f5159ce9 https://conda.anaconda.org/conda-forge/linux-64/liblapack-3.9.0-31_h7ac8fdf_openblas.conda#452b98eafe050ecff932f0ec832dd03f +https://conda.anaconda.org/conda-forge/linux-64/pillow-11.2.1-py310h7e6dc6c_0.conda#5645a243d90adb50909b9edc209d84fe https://conda.anaconda.org/conda-forge/noarch/pip-25.1.1-pyh8b19718_0.conda#32d0781ace05105cc99af55d36cbec7c https://conda.anaconda.org/conda-forge/noarch/pyproject-metadata-0.9.1-pyhd8ed1ab_0.conda#22ae7c6ea81e0c8661ef32168dda929b -https://conda.anaconda.org/conda-forge/noarch/pytest-8.3.5-pyhd8ed1ab_0.conda#c3c9316209dec74a705a36797970c6be https://conda.anaconda.org/conda-forge/noarch/python-dateutil-2.9.0.post0-pyhff2d567_1.conda#5ba79d7c71f03c678c8ead841f347d6e https://conda.anaconda.org/conda-forge/linux-64/liblapacke-3.9.0-31_he2f377e_openblas.conda#7e5fff7d0db69be3a266f7e79a3bb0e2 -https://conda.anaconda.org/conda-forge/noarch/meson-python-0.17.1-pyh70fd9c4_1.conda#7a02679229c6c2092571b4c025055440 -https://conda.anaconda.org/conda-forge/linux-64/numpy-2.2.5-py310hefbff90_0.conda#5526bc875ec897f0d335e38da832b6ee -https://conda.anaconda.org/conda-forge/linux-64/pillow-11.1.0-py310h7e6dc6c_0.conda#14d300b9e1504748e70cc6499a7b4d25 -https://conda.anaconda.org/conda-forge/noarch/pytest-xdist-3.6.1-pyhd8ed1ab_1.conda#59aad4fb37cabc0bacc73cf344612ddd +https://conda.anaconda.org/conda-forge/noarch/meson-python-0.18.0-pyh70fd9c4_0.conda#576c04b9d9f8e45285fb4d9452c26133 +https://conda.anaconda.org/conda-forge/linux-64/numpy-2.2.6-py310hefbff90_0.conda#b0cea2c364bf65cd19e023040eeab05d +https://conda.anaconda.org/conda-forge/noarch/pytest-8.3.5-pyhd8ed1ab_0.conda#c3c9316209dec74a705a36797970c6be https://conda.anaconda.org/conda-forge/linux-64/zstandard-0.23.0-py310ha75aee5_2.conda#f9254b5b0193982416b91edcb4b2676f https://conda.anaconda.org/conda-forge/linux-64/blas-devel-3.9.0-31_h1ea3ea9_openblas.conda#ba652ee0576396d4765e567f043c57f9 https://conda.anaconda.org/conda-forge/linux-64/pandas-2.2.3-py310h5eaa309_3.conda#07697a584fab513ce895c4511f7a2403 +https://conda.anaconda.org/conda-forge/noarch/pytest-xdist-3.6.1-pyhd8ed1ab_1.conda#59aad4fb37cabc0bacc73cf344612ddd https://conda.anaconda.org/conda-forge/linux-64/scipy-1.15.2-py310h1d65ade_0.conda#8c29cd33b64b2eb78597fa28b5595c8d https://conda.anaconda.org/conda-forge/noarch/urllib3-2.4.0-pyhd8ed1ab_0.conda#c1e349028e0052c4eea844e94f773065 https://conda.anaconda.org/conda-forge/linux-64/blas-2.131-openblas.conda#38b2ec894c69bb4be0e66d2ef7fc60bf diff --git a/build_tools/azure/test_script.sh b/build_tools/azure/test_script.sh index d8152bd7c3ae2..eb4414283be2b 100755 --- a/build_tools/azure/test_script.sh +++ b/build_tools/azure/test_script.sh @@ -75,6 +75,14 @@ else echo "Could not inspect CPU architecture." fi +if [[ "$DISTRIB" == "conda-free-threaded" ]]; then + # Make sure that GIL is disabled even when importing extensions that have + # not declared free-threaded compatibility. This can be removed when numpy, + # scipy and scikit-learn extensions all have declared free-threaded + # compatibility. + export PYTHON_GIL=0 +fi + TEST_CMD="$TEST_CMD --pyargs sklearn" set -x diff --git a/build_tools/azure/ubuntu_atlas_lock.txt b/build_tools/azure/ubuntu_atlas_lock.txt index ea978eeabcb51..ab86e683f6f09 100644 --- a/build_tools/azure/ubuntu_atlas_lock.txt +++ b/build_tools/azure/ubuntu_atlas_lock.txt @@ -6,7 +6,7 @@ # cython==3.0.10 # via -r build_tools/azure/ubuntu_atlas_requirements.txt -exceptiongroup==1.2.2 +exceptiongroup==1.3.0 # via pytest execnet==2.1.1 # via pytest-xdist @@ -14,9 +14,9 @@ iniconfig==2.1.0 # via pytest joblib==1.2.0 # via -r build_tools/azure/ubuntu_atlas_requirements.txt -meson==1.8.0 +meson==1.8.1 # via meson-python -meson-python==0.17.1 +meson-python==0.18.0 # via -r build_tools/azure/ubuntu_atlas_requirements.txt ninja==1.11.1.4 # via -r build_tools/azure/ubuntu_atlas_requirements.txt @@ -25,7 +25,7 @@ packaging==25.0 # meson-python # pyproject-metadata # pytest -pluggy==1.5.0 +pluggy==1.6.0 # via pytest pyproject-metadata==0.9.1 # via meson-python @@ -41,3 +41,5 @@ tomli==2.2.1 # via # meson-python # pytest +typing-extensions==4.13.2 + # via exceptiongroup diff --git a/build_tools/circle/doc_linux-64_conda.lock b/build_tools/circle/doc_linux-64_conda.lock index c489e4f01a9f7..db2d896dc6ddc 100644 --- a/build_tools/circle/doc_linux-64_conda.lock +++ b/build_tools/circle/doc_linux-64_conda.lock @@ -1,6 +1,6 @@ # Generated by conda-lock. # platform: linux-64 -# input_hash: 208134f3b8c140a6fe6fffe85293a731d77b7bf6cdcf0b12f7a44fdcf6e665d2 +# input_hash: 93cb6f7aa17dce662512650f1419e87eae56ed49163348847bf965697cd268bb @EXPLICIT https://conda.anaconda.org/conda-forge/linux-64/_libgcc_mutex-0.1-conda_forge.tar.bz2#d7c89558ba9fa0495403155b64376d81 https://conda.anaconda.org/conda-forge/noarch/font-ttf-dejavu-sans-mono-2.37-hab24e00_0.tar.bz2#0c96522c6bdaed4b1566d11387caaf45 @@ -15,7 +15,7 @@ https://conda.anaconda.org/conda-forge/noarch/fonts-conda-forge-1-0.tar.bz2#f766 https://conda.anaconda.org/conda-forge/linux-64/ld_impl_linux-64-2.43-h712a8e2_4.conda#01f8d123c96816249efd255a31ad7712 https://conda.anaconda.org/conda-forge/noarch/libgcc-devel_linux-64-13.3.0-hc03c837_102.conda#4c1d6961a6a54f602ae510d9bf31fa60 https://conda.anaconda.org/conda-forge/linux-64/libglvnd-1.7.0-ha4b6fd6_2.conda#434ca7e50e40f4918ab701e3facd59a0 -https://conda.anaconda.org/conda-forge/linux-64/libgomp-14.2.0-h767d61c_2.conda#06d02030237f4d5b3d9a7e7d348fe3c6 +https://conda.anaconda.org/conda-forge/linux-64/libgomp-15.1.0-h767d61c_2.conda#fbe7d535ff9d3a168c148e07358cd5b1 https://conda.anaconda.org/conda-forge/noarch/libstdcxx-devel_linux-64-13.3.0-hc03c837_102.conda#aa38de2738c5f4a72a880e3d31ffe8b4 https://conda.anaconda.org/conda-forge/noarch/sysroot_linux-64-2.17-h0157908_18.conda#460eba7851277ec1fd80a1a24080787a https://conda.anaconda.org/conda-forge/linux-64/_openmp_mutex-4.5-2_gnu.tar.bz2#73aaf86a425cc6e73fcf236a5a46396d @@ -25,31 +25,31 @@ https://conda.anaconda.org/conda-forge/linux-64/libegl-1.7.0-ha4b6fd6_2.conda#c1 https://conda.anaconda.org/conda-forge/linux-64/libopengl-1.7.0-ha4b6fd6_2.conda#7df50d44d4a14d6c31a2c54f2cd92157 https://conda.anaconda.org/conda-forge/linux-64/binutils-2.43-h4852527_4.conda#29782348a527eda3ecfc673109d28e93 https://conda.anaconda.org/conda-forge/linux-64/binutils_linux-64-2.43-h4852527_4.conda#c87e146f5b685672d4aa6b527c6d3b5e -https://conda.anaconda.org/conda-forge/linux-64/libgcc-14.2.0-h767d61c_2.conda#ef504d1acbd74b7cc6849ef8af47dd03 +https://conda.anaconda.org/conda-forge/linux-64/libgcc-15.1.0-h767d61c_2.conda#ea8ac52380885ed41c1baa8f1d6d2b93 https://conda.anaconda.org/conda-forge/linux-64/alsa-lib-1.2.14-hb9d3cd8_0.conda#76df83c2a9035c54df5d04ff81bcc02d https://conda.anaconda.org/conda-forge/linux-64/libbrotlicommon-1.1.0-hb9d3cd8_2.conda#41b599ed2b02abcfdd84302bff174b23 -https://conda.anaconda.org/conda-forge/linux-64/libdeflate-1.23-h86f0d12_0.conda#27fe770decaf469a53f3e3a6d593067f +https://conda.anaconda.org/conda-forge/linux-64/libdeflate-1.24-h86f0d12_0.conda#64f0c503da58ec25ebd359e4d990afa8 https://conda.anaconda.org/conda-forge/linux-64/libexpat-2.7.0-h5888daf_0.conda#db0bfbe7dd197b68ad5f30333bae6ce0 https://conda.anaconda.org/conda-forge/linux-64/libffi-3.4.6-h2dba641_1.conda#ede4673863426c0883c0063d853bbd85 -https://conda.anaconda.org/conda-forge/linux-64/libgcc-ng-14.2.0-h69a702a_2.conda#a2222a6ada71fb478682efe483ce0f92 -https://conda.anaconda.org/conda-forge/linux-64/libgfortran5-14.2.0-hf1ad2bd_2.conda#556a4fdfac7287d349b8f09aba899693 +https://conda.anaconda.org/conda-forge/linux-64/libgcc-ng-15.1.0-h69a702a_2.conda#ddca86c7040dd0e73b2b69bd7833d225 +https://conda.anaconda.org/conda-forge/linux-64/libgfortran5-15.1.0-hcea5267_2.conda#01de444988ed960031dbe84cf4f9b1fc https://conda.anaconda.org/conda-forge/linux-64/libiconv-1.18-h4ce23a2_1.conda#e796ff8ddc598affdf7c173d6145f087 https://conda.anaconda.org/conda-forge/linux-64/libjpeg-turbo-3.1.0-hb9d3cd8_0.conda#9fa334557db9f63da6c9285fd2a48638 -https://conda.anaconda.org/conda-forge/linux-64/liblzma-5.8.1-hb9d3cd8_0.conda#0e87378639676987af32fee53ba32258 +https://conda.anaconda.org/conda-forge/linux-64/liblzma-5.8.1-hb9d3cd8_1.conda#a76fd702c93cd2dfd89eff30a5fd45a8 https://conda.anaconda.org/conda-forge/linux-64/libntlm-1.8-hb9d3cd8_0.conda#7c7927b404672409d9917d49bff5f2d6 -https://conda.anaconda.org/conda-forge/linux-64/libstdcxx-14.2.0-h8f9b012_2.conda#a78c856b6dc6bf4ea8daeb9beaaa3fb0 +https://conda.anaconda.org/conda-forge/linux-64/libstdcxx-15.1.0-h8f9b012_2.conda#1cb1c67961f6dd257eae9e9691b341aa https://conda.anaconda.org/conda-forge/linux-64/libwebp-base-1.5.0-h851e524_0.conda#63f790534398730f59e1b899c3644d4a https://conda.anaconda.org/conda-forge/linux-64/libzlib-1.3.1-hb9d3cd8_2.conda#edb0dca6bc32e4f4789199455a1dbeb8 https://conda.anaconda.org/conda-forge/linux-64/ncurses-6.5-h2d0b736_3.conda#47e340acb35de30501a76c7c799c41d7 https://conda.anaconda.org/conda-forge/linux-64/openssl-3.5.0-h7b32b05_1.conda#de356753cfdbffcde5bb1e86e3aa6cd0 https://conda.anaconda.org/conda-forge/linux-64/pthread-stubs-0.4-hb9d3cd8_1002.conda#b3c17d95b5a10c6e64a21fa17573e70e +https://conda.anaconda.org/conda-forge/linux-64/rav1e-0.7.1-h8fae777_3.conda#2c42649888aac645608191ffdc80d13a https://conda.anaconda.org/conda-forge/linux-64/xorg-libice-1.1.2-hb9d3cd8_0.conda#fb901ff28063514abb6046c9ec2c4a45 https://conda.anaconda.org/conda-forge/linux-64/xorg-libxau-1.0.12-hb9d3cd8_0.conda#f6ebe2cb3f82ba6c057dde5d9debe4f7 https://conda.anaconda.org/conda-forge/linux-64/xorg-libxdmcp-1.1.5-hb9d3cd8_0.conda#8035c64cb77ed555e3f150b7b3972480 https://conda.anaconda.org/conda-forge/linux-64/bzip2-1.0.8-h4bc722e_7.conda#62ee74e96c5ebb0af99386de58cf9553 https://conda.anaconda.org/conda-forge/linux-64/dav1d-1.2.1-hd590300_0.conda#418c6ca5929a611cbd69204907a83995 https://conda.anaconda.org/conda-forge/linux-64/double-conversion-3.3.1-h5888daf_0.conda#bfd56492d8346d669010eccafe0ba058 -https://conda.anaconda.org/conda-forge/linux-64/expat-2.7.0-h5888daf_0.conda#d6845ae4dea52a2f90178bf1829a21f8 https://conda.anaconda.org/conda-forge/linux-64/giflib-5.2.2-hd590300_0.conda#3bf7b9fd5a7136126e0234db4b87c8b6 https://conda.anaconda.org/conda-forge/linux-64/jxrlib-1.1-hd590300_3.conda#5aeabe88534ea4169d4c49998f293d6c https://conda.anaconda.org/conda-forge/linux-64/keyutils-1.6.1-h166bdaf_0.tar.bz2#30186d27e2c9fa62b45fb1476b7200e3 @@ -57,22 +57,20 @@ https://conda.anaconda.org/conda-forge/linux-64/lerc-4.0.0-h0aef613_1.conda#9344 https://conda.anaconda.org/conda-forge/linux-64/libbrotlidec-1.1.0-hb9d3cd8_2.conda#9566f0bd264fbd463002e759b8a82401 https://conda.anaconda.org/conda-forge/linux-64/libbrotlienc-1.1.0-hb9d3cd8_2.conda#06f70867945ea6a84d35836af780f1de https://conda.anaconda.org/conda-forge/linux-64/libedit-3.1.20250104-pl5321h7949ede_0.conda#c277e0a4d549b03ac1e9d6cbbe3d017b -https://conda.anaconda.org/conda-forge/linux-64/libgfortran-14.2.0-h69a702a_2.conda#fb54c4ea68b460c278d26eea89cfbcc3 +https://conda.anaconda.org/conda-forge/linux-64/libgfortran-15.1.0-h69a702a_2.conda#f92e6e0a3c0c0c85561ef61aa59d555d https://conda.anaconda.org/conda-forge/linux-64/libhwy-1.2.0-hf40a0c7_0.conda#2f433d593a66044c3f163cb25f0a09de https://conda.anaconda.org/conda-forge/linux-64/libnsl-2.0.1-hd590300_0.conda#30fd6e37fe21f86f4bd26d6ee73eeec7 https://conda.anaconda.org/conda-forge/linux-64/libpciaccess-0.18-hd590300_0.conda#48f4330bfcd959c3cfb704d424903c82 https://conda.anaconda.org/conda-forge/linux-64/libpng-1.6.47-h943b412_0.conda#55199e2ae2c3651f6f9b2a447b47bdc9 https://conda.anaconda.org/conda-forge/linux-64/libsanitizer-13.3.0-he8ea267_2.conda#2b6cdf7bb95d3d10ef4e38ce0bc95dba -https://conda.anaconda.org/conda-forge/linux-64/libsqlite-3.49.1-hee588c1_2.conda#962d6ac93c30b1dfc54c9cccafd1003e -https://conda.anaconda.org/conda-forge/linux-64/libstdcxx-ng-14.2.0-h4852527_2.conda#c75da67f045c2627f59e6fcb5f4e3a9b +https://conda.anaconda.org/conda-forge/linux-64/libsqlite-3.49.2-hee588c1_0.conda#93048463501053a00739215ea3f36324 +https://conda.anaconda.org/conda-forge/linux-64/libstdcxx-ng-15.1.0-h4852527_2.conda#9d2072af184b5caa29492bf2344597bb https://conda.anaconda.org/conda-forge/linux-64/libuuid-2.38.1-h0b41bf4_0.conda#40b61aab5c7ba9ff276c41cfffe6b80b https://conda.anaconda.org/conda-forge/linux-64/libxcb-1.17.0-h8a09558_0.conda#92ed62436b625154323d40d5f2f11dd7 https://conda.anaconda.org/conda-forge/linux-64/libxcrypt-4.4.36-hd590300_1.conda#5aa797f8787fe7a17d1b0821485b5adc https://conda.anaconda.org/conda-forge/linux-64/lz4-c-1.10.0-h5888daf_1.conda#9de5350a85c4a20c685259b889aa6393 -https://conda.anaconda.org/conda-forge/linux-64/mysql-common-9.2.0-h266115a_0.conda#db22a0962c953e81a2a679ecb1fc6027 https://conda.anaconda.org/conda-forge/linux-64/ninja-1.12.1-hff21bea_1.conda#2322531904f27501ee19847b87ba7c64 https://conda.anaconda.org/conda-forge/linux-64/pixman-0.46.0-h29eaf8c_0.conda#d2f1c87d4416d1e7344cf92b1aaee1c4 -https://conda.anaconda.org/conda-forge/linux-64/rav1e-0.6.6-he8a937b_2.conda#77d9955b4abddb811cb8ab1aa7d743e4 https://conda.anaconda.org/conda-forge/linux-64/readline-8.2-h8c095d6_2.conda#283b96675859b20a825f8fa30f311446 https://conda.anaconda.org/conda-forge/linux-64/snappy-1.2.1-h8bd8927_1.conda#3b3e64af585eadfb52bb90b553db5edf https://conda.anaconda.org/conda-forge/linux-64/svt-av1-3.0.2-h5888daf_0.conda#0096882bd623e6cc09e8bf920fc8fb47 @@ -84,7 +82,7 @@ https://conda.anaconda.org/conda-forge/linux-64/zstd-1.5.7-hb8e6e7a_2.conda#6432 https://conda.anaconda.org/conda-forge/linux-64/aom-3.9.1-hac33072_0.conda#346722a0be40f6edc53f12640d301338 https://conda.anaconda.org/conda-forge/linux-64/blosc-1.21.6-he440d0b_1.conda#2c2fae981fd2afd00812c92ac47d023d https://conda.anaconda.org/conda-forge/linux-64/brotli-bin-1.1.0-hb9d3cd8_2.conda#c63b5e52939e795ba8d26e35d767a843 -https://conda.anaconda.org/conda-forge/linux-64/c-blosc2-2.15.2-h3122c55_1.conda#2bc8d76acd818d7e79229f5157d5c156 +https://conda.anaconda.org/conda-forge/linux-64/c-blosc2-2.17.1-h3122c55_0.conda#009d16d3c9ed3e70d58ed46dab1571d1 https://conda.anaconda.org/conda-forge/linux-64/charls-2.4.2-h59595ed_0.conda#4336bd67920dd504cd8c6761d6a99645 https://conda.anaconda.org/conda-forge/linux-64/gcc_impl_linux-64-13.3.0-h1e990d8_2.conda#f46cf0acdcb6019397d37df1e407ab91 https://conda.anaconda.org/conda-forge/linux-64/graphite2-1.3.13-h59595ed_1003.conda#f87c7b7c2cb45f323ffbce941c78ab7c @@ -95,10 +93,9 @@ https://conda.anaconda.org/conda-forge/linux-64/libdrm-2.4.124-hb9d3cd8_0.conda# https://conda.anaconda.org/conda-forge/linux-64/libfreetype6-2.13.3-h48d6fc4_1.conda#3c255be50a506c50765a93a6644f32fe https://conda.anaconda.org/conda-forge/linux-64/libjxl-0.11.1-h7b0646d_1.conda#959fc2b6c0df7883e070b3fe525219a5 https://conda.anaconda.org/conda-forge/linux-64/libopenblas-0.3.29-pthreads_h94d23a6_0.conda#0a4d0252248ef9a0f88f2ba8b8a08e12 -https://conda.anaconda.org/conda-forge/linux-64/libtiff-4.7.0-hd9ff511_4.conda#6c1028898cf3a2032d9af46689e1b81a +https://conda.anaconda.org/conda-forge/linux-64/libtiff-4.7.0-hf01ce69_5.conda#e79a094918988bb1807462cd42c83962 https://conda.anaconda.org/conda-forge/linux-64/libzopfli-1.0.3-h9c3ff4c_0.tar.bz2#c66fe2d123249af7651ebde8984c51c2 -https://conda.anaconda.org/conda-forge/linux-64/mysql-libs-9.2.0-he0572af_0.conda#93340b072c393d23c4700a1d40565dca -https://conda.anaconda.org/conda-forge/linux-64/pcre2-10.44-hc749103_2.conda#31614c73d7b103ef76faa4d83d261d34 +https://conda.anaconda.org/conda-forge/linux-64/pcre2-10.45-hc749103_0.conda#b90bece58b4c2bf25969b70f3be42d25 https://conda.anaconda.org/conda-forge/linux-64/python-3.10.17-hd6af730_0_cpython.conda#7bb89638dae9ce1b8e051d0b721e83c2 https://conda.anaconda.org/conda-forge/linux-64/qhull-2020.2-h434a139_5.conda#353823361b1d27eb3960efb076dfcaf6 https://conda.anaconda.org/conda-forge/linux-64/xcb-util-0.4.1-hb711507_2.conda#8637c3e5821654d0edf97e2b0404b443 @@ -110,16 +107,15 @@ https://conda.anaconda.org/conda-forge/linux-64/xorg-libx11-1.8.12-h4f16b4b_0.co https://conda.anaconda.org/conda-forge/noarch/alabaster-1.0.0-pyhd8ed1ab_1.conda#1fd9696649f65fd6611fcdb4ffec738a https://conda.anaconda.org/conda-forge/linux-64/brotli-1.1.0-hb9d3cd8_2.conda#98514fe74548d768907ce7a13f680e8f https://conda.anaconda.org/conda-forge/linux-64/brotli-python-1.1.0-py310hf71b8c6_2.conda#bf502c169c71e3c6ac0d6175addfacc2 -https://conda.anaconda.org/conda-forge/noarch/certifi-2025.1.31-pyhd8ed1ab_0.conda#c207fa5ac7ea99b149344385a9c0880d +https://conda.anaconda.org/conda-forge/noarch/certifi-2025.4.26-pyhd8ed1ab_0.conda#c33eeaaa33f45031be34cda513df39b6 https://conda.anaconda.org/conda-forge/noarch/charset-normalizer-3.4.2-pyhd8ed1ab_0.conda#40fe4284b8b5835a9073a645139f35af -https://conda.anaconda.org/conda-forge/noarch/click-8.1.8-pyh707e725_0.conda#f22f4d4970e09d68a10b922cbb0408d3 +https://conda.anaconda.org/conda-forge/noarch/click-8.2.1-pyh707e725_0.conda#94b550b8d3a614dbd326af798c7dfb40 https://conda.anaconda.org/conda-forge/noarch/colorama-0.4.6-pyhd8ed1ab_1.conda#962b9857ee8e7018c22f2776ffa0b2d7 https://conda.anaconda.org/conda-forge/noarch/cpython-3.10.17-py310hd8ed1ab_0.conda#e2b81369f0473107784f8b7da8e6a8e9 https://conda.anaconda.org/conda-forge/noarch/cycler-0.12.1-pyhd8ed1ab_1.conda#44600c4667a319d67dbe0681fc0bc833 https://conda.anaconda.org/conda-forge/linux-64/cyrus-sasl-2.1.27-h54b06d7_7.conda#dce22f70b4e5a407ce88f2be046f4ceb -https://conda.anaconda.org/conda-forge/linux-64/cython-3.0.12-py310had8cdd9_0.conda#b630fe36f0b621d23e74872dc4fd2bd7 +https://conda.anaconda.org/conda-forge/linux-64/cython-3.1.1-py310had8cdd9_1.conda#4904cb1ba6e72940ff22a5235554532d https://conda.anaconda.org/conda-forge/noarch/docutils-0.21.2-pyhd8ed1ab_1.conda#24c1ca34138ee57de72a943237cde4cc -https://conda.anaconda.org/conda-forge/noarch/exceptiongroup-1.2.2-pyhd8ed1ab_1.conda#a16662747cdeb9abbac74d0057cc976e https://conda.anaconda.org/conda-forge/noarch/execnet-2.1.1-pyhd8ed1ab_1.conda#a71efeae2c160f6789900ba2631a2c90 https://conda.anaconda.org/conda-forge/linux-64/gcc-13.3.0-h9576a4e_2.conda#d92e51bf4b6bdbfe45e5884fb0755afe https://conda.anaconda.org/conda-forge/linux-64/gcc_linux-64-13.3.0-hc28eda2_10.conda#d151142bbafe5e68ec7fc065c5e6f80c @@ -132,23 +128,23 @@ https://conda.anaconda.org/conda-forge/noarch/imagesize-1.4.1-pyhd8ed1ab_0.tar.b https://conda.anaconda.org/conda-forge/noarch/iniconfig-2.0.0-pyhd8ed1ab_1.conda#6837f3eff7dcea42ecd714ce1ac2b108 https://conda.anaconda.org/conda-forge/linux-64/kiwisolver-1.4.7-py310h3788b33_0.conda#4186d9b4d004b0fe0de6aa62496fb48a https://conda.anaconda.org/conda-forge/linux-64/lcms2-2.17-h717163a_0.conda#000e85703f0fd9594c81710dd5066471 -https://conda.anaconda.org/conda-forge/linux-64/libavif16-1.2.1-hbb36593_2.conda#971387a27e61235b97cacb440a37e991 +https://conda.anaconda.org/conda-forge/linux-64/libavif16-1.3.0-h766b0b6_0.conda#f17f2d0e5c9ad6b958547fd67b155771 https://conda.anaconda.org/conda-forge/linux-64/libblas-3.9.0-31_h59b9bed_openblas.conda#728dbebd0f7a20337218beacffd37916 https://conda.anaconda.org/conda-forge/linux-64/libcups-2.3.3-h4637d8d_4.conda#d4529f4dff3057982a7617c7ac58fde3 https://conda.anaconda.org/conda-forge/linux-64/libfreetype-2.13.3-ha770c72_1.conda#51f5be229d83ecd401fb369ab96ae669 -https://conda.anaconda.org/conda-forge/linux-64/libglib-2.84.1-h2ff4ddf_0.conda#0305434da649d4fb48a425e588b79ea6 +https://conda.anaconda.org/conda-forge/linux-64/libglib-2.84.2-h3618099_0.conda#072ab14a02164b7c0c089055368ff776 https://conda.anaconda.org/conda-forge/linux-64/libglx-1.7.0-ha4b6fd6_2.conda#c8013e438185f33b13814c5c488acd5c -https://conda.anaconda.org/conda-forge/linux-64/libxml2-2.13.7-h4bc477f_1.conda#ad1f1f8238834cd3c88ceeaee8da444a +https://conda.anaconda.org/conda-forge/linux-64/libxml2-2.13.8-h4bc477f_0.conda#14dbe05b929e329dbaa6f2d0aa19466d https://conda.anaconda.org/conda-forge/linux-64/markupsafe-3.0.2-py310h89163eb_1.conda#8ce3f0332fd6de0d737e2911d329523f -https://conda.anaconda.org/conda-forge/noarch/meson-1.8.0-pyh29332c3_0.conda#8e25221b702272394b86b0f4d7217f77 +https://conda.anaconda.org/conda-forge/noarch/meson-1.8.1-pyhe01879c_0.conda#f3cccd9a6ce5331ae33f69ade5529162 https://conda.anaconda.org/conda-forge/noarch/munkres-1.1.4-pyh9f0ad1d_0.tar.bz2#2ba8498c1018c1e9c61eb99b973dfe19 -https://conda.anaconda.org/conda-forge/noarch/narwhals-1.37.0-pyh29332c3_0.conda#f9ae420fa431efd502a5d5c4c1f08263 +https://conda.anaconda.org/conda-forge/noarch/narwhals-1.40.0-pyhe01879c_0.conda#578a7350e50600779eac971be60cafdf https://conda.anaconda.org/conda-forge/noarch/networkx-3.4.2-pyh267e887_2.conda#fd40bf7f7f4bc4b647dc8512053d9873 https://conda.anaconda.org/conda-forge/linux-64/openblas-0.3.29-pthreads_h6ec200e_0.conda#7e4d48870b3258bea920d51b7f495a81 https://conda.anaconda.org/conda-forge/linux-64/openjpeg-2.5.3-h5fbd93e_0.conda#9e5816bc95d285c115a3ebc2f8563564 https://conda.anaconda.org/conda-forge/noarch/packaging-25.0-pyh29332c3_1.conda#58335b26c38bf4a20f399384c33cbcf9 -https://conda.anaconda.org/conda-forge/noarch/platformdirs-4.3.7-pyh29332c3_0.conda#e57da6fe54bb3a5556cf36d199ff07d8 -https://conda.anaconda.org/conda-forge/noarch/pluggy-1.5.0-pyhd8ed1ab_1.conda#e9dcbce5f45f9ee500e728ae58b605b6 +https://conda.anaconda.org/conda-forge/noarch/platformdirs-4.3.8-pyhe01879c_0.conda#424844562f5d337077b445ec6b1398a7 +https://conda.anaconda.org/conda-forge/noarch/pluggy-1.6.0-pyhd8ed1ab_0.conda#7da7ccd349dbf6487a7778579d2bb971 https://conda.anaconda.org/conda-forge/linux-64/psutil-7.0.0-py310ha75aee5_0.conda#da7d592394ff9084a23f62a1186451a2 https://conda.anaconda.org/conda-forge/noarch/pycparser-2.22-pyh29332c3_1.conda#12c566707c80111f9799308d9e265aef https://conda.anaconda.org/conda-forge/noarch/pygments-2.19.1-pyhd8ed1ab_0.conda#232fb4577b6687b2d503ef8e254270c9 @@ -156,15 +152,15 @@ https://conda.anaconda.org/conda-forge/noarch/pyparsing-3.2.3-pyhd8ed1ab_1.conda https://conda.anaconda.org/conda-forge/noarch/pysocks-1.7.1-pyha55dd90_7.conda#461219d1a5bd61342293efa2c0c90eac https://conda.anaconda.org/conda-forge/noarch/python-tzdata-2025.2-pyhd8ed1ab_0.conda#88476ae6ebd24f39261e0854ac244f33 https://conda.anaconda.org/conda-forge/noarch/pytz-2025.2-pyhd8ed1ab_0.conda#bc8e3267d44011051f2eb14d22fb0960 -https://conda.anaconda.org/conda-forge/noarch/setuptools-80.1.0-pyhff2d567_0.conda#f6f72d0837c79eaec77661be43e8a691 +https://conda.anaconda.org/conda-forge/noarch/setuptools-80.8.0-pyhff2d567_0.conda#ea075e94dc0106c7212128b6a25bbc4c https://conda.anaconda.org/conda-forge/noarch/six-1.17.0-pyhd8ed1ab_0.conda#a451d576819089b0d672f18768be0f65 -https://conda.anaconda.org/conda-forge/noarch/snowballstemmer-2.2.0-pyhd8ed1ab_0.tar.bz2#4d22a9315e78c6827f806065957d566e -https://conda.anaconda.org/conda-forge/noarch/soupsieve-2.5-pyhd8ed1ab_1.conda#3f144b2c34f8cb5a9abd9ed23a39c561 +https://conda.anaconda.org/conda-forge/noarch/snowballstemmer-3.0.1-pyhd8ed1ab_0.conda#755cf22df8693aa0d1aec1c123fa5863 +https://conda.anaconda.org/conda-forge/noarch/soupsieve-2.7-pyhd8ed1ab_0.conda#fb32097c717486aa34b38a9db57eb49e https://conda.anaconda.org/conda-forge/noarch/sphinxcontrib-jsmath-1.0.1-pyhd8ed1ab_1.conda#fa839b5ff59e192f411ccc7dae6588bb https://conda.anaconda.org/conda-forge/noarch/tabulate-0.9.0-pyhd8ed1ab_2.conda#959484a66b4b76befcddc4fa97c95567 https://conda.anaconda.org/conda-forge/noarch/threadpoolctl-3.6.0-pyhecae5ae_0.conda#9d64911b31d57ca443e9f1e36b04385f https://conda.anaconda.org/conda-forge/noarch/tomli-2.2.1-pyhd8ed1ab_1.conda#ac944244f1fed2eb49bae07193ae8215 -https://conda.anaconda.org/conda-forge/linux-64/tornado-6.4.2-py310ha75aee5_0.conda#166d59aab40b9c607b4cc21c03924e9d +https://conda.anaconda.org/conda-forge/linux-64/tornado-6.5.1-py310ha75aee5_0.conda#6f3da1072c0c4d2a1beb1e84615f7c9c https://conda.anaconda.org/conda-forge/noarch/typing_extensions-4.13.2-pyh29332c3_0.conda#83fc6ae00127671e301c9f44254c31b8 https://conda.anaconda.org/conda-forge/linux-64/unicodedata2-16.0.0-py310ha75aee5_0.conda#1d7a4b9202cdd10d56ecdd7f6c347190 https://conda.anaconda.org/conda-forge/noarch/wheel-0.45.1-pyhd8ed1ab_1.conda#75cb7132eb58d97896e173ef12ac9986 @@ -179,30 +175,31 @@ https://conda.anaconda.org/conda-forge/noarch/babel-2.17.0-pyhd8ed1ab_0.conda#0a https://conda.anaconda.org/conda-forge/linux-64/brunsli-0.1-h9c3ff4c_0.tar.bz2#c1ac6229d0bfd14f8354ff9ad2a26cad https://conda.anaconda.org/conda-forge/linux-64/c-compiler-1.9.0-h2b85faf_0.conda#3cb814f83f1f71ac1985013697f80cc1 https://conda.anaconda.org/conda-forge/linux-64/cffi-1.17.1-py310h8deb56e_0.conda#1fc24a3196ad5ede2a68148be61894f4 -https://conda.anaconda.org/conda-forge/linux-64/dbus-1.13.6-h5008d03_3.tar.bz2#ecfff944ba3960ecb334b9a2663d708d -https://conda.anaconda.org/conda-forge/linux-64/fonttools-4.57.0-py310h89163eb_0.conda#34378af82141b3c1725dcdf898b28fc6 +https://conda.anaconda.org/conda-forge/linux-64/dbus-1.16.2-h3c4dab8_0.conda#679616eb5ad4e521c83da4650860aba7 +https://conda.anaconda.org/conda-forge/noarch/exceptiongroup-1.3.0-pyhd8ed1ab_0.conda#72e42d28960d875c7654614f8b50939a +https://conda.anaconda.org/conda-forge/linux-64/fonttools-4.58.0-py310h89163eb_0.conda#4532df8a45ab4e37b2cc71186304dd5a https://conda.anaconda.org/conda-forge/linux-64/freetype-2.13.3-ha770c72_1.conda#9ccd736d31e0c6e41f54e704e5312811 https://conda.anaconda.org/conda-forge/linux-64/gfortran-13.3.0-h9576a4e_2.conda#19e6d3c9cde10a0a9a170a684082588e https://conda.anaconda.org/conda-forge/linux-64/gfortran_linux-64-13.3.0-hb919d3a_10.conda#7ce070e3329cd10bf79dbed562a21bd4 https://conda.anaconda.org/conda-forge/linux-64/gxx-13.3.0-h9576a4e_2.conda#07e8df00b7cd3084ad3ef598ce32a71c https://conda.anaconda.org/conda-forge/linux-64/gxx_linux-64-13.3.0-h6834431_10.conda#9a8ebde471cec5cc9c48f8682f434f92 https://conda.anaconda.org/conda-forge/noarch/h2-4.2.0-pyhd8ed1ab_0.conda#b4754fb1bdcb70c8fd54f918301582c6 -https://conda.anaconda.org/conda-forge/noarch/importlib-metadata-8.6.1-pyha770c72_0.conda#f4b39bf00c69f56ac01e020ebfac066c +https://conda.anaconda.org/conda-forge/noarch/importlib-metadata-8.7.0-pyhe01879c_1.conda#63ccfdc3a3ce25b027b8767eb722fca8 https://conda.anaconda.org/conda-forge/noarch/importlib_resources-6.5.2-pyhd8ed1ab_0.conda#c85c76dc67d75619a92f51dfbce06992 https://conda.anaconda.org/conda-forge/noarch/jinja2-3.1.6-pyhd8ed1ab_0.conda#446bd6c8cb26050d528881df495ce646 -https://conda.anaconda.org/conda-forge/noarch/joblib-1.5.0-pyhd8ed1ab_0.conda#3d7257f0a61c9aa4ffa3e324a887416b +https://conda.anaconda.org/conda-forge/noarch/joblib-1.5.1-pyhd8ed1ab_0.conda#fb1c14694de51a476ce8636d92b6f42c https://conda.anaconda.org/conda-forge/linux-64/libcblas-3.9.0-31_he106b2a_openblas.conda#abb32c727da370c481a1c206f5159ce9 https://conda.anaconda.org/conda-forge/linux-64/libgl-1.7.0-ha4b6fd6_2.conda#928b8be80851f5d8ffb016f9c81dae7a https://conda.anaconda.org/conda-forge/linux-64/liblapack-3.9.0-31_h7ac8fdf_openblas.conda#452b98eafe050ecff932f0ec832dd03f -https://conda.anaconda.org/conda-forge/linux-64/libllvm20-20.1.4-he9d0ab4_0.conda#96c33bbd084ef2b2463503fb7f1482ae -https://conda.anaconda.org/conda-forge/linux-64/libxkbcommon-1.9.1-h65c71a3_0.conda#6e45090fe0eec179ecc8041a3a3fc9f8 +https://conda.anaconda.org/conda-forge/linux-64/libllvm20-20.1.5-he9d0ab4_0.conda#8d2f5a2f019bd76ccba5eb771852d411 +https://conda.anaconda.org/conda-forge/linux-64/libxkbcommon-1.10.0-h65c71a3_0.conda#fedf6bfe5d21d21d2b1785ec00a8889a https://conda.anaconda.org/conda-forge/linux-64/libxslt-1.1.39-h76b75d6_0.conda#e71f31f8cfb0a91439f2086fc8aa0461 https://conda.anaconda.org/conda-forge/noarch/memory_profiler-0.61.0-pyhd8ed1ab_1.conda#71abbefb6f3b95e1668cd5e0af3affb9 -https://conda.anaconda.org/conda-forge/linux-64/openldap-2.6.9-he970967_0.conda#ca2de8bbdc871bce41dbf59e51324165 +https://conda.anaconda.org/conda-forge/linux-64/openldap-2.6.10-he970967_0.conda#2e5bf4f1da39c0b32778561c3c4e5878 +https://conda.anaconda.org/conda-forge/linux-64/pillow-11.2.1-py310h7e6dc6c_0.conda#5645a243d90adb50909b9edc209d84fe https://conda.anaconda.org/conda-forge/noarch/pip-25.1.1-pyh8b19718_0.conda#32d0781ace05105cc99af55d36cbec7c -https://conda.anaconda.org/conda-forge/noarch/plotly-6.0.1-pyhd8ed1ab_0.conda#37ce02c899ff42ac5c554257b1a5906e +https://conda.anaconda.org/conda-forge/noarch/plotly-6.1.1-pyhd8ed1ab_0.conda#b18343b5d779bf6d9205822c2cf76d6e https://conda.anaconda.org/conda-forge/noarch/pyproject-metadata-0.9.1-pyhd8ed1ab_0.conda#22ae7c6ea81e0c8661ef32168dda929b -https://conda.anaconda.org/conda-forge/noarch/pytest-8.3.5-pyhd8ed1ab_0.conda#c3c9316209dec74a705a36797970c6be https://conda.anaconda.org/conda-forge/noarch/python-dateutil-2.9.0.post0-pyhff2d567_1.conda#5ba79d7c71f03c678c8ead841f347d6e https://conda.anaconda.org/conda-forge/noarch/python-gil-3.10.17-hd8ed1ab_0.conda#c856adbd93a57004e21cd26564f4f724 https://conda.anaconda.org/conda-forge/noarch/typing-extensions-4.13.2-h0e9735f_0.conda#568ed1300869dca0ba09fb750cda5dbb @@ -220,44 +217,44 @@ https://conda.anaconda.org/conda-forge/linux-64/fontconfig-2.15.0-h7e30c49_1.con https://conda.anaconda.org/conda-forge/linux-64/fortran-compiler-1.9.0-h36df796_0.conda#cc0cf942201f9d3b0e9654ea02e12486 https://conda.anaconda.org/conda-forge/noarch/importlib-resources-6.5.2-pyhd8ed1ab_0.conda#e376ea42e9ae40f3278b0f79c9bf9826 https://conda.anaconda.org/conda-forge/noarch/lazy-loader-0.4-pyhd8ed1ab_2.conda#d10d9393680734a8febc4b362a4c94f2 -https://conda.anaconda.org/conda-forge/linux-64/libclang-cpp20.1-20.1.4-default_h1df26ce_0.conda#96f8d5b2e94c9ba4fef19f1adf068a15 -https://conda.anaconda.org/conda-forge/linux-64/libclang13-20.1.4-default_he06ed0a_0.conda#2d933632c8004be47deb2be61bf013be +https://conda.anaconda.org/conda-forge/linux-64/libclang-cpp20.1-20.1.5-default_h1df26ce_1.conda#330b1dadfa7c3205a01fa9599fabe808 +https://conda.anaconda.org/conda-forge/linux-64/libclang13-20.1.5-default_he06ed0a_1.conda#12117145218e7e1a528c8396ed803058 https://conda.anaconda.org/conda-forge/linux-64/liblapacke-3.9.0-31_he2f377e_openblas.conda#7e5fff7d0db69be3a266f7e79a3bb0e2 -https://conda.anaconda.org/conda-forge/linux-64/libpq-17.4-h27ae623_1.conda#37fba334855ef3b51549308e61ed7a3d -https://conda.anaconda.org/conda-forge/noarch/meson-python-0.17.1-pyh70fd9c4_1.conda#7a02679229c6c2092571b4c025055440 -https://conda.anaconda.org/conda-forge/linux-64/numpy-2.2.5-py310hefbff90_0.conda#5526bc875ec897f0d335e38da832b6ee -https://conda.anaconda.org/conda-forge/linux-64/pillow-11.1.0-py310h7e6dc6c_0.conda#14d300b9e1504748e70cc6499a7b4d25 -https://conda.anaconda.org/conda-forge/noarch/pytest-xdist-3.6.1-pyhd8ed1ab_1.conda#59aad4fb37cabc0bacc73cf344612ddd +https://conda.anaconda.org/conda-forge/linux-64/libpq-17.5-h27ae623_0.conda#6458be24f09e1b034902ab44fe9de908 +https://conda.anaconda.org/conda-forge/noarch/meson-python-0.18.0-pyh70fd9c4_0.conda#576c04b9d9f8e45285fb4d9452c26133 +https://conda.anaconda.org/conda-forge/linux-64/numpy-2.2.6-py310hefbff90_0.conda#b0cea2c364bf65cd19e023040eeab05d +https://conda.anaconda.org/conda-forge/noarch/pytest-8.3.5-pyhd8ed1ab_0.conda#c3c9316209dec74a705a36797970c6be https://conda.anaconda.org/conda-forge/linux-64/xorg-libxtst-1.2.5-hb9d3cd8_3.conda#7bbe9a0cc0df0ac5f5a8ad6d6a11af2f https://conda.anaconda.org/conda-forge/linux-64/zstandard-0.23.0-py310ha75aee5_2.conda#f9254b5b0193982416b91edcb4b2676f https://conda.anaconda.org/conda-forge/linux-64/blas-devel-3.9.0-31_h1ea3ea9_openblas.conda#ba652ee0576396d4765e567f043c57f9 https://conda.anaconda.org/conda-forge/linux-64/cairo-1.18.4-h3394656_0.conda#09262e66b19567aff4f592fb53b28760 https://conda.anaconda.org/conda-forge/linux-64/compilers-1.9.0-ha770c72_0.conda#5859096e397aba423340d0bbbb11ec64 https://conda.anaconda.org/conda-forge/linux-64/contourpy-1.3.2-py310h3788b33_0.conda#b6420d29123c7c823de168f49ccdfe6a -https://conda.anaconda.org/conda-forge/linux-64/imagecodecs-2024.12.30-py310h78a9a29_0.conda#e0c50079904122427bcf52e1afcd1cdb +https://conda.anaconda.org/conda-forge/linux-64/imagecodecs-2024.12.30-py310h481ba9f_1.conda#1a0a3b184dec933b4922a2721b3150a0 https://conda.anaconda.org/conda-forge/noarch/imageio-2.37.0-pyhfb79c49_0.conda#b5577bc2212219566578fd5af9993af6 -https://conda.anaconda.org/conda-forge/noarch/lazy_loader-0.4-pyhd8ed1ab_2.conda#bb0230917e2473c77d615104dbe8a49d https://conda.anaconda.org/conda-forge/linux-64/pandas-2.2.3-py310h5eaa309_3.conda#07697a584fab513ce895c4511f7a2403 https://conda.anaconda.org/conda-forge/noarch/patsy-1.0.1-pyhd8ed1ab_1.conda#ee23fabfd0a8c6b8d6f3729b47b2859d -https://conda.anaconda.org/conda-forge/linux-64/polars-1.27.1-py39h2a4a510_3.conda#fba08963eaa1f954480045d033d1221e +https://conda.anaconda.org/conda-forge/linux-64/polars-default-1.30.0-py39hfac2b71_0.conda#cd33cf1e631b4d766858c90e333b4832 +https://conda.anaconda.org/conda-forge/noarch/pytest-xdist-3.6.1-pyhd8ed1ab_1.conda#59aad4fb37cabc0bacc73cf344612ddd https://conda.anaconda.org/conda-forge/linux-64/pywavelets-1.8.0-py310hf462985_0.conda#4c441eff2be2e65bd67765c5642051c5 https://conda.anaconda.org/conda-forge/linux-64/scipy-1.15.2-py310h1d65ade_0.conda#8c29cd33b64b2eb78597fa28b5595c8d https://conda.anaconda.org/conda-forge/noarch/towncrier-24.8.0-pyhd8ed1ab_1.conda#820b6a1ddf590fba253f8204f7200d82 https://conda.anaconda.org/conda-forge/noarch/urllib3-2.4.0-pyhd8ed1ab_0.conda#c1e349028e0052c4eea844e94f773065 https://conda.anaconda.org/conda-forge/linux-64/blas-2.131-openblas.conda#38b2ec894c69bb4be0e66d2ef7fc60bf -https://conda.anaconda.org/conda-forge/linux-64/harfbuzz-11.1.0-h3beb420_0.conda#95e3bb97f9cdc251c0c68640e9c10ed3 -https://conda.anaconda.org/conda-forge/linux-64/matplotlib-base-3.10.1-py310h68603db_0.conda#29cf3f5959afb841eda926541f26b0fb +https://conda.anaconda.org/conda-forge/linux-64/harfbuzz-11.2.1-h3beb420_0.conda#0e6e192d4b3d95708ad192d957cf3163 +https://conda.anaconda.org/conda-forge/linux-64/matplotlib-base-3.10.3-py310h68603db_0.conda#50084ca38bf28440e2762966bac143fc +https://conda.anaconda.org/conda-forge/linux-64/polars-1.30.0-default_h1443d73_0.conda#19698b29e8544d2dd615699826037039 https://conda.anaconda.org/conda-forge/linux-64/pyamg-5.2.1-py310ha2bacc8_1.conda#817d32861729e14f474249f1036291c4 https://conda.anaconda.org/conda-forge/noarch/requests-2.32.3-pyhd8ed1ab_1.conda#a9b9368f3701a417eac9edbcae7cb737 https://conda.anaconda.org/conda-forge/linux-64/statsmodels-0.14.4-py310hf462985_0.conda#636d3c500d8a851e377360e88ec95372 -https://conda.anaconda.org/conda-forge/noarch/tifffile-2025.3.30-pyhd8ed1ab_0.conda#14f46147fae19bb867f82a787c7059e9 +https://conda.anaconda.org/conda-forge/noarch/tifffile-2025.5.10-pyhd8ed1ab_0.conda#1fdb801f28bf4987294c49aaa314bf5e https://conda.anaconda.org/conda-forge/noarch/pooch-1.8.2-pyhd8ed1ab_1.conda#b3e783e8e8ed7577cf0b6dee37d1fbac -https://conda.anaconda.org/conda-forge/linux-64/qt6-main-6.9.0-h6441bc3_1.conda#4029a8dcb1d97ea241dbe5abfda1fad6 -https://conda.anaconda.org/conda-forge/linux-64/scikit-image-0.25.2-py310h5eaa309_0.conda#4cc3a231679ecb3c0ba20ebf3c27d12e +https://conda.anaconda.org/conda-forge/linux-64/qt6-main-6.9.0-h0384650_3.conda#8aa69e15597a205fd6f81781fe62c232 +https://conda.anaconda.org/conda-forge/linux-64/scikit-image-0.25.2-py310h5eaa309_1.conda#ed21ab72d049ecdb60f829f04b4dca1c https://conda.anaconda.org/conda-forge/noarch/seaborn-base-0.13.2-pyhd8ed1ab_3.conda#fd96da444e81f9e6fcaac38590f3dd42 https://conda.anaconda.org/conda-forge/linux-64/pyside6-6.9.0-py310hfd10a26_0.conda#1610ccfe262ee519716bb69bd4395572 https://conda.anaconda.org/conda-forge/noarch/seaborn-0.13.2-hd8ed1ab_3.conda#62afb877ca2c2b4b6f9ecb37320085b6 -https://conda.anaconda.org/conda-forge/linux-64/matplotlib-3.10.1-py310hff52083_0.conda#45c1ad6a0351492b56d1b2bb5442cdfa +https://conda.anaconda.org/conda-forge/linux-64/matplotlib-3.10.3-py310hff52083_0.conda#4162a00ddf1d805557aff34ddf113f46 https://conda.anaconda.org/conda-forge/noarch/numpydoc-1.8.0-pyhd8ed1ab_1.conda#5af206d64d18d6c8dfb3122b4d9e643b https://conda.anaconda.org/conda-forge/noarch/pydata-sphinx-theme-0.16.1-pyhd8ed1ab_0.conda#837aaf71ddf3b27acae0e7e9015eebc6 https://conda.anaconda.org/conda-forge/noarch/sphinx-copybutton-0.5.2-pyhd8ed1ab_1.conda#bf22cb9c439572760316ce0748af3713 @@ -285,16 +282,16 @@ https://conda.anaconda.org/conda-forge/noarch/sphinxext-opengraph-0.9.1-pyhd8ed1 # pip overrides @ https://files.pythonhosted.org/packages/2c/ab/fc8290c6a4c722e5514d80f62b2dc4c4df1a68a41d1364e625c35990fcf3/overrides-7.7.0-py3-none-any.whl#sha256=c7ed9d062f78b8e4c1a7b70bd8796b35ead4d9f510227ef9c5dc7626c60d7e49 # pip pandocfilters @ https://files.pythonhosted.org/packages/ef/af/4fbc8cab944db5d21b7e2a5b8e9211a03a79852b1157e2c102fcc61ac440/pandocfilters-1.5.1-py2.py3-none-any.whl#sha256=93be382804a9cdb0a7267585f157e5d1731bbe5545a85b268d6f5fe6232de2bc # pip pkginfo @ https://files.pythonhosted.org/packages/fa/3d/f4f2ba829efb54b6cd2d91349c7463316a9cc55a43fc980447416c88540f/pkginfo-1.12.1.2-py3-none-any.whl#sha256=c783ac885519cab2c34927ccfa6bf64b5a704d7c69afaea583dd9b7afe969343 -# pip prometheus-client @ https://files.pythonhosted.org/packages/ff/c2/ab7d37426c179ceb9aeb109a85cda8948bb269b7561a0be870cc656eefe4/prometheus_client-0.21.1-py3-none-any.whl#sha256=594b45c410d6f4f8888940fe80b5cc2521b305a1fafe1c58609ef715a001f301 +# pip prometheus-client @ https://files.pythonhosted.org/packages/50/c7/cee159ba3d7192e84a4c166ec1752f44a5fa859ac0eeda2d73a1da65ab47/prometheus_client-0.22.0-py3-none-any.whl#sha256=c8951bbe64e62b96cd8e8f5d917279d1b9b91ab766793f33d4dce6c228558713 # pip ptyprocess @ https://files.pythonhosted.org/packages/22/a6/858897256d0deac81a172289110f31629fc4cee19b6f01283303e18c8db3/ptyprocess-0.7.0-py2.py3-none-any.whl#sha256=4b41f3967fce3af57cc7e94b888626c18bf37a083e3651ca8feeb66d492fef35 # pip python-json-logger @ https://files.pythonhosted.org/packages/08/20/0f2523b9e50a8052bc6a8b732dfc8568abbdc42010aef03a2d750bdab3b2/python_json_logger-3.3.0-py3-none-any.whl#sha256=dd980fae8cffb24c13caf6e158d3d61c0d6d22342f932cb6e9deedab3d35eec7 # pip pyyaml @ https://files.pythonhosted.org/packages/6b/4e/1523cb902fd98355e2e9ea5e5eb237cbc5f3ad5f3075fa65087aa0ecb669/PyYAML-6.0.2-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl#sha256=ec031d5d2feb36d1d1a24380e4db6d43695f3748343d99434e6f5f9156aaa2ed # pip rfc3986-validator @ https://files.pythonhosted.org/packages/9e/51/17023c0f8f1869d8806b979a2bffa3f861f26a3f1a66b094288323fba52f/rfc3986_validator-0.1.1-py2.py3-none-any.whl#sha256=2f235c432ef459970b4306369336b9d5dbdda31b510ca1e327636e01f528bfa9 -# pip rpds-py @ https://files.pythonhosted.org/packages/a7/a7/6d04d438f53d8bb2356bb000bea9cf5c96a9315e405b577117e344cc7404/rpds_py-0.24.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl#sha256=1b221c2457d92a1fb3c97bee9095c874144d196f47c038462ae6e4a14436f7bc +# pip rpds-py @ https://files.pythonhosted.org/packages/eb/76/66b523ffc84cf47db56efe13ae7cf368dee2bacdec9d89b9baca5e2e6301/rpds_py-0.25.1-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl#sha256=0701942049095741a8aeb298a31b203e735d1c61f4423511d2b1a41dcd8a16da # pip send2trash @ https://files.pythonhosted.org/packages/40/b0/4562db6223154aa4e22f939003cb92514c79f3d4dccca3444253fd17f902/Send2Trash-1.8.3-py3-none-any.whl#sha256=0c31227e0bd08961c7665474a3d1ef7193929fedda4233843689baa056be46c9 # pip sniffio @ https://files.pythonhosted.org/packages/e9/44/75a9c9421471a6c4805dbf2356f7c181a29c1879239abab1ea2cc8f38b40/sniffio-1.3.1-py3-none-any.whl#sha256=2f6da418d1f1e0fddd844478f41680e794e6051915791a034ff65e5f100525a2 # pip traitlets @ https://files.pythonhosted.org/packages/00/c0/8f5d070730d7836adc9c9b6408dec68c6ced86b304a9b26a14df072a6e8c/traitlets-5.14.3-py3-none-any.whl#sha256=b74e89e397b1ed28cc831db7aea759ba6640cb3de13090ca145426688ff1ac4f -# pip types-python-dateutil @ https://files.pythonhosted.org/packages/0f/b3/ca41df24db5eb99b00d97f89d7674a90cb6b3134c52fb8121b6d8d30f15c/types_python_dateutil-2.9.0.20241206-py3-none-any.whl#sha256=e248a4bc70a486d3e3ec84d0dc30eec3a5f979d6e7ee4123ae043eedbb987f53 +# pip types-python-dateutil @ https://files.pythonhosted.org/packages/c5/3f/b0e8db149896005adc938a1e7f371d6d7e9eca4053a29b108978ed15e0c2/types_python_dateutil-2.9.0.20250516-py3-none-any.whl#sha256=2b2b3f57f9c6a61fba26a9c0ffb9ea5681c9b83e69cd897c6b5f668d9c0cab93 # pip uri-template @ https://files.pythonhosted.org/packages/e7/00/3fca040d7cf8a32776d3d81a00c8ee7457e00f80c649f1e4a863c8321ae9/uri_template-1.3.0-py3-none-any.whl#sha256=a44a133ea12d44a0c0f06d7d42a52d71282e77e2f937d8abd5655b8d56fc1363 # pip webcolors @ https://files.pythonhosted.org/packages/60/e8/c0e05e4684d13459f93d312077a9a2efbe04d59c393bc2b8802248c908d4/webcolors-24.11.1-py3-none-any.whl#sha256=515291393b4cdf0eb19c155749a096f779f7d909f7cceea072791cb9095b92e9 # pip webencodings @ https://files.pythonhosted.org/packages/f4/24/2a3e3df732393fed8b3ebf2ec078f05546de641fe1b667ee316ec1dcf3b7/webencodings-0.5.1-py2.py3-none-any.whl#sha256=a0af1213f3c2226497a97e2b3aa01a7e4bee4f403f95be16fc9acd2947514a78 @@ -327,6 +324,6 @@ https://conda.anaconda.org/conda-forge/noarch/sphinxext-opengraph-0.9.1-pyhd8ed1 # pip jupytext @ https://files.pythonhosted.org/packages/12/b7/e7e3d34c8095c19228874b1babedfb5d901374e40d51ae66f2a90203be53/jupytext-1.17.1-py3-none-any.whl#sha256=99145b1e1fa96520c21ba157de7d354ffa4904724dcebdcd70b8413688a312de # pip nbclient @ https://files.pythonhosted.org/packages/34/6d/e7fa07f03a4a7b221d94b4d586edb754a9b0dc3c9e2c93353e9fa4e0d117/nbclient-0.10.2-py3-none-any.whl#sha256=4ffee11e788b4a27fabeb7955547e4318a5298f34342a4bfd01f2e1faaeadc3d # pip nbconvert @ https://files.pythonhosted.org/packages/cc/9a/cd673b2f773a12c992f41309ef81b99da1690426bd2f96957a7ade0d3ed7/nbconvert-7.16.6-py3-none-any.whl#sha256=1375a7b67e0c2883678c48e506dc320febb57685e5ee67faa51b18a90f3a712b -# pip jupyter-server @ https://files.pythonhosted.org/packages/e2/a2/89eeaf0bb954a123a909859fa507fa86f96eb61b62dc30667b60dbd5fdaf/jupyter_server-2.15.0-py3-none-any.whl#sha256=872d989becf83517012ee669f09604aa4a28097c0bd90b2f424310156c2cdae3 +# pip jupyter-server @ https://files.pythonhosted.org/packages/46/1f/5ebbced977171d09a7b0c08a285ff9a20aafb9c51bde07e52349ff1ddd71/jupyter_server-2.16.0-py3-none-any.whl#sha256=3d8db5be3bc64403b1c65b400a1d7f4647a5ce743f3b20dbdefe8ddb7b55af9e # pip jupyterlab-server @ https://files.pythonhosted.org/packages/54/09/2032e7d15c544a0e3cd831c51d77a8ca57f7555b2e1b2922142eddb02a84/jupyterlab_server-2.27.3-py3-none-any.whl#sha256=e697488f66c3db49df675158a77b3b017520d772c6e1548c7d9bcc5df7944ee4 -# pip jupyterlite-sphinx @ https://files.pythonhosted.org/packages/a9/f2/b64ad053b8b6fed95c46e8df85ee3349a1cca47e006eb6a65671c9a1c6e5/jupyterlite_sphinx-0.20.0-py3-none-any.whl#sha256=de2cb966f389d70cc269f501af24f0cbb1f47d521a89ee79ac83f0ad302214fc +# pip jupyterlite-sphinx @ https://files.pythonhosted.org/packages/b8/68/d35f70a5ae17b30da996c48138c2d655232c2ee839c881ef44587d75d0d3/jupyterlite_sphinx-0.20.1-py3-none-any.whl#sha256=6f477879e9793813b5ed554f08d87b2d949b68595ec5b7570332aa2d0fe0a8c1 diff --git a/build_tools/circle/doc_min_dependencies_linux-64_conda.lock b/build_tools/circle/doc_min_dependencies_linux-64_conda.lock index 4e9d8501dc411..cf6232d4ba950 100644 --- a/build_tools/circle/doc_min_dependencies_linux-64_conda.lock +++ b/build_tools/circle/doc_min_dependencies_linux-64_conda.lock @@ -1,6 +1,6 @@ # Generated by conda-lock. # platform: linux-64 -# input_hash: 1ff580fa5b39efc9a616b69d09ea9208049b15bb1bd5e42883b7295d717cc6ba +# input_hash: cf86af2534e8e281654ed19bc893b468656b355b2b200b12321dbc61cce562db @EXPLICIT https://conda.anaconda.org/conda-forge/linux-64/_libgcc_mutex-0.1-conda_forge.tar.bz2#d7c89558ba9fa0495403155b64376d81 https://conda.anaconda.org/conda-forge/noarch/font-ttf-dejavu-sans-mono-2.37-hab24e00_0.tar.bz2#0c96522c6bdaed4b1566d11387caaf45 @@ -15,37 +15,39 @@ https://conda.anaconda.org/conda-forge/noarch/fonts-conda-forge-1-0.tar.bz2#f766 https://conda.anaconda.org/conda-forge/linux-64/ld_impl_linux-64-2.43-h712a8e2_4.conda#01f8d123c96816249efd255a31ad7712 https://conda.anaconda.org/conda-forge/noarch/libgcc-devel_linux-64-13.3.0-hc03c837_102.conda#4c1d6961a6a54f602ae510d9bf31fa60 https://conda.anaconda.org/conda-forge/linux-64/libglvnd-1.7.0-ha4b6fd6_2.conda#434ca7e50e40f4918ab701e3facd59a0 -https://conda.anaconda.org/conda-forge/linux-64/libgomp-14.2.0-h767d61c_2.conda#06d02030237f4d5b3d9a7e7d348fe3c6 +https://conda.anaconda.org/conda-forge/linux-64/libgomp-15.1.0-h767d61c_2.conda#fbe7d535ff9d3a168c148e07358cd5b1 https://conda.anaconda.org/conda-forge/noarch/libstdcxx-devel_linux-64-13.3.0-hc03c837_102.conda#aa38de2738c5f4a72a880e3d31ffe8b4 https://conda.anaconda.org/conda-forge/noarch/sysroot_linux-64-2.17-h0157908_18.conda#460eba7851277ec1fd80a1a24080787a https://conda.anaconda.org/conda-forge/linux-64/_openmp_mutex-4.5-2_gnu.tar.bz2#73aaf86a425cc6e73fcf236a5a46396d https://conda.anaconda.org/conda-forge/linux-64/binutils_impl_linux-64-2.43-h4bf12b8_4.conda#ef67db625ad0d2dce398837102f875ed https://conda.anaconda.org/conda-forge/noarch/fonts-conda-ecosystem-1-0.tar.bz2#fee5683a3f04bd15cbd8318b096a27ab https://conda.anaconda.org/conda-forge/linux-64/libegl-1.7.0-ha4b6fd6_2.conda#c151d5eb730e9b7480e6d48c0fc44048 +https://conda.anaconda.org/conda-forge/linux-64/libopengl-1.7.0-ha4b6fd6_2.conda#7df50d44d4a14d6c31a2c54f2cd92157 https://conda.anaconda.org/conda-forge/linux-64/binutils-2.43-h4852527_4.conda#29782348a527eda3ecfc673109d28e93 https://conda.anaconda.org/conda-forge/linux-64/binutils_linux-64-2.43-h4852527_4.conda#c87e146f5b685672d4aa6b527c6d3b5e -https://conda.anaconda.org/conda-forge/linux-64/libgcc-14.2.0-h767d61c_2.conda#ef504d1acbd74b7cc6849ef8af47dd03 +https://conda.anaconda.org/conda-forge/linux-64/libgcc-15.1.0-h767d61c_2.conda#ea8ac52380885ed41c1baa8f1d6d2b93 https://conda.anaconda.org/conda-forge/linux-64/alsa-lib-1.2.14-hb9d3cd8_0.conda#76df83c2a9035c54df5d04ff81bcc02d https://conda.anaconda.org/conda-forge/linux-64/gettext-tools-0.24.1-h5888daf_0.conda#d54305672f0361c2f3886750e7165b5f https://conda.anaconda.org/conda-forge/linux-64/libbrotlicommon-1.1.0-hb9d3cd8_2.conda#41b599ed2b02abcfdd84302bff174b23 -https://conda.anaconda.org/conda-forge/linux-64/libdeflate-1.23-h86f0d12_0.conda#27fe770decaf469a53f3e3a6d593067f +https://conda.anaconda.org/conda-forge/linux-64/libdeflate-1.24-h86f0d12_0.conda#64f0c503da58ec25ebd359e4d990afa8 https://conda.anaconda.org/conda-forge/linux-64/libexpat-2.7.0-h5888daf_0.conda#db0bfbe7dd197b68ad5f30333bae6ce0 https://conda.anaconda.org/conda-forge/linux-64/libffi-3.4.6-h2dba641_1.conda#ede4673863426c0883c0063d853bbd85 -https://conda.anaconda.org/conda-forge/linux-64/libgcc-ng-14.2.0-h69a702a_2.conda#a2222a6ada71fb478682efe483ce0f92 +https://conda.anaconda.org/conda-forge/linux-64/libgcc-ng-15.1.0-h69a702a_2.conda#ddca86c7040dd0e73b2b69bd7833d225 https://conda.anaconda.org/conda-forge/linux-64/libgettextpo-0.24.1-h5888daf_0.conda#2ee6d71b72f75d50581f2f68e965efdb -https://conda.anaconda.org/conda-forge/linux-64/libgfortran5-14.2.0-hf1ad2bd_2.conda#556a4fdfac7287d349b8f09aba899693 +https://conda.anaconda.org/conda-forge/linux-64/libgfortran5-15.1.0-hcea5267_2.conda#01de444988ed960031dbe84cf4f9b1fc https://conda.anaconda.org/conda-forge/linux-64/libiconv-1.18-h4ce23a2_1.conda#e796ff8ddc598affdf7c173d6145f087 https://conda.anaconda.org/conda-forge/linux-64/libjpeg-turbo-3.1.0-hb9d3cd8_0.conda#9fa334557db9f63da6c9285fd2a48638 -https://conda.anaconda.org/conda-forge/linux-64/liblzma-5.8.1-hb9d3cd8_0.conda#0e87378639676987af32fee53ba32258 +https://conda.anaconda.org/conda-forge/linux-64/liblzma-5.8.1-hb9d3cd8_1.conda#a76fd702c93cd2dfd89eff30a5fd45a8 https://conda.anaconda.org/conda-forge/linux-64/libntlm-1.8-hb9d3cd8_0.conda#7c7927b404672409d9917d49bff5f2d6 https://conda.anaconda.org/conda-forge/linux-64/libogg-1.3.5-hd0c01bc_1.conda#68e52064ed3897463c0e958ab5c8f91b https://conda.anaconda.org/conda-forge/linux-64/libopus-1.5.2-hd0c01bc_0.conda#b64523fb87ac6f87f0790f324ad43046 -https://conda.anaconda.org/conda-forge/linux-64/libstdcxx-14.2.0-h8f9b012_2.conda#a78c856b6dc6bf4ea8daeb9beaaa3fb0 +https://conda.anaconda.org/conda-forge/linux-64/libstdcxx-15.1.0-h8f9b012_2.conda#1cb1c67961f6dd257eae9e9691b341aa https://conda.anaconda.org/conda-forge/linux-64/libwebp-base-1.5.0-h851e524_0.conda#63f790534398730f59e1b899c3644d4a https://conda.anaconda.org/conda-forge/linux-64/libzlib-1.3.1-hb9d3cd8_2.conda#edb0dca6bc32e4f4789199455a1dbeb8 https://conda.anaconda.org/conda-forge/linux-64/ncurses-6.5-h2d0b736_3.conda#47e340acb35de30501a76c7c799c41d7 https://conda.anaconda.org/conda-forge/linux-64/openssl-3.5.0-h7b32b05_1.conda#de356753cfdbffcde5bb1e86e3aa6cd0 https://conda.anaconda.org/conda-forge/linux-64/pthread-stubs-0.4-hb9d3cd8_1002.conda#b3c17d95b5a10c6e64a21fa17573e70e +https://conda.anaconda.org/conda-forge/linux-64/rav1e-0.7.1-h8fae777_3.conda#2c42649888aac645608191ffdc80d13a https://conda.anaconda.org/conda-forge/linux-64/xorg-libice-1.1.2-hb9d3cd8_0.conda#fb901ff28063514abb6046c9ec2c4a45 https://conda.anaconda.org/conda-forge/linux-64/xorg-libxau-1.0.12-hb9d3cd8_0.conda#f6ebe2cb3f82ba6c057dde5d9debe4f7 https://conda.anaconda.org/conda-forge/linux-64/xorg-libxdmcp-1.1.5-hb9d3cd8_0.conda#8035c64cb77ed555e3f150b7b3972480 @@ -54,7 +56,6 @@ https://conda.anaconda.org/conda-forge/linux-64/attr-2.5.1-h166bdaf_1.tar.bz2#d9 https://conda.anaconda.org/conda-forge/linux-64/blis-0.9.0-h4ab18f5_2.conda#6f77ba1352b69c4a6f8a6d20def30e4e https://conda.anaconda.org/conda-forge/linux-64/bzip2-1.0.8-h4bc722e_7.conda#62ee74e96c5ebb0af99386de58cf9553 https://conda.anaconda.org/conda-forge/linux-64/dav1d-1.2.1-hd590300_0.conda#418c6ca5929a611cbd69204907a83995 -https://conda.anaconda.org/conda-forge/linux-64/expat-2.7.0-h5888daf_0.conda#d6845ae4dea52a2f90178bf1829a21f8 https://conda.anaconda.org/conda-forge/linux-64/giflib-5.2.2-hd590300_0.conda#3bf7b9fd5a7136126e0234db4b87c8b6 https://conda.anaconda.org/conda-forge/linux-64/jxrlib-1.1-hd590300_3.conda#5aeabe88534ea4169d4c49998f293d6c https://conda.anaconda.org/conda-forge/linux-64/keyutils-1.6.1-h166bdaf_0.tar.bz2#30186d27e2c9fa62b45fb1476b7200e3 @@ -66,25 +67,23 @@ https://conda.anaconda.org/conda-forge/linux-64/libbrotlienc-1.1.0-hb9d3cd8_2.co https://conda.anaconda.org/conda-forge/linux-64/libedit-3.1.20250104-pl5321h7949ede_0.conda#c277e0a4d549b03ac1e9d6cbbe3d017b https://conda.anaconda.org/conda-forge/linux-64/libevent-2.1.12-hf998b51_1.conda#a1cfcc585f0c42bf8d5546bb1dfb668d https://conda.anaconda.org/conda-forge/linux-64/libgettextpo-devel-0.24.1-h5888daf_0.conda#8f04c7aae6a46503bc36d1ed5abc8c7c -https://conda.anaconda.org/conda-forge/linux-64/libgfortran-14.2.0-h69a702a_2.conda#fb54c4ea68b460c278d26eea89cfbcc3 +https://conda.anaconda.org/conda-forge/linux-64/libgfortran-15.1.0-h69a702a_2.conda#f92e6e0a3c0c0c85561ef61aa59d555d https://conda.anaconda.org/conda-forge/linux-64/libgpg-error-1.55-h3f2d84a_0.conda#2bd47db5807daade8500ed7ca4c512a4 https://conda.anaconda.org/conda-forge/linux-64/libhwy-1.2.0-hf40a0c7_0.conda#2f433d593a66044c3f163cb25f0a09de https://conda.anaconda.org/conda-forge/linux-64/libnsl-2.0.1-hd590300_0.conda#30fd6e37fe21f86f4bd26d6ee73eeec7 https://conda.anaconda.org/conda-forge/linux-64/libpciaccess-0.18-hd590300_0.conda#48f4330bfcd959c3cfb704d424903c82 https://conda.anaconda.org/conda-forge/linux-64/libpng-1.6.47-h943b412_0.conda#55199e2ae2c3651f6f9b2a447b47bdc9 https://conda.anaconda.org/conda-forge/linux-64/libsanitizer-13.3.0-he8ea267_2.conda#2b6cdf7bb95d3d10ef4e38ce0bc95dba -https://conda.anaconda.org/conda-forge/linux-64/libsqlite-3.49.1-hee588c1_2.conda#962d6ac93c30b1dfc54c9cccafd1003e -https://conda.anaconda.org/conda-forge/linux-64/libstdcxx-ng-14.2.0-h4852527_2.conda#c75da67f045c2627f59e6fcb5f4e3a9b +https://conda.anaconda.org/conda-forge/linux-64/libsqlite-3.49.2-hee588c1_0.conda#93048463501053a00739215ea3f36324 +https://conda.anaconda.org/conda-forge/linux-64/libstdcxx-ng-15.1.0-h4852527_2.conda#9d2072af184b5caa29492bf2344597bb https://conda.anaconda.org/conda-forge/linux-64/libuuid-2.38.1-h0b41bf4_0.conda#40b61aab5c7ba9ff276c41cfffe6b80b https://conda.anaconda.org/conda-forge/linux-64/libxcb-1.17.0-h8a09558_0.conda#92ed62436b625154323d40d5f2f11dd7 https://conda.anaconda.org/conda-forge/linux-64/libxcrypt-4.4.36-hd590300_1.conda#5aa797f8787fe7a17d1b0821485b5adc https://conda.anaconda.org/conda-forge/linux-64/lz4-c-1.10.0-h5888daf_1.conda#9de5350a85c4a20c685259b889aa6393 https://conda.anaconda.org/conda-forge/linux-64/mpg123-1.32.9-hc50e24c_0.conda#c7f302fd11eeb0987a6a5e1f3aed6a21 -https://conda.anaconda.org/conda-forge/linux-64/mysql-common-9.0.1-h266115a_6.conda#94116b69829e90b72d566e64421e1bff https://conda.anaconda.org/conda-forge/linux-64/ninja-1.12.1-hff21bea_1.conda#2322531904f27501ee19847b87ba7c64 https://conda.anaconda.org/conda-forge/linux-64/nspr-4.36-h5888daf_0.conda#de9cd5bca9e4918527b9b72b6e2e1409 https://conda.anaconda.org/conda-forge/linux-64/pixman-0.46.0-h29eaf8c_0.conda#d2f1c87d4416d1e7344cf92b1aaee1c4 -https://conda.anaconda.org/conda-forge/linux-64/rav1e-0.6.6-he8a937b_2.conda#77d9955b4abddb811cb8ab1aa7d743e4 https://conda.anaconda.org/conda-forge/linux-64/readline-8.2-h8c095d6_2.conda#283b96675859b20a825f8fa30f311446 https://conda.anaconda.org/conda-forge/linux-64/snappy-1.2.1-h8bd8927_1.conda#3b3e64af585eadfb52bb90b553db5edf https://conda.anaconda.org/conda-forge/linux-64/svt-av1-3.0.2-h5888daf_0.conda#0096882bd623e6cc09e8bf920fc8fb47 @@ -96,7 +95,7 @@ https://conda.anaconda.org/conda-forge/linux-64/zstd-1.5.7-hb8e6e7a_2.conda#6432 https://conda.anaconda.org/conda-forge/linux-64/aom-3.9.1-hac33072_0.conda#346722a0be40f6edc53f12640d301338 https://conda.anaconda.org/conda-forge/linux-64/blosc-1.21.6-he440d0b_1.conda#2c2fae981fd2afd00812c92ac47d023d https://conda.anaconda.org/conda-forge/linux-64/brotli-bin-1.1.0-hb9d3cd8_2.conda#c63b5e52939e795ba8d26e35d767a843 -https://conda.anaconda.org/conda-forge/linux-64/c-blosc2-2.15.2-h3122c55_1.conda#2bc8d76acd818d7e79229f5157d5c156 +https://conda.anaconda.org/conda-forge/linux-64/c-blosc2-2.17.1-h3122c55_0.conda#009d16d3c9ed3e70d58ed46dab1571d1 https://conda.anaconda.org/conda-forge/linux-64/charls-2.4.2-h59595ed_0.conda#4336bd67920dd504cd8c6761d6a99645 https://conda.anaconda.org/conda-forge/linux-64/gcc_impl_linux-64-13.3.0-h1e990d8_2.conda#f46cf0acdcb6019397d37df1e407ab91 https://conda.anaconda.org/conda-forge/linux-64/graphite2-1.3.13-h59595ed_1003.conda#f87c7b7c2cb45f323ffbce941c78ab7c @@ -108,14 +107,13 @@ https://conda.anaconda.org/conda-forge/linux-64/libblas-3.9.0-31_h66dfbfd_blis.c https://conda.anaconda.org/conda-forge/linux-64/libcap-2.75-h39aace5_0.conda#c44c16d6976d2aebbd65894d7741e67e https://conda.anaconda.org/conda-forge/linux-64/libdrm-2.4.124-hb9d3cd8_0.conda#8bc89311041d7fcb510238cf0848ccae https://conda.anaconda.org/conda-forge/linux-64/libfreetype6-2.13.3-h48d6fc4_1.conda#3c255be50a506c50765a93a6644f32fe -https://conda.anaconda.org/conda-forge/linux-64/libgcrypt-lib-1.11.0-hb9d3cd8_2.conda#e55712ff40a054134d51b89afca57dbc -https://conda.anaconda.org/conda-forge/linux-64/libgfortran-ng-14.2.0-h69a702a_2.conda#4056c857af1a99ee50589a941059ec55 +https://conda.anaconda.org/conda-forge/linux-64/libgcrypt-lib-1.11.1-hb9d3cd8_0.conda#8504a291085c9fb809b66cabd5834307 +https://conda.anaconda.org/conda-forge/linux-64/libgfortran-ng-15.1.0-h69a702a_2.conda#a483a87b71e974bb75d1b9413d4436dd https://conda.anaconda.org/conda-forge/linux-64/libjxl-0.11.1-h7b0646d_1.conda#959fc2b6c0df7883e070b3fe525219a5 -https://conda.anaconda.org/conda-forge/linux-64/libtiff-4.7.0-hd9ff511_4.conda#6c1028898cf3a2032d9af46689e1b81a +https://conda.anaconda.org/conda-forge/linux-64/libtiff-4.7.0-hf01ce69_5.conda#e79a094918988bb1807462cd42c83962 https://conda.anaconda.org/conda-forge/linux-64/libvorbis-1.3.7-h9c3ff4c_0.tar.bz2#309dec04b70a3cc0f1e84a4013683bc0 https://conda.anaconda.org/conda-forge/linux-64/libzopfli-1.0.3-h9c3ff4c_0.tar.bz2#c66fe2d123249af7651ebde8984c51c2 -https://conda.anaconda.org/conda-forge/linux-64/mysql-libs-9.0.1-he0572af_6.conda#9802ae6d20982f42c0f5d69008988763 -https://conda.anaconda.org/conda-forge/linux-64/nss-3.110-h159eef7_0.conda#945659af183e87429c8aa7e0be3cc91d +https://conda.anaconda.org/conda-forge/linux-64/nss-3.111-h159eef7_0.conda#311e8370c9db254611ec87250f6370a0 https://conda.anaconda.org/conda-forge/linux-64/pcre2-10.45-hc749103_0.conda#b90bece58b4c2bf25969b70f3be42d25 https://conda.anaconda.org/conda-forge/linux-64/python-3.10.17-hd6af730_0_cpython.conda#7bb89638dae9ce1b8e051d0b721e83c2 https://conda.anaconda.org/conda-forge/linux-64/xcb-util-0.4.1-hb711507_2.conda#8637c3e5821654d0edf97e2b0404b443 @@ -128,18 +126,17 @@ https://conda.anaconda.org/conda-forge/noarch/alabaster-0.7.16-pyhd8ed1ab_0.cond https://conda.anaconda.org/conda-forge/noarch/appdirs-1.4.4-pyhd8ed1ab_1.conda#f4e90937bbfc3a4a92539545a37bb448 https://conda.anaconda.org/conda-forge/linux-64/brotli-1.1.0-hb9d3cd8_2.conda#98514fe74548d768907ce7a13f680e8f https://conda.anaconda.org/conda-forge/linux-64/brotli-python-1.1.0-py310hf71b8c6_2.conda#bf502c169c71e3c6ac0d6175addfacc2 -https://conda.anaconda.org/conda-forge/noarch/certifi-2025.1.31-pyhd8ed1ab_0.conda#c207fa5ac7ea99b149344385a9c0880d +https://conda.anaconda.org/conda-forge/noarch/certifi-2025.4.26-pyhd8ed1ab_0.conda#c33eeaaa33f45031be34cda513df39b6 https://conda.anaconda.org/conda-forge/noarch/charset-normalizer-3.4.2-pyhd8ed1ab_0.conda#40fe4284b8b5835a9073a645139f35af -https://conda.anaconda.org/conda-forge/noarch/click-8.1.8-pyh707e725_0.conda#f22f4d4970e09d68a10b922cbb0408d3 +https://conda.anaconda.org/conda-forge/noarch/click-8.2.1-pyh707e725_0.conda#94b550b8d3a614dbd326af798c7dfb40 https://conda.anaconda.org/conda-forge/noarch/cloudpickle-3.1.1-pyhd8ed1ab_0.conda#364ba6c9fb03886ac979b482f39ebb92 https://conda.anaconda.org/conda-forge/noarch/colorama-0.4.6-pyhd8ed1ab_1.conda#962b9857ee8e7018c22f2776ffa0b2d7 https://conda.anaconda.org/conda-forge/noarch/cycler-0.12.1-pyhd8ed1ab_1.conda#44600c4667a319d67dbe0681fc0bc833 https://conda.anaconda.org/conda-forge/linux-64/cyrus-sasl-2.1.27-h54b06d7_7.conda#dce22f70b4e5a407ce88f2be046f4ceb https://conda.anaconda.org/conda-forge/linux-64/cython-3.0.10-py310hc6cd4ac_0.conda#bd1d71ee240be36f1d85c86177d6964f https://conda.anaconda.org/conda-forge/noarch/docutils-0.21.2-pyhd8ed1ab_1.conda#24c1ca34138ee57de72a943237cde4cc -https://conda.anaconda.org/conda-forge/noarch/exceptiongroup-1.2.2-pyhd8ed1ab_1.conda#a16662747cdeb9abbac74d0057cc976e https://conda.anaconda.org/conda-forge/noarch/execnet-2.1.1-pyhd8ed1ab_1.conda#a71efeae2c160f6789900ba2631a2c90 -https://conda.anaconda.org/conda-forge/noarch/fsspec-2025.3.2-pyhd8ed1ab_0.conda#9c40692c3d24c7aaf335f673ac09d308 +https://conda.anaconda.org/conda-forge/noarch/fsspec-2025.5.1-pyhd8ed1ab_0.conda#2d2c9ef879a7e64e2dc657b09272c2b6 https://conda.anaconda.org/conda-forge/linux-64/gcc-13.3.0-h9576a4e_2.conda#d92e51bf4b6bdbfe45e5884fb0755afe https://conda.anaconda.org/conda-forge/linux-64/gcc_linux-64-13.3.0-hc28eda2_10.conda#d151142bbafe5e68ec7fc065c5e6f80c https://conda.anaconda.org/conda-forge/linux-64/gettext-0.24.1-h5888daf_0.conda#c63e7590d4d6f4c85721040ed8b12888 @@ -152,23 +149,23 @@ https://conda.anaconda.org/conda-forge/noarch/imagesize-1.4.1-pyhd8ed1ab_0.tar.b https://conda.anaconda.org/conda-forge/noarch/iniconfig-2.0.0-pyhd8ed1ab_1.conda#6837f3eff7dcea42ecd714ce1ac2b108 https://conda.anaconda.org/conda-forge/linux-64/kiwisolver-1.4.7-py310h3788b33_0.conda#4186d9b4d004b0fe0de6aa62496fb48a https://conda.anaconda.org/conda-forge/linux-64/lcms2-2.17-h717163a_0.conda#000e85703f0fd9594c81710dd5066471 -https://conda.anaconda.org/conda-forge/linux-64/libavif16-1.2.1-hbb36593_2.conda#971387a27e61235b97cacb440a37e991 +https://conda.anaconda.org/conda-forge/linux-64/libavif16-1.3.0-h766b0b6_0.conda#f17f2d0e5c9ad6b958547fd67b155771 https://conda.anaconda.org/conda-forge/linux-64/libcblas-3.9.0-31_hba4ea11_blis.conda#1ea7ae3db0fea0c5222388d841583c51 https://conda.anaconda.org/conda-forge/linux-64/libcups-2.3.3-h4637d8d_4.conda#d4529f4dff3057982a7617c7ac58fde3 https://conda.anaconda.org/conda-forge/linux-64/libfreetype-2.13.3-ha770c72_1.conda#51f5be229d83ecd401fb369ab96ae669 -https://conda.anaconda.org/conda-forge/linux-64/libglib-2.84.1-h3618099_1.conda#714c97d4ff495ab69d1fdfcadbcae985 +https://conda.anaconda.org/conda-forge/linux-64/libglib-2.84.2-h3618099_0.conda#072ab14a02164b7c0c089055368ff776 https://conda.anaconda.org/conda-forge/linux-64/libglx-1.7.0-ha4b6fd6_2.conda#c8013e438185f33b13814c5c488acd5c https://conda.anaconda.org/conda-forge/linux-64/liblapack-3.9.0-12_hd37a5e2_netlib.conda#4b181b55915cefcd35c8398c9274e629 https://conda.anaconda.org/conda-forge/linux-64/libsystemd0-257.4-h4e0b6ca_1.conda#04bcf3055e51f8dde6fab9672fb9fca0 -https://conda.anaconda.org/conda-forge/linux-64/libxml2-2.13.7-h4bc477f_1.conda#ad1f1f8238834cd3c88ceeaee8da444a +https://conda.anaconda.org/conda-forge/linux-64/libxml2-2.13.8-h4bc477f_0.conda#14dbe05b929e329dbaa6f2d0aa19466d https://conda.anaconda.org/conda-forge/noarch/locket-1.0.0-pyhd8ed1ab_0.tar.bz2#91e27ef3d05cc772ce627e51cff111c4 https://conda.anaconda.org/conda-forge/linux-64/markupsafe-3.0.2-py310h89163eb_1.conda#8ce3f0332fd6de0d737e2911d329523f -https://conda.anaconda.org/conda-forge/noarch/meson-1.8.0-pyh29332c3_0.conda#8e25221b702272394b86b0f4d7217f77 +https://conda.anaconda.org/conda-forge/noarch/meson-1.8.1-pyhe01879c_0.conda#f3cccd9a6ce5331ae33f69ade5529162 https://conda.anaconda.org/conda-forge/noarch/munkres-1.1.4-pyh9f0ad1d_0.tar.bz2#2ba8498c1018c1e9c61eb99b973dfe19 https://conda.anaconda.org/conda-forge/noarch/networkx-3.2-pyhd8ed1ab_0.conda#cec8cc498664cc00a070676aa89e69a7 https://conda.anaconda.org/conda-forge/linux-64/openjpeg-2.5.3-h5fbd93e_0.conda#9e5816bc95d285c115a3ebc2f8563564 https://conda.anaconda.org/conda-forge/noarch/packaging-25.0-pyh29332c3_1.conda#58335b26c38bf4a20f399384c33cbcf9 -https://conda.anaconda.org/conda-forge/noarch/pluggy-1.5.0-pyhd8ed1ab_1.conda#e9dcbce5f45f9ee500e728ae58b605b6 +https://conda.anaconda.org/conda-forge/noarch/pluggy-1.6.0-pyhd8ed1ab_0.conda#7da7ccd349dbf6487a7778579d2bb971 https://conda.anaconda.org/conda-forge/noarch/ply-3.11-pyhd8ed1ab_3.conda#fd5062942bfa1b0bd5e0d2a4397b099e https://conda.anaconda.org/conda-forge/linux-64/psutil-7.0.0-py310ha75aee5_0.conda#da7d592394ff9084a23f62a1186451a2 https://conda.anaconda.org/conda-forge/noarch/pycparser-2.22-pyh29332c3_1.conda#12c566707c80111f9799308d9e265aef @@ -177,17 +174,17 @@ https://conda.anaconda.org/conda-forge/noarch/pyparsing-3.2.3-pyhd8ed1ab_1.conda https://conda.anaconda.org/conda-forge/noarch/pysocks-1.7.1-pyha55dd90_7.conda#461219d1a5bd61342293efa2c0c90eac https://conda.anaconda.org/conda-forge/noarch/pytz-2025.2-pyhd8ed1ab_0.conda#bc8e3267d44011051f2eb14d22fb0960 https://conda.anaconda.org/conda-forge/linux-64/pyyaml-6.0.2-py310h89163eb_2.conda#fd343408e64cf1e273ab7c710da374db -https://conda.anaconda.org/conda-forge/noarch/setuptools-80.1.0-pyhff2d567_0.conda#f6f72d0837c79eaec77661be43e8a691 +https://conda.anaconda.org/conda-forge/noarch/setuptools-80.8.0-pyhff2d567_0.conda#ea075e94dc0106c7212128b6a25bbc4c https://conda.anaconda.org/conda-forge/noarch/six-1.17.0-pyhd8ed1ab_0.conda#a451d576819089b0d672f18768be0f65 -https://conda.anaconda.org/conda-forge/noarch/snowballstemmer-2.2.0-pyhd8ed1ab_0.tar.bz2#4d22a9315e78c6827f806065957d566e -https://conda.anaconda.org/conda-forge/noarch/soupsieve-2.5-pyhd8ed1ab_1.conda#3f144b2c34f8cb5a9abd9ed23a39c561 +https://conda.anaconda.org/conda-forge/noarch/snowballstemmer-3.0.1-pyhd8ed1ab_0.conda#755cf22df8693aa0d1aec1c123fa5863 +https://conda.anaconda.org/conda-forge/noarch/soupsieve-2.7-pyhd8ed1ab_0.conda#fb32097c717486aa34b38a9db57eb49e https://conda.anaconda.org/conda-forge/noarch/sphinxcontrib-jsmath-1.0.1-pyhd8ed1ab_1.conda#fa839b5ff59e192f411ccc7dae6588bb https://conda.anaconda.org/conda-forge/noarch/tenacity-9.1.2-pyhd8ed1ab_0.conda#5d99943f2ae3cc69e1ada12ce9d4d701 https://conda.anaconda.org/conda-forge/noarch/threadpoolctl-3.6.0-pyhecae5ae_0.conda#9d64911b31d57ca443e9f1e36b04385f https://conda.anaconda.org/conda-forge/noarch/toml-0.10.2-pyhd8ed1ab_1.conda#b0dd904de08b7db706167240bf37b164 https://conda.anaconda.org/conda-forge/noarch/tomli-2.2.1-pyhd8ed1ab_1.conda#ac944244f1fed2eb49bae07193ae8215 https://conda.anaconda.org/conda-forge/noarch/toolz-1.0.0-pyhd8ed1ab_1.conda#40d0ed782a8aaa16ef248e68c06c168d -https://conda.anaconda.org/conda-forge/linux-64/tornado-6.4.2-py310ha75aee5_0.conda#166d59aab40b9c607b4cc21c03924e9d +https://conda.anaconda.org/conda-forge/linux-64/tornado-6.5.1-py310ha75aee5_0.conda#6f3da1072c0c4d2a1beb1e84615f7c9c https://conda.anaconda.org/conda-forge/noarch/typing_extensions-4.13.2-pyh29332c3_0.conda#83fc6ae00127671e301c9f44254c31b8 https://conda.anaconda.org/conda-forge/linux-64/unicodedata2-16.0.0-py310ha75aee5_0.conda#1d7a4b9202cdd10d56ecdd7f6c347190 https://conda.anaconda.org/conda-forge/noarch/wheel-0.45.1-pyhd8ed1ab_1.conda#75cb7132eb58d97896e173ef12ac9986 @@ -203,57 +200,60 @@ https://conda.anaconda.org/conda-forge/linux-64/brunsli-0.1-h9c3ff4c_0.tar.bz2#c https://conda.anaconda.org/conda-forge/linux-64/c-compiler-1.9.0-h2b85faf_0.conda#3cb814f83f1f71ac1985013697f80cc1 https://conda.anaconda.org/conda-forge/linux-64/cffi-1.17.1-py310h8deb56e_0.conda#1fc24a3196ad5ede2a68148be61894f4 https://conda.anaconda.org/conda-forge/linux-64/cytoolz-1.0.1-py310ha75aee5_0.conda#d0be1adaa04a03aed745f3d02afb59ce -https://conda.anaconda.org/conda-forge/linux-64/dbus-1.13.6-h5008d03_3.tar.bz2#ecfff944ba3960ecb334b9a2663d708d -https://conda.anaconda.org/conda-forge/linux-64/fonttools-4.57.0-py310h89163eb_0.conda#34378af82141b3c1725dcdf898b28fc6 +https://conda.anaconda.org/conda-forge/linux-64/dbus-1.16.2-h3c4dab8_0.conda#679616eb5ad4e521c83da4650860aba7 +https://conda.anaconda.org/conda-forge/noarch/exceptiongroup-1.3.0-pyhd8ed1ab_0.conda#72e42d28960d875c7654614f8b50939a +https://conda.anaconda.org/conda-forge/linux-64/fonttools-4.58.0-py310h89163eb_0.conda#4532df8a45ab4e37b2cc71186304dd5a https://conda.anaconda.org/conda-forge/linux-64/freetype-2.13.3-ha770c72_1.conda#9ccd736d31e0c6e41f54e704e5312811 https://conda.anaconda.org/conda-forge/linux-64/gfortran-13.3.0-h9576a4e_2.conda#19e6d3c9cde10a0a9a170a684082588e https://conda.anaconda.org/conda-forge/linux-64/gfortran_linux-64-13.3.0-hb919d3a_10.conda#7ce070e3329cd10bf79dbed562a21bd4 -https://conda.anaconda.org/conda-forge/linux-64/glib-tools-2.84.1-h4833e2c_1.conda#418de18c9b79a3d8583d90d27e0937c2 +https://conda.anaconda.org/conda-forge/linux-64/glib-tools-2.84.2-h4833e2c_0.conda#f2ec1facec64147850b7674633978050 https://conda.anaconda.org/conda-forge/linux-64/gxx-13.3.0-h9576a4e_2.conda#07e8df00b7cd3084ad3ef598ce32a71c https://conda.anaconda.org/conda-forge/linux-64/gxx_linux-64-13.3.0-h6834431_10.conda#9a8ebde471cec5cc9c48f8682f434f92 https://conda.anaconda.org/conda-forge/noarch/h2-4.2.0-pyhd8ed1ab_0.conda#b4754fb1bdcb70c8fd54f918301582c6 -https://conda.anaconda.org/conda-forge/noarch/importlib-metadata-8.6.1-pyha770c72_0.conda#f4b39bf00c69f56ac01e020ebfac066c +https://conda.anaconda.org/conda-forge/noarch/importlib-metadata-8.7.0-pyhe01879c_1.conda#63ccfdc3a3ce25b027b8767eb722fca8 https://conda.anaconda.org/conda-forge/noarch/importlib_resources-6.5.2-pyhd8ed1ab_0.conda#c85c76dc67d75619a92f51dfbce06992 https://conda.anaconda.org/conda-forge/noarch/jinja2-3.1.6-pyhd8ed1ab_0.conda#446bd6c8cb26050d528881df495ce646 -https://conda.anaconda.org/conda-forge/noarch/joblib-1.5.0-pyhd8ed1ab_0.conda#3d7257f0a61c9aa4ffa3e324a887416b +https://conda.anaconda.org/conda-forge/noarch/joblib-1.5.1-pyhd8ed1ab_0.conda#fb1c14694de51a476ce8636d92b6f42c https://conda.anaconda.org/conda-forge/linux-64/libflac-1.4.3-h59595ed_0.conda#ee48bf17cc83a00f59ca1494d5646869 https://conda.anaconda.org/conda-forge/linux-64/libgl-1.7.0-ha4b6fd6_2.conda#928b8be80851f5d8ffb016f9c81dae7a https://conda.anaconda.org/conda-forge/linux-64/liblapacke-3.9.0-12_hce4cc19_netlib.conda#bdcf65db13abdddba7af29592f93600b -https://conda.anaconda.org/conda-forge/linux-64/libllvm20-20.1.4-he9d0ab4_0.conda#96c33bbd084ef2b2463503fb7f1482ae -https://conda.anaconda.org/conda-forge/linux-64/libxkbcommon-1.9.1-h65c71a3_0.conda#6e45090fe0eec179ecc8041a3a3fc9f8 +https://conda.anaconda.org/conda-forge/linux-64/libllvm20-20.1.5-he9d0ab4_0.conda#8d2f5a2f019bd76ccba5eb771852d411 +https://conda.anaconda.org/conda-forge/linux-64/libxkbcommon-1.10.0-h65c71a3_0.conda#fedf6bfe5d21d21d2b1785ec00a8889a https://conda.anaconda.org/conda-forge/noarch/memory_profiler-0.61.0-pyhd8ed1ab_1.conda#71abbefb6f3b95e1668cd5e0af3affb9 https://conda.anaconda.org/conda-forge/linux-64/numpy-1.22.0-py310h454958d_1.tar.bz2#607c66f0cce2986515a8fe9e136b2b57 -https://conda.anaconda.org/conda-forge/linux-64/openldap-2.6.9-he970967_0.conda#ca2de8bbdc871bce41dbf59e51324165 +https://conda.anaconda.org/conda-forge/linux-64/openldap-2.6.10-he970967_0.conda#2e5bf4f1da39c0b32778561c3c4e5878 https://conda.anaconda.org/conda-forge/noarch/partd-1.4.2-pyhd8ed1ab_0.conda#0badf9c54e24cecfb0ad2f99d680c163 +https://conda.anaconda.org/conda-forge/linux-64/pillow-11.2.1-py310h7e6dc6c_0.conda#5645a243d90adb50909b9edc209d84fe https://conda.anaconda.org/conda-forge/noarch/pip-25.1.1-pyh8b19718_0.conda#32d0781ace05105cc99af55d36cbec7c https://conda.anaconda.org/conda-forge/noarch/plotly-5.14.0-pyhd8ed1ab_0.conda#6a7bcc42ef58dd6cf3da9333ea102433 https://conda.anaconda.org/conda-forge/noarch/pyproject-metadata-0.9.1-pyhd8ed1ab_0.conda#22ae7c6ea81e0c8661ef32168dda929b -https://conda.anaconda.org/conda-forge/noarch/pytest-8.3.5-pyhd8ed1ab_0.conda#c3c9316209dec74a705a36797970c6be https://conda.anaconda.org/conda-forge/noarch/python-dateutil-2.9.0.post0-pyhff2d567_1.conda#5ba79d7c71f03c678c8ead841f347d6e -https://conda.anaconda.org/conda-forge/linux-64/sip-6.8.6-py310hf71b8c6_2.conda#a50d1007fecaff3f98b19034a8e0b2e7 +https://conda.anaconda.org/conda-forge/linux-64/sip-6.10.0-py310hf71b8c6_0.conda#2d7e4445be227e8210140b75725689ad https://conda.anaconda.org/conda-forge/noarch/typing-extensions-4.13.2-h0e9735f_0.conda#568ed1300869dca0ba09fb750cda5dbb +https://conda.anaconda.org/conda-forge/linux-64/xorg-libxcomposite-0.4.6-hb9d3cd8_2.conda#d3c295b50f092ab525ffe3c2aa4b7413 https://conda.anaconda.org/conda-forge/linux-64/xorg-libxdamage-1.1.6-hb9d3cd8_0.conda#b5fcc7172d22516e1f965490e65e33a4 https://conda.anaconda.org/conda-forge/linux-64/xorg-libxxf86vm-1.1.6-hb9d3cd8_0.conda#5efa5fa6243a622445fdfd72aee15efa https://conda.anaconda.org/conda-forge/noarch/beautifulsoup4-4.13.4-pyha770c72_0.conda#9f07c4fc992adb2d6c30da7fab3959a7 https://conda.anaconda.org/conda-forge/linux-64/blas-devel-3.9.0-31_hdec4247_blis.conda#1675e95a742c910204645f7b6d7e56dc https://conda.anaconda.org/conda-forge/linux-64/cxx-compiler-1.9.0-h1a2810e_0.conda#1ce8b218d359d9ed0ab481f2a3f3c512 -https://conda.anaconda.org/conda-forge/noarch/dask-core-2025.4.1-pyhd8ed1ab_0.conda#0735ecef025a6c2d6eb61aae4785fc3f +https://conda.anaconda.org/conda-forge/noarch/dask-core-2025.5.1-pyhd8ed1ab_0.conda#8f0ef561cd615a17df3256742a3457c4 https://conda.anaconda.org/conda-forge/linux-64/fontconfig-2.15.0-h7e30c49_1.conda#8f5b0b297b59e1ac160ad4beec99dbee https://conda.anaconda.org/conda-forge/linux-64/fortran-compiler-1.9.0-h36df796_0.conda#cc0cf942201f9d3b0e9654ea02e12486 -https://conda.anaconda.org/conda-forge/linux-64/glib-2.84.1-h6287aef_1.conda#35012688d30e1b52bff2ba5d1f342a50 -https://conda.anaconda.org/conda-forge/linux-64/imagecodecs-2024.12.30-py310h78a9a29_0.conda#e0c50079904122427bcf52e1afcd1cdb +https://conda.anaconda.org/conda-forge/linux-64/glib-2.84.2-h6287aef_0.conda#704648df3a01d4d24bc2c0466b718d63 +https://conda.anaconda.org/conda-forge/linux-64/imagecodecs-2024.12.30-py310h481ba9f_1.conda#1a0a3b184dec933b4922a2721b3150a0 +https://conda.anaconda.org/conda-forge/noarch/imageio-2.37.0-pyhfb79c49_0.conda#b5577bc2212219566578fd5af9993af6 https://conda.anaconda.org/conda-forge/noarch/importlib-resources-6.5.2-pyhd8ed1ab_0.conda#e376ea42e9ae40f3278b0f79c9bf9826 -https://conda.anaconda.org/conda-forge/linux-64/libclang-cpp20.1-20.1.4-default_h1df26ce_0.conda#96f8d5b2e94c9ba4fef19f1adf068a15 -https://conda.anaconda.org/conda-forge/linux-64/libclang13-20.1.4-default_he06ed0a_0.conda#2d933632c8004be47deb2be61bf013be -https://conda.anaconda.org/conda-forge/linux-64/libpq-17.4-h27ae623_1.conda#37fba334855ef3b51549308e61ed7a3d +https://conda.anaconda.org/conda-forge/linux-64/libclang-cpp20.1-20.1.5-default_h1df26ce_1.conda#330b1dadfa7c3205a01fa9599fabe808 +https://conda.anaconda.org/conda-forge/linux-64/libclang13-20.1.5-default_he06ed0a_1.conda#12117145218e7e1a528c8396ed803058 +https://conda.anaconda.org/conda-forge/linux-64/libpq-17.5-h27ae623_0.conda#6458be24f09e1b034902ab44fe9de908 https://conda.anaconda.org/conda-forge/linux-64/libsndfile-1.2.2-hc60ed4a_1.conda#ef1910918dd895516a769ed36b5b3a4e -https://conda.anaconda.org/conda-forge/noarch/meson-python-0.17.1-pyh70fd9c4_1.conda#7a02679229c6c2092571b4c025055440 +https://conda.anaconda.org/conda-forge/linux-64/matplotlib-base-3.5.0-py310h23f4a51_0.tar.bz2#9911225650b298776c8e8c083b5cacf1 +https://conda.anaconda.org/conda-forge/noarch/meson-python-0.18.0-pyh70fd9c4_0.conda#576c04b9d9f8e45285fb4d9452c26133 https://conda.anaconda.org/conda-forge/linux-64/pandas-1.4.0-py310hb5077e9_0.tar.bz2#43e920bc9856daa7d8d18fcbfb244c4e https://conda.anaconda.org/conda-forge/noarch/patsy-1.0.1-pyhd8ed1ab_1.conda#ee23fabfd0a8c6b8d6f3729b47b2859d -https://conda.anaconda.org/conda-forge/linux-64/pillow-11.1.0-py310h7e6dc6c_0.conda#14d300b9e1504748e70cc6499a7b4d25 https://conda.anaconda.org/conda-forge/linux-64/polars-0.20.30-py310h031f9ce_0.conda#0743f5db9f978b6df92d412935ff8371 -https://conda.anaconda.org/conda-forge/linux-64/pyqt5-sip-12.13.0-py310hf71b8c6_1.conda#0c8cbfbe70f4c8a47b040a14615e6f1f -https://conda.anaconda.org/conda-forge/noarch/pytest-xdist-3.6.1-pyhd8ed1ab_1.conda#59aad4fb37cabc0bacc73cf344612ddd +https://conda.anaconda.org/conda-forge/linux-64/pyqt5-sip-12.17.0-py310hf71b8c6_0.conda#012465861673a67a30bc8ca6284074f3 +https://conda.anaconda.org/conda-forge/noarch/pytest-8.3.5-pyhd8ed1ab_0.conda#c3c9316209dec74a705a36797970c6be https://conda.anaconda.org/conda-forge/linux-64/pywavelets-1.6.0-py310h261611a_0.conda#04a405ee0bccb4de8d1ed0c87704f5f6 https://conda.anaconda.org/conda-forge/linux-64/scipy-1.8.0-py310hea5193d_1.tar.bz2#664d80ddeb51241629b3ada5ea926e4d https://conda.anaconda.org/conda-forge/linux-64/zstandard-0.23.0-py310ha75aee5_2.conda#f9254b5b0193982416b91edcb4b2676f @@ -261,23 +261,22 @@ https://conda.anaconda.org/conda-forge/linux-64/blas-2.131-blis.conda#87829e6b9f https://conda.anaconda.org/conda-forge/linux-64/cairo-1.18.4-h3394656_0.conda#09262e66b19567aff4f592fb53b28760 https://conda.anaconda.org/conda-forge/linux-64/compilers-1.9.0-ha770c72_0.conda#5859096e397aba423340d0bbbb11ec64 https://conda.anaconda.org/conda-forge/linux-64/gstreamer-1.24.11-hc37bda9_0.conda#056d86cacf2b48c79c6a562a2486eb8c -https://conda.anaconda.org/conda-forge/noarch/imageio-2.37.0-pyhfb79c49_0.conda#b5577bc2212219566578fd5af9993af6 -https://conda.anaconda.org/conda-forge/linux-64/matplotlib-base-3.5.0-py310h23f4a51_0.tar.bz2#9911225650b298776c8e8c083b5cacf1 https://conda.anaconda.org/conda-forge/linux-64/pulseaudio-client-17.0-hac146a9_1.conda#66b1fa9608d8836e25f9919159adc9c6 https://conda.anaconda.org/conda-forge/linux-64/pyamg-4.2.1-py310h7c3ba0c_0.tar.bz2#89f5a48e1f23b5cf3163a6094903d181 +https://conda.anaconda.org/conda-forge/noarch/pytest-xdist-3.6.1-pyhd8ed1ab_1.conda#59aad4fb37cabc0bacc73cf344612ddd +https://conda.anaconda.org/conda-forge/noarch/seaborn-base-0.13.2-pyhd8ed1ab_3.conda#fd96da444e81f9e6fcaac38590f3dd42 https://conda.anaconda.org/conda-forge/linux-64/statsmodels-0.14.2-py310h261611a_0.conda#4b8508bab02b2aa2cef12eab4883f4a1 -https://conda.anaconda.org/conda-forge/noarch/tifffile-2025.3.30-pyhd8ed1ab_0.conda#14f46147fae19bb867f82a787c7059e9 +https://conda.anaconda.org/conda-forge/noarch/tifffile-2025.5.10-pyhd8ed1ab_0.conda#1fdb801f28bf4987294c49aaa314bf5e https://conda.anaconda.org/conda-forge/noarch/towncrier-24.8.0-pyhd8ed1ab_1.conda#820b6a1ddf590fba253f8204f7200d82 https://conda.anaconda.org/conda-forge/noarch/urllib3-2.4.0-pyhd8ed1ab_0.conda#c1e349028e0052c4eea844e94f773065 https://conda.anaconda.org/conda-forge/linux-64/gst-plugins-base-1.24.11-h651a532_0.conda#d8d8894f8ced2c9be76dc9ad1ae531ce -https://conda.anaconda.org/conda-forge/linux-64/harfbuzz-11.1.0-h3beb420_0.conda#95e3bb97f9cdc251c0c68640e9c10ed3 +https://conda.anaconda.org/conda-forge/linux-64/harfbuzz-11.2.1-h3beb420_0.conda#0e6e192d4b3d95708ad192d957cf3163 https://conda.anaconda.org/conda-forge/noarch/requests-2.32.3-pyhd8ed1ab_1.conda#a9b9368f3701a417eac9edbcae7cb737 https://conda.anaconda.org/conda-forge/linux-64/scikit-image-0.19.0-py310hb5077e9_0.tar.bz2#aa24b3a4aa979641ac3144405209cd89 -https://conda.anaconda.org/conda-forge/noarch/seaborn-base-0.13.2-pyhd8ed1ab_3.conda#fd96da444e81f9e6fcaac38590f3dd42 -https://conda.anaconda.org/conda-forge/noarch/pooch-1.6.0-pyhd8ed1ab_0.tar.bz2#6429e1d1091c51f626b5dcfdd38bf429 -https://conda.anaconda.org/conda-forge/linux-64/qt-main-5.15.15-h993ce98_3.conda#aa49f5308f39277477d47cd6687eb8f3 https://conda.anaconda.org/conda-forge/noarch/seaborn-0.13.2-hd8ed1ab_3.conda#62afb877ca2c2b4b6f9ecb37320085b6 -https://conda.anaconda.org/conda-forge/linux-64/pyqt-5.15.10-py310hb3b5edb_1.conda#c370972fc4557cb54d265c9c1f71bd20 +https://conda.anaconda.org/conda-forge/noarch/pooch-1.6.0-pyhd8ed1ab_0.tar.bz2#6429e1d1091c51f626b5dcfdd38bf429 +https://conda.anaconda.org/conda-forge/linux-64/qt-main-5.15.15-hea1682b_4.conda#c054d7f22cc719e12c72d454b2328d6c +https://conda.anaconda.org/conda-forge/linux-64/pyqt-5.15.11-py310hf392a12_0.conda#65924d3e57be25342c76530d23d75f0f https://conda.anaconda.org/conda-forge/linux-64/matplotlib-3.5.0-py310hff52083_0.tar.bz2#1b2f3b135d5d9c594b5e0e6150c03b7b https://conda.anaconda.org/conda-forge/noarch/numpydoc-1.2-pyhd8ed1ab_0.tar.bz2#025ad7ca2c7f65007ab6b6f5d93a56eb https://conda.anaconda.org/conda-forge/noarch/pydata-sphinx-theme-0.15.3-pyhd8ed1ab_0.conda#55e445f4fcb07f2471fb0e1102d36488 diff --git a/build_tools/github/pylatest_conda_forge_cuda_array-api_linux-64_conda.lock b/build_tools/github/pylatest_conda_forge_cuda_array-api_linux-64_conda.lock index 8a707637fbc9b..78846708d0a03 100644 --- a/build_tools/github/pylatest_conda_forge_cuda_array-api_linux-64_conda.lock +++ b/build_tools/github/pylatest_conda_forge_cuda_array-api_linux-64_conda.lock @@ -1,6 +1,6 @@ # Generated by conda-lock. # platform: linux-64 -# input_hash: e141e0789f4a2b4be527fb91bb83f873bd14718407fa58b8790d2198f61bc6f5 +# input_hash: 0c167b26e12c284b769bf4d76bd3e604db266ed21c8f9e11e4bb737419ccdc93 @EXPLICIT https://conda.anaconda.org/conda-forge/noarch/cuda-version-11.8-h70ddcb2_3.conda#670f0e1593b8c1d84f57ad5fe5256799 https://conda.anaconda.org/conda-forge/noarch/font-ttf-dejavu-sans-mono-2.37-hab24e00_0.tar.bz2#0c96522c6bdaed4b1566d11387caaf45 @@ -16,27 +16,27 @@ https://conda.anaconda.org/conda-forge/noarch/ca-certificates-2025.4.26-hbd8a1cb https://conda.anaconda.org/conda-forge/noarch/fonts-conda-forge-1-0.tar.bz2#f766549260d6815b0c52253f1fb1bb29 https://conda.anaconda.org/conda-forge/linux-64/ld_impl_linux-64-2.43-h712a8e2_4.conda#01f8d123c96816249efd255a31ad7712 https://conda.anaconda.org/conda-forge/linux-64/libglvnd-1.7.0-ha4b6fd6_2.conda#434ca7e50e40f4918ab701e3facd59a0 -https://conda.anaconda.org/conda-forge/linux-64/llvm-openmp-20.1.4-h024ca30_0.conda#4fc395cda27912a7d904b86b5dbf3a4d +https://conda.anaconda.org/conda-forge/linux-64/llvm-openmp-20.1.5-h024ca30_0.conda#86f58be65a51d62ccc06cacfd83ff987 https://conda.anaconda.org/conda-forge/noarch/sysroot_linux-64-2.17-h0157908_18.conda#460eba7851277ec1fd80a1a24080787a https://conda.anaconda.org/conda-forge/linux-64/_openmp_mutex-4.5-3_kmp_llvm.conda#ee5c2118262e30b972bc0b4db8ef0ba5 https://conda.anaconda.org/conda-forge/noarch/fonts-conda-ecosystem-1-0.tar.bz2#fee5683a3f04bd15cbd8318b096a27ab https://conda.anaconda.org/conda-forge/linux-64/libegl-1.7.0-ha4b6fd6_2.conda#c151d5eb730e9b7480e6d48c0fc44048 https://conda.anaconda.org/conda-forge/linux-64/libopengl-1.7.0-ha4b6fd6_2.conda#7df50d44d4a14d6c31a2c54f2cd92157 -https://conda.anaconda.org/conda-forge/linux-64/libgcc-14.2.0-h767d61c_2.conda#ef504d1acbd74b7cc6849ef8af47dd03 +https://conda.anaconda.org/conda-forge/linux-64/libgcc-15.1.0-h767d61c_2.conda#ea8ac52380885ed41c1baa8f1d6d2b93 https://conda.anaconda.org/conda-forge/linux-64/alsa-lib-1.2.14-hb9d3cd8_0.conda#76df83c2a9035c54df5d04ff81bcc02d https://conda.anaconda.org/conda-forge/linux-64/aws-c-common-0.12.0-hb9d3cd8_0.conda#f65c946f28f0518f41ced702f44c52b7 https://conda.anaconda.org/conda-forge/linux-64/c-ares-1.34.5-hb9d3cd8_0.conda#f7f0d6cc2dc986d42ac2689ec88192be https://conda.anaconda.org/conda-forge/linux-64/libbrotlicommon-1.1.0-hb9d3cd8_2.conda#41b599ed2b02abcfdd84302bff174b23 -https://conda.anaconda.org/conda-forge/linux-64/libdeflate-1.23-h86f0d12_0.conda#27fe770decaf469a53f3e3a6d593067f +https://conda.anaconda.org/conda-forge/linux-64/libdeflate-1.24-h86f0d12_0.conda#64f0c503da58ec25ebd359e4d990afa8 https://conda.anaconda.org/conda-forge/linux-64/libexpat-2.7.0-h5888daf_0.conda#db0bfbe7dd197b68ad5f30333bae6ce0 https://conda.anaconda.org/conda-forge/linux-64/libffi-3.4.6-h2dba641_1.conda#ede4673863426c0883c0063d853bbd85 -https://conda.anaconda.org/conda-forge/linux-64/libgcc-ng-14.2.0-h69a702a_2.conda#a2222a6ada71fb478682efe483ce0f92 -https://conda.anaconda.org/conda-forge/linux-64/libgfortran5-14.2.0-hf1ad2bd_2.conda#556a4fdfac7287d349b8f09aba899693 +https://conda.anaconda.org/conda-forge/linux-64/libgcc-ng-15.1.0-h69a702a_2.conda#ddca86c7040dd0e73b2b69bd7833d225 +https://conda.anaconda.org/conda-forge/linux-64/libgfortran5-15.1.0-hcea5267_2.conda#01de444988ed960031dbe84cf4f9b1fc https://conda.anaconda.org/conda-forge/linux-64/libiconv-1.18-h4ce23a2_1.conda#e796ff8ddc598affdf7c173d6145f087 https://conda.anaconda.org/conda-forge/linux-64/libjpeg-turbo-3.1.0-hb9d3cd8_0.conda#9fa334557db9f63da6c9285fd2a48638 -https://conda.anaconda.org/conda-forge/linux-64/liblzma-5.8.1-hb9d3cd8_0.conda#0e87378639676987af32fee53ba32258 +https://conda.anaconda.org/conda-forge/linux-64/liblzma-5.8.1-hb9d3cd8_1.conda#a76fd702c93cd2dfd89eff30a5fd45a8 https://conda.anaconda.org/conda-forge/linux-64/libntlm-1.8-hb9d3cd8_0.conda#7c7927b404672409d9917d49bff5f2d6 -https://conda.anaconda.org/conda-forge/linux-64/libstdcxx-14.2.0-h8f9b012_2.conda#a78c856b6dc6bf4ea8daeb9beaaa3fb0 +https://conda.anaconda.org/conda-forge/linux-64/libstdcxx-15.1.0-h8f9b012_2.conda#1cb1c67961f6dd257eae9e9691b341aa https://conda.anaconda.org/conda-forge/linux-64/libutf8proc-2.10.0-h4c51ac1_0.conda#aeccfff2806ae38430638ffbb4be9610 https://conda.anaconda.org/conda-forge/linux-64/libuv-1.50.0-hb9d3cd8_0.conda#771ee65e13bc599b0b62af5359d80169 https://conda.anaconda.org/conda-forge/linux-64/libwebp-base-1.5.0-h851e524_0.conda#63f790534398730f59e1b899c3644d4a @@ -53,7 +53,6 @@ https://conda.anaconda.org/conda-forge/linux-64/aws-c-sdkutils-0.2.3-h3870646_2. https://conda.anaconda.org/conda-forge/linux-64/aws-checksums-0.2.3-h3870646_2.conda#303d9e83e0518f1dcb66e90054635ca6 https://conda.anaconda.org/conda-forge/linux-64/bzip2-1.0.8-h4bc722e_7.conda#62ee74e96c5ebb0af99386de58cf9553 https://conda.anaconda.org/conda-forge/linux-64/double-conversion-3.3.1-h5888daf_0.conda#bfd56492d8346d669010eccafe0ba058 -https://conda.anaconda.org/conda-forge/linux-64/expat-2.7.0-h5888daf_0.conda#d6845ae4dea52a2f90178bf1829a21f8 https://conda.anaconda.org/conda-forge/linux-64/gflags-2.2.2-h5888daf_1005.conda#d411fc29e338efb48c5fd4576d71d881 https://conda.anaconda.org/conda-forge/linux-64/keyutils-1.6.1-h166bdaf_0.tar.bz2#30186d27e2c9fa62b45fb1476b7200e3 https://conda.anaconda.org/conda-forge/linux-64/lerc-4.0.0-h0aef613_1.conda#9344155d33912347b37f0ae6c410a835 @@ -63,17 +62,16 @@ https://conda.anaconda.org/conda-forge/linux-64/libbrotlienc-1.1.0-hb9d3cd8_2.co https://conda.anaconda.org/conda-forge/linux-64/libedit-3.1.20250104-pl5321h7949ede_0.conda#c277e0a4d549b03ac1e9d6cbbe3d017b https://conda.anaconda.org/conda-forge/linux-64/libev-4.33-hd590300_2.conda#172bf1cd1ff8629f2b1179945ed45055 https://conda.anaconda.org/conda-forge/linux-64/libevent-2.1.12-hf998b51_1.conda#a1cfcc585f0c42bf8d5546bb1dfb668d -https://conda.anaconda.org/conda-forge/linux-64/libgfortran-14.2.0-h69a702a_2.conda#fb54c4ea68b460c278d26eea89cfbcc3 +https://conda.anaconda.org/conda-forge/linux-64/libgfortran-15.1.0-h69a702a_2.conda#f92e6e0a3c0c0c85561ef61aa59d555d https://conda.anaconda.org/conda-forge/linux-64/libmpdec-4.0.0-h4bc722e_0.conda#aeb98fdeb2e8f25d43ef71fbacbeec80 https://conda.anaconda.org/conda-forge/linux-64/libpciaccess-0.18-hd590300_0.conda#48f4330bfcd959c3cfb704d424903c82 https://conda.anaconda.org/conda-forge/linux-64/libpng-1.6.47-h943b412_0.conda#55199e2ae2c3651f6f9b2a447b47bdc9 -https://conda.anaconda.org/conda-forge/linux-64/libsqlite-3.49.1-hee588c1_2.conda#962d6ac93c30b1dfc54c9cccafd1003e +https://conda.anaconda.org/conda-forge/linux-64/libsqlite-3.49.2-hee588c1_0.conda#93048463501053a00739215ea3f36324 https://conda.anaconda.org/conda-forge/linux-64/libssh2-1.11.1-hcf80075_0.conda#eecce068c7e4eddeb169591baac20ac4 -https://conda.anaconda.org/conda-forge/linux-64/libstdcxx-ng-14.2.0-h4852527_2.conda#c75da67f045c2627f59e6fcb5f4e3a9b +https://conda.anaconda.org/conda-forge/linux-64/libstdcxx-ng-15.1.0-h4852527_2.conda#9d2072af184b5caa29492bf2344597bb https://conda.anaconda.org/conda-forge/linux-64/libuuid-2.38.1-h0b41bf4_0.conda#40b61aab5c7ba9ff276c41cfffe6b80b https://conda.anaconda.org/conda-forge/linux-64/libxcb-1.17.0-h8a09558_0.conda#92ed62436b625154323d40d5f2f11dd7 https://conda.anaconda.org/conda-forge/linux-64/lz4-c-1.10.0-h5888daf_1.conda#9de5350a85c4a20c685259b889aa6393 -https://conda.anaconda.org/conda-forge/linux-64/mysql-common-9.2.0-h266115a_0.conda#db22a0962c953e81a2a679ecb1fc6027 https://conda.anaconda.org/conda-forge/linux-64/ninja-1.12.1-hff21bea_1.conda#2322531904f27501ee19847b87ba7c64 https://conda.anaconda.org/conda-forge/linux-64/pixman-0.46.0-h29eaf8c_0.conda#d2f1c87d4416d1e7344cf92b1aaee1c4 https://conda.anaconda.org/conda-forge/linux-64/readline-8.2-h8c095d6_2.conda#283b96675859b20a825f8fa30f311446 @@ -95,16 +93,15 @@ https://conda.anaconda.org/conda-forge/linux-64/krb5-1.21.3-h659f571_0.conda#3f4 https://conda.anaconda.org/conda-forge/linux-64/libcrc32c-1.1.2-h9c3ff4c_0.tar.bz2#c965a5aa0d5c1c37ffc62dff36e28400 https://conda.anaconda.org/conda-forge/linux-64/libdrm-2.4.124-hb9d3cd8_0.conda#8bc89311041d7fcb510238cf0848ccae https://conda.anaconda.org/conda-forge/linux-64/libfreetype6-2.13.3-h48d6fc4_1.conda#3c255be50a506c50765a93a6644f32fe -https://conda.anaconda.org/conda-forge/linux-64/libgfortran-ng-14.2.0-h69a702a_2.conda#4056c857af1a99ee50589a941059ec55 +https://conda.anaconda.org/conda-forge/linux-64/libgfortran-ng-15.1.0-h69a702a_2.conda#a483a87b71e974bb75d1b9413d4436dd https://conda.anaconda.org/conda-forge/linux-64/libnghttp2-1.64.0-h161d5f1_0.conda#19e57602824042dfd0446292ef90488b https://conda.anaconda.org/conda-forge/linux-64/libopenblas-0.3.29-pthreads_h94d23a6_0.conda#0a4d0252248ef9a0f88f2ba8b8a08e12 https://conda.anaconda.org/conda-forge/linux-64/libprotobuf-5.28.3-h6128344_1.conda#d8703f1ffe5a06356f06467f1d0b9464 https://conda.anaconda.org/conda-forge/linux-64/libre2-11-2024.07.02-hbbce691_2.conda#b2fede24428726dd867611664fb372e8 https://conda.anaconda.org/conda-forge/linux-64/libthrift-0.21.0-h0e7cc3e_0.conda#dcb95c0a98ba9ff737f7ae482aef7833 -https://conda.anaconda.org/conda-forge/linux-64/libtiff-4.7.0-hd9ff511_4.conda#6c1028898cf3a2032d9af46689e1b81a -https://conda.anaconda.org/conda-forge/linux-64/mysql-libs-9.2.0-he0572af_0.conda#93340b072c393d23c4700a1d40565dca -https://conda.anaconda.org/conda-forge/linux-64/nccl-2.26.5.1-h03a54cd_0.conda#47dc81d35df91d38609df9c93d608b2b -https://conda.anaconda.org/conda-forge/linux-64/pcre2-10.44-hc749103_2.conda#31614c73d7b103ef76faa4d83d261d34 +https://conda.anaconda.org/conda-forge/linux-64/libtiff-4.7.0-hf01ce69_5.conda#e79a094918988bb1807462cd42c83962 +https://conda.anaconda.org/conda-forge/linux-64/nccl-2.26.6.1-h03a54cd_0.conda#323f9253803b715728e8d0c94c495f53 +https://conda.anaconda.org/conda-forge/linux-64/pcre2-10.45-hc749103_0.conda#b90bece58b4c2bf25969b70f3be42d25 https://conda.anaconda.org/conda-forge/linux-64/python-3.13.3-hf636f53_101_cp313.conda#10622e12d649154af0bd76bcf33a7c5c https://conda.anaconda.org/conda-forge/linux-64/qhull-2020.2-h434a139_5.conda#353823361b1d27eb3960efb076dfcaf6 https://conda.anaconda.org/conda-forge/linux-64/xcb-util-0.4.1-hb711507_2.conda#8637c3e5821654d0edf97e2b0404b443 @@ -118,28 +115,27 @@ https://conda.anaconda.org/conda-forge/linux-64/aws-c-http-0.9.4-hb9b18c6_4.cond https://conda.anaconda.org/conda-forge/linux-64/brotli-1.1.0-hb9d3cd8_2.conda#98514fe74548d768907ce7a13f680e8f https://conda.anaconda.org/conda-forge/noarch/colorama-0.4.6-pyhd8ed1ab_1.conda#962b9857ee8e7018c22f2776ffa0b2d7 https://conda.anaconda.org/conda-forge/noarch/cpython-3.13.3-py313hd8ed1ab_101.conda#904a822cbd380adafb9070debf8579a8 -https://conda.anaconda.org/conda-forge/linux-64/cudnn-9.8.0.87-hf36481c_1.conda#988b6d0f8a2660fdee429d3d0f761ed3 https://conda.anaconda.org/conda-forge/noarch/cycler-0.12.1-pyhd8ed1ab_1.conda#44600c4667a319d67dbe0681fc0bc833 https://conda.anaconda.org/conda-forge/linux-64/cyrus-sasl-2.1.27-h54b06d7_7.conda#dce22f70b4e5a407ce88f2be046f4ceb -https://conda.anaconda.org/conda-forge/linux-64/cython-3.0.12-py313h5dec8f5_0.conda#24a42a0c1cc33743e33572d63d489b54 -https://conda.anaconda.org/conda-forge/noarch/exceptiongroup-1.2.2-pyhd8ed1ab_1.conda#a16662747cdeb9abbac74d0057cc976e +https://conda.anaconda.org/conda-forge/linux-64/cython-3.1.1-py313h5dec8f5_1.conda#f114755cdd37627732b1884b7b15d4b5 https://conda.anaconda.org/conda-forge/noarch/execnet-2.1.1-pyhd8ed1ab_1.conda#a71efeae2c160f6789900ba2631a2c90 https://conda.anaconda.org/conda-forge/linux-64/fastrlock-0.8.3-py313h9800cb9_1.conda#54dd71b3be2ed6ccc50f180347c901db https://conda.anaconda.org/conda-forge/noarch/filelock-3.18.0-pyhd8ed1ab_0.conda#4547b39256e296bb758166893e909a7c -https://conda.anaconda.org/conda-forge/noarch/fsspec-2025.3.2-pyhd8ed1ab_0.conda#9c40692c3d24c7aaf335f673ac09d308 +https://conda.anaconda.org/conda-forge/noarch/fsspec-2025.5.1-pyhd8ed1ab_0.conda#2d2c9ef879a7e64e2dc657b09272c2b6 https://conda.anaconda.org/conda-forge/noarch/iniconfig-2.0.0-pyhd8ed1ab_1.conda#6837f3eff7dcea42ecd714ce1ac2b108 https://conda.anaconda.org/conda-forge/linux-64/kiwisolver-1.4.7-py313h33d0bda_0.conda#9862d13a5e466273d5a4738cffcb8d6c https://conda.anaconda.org/conda-forge/linux-64/lcms2-2.17-h717163a_0.conda#000e85703f0fd9594c81710dd5066471 https://conda.anaconda.org/conda-forge/linux-64/libblas-3.9.0-31_h59b9bed_openblas.conda#728dbebd0f7a20337218beacffd37916 +https://conda.anaconda.org/conda-forge/linux-64/libcudnn-9.10.1.4-h7d33bf5_0.conda#93fe78190bc6fe40d5e7a737c8065286 https://conda.anaconda.org/conda-forge/linux-64/libcups-2.3.3-h4637d8d_4.conda#d4529f4dff3057982a7617c7ac58fde3 https://conda.anaconda.org/conda-forge/linux-64/libcurl-8.13.0-h332b0f4_0.conda#cbdc92ac0d93fe3c796e36ad65c7905c https://conda.anaconda.org/conda-forge/linux-64/libfreetype-2.13.3-ha770c72_1.conda#51f5be229d83ecd401fb369ab96ae669 -https://conda.anaconda.org/conda-forge/linux-64/libglib-2.84.1-h2ff4ddf_0.conda#0305434da649d4fb48a425e588b79ea6 +https://conda.anaconda.org/conda-forge/linux-64/libglib-2.84.2-h3618099_0.conda#072ab14a02164b7c0c089055368ff776 https://conda.anaconda.org/conda-forge/linux-64/libglx-1.7.0-ha4b6fd6_2.conda#c8013e438185f33b13814c5c488acd5c https://conda.anaconda.org/conda-forge/linux-64/libhiredis-1.0.2-h2cc385e_0.tar.bz2#b34907d3a81a3cd8095ee83d174c074a -https://conda.anaconda.org/conda-forge/linux-64/libxml2-2.13.7-h4bc477f_1.conda#ad1f1f8238834cd3c88ceeaee8da444a +https://conda.anaconda.org/conda-forge/linux-64/libxml2-2.13.8-h4bc477f_0.conda#14dbe05b929e329dbaa6f2d0aa19466d https://conda.anaconda.org/conda-forge/linux-64/markupsafe-3.0.2-py313h8060acc_1.conda#21b62c55924f01b6eef6827167b46acb -https://conda.anaconda.org/conda-forge/noarch/meson-1.8.0-pyh29332c3_0.conda#8e25221b702272394b86b0f4d7217f77 +https://conda.anaconda.org/conda-forge/noarch/meson-1.8.1-pyhe01879c_0.conda#f3cccd9a6ce5331ae33f69ade5529162 https://conda.anaconda.org/conda-forge/linux-64/mpfr-4.2.1-h90cbb55_3.conda#2eeb50cab6652538eee8fc0bc3340c81 https://conda.anaconda.org/conda-forge/noarch/mpmath-1.3.0-pyhd8ed1ab_1.conda#3585aa87c43ab15b167b574cd73b057b https://conda.anaconda.org/conda-forge/noarch/munkres-1.1.4-pyh9f0ad1d_0.tar.bz2#2ba8498c1018c1e9c61eb99b973dfe19 @@ -149,17 +145,17 @@ https://conda.anaconda.org/conda-forge/linux-64/openjpeg-2.5.3-h5fbd93e_0.conda# https://conda.anaconda.org/conda-forge/linux-64/orc-2.1.1-h2271f48_0.conda#67075ef2cb33079efee3abfe58127a3b https://conda.anaconda.org/conda-forge/noarch/packaging-25.0-pyh29332c3_1.conda#58335b26c38bf4a20f399384c33cbcf9 https://conda.anaconda.org/conda-forge/noarch/pip-25.1.1-pyh145f28c_0.conda#01384ff1639c6330a0924791413b8714 -https://conda.anaconda.org/conda-forge/noarch/pluggy-1.5.0-pyhd8ed1ab_1.conda#e9dcbce5f45f9ee500e728ae58b605b6 +https://conda.anaconda.org/conda-forge/noarch/pluggy-1.6.0-pyhd8ed1ab_0.conda#7da7ccd349dbf6487a7778579d2bb971 https://conda.anaconda.org/conda-forge/noarch/pyparsing-3.2.3-pyhd8ed1ab_1.conda#513d3c262ee49b54a8fec85c5bc99764 https://conda.anaconda.org/conda-forge/noarch/python-tzdata-2025.2-pyhd8ed1ab_0.conda#88476ae6ebd24f39261e0854ac244f33 https://conda.anaconda.org/conda-forge/noarch/pytz-2025.2-pyhd8ed1ab_0.conda#bc8e3267d44011051f2eb14d22fb0960 https://conda.anaconda.org/conda-forge/linux-64/re2-2024.07.02-h9925aae_2.conda#e84ddf12bde691e8ec894b00ea829ddf -https://conda.anaconda.org/conda-forge/noarch/setuptools-80.1.0-pyhff2d567_0.conda#f6f72d0837c79eaec77661be43e8a691 +https://conda.anaconda.org/conda-forge/noarch/setuptools-80.8.0-pyhff2d567_0.conda#ea075e94dc0106c7212128b6a25bbc4c https://conda.anaconda.org/conda-forge/noarch/six-1.17.0-pyhd8ed1ab_0.conda#a451d576819089b0d672f18768be0f65 https://conda.anaconda.org/conda-forge/noarch/threadpoolctl-3.6.0-pyhecae5ae_0.conda#9d64911b31d57ca443e9f1e36b04385f https://conda.anaconda.org/conda-forge/noarch/toml-0.10.2-pyhd8ed1ab_1.conda#b0dd904de08b7db706167240bf37b164 https://conda.anaconda.org/conda-forge/noarch/tomli-2.2.1-pyhd8ed1ab_1.conda#ac944244f1fed2eb49bae07193ae8215 -https://conda.anaconda.org/conda-forge/linux-64/tornado-6.4.2-py313h536fd9c_0.conda#5f5cbdd527d2e74e270d8b6255ba714f +https://conda.anaconda.org/conda-forge/linux-64/tornado-6.5.1-py313h536fd9c_0.conda#e9434a5155db25c38ade26f71a2f5a48 https://conda.anaconda.org/conda-forge/noarch/typing_extensions-4.13.2-pyh29332c3_0.conda#83fc6ae00127671e301c9f44254c31b8 https://conda.anaconda.org/conda-forge/linux-64/xcb-util-image-0.4.0-hb711507_2.conda#a0901183f08b6c7107aab109733a3c91 https://conda.anaconda.org/conda-forge/linux-64/xkeyboard-config-2.44-hb9d3cd8_0.conda#7c91bfc90672888259675ad2ad28af9c @@ -170,25 +166,27 @@ https://conda.anaconda.org/conda-forge/linux-64/aws-c-auth-0.8.6-hd08a7f5_4.cond https://conda.anaconda.org/conda-forge/linux-64/aws-c-mqtt-0.12.2-h108da3e_2.conda#90e07c8bac8da6378ee1882ef0a9374a https://conda.anaconda.org/conda-forge/linux-64/azure-core-cpp-1.14.0-h5cfcd09_0.conda#0a8838771cc2e985cd295e01ae83baf1 https://conda.anaconda.org/conda-forge/linux-64/ccache-4.11.3-h80c52d3_0.conda#eb517c6a2b960c3ccb6f1db1005f063a -https://conda.anaconda.org/conda-forge/linux-64/coverage-7.8.0-py313h8060acc_0.conda#375064d30e709bf7c1d4580e70aaea61 -https://conda.anaconda.org/conda-forge/linux-64/dbus-1.13.6-h5008d03_3.tar.bz2#ecfff944ba3960ecb334b9a2663d708d -https://conda.anaconda.org/conda-forge/linux-64/fonttools-4.57.0-py313h8060acc_0.conda#76b3a3367ac578a7cc43f4b7814e7e87 +https://conda.anaconda.org/conda-forge/linux-64/coverage-7.8.2-py313h8060acc_0.conda#b278629953bd3424060870fca744de4a +https://conda.anaconda.org/conda-forge/linux-64/dbus-1.16.2-h3c4dab8_0.conda#679616eb5ad4e521c83da4650860aba7 +https://conda.anaconda.org/conda-forge/noarch/exceptiongroup-1.3.0-pyhd8ed1ab_0.conda#72e42d28960d875c7654614f8b50939a +https://conda.anaconda.org/conda-forge/linux-64/fonttools-4.58.0-py313h8060acc_0.conda#0bf58a605826e69e1c6b28f35f83ea32 https://conda.anaconda.org/conda-forge/linux-64/freetype-2.13.3-ha770c72_1.conda#9ccd736d31e0c6e41f54e704e5312811 https://conda.anaconda.org/conda-forge/noarch/jinja2-3.1.6-pyhd8ed1ab_0.conda#446bd6c8cb26050d528881df495ce646 -https://conda.anaconda.org/conda-forge/noarch/joblib-1.5.0-pyhd8ed1ab_0.conda#3d7257f0a61c9aa4ffa3e324a887416b +https://conda.anaconda.org/conda-forge/noarch/joblib-1.5.1-pyhd8ed1ab_0.conda#fb1c14694de51a476ce8636d92b6f42c https://conda.anaconda.org/conda-forge/linux-64/libcblas-3.9.0-31_he106b2a_openblas.conda#abb32c727da370c481a1c206f5159ce9 +https://conda.anaconda.org/conda-forge/linux-64/libcudnn-dev-9.10.1.4-h0fdc2d1_0.conda#a0c0b44d26a4710e6ea577fcddbe09d1 https://conda.anaconda.org/conda-forge/linux-64/libgl-1.7.0-ha4b6fd6_2.conda#928b8be80851f5d8ffb016f9c81dae7a https://conda.anaconda.org/conda-forge/linux-64/libgrpc-1.67.1-h25350d4_2.conda#bfcedaf5f9b003029cc6abe9431f66bf https://conda.anaconda.org/conda-forge/linux-64/libhwloc-2.11.2-default_h0d58e46_1001.conda#804ca9e91bcaea0824a341d55b1684f2 https://conda.anaconda.org/conda-forge/linux-64/liblapack-3.9.0-31_h7ac8fdf_openblas.conda#452b98eafe050ecff932f0ec832dd03f -https://conda.anaconda.org/conda-forge/linux-64/libllvm20-20.1.4-he9d0ab4_0.conda#96c33bbd084ef2b2463503fb7f1482ae -https://conda.anaconda.org/conda-forge/linux-64/libxkbcommon-1.9.1-h65c71a3_0.conda#6e45090fe0eec179ecc8041a3a3fc9f8 +https://conda.anaconda.org/conda-forge/linux-64/libllvm20-20.1.5-he9d0ab4_0.conda#8d2f5a2f019bd76ccba5eb771852d411 +https://conda.anaconda.org/conda-forge/linux-64/libxkbcommon-1.10.0-h65c71a3_0.conda#fedf6bfe5d21d21d2b1785ec00a8889a https://conda.anaconda.org/conda-forge/linux-64/libxslt-1.1.39-h76b75d6_0.conda#e71f31f8cfb0a91439f2086fc8aa0461 https://conda.anaconda.org/conda-forge/linux-64/mpc-1.3.1-h24ddda3_1.conda#aa14b9a5196a6d8dd364164b7ce56acf -https://conda.anaconda.org/conda-forge/linux-64/openldap-2.6.9-he970967_0.conda#ca2de8bbdc871bce41dbf59e51324165 +https://conda.anaconda.org/conda-forge/linux-64/openldap-2.6.10-he970967_0.conda#2e5bf4f1da39c0b32778561c3c4e5878 +https://conda.anaconda.org/conda-forge/linux-64/pillow-11.2.1-py313h8db990d_0.conda#91b00afee98d72d29dc3d1c1ab0008d7 https://conda.anaconda.org/conda-forge/linux-64/prometheus-cpp-1.3.0-ha5d0236_0.conda#a83f6a2fdc079e643237887a37460668 https://conda.anaconda.org/conda-forge/noarch/pyproject-metadata-0.9.1-pyhd8ed1ab_0.conda#22ae7c6ea81e0c8661ef32168dda929b -https://conda.anaconda.org/conda-forge/noarch/pytest-8.3.5-pyhd8ed1ab_0.conda#c3c9316209dec74a705a36797970c6be https://conda.anaconda.org/conda-forge/noarch/python-dateutil-2.9.0.post0-pyhff2d567_1.conda#5ba79d7c71f03c678c8ead841f347d6e https://conda.anaconda.org/conda-forge/noarch/python-gil-3.13.3-h4df99d1_101.conda#82c2641f2f0f513f7d2d1b847a2588e3 https://conda.anaconda.org/conda-forge/linux-64/xcb-util-cursor-0.1.5-hb9d3cd8_0.conda#eb44b3b6deb1cab08d72cb61686fe64c @@ -202,20 +200,19 @@ https://conda.anaconda.org/conda-forge/noarch/_python_abi3_support-1.0-hd8ed1ab_ https://conda.anaconda.org/conda-forge/linux-64/aws-c-s3-0.7.13-h822ba82_2.conda#9cf2c3c13468f2209ee814be2c88655f https://conda.anaconda.org/conda-forge/linux-64/azure-identity-cpp-1.10.0-h113e628_0.conda#73f73f60854f325a55f1d31459f2ab73 https://conda.anaconda.org/conda-forge/linux-64/azure-storage-common-cpp-12.8.0-h736e048_1.conda#13de36be8de3ae3f05ba127631599213 +https://conda.anaconda.org/conda-forge/linux-64/cudnn-9.10.1.4-haad7af6_0.conda#8382d957333e0d3280dcbf5691516dc1 https://conda.anaconda.org/conda-forge/linux-64/fontconfig-2.15.0-h7e30c49_1.conda#8f5b0b297b59e1ac160ad4beec99dbee https://conda.anaconda.org/conda-forge/linux-64/gmpy2-2.2.1-py313h11186cd_0.conda#54d020e0eaacf1e99bfb2410b9aa2e5e -https://conda.anaconda.org/conda-forge/linux-64/libclang-cpp20.1-20.1.4-default_h1df26ce_0.conda#96f8d5b2e94c9ba4fef19f1adf068a15 -https://conda.anaconda.org/conda-forge/linux-64/libclang13-20.1.4-default_he06ed0a_0.conda#2d933632c8004be47deb2be61bf013be +https://conda.anaconda.org/conda-forge/linux-64/libclang-cpp20.1-20.1.5-default_h1df26ce_1.conda#330b1dadfa7c3205a01fa9599fabe808 +https://conda.anaconda.org/conda-forge/linux-64/libclang13-20.1.5-default_he06ed0a_1.conda#12117145218e7e1a528c8396ed803058 https://conda.anaconda.org/conda-forge/linux-64/libgoogle-cloud-2.36.0-h2b5623c_0.conda#c96ca58ad3352a964bfcb85de6cd1496 https://conda.anaconda.org/conda-forge/linux-64/liblapacke-3.9.0-31_he2f377e_openblas.conda#7e5fff7d0db69be3a266f7e79a3bb0e2 https://conda.anaconda.org/conda-forge/linux-64/libmagma-2.9.0-h45b15fe_0.conda#703a1ab01e36111d8bb40bc7517e900b https://conda.anaconda.org/conda-forge/linux-64/libopentelemetry-cpp-1.18.0-hfcad708_1.conda#1f5a5d66e77a39dc5bd639ec953705cf -https://conda.anaconda.org/conda-forge/linux-64/libpq-17.4-h27ae623_1.conda#37fba334855ef3b51549308e61ed7a3d -https://conda.anaconda.org/conda-forge/noarch/meson-python-0.17.1-pyh70fd9c4_1.conda#7a02679229c6c2092571b4c025055440 -https://conda.anaconda.org/conda-forge/linux-64/numpy-2.2.5-py313h17eae1a_0.conda#6ceeff9ed72e54e4a2f9a1c88f47bdde -https://conda.anaconda.org/conda-forge/linux-64/pillow-11.1.0-py313h8db990d_0.conda#1e86810c6c3fb6d6aebdba26564eb2e8 -https://conda.anaconda.org/conda-forge/noarch/pytest-cov-6.1.1-pyhd8ed1ab_0.conda#1e35d8f975bc0e984a19819aa91c440a -https://conda.anaconda.org/conda-forge/noarch/pytest-xdist-3.6.1-pyhd8ed1ab_1.conda#59aad4fb37cabc0bacc73cf344612ddd +https://conda.anaconda.org/conda-forge/linux-64/libpq-17.5-h27ae623_0.conda#6458be24f09e1b034902ab44fe9de908 +https://conda.anaconda.org/conda-forge/noarch/meson-python-0.18.0-pyh70fd9c4_0.conda#576c04b9d9f8e45285fb4d9452c26133 +https://conda.anaconda.org/conda-forge/linux-64/numpy-2.2.6-py313h17eae1a_0.conda#7a2d2f9adecd86ed5c29c2115354f615 +https://conda.anaconda.org/conda-forge/noarch/pytest-8.3.5-pyhd8ed1ab_0.conda#c3c9316209dec74a705a36797970c6be https://conda.anaconda.org/conda-forge/linux-64/tbb-2021.13.0-hceb3a55_1.conda#ba7726b8df7b9d34ea80e82b097a4893 https://conda.anaconda.org/conda-forge/linux-64/xorg-libxtst-1.2.5-hb9d3cd8_3.conda#7bbe9a0cc0df0ac5f5a8ad6d6a11af2f https://conda.anaconda.org/conda-forge/noarch/array-api-strict-2.3.1-pyhd8ed1ab_0.conda#11107d0aeb8c590a34fee0894909816b @@ -229,26 +226,29 @@ https://conda.anaconda.org/conda-forge/linux-64/libgoogle-cloud-storage-2.36.0-h https://conda.anaconda.org/conda-forge/linux-64/libmagma_sparse-2.9.0-h45b15fe_0.conda#beac0a5bbe0af75db6b16d3d8fd24f7e https://conda.anaconda.org/conda-forge/linux-64/mkl-2024.2.2-ha957f24_16.conda#1459379c79dda834673426504d52b319 https://conda.anaconda.org/conda-forge/linux-64/pandas-2.2.3-py313ha87cce1_3.conda#6248b529e537b1d4cb5ab3ef7f537795 -https://conda.anaconda.org/conda-forge/linux-64/polars-1.27.1-py39h2a4a510_3.conda#fba08963eaa1f954480045d033d1221e +https://conda.anaconda.org/conda-forge/linux-64/polars-default-1.30.0-py39hfac2b71_0.conda#cd33cf1e631b4d766858c90e333b4832 +https://conda.anaconda.org/conda-forge/noarch/pytest-cov-6.1.1-pyhd8ed1ab_0.conda#1e35d8f975bc0e984a19819aa91c440a +https://conda.anaconda.org/conda-forge/noarch/pytest-xdist-3.6.1-pyhd8ed1ab_1.conda#59aad4fb37cabc0bacc73cf344612ddd https://conda.anaconda.org/conda-forge/linux-64/scipy-1.15.2-py313h86fcf2b_0.conda#ca68acd9febc86448eeed68d0c6c8643 https://conda.anaconda.org/conda-forge/noarch/sympy-1.14.0-pyh2585a3b_105.conda#8c09fac3785696e1c477156192d64b91 https://conda.anaconda.org/conda-forge/linux-64/aws-sdk-cpp-1.11.510-h37a5c72_3.conda#beb8577571033140c6897d257acc7724 https://conda.anaconda.org/conda-forge/linux-64/azure-storage-files-datalake-cpp-12.12.0-ha633028_1.conda#7c1980f89dd41b097549782121a73490 https://conda.anaconda.org/conda-forge/linux-64/blas-2.131-openblas.conda#38b2ec894c69bb4be0e66d2ef7fc60bf https://conda.anaconda.org/conda-forge/linux-64/cupy-13.4.1-py313h66a2ee2_0.conda#784d6bd149ef2b5d9c733ea3dd4d15ad -https://conda.anaconda.org/conda-forge/linux-64/harfbuzz-11.1.0-h3beb420_0.conda#95e3bb97f9cdc251c0c68640e9c10ed3 +https://conda.anaconda.org/conda-forge/linux-64/harfbuzz-11.2.1-h3beb420_0.conda#0e6e192d4b3d95708ad192d957cf3163 https://conda.anaconda.org/conda-forge/linux-64/libtorch-2.4.1-cuda118_mkl_hee7131c_306.conda#28b3b3da11973494ed0100aa50f47328 -https://conda.anaconda.org/conda-forge/linux-64/matplotlib-base-3.10.1-py313h129903b_0.conda#4e23b3fabf434b418e0d9c6975a6453f +https://conda.anaconda.org/conda-forge/linux-64/matplotlib-base-3.10.3-py313h129903b_0.conda#4f8816d006b1c155ec416bcf7ff6cee2 +https://conda.anaconda.org/conda-forge/linux-64/polars-1.30.0-default_h1443d73_0.conda#19698b29e8544d2dd615699826037039 https://conda.anaconda.org/conda-forge/linux-64/pyamg-5.2.1-py313hf0ab243_1.conda#4c769bf3858f424cb2ecf952175ec600 https://conda.anaconda.org/conda-forge/linux-64/libarrow-19.0.1-hc7b3859_3_cpu.conda#9ed3ded6da29dec8417f2e1db68798f2 https://conda.anaconda.org/conda-forge/linux-64/pytorch-2.4.1-cuda118_mkl_py313_h909c4c2_306.conda#de6e45613bbdb51127e9ff483c31bf41 -https://conda.anaconda.org/conda-forge/linux-64/qt6-main-6.9.0-h6441bc3_1.conda#4029a8dcb1d97ea241dbe5abfda1fad6 +https://conda.anaconda.org/conda-forge/linux-64/qt6-main-6.9.0-h0384650_3.conda#8aa69e15597a205fd6f81781fe62c232 https://conda.anaconda.org/conda-forge/linux-64/libarrow-acero-19.0.1-hcb10f89_3_cpu.conda#8f8dc214d89e06933f1bc1dcd2310b9c https://conda.anaconda.org/conda-forge/linux-64/libparquet-19.0.1-h081d1f1_3_cpu.conda#1d04307cdb1d8aeb5f55b047d5d403ea https://conda.anaconda.org/conda-forge/linux-64/pyarrow-core-19.0.1-py313he5f92c8_0_cpu.conda#7d8649531c807b24295c8f9a0a396a78 https://conda.anaconda.org/conda-forge/linux-64/pyside6-6.9.0-py313h5f61773_0.conda#f51f25ec8fcbf777f8b186bb5deeed40 https://conda.anaconda.org/conda-forge/linux-64/pytorch-gpu-2.4.1-cuda118_mkl_hf8a3b2d_306.conda#b1802a39f1ca7ebed5f8c35755bffec1 https://conda.anaconda.org/conda-forge/linux-64/libarrow-dataset-19.0.1-hcb10f89_3_cpu.conda#a28f04b6e68a1c76de76783108ad729d -https://conda.anaconda.org/conda-forge/linux-64/matplotlib-3.10.1-py313h78bf25f_0.conda#d0c80dea550ca97fc0710b2ecef919ba +https://conda.anaconda.org/conda-forge/linux-64/matplotlib-3.10.3-py313h78bf25f_0.conda#cc9324e614a297fdf23439d887d3513d https://conda.anaconda.org/conda-forge/linux-64/libarrow-substrait-19.0.1-h08228c5_3_cpu.conda#a58e4763af8293deaac77b63bc7804d8 https://conda.anaconda.org/conda-forge/linux-64/pyarrow-19.0.1-py313h78bf25f_0.conda#e8efe6998a383dd149787c83d3d6a92e diff --git a/build_tools/github/pymin_conda_forge_arm_linux-aarch64_conda.lock b/build_tools/github/pymin_conda_forge_arm_linux-aarch64_conda.lock index 5f7bedbbfeaa8..e4949a89892c4 100644 --- a/build_tools/github/pymin_conda_forge_arm_linux-aarch64_conda.lock +++ b/build_tools/github/pymin_conda_forge_arm_linux-aarch64_conda.lock @@ -1,6 +1,6 @@ # Generated by conda-lock. # platform: linux-aarch64 -# input_hash: 9226800dfe446f7b9ed783525101a7cf60f0da339c6c1fc6db00ea557831de1d +# input_hash: f12646c755adbf5f02f95c5d07e868bf1570777923e737bc27273eb1a5e40cd7 @EXPLICIT https://conda.anaconda.org/conda-forge/noarch/font-ttf-dejavu-sans-mono-2.37-hab24e00_0.tar.bz2#0c96522c6bdaed4b1566d11387caaf45 https://conda.anaconda.org/conda-forge/noarch/font-ttf-inconsolata-3.000-h77eed37_0.tar.bz2#34893075a5c9e55cdafac56607368fc6 @@ -8,7 +8,7 @@ https://conda.anaconda.org/conda-forge/noarch/font-ttf-source-code-pro-2.038-h77 https://conda.anaconda.org/conda-forge/noarch/font-ttf-ubuntu-0.83-h77eed37_3.conda#49023d73832ef61042f6a237cb2687e7 https://conda.anaconda.org/conda-forge/linux-aarch64/ld_impl_linux-aarch64-2.43-h80caac9_4.conda#80c9ad5e05e91bb6c0967af3880c9742 https://conda.anaconda.org/conda-forge/linux-aarch64/libglvnd-1.7.0-hd24410f_2.conda#9e115653741810778c9a915a2f8439e7 -https://conda.anaconda.org/conda-forge/linux-aarch64/libgomp-14.2.0-he277a41_2.conda#b11c09d9463daf4cae492d29806b1889 +https://conda.anaconda.org/conda-forge/linux-aarch64/libgomp-15.1.0-he277a41_2.conda#a28544b28961994eab37e1132a7dadcf https://conda.anaconda.org/conda-forge/noarch/python_abi-3.10-7_cp310.conda#44e871cba2b162368476a84b8d040b6c https://conda.anaconda.org/conda-forge/noarch/tzdata-2025b-h78e105d_0.conda#4222072737ccff51314b5ece9c7d6f5a https://conda.anaconda.org/conda-forge/linux-aarch64/_openmp_mutex-4.5-2_gnu.tar.bz2#6168d71addc746e8f2b8d57dfd2edcea @@ -17,18 +17,18 @@ https://conda.anaconda.org/conda-forge/noarch/fonts-conda-forge-1-0.tar.bz2#f766 https://conda.anaconda.org/conda-forge/linux-aarch64/libegl-1.7.0-hd24410f_2.conda#cf105bce884e4ef8c8ccdca9fe6695e7 https://conda.anaconda.org/conda-forge/linux-aarch64/libopengl-1.7.0-hd24410f_2.conda#cf9d12bfab305e48d095a4c79002c922 https://conda.anaconda.org/conda-forge/noarch/fonts-conda-ecosystem-1-0.tar.bz2#fee5683a3f04bd15cbd8318b096a27ab -https://conda.anaconda.org/conda-forge/linux-aarch64/libgcc-14.2.0-he277a41_2.conda#6b4268a60b10f29257b51b9b67ff8d76 +https://conda.anaconda.org/conda-forge/linux-aarch64/libgcc-15.1.0-he277a41_2.conda#224e999bbcad260d7bd4c0c27fdb99a4 https://conda.anaconda.org/conda-forge/linux-aarch64/alsa-lib-1.2.14-h86ecc28_0.conda#a696b24c1b473ecc4774bcb5a6ac6337 https://conda.anaconda.org/conda-forge/linux-aarch64/libbrotlicommon-1.1.0-h86ecc28_2.conda#3ee026955c688f551a9999840cff4c67 -https://conda.anaconda.org/conda-forge/linux-aarch64/libdeflate-1.23-he377734_0.conda#308ad7cbe9fd92add59ef3d547a42c17 +https://conda.anaconda.org/conda-forge/linux-aarch64/libdeflate-1.24-he377734_0.conda#f0b3d6494663b3385bf87fc206d7451a https://conda.anaconda.org/conda-forge/linux-aarch64/libexpat-2.7.0-h5ad3122_0.conda#d41a057e7968705dae8dcb7c8ba2c8dd https://conda.anaconda.org/conda-forge/linux-aarch64/libffi-3.4.6-he21f813_1.conda#15a131f30cae36e9a655ca81fee9a285 -https://conda.anaconda.org/conda-forge/linux-aarch64/libgcc-ng-14.2.0-he9431aa_2.conda#692c2bb75f32cfafb6799cf6d1c5d0e0 -https://conda.anaconda.org/conda-forge/linux-aarch64/libgfortran5-14.2.0-hb6113d0_2.conda#cd754566661513808ef2408c4ab99a2f +https://conda.anaconda.org/conda-forge/linux-aarch64/libgcc-ng-15.1.0-he9431aa_2.conda#d12a4b26073751bbc3db18de83ccba5f +https://conda.anaconda.org/conda-forge/linux-aarch64/libgfortran5-15.1.0-hbc25352_2.conda#4b5f4d119f9b28f254f82dbe56b2406f https://conda.anaconda.org/conda-forge/linux-aarch64/libiconv-1.18-hc99b53d_1.conda#81541d85a45fbf4d0a29346176f1f21c https://conda.anaconda.org/conda-forge/linux-aarch64/libjpeg-turbo-3.1.0-h86ecc28_0.conda#a689388210d502364b79e8b19e7fa2cb -https://conda.anaconda.org/conda-forge/linux-aarch64/liblzma-5.8.1-h86ecc28_0.conda#775d36ea4e469b0c049a6f2cd6253d82 -https://conda.anaconda.org/conda-forge/linux-aarch64/libstdcxx-14.2.0-h3f4de04_2.conda#eadee2cda99697e29411c1013c187b92 +https://conda.anaconda.org/conda-forge/linux-aarch64/liblzma-5.8.1-h86ecc28_1.conda#8ced9a547a29f7a71b7f15a4443ad1de +https://conda.anaconda.org/conda-forge/linux-aarch64/libstdcxx-15.1.0-h3f4de04_2.conda#6247ea6d1ecac20a9e98674342984726 https://conda.anaconda.org/conda-forge/linux-aarch64/libwebp-base-1.5.0-h0886dbf_0.conda#95ef4a689b8cc1b7e18b53784d88f96b https://conda.anaconda.org/conda-forge/linux-aarch64/libzlib-1.3.1-h86ecc28_2.conda#08aad7cbe9f5a6b460d0976076b6ae64 https://conda.anaconda.org/conda-forge/linux-aarch64/ncurses-6.5-ha32ae93_3.conda#182afabe009dc78d8b73100255ee6868 @@ -39,23 +39,21 @@ https://conda.anaconda.org/conda-forge/linux-aarch64/xorg-libxau-1.0.12-h86ecc28 https://conda.anaconda.org/conda-forge/linux-aarch64/xorg-libxdmcp-1.1.5-h57736b2_0.conda#25a5a7b797fe6e084e04ffe2db02fc62 https://conda.anaconda.org/conda-forge/linux-aarch64/bzip2-1.0.8-h68df207_7.conda#56398c28220513b9ea13d7b450acfb20 https://conda.anaconda.org/conda-forge/linux-aarch64/double-conversion-3.3.1-h5ad3122_0.conda#399959d889e1a73fc99f12ce480e77e1 -https://conda.anaconda.org/conda-forge/linux-aarch64/expat-2.7.0-h5ad3122_0.conda#c22e14e241ade3d3a74c0409c3d582a2 https://conda.anaconda.org/conda-forge/linux-aarch64/keyutils-1.6.1-h4e544f5_0.tar.bz2#1f24853e59c68892452ef94ddd8afd4b https://conda.anaconda.org/conda-forge/linux-aarch64/lerc-4.0.0-hfdc4d58_1.conda#60dceb7e876f4d74a9cbd42bbbc6b9cf https://conda.anaconda.org/conda-forge/linux-aarch64/libbrotlidec-1.1.0-h86ecc28_2.conda#e64d0f3b59c7c4047446b97a8624a72d https://conda.anaconda.org/conda-forge/linux-aarch64/libbrotlienc-1.1.0-h86ecc28_2.conda#0e9bd365480c72b25c71a448257b537d https://conda.anaconda.org/conda-forge/linux-aarch64/libedit-3.1.20250104-pl5321h976ea20_0.conda#fb640d776fc92b682a14e001980825b1 -https://conda.anaconda.org/conda-forge/linux-aarch64/libgfortran-14.2.0-he9431aa_2.conda#d8b9d9dc0c8cd97d375b48e55947ba70 +https://conda.anaconda.org/conda-forge/linux-aarch64/libgfortran-15.1.0-he9431aa_2.conda#dc8675aa2658bb0d92cefbff83ce2db8 https://conda.anaconda.org/conda-forge/linux-aarch64/libnsl-2.0.1-h31becfc_0.conda#c14f32510f694e3185704d89967ec422 https://conda.anaconda.org/conda-forge/linux-aarch64/libntlm-1.4-hf897c2e_1002.tar.bz2#835c7c4137821de5c309f4266a51ba89 https://conda.anaconda.org/conda-forge/linux-aarch64/libpciaccess-0.18-h31becfc_0.conda#6d48179630f00e8c9ad9e30879ce1e54 https://conda.anaconda.org/conda-forge/linux-aarch64/libpng-1.6.47-hec79eb8_0.conda#c4b1ba0d7cef5002759d2f156722feee -https://conda.anaconda.org/conda-forge/linux-aarch64/libsqlite-3.49.1-h5eb1b54_2.conda#7c45959e187fd3313f9f1734464baecc -https://conda.anaconda.org/conda-forge/linux-aarch64/libstdcxx-ng-14.2.0-hf1166c9_2.conda#c934c1fddad582fcc385b608eb06a70c +https://conda.anaconda.org/conda-forge/linux-aarch64/libsqlite-3.49.2-h5eb1b54_0.conda#462e571b023e916587ff0925ae22522d +https://conda.anaconda.org/conda-forge/linux-aarch64/libstdcxx-ng-15.1.0-hf1166c9_2.conda#18e532d1a39ae9f78cc8988a034f1cae https://conda.anaconda.org/conda-forge/linux-aarch64/libuuid-2.38.1-hb4cce97_0.conda#000e30b09db0b7c775b21695dff30969 https://conda.anaconda.org/conda-forge/linux-aarch64/libxcb-1.17.0-h262b8f6_0.conda#cd14ee5cca2464a425b1dbfc24d90db2 https://conda.anaconda.org/conda-forge/linux-aarch64/libxcrypt-4.4.36-h31becfc_1.conda#b4df5d7d4b63579d081fd3a4cf99740e -https://conda.anaconda.org/conda-forge/linux-aarch64/mysql-common-9.2.0-h3f5c77f_0.conda#f9db1ad1a8897483edb3ac321d662e7b https://conda.anaconda.org/conda-forge/linux-aarch64/ninja-1.12.1-h17cf362_1.conda#885414635e2a65ed06f284f6d569cdff https://conda.anaconda.org/conda-forge/linux-aarch64/pixman-0.46.0-h86a87f0_0.conda#1328d5bad76f7b31926ccd2a33e0d6ef https://conda.anaconda.org/conda-forge/linux-aarch64/readline-8.2-h8382b9d_2.conda#c0f08fc2737967edde1a272d4bf41ed9 @@ -68,11 +66,10 @@ https://conda.anaconda.org/conda-forge/linux-aarch64/icu-75.1-hf9b3779_0.conda#2 https://conda.anaconda.org/conda-forge/linux-aarch64/krb5-1.21.3-h50a48e9_0.conda#29c10432a2ca1472b53f299ffb2ffa37 https://conda.anaconda.org/conda-forge/linux-aarch64/libdrm-2.4.124-h86ecc28_0.conda#a8058bcb6b4fa195aaa20452437c7727 https://conda.anaconda.org/conda-forge/linux-aarch64/libfreetype6-2.13.3-he93130f_1.conda#51eae9012d75b8f7e4b0adfe61a83330 -https://conda.anaconda.org/conda-forge/linux-aarch64/libgfortran-ng-14.2.0-he9431aa_2.conda#0980d7d931474a6a037ae66f1da4d2fe +https://conda.anaconda.org/conda-forge/linux-aarch64/libgfortran-ng-15.1.0-he9431aa_2.conda#55c5691e8b65612aaa0ef109cf645724 https://conda.anaconda.org/conda-forge/linux-aarch64/libopenblas-0.3.29-pthreads_h9d3fd7e_0.conda#a99e2bfcb1ad6362544c71281eb617e9 -https://conda.anaconda.org/conda-forge/linux-aarch64/libtiff-4.7.0-h88f7998_4.conda#6edd78ac9bee9a972f25cb6e8c6e21ad -https://conda.anaconda.org/conda-forge/linux-aarch64/mysql-libs-9.2.0-h11569fd_0.conda#72f21962b1205535d810b82f8f0fa342 -https://conda.anaconda.org/conda-forge/linux-aarch64/pcre2-10.44-hf4ec17f_2.conda#ab9d0f9a3c9ce23e4fd2af4edc6fa245 +https://conda.anaconda.org/conda-forge/linux-aarch64/libtiff-4.7.0-h7c15681_5.conda#264a9aac20276b1784dac8c5f8d3704a +https://conda.anaconda.org/conda-forge/linux-aarch64/pcre2-10.45-hf4ec17f_0.conda#ad22a9a9497f7aedce73e0da53cd215f https://conda.anaconda.org/conda-forge/linux-aarch64/python-3.10.17-h256493d_0_cpython.conda#c496213b6ede3c5a30ce1bf02bebf382 https://conda.anaconda.org/conda-forge/linux-aarch64/qhull-2020.2-h70be974_5.conda#bb138086d938e2b64f5f364945793ebf https://conda.anaconda.org/conda-forge/linux-aarch64/xcb-util-0.4.1-h5c728e9_2.conda#b4cf8ba6cff9cdf1249bcfe1314222b0 @@ -85,8 +82,7 @@ https://conda.anaconda.org/conda-forge/linux-aarch64/brotli-1.1.0-h86ecc28_2.con https://conda.anaconda.org/conda-forge/noarch/colorama-0.4.6-pyhd8ed1ab_1.conda#962b9857ee8e7018c22f2776ffa0b2d7 https://conda.anaconda.org/conda-forge/noarch/cycler-0.12.1-pyhd8ed1ab_1.conda#44600c4667a319d67dbe0681fc0bc833 https://conda.anaconda.org/conda-forge/linux-aarch64/cyrus-sasl-2.1.27-hf6b2984_7.conda#7a85d417c8acd7a5215c082c5b9219e5 -https://conda.anaconda.org/conda-forge/linux-aarch64/cython-3.0.12-py310hc86cfe9_0.conda#4bd71650f315b643774841272d02911a -https://conda.anaconda.org/conda-forge/noarch/exceptiongroup-1.2.2-pyhd8ed1ab_1.conda#a16662747cdeb9abbac74d0057cc976e +https://conda.anaconda.org/conda-forge/linux-aarch64/cython-3.1.1-py310hc86cfe9_1.conda#927cfc32db9db46c1804d977aaa11173 https://conda.anaconda.org/conda-forge/noarch/execnet-2.1.1-pyhd8ed1ab_1.conda#a71efeae2c160f6789900ba2631a2c90 https://conda.anaconda.org/conda-forge/noarch/iniconfig-2.0.0-pyhd8ed1ab_1.conda#6837f3eff7dcea42ecd714ce1ac2b108 https://conda.anaconda.org/conda-forge/linux-aarch64/kiwisolver-1.4.7-py310h5d7f10c_0.conda#b86d594bf17c9ad7a291593368ae8ba7 @@ -94,22 +90,23 @@ https://conda.anaconda.org/conda-forge/linux-aarch64/lcms2-2.17-hc88f144_0.conda https://conda.anaconda.org/conda-forge/linux-aarch64/libblas-3.9.0-31_h1a9f1db_openblas.conda#48bd5bf15ccf3e409840be9caafc0ad5 https://conda.anaconda.org/conda-forge/linux-aarch64/libcups-2.3.3-h405e4a8_4.conda#d42c670b0c96c1795fd859d5e0275a55 https://conda.anaconda.org/conda-forge/linux-aarch64/libfreetype-2.13.3-h8af1aa0_1.conda#2d4a1c3dcabb80b4a56d5c34bdacea08 -https://conda.anaconda.org/conda-forge/linux-aarch64/libglib-2.84.1-hc486b8e_0.conda#07cb059040220481ab9eda17cb86f644 +https://conda.anaconda.org/conda-forge/linux-aarch64/libglib-2.84.2-hc022ef1_0.conda#51323eab8e9f049d001424828c4c25a4 https://conda.anaconda.org/conda-forge/linux-aarch64/libglx-1.7.0-hd24410f_2.conda#1d4269e233636148696a67e2d30dad2a https://conda.anaconda.org/conda-forge/linux-aarch64/libhiredis-1.0.2-h05efe27_0.tar.bz2#a87f068744fd20334cd41489eb163bee -https://conda.anaconda.org/conda-forge/linux-aarch64/libxml2-2.13.7-he060846_1.conda#b461618b5dafbc95c6f9492043cd991a -https://conda.anaconda.org/conda-forge/noarch/meson-1.8.0-pyh29332c3_0.conda#8e25221b702272394b86b0f4d7217f77 +https://conda.anaconda.org/conda-forge/linux-aarch64/libxml2-2.13.8-he060846_0.conda#c73dfe6886cc8d39a09c357a36f91fb2 +https://conda.anaconda.org/conda-forge/noarch/meson-1.8.1-pyhe01879c_0.conda#f3cccd9a6ce5331ae33f69ade5529162 https://conda.anaconda.org/conda-forge/noarch/munkres-1.1.4-pyh9f0ad1d_0.tar.bz2#2ba8498c1018c1e9c61eb99b973dfe19 https://conda.anaconda.org/conda-forge/linux-aarch64/openblas-0.3.29-pthreads_h3a8cbd8_0.conda#4ec5b6144709ced5e7933977675f61c6 https://conda.anaconda.org/conda-forge/linux-aarch64/openjpeg-2.5.3-h3f56577_0.conda#04231368e4af50d11184b50e14250993 https://conda.anaconda.org/conda-forge/noarch/packaging-25.0-pyh29332c3_1.conda#58335b26c38bf4a20f399384c33cbcf9 -https://conda.anaconda.org/conda-forge/noarch/pluggy-1.5.0-pyhd8ed1ab_1.conda#e9dcbce5f45f9ee500e728ae58b605b6 +https://conda.anaconda.org/conda-forge/noarch/pluggy-1.6.0-pyhd8ed1ab_0.conda#7da7ccd349dbf6487a7778579d2bb971 https://conda.anaconda.org/conda-forge/noarch/pyparsing-3.2.3-pyhd8ed1ab_1.conda#513d3c262ee49b54a8fec85c5bc99764 -https://conda.anaconda.org/conda-forge/noarch/setuptools-80.1.0-pyhff2d567_0.conda#f6f72d0837c79eaec77661be43e8a691 +https://conda.anaconda.org/conda-forge/noarch/setuptools-80.8.0-pyhff2d567_0.conda#ea075e94dc0106c7212128b6a25bbc4c https://conda.anaconda.org/conda-forge/noarch/six-1.17.0-pyhd8ed1ab_0.conda#a451d576819089b0d672f18768be0f65 https://conda.anaconda.org/conda-forge/noarch/threadpoolctl-3.6.0-pyhecae5ae_0.conda#9d64911b31d57ca443e9f1e36b04385f https://conda.anaconda.org/conda-forge/noarch/tomli-2.2.1-pyhd8ed1ab_1.conda#ac944244f1fed2eb49bae07193ae8215 -https://conda.anaconda.org/conda-forge/linux-aarch64/tornado-6.4.2-py310h78583b1_0.conda#68a2bd5dcbb6feac96dee39f4b49fe0f +https://conda.anaconda.org/conda-forge/linux-aarch64/tornado-6.5.1-py310h78583b1_0.conda#e1e576b66cca7642b0a66310b675ea36 +https://conda.anaconda.org/conda-forge/noarch/typing_extensions-4.13.2-pyh29332c3_0.conda#83fc6ae00127671e301c9f44254c31b8 https://conda.anaconda.org/conda-forge/linux-aarch64/unicodedata2-16.0.0-py310ha766c32_0.conda#2936ce19a675e162962f396c7b40b905 https://conda.anaconda.org/conda-forge/noarch/wheel-0.45.1-pyhd8ed1ab_1.conda#75cb7132eb58d97896e173ef12ac9986 https://conda.anaconda.org/conda-forge/linux-aarch64/xcb-util-image-0.4.0-h5c728e9_2.conda#b82e5c78dbbfa931980e8bfe83bce913 @@ -118,20 +115,21 @@ https://conda.anaconda.org/conda-forge/linux-aarch64/xorg-libxext-1.3.6-h57736b2 https://conda.anaconda.org/conda-forge/linux-aarch64/xorg-libxfixes-6.0.1-h57736b2_0.conda#78f8715c002cc66991d7c11e3cf66039 https://conda.anaconda.org/conda-forge/linux-aarch64/xorg-libxrender-0.9.12-h86ecc28_0.conda#ae2c2dd0e2d38d249887727db2af960e https://conda.anaconda.org/conda-forge/linux-aarch64/ccache-4.11.3-h4889ad1_0.conda#e0b9e519da2bf0fb8c48381daf87a194 -https://conda.anaconda.org/conda-forge/linux-aarch64/dbus-1.13.6-h12b9eeb_3.tar.bz2#f3d63805602166bac09386741e00935e -https://conda.anaconda.org/conda-forge/linux-aarch64/fonttools-4.57.0-py310heeae437_0.conda#548b750f1b3ec57d07b0014f8081e9c2 +https://conda.anaconda.org/conda-forge/linux-aarch64/dbus-1.16.2-heda779d_0.conda#9203b74bb1f3fa0d6f308094b3b44c1e +https://conda.anaconda.org/conda-forge/noarch/exceptiongroup-1.3.0-pyhd8ed1ab_0.conda#72e42d28960d875c7654614f8b50939a +https://conda.anaconda.org/conda-forge/linux-aarch64/fonttools-4.58.0-py310heeae437_0.conda#426a52d57550926ebe1735ba0eacd99d https://conda.anaconda.org/conda-forge/linux-aarch64/freetype-2.13.3-h8af1aa0_1.conda#71c4cbe1b384a8e7b56993394a435343 -https://conda.anaconda.org/conda-forge/noarch/joblib-1.5.0-pyhd8ed1ab_0.conda#3d7257f0a61c9aa4ffa3e324a887416b +https://conda.anaconda.org/conda-forge/noarch/joblib-1.5.1-pyhd8ed1ab_0.conda#fb1c14694de51a476ce8636d92b6f42c https://conda.anaconda.org/conda-forge/linux-aarch64/libcblas-3.9.0-31_hab92f65_openblas.conda#6b81dbae56a519f1ec2f25e0ee2f4334 https://conda.anaconda.org/conda-forge/linux-aarch64/libgl-1.7.0-hd24410f_2.conda#0d00176464ebb25af83d40736a2cd3bb https://conda.anaconda.org/conda-forge/linux-aarch64/liblapack-3.9.0-31_h411afd4_openblas.conda#41dbff5eb805a75c120a7b7a1c744dc2 -https://conda.anaconda.org/conda-forge/linux-aarch64/libllvm20-20.1.4-h07bd352_0.conda#a83f31777ec098202198145883d86ffb -https://conda.anaconda.org/conda-forge/linux-aarch64/libxkbcommon-1.9.1-hbab7b08_0.conda#49a02083d4ab2cda74584a64defb4b9d +https://conda.anaconda.org/conda-forge/linux-aarch64/libllvm20-20.1.5-h07bd352_0.conda#d898466dd826e8acf6d0ee075028f6bd +https://conda.anaconda.org/conda-forge/linux-aarch64/libxkbcommon-1.10.0-hbab7b08_0.conda#36cd1db31e923c6068b7e0e6fce2cd7b https://conda.anaconda.org/conda-forge/linux-aarch64/libxslt-1.1.39-h1cc9640_0.conda#13e1d3f9188e85c6d59a98651aced002 -https://conda.anaconda.org/conda-forge/linux-aarch64/openldap-2.6.9-h30c48ee_0.conda#c07822a5de65ce9797b9afa257faa917 +https://conda.anaconda.org/conda-forge/linux-aarch64/openldap-2.6.10-h30c48ee_0.conda#48f31a61be512ec1929f4b4a9cedf4bd +https://conda.anaconda.org/conda-forge/linux-aarch64/pillow-11.2.1-py310h34c99de_0.conda#116816e9f034fcaeafcd878ef8b1e323 https://conda.anaconda.org/conda-forge/noarch/pip-25.1.1-pyh8b19718_0.conda#32d0781ace05105cc99af55d36cbec7c https://conda.anaconda.org/conda-forge/noarch/pyproject-metadata-0.9.1-pyhd8ed1ab_0.conda#22ae7c6ea81e0c8661ef32168dda929b -https://conda.anaconda.org/conda-forge/noarch/pytest-8.3.5-pyhd8ed1ab_0.conda#c3c9316209dec74a705a36797970c6be https://conda.anaconda.org/conda-forge/noarch/python-dateutil-2.9.0.post0-pyhff2d567_1.conda#5ba79d7c71f03c678c8ead841f347d6e https://conda.anaconda.org/conda-forge/linux-aarch64/xcb-util-cursor-0.1.5-h86ecc28_0.conda#d6bb2038d26fa118d5cbc2761116f3e5 https://conda.anaconda.org/conda-forge/linux-aarch64/xorg-libxcomposite-0.4.6-h86ecc28_2.conda#86051eee0766c3542be24844a9c3cf36 @@ -141,22 +139,22 @@ https://conda.anaconda.org/conda-forge/linux-aarch64/xorg-libxi-1.8.2-h57736b2_0 https://conda.anaconda.org/conda-forge/linux-aarch64/xorg-libxrandr-1.5.4-h86ecc28_0.conda#dd3e74283a082381aa3860312e3c721e https://conda.anaconda.org/conda-forge/linux-aarch64/xorg-libxxf86vm-1.1.6-h86ecc28_0.conda#d745faa2d7c15092652e40a22bb261ed https://conda.anaconda.org/conda-forge/linux-aarch64/fontconfig-2.15.0-h8dda3cd_1.conda#112b71b6af28b47c624bcbeefeea685b -https://conda.anaconda.org/conda-forge/linux-aarch64/libclang-cpp20.1-20.1.4-default_h7d4303a_0.conda#d71665eccdb65183c72e149424ec3928 -https://conda.anaconda.org/conda-forge/linux-aarch64/libclang13-20.1.4-default_h9e36cb9_0.conda#6d587caa650694fa5f6d04fda1bcfee2 +https://conda.anaconda.org/conda-forge/linux-aarch64/libclang-cpp20.1-20.1.5-default_h7d4303a_1.conda#e2c94afb8bc1364bc872a61cbd876688 +https://conda.anaconda.org/conda-forge/linux-aarch64/libclang13-20.1.5-default_h9e36cb9_1.conda#d98eeb2cba2804d5cffc7f17787211fc https://conda.anaconda.org/conda-forge/linux-aarch64/liblapacke-3.9.0-31_hc659ca5_openblas.conda#256bb281d78e5b8927ff13a1cde9f6f5 -https://conda.anaconda.org/conda-forge/linux-aarch64/libpq-17.4-hf590da8_1.conda#10fdc78be541c9017e2144f86d092aa2 -https://conda.anaconda.org/conda-forge/noarch/meson-python-0.17.1-pyh70fd9c4_1.conda#7a02679229c6c2092571b4c025055440 -https://conda.anaconda.org/conda-forge/linux-aarch64/numpy-2.2.5-py310h6e5608f_0.conda#5c521c566cbcf058769c613dee3a18d6 -https://conda.anaconda.org/conda-forge/linux-aarch64/pillow-11.1.0-py310h34c99de_0.conda#c4fa80647a708505d65573c2353bc216 -https://conda.anaconda.org/conda-forge/noarch/pytest-xdist-3.6.1-pyhd8ed1ab_1.conda#59aad4fb37cabc0bacc73cf344612ddd +https://conda.anaconda.org/conda-forge/linux-aarch64/libpq-17.5-hf590da8_0.conda#b5a01e5aa04651ccf5865c2d029affa3 +https://conda.anaconda.org/conda-forge/noarch/meson-python-0.18.0-pyh70fd9c4_0.conda#576c04b9d9f8e45285fb4d9452c26133 +https://conda.anaconda.org/conda-forge/linux-aarch64/numpy-2.2.6-py310h6e5608f_0.conda#9e9f1f279eb02c41bda162a42861adc0 +https://conda.anaconda.org/conda-forge/noarch/pytest-8.3.5-pyhd8ed1ab_0.conda#c3c9316209dec74a705a36797970c6be https://conda.anaconda.org/conda-forge/linux-aarch64/xorg-libxtst-1.2.5-h57736b2_3.conda#c05698071b5c8e0da82a282085845860 https://conda.anaconda.org/conda-forge/linux-aarch64/blas-devel-3.9.0-31_h9678261_openblas.conda#a2cc143d7e25e52a915cb320e5b0d592 https://conda.anaconda.org/conda-forge/linux-aarch64/cairo-1.18.4-h83712da_0.conda#cd55953a67ec727db5dc32b167201aa6 https://conda.anaconda.org/conda-forge/linux-aarch64/contourpy-1.3.2-py310hf54e67a_0.conda#779694434d1f0a67c5260db76b7b7907 +https://conda.anaconda.org/conda-forge/noarch/pytest-xdist-3.6.1-pyhd8ed1ab_1.conda#59aad4fb37cabc0bacc73cf344612ddd https://conda.anaconda.org/conda-forge/linux-aarch64/scipy-1.15.2-py310hf37559f_0.conda#5c9b72f10d2118d943a5eaaf2f396891 https://conda.anaconda.org/conda-forge/linux-aarch64/blas-2.131-openblas.conda#51c5f346e1ebee750f76066490059df9 -https://conda.anaconda.org/conda-forge/linux-aarch64/harfbuzz-11.1.0-h405b6a2_0.conda#6fd48c127b76a95ed3858c47fa9db7b0 -https://conda.anaconda.org/conda-forge/linux-aarch64/matplotlib-base-3.10.1-py310h2cc5e2d_0.conda#5652e355346f4823f6b4bfdd4860359d -https://conda.anaconda.org/conda-forge/linux-aarch64/qt6-main-6.9.0-ha483c8b_1.conda#fb32973c68de1f23a7e4de3651442b15 +https://conda.anaconda.org/conda-forge/linux-aarch64/harfbuzz-11.2.1-h405b6a2_0.conda#b55680fc90e9747dc858e7ceb0abc2b2 +https://conda.anaconda.org/conda-forge/linux-aarch64/matplotlib-base-3.10.3-py310h2cc5e2d_0.conda#e29f4329f4f76cf14f74ed86dcc59bac +https://conda.anaconda.org/conda-forge/linux-aarch64/qt6-main-6.9.0-h13135bf_3.conda#f3d24ce6f388642e76f4917b5069c2e9 https://conda.anaconda.org/conda-forge/linux-aarch64/pyside6-6.9.0-py310hee8ad4f_0.conda#68f556281ac23f1780381f00de99d66d -https://conda.anaconda.org/conda-forge/linux-aarch64/matplotlib-3.10.1-py310hbbe02a8_0.conda#c6aa0ea00ec104d0ad260c2ed2bb5582 +https://conda.anaconda.org/conda-forge/linux-aarch64/matplotlib-3.10.3-py310hbbe02a8_0.conda#08982f6ac753e962d59160b08839221b diff --git a/build_tools/update_environments_and_lock_files.py b/build_tools/update_environments_and_lock_files.py index 0edf62b5a0d7b..5efd7f12cffd7 100644 --- a/build_tools/update_environments_and_lock_files.py +++ b/build_tools/update_environments_and_lock_files.py @@ -271,11 +271,8 @@ def remove_from(alist, to_remove): "conda_dependencies": [ "python-freethreading", "numpy", - # TODO add cython and scipy when there are conda-forge packages for - # them and remove dev version install in - # build_tools/azure/install.sh. Note that for now conda-lock does - # not deal with free-threaded wheels correctly, see - # https://github.com/conda/conda-lock/issues/754. + "scipy", + "cython", "joblib", "threadpoolctl", "pytest", diff --git a/doc/conf.py b/doc/conf.py index 1113d4b2c100a..71c9ec5bb60c3 100644 --- a/doc/conf.py +++ b/doc/conf.py @@ -668,7 +668,7 @@ def notebook_modification_function(notebook_content, notebook_filename): if "seaborn" in notebook_content_str: code_lines.append("%pip install seaborn") if "plotly.express" in notebook_content_str: - code_lines.append("%pip install plotly") + code_lines.append("%pip install plotly nbformat") if "skimage" in notebook_content_str: code_lines.append("%pip install scikit-image") if "polars" in notebook_content_str: diff --git a/doc/developers/contributing.rst b/doc/developers/contributing.rst index 34e8e6d3e2aca..bebeb93d86b0c 100644 --- a/doc/developers/contributing.rst +++ b/doc/developers/contributing.rst @@ -726,6 +726,19 @@ We are glad to accept any sort of documentation: .. dropdown:: Guidelines for writing docstrings + * You can use `pytest` to test docstrings, e.g. assuming the + `RandomForestClassifier` docstring has been modified, the following command + would test its docstring compliance: + + .. prompt:: bash + + pytest --doctest-modules sklearn/ensemble/_forest.py -k RandomForestClassifier + + * The correct order of sections is: Parameters, Returns, See Also, Notes, Examples. + See the `numpydoc documentation + `_ for + information on other possible sections. + * When documenting the parameters and attributes, here is a list of some well-formatted examples @@ -791,7 +804,15 @@ We are glad to accept any sort of documentation: SelectKBest : Select features based on the k highest scores. SelectFpr : Select features based on a false positive rate test. - * Add one or two snippets of code in "Example" section to show how it can be used. + * The "Notes" section is optional. It is meant to provide information on + specific behavior of a function/class/classmethod/method. + + * A `Note` can also be added to an attribute, but in that case it requires + using the `.. rubric:: Note` directive. + + * Add one or two **snippets** of code in "Example" section to show how it can + be used. The code should be runable as is, i.e. it should include all + required imports. Keep this section as brief as possible. .. dropdown:: Guidelines for writing the user guide and other reStructuredText documents diff --git a/doc/developers/maintainer.rst.template b/doc/developers/maintainer.rst.template index b7134d4170521..5211d9a575389 100644 --- a/doc/developers/maintainer.rst.template +++ b/doc/developers/maintainer.rst.template @@ -121,6 +121,9 @@ Reference Steps * [ ] Update the sklearn dev0 version in main branch {%- endif %} * [ ] Set the version number in the release branch + {% if key == "rc" -%} + * [ ] Set an upper bound on build dependencies in the release branch + {%- endif %} * [ ] Generate the changelog in the release branch * [ ] Check that the wheels for the release can be built successfully * [ ] Merge the PR with `[cd build]` commit message to upload wheels to the staging repo @@ -162,6 +165,17 @@ Reference Steps - In the release branch, change the version number `__version__` in `sklearn/__init__.py` to `{{ version_full }}`. + {% if key == "rc" %} + - Still in the release branch, set or update the upper bound on the build + dependencies in the `[build-system]` section of `pyproject.toml`. The goal is to + prevent future backward incompatible releases of the dependencies to break the + build in the maintenance branch. + + The upper bounds should match the latest already-released minor versions of the + dependencies and should allow future micro (bug-fix) versions. For instance, if + numpy 2.2.5 is the most recent version, its upper bound should be set to <2.3.0. + {% endif %} + - In the release branch, generate the changelog for the incoming version, i.e., `doc/whats_new/{{ version_short }}.rst`. {%- if key == "rc" %} diff --git a/doc/modules/array_api.rst b/doc/modules/array_api.rst index e7261ea35cc7c..e1a499c97506b 100644 --- a/doc/modules/array_api.rst +++ b/doc/modules/array_api.rst @@ -139,6 +139,7 @@ Metrics - :func:`sklearn.metrics.f1_score` - :func:`sklearn.metrics.fbeta_score` - :func:`sklearn.metrics.hamming_loss` +- :func:`sklearn.metrics.jaccard_score` - :func:`sklearn.metrics.max_error` - :func:`sklearn.metrics.mean_absolute_error` - :func:`sklearn.metrics.mean_absolute_percentage_error` @@ -201,17 +202,32 @@ it supports the Array API. This will enable dedicated checks as part of the common tests to verify that the estimators' results are the same when using vanilla NumPy and Array API inputs. -To run the full set of checks you need to install both -`PyTorch `_ and `CuPy `_ and have +To run these checks you need to install +`array-api-strict `_ in your +test environment. This allows you to run checks without having a +GPU. To run the full set of checks you also need to install +`PyTorch `_, `CuPy `_ and have a GPU. Checks that can not be executed or have missing dependencies will be automatically skipped. Therefore it's important to run the tests with the `-v` flag to see which checks are skipped: .. prompt:: bash $ - pip install ... # selected libraries as needed + pip install array-api-strict # and other libraries as needed pytest -k "array_api" -v +Running the scikit-learn tests against `array-api-strict` should help reveal +most code problems related to handling multiple device inputs via the use of +simulated non-CPU devices. This allows for fast iterative development and debugging of +array API related code. + +However, to ensure full handling of PyTorch or CuPy inputs allocated on actual GPU +devices, it is necessary to run the tests against those libraries and hardware. +This can either be achieved by using +`Google Colab `_ +or leveraging our CI infrastructure on pull requests (manually triggered by maintainers +for cost reasons). + .. _mps_support: Note on MPS device support diff --git a/doc/modules/calibration.rst b/doc/modules/calibration.rst index a7b34065fe330..e8e6aa8b9953a 100644 --- a/doc/modules/calibration.rst +++ b/doc/modules/calibration.rst @@ -103,7 +103,7 @@ difficulty making predictions near 0 and 1 because variance in the underlying base models will bias predictions that should be near zero or one away from these values. Because predictions are restricted to the interval [0,1], errors caused by variance tend to be one-sided near zero and one. For -example, if a model should predict p = 0 for a case, the only way bagging +example, if a model should predict :math:`p = 0` for a case, the only way bagging can achieve this is if all bagged trees predict zero. If we add noise to the trees that bagging is averaging over, this noise will cause some trees to predict values larger than 0 for this case, thus moving the average @@ -146,7 +146,7 @@ Usage The :class:`CalibratedClassifierCV` class is used to calibrate a classifier. :class:`CalibratedClassifierCV` uses a cross-validation approach to ensure -unbiased data is always used to fit the calibrator. The data is split into k +unbiased data is always used to fit the calibrator. The data is split into :math:`k` `(train_set, test_set)` couples (as determined by `cv`). When `ensemble=True` (default), the following procedure is repeated independently for each cross-validation split: @@ -157,13 +157,13 @@ cross-validation split: regressor) (when the data is multiclass, a calibrator is fit for every class) This results in an -ensemble of k `(classifier, calibrator)` couples where each calibrator maps +ensemble of :math:`k` `(classifier, calibrator)` couples where each calibrator maps the output of its corresponding classifier into [0, 1]. Each couple is exposed in the `calibrated_classifiers_` attribute, where each entry is a calibrated classifier with a :term:`predict_proba` method that outputs calibrated probabilities. The output of :term:`predict_proba` for the main :class:`CalibratedClassifierCV` instance corresponds to the average of the -predicted probabilities of the `k` estimators in the `calibrated_classifiers_` +predicted probabilities of the :math:`k` estimators in the `calibrated_classifiers_` list. The output of :term:`predict` is the class that has the highest probability. @@ -244,12 +244,12 @@ subject to :math:`\hat{f}_i \geq \hat{f}_j` whenever :math:`f_i \geq f_j`. :math:`y_i` is the true label of sample :math:`i` and :math:`\hat{f}_i` is the output of the calibrated classifier for sample :math:`i` (i.e., the calibrated probability). -This method is more general when compared to 'sigmoid' as the only restriction +This method is more general when compared to `'sigmoid'` as the only restriction is that the mapping function is monotonically increasing. It is thus more powerful as it can correct any monotonic distortion of the un-calibrated model. However, it is more prone to overfitting, especially on small datasets [6]_. -Overall, 'isotonic' will perform as well as or better than 'sigmoid' when +Overall, `'isotonic'` will perform as well as or better than `'sigmoid'` when there is enough data (greater than ~ 1000 samples) to avoid overfitting [3]_. .. note:: Impact on ranking metrics like AUC diff --git a/doc/modules/cross_validation.rst b/doc/modules/cross_validation.rst index bfdee6c8a043d..b1c9ccec8f641 100644 --- a/doc/modules/cross_validation.rst +++ b/doc/modules/cross_validation.rst @@ -372,8 +372,7 @@ Thus, one can create the training/test sets using numpy indexing:: Repeated K-Fold ^^^^^^^^^^^^^^^ -:class:`RepeatedKFold` repeats K-Fold n times. It can be used when one -requires to run :class:`KFold` n times, producing different splits in +:class:`RepeatedKFold` repeats :class:`KFold` :math:`n` times, producing different splits in each repetition. Example of 2-fold K-Fold repeated 2 times:: @@ -392,7 +391,7 @@ Example of 2-fold K-Fold repeated 2 times:: [1 3] [0 2] -Similarly, :class:`RepeatedStratifiedKFold` repeats Stratified K-Fold n times +Similarly, :class:`RepeatedStratifiedKFold` repeats :class:`StratifiedKFold` :math:`n` times with different randomization in each repetition. .. _leave_one_out: @@ -434,10 +433,10 @@ folds are virtually identical to each other and to the model built from the entire training set. However, if the learning curve is steep for the training size in question, -then 5- or 10- fold cross validation can overestimate the generalization error. +then 5 or 10-fold cross validation can overestimate the generalization error. -As a general rule, most authors, and empirical evidence, suggest that 5- or 10- -fold cross validation should be preferred to LOO. +As a general rule, most authors and empirical evidence suggest that 5 or 10-fold +cross validation should be preferred to LOO. .. dropdown:: References @@ -553,10 +552,10 @@ relative class frequencies are approximately preserved in each fold. .. _stratified_k_fold: -Stratified k-fold +Stratified K-fold ^^^^^^^^^^^^^^^^^ -:class:`StratifiedKFold` is a variation of *k-fold* which returns *stratified* +:class:`StratifiedKFold` is a variation of *K-fold* which returns *stratified* folds: each set contains approximately the same percentage of samples of each target class as the complete set. @@ -648,10 +647,10 @@ parameter. .. _group_k_fold: -Group k-fold +Group K-fold ^^^^^^^^^^^^ -:class:`GroupKFold` is a variation of k-fold which ensures that the same group is +:class:`GroupKFold` is a variation of K-fold which ensures that the same group is not represented in both testing and training sets. For example if the data is obtained from different subjects with several samples per-subject and if the model is flexible enough to learn from highly person specific features it diff --git a/doc/modules/ensemble.rst b/doc/modules/ensemble.rst index f0f14c60e4867..6b0fc93e437ff 100644 --- a/doc/modules/ensemble.rst +++ b/doc/modules/ensemble.rst @@ -308,7 +308,7 @@ values. all of the :math:`2^{K - 1} - 1` partitions, where :math:`K` is the number of categories. This can quickly become prohibitive when :math:`K` is large. Fortunately, since gradient boosting trees are always regression trees (even - for classification problems), there exist a faster strategy that can yield + for classification problems), there exists a faster strategy that can yield equivalent splits. First, the categories of a feature are sorted according to the variance of the target, for each category `k`. Once the categories are sorted, one can consider *continuous partitions*, i.e. treat the categories @@ -1587,7 +1587,7 @@ Note that it is also possible to get the output of the stacked In practice, a stacking predictor predicts as good as the best predictor of the base layer and even sometimes outperforms it by combining the different -strengths of the these predictors. However, training a stacking predictor is +strengths of these predictors. However, training a stacking predictor is computationally expensive. .. note:: diff --git a/doc/modules/kernel_ridge.rst b/doc/modules/kernel_ridge.rst index fcc19a49628c4..64267f4233a53 100644 --- a/doc/modules/kernel_ridge.rst +++ b/doc/modules/kernel_ridge.rst @@ -7,7 +7,7 @@ Kernel ridge regression .. currentmodule:: sklearn.kernel_ridge Kernel ridge regression (KRR) [M2012]_ combines :ref:`ridge_regression` -(linear least squares with l2-norm regularization) with the `kernel trick +(linear least squares with :math:`L_2`-norm regularization) with the `kernel trick `_. It thus learns a linear function in the space induced by the respective kernel and the data. For non-linear kernels, this corresponds to a non-linear function in the original @@ -16,7 +16,7 @@ space. The form of the model learned by :class:`KernelRidge` is identical to support vector regression (:class:`~sklearn.svm.SVR`). However, different loss functions are used: KRR uses squared error loss while support vector -regression uses :math:`\epsilon`-insensitive loss, both combined with l2 +regression uses :math:`\epsilon`-insensitive loss, both combined with :math:`L_2` regularization. In contrast to :class:`~sklearn.svm.SVR`, fitting :class:`KernelRidge` can be done in closed-form and is typically faster for medium-sized datasets. On the other hand, the learned model is non-sparse and @@ -31,7 +31,7 @@ plotted, where both complexity/regularization and bandwidth of the RBF kernel have been optimized using grid-search. The learned functions are very similar; however, fitting :class:`KernelRidge` is approximately seven times faster than fitting :class:`~sklearn.svm.SVR` (both with grid-search). -However, prediction of 100000 target values is more than three times faster +However, prediction of 100,000 target values is more than three times faster with :class:`~sklearn.svm.SVR` since it has learned a sparse model using only approximately 1/3 of the 100 training datapoints as support vectors. diff --git a/doc/modules/lda_qda.rst b/doc/modules/lda_qda.rst index 405ef8e5d3a8b..c18835d514a9f 100644 --- a/doc/modules/lda_qda.rst +++ b/doc/modules/lda_qda.rst @@ -173,11 +173,11 @@ In this scenario, the empirical sample covariance is a poor estimator, and shrinkage helps improving the generalization performance of the classifier. Shrinkage LDA can be used by setting the ``shrinkage`` parameter of -the :class:`~discriminant_analysis.LinearDiscriminantAnalysis` class to 'auto'. +the :class:`~discriminant_analysis.LinearDiscriminantAnalysis` class to `'auto'`. This automatically determines the optimal shrinkage parameter in an analytic way following the lemma introduced by Ledoit and Wolf [2]_. Note that -currently shrinkage only works when setting the ``solver`` parameter to 'lsqr' -or 'eigen'. +currently shrinkage only works when setting the ``solver`` parameter to `'lsqr'` +or `'eigen'`. The ``shrinkage`` parameter can also be manually set between 0 and 1. In particular, a value of 0 corresponds to no shrinkage (which means the empirical @@ -192,7 +192,7 @@ best choice. For example if the distribution of the data is normally distributed, the Oracle Approximating Shrinkage estimator :class:`sklearn.covariance.OAS` yields a smaller Mean Squared Error than the one given by Ledoit and Wolf's -formula used with shrinkage="auto". In LDA, the data are assumed to be gaussian +formula used with `shrinkage="auto"`. In LDA, the data are assumed to be gaussian conditionally to the class. If these assumptions hold, using LDA with the OAS estimator of covariance will yield a better classification accuracy than if Ledoit and Wolf or the empirical covariance estimator is used. @@ -239,7 +239,7 @@ computing :math:`S` and :math:`V` via the SVD of :math:`X` is enough. For LDA, two SVDs are computed: the SVD of the centered input matrix :math:`X` and the SVD of the class-wise mean vectors. -The 'lsqr' solver is an efficient algorithm that only works for +The `'lsqr'` solver is an efficient algorithm that only works for classification. It needs to explicitly compute the covariance matrix :math:`\Sigma`, and supports shrinkage and custom covariance estimators. This solver computes the coefficients @@ -247,9 +247,9 @@ This solver computes the coefficients \mu_k`, thus avoiding the explicit computation of the inverse :math:`\Sigma^{-1}`. -The 'eigen' solver is based on the optimization of the between class scatter to +The `'eigen'` solver is based on the optimization of the between class scatter to within class scatter ratio. It can be used for both classification and -transform, and it supports shrinkage. However, the 'eigen' solver needs to +transform, and it supports shrinkage. However, the `'eigen'` solver needs to compute the covariance matrix, so it might not be suitable for situations with a high number of features. diff --git a/doc/modules/linear_model.rst b/doc/modules/linear_model.rst index 69a2bf9b7f477..9edd90321bd02 100644 --- a/doc/modules/linear_model.rst +++ b/doc/modules/linear_model.rst @@ -654,7 +654,7 @@ or :func:`lars_path_gram`. .. rubric:: References * Original Algorithm is detailed in the paper `Least Angle Regression - `_ + `_ by Hastie et al. .. _omp: @@ -971,7 +971,7 @@ logistic regression, see also `log-linear model .. dropdown:: Mathematical details - Let :math:`y_i \in {1, \ldots, K}` be the label (ordinal) encoded target variable for observation :math:`i`. + Let :math:`y_i \in \{1, \ldots, K\}` be the label (ordinal) encoded target variable for observation :math:`i`. Instead of a single coefficient vector, we now have a matrix of coefficients :math:`W` where each row vector :math:`W_k` corresponds to class :math:`k`. We aim at predicting the class probabilities :math:`P(y_i=k|X_i)` via @@ -1022,7 +1022,7 @@ The following table summarizes the penalties and multinomial multiclass supporte +------------------------------+-------------+-----------------+-----------------+-----------------------+-----------+------------+ | **Penalties** | **'lbfgs'** | **'liblinear'** | **'newton-cg'** | **'newton-cholesky'** | **'sag'** | **'saga'** | +------------------------------+-------------+-----------------+-----------------+-----------------------+-----------+------------+ -| L2 penalty | yes | no | yes | no | yes | yes | +| L2 penalty | yes | yes | yes | yes | yes | yes | +------------------------------+-------------+-----------------+-----------------+-----------------------+-----------+------------+ | L1 penalty | no | yes | no | no | no | yes | +------------------------------+-------------+-----------------+-----------------+-----------------------+-----------+------------+ @@ -1032,7 +1032,7 @@ The following table summarizes the penalties and multinomial multiclass supporte +------------------------------+-------------+-----------------+-----------------+-----------------------+-----------+------------+ | **Multiclass support** | | +------------------------------+-------------+-----------------+-----------------+-----------------------+-----------+------------+ -| multinomial multiclass | yes | no | yes | no | yes | yes | +| multinomial multiclass | yes | no | yes | yes | yes | yes | +------------------------------+-------------+-----------------+-----------------+-----------------------+-----------+------------+ | **Behaviors** | | +------------------------------+-------------+-----------------+-----------------+-----------------------+-----------+------------+ @@ -1043,8 +1043,11 @@ The following table summarizes the penalties and multinomial multiclass supporte | Robust to unscaled datasets | yes | yes | yes | yes | no | no | +------------------------------+-------------+-----------------+-----------------+-----------------------+-----------+------------+ -The "lbfgs" solver is used by default for its robustness. For large datasets -the "saga" solver is usually faster. +The "lbfgs" solver is used by default for its robustness. For +`n_samples >> n_features`, "newton-cholesky" is a good choice and can reach high +precision (tiny `tol` values). For large datasets +the "saga" solver is usually faster (than "lbfgs"), in particular for low precision +(high `tol`). For large dataset, you may also consider using :class:`SGDClassifier` with `loss="log_loss"`, which might be even faster but requires more tuning. @@ -1101,13 +1104,12 @@ zero, is likely to be an underfit, bad model and you are advised to set scaled datasets and on datasets with one-hot encoded categorical features with rare categories. - * The "newton-cholesky" solver is an exact Newton solver that calculates the hessian + * The "newton-cholesky" solver is an exact Newton solver that calculates the Hessian matrix and solves the resulting linear system. It is a very good choice for - `n_samples` >> `n_features`, but has a few shortcomings: Only :math:`\ell_2` - regularization is supported. Furthermore, because the hessian matrix is explicitly - computed, the memory usage has a quadratic dependency on `n_features` as well as on - `n_classes`. As a consequence, only the one-vs-rest scheme is implemented for the - multiclass case. + `n_samples` >> `n_features` and can reach high precision (tiny values of `tol`), + but has a few shortcomings: Only :math:`\ell_2` regularization is supported. + Furthermore, because the Hessian matrix is explicitly computed, the memory usage + has a quadratic dependency on `n_features` as well as on `n_classes`. For a comparison of some of these solvers, see [9]_. diff --git a/doc/modules/manifold.rst b/doc/modules/manifold.rst index fec6e96153323..aec992a8f9dc1 100644 --- a/doc/modules/manifold.rst +++ b/doc/modules/manifold.rst @@ -115,6 +115,9 @@ from the data itself, without the use of predetermined classifications. * See :ref:`sphx_glr_auto_examples_manifold_plot_manifold_sphere.py` for an example of manifold learning techniques applied to a spherical data-set. +* See :ref:`sphx_glr_auto_examples_manifold_plot_swissroll.py` for an example of using + manifold learning techniques on a Swiss Roll dataset. + The manifold learning implementations available in scikit-learn are summarized below diff --git a/doc/modules/model_evaluation.rst b/doc/modules/model_evaluation.rst index cf168295a6024..c304966fccdb2 100644 --- a/doc/modules/model_evaluation.rst +++ b/doc/modules/model_evaluation.rst @@ -1880,7 +1880,7 @@ In multilabel classification, the :func:`zero_one_loss` scores a subset as one if its labels strictly match the predictions, and as a zero if there are any errors. By default, the function returns the percentage of imperfectly predicted subsets. To get the count of such subsets instead, set -``normalize`` to ``False`` +``normalize`` to ``False``. If :math:`\hat{y}_i` is the predicted value of the :math:`i`-th sample and :math:`y_i` is the corresponding true value, @@ -1891,8 +1891,8 @@ then the 0-1 loss :math:`L_{0-1}` is defined as: L_{0-1}(y, \hat{y}) = \frac{1}{n_\text{samples}} \sum_{i=0}^{n_\text{samples}-1} 1(\hat{y}_i \not= y_i) where :math:`1(x)` is the `indicator function -`_. The zero one -loss can also be computed as :math:`zero-one loss = 1 - accuracy`. +`_. The zero-one +loss can also be computed as :math:`\text{zero-one loss} = 1 - \text{accuracy}`. >>> from sklearn.metrics import zero_one_loss diff --git a/doc/modules/partial_dependence.rst b/doc/modules/partial_dependence.rst index 083b23c1f1c91..7f30a3a7e6731 100644 --- a/doc/modules/partial_dependence.rst +++ b/doc/modules/partial_dependence.rst @@ -211,11 +211,11 @@ Computation methods =================== There are two main methods to approximate the integral above, namely the -'brute' and 'recursion' methods. The `method` parameter controls which method +`'brute'` and `'recursion'` methods. The `method` parameter controls which method to use. -The 'brute' method is a generic method that works with any estimator. Note that -computing ICE plots is only supported with the 'brute' method. It +The `'brute'` method is a generic method that works with any estimator. Note that +computing ICE plots is only supported with the `'brute'` method. It approximates the above integral by computing an average over the data `X`: .. math:: @@ -231,7 +231,7 @@ at :math:`x_{S}`. Computing this for multiple values of :math:`x_{S}`, one obtains a full ICE line. As one can see, the average of the ICE lines corresponds to the partial dependence line. -The 'recursion' method is faster than the 'brute' method, but it is only +The `'recursion'` method is faster than the `'brute'` method, but it is only supported for PDP plots by some tree-based estimators. It is computed as follows. For a given point :math:`x_S`, a weighted tree traversal is performed: if a split node involves an input feature of interest, the corresponding left @@ -240,12 +240,12 @@ being weighted by the fraction of training samples that entered that branch. Finally, the partial dependence is given by a weighted average of all the visited leaves' values. -With the 'brute' method, the parameter `X` is used both for generating the +With the `'brute'` method, the parameter `X` is used both for generating the grid of values :math:`x_S` and the complement feature values :math:`x_C`. However with the 'recursion' method, `X` is only used for the grid values: implicitly, the :math:`x_C` values are those of the training data. -By default, the 'recursion' method is used for plotting PDPs on tree-based +By default, the `'recursion'` method is used for plotting PDPs on tree-based estimators that support it, and 'brute' is used for the rest. .. _pdp_method_differences: @@ -253,10 +253,10 @@ estimators that support it, and 'brute' is used for the rest. .. note:: While both methods should be close in general, they might differ in some - specific settings. The 'brute' method assumes the existence of the + specific settings. The `'brute'` method assumes the existence of the data points :math:`(x_S, x_C^{(i)})`. When the features are correlated, - such artificial samples may have a very low probability mass. The 'brute' - and 'recursion' methods will likely disagree regarding the value of the + such artificial samples may have a very low probability mass. The `'brute'` + and `'recursion'` methods will likely disagree regarding the value of the partial dependence, because they will treat these unlikely samples differently. Remember, however, that the primary assumption for interpreting PDPs is that the features should be independent. diff --git a/doc/modules/sgd.rst b/doc/modules/sgd.rst index 103ae205387e3..4f34b7f50e072 100644 --- a/doc/modules/sgd.rst +++ b/doc/modules/sgd.rst @@ -71,7 +71,7 @@ penalties for classification. Below is the decision boundary of a As other classifiers, SGD has to be fitted with two arrays: an array `X` of shape (n_samples, n_features) holding the training samples, and an -array y of shape (n_samples,) holding the target values (class labels) +array `y` of shape (n_samples,) holding the target values (class labels) for the training samples:: >>> from sklearn.linear_model import SGDClassifier @@ -114,8 +114,8 @@ parameter. :class:`SGDClassifier` supports the following loss functions: * ``loss="hinge"``: (soft-margin) linear Support Vector Machine, * ``loss="modified_huber"``: smoothed hinge loss, * ``loss="log_loss"``: logistic regression, -* and all regression losses below. In this case the target is encoded as -1 - or 1, and the problem is treated as a regression problem. The predicted +* and all regression losses below. In this case the target is encoded as :math:`-1` + or :math:`1`, and the problem is treated as a regression problem. The predicted class then corresponds to the sign of the predicted target. Please refer to the :ref:`mathematical section below @@ -123,7 +123,7 @@ Please refer to the :ref:`mathematical section below The first two loss functions are lazy, they only update the model parameters if an example violates the margin constraint, which makes training very efficient and may result in sparser models (i.e. with more zero -coefficients), even when L2 penalty is used. +coefficients), even when :math:`L_2` penalty is used. Using ``loss="log_loss"`` or ``loss="modified_huber"`` enables the ``predict_proba`` method, which gives a vector of probability estimates @@ -136,16 +136,16 @@ Using ``loss="log_loss"`` or ``loss="modified_huber"`` enables the The concrete penalty can be set via the ``penalty`` parameter. SGD supports the following penalties: -* ``penalty="l2"``: L2 norm penalty on ``coef_``. -* ``penalty="l1"``: L1 norm penalty on ``coef_``. -* ``penalty="elasticnet"``: Convex combination of L2 and L1; +* ``penalty="l2"``: :math:`L_2` norm penalty on ``coef_``. +* ``penalty="l1"``: :math:`L_1` norm penalty on ``coef_``. +* ``penalty="elasticnet"``: Convex combination of :math:`L_2` and :math:`L_1`; ``(1 - l1_ratio) * L2 + l1_ratio * L1``. -The default setting is ``penalty="l2"``. The L1 penalty leads to sparse +The default setting is ``penalty="l2"``. The :math:`L_1` penalty leads to sparse solutions, driving most coefficients to zero. The Elastic Net [#5]_ solves -some deficiencies of the L1 penalty in the presence of highly correlated +some deficiencies of the :math:`L_1` penalty in the presence of highly correlated attributes. The parameter ``l1_ratio`` controls the convex combination -of L1 and L2 penalty. +of :math:`L_1` and :math:`L_2` penalty. :class:`SGDClassifier` supports multi-class classification by combining multiple binary classifiers in a "one versus all" (OVA) scheme. For each @@ -164,8 +164,8 @@ the decision surface induced by the three classifiers. In the case of multi-class classification ``coef_`` is a two-dimensional array of shape (n_classes, n_features) and ``intercept_`` is a -one-dimensional array of shape (n_classes,). The i-th row of ``coef_`` holds -the weight vector of the OVA classifier for the i-th class; classes are +one-dimensional array of shape (n_classes,). The :math:`i`-th row of ``coef_`` holds +the weight vector of the OVA classifier for the :math:`i`-th class; classes are indexed in ascending order (see attribute ``classes_``). Note that, in principle, since they allow to create a probability model, ``loss="log_loss"`` and ``loss="modified_huber"`` are more suitable for @@ -227,7 +227,7 @@ description above in the classification section). :class:`SGDRegressor` also supports averaged SGD [#4]_ (here again, see description above in the classification section). -For regression with a squared loss and a l2 penalty, another variant of +For regression with a squared loss and a :math:`L_2` penalty, another variant of SGD with an averaging strategy is available with Stochastic Average Gradient (SAG) algorithm, available as a solver in :class:`Ridge`. @@ -245,7 +245,7 @@ solution of a kernelized One-Class SVM, implemented in samples. Note that the complexity of a kernelized One-Class SVM is at best quadratic in the number of samples. :class:`sklearn.linear_model.SGDOneClassSVM` is thus well suited for datasets -with a large number of training samples (> 10,000) for which the SGD +with a large number of training samples (over 10,000) for which the SGD variant can be several orders of magnitude faster. .. dropdown:: Mathematical details @@ -280,7 +280,7 @@ variant can be several orders of magnitude faster. This is similar to the optimization problems studied in section :ref:`sgd_mathematical_formulation` with :math:`y_i = 1, 1 \leq i \leq n` and :math:`\alpha = \nu/2`, :math:`L` being the hinge loss function and :math:`R` - being the L2 norm. We just need to add the term :math:`b\nu` in the + being the :math:`L_2` norm. We just need to add the term :math:`b\nu` in the optimization loop. As :class:`SGDClassifier` and :class:`SGDRegressor`, :class:`SGDOneClassSVM` @@ -312,8 +312,9 @@ Complexity ========== The major advantage of SGD is its efficiency, which is basically -linear in the number of training examples. If X is a matrix of size (n, p) -training has a cost of :math:`O(k n \bar p)`, where k is the number +linear in the number of training examples. If :math:`X` is a matrix of size +:math:`n \times p` (with :math:`n` samples and :math:`p` features), +training has a cost of :math:`O(k n \bar p)`, where :math:`k` is the number of iterations (epochs) and :math:`\bar p` is the average number of non-zero attributes per sample. @@ -348,8 +349,8 @@ Tips on Practical Use * Stochastic Gradient Descent is sensitive to feature scaling, so it is highly recommended to scale your data. For example, scale each - attribute on the input vector X to [0,1] or [-1,+1], or standardize - it to have mean 0 and variance 1. Note that the *same* scaling must be + attribute on the input vector :math:`X` to :math:`[0,1]` or :math:`[-1,1]`, or standardize + it to have mean :math:`0` and variance :math:`1`. Note that the *same* scaling must be applied to the test vector to obtain meaningful results. This can be easily done using :class:`~sklearn.preprocessing.StandardScaler`:: @@ -375,16 +376,16 @@ Tips on Practical Use range ``10.0**-np.arange(1,7)``. * Empirically, we found that SGD converges after observing - approximately 10^6 training samples. Thus, a reasonable first guess + approximately :math:`10^6` training samples. Thus, a reasonable first guess for the number of iterations is ``max_iter = np.ceil(10**6 / n)``, where ``n`` is the size of the training set. * If you apply SGD to features extracted using PCA we found that it is often wise to scale the feature values by some constant `c` - such that the average L2 norm of the training data equals one. + such that the average :math:`L_2` norm of the training data equals one. * We found that Averaged SGD works best with a larger number of features - and a higher eta0. + and a higher `eta0`. .. rubric:: References @@ -452,11 +453,11 @@ misclassification error (Zero-one loss) as shown in the Figure below. Popular choices for the regularization term :math:`R` (the `penalty` parameter) include: -- L2 norm: :math:`R(w) := \frac{1}{2} \sum_{j=1}^{m} w_j^2 = ||w||_2^2`, -- L1 norm: :math:`R(w) := \sum_{j=1}^{m} |w_j|`, which leads to sparse +- :math:`L_2` norm: :math:`R(w) := \frac{1}{2} \sum_{j=1}^{m} w_j^2 = ||w||_2^2`, +- :math:`L_1` norm: :math:`R(w) := \sum_{j=1}^{m} |w_j|`, which leads to sparse solutions. - Elastic Net: :math:`R(w) := \frac{\rho}{2} \sum_{j=1}^{n} w_j^2 + - (1-\rho) \sum_{j=1}^{m} |w_j|`, a convex combination of L2 and L1, where + (1-\rho) \sum_{j=1}^{m} |w_j|`, a convex combination of :math:`L_2` and :math:`L_1`, where :math:`\rho` is given by ``1 - l1_ratio``. The Figure below shows the contours of the different regularization terms @@ -500,8 +501,8 @@ is given by where :math:`t` is the time step (there are a total of `n_samples * n_iter` time steps), :math:`t_0` is determined based on a heuristic proposed by Léon Bottou such that the expected initial updates are comparable with the expected -size of the weights (this assuming that the norm of the training samples is -approx. 1). The exact definition can be found in ``_init_t`` in `BaseSGD`. +size of the weights (this assumes that the norm of the training samples is +approximately 1). The exact definition can be found in ``_init_t`` in `BaseSGD`. For regression the default learning rate schedule is inverse scaling @@ -512,7 +513,7 @@ For regression the default learning rate schedule is inverse scaling \eta^{(t)} = \frac{eta_0}{t^{power\_t}} where :math:`eta_0` and :math:`power\_t` are hyperparameters chosen by the -user via ``eta0`` and ``power_t``, resp. +user via ``eta0`` and ``power_t``, respectively. For a constant learning rate use ``learning_rate='constant'`` and use ``eta0`` to specify the learning rate. @@ -520,7 +521,7 @@ to specify the learning rate. For an adaptively decreasing learning rate, use ``learning_rate='adaptive'`` and use ``eta0`` to specify the starting learning rate. When the stopping criterion is reached, the learning rate is divided by 5, and the algorithm -does not stop. The algorithm stops when the learning rate goes below 1e-6. +does not stop. The algorithm stops when the learning rate goes below `1e-6`. The model parameters can be accessed through the ``coef_`` and ``intercept_`` attributes: ``coef_`` holds the weights :math:`w` and @@ -540,7 +541,7 @@ The implementation of SGD is influenced by the `Stochastic Gradient SVM` of [#1]_. Similar to SvmSGD, the weight vector is represented as the product of a scalar and a vector -which allows an efficient weight update in the case of L2 regularization. +which allows an efficient weight update in the case of :math:`L_2` regularization. In the case of sparse input `X`, the intercept is updated with a smaller learning rate (multiplied by 0.01) to account for the fact that it is updated more frequently. Training examples are picked up sequentially @@ -548,7 +549,7 @@ and the learning rate is lowered after each observed example. We adopted the learning rate schedule from [#2]_. For multi-class classification, a "one versus all" approach is used. We use the truncated gradient algorithm proposed in [#3]_ -for L1 regularization (and the Elastic Net). +for :math:`L_1` regularization (and the Elastic Net). The code is written in Cython. .. rubric:: References diff --git a/doc/templates/index.html b/doc/templates/index.html index 0f0cecf7fed96..ff71b52ebd59c 100644 --- a/doc/templates/index.html +++ b/doc/templates/index.html @@ -206,15 +206,13 @@

News

    -
  • On-going development: scikit-learn 1.7 (Changelog).
  • +
  • On-going development: scikit-learn 1.8 (Changelog).
  • +
  • June 2025. scikit-learn 1.7.0 is available for download (Changelog).
  • January 2025. scikit-learn 1.6.1 is available for download (Changelog).
  • December 2024. scikit-learn 1.6.0 is available for download (Changelog).
  • September 2024. scikit-learn 1.5.2 is available for download (Changelog).
  • July 2024. scikit-learn 1.5.1 is available for download (Changelog).
  • May 2024. scikit-learn 1.5.0 is available for download (Changelog).
  • -
  • April 2024. scikit-learn 1.4.2 is available for download (Changelog).
  • -
  • February 2024. scikit-learn 1.4.1.post1 is available for download (Changelog).
  • -
  • January 2024. scikit-learn 1.4.0 is available for download (Changelog).
  • All releases: What's new (Changelog).
diff --git a/doc/visualizations.rst b/doc/visualizations.rst index 412dfc001fab1..e9d38f25e1e0d 100644 --- a/doc/visualizations.rst +++ b/doc/visualizations.rst @@ -8,37 +8,86 @@ Scikit-learn defines a simple API for creating visualizations for machine learning. The key feature of this API is to allow for quick plotting and visual adjustments without recalculation. We provide `Display` classes that expose two methods for creating plots: `from_estimator` and -`from_predictions`. The `from_estimator` method will take a fitted estimator -and some data (`X` and `y`) and create a `Display` object. Sometimes, we would -like to only compute the predictions once and one should use `from_predictions` -instead. In the following example, we plot a ROC curve for a fitted support -vector machine: +`from_predictions`. + +The `from_estimator` method generates a `Display` object from a fitted estimator, +input data (`X`, `y`), and a plot. +The `from_predictions` method creates a `Display` object from true and predicted +values (`y_test`, `y_pred`), and a plot. + +Using `from_predictions` avoids having to recompute predictions, +but the user needs to take care that the prediction values passed correspond +to the `pos_label`. For :term:`predict_proba`, select the column corresponding +to the `pos_label` class while for :term:`decision_function`, revert the score +(i.e. multiply by -1) if `pos_label` is not the last class in the +`classes_` attribute of your estimator. + +The `Display` object stores the computed values (e.g., metric values or +feature importance) required for plotting with Matplotlib. These values are the +results derived from the raw predictions passed to `from_predictions`, or +an estimator and `X` passed to `from_estimator`. + +Display objects have a plot method that creates a matplotlib plot once the display +object has been initialized (note that we recommend that display objects are created +via `from_estimator` or `from_predictions` instead of initialized directly). +The plot method allows adding to an existing plot by passing the existing plots +:class:`matplotlib.axes.Axes` to the `ax` parameter. + +In the following example, we plot a ROC curve for a fitted Logistic Regression +model `from_estimator`: .. plot:: :context: close-figs :align: center from sklearn.model_selection import train_test_split - from sklearn.svm import SVC + from sklearn.linear_model import LogisticRegression from sklearn.metrics import RocCurveDisplay - from sklearn.datasets import load_wine + from sklearn.datasets import load_iris - X, y = load_wine(return_X_y=True) + X, y = load_iris(return_X_y=True) y = y == 2 # make binary - X_train, X_test, y_train, y_test = train_test_split(X, y, random_state=42) - svc = SVC(random_state=42) - svc.fit(X_train, y_train) + X_train, X_test, y_train, y_test = train_test_split( + X, y, test_size=.8, random_state=42 + ) + clf = LogisticRegression(random_state=42, C=.01) + clf.fit(X_train, y_train) - svc_disp = RocCurveDisplay.from_estimator(svc, X_test, y_test) + clf_disp = RocCurveDisplay.from_estimator(clf, X_test, y_test) -The returned `svc_disp` object allows us to continue using the already computed -ROC curve for SVC in future plots. In this case, the `svc_disp` is a -:class:`~sklearn.metrics.RocCurveDisplay` that stores the computed values as -attributes called `roc_auc`, `fpr`, and `tpr`. Be aware that we could get -the predictions from the support vector machine and then use `from_predictions` -instead of `from_estimator`. Next, we train a random forest classifier and plot -the previously computed ROC curve again by using the `plot` method of the -`Display` object. +If you already have the prediction values, you could instead use +`from_predictions` to do the same thing (and save on compute): + + +.. plot:: + :context: close-figs + :align: center + + from sklearn.model_selection import train_test_split + from sklearn.linear_model import LogisticRegression + from sklearn.metrics import RocCurveDisplay + from sklearn.datasets import load_iris + + X, y = load_iris(return_X_y=True) + y = y == 2 # make binary + X_train, X_test, y_train, y_test = train_test_split( + X, y, test_size=.8, random_state=42 + ) + clf = LogisticRegression(random_state=42, C=.01) + clf.fit(X_train, y_train) + + # select the probability of the class that we considered to be the positive label + y_pred = clf.predict_proba(X_test)[:, 1] + + clf_disp = RocCurveDisplay.from_predictions(y_test, y_pred) + + +The returned `clf_disp` object allows us to add another curve to the already computed +ROC curve. In this case, the `clf_disp` is a :class:`~sklearn.metrics.RocCurveDisplay` +that stores the computed values as attributes called `roc_auc`, `fpr`, and `tpr`. + +Next, we train a random forest classifier and plot the previously computed ROC curve +again by using the `plot` method of the `Display` object. .. plot:: :context: close-figs @@ -51,12 +100,15 @@ the previously computed ROC curve again by using the `plot` method of the rfc.fit(X_train, y_train) ax = plt.gca() - rfc_disp = RocCurveDisplay.from_estimator(rfc, X_test, y_test, ax=ax, alpha=0.8) - svc_disp.plot(ax=ax, alpha=0.8) + rfc_disp = RocCurveDisplay.from_estimator( + rfc, X_test, y_test, ax=ax, curve_kwargs={"alpha": 0.8} + ) + clf_disp.plot(ax=ax, curve_kwargs={"alpha": 0.8}) Notice that we pass `alpha=0.8` to the plot functions to adjust the alpha values of the curves. + .. rubric:: Examples * :ref:`sphx_glr_auto_examples_miscellaneous_plot_roc_curve_visualization_api.py` diff --git a/doc/whats_new/upcoming_changes/array-api/29519.feature.rst b/doc/whats_new/upcoming_changes/array-api/29519.feature.rst deleted file mode 100644 index 19f800ee45b4b..0000000000000 --- a/doc/whats_new/upcoming_changes/array-api/29519.feature.rst +++ /dev/null @@ -1,3 +0,0 @@ -- :func:`sklearn.utils.check_consistent_length` now supports Array API compatible - inputs. - By :user:`Stefanie Senger ` diff --git a/doc/whats_new/upcoming_changes/array-api/29978.feature.rst b/doc/whats_new/upcoming_changes/array-api/29978.feature.rst deleted file mode 100644 index 16cbd174a3dfa..0000000000000 --- a/doc/whats_new/upcoming_changes/array-api/29978.feature.rst +++ /dev/null @@ -1,3 +0,0 @@ -- :func:`sklearn.metrics.explained_variance_score` and - :func:`sklearn.metrics.mean_pinball_loss` now support Array API compatible inputs. - By :user:`Virgil Chan ` diff --git a/doc/whats_new/upcoming_changes/array-api/30340.other.rst b/doc/whats_new/upcoming_changes/array-api/30340.other.rst deleted file mode 100644 index 38053567080f4..0000000000000 --- a/doc/whats_new/upcoming_changes/array-api/30340.other.rst +++ /dev/null @@ -1,4 +0,0 @@ -- array-api-compat and array-api-extra are now vendored within the - scikit-learn source. Users of the experimental array API standard - support no longer need to install array-api-compat in their environment. - by :user:`Lucas Colley ` diff --git a/doc/whats_new/upcoming_changes/array-api/30395.feature.rst b/doc/whats_new/upcoming_changes/array-api/30395.feature.rst deleted file mode 100644 index 739ea20071dfc..0000000000000 --- a/doc/whats_new/upcoming_changes/array-api/30395.feature.rst +++ /dev/null @@ -1,4 +0,0 @@ -- :func:`sklearn.metrics.fbeta_score`, - :func:`sklearn.metrics.precision_score` and - :func:`sklearn.metrics.recall_score` now support Array API compatible inputs. - By :user:`Omar Salman ` diff --git a/doc/whats_new/upcoming_changes/array-api/30819.feature.rst b/doc/whats_new/upcoming_changes/array-api/30819.feature.rst deleted file mode 100644 index 56955d73ae903..0000000000000 --- a/doc/whats_new/upcoming_changes/array-api/30819.feature.rst +++ /dev/null @@ -1,2 +0,0 @@ -- :func:`sklearn.utils.extmath.randomized_svd` now support Array API compatible inputs. - By :user:`Connor Lane ` and :user:`Jérémie du Boisberranger `. diff --git a/doc/whats_new/upcoming_changes/array-api/30838.feature.rst b/doc/whats_new/upcoming_changes/array-api/30838.feature.rst deleted file mode 100644 index f733f1c6476a6..0000000000000 --- a/doc/whats_new/upcoming_changes/array-api/30838.feature.rst +++ /dev/null @@ -1,2 +0,0 @@ -- :func:`sklearn.metrics.hamming_loss` now support Array API compatible inputs. - By :user:`Thomas Li ` diff --git a/doc/whats_new/upcoming_changes/array-api/31190.feature.rst b/doc/whats_new/upcoming_changes/array-api/31190.feature.rst deleted file mode 100644 index 15504c0e28fce..0000000000000 --- a/doc/whats_new/upcoming_changes/array-api/31190.feature.rst +++ /dev/null @@ -1,2 +0,0 @@ -- :class:`preprocessing.Binarizer` now supports Array API compatible inputs. - By :user:`Yaroslav Korobko `, :user:`Olivier Grisel `, and :user:`Thomas Li `. diff --git a/doc/whats_new/upcoming_changes/many-modules/30858.other.rst b/doc/whats_new/upcoming_changes/many-modules/30858.other.rst deleted file mode 100644 index 5e2441cf5c95e..0000000000000 --- a/doc/whats_new/upcoming_changes/many-modules/30858.other.rst +++ /dev/null @@ -1,7 +0,0 @@ - -- Sparse update: As part of the SciPy change from spmatrix to sparray, all - internal use of sparse now supports both sparray and spmatrix. - All manipulations of sparse objects should work for either spmatrix or sparray. - This is pass 1 of a migration toward sparray (see - `SciPy migration to sparray `_ - By :user:`Dan Schult ` diff --git a/doc/whats_new/upcoming_changes/metadata-routing/30833.feature.rst b/doc/whats_new/upcoming_changes/metadata-routing/30833.feature.rst deleted file mode 100644 index e46420e9ee2d2..0000000000000 --- a/doc/whats_new/upcoming_changes/metadata-routing/30833.feature.rst +++ /dev/null @@ -1,4 +0,0 @@ -- :class:`ensemble.BaggingClassifier` and :class:`ensemble.BaggingRegressor` now support - metadata routing through their `predict`, `predict_proba`, `predict_log_proba` and - `decision_function` methods and pass `**params` to the underlying estimators. - By :user:`Stefanie Senger `. diff --git a/doc/whats_new/upcoming_changes/sklearn.calibration/30873.fix.rst b/doc/whats_new/upcoming_changes/sklearn.calibration/30873.fix.rst deleted file mode 100644 index 3e438622f4918..0000000000000 --- a/doc/whats_new/upcoming_changes/sklearn.calibration/30873.fix.rst +++ /dev/null @@ -1,7 +0,0 @@ -- :class:`~calibration.CalibratedClassifierCV` now raises `FutureWarning` - instead of `UserWarning` when passing `cv="prefit`". By - :user:`Olivier Grisel ` -- :class:`~calibration.CalibratedClassifierCV` with `method="sigmoid"` no - longer crashes when passing `float64`-dtyped `sample_weight` along with a - base estimator that outputs `float32`-dtyped predictions. By :user:`Olivier - Grisel ` diff --git a/doc/whats_new/upcoming_changes/sklearn.compose/31167.api.rst b/doc/whats_new/upcoming_changes/sklearn.compose/31167.api.rst deleted file mode 100644 index 5f25cbac65020..0000000000000 --- a/doc/whats_new/upcoming_changes/sklearn.compose/31167.api.rst +++ /dev/null @@ -1,4 +0,0 @@ -- The `force_int_remainder_cols` parameter of :class:`compose.ColumnTransformer` and - :func:`compose.make_column_transformer` is deprecated and will be removed in 1.9. - It has no effect. - By :user:`Jérémie du Boisberranger ` diff --git a/doc/whats_new/upcoming_changes/sklearn.covariance/30483.fix.rst b/doc/whats_new/upcoming_changes/sklearn.covariance/30483.fix.rst deleted file mode 100644 index 4329c5a2696fd..0000000000000 --- a/doc/whats_new/upcoming_changes/sklearn.covariance/30483.fix.rst +++ /dev/null @@ -1,2 +0,0 @@ -- Support for ``n_samples == n_features`` in `sklearn.covariance.MinCovDet` has - been restored. By :user:`Antony Lee `. diff --git a/doc/whats_new/upcoming_changes/sklearn.datasets/30196.enhancement.rst b/doc/whats_new/upcoming_changes/sklearn.datasets/30196.enhancement.rst deleted file mode 100644 index d044d039badd2..0000000000000 --- a/doc/whats_new/upcoming_changes/sklearn.datasets/30196.enhancement.rst +++ /dev/null @@ -1,3 +0,0 @@ -- New parameter ``return_X_y`` added to :func:`datasets.make_classification`. The - default value of the parameter does not change how the function behaves. - By :user:`Success Moses ` and :user:`Adam Cooper ` diff --git a/doc/whats_new/upcoming_changes/sklearn.decomposition/30443.feature.rst b/doc/whats_new/upcoming_changes/sklearn.decomposition/30443.feature.rst deleted file mode 100644 index 5678039b69065..0000000000000 --- a/doc/whats_new/upcoming_changes/sklearn.decomposition/30443.feature.rst +++ /dev/null @@ -1,4 +0,0 @@ -- :class:`~sklearn.decomposition.DictionaryLearning`, - :class:`~sklearn.decomposition.SparseCoder` and - :class:`~sklearn.decomposition.MiniBatchDictionaryLearning` now have a - ``inverse_transform`` method. By :user:`Rémi Flamary ` diff --git a/doc/whats_new/upcoming_changes/sklearn.ensemble/27124.feature.rst b/doc/whats_new/upcoming_changes/sklearn.ensemble/27124.feature.rst deleted file mode 100644 index 2087efb00d779..0000000000000 --- a/doc/whats_new/upcoming_changes/sklearn.ensemble/27124.feature.rst +++ /dev/null @@ -1,6 +0,0 @@ -- :class:`ensemble.HistGradientBoostingClassifier` and - :class:`ensemble.HistGradientBoostingRegressor` allow for more control over the - validation set used for early stopping. You can now pass data to be used for - validation directly to `fit` via the arguments `X_val`, `y_val` and - `sample_weight_val`. - By :user:`Christian Lorentzen `. diff --git a/doc/whats_new/upcoming_changes/sklearn.ensemble/30649.fix.rst b/doc/whats_new/upcoming_changes/sklearn.ensemble/30649.fix.rst deleted file mode 100644 index 43ad381fb5ca8..0000000000000 --- a/doc/whats_new/upcoming_changes/sklearn.ensemble/30649.fix.rst +++ /dev/null @@ -1,2 +0,0 @@ -- :class:`ensemble.VotingClassifier` and :class:`ensemble.VotingRegressor` - validate `estimators` to make sure it is a list of tuples. By `Thomas Fan`_. diff --git a/doc/whats_new/upcoming_changes/sklearn.feature_selection/30179.enhancement.rst b/doc/whats_new/upcoming_changes/sklearn.feature_selection/30179.enhancement.rst deleted file mode 100644 index 6eec68c0d95e7..0000000000000 --- a/doc/whats_new/upcoming_changes/sklearn.feature_selection/30179.enhancement.rst +++ /dev/null @@ -1,3 +0,0 @@ -- :class:`feature_selection.RFECV` now gives access to the ranking and support in each - iteration and cv step of feature selection. - By :user:`Marie S. ` diff --git a/doc/whats_new/upcoming_changes/sklearn.feature_selection/31107.fix.rst b/doc/whats_new/upcoming_changes/sklearn.feature_selection/31107.fix.rst deleted file mode 100644 index b5ca4ab283434..0000000000000 --- a/doc/whats_new/upcoming_changes/sklearn.feature_selection/31107.fix.rst +++ /dev/null @@ -1,4 +0,0 @@ -- :class:`feature_selection.SelectFromModel` now correctly works when the estimator - is an instance of :class:`linear_model.ElasticNetCV` with its `l1_ratio` parameter - being an array-like. - By :user:`Vasco Pereira `. diff --git a/doc/whats_new/upcoming_changes/sklearn.gaussian_process/22227.enhancement.rst b/doc/whats_new/upcoming_changes/sklearn.gaussian_process/22227.enhancement.rst deleted file mode 100644 index bcc9825f30978..0000000000000 --- a/doc/whats_new/upcoming_changes/sklearn.gaussian_process/22227.enhancement.rst +++ /dev/null @@ -1 +0,0 @@ -- :class:`gaussian_process.GaussianProcessClassifier` now includes a `latent_mean_and_variance` method that exposes the mean and the variance of the latent function, :math:`f`, used in the Laplace approximation. By :user:`Miguel González Duque ` diff --git a/doc/whats_new/upcoming_changes/sklearn.inspection/26202.enhancement.rst b/doc/whats_new/upcoming_changes/sklearn.inspection/26202.enhancement.rst deleted file mode 100644 index 666d55a24c577..0000000000000 --- a/doc/whats_new/upcoming_changes/sklearn.inspection/26202.enhancement.rst +++ /dev/null @@ -1,5 +0,0 @@ -- Add `custom_values` parameter in :func:`inspection.partial_dependence`. It enables - users to pass their own grid of values at which the partial dependence should be - calculated. - By :user:`Freddy A. Boulton ` and :user:`Stephen Pardy - ` diff --git a/doc/whats_new/upcoming_changes/sklearn.inspection/29797.enhancement.rst b/doc/whats_new/upcoming_changes/sklearn.inspection/29797.enhancement.rst deleted file mode 100644 index 2b16d7e2bf6be..0000000000000 --- a/doc/whats_new/upcoming_changes/sklearn.inspection/29797.enhancement.rst +++ /dev/null @@ -1,4 +0,0 @@ -- :class:`inspection.DecisionBoundaryDisplay` now supports - plotting all classes for multi-class problems when `response_method` is - 'decision_function', 'predict_proba' or 'auto'. - By :user:`Lucy Liu ` diff --git a/doc/whats_new/upcoming_changes/sklearn.inspection/30409.api.rst b/doc/whats_new/upcoming_changes/sklearn.inspection/30409.api.rst deleted file mode 100644 index ab73ed4bd1afd..0000000000000 --- a/doc/whats_new/upcoming_changes/sklearn.inspection/30409.api.rst +++ /dev/null @@ -1,5 +0,0 @@ -- :func:`inspection.partial_dependence` does no longer accept integer dtype for - numerical feature columns. Explicit conversion to floating point values is - now required before calling this tool (and preferably even before fitting the - model to inspect). - By :user:`Olivier Grisel ` diff --git a/doc/whats_new/upcoming_changes/sklearn.inspection/31146.fix.rst b/doc/whats_new/upcoming_changes/sklearn.inspection/31146.fix.rst deleted file mode 100644 index 2cd7d6eed61f5..0000000000000 --- a/doc/whats_new/upcoming_changes/sklearn.inspection/31146.fix.rst +++ /dev/null @@ -1,4 +0,0 @@ -- :func:`inspection.partial_dependence` now raises an informative error when passing - an empty list as the `categorical_features` parameter. `None` should be used instead - to indicate that no categorical features are present. - By :user:`Pedro Lopes `. diff --git a/doc/whats_new/upcoming_changes/sklearn.linear_model/30057.fix.rst b/doc/whats_new/upcoming_changes/sklearn.linear_model/30057.fix.rst deleted file mode 100644 index 94ed332295b9b..0000000000000 --- a/doc/whats_new/upcoming_changes/sklearn.linear_model/30057.fix.rst +++ /dev/null @@ -1,5 +0,0 @@ -- :class:`linear_model.LogisticRegression` and - :class:`linear_model.LogisticRegressionCV` now properly pass sample weights to - :func:`utils.class_weight.compute_class_weight` when fit with - `class_weight="balanced"`. - By :user:`Shruti Nath ` and :user:`Olivier Grisel ` diff --git a/doc/whats_new/upcoming_changes/sklearn.linear_model/30521.fix.rst b/doc/whats_new/upcoming_changes/sklearn.linear_model/30521.fix.rst deleted file mode 100644 index 951da8f2627b4..0000000000000 --- a/doc/whats_new/upcoming_changes/sklearn.linear_model/30521.fix.rst +++ /dev/null @@ -1,4 +0,0 @@ -- Added a new parameter `tol` to - :class:`linear_model.LinearRegression` that determines the precision of the - solution `coef_` when fitting on sparse data. - By :user:`Success Moses ` diff --git a/doc/whats_new/upcoming_changes/sklearn.linear_model/30616.api.rst b/doc/whats_new/upcoming_changes/sklearn.linear_model/30616.api.rst deleted file mode 100644 index 2b9d30e445bcf..0000000000000 --- a/doc/whats_new/upcoming_changes/sklearn.linear_model/30616.api.rst +++ /dev/null @@ -1,9 +0,0 @@ -- The parameter `n_alphas` has been deprecated in the following classes: - :class:`linear_model.ElasticNetCV` and :class:`linear_model.LassoCV` - and :class:`linear_model.MultiTaskElasticNetCV` - and :class:`linear_model.MultiTaskLassoCV`, and will be removed in 1.9. The parameter - `alphas` now supports both integers and array-likes, removing the need for `n_alphas`. - From now on, only `alphas` should be set to either indicate the number of alphas to - automatically generate (int) or to provide a list of alphas (array-like) to test along - the regularization path. - By :user:`Siddharth Bansal `. diff --git a/doc/whats_new/upcoming_changes/sklearn.linear_model/30644.fix.rst b/doc/whats_new/upcoming_changes/sklearn.linear_model/30644.fix.rst deleted file mode 100644 index 9c8a85b080617..0000000000000 --- a/doc/whats_new/upcoming_changes/sklearn.linear_model/30644.fix.rst +++ /dev/null @@ -1,3 +0,0 @@ -- The update and initialization of the hyperparameters now properly handle - sample weights in :class:`linear_model.BayesianRidge`. - By :user:`Antoine Baker `. diff --git a/doc/whats_new/upcoming_changes/sklearn.linear_model/30730.enhancement.rst b/doc/whats_new/upcoming_changes/sklearn.linear_model/30730.enhancement.rst deleted file mode 100644 index 91638cbcd9c7a..0000000000000 --- a/doc/whats_new/upcoming_changes/sklearn.linear_model/30730.enhancement.rst +++ /dev/null @@ -1,3 +0,0 @@ -- :class:`linear_model.SGDClassifier` and :class:`linear_model.SGDRegressor` now accept - `l1_ratio=None` when `penalty` is not `"elasticnet"`. - By :user:`Marc Bresson `. diff --git a/doc/whats_new/upcoming_changes/sklearn.linear_model/31094.fix.rst b/doc/whats_new/upcoming_changes/sklearn.linear_model/31094.fix.rst deleted file mode 100644 index b65d96bccd7d2..0000000000000 --- a/doc/whats_new/upcoming_changes/sklearn.linear_model/31094.fix.rst +++ /dev/null @@ -1,3 +0,0 @@ -- :class:`linear_model.BayesianRidge` now uses the full SVD to correctly estimate - the posterior covariance matrix `sigma_` when `n_samples < n_features`. - By :user:`Antoine Baker ` diff --git a/doc/whats_new/upcoming_changes/sklearn.linear_model/31241.api.rst b/doc/whats_new/upcoming_changes/sklearn.linear_model/31241.api.rst deleted file mode 100644 index 9cd97143e29c7..0000000000000 --- a/doc/whats_new/upcoming_changes/sklearn.linear_model/31241.api.rst +++ /dev/null @@ -1,7 +0,0 @@ -- Using the `"liblinear"` solver for multiclass classification with a one-versus-rest - scheme in :class:`linear_model.LogisticRegression` and - :class:`linear_model.LogisticRegressionCV` is deprecated and will raise an error in - version 1.8. Either use a solver which supports the multinomial loss or wrap the - estimator in a :class:`sklearn.multiclass.OneVsRestClassifier` to keep applying a - one-versus-rest scheme. - By :user:`Jérémie du Boisberranger `. diff --git a/doc/whats_new/upcoming_changes/sklearn.manifold/30514.fix.rst b/doc/whats_new/upcoming_changes/sklearn.manifold/30514.fix.rst deleted file mode 100644 index 7f4e4104446dc..0000000000000 --- a/doc/whats_new/upcoming_changes/sklearn.manifold/30514.fix.rst +++ /dev/null @@ -1,4 +0,0 @@ -- :class:`manifold.MDS` now correctly handles non-metric MDS. Furthermore, - the returned stress value now corresponds to the returned embedding and - normalized stress is now allowed for metric MDS. - By :user:`Dmitry Kobak ` diff --git a/doc/whats_new/upcoming_changes/sklearn.manifold/31117.enhancement.rst b/doc/whats_new/upcoming_changes/sklearn.manifold/31117.enhancement.rst deleted file mode 100644 index 87b6896890163..0000000000000 --- a/doc/whats_new/upcoming_changes/sklearn.manifold/31117.enhancement.rst +++ /dev/null @@ -1,3 +0,0 @@ -- :class:`manifold.MDS` will switch to use `n_init=1` by default, - starting from version 1.9. - By :user:`Dmitry Kobak ` diff --git a/doc/whats_new/upcoming_changes/sklearn.manifold/31117.fix.rst b/doc/whats_new/upcoming_changes/sklearn.manifold/31117.fix.rst deleted file mode 100644 index 6248a23b86546..0000000000000 --- a/doc/whats_new/upcoming_changes/sklearn.manifold/31117.fix.rst +++ /dev/null @@ -1,5 +0,0 @@ -- :class:`manifold.MDS` now uses `eps=1e-6` by default and the convergence - criterion was adjusted to make sense for both metric and non-metric MDS - and to follow the reference R implementation. The formula for normalized - stress was adjusted to follow the original definition by Kruskal. - By :user:`Dmitry Kobak ` diff --git a/doc/whats_new/upcoming_changes/sklearn.metrics/22046.feature.rst b/doc/whats_new/upcoming_changes/sklearn.metrics/22046.feature.rst deleted file mode 100644 index dbe9166aa1314..0000000000000 --- a/doc/whats_new/upcoming_changes/sklearn.metrics/22046.feature.rst +++ /dev/null @@ -1,6 +0,0 @@ -- :func:`metrics.brier_score_loss` implements the Brier score for multiclass - classification problems and adds a `scale_by_half` argument. This metric is - notably useful to assess both sharpness and calibration of probabilistic - classifiers. See the docstrings for more details. By - :user:`Varun Aggarwal `, :user:`Olivier Grisel ` and - :user:`Antoine Baker `. diff --git a/doc/whats_new/upcoming_changes/sklearn.metrics/22046.fix.rst b/doc/whats_new/upcoming_changes/sklearn.metrics/22046.fix.rst deleted file mode 100644 index 7ba041f2686cf..0000000000000 --- a/doc/whats_new/upcoming_changes/sklearn.metrics/22046.fix.rst +++ /dev/null @@ -1,3 +0,0 @@ -- :func:`metrics.log_loss` now raises a `ValueError` if values of `y_true` - are missing in `labels`. By :user:`Varun Aggarwal `, - :user:`Olivier Grisel ` and :user:`Antoine Baker `. diff --git a/doc/whats_new/upcoming_changes/sklearn.metrics/28981.api.rst b/doc/whats_new/upcoming_changes/sklearn.metrics/28981.api.rst deleted file mode 100644 index 6cc771d6a0d45..0000000000000 --- a/doc/whats_new/upcoming_changes/sklearn.metrics/28981.api.rst +++ /dev/null @@ -1,3 +0,0 @@ -- The `sparse` parameter of :func:`metrics.fowlkes_mallows_score` is deprecated and - will be removed in 1.9. It has no effect. - By :user:`Luc Rocher `. diff --git a/doc/whats_new/upcoming_changes/sklearn.metrics/29151.enhancement.rst b/doc/whats_new/upcoming_changes/sklearn.metrics/29151.enhancement.rst deleted file mode 100644 index fc552703f2512..0000000000000 --- a/doc/whats_new/upcoming_changes/sklearn.metrics/29151.enhancement.rst +++ /dev/null @@ -1,6 +0,0 @@ -- :func:`metrics.det_curve`, :class:`metrics.DetCurveDisplay.from_estimator`, - and :class:`metrics.DetCurveDisplay.from_estimator` now accept a - `drop_intermediate` option to drop thresholds where true positives (tp) do not - change from the previous or subsequent thresholds. All points with the same tp - value have the same `fnr` and thus same y coordinate in a DET curve. - By :user:`Arturo Amor ` diff --git a/doc/whats_new/upcoming_changes/sklearn.metrics/29151.fix.rst b/doc/whats_new/upcoming_changes/sklearn.metrics/29151.fix.rst deleted file mode 100644 index 61cf97e9b27f6..0000000000000 --- a/doc/whats_new/upcoming_changes/sklearn.metrics/29151.fix.rst +++ /dev/null @@ -1,4 +0,0 @@ -- :func:`metrics.det_curve` and :class:`metrics.DetCurveDisplay` now return an - extra threshold at infinity where the classifier always predicts the negative - class i.e. tps = fps = 0. - By :user:`Arturo Amor ` diff --git a/doc/whats_new/upcoming_changes/sklearn.metrics/29288.api.rst b/doc/whats_new/upcoming_changes/sklearn.metrics/29288.api.rst deleted file mode 100644 index 1c8e15d714391..0000000000000 --- a/doc/whats_new/upcoming_changes/sklearn.metrics/29288.api.rst +++ /dev/null @@ -1,4 +0,0 @@ -- The `raise_warning` parameter of :func:`metrics.class_likelihood_ratios` is deprecated - and will be removed in 1.9. An `UndefinedMetricWarning` will always be raised in case - of a division by zero. - By :user:`Stefanie Senger `. diff --git a/doc/whats_new/upcoming_changes/sklearn.metrics/29288.enhancement.rst b/doc/whats_new/upcoming_changes/sklearn.metrics/29288.enhancement.rst deleted file mode 100644 index e6e682a333f86..0000000000000 --- a/doc/whats_new/upcoming_changes/sklearn.metrics/29288.enhancement.rst +++ /dev/null @@ -1,4 +0,0 @@ -- :func:`~metrics.class_likelihood_ratios` now has a `replace_undefined_by` param. - When there is a division by zero, the metric is undefined and the set values are - returned for `LR+` and `LR-`. - By :user:`Stefanie Senger ` diff --git a/doc/whats_new/upcoming_changes/sklearn.metrics/29288.fix.rst b/doc/whats_new/upcoming_changes/sklearn.metrics/29288.fix.rst deleted file mode 100644 index 23237b3923668..0000000000000 --- a/doc/whats_new/upcoming_changes/sklearn.metrics/29288.fix.rst +++ /dev/null @@ -1,3 +0,0 @@ -- :func:`~metrics.class_likelihood_ratios` now raises `UndefinedMetricWarning` instead - of `UserWarning` when a division by zero occurs. - By :user:`Stefanie Senger ` diff --git a/doc/whats_new/upcoming_changes/sklearn.metrics/29727.fix.rst b/doc/whats_new/upcoming_changes/sklearn.metrics/29727.fix.rst deleted file mode 100644 index b25de83128504..0000000000000 --- a/doc/whats_new/upcoming_changes/sklearn.metrics/29727.fix.rst +++ /dev/null @@ -1,3 +0,0 @@ -- :class:`metrics.RocCurveDisplay` will no longer set a legend when - `label` is `None` in both the `line_kwargs` and the `chance_level_kw`. - By :user:`Arturo Amor ` diff --git a/doc/whats_new/upcoming_changes/sklearn.metrics/29865.api.rst b/doc/whats_new/upcoming_changes/sklearn.metrics/29865.api.rst deleted file mode 100644 index 60ea7d83de71f..0000000000000 --- a/doc/whats_new/upcoming_changes/sklearn.metrics/29865.api.rst +++ /dev/null @@ -1,4 +0,0 @@ -- In :meth:`sklearn.metrics.RocCurveDisplay.from_predictions`, - the argument `y_pred` has been renamed to `y_score` to better reflect its purpose. - `y_pred` will be removed in 1.9. - By :user:`Bagus Tris Atmaja ` in diff --git a/doc/whats_new/upcoming_changes/sklearn.metrics/30903.fix.rst b/doc/whats_new/upcoming_changes/sklearn.metrics/30903.fix.rst deleted file mode 100644 index 90250f427dc20..0000000000000 --- a/doc/whats_new/upcoming_changes/sklearn.metrics/30903.fix.rst +++ /dev/null @@ -1,3 +0,0 @@ -- :func:`~metrics.d2_log_loss_score` now properly handles the case when `labels` is - passed and not all of the labels are present in `y_true`. - By :user:`Vassilis Margonis ` diff --git a/doc/whats_new/upcoming_changes/sklearn.metrics/31065.fix.rst b/doc/whats_new/upcoming_changes/sklearn.metrics/31065.fix.rst deleted file mode 100644 index 82126da7852cc..0000000000000 --- a/doc/whats_new/upcoming_changes/sklearn.metrics/31065.fix.rst +++ /dev/null @@ -1,3 +0,0 @@ -- Fix :func:`metrics.adjusted_mutual_info_score` numerical issue when number of - classes and samples is low. - By :user:`Hleb Levitski ` diff --git a/doc/whats_new/upcoming_changes/sklearn.mixture/28559.feature.rst b/doc/whats_new/upcoming_changes/sklearn.mixture/28559.feature.rst deleted file mode 100644 index 31da86d63c0f7..0000000000000 --- a/doc/whats_new/upcoming_changes/sklearn.mixture/28559.feature.rst +++ /dev/null @@ -1,5 +0,0 @@ -- Added an attribute `lower_bounds_` in the :class:`mixture.BaseMixture` - class to save the list of lower bounds for each iteration thereby providing - insights into the convergence behavior of mixture models like - :class:`mixture.GaussianMixture`. - By :user:`Manideep Yenugula ` diff --git a/doc/whats_new/upcoming_changes/sklearn.mixture/30414.efficiency.rst b/doc/whats_new/upcoming_changes/sklearn.mixture/30414.efficiency.rst deleted file mode 100644 index 401ebb65916bb..0000000000000 --- a/doc/whats_new/upcoming_changes/sklearn.mixture/30414.efficiency.rst +++ /dev/null @@ -1,4 +0,0 @@ -- Simplified redundant computation when estimating covariances in - :class:`~mixture.GaussianMixture` with a `covariance_type="spherical"` or - `covariance_type="diag"`. - By :user:`Leonce Mekinda ` and :user:`Olivier Grisel ` diff --git a/doc/whats_new/upcoming_changes/sklearn.mixture/30415.efficiency.rst b/doc/whats_new/upcoming_changes/sklearn.mixture/30415.efficiency.rst deleted file mode 100644 index 095ef66ce28c0..0000000000000 --- a/doc/whats_new/upcoming_changes/sklearn.mixture/30415.efficiency.rst +++ /dev/null @@ -1,5 +0,0 @@ -- :class:`~mixture.GaussianMixture` now consistently operates at `float32` - precision when fitted with `float32` data to improve training speed and - memory efficiency. Previously, part of the computation would be implicitly - cast to `float64`. By :user:`Olivier Grisel ` and :user:`Omar Salman - `. diff --git a/doc/whats_new/upcoming_changes/sklearn.model_selection/30743.fix.rst b/doc/whats_new/upcoming_changes/sklearn.model_selection/30743.fix.rst deleted file mode 100644 index 8e091f55b2e31..0000000000000 --- a/doc/whats_new/upcoming_changes/sklearn.model_selection/30743.fix.rst +++ /dev/null @@ -1,3 +0,0 @@ -- Hyper-parameter optimizers such as :class:`model_selection.GridSearchCV` - now forward `sample_weight` to the scorer even when metadata routing is not enabled. - By :user:`Antoine Baker ` diff --git a/doc/whats_new/upcoming_changes/sklearn.multiclass/31228.fix.rst b/doc/whats_new/upcoming_changes/sklearn.multiclass/31228.fix.rst deleted file mode 100644 index 68056db580fd7..0000000000000 --- a/doc/whats_new/upcoming_changes/sklearn.multiclass/31228.fix.rst +++ /dev/null @@ -1,5 +0,0 @@ -- The `predict_proba` method of :class:`sklearn.multiclass.OneVsRestClassifier` now - returns zero for all classes when all inner estimators never predict their positive - class. - By :user:`Luis M. B. Varona `, :user:`Marc Bresson `, and - :user:`Jérémie du Boisberranger `. diff --git a/doc/whats_new/upcoming_changes/sklearn.multioutput/30152.enhancement.rst b/doc/whats_new/upcoming_changes/sklearn.multioutput/30152.enhancement.rst deleted file mode 100644 index 3bc2ae2f6ced4..0000000000000 --- a/doc/whats_new/upcoming_changes/sklearn.multioutput/30152.enhancement.rst +++ /dev/null @@ -1,3 +0,0 @@ -- The parameter `base_estimator` has been deprecated in favour of `estimator` for - :class:`multioutput.RegressorChain` and :class:`multioutput.ClassifierChain`. - By :user:`Success Moses ` and :user:`dikraMasrour ` diff --git a/doc/whats_new/upcoming_changes/sklearn.neural_network/24788.fix.rst b/doc/whats_new/upcoming_changes/sklearn.neural_network/24788.fix.rst deleted file mode 100644 index dc2742e9a04d8..0000000000000 --- a/doc/whats_new/upcoming_changes/sklearn.neural_network/24788.fix.rst +++ /dev/null @@ -1,3 +0,0 @@ -- :class:`neural_network.MLPRegressor` now raises an informative error when - `early_stopping` is set and the computed validation set is too small. - By :user:`David Shumway `. diff --git a/doc/whats_new/upcoming_changes/sklearn.neural_network/30155.feature.rst b/doc/whats_new/upcoming_changes/sklearn.neural_network/30155.feature.rst deleted file mode 100644 index 4fcf738072e5e..0000000000000 --- a/doc/whats_new/upcoming_changes/sklearn.neural_network/30155.feature.rst +++ /dev/null @@ -1,3 +0,0 @@ -- Added support for `sample_weight` in :class:`neural_network.MLPClassifier` and - :class:`neural_network.MLPRegressor`. - By :user:`Zach Shu ` and :user:`Christian Lorentzen ` diff --git a/doc/whats_new/upcoming_changes/sklearn.neural_network/30712.feature.rst b/doc/whats_new/upcoming_changes/sklearn.neural_network/30712.feature.rst deleted file mode 100644 index e8ad9882ff0f0..0000000000000 --- a/doc/whats_new/upcoming_changes/sklearn.neural_network/30712.feature.rst +++ /dev/null @@ -1,3 +0,0 @@ -- Added parameter for `loss` in :class:`neural_network.MLPRegressor` with options - `"squared_error"` (default) and `"poisson"` (new). - By :user:`Christian Lorentzen ` diff --git a/doc/whats_new/upcoming_changes/sklearn.pipeline/30406.enhancement.rst b/doc/whats_new/upcoming_changes/sklearn.pipeline/30406.enhancement.rst deleted file mode 100644 index 8e2a5f6242392..0000000000000 --- a/doc/whats_new/upcoming_changes/sklearn.pipeline/30406.enhancement.rst +++ /dev/null @@ -1,4 +0,0 @@ -- Expose the ``verbose_feature_names_out`` argument in the - :func:`pipeline.make_union` function, allowing users to control - feature name uniqueness in the :class:`pipeline.FeatureUnion`. - By :user:`Abhijeetsingh Meena ` diff --git a/doc/whats_new/upcoming_changes/sklearn.preprocessing/29907.enhancement.rst b/doc/whats_new/upcoming_changes/sklearn.preprocessing/29907.enhancement.rst deleted file mode 100644 index 0ce9249cc94fb..0000000000000 --- a/doc/whats_new/upcoming_changes/sklearn.preprocessing/29907.enhancement.rst +++ /dev/null @@ -1,6 +0,0 @@ -- :class:`preprocessing.KBinsDiscretizer` with `strategy="uniform"` now - accepts `sample_weight`. Additionally with `strategy="quantile"` the - `quantile_method` can now be specified (in the future - `quantile_method="averaged_inverted_cdf"` will become the default). - By :user:`Shruti Nath ` and :user:`Olivier Grisel - ` diff --git a/doc/whats_new/upcoming_changes/sklearn.preprocessing/29907.fix.rst b/doc/whats_new/upcoming_changes/sklearn.preprocessing/29907.fix.rst deleted file mode 100644 index d2f61e099c5eb..0000000000000 --- a/doc/whats_new/upcoming_changes/sklearn.preprocessing/29907.fix.rst +++ /dev/null @@ -1,6 +0,0 @@ -- :class:`preprocessing.KBinsDiscretizer` now uses weighted resampling when - sample weights are given and subsampling is used. This may change results - even when not using sample weights, although in absolute and not in terms - of statistical properties. - By :user:`Shruti Nath ` and :user:`Jérémie du Boisberranger - ` diff --git a/doc/whats_new/upcoming_changes/sklearn.preprocessing/31227.fix.rst b/doc/whats_new/upcoming_changes/sklearn.preprocessing/31227.fix.rst deleted file mode 100644 index 803517760a822..0000000000000 --- a/doc/whats_new/upcoming_changes/sklearn.preprocessing/31227.fix.rst +++ /dev/null @@ -1,6 +0,0 @@ -- Now using ``scipy.stats.yeojohnson`` instead of our own implementation of the Yeo-Johnson transform. - Fixed numerical stability (mostly overflows) of the Yeo-Johnson transform with - `PowerTransformer(method="yeo-johnson")` when scipy version is `>= 1.12`. - Initial PR by :user:`Xuefeng Xu ` completed by :user:`Mohamed Yaich `, - :user:`Oussama Er-rabie `, :user:`Mohammed Yaslam Dlimi `, - :user:`Hamza Zaroual `, :user:`Amine Hannoun ` and :user:`Sylvain Marié `. \ No newline at end of file diff --git a/doc/whats_new/upcoming_changes/sklearn.svm/30057.fix.rst b/doc/whats_new/upcoming_changes/sklearn.svm/30057.fix.rst deleted file mode 100644 index 5951e0dd2a0c0..0000000000000 --- a/doc/whats_new/upcoming_changes/sklearn.svm/30057.fix.rst +++ /dev/null @@ -1,4 +0,0 @@ -- :class:`svm.LinearSVC` now properly passes sample weights to - :func:`utils.class_weight.compute_class_weight` when fit with - `class_weight="balanced"`. - By :user:`Shruti Nath ` diff --git a/doc/whats_new/upcoming_changes/sklearn.utils/26335.enhancement.rst b/doc/whats_new/upcoming_changes/sklearn.utils/26335.enhancement.rst deleted file mode 100644 index 9a82ab4f02675..0000000000000 --- a/doc/whats_new/upcoming_changes/sklearn.utils/26335.enhancement.rst +++ /dev/null @@ -1,4 +0,0 @@ -- :func:`utils.multiclass.type_of_target` raises a warning when the number - of unique classes is greater than 50% of the number of samples. This warning is raised - only if `y` has more than 20 samples. - By :user:`Rahil Parikh `. diff --git a/doc/whats_new/upcoming_changes/sklearn.utils/29907.enhancement.rst b/doc/whats_new/upcoming_changes/sklearn.utils/29907.enhancement.rst deleted file mode 100644 index 0a17e5d1d1ae1..0000000000000 --- a/doc/whats_new/upcoming_changes/sklearn.utils/29907.enhancement.rst +++ /dev/null @@ -1,4 +0,0 @@ -- :func: `resample` now handles sample weights which allows - weighted resampling. - By :user:`Shruti Nath ` and :user:`Olivier Grisel - ` diff --git a/doc/whats_new/upcoming_changes/sklearn.utils/30057.enhancement.rst b/doc/whats_new/upcoming_changes/sklearn.utils/30057.enhancement.rst deleted file mode 100644 index 8ca10c884c9b3..0000000000000 --- a/doc/whats_new/upcoming_changes/sklearn.utils/30057.enhancement.rst +++ /dev/null @@ -1,3 +0,0 @@ -- :func:`utils.class_weight.compute_class_weight` now properly accounts for - sample weights when using strategy "balanced" to calculate class weights. - By :user:`Shruti Nath ` diff --git a/doc/whats_new/upcoming_changes/sklearn.utils/30380.enhancement.rst b/doc/whats_new/upcoming_changes/sklearn.utils/30380.enhancement.rst deleted file mode 100644 index bd1eaf9213257..0000000000000 --- a/doc/whats_new/upcoming_changes/sklearn.utils/30380.enhancement.rst +++ /dev/null @@ -1,2 +0,0 @@ -- Warning filters from the main process are propagated to joblib workers. - By `Thomas Fan`_ diff --git a/doc/whats_new/upcoming_changes/sklearn.utils/30775.fix.rst b/doc/whats_new/upcoming_changes/sklearn.utils/30775.fix.rst deleted file mode 100644 index bd383a70c2bba..0000000000000 --- a/doc/whats_new/upcoming_changes/sklearn.utils/30775.fix.rst +++ /dev/null @@ -1,5 +0,0 @@ -- In :mod:`utils.estimator_checks` we now enforce for binary classifiers a - binary `y` by taking the minimum as the negative class instead of the first - element, which makes it robust to `y` shuffling. It prevents two checks from - wrongly failing on binary classifiers. - By :user:`Antoine Baker `. diff --git a/doc/whats_new/upcoming_changes/sklearn.utils/30819.fix.rst b/doc/whats_new/upcoming_changes/sklearn.utils/30819.fix.rst deleted file mode 100644 index 81c7564023ac1..0000000000000 --- a/doc/whats_new/upcoming_changes/sklearn.utils/30819.fix.rst +++ /dev/null @@ -1,4 +0,0 @@ -- :func:`utils.extmath.randomized_svd` and :func:`utils.extmath.randomized_range_finder` - now validate their input array to fail early with an informative error message on - invalid input. - By :user:`Connor Lane `. diff --git a/doc/whats_new/upcoming_changes/sklearn.utils/31040.enhancement.rst b/doc/whats_new/upcoming_changes/sklearn.utils/31040.enhancement.rst deleted file mode 100644 index 096a98cb176bc..0000000000000 --- a/doc/whats_new/upcoming_changes/sklearn.utils/31040.enhancement.rst +++ /dev/null @@ -1,4 +0,0 @@ -- The private helper function :func:`utils._safe_indexing` now officially supports - pyarrow data. For instance, passing a pyarrow `Table` as `X` in a - :class:`compose.ColumnTransformer` is now possible. - By :user:`Christian Lorentzen ` diff --git a/doc/whats_new/v0.20.rst b/doc/whats_new/v0.20.rst index 1bd4a6cd2af9a..a7d43d2d45d85 100644 --- a/doc/whats_new/v0.20.rst +++ b/doc/whats_new/v0.20.rst @@ -445,7 +445,7 @@ Miscellaneous - |API| Removed all mentions of ``sklearn.externals.joblib``, and deprecated joblib methods exposed in ``sklearn.utils``, except for - :func:`utils.parallel_backend` and :func:`utils.register_parallel_backend`, + `utils.parallel_backend` and `utils.register_parallel_backend`, which allow users to configure parallel computation in scikit-learn. Other functionalities are part of `joblib `_. package and should be used directly, by installing it. diff --git a/doc/whats_new/v1.5.rst b/doc/whats_new/v1.5.rst index 1ce5aa4839426..411a1b6b5dd95 100644 --- a/doc/whats_new/v1.5.rst +++ b/doc/whats_new/v1.5.rst @@ -656,7 +656,7 @@ Changelog - |API| :func:`utils.tosequence` is deprecated and will be removed in version 1.7. :pr:`28763` by :user:`Jérémie du Boisberranger `. -- |API| :class:`utils.parallel_backend` and :func:`utils.register_parallel_backend` are +- |API| `utils.parallel_backend` and `utils.register_parallel_backend` are deprecated and will be removed in version 1.7. Use `joblib.parallel_backend` and `joblib.register_parallel_backend` instead. :pr:`28847` by :user:`Jérémie du Boisberranger `. diff --git a/doc/whats_new/v1.7.rst b/doc/whats_new/v1.7.rst index 9043f8ac6d0d4..ab022414982ff 100644 --- a/doc/whats_new/v1.7.rst +++ b/doc/whats_new/v1.7.rst @@ -8,27 +8,507 @@ Version 1.7 =========== -.. - -- UNCOMMENT WHEN 1.7.0 IS RELEASED -- - For a short description of the main highlights of the release, please refer to - :ref:`sphx_glr_auto_examples_release_highlights_plot_release_highlights_1_6_0.py`. - - -.. - DELETE WHEN 1.7.0 IS RELEASED - Since October 2024, DO NOT add your changelog entry in this file. -.. - Instead, create a file named `..rst` in the relevant sub-folder in - `doc/whats_new/upcoming_changes/`. For full details, see: - https://github.com/scikit-learn/scikit-learn/blob/main/doc/whats_new/upcoming_changes/README.md +For a short description of the main highlights of the release, please refer to +:ref:`sphx_glr_auto_examples_release_highlights_plot_release_highlights_1_7_0.py`. .. include:: changelog_legend.inc .. towncrier release notes start +.. _changes_1_7_0: + +Version 1.7.0 +============= + +**June 2025** + +Changed models +-------------- + +- |Fix| Change the `ConvergenceWarning` message of estimators that rely on the + `"lbfgs"` optimizer internally to be more informative and to avoid + suggesting to increase the maximum number of iterations when it is not + user-settable or when the convergence problem happens before reaching it. + By :user:`Olivier Grisel `. :pr:`31316` + +Changes impacting many modules +------------------------------ + +- Sparse update: As part of the SciPy change from spmatrix to sparray, all + internal use of sparse now supports both sparray and spmatrix. + All manipulations of sparse objects should work for either spmatrix or sparray. + This is pass 1 of a migration toward sparray (see + `SciPy migration to sparray `_ + By :user:`Dan Schult ` :pr:`30858` + +Support for Array API +--------------------- + +Additional estimators and functions have been updated to include support for all +`Array API `_ compliant inputs. + +See :ref:`array_api` for more details. + +- |Feature| :func:`sklearn.utils.check_consistent_length` now supports Array API compatible + inputs. + By :user:`Stefanie Senger ` :pr:`29519` + +- |Feature| :func:`sklearn.metrics.explained_variance_score` and + :func:`sklearn.metrics.mean_pinball_loss` now support Array API compatible inputs. + By :user:`Virgil Chan ` :pr:`29978` + +- |Feature| :func:`sklearn.metrics.fbeta_score`, + :func:`sklearn.metrics.precision_score` and + :func:`sklearn.metrics.recall_score` now support Array API compatible inputs. + By :user:`Omar Salman ` :pr:`30395` + +- |Feature| :func:`sklearn.utils.extmath.randomized_svd` now support Array API compatible inputs. + By :user:`Connor Lane ` and :user:`Jérémie du Boisberranger `. :pr:`30819` + +- |Feature| :func:`sklearn.metrics.hamming_loss` now support Array API compatible inputs. + By :user:`Thomas Li ` :pr:`30838` + +- |Feature| :class:`preprocessing.Binarizer` now supports Array API compatible inputs. + By :user:`Yaroslav Korobko `, :user:`Olivier Grisel `, and :user:`Thomas Li `. :pr:`31190` + +- |Feature| :func:`sklearn.metrics.jaccard_score` now supports Array API compatible inputs. + By :user:`Omar Salman ` :pr:`31204` + +- array-api-compat and array-api-extra are now vendored within the + scikit-learn source. Users of the experimental array API standard + support no longer need to install array-api-compat in their environment. + by :user:`Lucas Colley ` :pr:`30340` + +Metadata routing +---------------- + +Refer to the :ref:`Metadata Routing User Guide ` for +more details. + +- |Feature| :class:`ensemble.BaggingClassifier` and :class:`ensemble.BaggingRegressor` now support + metadata routing through their `predict`, `predict_proba`, `predict_log_proba` and + `decision_function` methods and pass `**params` to the underlying estimators. + By :user:`Stefanie Senger `. :pr:`30833` + +:mod:`sklearn.base` +------------------- + +- |Enhancement| :class:`base.BaseEstimator` now has a parameter table added to the + estimators HTML representation that can be visualized with jupyter. + By :user:`Guillaume Lemaitre ` and + :user:`Dea María Léon ` :pr:`30763` + +:mod:`sklearn.calibration` +-------------------------- + +- |Fix| :class:`~calibration.CalibratedClassifierCV` now raises `FutureWarning` + instead of `UserWarning` when passing `cv="prefit`". By + :user:`Olivier Grisel ` +- :class:`~calibration.CalibratedClassifierCV` with `method="sigmoid"` no + longer crashes when passing `float64`-dtyped `sample_weight` along with a + base estimator that outputs `float32`-dtyped predictions. By :user:`Olivier + Grisel ` :pr:`30873` + +:mod:`sklearn.compose` +---------------------- + +- |API| The `force_int_remainder_cols` parameter of :class:`compose.ColumnTransformer` and + :func:`compose.make_column_transformer` is deprecated and will be removed in 1.9. + It has no effect. + By :user:`Jérémie du Boisberranger ` :pr:`31167` + +:mod:`sklearn.covariance` +------------------------- + +- |Fix| Support for ``n_samples == n_features`` in `sklearn.covariance.MinCovDet` has + been restored. By :user:`Antony Lee `. :pr:`30483` + +:mod:`sklearn.datasets` +----------------------- + +- |Enhancement| New parameter ``return_X_y`` added to :func:`datasets.make_classification`. The + default value of the parameter does not change how the function behaves. + By :user:`Success Moses ` and :user:`Adam Cooper ` :pr:`30196` + +:mod:`sklearn.decomposition` +---------------------------- + +- |Feature| :class:`~sklearn.decomposition.DictionaryLearning`, + :class:`~sklearn.decomposition.SparseCoder` and + :class:`~sklearn.decomposition.MiniBatchDictionaryLearning` now have a + ``inverse_transform`` method. By :user:`Rémi Flamary ` :pr:`30443` + +:mod:`sklearn.ensemble` +----------------------- + +- |Feature| :class:`ensemble.HistGradientBoostingClassifier` and + :class:`ensemble.HistGradientBoostingRegressor` allow for more control over the + validation set used for early stopping. You can now pass data to be used for + validation directly to `fit` via the arguments `X_val`, `y_val` and + `sample_weight_val`. + By :user:`Christian Lorentzen `. :pr:`27124` + +- |Fix| :class:`ensemble.VotingClassifier` and :class:`ensemble.VotingRegressor` + validate `estimators` to make sure it is a list of tuples. By `Thomas Fan`_. :pr:`30649` + +:mod:`sklearn.feature_selection` +-------------------------------- + +- |Enhancement| :class:`feature_selection.RFECV` now gives access to the ranking and support in each + iteration and cv step of feature selection. + By :user:`Marie S. ` :pr:`30179` + +- |Fix| :class:`feature_selection.SelectFromModel` now correctly works when the estimator + is an instance of :class:`linear_model.ElasticNetCV` with its `l1_ratio` parameter + being an array-like. + By :user:`Vasco Pereira `. :pr:`31107` + +:mod:`sklearn.gaussian_process` +------------------------------- + +- |Enhancement| :class:`gaussian_process.GaussianProcessClassifier` now includes a `latent_mean_and_variance` method that exposes the mean and the variance of the latent function, :math:`f`, used in the Laplace approximation. By :user:`Miguel González Duque ` :pr:`22227` + +:mod:`sklearn.inspection` +------------------------- + +- |Enhancement| Add `custom_values` parameter in :func:`inspection.partial_dependence`. It enables + users to pass their own grid of values at which the partial dependence should be + calculated. + By :user:`Freddy A. Boulton ` and :user:`Stephen Pardy + ` :pr:`26202` + +- |Enhancement| :class:`inspection.DecisionBoundaryDisplay` now supports + plotting all classes for multi-class problems when `response_method` is + 'decision_function', 'predict_proba' or 'auto'. + By :user:`Lucy Liu ` :pr:`29797` + +- |Fix| :func:`inspection.partial_dependence` now raises an informative error when passing + an empty list as the `categorical_features` parameter. `None` should be used instead + to indicate that no categorical features are present. + By :user:`Pedro Lopes `. :pr:`31146` + +- |API| :func:`inspection.partial_dependence` does no longer accept integer dtype for + numerical feature columns. Explicit conversion to floating point values is + now required before calling this tool (and preferably even before fitting the + model to inspect). + By :user:`Olivier Grisel ` :pr:`30409` + +:mod:`sklearn.linear_model` +--------------------------- + +- |Enhancement| :class:`linear_model.SGDClassifier` and :class:`linear_model.SGDRegressor` now accept + `l1_ratio=None` when `penalty` is not `"elasticnet"`. + By :user:`Marc Bresson `. :pr:`30730` + +- |Enhancement| Fitting :class:`linear_model.Lasso` and :class:`linear_model.ElasticNet` with + `fit_intercept=True` is faster for sparse input `X` because an unnecessary + re-computation of the sum of residuals is avoided. + By :user:`Christian Lorentzen ` :pr:`31387` + +- |Fix| :class:`linear_model.LogisticRegression` and + :class:`linear_model.LogisticRegressionCV` now properly pass sample weights to + :func:`utils.class_weight.compute_class_weight` when fit with + `class_weight="balanced"`. + By :user:`Shruti Nath ` and :user:`Olivier Grisel ` :pr:`30057` + +- |Fix| Added a new parameter `tol` to + :class:`linear_model.LinearRegression` that determines the precision of the + solution `coef_` when fitting on sparse data. + By :user:`Success Moses ` :pr:`30521` + +- |Fix| The update and initialization of the hyperparameters now properly handle + sample weights in :class:`linear_model.BayesianRidge`. + By :user:`Antoine Baker `. :pr:`30644` + +- |Fix| :class:`linear_model.BayesianRidge` now uses the full SVD to correctly estimate + the posterior covariance matrix `sigma_` when `n_samples < n_features`. + By :user:`Antoine Baker ` :pr:`31094` + +- |API| The parameter `n_alphas` has been deprecated in the following classes: + :class:`linear_model.ElasticNetCV` and :class:`linear_model.LassoCV` + and :class:`linear_model.MultiTaskElasticNetCV` + and :class:`linear_model.MultiTaskLassoCV`, and will be removed in 1.9. The parameter + `alphas` now supports both integers and array-likes, removing the need for `n_alphas`. + From now on, only `alphas` should be set to either indicate the number of alphas to + automatically generate (int) or to provide a list of alphas (array-like) to test along + the regularization path. + By :user:`Siddharth Bansal `. :pr:`30616` + +- |API| Using the `"liblinear"` solver for multiclass classification with a one-versus-rest + scheme in :class:`linear_model.LogisticRegression` and + :class:`linear_model.LogisticRegressionCV` is deprecated and will raise an error in + version 1.8. Either use a solver which supports the multinomial loss or wrap the + estimator in a :class:`sklearn.multiclass.OneVsRestClassifier` to keep applying a + one-versus-rest scheme. + By :user:`Jérémie du Boisberranger `. :pr:`31241` + +:mod:`sklearn.manifold` +----------------------- + +- |Enhancement| :class:`manifold.MDS` will switch to use `n_init=1` by default, + starting from version 1.9. + By :user:`Dmitry Kobak ` :pr:`31117` + +- |Fix| :class:`manifold.MDS` now correctly handles non-metric MDS. Furthermore, + the returned stress value now corresponds to the returned embedding and + normalized stress is now allowed for metric MDS. + By :user:`Dmitry Kobak ` :pr:`30514` + +- |Fix| :class:`manifold.MDS` now uses `eps=1e-6` by default and the convergence + criterion was adjusted to make sense for both metric and non-metric MDS + and to follow the reference R implementation. The formula for normalized + stress was adjusted to follow the original definition by Kruskal. + By :user:`Dmitry Kobak ` :pr:`31117` + +:mod:`sklearn.metrics` +---------------------- + +- |Feature| :func:`metrics.brier_score_loss` implements the Brier score for multiclass + classification problems and adds a `scale_by_half` argument. This metric is + notably useful to assess both sharpness and calibration of probabilistic + classifiers. See the docstrings for more details. By + :user:`Varun Aggarwal `, :user:`Olivier Grisel ` and + :user:`Antoine Baker `. :pr:`22046` + +- |Feature| Add class method `from_cv_results` to :class:`metrics.RocCurveDisplay`, which allows + easy plotting of multiple ROC curves from :func:`model_selection.cross_validate` + results. + By :user:`Lucy Liu ` :pr:`30399` + +- |Enhancement| :func:`metrics.det_curve`, :class:`metrics.DetCurveDisplay.from_estimator`, + and :class:`metrics.DetCurveDisplay.from_estimator` now accept a + `drop_intermediate` option to drop thresholds where true positives (tp) do not + change from the previous or subsequent thresholds. All points with the same tp + value have the same `fnr` and thus same y coordinate in a DET curve. + By :user:`Arturo Amor ` :pr:`29151` + +- |Enhancement| :func:`~metrics.class_likelihood_ratios` now has a `replace_undefined_by` param. + When there is a division by zero, the metric is undefined and the set values are + returned for `LR+` and `LR-`. + By :user:`Stefanie Senger ` :pr:`29288` + +- |Fix| :func:`metrics.log_loss` now raises a `ValueError` if values of `y_true` + are missing in `labels`. By :user:`Varun Aggarwal `, + :user:`Olivier Grisel ` and :user:`Antoine Baker `. :pr:`22046` + +- |Fix| :func:`metrics.det_curve` and :class:`metrics.DetCurveDisplay` now return an + extra threshold at infinity where the classifier always predicts the negative + class i.e. tps = fps = 0. + By :user:`Arturo Amor ` :pr:`29151` + +- |Fix| :func:`~metrics.class_likelihood_ratios` now raises `UndefinedMetricWarning` instead + of `UserWarning` when a division by zero occurs. + By :user:`Stefanie Senger ` :pr:`29288` + +- |Fix| :class:`metrics.RocCurveDisplay` will no longer set a legend when + `label` is `None` in both the `line_kwargs` and the `chance_level_kw`. + By :user:`Arturo Amor ` :pr:`29727` + +- |Fix| Additional `sample_weight` checking has been added to + :func:`metrics.mean_absolute_error`, + :func:`metrics.mean_pinball_loss`, + :func:`metrics.mean_absolute_percentage_error`, + :func:`metrics.mean_squared_error`, + :func:`metrics.root_mean_squared_error`, + :func:`metrics.mean_squared_log_error`, + :func:`metrics.root_mean_squared_log_error`, + :func:`metrics.explained_variance_score`, + :func:`metrics.r2_score`, + :func:`metrics.mean_tweedie_deviance`, + :func:`metrics.mean_poisson_deviance`, + :func:`metrics.mean_gamma_deviance` and + :func:`metrics.d2_tweedie_score`. + `sample_weight` can only be 1D, consistent to `y_true` and `y_pred` in length + or a scalar. + By :user:`Lucy Liu `. :pr:`30886` + +- |Fix| :func:`~metrics.d2_log_loss_score` now properly handles the case when `labels` is + passed and not all of the labels are present in `y_true`. + By :user:`Vassilis Margonis ` :pr:`30903` + +- |Fix| Fix :func:`metrics.adjusted_mutual_info_score` numerical issue when number of + classes and samples is low. + By :user:`Hleb Levitski ` :pr:`31065` + +- |API| The `sparse` parameter of :func:`metrics.fowlkes_mallows_score` is deprecated and + will be removed in 1.9. It has no effect. + By :user:`Luc Rocher `. :pr:`28981` + +- |API| The `raise_warning` parameter of :func:`metrics.class_likelihood_ratios` is deprecated + and will be removed in 1.9. An `UndefinedMetricWarning` will always be raised in case + of a division by zero. + By :user:`Stefanie Senger `. :pr:`29288` + +- |API| In :meth:`sklearn.metrics.RocCurveDisplay.from_predictions`, + the argument `y_pred` has been renamed to `y_score` to better reflect its purpose. + `y_pred` will be removed in 1.9. + By :user:`Bagus Tris Atmaja ` in :pr:`29865` + +:mod:`sklearn.mixture` +---------------------- + +- |Feature| Added an attribute `lower_bounds_` in the :class:`mixture.BaseMixture` + class to save the list of lower bounds for each iteration thereby providing + insights into the convergence behavior of mixture models like + :class:`mixture.GaussianMixture`. + By :user:`Manideep Yenugula ` :pr:`28559` + +- |Efficiency| Simplified redundant computation when estimating covariances in + :class:`~mixture.GaussianMixture` with a `covariance_type="spherical"` or + `covariance_type="diag"`. + By :user:`Leonce Mekinda ` and :user:`Olivier Grisel ` :pr:`30414` + +- |Efficiency| :class:`~mixture.GaussianMixture` now consistently operates at `float32` + precision when fitted with `float32` data to improve training speed and + memory efficiency. Previously, part of the computation would be implicitly + cast to `float64`. By :user:`Olivier Grisel ` and :user:`Omar Salman + `. :pr:`30415` + +:mod:`sklearn.model_selection` +------------------------------ + +- |Fix| Hyper-parameter optimizers such as :class:`model_selection.GridSearchCV` + now forward `sample_weight` to the scorer even when metadata routing is not enabled. + By :user:`Antoine Baker ` :pr:`30743` + +:mod:`sklearn.multiclass` +------------------------- + +- |Fix| The `predict_proba` method of :class:`sklearn.multiclass.OneVsRestClassifier` now + returns zero for all classes when all inner estimators never predict their positive + class. + By :user:`Luis M. B. Varona `, :user:`Marc Bresson `, and + :user:`Jérémie du Boisberranger `. :pr:`31228` + +:mod:`sklearn.multioutput` +-------------------------- + +- |Enhancement| The parameter `base_estimator` has been deprecated in favour of `estimator` for + :class:`multioutput.RegressorChain` and :class:`multioutput.ClassifierChain`. + By :user:`Success Moses ` and :user:`dikraMasrour ` :pr:`30152` + +:mod:`sklearn.neural_network` +----------------------------- + +- |Feature| Added support for `sample_weight` in :class:`neural_network.MLPClassifier` and + :class:`neural_network.MLPRegressor`. + By :user:`Zach Shu ` and :user:`Christian Lorentzen ` :pr:`30155` + +- |Feature| Added parameter for `loss` in :class:`neural_network.MLPRegressor` with options + `"squared_error"` (default) and `"poisson"` (new). + By :user:`Christian Lorentzen ` :pr:`30712` + +- |Fix| :class:`neural_network.MLPRegressor` now raises an informative error when + `early_stopping` is set and the computed validation set is too small. + By :user:`David Shumway `. :pr:`24788` + +:mod:`sklearn.pipeline` +----------------------- + +- |Enhancement| Expose the ``verbose_feature_names_out`` argument in the + :func:`pipeline.make_union` function, allowing users to control + feature name uniqueness in the :class:`pipeline.FeatureUnion`. + By :user:`Abhijeetsingh Meena ` :pr:`30406` + +:mod:`sklearn.preprocessing` +---------------------------- + +- |Enhancement| :class:`preprocessing.KBinsDiscretizer` with `strategy="uniform"` now + accepts `sample_weight`. Additionally with `strategy="quantile"` the + `quantile_method` can now be specified (in the future + `quantile_method="averaged_inverted_cdf"` will become the default). + By :user:`Shruti Nath ` and :user:`Olivier Grisel + ` :pr:`29907` + +- |Fix| :class:`preprocessing.KBinsDiscretizer` now uses weighted resampling when + sample weights are given and subsampling is used. This may change results + even when not using sample weights, although in absolute and not in terms + of statistical properties. + By :user:`Shruti Nath ` and :user:`Jérémie du Boisberranger + ` :pr:`29907` + +- |Fix| Now using ``scipy.stats.yeojohnson`` instead of our own implementation of the Yeo-Johnson transform. + Fixed numerical stability (mostly overflows) of the Yeo-Johnson transform with + `PowerTransformer(method="yeo-johnson")` when scipy version is `>= 1.12`. + Initial PR by :user:`Xuefeng Xu ` completed by :user:`Mohamed Yaich `, + :user:`Oussama Er-rabie `, :user:`Mohammed Yaslam Dlimi `, + :user:`Hamza Zaroual `, :user:`Amine Hannoun ` and :user:`Sylvain Marié `. :pr:`31227` + +:mod:`sklearn.svm` +------------------ + +- |Fix| :class:`svm.LinearSVC` now properly passes sample weights to + :func:`utils.class_weight.compute_class_weight` when fit with + `class_weight="balanced"`. + By :user:`Shruti Nath ` :pr:`30057` + +:mod:`sklearn.utils` +-------------------- + +- |Enhancement| :func:`utils.multiclass.type_of_target` raises a warning when the number + of unique classes is greater than 50% of the number of samples. This warning is raised + only if `y` has more than 20 samples. + By :user:`Rahil Parikh `. :pr:`26335` + +- |Enhancement| :func: `resample` now handles sample weights which allows + weighted resampling. + By :user:`Shruti Nath ` and :user:`Olivier Grisel + ` :pr:`29907` + +- |Enhancement| :func:`utils.class_weight.compute_class_weight` now properly accounts for + sample weights when using strategy "balanced" to calculate class weights. + By :user:`Shruti Nath ` :pr:`30057` + +- |Enhancement| Warning filters from the main process are propagated to joblib workers. + By `Thomas Fan`_ :pr:`30380` + +- |Enhancement| The private helper function :func:`utils._safe_indexing` now officially supports + pyarrow data. For instance, passing a pyarrow `Table` as `X` in a + :class:`compose.ColumnTransformer` is now possible. + By :user:`Christian Lorentzen ` :pr:`31040` + +- |Fix| In :mod:`utils.estimator_checks` we now enforce for binary classifiers a + binary `y` by taking the minimum as the negative class instead of the first + element, which makes it robust to `y` shuffling. It prevents two checks from + wrongly failing on binary classifiers. + By :user:`Antoine Baker `. :pr:`30775` + +- |Fix| :func:`utils.extmath.randomized_svd` and :func:`utils.extmath.randomized_range_finder` + now validate their input array to fail early with an informative error message on + invalid input. + By :user:`Connor Lane `. :pr:`30819` + .. rubric:: Code and documentation contributors Thanks to everyone who has contributed to the maintenance and improvement of -the project since version 1.7, including: +the project since version 1.6, including: -TODO: update at the time of the release. +4hm3d, Aaron Schumacher, Abhijeetsingh Meena, Acciaro Gennaro Daniele, +Achraf Tasfaout, Adrien Linares, Adrin Jalali, Agriya Khetarpal, Aiden Frank, +Aitsaid Azzedine Idir, ajay-sentry, Akanksha Mhadolkar, Alfredo Saucedo, +Anderson Chaves, Andres Guzman-Ballen, Aniruddha Saha, antoinebaker, Antony +Lee, Arjun S, ArthurDbrn, Arturo, Arturo Amor, ash, Ashton Powell, +ayoub.agouzoul, Bagus Tris Atmaja, Benjamin Danek, Boney Patel, Camille +Troillard, Chems Ben, Christian Lorentzen, Christian Veenhuis, Christine P. +Chai, claudio, Code_Blooded, Colas, Colin Coe, Connor Lane, Corey Farwell, +Daniel Agyapong, Dan Schult, Dea María Léon, Deepak Saldanha, +dependabot[bot], Dimitri Papadopoulos Orfanos, Dmitry Kobak, Domenico, Elham +Babaei, emelia-hdz, EmilyXinyi, Emma Carballal, Eric Larson, fabianhenning, +Gael Varoquaux, Gil Ramot, Gordon Grey, Goutam, G Sreeja, Guillaume Lemaitre, +Haesun Park, Hanjun Kim, Helder Geovane Gomes de Lima, Henri Bonamy, Hleb +Levitski, Hugo Boulenger, IlyaSolomatin, Irene, Jérémie du Boisberranger, +Jérôme Dockès, JoaoRodriguesIST, Joel Nothman, Josh, Kevin Klein, Loic +Esteve, Lucas Colley, Luc Rocher, Lucy Liu, Luis M. B. Varona, lunovian, Mamduh +Zabidi, Marc Bresson, Marco Edward Gorelli, Marco Maggi, Maren Westermann, +Marie Sacksick, Martin Jurča, Miguel González Duque, Mihir Waknis, Mohamed +Ali SRIR, Mohamed DHIFALLAH, mohammed benyamna, Mohit Singh Thakur, Mounir +Lbath, myenugula, Natalia Mokeeva, Olivier Grisel, omahs, Omar Salman, Pedro +Lopes, Pedro Olivares, Preyas Shah, Radovenchyk, Rahil Parikh, Rémi Flamary, +Reshama Shaikh, Rishab Saini, rolandrmgservices, SanchitD, Santiago Castro, +Santiago Víquez, scikit-learn-bot, Scott Huberty, Shruti Nath, Siddharth +Bansal, Simarjot Sidhu, Sortofamudkip, sotagg, Sourabh Kumar, Stefan, Stefanie +Senger, Stefano Gaspari, Stephen Pardy, Success Moses, Sylvain Combettes, Tahar +Allouche, Thomas J. Fan, Thomas Li, ThorbenMaa, Tim Head, Umberto Fasci, UV, +Vasco Pereira, Vassilis Margonis, Velislav Babatchev, Victoria Shevchenko, +viktor765, Vipsa Kamani, Virgil Chan, vpz, Xiao Yuan, Yaich Mohamed, Yair +Shimony, Yao Xiao, Yaroslav Halchenko, Yulia Vilensky, Yuvi Panda diff --git a/examples/bicluster/plot_spectral_biclustering.py b/examples/bicluster/plot_spectral_biclustering.py index 469c3c71e17c6..86245325ae493 100644 --- a/examples/bicluster/plot_spectral_biclustering.py +++ b/examples/bicluster/plot_spectral_biclustering.py @@ -26,7 +26,7 @@ # -------------------- # We generate the sample data using the # :func:`~sklearn.datasets.make_checkerboard` function. Each pixel within -# `shape=(300, 300)` represents with it's color a value from a uniform +# `shape=(300, 300)` represents with its color a value from a uniform # distribution. The noise is added from a normal distribution, where the value # chosen for `noise` is the standard deviation. # diff --git a/examples/cluster/plot_agglomerative_clustering_metrics.py b/examples/cluster/plot_agglomerative_clustering_metrics.py index c565a5859d093..dbf929d9576e1 100644 --- a/examples/cluster/plot_agglomerative_clustering_metrics.py +++ b/examples/cluster/plot_agglomerative_clustering_metrics.py @@ -18,7 +18,7 @@ We add observation noise to these waveforms. We generate very sparse noise: only 6% of the time points contain noise. As a result, the -l1 norm of this noise (ie "cityblock" distance) is much smaller than it's +l1 norm of this noise (ie "cityblock" distance) is much smaller than its l2 norm ("euclidean" distance). This can be seen on the inter-class distance matrices: the values on the diagonal, that characterize the spread of the class, are much bigger for the Euclidean distance than for diff --git a/examples/miscellaneous/plot_outlier_detection_bench.py b/examples/miscellaneous/plot_outlier_detection_bench.py index 600eceb1a06b3..933902500ef8b 100644 --- a/examples/miscellaneous/plot_outlier_detection_bench.py +++ b/examples/miscellaneous/plot_outlier_detection_bench.py @@ -355,8 +355,7 @@ def fit_predict(estimator, X): ax=ax, plot_chance_level=(model_idx == len(n_neighbors_list) - 1), chance_level_kw={"linestyle": (0, (1, 10))}, - linestyle=linestyle, - linewidth=2, + curve_kwargs=dict(linestyle=linestyle, linewidth=2), ) _ = ax.set_title("RobustScaler with varying n_neighbors\non forestcover dataset") @@ -395,8 +394,7 @@ def fit_predict(estimator, X): ax=ax, plot_chance_level=(model_idx == len(preprocessor_list) - 1), chance_level_kw={"linestyle": (0, (1, 10))}, - linestyle=linestyle, - linewidth=2, + curve_kwargs=dict(linestyle=linestyle, linewidth=2), ) _ = ax.set_title("Fixed n_neighbors with varying preprocessing\non forestcover dataset") @@ -447,8 +445,7 @@ def fit_predict(estimator, X): ax=ax, plot_chance_level=(model_idx == len(preprocessor_list) - 1), chance_level_kw={"linestyle": (0, (1, 10))}, - linestyle=linestyle, - linewidth=2, + curve_kwargs=dict(linestyle=linestyle, linewidth=2), ) ax.set_title( "Fixed n_neighbors with varying preprocessing\non cardiotocography dataset" diff --git a/examples/miscellaneous/plot_roc_curve_visualization_api.py b/examples/miscellaneous/plot_roc_curve_visualization_api.py index d377d321e061e..1aacbd9de3631 100644 --- a/examples/miscellaneous/plot_roc_curve_visualization_api.py +++ b/examples/miscellaneous/plot_roc_curve_visualization_api.py @@ -54,6 +54,8 @@ rfc = RandomForestClassifier(n_estimators=10, random_state=42) rfc.fit(X_train, y_train) ax = plt.gca() -rfc_disp = RocCurveDisplay.from_estimator(rfc, X_test, y_test, ax=ax, alpha=0.8) -svc_disp.plot(ax=ax, alpha=0.8) +rfc_disp = RocCurveDisplay.from_estimator( + rfc, X_test, y_test, ax=ax, curve_kwargs=dict(alpha=0.8) +) +svc_disp.plot(ax=ax, curve_kwargs=dict(alpha=0.8)) plt.show() diff --git a/examples/model_selection/plot_cost_sensitive_learning.py b/examples/model_selection/plot_cost_sensitive_learning.py index 9845d27661374..6b5b651463b05 100644 --- a/examples/model_selection/plot_cost_sensitive_learning.py +++ b/examples/model_selection/plot_cost_sensitive_learning.py @@ -321,8 +321,7 @@ def plot_roc_pr_curves(vanilla_model, tuned_model, *, title): X_test, y_test, pos_label=pos_label, - linestyle=linestyle, - color=color, + curve_kwargs=dict(linestyle=linestyle, color=color), ax=axs[1], name=name, plot_chance_level=idx == 1, diff --git a/examples/model_selection/plot_det.py b/examples/model_selection/plot_det.py index 873d00d696d95..4a22cdcd44eb8 100644 --- a/examples/model_selection/plot_det.py +++ b/examples/model_selection/plot_det.py @@ -103,7 +103,12 @@ ) clf.fit(X_train, y_train) RocCurveDisplay.from_estimator( - clf, X_test, y_test, ax=ax_roc, name=name, color=color, linestyle=linestyle + clf, + X_test, + y_test, + ax=ax_roc, + name=name, + curve_kwargs=dict(color=color, linestyle=linestyle), ) DetCurveDisplay.from_estimator( clf, X_test, y_test, ax=ax_det, name=name, color=color, linestyle=linestyle diff --git a/examples/model_selection/plot_grid_search_refit_callable.py b/examples/model_selection/plot_grid_search_refit_callable.py index 2b13ee5ad584c..945daf32b41ff 100644 --- a/examples/model_selection/plot_grid_search_refit_callable.py +++ b/examples/model_selection/plot_grid_search_refit_callable.py @@ -3,19 +3,20 @@ Balance model complexity and cross-validated score ================================================== -This example balances model complexity and cross-validated score by -finding a decent accuracy within 1 standard deviation of the best accuracy -score while minimising the number of PCA components [1]. +This example demonstrates how to balance model complexity and cross-validated score by +finding a decent accuracy within 1 standard deviation of the best accuracy score while +minimising the number of :class:`~sklearn.decomposition.PCA` components [1]. It uses +:class:`~sklearn.model_selection.GridSearchCV` with a custom refit callable to select +the optimal model. The figure shows the trade-off between cross-validated score and the number -of PCA components. The balanced case is when n_components=10 and accuracy=0.88, +of PCA components. The balanced case is when `n_components=10` and `accuracy=0.88`, which falls into the range within 1 standard deviation of the best accuracy score. [1] Hastie, T., Tibshirani, R.,, Friedman, J. (2001). Model Assessment and Selection. The Elements of Statistical Learning (pp. 219-260). New York, NY, USA: Springer New York Inc.. - """ # Authors: The scikit-learn developers @@ -23,12 +24,33 @@ import matplotlib.pyplot as plt import numpy as np +import polars as pl from sklearn.datasets import load_digits from sklearn.decomposition import PCA -from sklearn.model_selection import GridSearchCV +from sklearn.linear_model import LogisticRegression +from sklearn.model_selection import GridSearchCV, ShuffleSplit from sklearn.pipeline import Pipeline -from sklearn.svm import LinearSVC + +# %% +# Introduction +# ------------ +# +# When tuning hyperparameters, we often want to balance model complexity and +# performance. The "one-standard-error" rule is a common approach: select the simplest +# model whose performance is within one standard error of the best model's performance. +# This helps to avoid overfitting by preferring simpler models when their performance is +# statistically comparable to more complex ones. + +# %% +# Helper functions +# ---------------- +# +# We define two helper functions: +# 1. `lower_bound`: Calculates the threshold for acceptable performance +# (best score - 1 std) +# 2. `best_low_complexity`: Selects the model with the fewest PCA components that +# exceeds this threshold def lower_bound(cv_results): @@ -79,49 +101,280 @@ def best_low_complexity(cv_results): return best_idx +# %% +# Set up the pipeline and parameter grid +# -------------------------------------- +# +# We create a pipeline with two steps: +# 1. Dimensionality reduction using PCA +# 2. Classification using LogisticRegression +# +# We'll search over different numbers of PCA components to find the optimal complexity. + pipe = Pipeline( [ ("reduce_dim", PCA(random_state=42)), - ("classify", LinearSVC(random_state=42, C=0.01)), + ("classify", LogisticRegression(random_state=42, C=0.01, max_iter=1000)), ] ) -param_grid = {"reduce_dim__n_components": [6, 8, 10, 12, 14]} +param_grid = {"reduce_dim__n_components": [6, 8, 10, 15, 20, 25, 35, 45, 55]} + +# %% +# Perform the search with GridSearchCV +# ------------------------------------ +# +# We use `GridSearchCV` with our custom `best_low_complexity` function as the refit +# parameter. This function will select the model with the fewest PCA components that +# still performs within one standard deviation of the best model. grid = GridSearchCV( pipe, - cv=10, - n_jobs=1, + # Use a non-stratified CV strategy to make sure that the inter-fold + # standard deviation of the test scores is informative. + cv=ShuffleSplit(n_splits=30, random_state=0), + n_jobs=1, # increase this on your machine to use more physical cores param_grid=param_grid, scoring="accuracy", refit=best_low_complexity, + return_train_score=True, ) + +# %% +# Load the digits dataset and fit the model +# ----------------------------------------- + X, y = load_digits(return_X_y=True) grid.fit(X, y) +# %% +# Visualize the results +# --------------------- +# +# We'll create a bar chart showing the test scores for different numbers of PCA +# components, along with horizontal lines indicating the best score and the +# one-standard-deviation threshold. + n_components = grid.cv_results_["param_reduce_dim__n_components"] test_scores = grid.cv_results_["mean_test_score"] -plt.figure() -plt.bar(n_components, test_scores, width=1.3, color="b") +# Create a polars DataFrame for better data manipulation and visualization +results_df = pl.DataFrame( + { + "n_components": n_components, + "mean_test_score": test_scores, + "std_test_score": grid.cv_results_["std_test_score"], + "mean_train_score": grid.cv_results_["mean_train_score"], + "std_train_score": grid.cv_results_["std_train_score"], + "mean_fit_time": grid.cv_results_["mean_fit_time"], + "rank_test_score": grid.cv_results_["rank_test_score"], + } +) -lower = lower_bound(grid.cv_results_) -plt.axhline(np.max(test_scores), linestyle="--", color="y", label="Best score") -plt.axhline(lower, linestyle="--", color=".5", label="Best score - 1 std") +# Sort by number of components +results_df = results_df.sort("n_components") -plt.title("Balance model complexity and cross-validated score") -plt.xlabel("Number of PCA components used") -plt.ylabel("Digit classification accuracy") -plt.xticks(n_components.tolist()) -plt.ylim((0, 1.0)) -plt.legend(loc="upper left") +# Calculate the lower bound threshold +lower = lower_bound(grid.cv_results_) +# Get the best model information best_index_ = grid.best_index_ +best_components = n_components[best_index_] +best_score = grid.cv_results_["mean_test_score"][best_index_] + +# Add a column to mark the selected model +results_df = results_df.with_columns( + pl.when(pl.col("n_components") == best_components) + .then(pl.lit("Selected")) + .otherwise(pl.lit("Regular")) + .alias("model_type") +) + +# Get the number of CV splits from the results +n_splits = sum( + 1 + for key in grid.cv_results_.keys() + if key.startswith("split") and key.endswith("test_score") +) + +# Extract individual scores for each split +test_scores = np.array( + [ + [grid.cv_results_[f"split{i}_test_score"][j] for i in range(n_splits)] + for j in range(len(n_components)) + ] +) +train_scores = np.array( + [ + [grid.cv_results_[f"split{i}_train_score"][j] for i in range(n_splits)] + for j in range(len(n_components)) + ] +) + +# Calculate mean and std of test scores +mean_test_scores = np.mean(test_scores, axis=1) +std_test_scores = np.std(test_scores, axis=1) + +# Find best score and threshold +best_mean_score = np.max(mean_test_scores) +threshold = best_mean_score - std_test_scores[np.argmax(mean_test_scores)] + +# Create a single figure for visualization +fig, ax = plt.subplots(figsize=(12, 8)) -print("The best_index_ is %d" % best_index_) -print("The n_components selected is %d" % n_components[best_index_]) -print( - "The corresponding accuracy score is %.2f" - % grid.cv_results_["mean_test_score"][best_index_] +# Plot individual points +for i, comp in enumerate(n_components): + # Plot individual test points + plt.scatter( + [comp] * n_splits, + test_scores[i], + alpha=0.2, + color="blue", + s=20, + label="Individual test scores" if i == 0 else "", + ) + # Plot individual train points + plt.scatter( + [comp] * n_splits, + train_scores[i], + alpha=0.2, + color="green", + s=20, + label="Individual train scores" if i == 0 else "", + ) + +# Plot mean lines with error bands +plt.plot( + n_components, + np.mean(test_scores, axis=1), + "-", + color="blue", + linewidth=2, + label="Mean test score", +) +plt.fill_between( + n_components, + np.mean(test_scores, axis=1) - np.std(test_scores, axis=1), + np.mean(test_scores, axis=1) + np.std(test_scores, axis=1), + alpha=0.15, + color="blue", +) + +plt.plot( + n_components, + np.mean(train_scores, axis=1), + "-", + color="green", + linewidth=2, + label="Mean train score", +) +plt.fill_between( + n_components, + np.mean(train_scores, axis=1) - np.std(train_scores, axis=1), + np.mean(train_scores, axis=1) + np.std(train_scores, axis=1), + alpha=0.15, + color="green", ) + +# Add threshold lines +plt.axhline( + best_mean_score, + color="#9b59b6", # Purple + linestyle="--", + label="Best score", + linewidth=2, +) +plt.axhline( + threshold, + color="#e67e22", # Orange + linestyle="--", + label="Best score - 1 std", + linewidth=2, +) + +# Highlight selected model +plt.axvline( + best_components, + color="#9b59b6", # Purple + alpha=0.2, + linewidth=8, + label="Selected model", +) + +# Set titles and labels +plt.xlabel("Number of PCA components", fontsize=12) +plt.ylabel("Score", fontsize=12) +plt.title("Model Selection: Balancing Complexity and Performance", fontsize=14) +plt.grid(True, linestyle="--", alpha=0.7) +plt.legend( + bbox_to_anchor=(1.02, 1), + loc="upper left", + borderaxespad=0, +) + +# Set axis properties +plt.xticks(n_components) +plt.ylim((0.85, 1.0)) + +# # Adjust layout +plt.tight_layout() + +# %% +# Print the results +# ----------------- +# +# We print information about the selected model, including its complexity and +# performance. We also show a summary table of all models using polars. + +print("Best model selected by the one-standard-error rule:") +print(f"Number of PCA components: {best_components}") +print(f"Accuracy score: {best_score:.4f}") +print(f"Best possible accuracy: {np.max(test_scores):.4f}") +print(f"Accuracy threshold (best - 1 std): {lower:.4f}") + +# Create a summary table with polars +summary_df = results_df.select( + pl.col("n_components"), + pl.col("mean_test_score").round(4).alias("test_score"), + pl.col("std_test_score").round(4).alias("test_std"), + pl.col("mean_train_score").round(4).alias("train_score"), + pl.col("std_train_score").round(4).alias("train_std"), + pl.col("mean_fit_time").round(3).alias("fit_time"), + pl.col("rank_test_score").alias("rank"), +) + +# Add a column to mark the selected model +summary_df = summary_df.with_columns( + pl.when(pl.col("n_components") == best_components) + .then(pl.lit("*")) + .otherwise(pl.lit("")) + .alias("selected") +) + +print("\nModel comparison table:") +print(summary_df) + +# %% +# Conclusion +# ---------- +# +# The one-standard-error rule helps us select a simpler model (fewer PCA components) +# while maintaining performance statistically comparable to the best model. +# This approach can help prevent overfitting and improve model interpretability +# and efficiency. +# +# In this example, we've seen how to implement this rule using a custom refit +# callable with :class:`~sklearn.model_selection.GridSearchCV`. +# +# Key takeaways: +# 1. The one-standard-error rule provides a good rule of thumb to select simpler models +# 2. Custom refit callables in :class:`~sklearn.model_selection.GridSearchCV` allow for +# flexible model selection strategies +# 3. Visualizing both train and test scores helps identify potential overfitting +# +# This approach can be applied to other model selection scenarios where balancing +# complexity and performance is important, or in cases where a use-case specific +# selection of the "best" model is desired. + +# Display the figure plt.show() diff --git a/examples/model_selection/plot_roc.py b/examples/model_selection/plot_roc.py index a482ad5f4ab95..9e659b9a2aa64 100644 --- a/examples/model_selection/plot_roc.py +++ b/examples/model_selection/plot_roc.py @@ -129,7 +129,7 @@ y_onehot_test[:, class_id], y_score[:, class_id], name=f"{class_of_interest} vs the rest", - color="darkorange", + curve_kwargs=dict(color="darkorange"), plot_chance_level=True, despine=True, ) @@ -165,7 +165,7 @@ y_onehot_test.ravel(), y_score.ravel(), name="micro-average OvR", - color="darkorange", + curve_kwargs=dict(color="darkorange"), plot_chance_level=True, despine=True, ) @@ -290,7 +290,7 @@ y_onehot_test[:, class_id], y_score[:, class_id], name=f"ROC curve for {target_names[class_id]}", - color=color, + curve_kwargs=dict(color=color), ax=ax, plot_chance_level=(class_id == 2), despine=True, diff --git a/examples/model_selection/plot_roc_crossval.py b/examples/model_selection/plot_roc_crossval.py index fb6432a71ed79..868454626451c 100644 --- a/examples/model_selection/plot_roc_crossval.py +++ b/examples/model_selection/plot_roc_crossval.py @@ -89,8 +89,7 @@ X[test], y[test], name=f"ROC fold {fold}", - alpha=0.3, - lw=1, + curve_kwargs=dict(alpha=0.3, lw=1), ax=ax, plot_chance_level=(fold == n_splits - 1), ) diff --git a/examples/release_highlights/plot_release_highlights_1_7_0.py b/examples/release_highlights/plot_release_highlights_1_7_0.py new file mode 100644 index 0000000000000..06c2f10e70b28 --- /dev/null +++ b/examples/release_highlights/plot_release_highlights_1_7_0.py @@ -0,0 +1,115 @@ +# ruff: noqa: CPY001 +""" +======================================= +Release Highlights for scikit-learn 1.7 +======================================= + +.. currentmodule:: sklearn + +We are pleased to announce the release of scikit-learn 1.7! Many bug fixes +and improvements were added, as well as some key new features. Below we +detail the highlights of this release. **For an exhaustive list of +all the changes**, please refer to the :ref:`release notes `. + +To install the latest version (with pip):: + + pip install --upgrade scikit-learn + +or with conda:: + + conda install -c conda-forge scikit-learn + +""" + +# %% +# Improved estimator's HTML representation +# ---------------------------------------- +# The HTML representation of estimators now includes a section containing the list of +# parameters and their values. Non-default parameters are highlighted in orange. A copy +# button is also available to copy the "fully-qualified" parameter name without the +# need to call the `get_params` method. It is particularly useful when defining a +# parameter grid for a grid-search or a randomized-search with a complex pipeline. +# +# See the example below and click on the different estimator's blocks to see the +# improved HTML representation. + +from sklearn.linear_model import LogisticRegression +from sklearn.pipeline import make_pipeline +from sklearn.preprocessing import StandardScaler + +model = make_pipeline(StandardScaler(with_std=False), LogisticRegression(C=2.0)) +model + +# %% +# Custom validation set for histogram-based Gradient Boosting estimators +# ---------------------------------------------------------------------- +# The :class:`ensemble.HistGradientBoostingClassifier` and +# :class:`ensemble.HistGradientBoostingRegressor` now support directly passing a custom +# validation set for early stopping to the `fit` method, using the `X_val`, `y_val`, and +# `sample_weight_val` parameters. +# In a :class:`pipeline.Pipeline`, the validation set `X_val` can be transformed along +# with `X` using the `transform_input` parameter. + +import sklearn +from sklearn.datasets import make_classification +from sklearn.ensemble import HistGradientBoostingClassifier +from sklearn.model_selection import train_test_split +from sklearn.pipeline import Pipeline +from sklearn.preprocessing import StandardScaler + +sklearn.set_config(enable_metadata_routing=True) + +X, y = make_classification(random_state=0) +X_train, X_val, y_train, y_val = train_test_split(X, y, test_size=0.2, random_state=0) + +clf = HistGradientBoostingClassifier() +clf.set_fit_request(X_val=True, y_val=True) + +model = Pipeline([("sc", StandardScaler()), ("clf", clf)], transform_input=["X_val"]) +model.fit(X, y, X_val=X_val, y_val=y_val) + +# %% +# Plotting ROC curves from cross-validation results +# ------------------------------------------------- +# The class :class:`metrics.RocCurveDisplay` has a new class method `from_cv_results` +# that allows to easily plot multiple ROC curves from the results of +# :func:`model_selection.cross_validate`. + +from sklearn.datasets import make_classification +from sklearn.linear_model import LogisticRegression +from sklearn.metrics import RocCurveDisplay +from sklearn.model_selection import cross_validate + +X, y = make_classification(n_samples=150, random_state=0) +clf = LogisticRegression(random_state=0) +cv_results = cross_validate(clf, X, y, cv=5, return_estimator=True, return_indices=True) +_ = RocCurveDisplay.from_cv_results(cv_results, X, y) + +# %% +# Array API support +# ----------------- +# Several functions have been updated to support array API compatible inputs since +# version 1.6, especially metrics from the :mod:`sklearn.metrics` module. +# +# In addition, it is no longer required to install the `array-api-compat` package to use +# the experimental array API support in scikit-learn. +# +# Please refer to the :ref:`array API support` page for instructions to use +# scikit-learn with array API compatible libraries such as PyTorch or CuPy. + +# %% +# Improved API consistency of Multi-layer Perceptron +# -------------------------------------------------- +# The :class:`neural_network.MLPRegressor` has a new parameter `loss` and now supports +# the "poisson" loss in addition to the default "squared_error" loss. +# Moreover, the :class:`neural_network.MLPClassifier` and +# :class:`neural_network.MLPRegressor` estimators now support sample weights. +# These improvements have been made to improve the consistency of these estimators +# with regard to the other estimators in scikit-learn. + +# %% +# Migration toward sparse arrays +# ------------------------------ +# In order to prepare `SciPy migration from sparse matrices to sparse arrays `_, +# all scikit-learn estimators that accept sparse matrices as input now also accept +# sparse arrays. diff --git a/examples/svm/plot_svm_kernels.py b/examples/svm/plot_svm_kernels.py index df29d198abcbc..d01f049dbe0b4 100644 --- a/examples/svm/plot_svm_kernels.py +++ b/examples/svm/plot_svm_kernels.py @@ -255,7 +255,7 @@ def plot_training_data_with_decision_boundary( # that may not generalize well to unseen data. From this example it becomes # obvious, that the sigmoid kernel has very specific use cases, when dealing # with data that exhibits a sigmoidal shape. In this example, careful fine -# tuning might find more generalizable decision boundaries. Because of it's +# tuning might find more generalizable decision boundaries. Because of its # specificity, the sigmoid kernel is less commonly used in practice compared to # other kernels. # diff --git a/pyproject.toml b/pyproject.toml index 9a1c7c96241c7..c068fed72eda1 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -91,16 +91,16 @@ tests = [ "numpydoc>=1.2.0", "pooch>=1.6.0", ] -maintenance = ["conda-lock==2.5.7"] +maintenance = ["conda-lock==3.0.1"] [build-system] build-backend = "mesonpy" # Minimum requirements for the build system to execute. requires = [ - "meson-python>=0.16.0", - "Cython>=3.0.10", - "numpy>=2", - "scipy>=1.8.0", + "meson-python>=0.16.0,<0.19.0", + "Cython>=3.0.10,<3.2.0", + "numpy>=2,<2.3.0", + "scipy>=1.8.0,<1.16.0", ] [tool.pytest.ini_options] diff --git a/sklearn/__init__.py b/sklearn/__init__.py index 8ea5aacf84cf3..1ee488e44d713 100644 --- a/sklearn/__init__.py +++ b/sklearn/__init__.py @@ -42,7 +42,7 @@ # Dev branch marker is: 'X.Y.dev' or 'X.Y.devN' where N is an integer. # 'X.Y.dev0' is the canonical version of 'X.Y.dev' # -__version__ = "1.7.dev0" +__version__ = "1.7.0" # On OSX, we can get a runtime error due to multiple OpenMP libraries loaded diff --git a/sklearn/_loss/_loss.pyx.tp b/sklearn/_loss/_loss.pyx.tp index 6054d4c9472ca..44d5acd530a7f 100644 --- a/sklearn/_loss/_loss.pyx.tp +++ b/sklearn/_loss/_loss.pyx.tp @@ -121,7 +121,7 @@ doc_HalfTweedieLoss = ( - y_true * exp((1-p) * raw_prediction) / (1-p) Notes: - - Poisson with p=1 and and Gamma with p=2 have different terms dropped such + - Poisson with p=1 and Gamma with p=2 have different terms dropped such that cHalfTweedieLoss is not continuous in p=power at p=1 and p=2. - While the Tweedie distribution only exists for p<=0 or p>=1, the range 0>> clustering SpectralCoclustering(n_clusters=2, random_state=0) + + For a more detailed example, see the following: + :ref:`sphx_glr_auto_examples_bicluster_plot_spectral_coclustering.py`. """ _parameter_constraints: dict = { diff --git a/sklearn/cluster/_hdbscan/meson.build b/sklearn/cluster/_hdbscan/meson.build index f2e3ac91b1eb2..8d880b39a4db5 100644 --- a/sklearn/cluster/_hdbscan/meson.build +++ b/sklearn/cluster/_hdbscan/meson.build @@ -1,7 +1,7 @@ cluster_hdbscan_extension_metadata = { '_linkage': {'sources': [cython_gen.process('_linkage.pyx'), metrics_cython_tree]}, '_reachability': {'sources': [cython_gen.process('_reachability.pyx')]}, - '_tree': {'sources': ['_tree.pyx']} + '_tree': {'sources': [cython_gen.process('_tree.pyx')]} } foreach ext_name, ext_dict : cluster_hdbscan_extension_metadata diff --git a/sklearn/cluster/_optics.py b/sklearn/cluster/_optics.py index 0cd32023de46c..4a1a80c9065c2 100644 --- a/sklearn/cluster/_optics.py +++ b/sklearn/cluster/_optics.py @@ -34,19 +34,21 @@ class OPTICS(ClusterMixin, BaseEstimator): """Estimate clustering structure from vector array. OPTICS (Ordering Points To Identify the Clustering Structure), closely - related to DBSCAN, finds core sample of high density and expands clusters - from them [1]_. Unlike DBSCAN, keeps cluster hierarchy for a variable + related to DBSCAN, finds core samples of high density and expands clusters + from them [1]_. Unlike DBSCAN, it keeps cluster hierarchy for a variable neighborhood radius. Better suited for usage on large datasets than the - current sklearn implementation of DBSCAN. + current scikit-learn implementation of DBSCAN. - Clusters are then extracted using a DBSCAN-like method - (cluster_method = 'dbscan') or an automatic + Clusters are then extracted from the cluster-order using a + DBSCAN-like method (cluster_method = 'dbscan') or an automatic technique proposed in [1]_ (cluster_method = 'xi'). This implementation deviates from the original OPTICS by first performing - k-nearest-neighborhood searches on all points to identify core sizes, then - computing only the distances to unprocessed points when constructing the - cluster order. Note that we do not employ a heap to manage the expansion + k-nearest-neighborhood searches on all points to identify core sizes of + all points (instead of computing neighbors while looping through points). + Reachability distances to only unprocessed points are then computed, to + construct the cluster order, similar to the original OPTICS. + Note that we do not employ a heap to manage the expansion candidates, so the time complexity will be O(n^2). Read more in the :ref:`User Guide `. @@ -68,9 +70,9 @@ class OPTICS(ClusterMixin, BaseEstimator): metric : str or callable, default='minkowski' Metric to use for distance computation. Any metric from scikit-learn - or scipy.spatial.distance can be used. + or :mod:`scipy.spatial.distance` can be used. - If metric is a callable function, it is called on each + If `metric` is a callable function, it is called on each pair of instances (rows) and the resulting value recorded. The callable should take two arrays as input and return one value indicating the distance between them. This works for Scipy's metrics, but is less @@ -90,8 +92,7 @@ class OPTICS(ClusterMixin, BaseEstimator): 'yule'] Sparse matrices are only supported by scikit-learn metrics. - See the documentation for scipy.spatial.distance for details on these - metrics. + See :mod:`scipy.spatial.distance` for details on these metrics. .. note:: `'kulsinski'` is deprecated from SciPy 1.9 and will be removed in SciPy 1.11. @@ -105,9 +106,9 @@ class OPTICS(ClusterMixin, BaseEstimator): metric_params : dict, default=None Additional keyword arguments for the metric function. - cluster_method : str, default='xi' + cluster_method : {'xi', 'dbscan'}, default='xi' The extraction method used to extract clusters using the calculated - reachability and ordering. Possible values are "xi" and "dbscan". + reachability and ordering. eps : float, default=None The maximum distance between two samples for one to be considered as diff --git a/sklearn/compose/_column_transformer.py b/sklearn/compose/_column_transformer.py index 8e3938c49be32..2b9c32659e66e 100644 --- a/sklearn/compose/_column_transformer.py +++ b/sklearn/compose/_column_transformer.py @@ -20,10 +20,10 @@ from ..pipeline import _fit_transform_one, _name_estimators, _transform_one from ..preprocessing import FunctionTransformer from ..utils import Bunch -from ..utils._estimator_html_repr import _VisualBlock from ..utils._indexing import _determine_key_type, _get_column_indices, _safe_indexing from ..utils._metadata_requests import METHODS from ..utils._param_validation import HasMethods, Hidden, Interval, StrOptions +from ..utils._repr_html.estimator import _VisualBlock from ..utils._set_output import ( _get_container_adapter, _get_output_config, diff --git a/sklearn/datasets/data/boston_house_prices.csv b/sklearn/datasets/data/boston_house_prices.csv deleted file mode 100644 index 61193a5d646cc..0000000000000 --- a/sklearn/datasets/data/boston_house_prices.csv +++ /dev/null @@ -1,508 +0,0 @@ -506,13,,,,,,,,,,,, -"CRIM","ZN","INDUS","CHAS","NOX","RM","AGE","DIS","RAD","TAX","PTRATIO","B","LSTAT","MEDV" -0.00632,18,2.31,0,0.538,6.575,65.2,4.09,1,296,15.3,396.9,4.98,24 -0.02731,0,7.07,0,0.469,6.421,78.9,4.9671,2,242,17.8,396.9,9.14,21.6 -0.02729,0,7.07,0,0.469,7.185,61.1,4.9671,2,242,17.8,392.83,4.03,34.7 -0.03237,0,2.18,0,0.458,6.998,45.8,6.0622,3,222,18.7,394.63,2.94,33.4 -0.06905,0,2.18,0,0.458,7.147,54.2,6.0622,3,222,18.7,396.9,5.33,36.2 -0.02985,0,2.18,0,0.458,6.43,58.7,6.0622,3,222,18.7,394.12,5.21,28.7 -0.08829,12.5,7.87,0,0.524,6.012,66.6,5.5605,5,311,15.2,395.6,12.43,22.9 -0.14455,12.5,7.87,0,0.524,6.172,96.1,5.9505,5,311,15.2,396.9,19.15,27.1 -0.21124,12.5,7.87,0,0.524,5.631,100,6.0821,5,311,15.2,386.63,29.93,16.5 -0.17004,12.5,7.87,0,0.524,6.004,85.9,6.5921,5,311,15.2,386.71,17.1,18.9 -0.22489,12.5,7.87,0,0.524,6.377,94.3,6.3467,5,311,15.2,392.52,20.45,15 -0.11747,12.5,7.87,0,0.524,6.009,82.9,6.2267,5,311,15.2,396.9,13.27,18.9 -0.09378,12.5,7.87,0,0.524,5.889,39,5.4509,5,311,15.2,390.5,15.71,21.7 -0.62976,0,8.14,0,0.538,5.949,61.8,4.7075,4,307,21,396.9,8.26,20.4 -0.63796,0,8.14,0,0.538,6.096,84.5,4.4619,4,307,21,380.02,10.26,18.2 -0.62739,0,8.14,0,0.538,5.834,56.5,4.4986,4,307,21,395.62,8.47,19.9 -1.05393,0,8.14,0,0.538,5.935,29.3,4.4986,4,307,21,386.85,6.58,23.1 -0.7842,0,8.14,0,0.538,5.99,81.7,4.2579,4,307,21,386.75,14.67,17.5 -0.80271,0,8.14,0,0.538,5.456,36.6,3.7965,4,307,21,288.99,11.69,20.2 -0.7258,0,8.14,0,0.538,5.727,69.5,3.7965,4,307,21,390.95,11.28,18.2 -1.25179,0,8.14,0,0.538,5.57,98.1,3.7979,4,307,21,376.57,21.02,13.6 -0.85204,0,8.14,0,0.538,5.965,89.2,4.0123,4,307,21,392.53,13.83,19.6 -1.23247,0,8.14,0,0.538,6.142,91.7,3.9769,4,307,21,396.9,18.72,15.2 -0.98843,0,8.14,0,0.538,5.813,100,4.0952,4,307,21,394.54,19.88,14.5 -0.75026,0,8.14,0,0.538,5.924,94.1,4.3996,4,307,21,394.33,16.3,15.6 -0.84054,0,8.14,0,0.538,5.599,85.7,4.4546,4,307,21,303.42,16.51,13.9 -0.67191,0,8.14,0,0.538,5.813,90.3,4.682,4,307,21,376.88,14.81,16.6 -0.95577,0,8.14,0,0.538,6.047,88.8,4.4534,4,307,21,306.38,17.28,14.8 -0.77299,0,8.14,0,0.538,6.495,94.4,4.4547,4,307,21,387.94,12.8,18.4 -1.00245,0,8.14,0,0.538,6.674,87.3,4.239,4,307,21,380.23,11.98,21 -1.13081,0,8.14,0,0.538,5.713,94.1,4.233,4,307,21,360.17,22.6,12.7 -1.35472,0,8.14,0,0.538,6.072,100,4.175,4,307,21,376.73,13.04,14.5 -1.38799,0,8.14,0,0.538,5.95,82,3.99,4,307,21,232.6,27.71,13.2 -1.15172,0,8.14,0,0.538,5.701,95,3.7872,4,307,21,358.77,18.35,13.1 -1.61282,0,8.14,0,0.538,6.096,96.9,3.7598,4,307,21,248.31,20.34,13.5 -0.06417,0,5.96,0,0.499,5.933,68.2,3.3603,5,279,19.2,396.9,9.68,18.9 -0.09744,0,5.96,0,0.499,5.841,61.4,3.3779,5,279,19.2,377.56,11.41,20 -0.08014,0,5.96,0,0.499,5.85,41.5,3.9342,5,279,19.2,396.9,8.77,21 -0.17505,0,5.96,0,0.499,5.966,30.2,3.8473,5,279,19.2,393.43,10.13,24.7 -0.02763,75,2.95,0,0.428,6.595,21.8,5.4011,3,252,18.3,395.63,4.32,30.8 -0.03359,75,2.95,0,0.428,7.024,15.8,5.4011,3,252,18.3,395.62,1.98,34.9 -0.12744,0,6.91,0,0.448,6.77,2.9,5.7209,3,233,17.9,385.41,4.84,26.6 -0.1415,0,6.91,0,0.448,6.169,6.6,5.7209,3,233,17.9,383.37,5.81,25.3 -0.15936,0,6.91,0,0.448,6.211,6.5,5.7209,3,233,17.9,394.46,7.44,24.7 -0.12269,0,6.91,0,0.448,6.069,40,5.7209,3,233,17.9,389.39,9.55,21.2 -0.17142,0,6.91,0,0.448,5.682,33.8,5.1004,3,233,17.9,396.9,10.21,19.3 -0.18836,0,6.91,0,0.448,5.786,33.3,5.1004,3,233,17.9,396.9,14.15,20 -0.22927,0,6.91,0,0.448,6.03,85.5,5.6894,3,233,17.9,392.74,18.8,16.6 -0.25387,0,6.91,0,0.448,5.399,95.3,5.87,3,233,17.9,396.9,30.81,14.4 -0.21977,0,6.91,0,0.448,5.602,62,6.0877,3,233,17.9,396.9,16.2,19.4 -0.08873,21,5.64,0,0.439,5.963,45.7,6.8147,4,243,16.8,395.56,13.45,19.7 -0.04337,21,5.64,0,0.439,6.115,63,6.8147,4,243,16.8,393.97,9.43,20.5 -0.0536,21,5.64,0,0.439,6.511,21.1,6.8147,4,243,16.8,396.9,5.28,25 -0.04981,21,5.64,0,0.439,5.998,21.4,6.8147,4,243,16.8,396.9,8.43,23.4 -0.0136,75,4,0,0.41,5.888,47.6,7.3197,3,469,21.1,396.9,14.8,18.9 -0.01311,90,1.22,0,0.403,7.249,21.9,8.6966,5,226,17.9,395.93,4.81,35.4 -0.02055,85,0.74,0,0.41,6.383,35.7,9.1876,2,313,17.3,396.9,5.77,24.7 -0.01432,100,1.32,0,0.411,6.816,40.5,8.3248,5,256,15.1,392.9,3.95,31.6 -0.15445,25,5.13,0,0.453,6.145,29.2,7.8148,8,284,19.7,390.68,6.86,23.3 -0.10328,25,5.13,0,0.453,5.927,47.2,6.932,8,284,19.7,396.9,9.22,19.6 -0.14932,25,5.13,0,0.453,5.741,66.2,7.2254,8,284,19.7,395.11,13.15,18.7 -0.17171,25,5.13,0,0.453,5.966,93.4,6.8185,8,284,19.7,378.08,14.44,16 -0.11027,25,5.13,0,0.453,6.456,67.8,7.2255,8,284,19.7,396.9,6.73,22.2 -0.1265,25,5.13,0,0.453,6.762,43.4,7.9809,8,284,19.7,395.58,9.5,25 -0.01951,17.5,1.38,0,0.4161,7.104,59.5,9.2229,3,216,18.6,393.24,8.05,33 -0.03584,80,3.37,0,0.398,6.29,17.8,6.6115,4,337,16.1,396.9,4.67,23.5 -0.04379,80,3.37,0,0.398,5.787,31.1,6.6115,4,337,16.1,396.9,10.24,19.4 -0.05789,12.5,6.07,0,0.409,5.878,21.4,6.498,4,345,18.9,396.21,8.1,22 -0.13554,12.5,6.07,0,0.409,5.594,36.8,6.498,4,345,18.9,396.9,13.09,17.4 -0.12816,12.5,6.07,0,0.409,5.885,33,6.498,4,345,18.9,396.9,8.79,20.9 -0.08826,0,10.81,0,0.413,6.417,6.6,5.2873,4,305,19.2,383.73,6.72,24.2 -0.15876,0,10.81,0,0.413,5.961,17.5,5.2873,4,305,19.2,376.94,9.88,21.7 -0.09164,0,10.81,0,0.413,6.065,7.8,5.2873,4,305,19.2,390.91,5.52,22.8 -0.19539,0,10.81,0,0.413,6.245,6.2,5.2873,4,305,19.2,377.17,7.54,23.4 -0.07896,0,12.83,0,0.437,6.273,6,4.2515,5,398,18.7,394.92,6.78,24.1 -0.09512,0,12.83,0,0.437,6.286,45,4.5026,5,398,18.7,383.23,8.94,21.4 -0.10153,0,12.83,0,0.437,6.279,74.5,4.0522,5,398,18.7,373.66,11.97,20 -0.08707,0,12.83,0,0.437,6.14,45.8,4.0905,5,398,18.7,386.96,10.27,20.8 -0.05646,0,12.83,0,0.437,6.232,53.7,5.0141,5,398,18.7,386.4,12.34,21.2 -0.08387,0,12.83,0,0.437,5.874,36.6,4.5026,5,398,18.7,396.06,9.1,20.3 -0.04113,25,4.86,0,0.426,6.727,33.5,5.4007,4,281,19,396.9,5.29,28 -0.04462,25,4.86,0,0.426,6.619,70.4,5.4007,4,281,19,395.63,7.22,23.9 -0.03659,25,4.86,0,0.426,6.302,32.2,5.4007,4,281,19,396.9,6.72,24.8 -0.03551,25,4.86,0,0.426,6.167,46.7,5.4007,4,281,19,390.64,7.51,22.9 -0.05059,0,4.49,0,0.449,6.389,48,4.7794,3,247,18.5,396.9,9.62,23.9 -0.05735,0,4.49,0,0.449,6.63,56.1,4.4377,3,247,18.5,392.3,6.53,26.6 -0.05188,0,4.49,0,0.449,6.015,45.1,4.4272,3,247,18.5,395.99,12.86,22.5 -0.07151,0,4.49,0,0.449,6.121,56.8,3.7476,3,247,18.5,395.15,8.44,22.2 -0.0566,0,3.41,0,0.489,7.007,86.3,3.4217,2,270,17.8,396.9,5.5,23.6 -0.05302,0,3.41,0,0.489,7.079,63.1,3.4145,2,270,17.8,396.06,5.7,28.7 -0.04684,0,3.41,0,0.489,6.417,66.1,3.0923,2,270,17.8,392.18,8.81,22.6 -0.03932,0,3.41,0,0.489,6.405,73.9,3.0921,2,270,17.8,393.55,8.2,22 -0.04203,28,15.04,0,0.464,6.442,53.6,3.6659,4,270,18.2,395.01,8.16,22.9 -0.02875,28,15.04,0,0.464,6.211,28.9,3.6659,4,270,18.2,396.33,6.21,25 -0.04294,28,15.04,0,0.464,6.249,77.3,3.615,4,270,18.2,396.9,10.59,20.6 -0.12204,0,2.89,0,0.445,6.625,57.8,3.4952,2,276,18,357.98,6.65,28.4 -0.11504,0,2.89,0,0.445,6.163,69.6,3.4952,2,276,18,391.83,11.34,21.4 -0.12083,0,2.89,0,0.445,8.069,76,3.4952,2,276,18,396.9,4.21,38.7 -0.08187,0,2.89,0,0.445,7.82,36.9,3.4952,2,276,18,393.53,3.57,43.8 -0.0686,0,2.89,0,0.445,7.416,62.5,3.4952,2,276,18,396.9,6.19,33.2 -0.14866,0,8.56,0,0.52,6.727,79.9,2.7778,5,384,20.9,394.76,9.42,27.5 -0.11432,0,8.56,0,0.52,6.781,71.3,2.8561,5,384,20.9,395.58,7.67,26.5 -0.22876,0,8.56,0,0.52,6.405,85.4,2.7147,5,384,20.9,70.8,10.63,18.6 -0.21161,0,8.56,0,0.52,6.137,87.4,2.7147,5,384,20.9,394.47,13.44,19.3 -0.1396,0,8.56,0,0.52,6.167,90,2.421,5,384,20.9,392.69,12.33,20.1 -0.13262,0,8.56,0,0.52,5.851,96.7,2.1069,5,384,20.9,394.05,16.47,19.5 -0.1712,0,8.56,0,0.52,5.836,91.9,2.211,5,384,20.9,395.67,18.66,19.5 -0.13117,0,8.56,0,0.52,6.127,85.2,2.1224,5,384,20.9,387.69,14.09,20.4 -0.12802,0,8.56,0,0.52,6.474,97.1,2.4329,5,384,20.9,395.24,12.27,19.8 -0.26363,0,8.56,0,0.52,6.229,91.2,2.5451,5,384,20.9,391.23,15.55,19.4 -0.10793,0,8.56,0,0.52,6.195,54.4,2.7778,5,384,20.9,393.49,13,21.7 -0.10084,0,10.01,0,0.547,6.715,81.6,2.6775,6,432,17.8,395.59,10.16,22.8 -0.12329,0,10.01,0,0.547,5.913,92.9,2.3534,6,432,17.8,394.95,16.21,18.8 -0.22212,0,10.01,0,0.547,6.092,95.4,2.548,6,432,17.8,396.9,17.09,18.7 -0.14231,0,10.01,0,0.547,6.254,84.2,2.2565,6,432,17.8,388.74,10.45,18.5 -0.17134,0,10.01,0,0.547,5.928,88.2,2.4631,6,432,17.8,344.91,15.76,18.3 -0.13158,0,10.01,0,0.547,6.176,72.5,2.7301,6,432,17.8,393.3,12.04,21.2 -0.15098,0,10.01,0,0.547,6.021,82.6,2.7474,6,432,17.8,394.51,10.3,19.2 -0.13058,0,10.01,0,0.547,5.872,73.1,2.4775,6,432,17.8,338.63,15.37,20.4 -0.14476,0,10.01,0,0.547,5.731,65.2,2.7592,6,432,17.8,391.5,13.61,19.3 -0.06899,0,25.65,0,0.581,5.87,69.7,2.2577,2,188,19.1,389.15,14.37,22 -0.07165,0,25.65,0,0.581,6.004,84.1,2.1974,2,188,19.1,377.67,14.27,20.3 -0.09299,0,25.65,0,0.581,5.961,92.9,2.0869,2,188,19.1,378.09,17.93,20.5 -0.15038,0,25.65,0,0.581,5.856,97,1.9444,2,188,19.1,370.31,25.41,17.3 -0.09849,0,25.65,0,0.581,5.879,95.8,2.0063,2,188,19.1,379.38,17.58,18.8 -0.16902,0,25.65,0,0.581,5.986,88.4,1.9929,2,188,19.1,385.02,14.81,21.4 -0.38735,0,25.65,0,0.581,5.613,95.6,1.7572,2,188,19.1,359.29,27.26,15.7 -0.25915,0,21.89,0,0.624,5.693,96,1.7883,4,437,21.2,392.11,17.19,16.2 -0.32543,0,21.89,0,0.624,6.431,98.8,1.8125,4,437,21.2,396.9,15.39,18 -0.88125,0,21.89,0,0.624,5.637,94.7,1.9799,4,437,21.2,396.9,18.34,14.3 -0.34006,0,21.89,0,0.624,6.458,98.9,2.1185,4,437,21.2,395.04,12.6,19.2 -1.19294,0,21.89,0,0.624,6.326,97.7,2.271,4,437,21.2,396.9,12.26,19.6 -0.59005,0,21.89,0,0.624,6.372,97.9,2.3274,4,437,21.2,385.76,11.12,23 -0.32982,0,21.89,0,0.624,5.822,95.4,2.4699,4,437,21.2,388.69,15.03,18.4 -0.97617,0,21.89,0,0.624,5.757,98.4,2.346,4,437,21.2,262.76,17.31,15.6 -0.55778,0,21.89,0,0.624,6.335,98.2,2.1107,4,437,21.2,394.67,16.96,18.1 -0.32264,0,21.89,0,0.624,5.942,93.5,1.9669,4,437,21.2,378.25,16.9,17.4 -0.35233,0,21.89,0,0.624,6.454,98.4,1.8498,4,437,21.2,394.08,14.59,17.1 -0.2498,0,21.89,0,0.624,5.857,98.2,1.6686,4,437,21.2,392.04,21.32,13.3 -0.54452,0,21.89,0,0.624,6.151,97.9,1.6687,4,437,21.2,396.9,18.46,17.8 -0.2909,0,21.89,0,0.624,6.174,93.6,1.6119,4,437,21.2,388.08,24.16,14 -1.62864,0,21.89,0,0.624,5.019,100,1.4394,4,437,21.2,396.9,34.41,14.4 -3.32105,0,19.58,1,0.871,5.403,100,1.3216,5,403,14.7,396.9,26.82,13.4 -4.0974,0,19.58,0,0.871,5.468,100,1.4118,5,403,14.7,396.9,26.42,15.6 -2.77974,0,19.58,0,0.871,4.903,97.8,1.3459,5,403,14.7,396.9,29.29,11.8 -2.37934,0,19.58,0,0.871,6.13,100,1.4191,5,403,14.7,172.91,27.8,13.8 -2.15505,0,19.58,0,0.871,5.628,100,1.5166,5,403,14.7,169.27,16.65,15.6 -2.36862,0,19.58,0,0.871,4.926,95.7,1.4608,5,403,14.7,391.71,29.53,14.6 -2.33099,0,19.58,0,0.871,5.186,93.8,1.5296,5,403,14.7,356.99,28.32,17.8 -2.73397,0,19.58,0,0.871,5.597,94.9,1.5257,5,403,14.7,351.85,21.45,15.4 -1.6566,0,19.58,0,0.871,6.122,97.3,1.618,5,403,14.7,372.8,14.1,21.5 -1.49632,0,19.58,0,0.871,5.404,100,1.5916,5,403,14.7,341.6,13.28,19.6 -1.12658,0,19.58,1,0.871,5.012,88,1.6102,5,403,14.7,343.28,12.12,15.3 -2.14918,0,19.58,0,0.871,5.709,98.5,1.6232,5,403,14.7,261.95,15.79,19.4 -1.41385,0,19.58,1,0.871,6.129,96,1.7494,5,403,14.7,321.02,15.12,17 -3.53501,0,19.58,1,0.871,6.152,82.6,1.7455,5,403,14.7,88.01,15.02,15.6 -2.44668,0,19.58,0,0.871,5.272,94,1.7364,5,403,14.7,88.63,16.14,13.1 -1.22358,0,19.58,0,0.605,6.943,97.4,1.8773,5,403,14.7,363.43,4.59,41.3 -1.34284,0,19.58,0,0.605,6.066,100,1.7573,5,403,14.7,353.89,6.43,24.3 -1.42502,0,19.58,0,0.871,6.51,100,1.7659,5,403,14.7,364.31,7.39,23.3 -1.27346,0,19.58,1,0.605,6.25,92.6,1.7984,5,403,14.7,338.92,5.5,27 -1.46336,0,19.58,0,0.605,7.489,90.8,1.9709,5,403,14.7,374.43,1.73,50 -1.83377,0,19.58,1,0.605,7.802,98.2,2.0407,5,403,14.7,389.61,1.92,50 -1.51902,0,19.58,1,0.605,8.375,93.9,2.162,5,403,14.7,388.45,3.32,50 -2.24236,0,19.58,0,0.605,5.854,91.8,2.422,5,403,14.7,395.11,11.64,22.7 -2.924,0,19.58,0,0.605,6.101,93,2.2834,5,403,14.7,240.16,9.81,25 -2.01019,0,19.58,0,0.605,7.929,96.2,2.0459,5,403,14.7,369.3,3.7,50 -1.80028,0,19.58,0,0.605,5.877,79.2,2.4259,5,403,14.7,227.61,12.14,23.8 -2.3004,0,19.58,0,0.605,6.319,96.1,2.1,5,403,14.7,297.09,11.1,23.8 -2.44953,0,19.58,0,0.605,6.402,95.2,2.2625,5,403,14.7,330.04,11.32,22.3 -1.20742,0,19.58,0,0.605,5.875,94.6,2.4259,5,403,14.7,292.29,14.43,17.4 -2.3139,0,19.58,0,0.605,5.88,97.3,2.3887,5,403,14.7,348.13,12.03,19.1 -0.13914,0,4.05,0,0.51,5.572,88.5,2.5961,5,296,16.6,396.9,14.69,23.1 -0.09178,0,4.05,0,0.51,6.416,84.1,2.6463,5,296,16.6,395.5,9.04,23.6 -0.08447,0,4.05,0,0.51,5.859,68.7,2.7019,5,296,16.6,393.23,9.64,22.6 -0.06664,0,4.05,0,0.51,6.546,33.1,3.1323,5,296,16.6,390.96,5.33,29.4 -0.07022,0,4.05,0,0.51,6.02,47.2,3.5549,5,296,16.6,393.23,10.11,23.2 -0.05425,0,4.05,0,0.51,6.315,73.4,3.3175,5,296,16.6,395.6,6.29,24.6 -0.06642,0,4.05,0,0.51,6.86,74.4,2.9153,5,296,16.6,391.27,6.92,29.9 -0.0578,0,2.46,0,0.488,6.98,58.4,2.829,3,193,17.8,396.9,5.04,37.2 -0.06588,0,2.46,0,0.488,7.765,83.3,2.741,3,193,17.8,395.56,7.56,39.8 -0.06888,0,2.46,0,0.488,6.144,62.2,2.5979,3,193,17.8,396.9,9.45,36.2 -0.09103,0,2.46,0,0.488,7.155,92.2,2.7006,3,193,17.8,394.12,4.82,37.9 -0.10008,0,2.46,0,0.488,6.563,95.6,2.847,3,193,17.8,396.9,5.68,32.5 -0.08308,0,2.46,0,0.488,5.604,89.8,2.9879,3,193,17.8,391,13.98,26.4 -0.06047,0,2.46,0,0.488,6.153,68.8,3.2797,3,193,17.8,387.11,13.15,29.6 -0.05602,0,2.46,0,0.488,7.831,53.6,3.1992,3,193,17.8,392.63,4.45,50 -0.07875,45,3.44,0,0.437,6.782,41.1,3.7886,5,398,15.2,393.87,6.68,32 -0.12579,45,3.44,0,0.437,6.556,29.1,4.5667,5,398,15.2,382.84,4.56,29.8 -0.0837,45,3.44,0,0.437,7.185,38.9,4.5667,5,398,15.2,396.9,5.39,34.9 -0.09068,45,3.44,0,0.437,6.951,21.5,6.4798,5,398,15.2,377.68,5.1,37 -0.06911,45,3.44,0,0.437,6.739,30.8,6.4798,5,398,15.2,389.71,4.69,30.5 -0.08664,45,3.44,0,0.437,7.178,26.3,6.4798,5,398,15.2,390.49,2.87,36.4 -0.02187,60,2.93,0,0.401,6.8,9.9,6.2196,1,265,15.6,393.37,5.03,31.1 -0.01439,60,2.93,0,0.401,6.604,18.8,6.2196,1,265,15.6,376.7,4.38,29.1 -0.01381,80,0.46,0,0.422,7.875,32,5.6484,4,255,14.4,394.23,2.97,50 -0.04011,80,1.52,0,0.404,7.287,34.1,7.309,2,329,12.6,396.9,4.08,33.3 -0.04666,80,1.52,0,0.404,7.107,36.6,7.309,2,329,12.6,354.31,8.61,30.3 -0.03768,80,1.52,0,0.404,7.274,38.3,7.309,2,329,12.6,392.2,6.62,34.6 -0.0315,95,1.47,0,0.403,6.975,15.3,7.6534,3,402,17,396.9,4.56,34.9 -0.01778,95,1.47,0,0.403,7.135,13.9,7.6534,3,402,17,384.3,4.45,32.9 -0.03445,82.5,2.03,0,0.415,6.162,38.4,6.27,2,348,14.7,393.77,7.43,24.1 -0.02177,82.5,2.03,0,0.415,7.61,15.7,6.27,2,348,14.7,395.38,3.11,42.3 -0.0351,95,2.68,0,0.4161,7.853,33.2,5.118,4,224,14.7,392.78,3.81,48.5 -0.02009,95,2.68,0,0.4161,8.034,31.9,5.118,4,224,14.7,390.55,2.88,50 -0.13642,0,10.59,0,0.489,5.891,22.3,3.9454,4,277,18.6,396.9,10.87,22.6 -0.22969,0,10.59,0,0.489,6.326,52.5,4.3549,4,277,18.6,394.87,10.97,24.4 -0.25199,0,10.59,0,0.489,5.783,72.7,4.3549,4,277,18.6,389.43,18.06,22.5 -0.13587,0,10.59,1,0.489,6.064,59.1,4.2392,4,277,18.6,381.32,14.66,24.4 -0.43571,0,10.59,1,0.489,5.344,100,3.875,4,277,18.6,396.9,23.09,20 -0.17446,0,10.59,1,0.489,5.96,92.1,3.8771,4,277,18.6,393.25,17.27,21.7 -0.37578,0,10.59,1,0.489,5.404,88.6,3.665,4,277,18.6,395.24,23.98,19.3 -0.21719,0,10.59,1,0.489,5.807,53.8,3.6526,4,277,18.6,390.94,16.03,22.4 -0.14052,0,10.59,0,0.489,6.375,32.3,3.9454,4,277,18.6,385.81,9.38,28.1 -0.28955,0,10.59,0,0.489,5.412,9.8,3.5875,4,277,18.6,348.93,29.55,23.7 -0.19802,0,10.59,0,0.489,6.182,42.4,3.9454,4,277,18.6,393.63,9.47,25 -0.0456,0,13.89,1,0.55,5.888,56,3.1121,5,276,16.4,392.8,13.51,23.3 -0.07013,0,13.89,0,0.55,6.642,85.1,3.4211,5,276,16.4,392.78,9.69,28.7 -0.11069,0,13.89,1,0.55,5.951,93.8,2.8893,5,276,16.4,396.9,17.92,21.5 -0.11425,0,13.89,1,0.55,6.373,92.4,3.3633,5,276,16.4,393.74,10.5,23 -0.35809,0,6.2,1,0.507,6.951,88.5,2.8617,8,307,17.4,391.7,9.71,26.7 -0.40771,0,6.2,1,0.507,6.164,91.3,3.048,8,307,17.4,395.24,21.46,21.7 -0.62356,0,6.2,1,0.507,6.879,77.7,3.2721,8,307,17.4,390.39,9.93,27.5 -0.6147,0,6.2,0,0.507,6.618,80.8,3.2721,8,307,17.4,396.9,7.6,30.1 -0.31533,0,6.2,0,0.504,8.266,78.3,2.8944,8,307,17.4,385.05,4.14,44.8 -0.52693,0,6.2,0,0.504,8.725,83,2.8944,8,307,17.4,382,4.63,50 -0.38214,0,6.2,0,0.504,8.04,86.5,3.2157,8,307,17.4,387.38,3.13,37.6 -0.41238,0,6.2,0,0.504,7.163,79.9,3.2157,8,307,17.4,372.08,6.36,31.6 -0.29819,0,6.2,0,0.504,7.686,17,3.3751,8,307,17.4,377.51,3.92,46.7 -0.44178,0,6.2,0,0.504,6.552,21.4,3.3751,8,307,17.4,380.34,3.76,31.5 -0.537,0,6.2,0,0.504,5.981,68.1,3.6715,8,307,17.4,378.35,11.65,24.3 -0.46296,0,6.2,0,0.504,7.412,76.9,3.6715,8,307,17.4,376.14,5.25,31.7 -0.57529,0,6.2,0,0.507,8.337,73.3,3.8384,8,307,17.4,385.91,2.47,41.7 -0.33147,0,6.2,0,0.507,8.247,70.4,3.6519,8,307,17.4,378.95,3.95,48.3 -0.44791,0,6.2,1,0.507,6.726,66.5,3.6519,8,307,17.4,360.2,8.05,29 -0.33045,0,6.2,0,0.507,6.086,61.5,3.6519,8,307,17.4,376.75,10.88,24 -0.52058,0,6.2,1,0.507,6.631,76.5,4.148,8,307,17.4,388.45,9.54,25.1 -0.51183,0,6.2,0,0.507,7.358,71.6,4.148,8,307,17.4,390.07,4.73,31.5 -0.08244,30,4.93,0,0.428,6.481,18.5,6.1899,6,300,16.6,379.41,6.36,23.7 -0.09252,30,4.93,0,0.428,6.606,42.2,6.1899,6,300,16.6,383.78,7.37,23.3 -0.11329,30,4.93,0,0.428,6.897,54.3,6.3361,6,300,16.6,391.25,11.38,22 -0.10612,30,4.93,0,0.428,6.095,65.1,6.3361,6,300,16.6,394.62,12.4,20.1 -0.1029,30,4.93,0,0.428,6.358,52.9,7.0355,6,300,16.6,372.75,11.22,22.2 -0.12757,30,4.93,0,0.428,6.393,7.8,7.0355,6,300,16.6,374.71,5.19,23.7 -0.20608,22,5.86,0,0.431,5.593,76.5,7.9549,7,330,19.1,372.49,12.5,17.6 -0.19133,22,5.86,0,0.431,5.605,70.2,7.9549,7,330,19.1,389.13,18.46,18.5 -0.33983,22,5.86,0,0.431,6.108,34.9,8.0555,7,330,19.1,390.18,9.16,24.3 -0.19657,22,5.86,0,0.431,6.226,79.2,8.0555,7,330,19.1,376.14,10.15,20.5 -0.16439,22,5.86,0,0.431,6.433,49.1,7.8265,7,330,19.1,374.71,9.52,24.5 -0.19073,22,5.86,0,0.431,6.718,17.5,7.8265,7,330,19.1,393.74,6.56,26.2 -0.1403,22,5.86,0,0.431,6.487,13,7.3967,7,330,19.1,396.28,5.9,24.4 -0.21409,22,5.86,0,0.431,6.438,8.9,7.3967,7,330,19.1,377.07,3.59,24.8 -0.08221,22,5.86,0,0.431,6.957,6.8,8.9067,7,330,19.1,386.09,3.53,29.6 -0.36894,22,5.86,0,0.431,8.259,8.4,8.9067,7,330,19.1,396.9,3.54,42.8 -0.04819,80,3.64,0,0.392,6.108,32,9.2203,1,315,16.4,392.89,6.57,21.9 -0.03548,80,3.64,0,0.392,5.876,19.1,9.2203,1,315,16.4,395.18,9.25,20.9 -0.01538,90,3.75,0,0.394,7.454,34.2,6.3361,3,244,15.9,386.34,3.11,44 -0.61154,20,3.97,0,0.647,8.704,86.9,1.801,5,264,13,389.7,5.12,50 -0.66351,20,3.97,0,0.647,7.333,100,1.8946,5,264,13,383.29,7.79,36 -0.65665,20,3.97,0,0.647,6.842,100,2.0107,5,264,13,391.93,6.9,30.1 -0.54011,20,3.97,0,0.647,7.203,81.8,2.1121,5,264,13,392.8,9.59,33.8 -0.53412,20,3.97,0,0.647,7.52,89.4,2.1398,5,264,13,388.37,7.26,43.1 -0.52014,20,3.97,0,0.647,8.398,91.5,2.2885,5,264,13,386.86,5.91,48.8 -0.82526,20,3.97,0,0.647,7.327,94.5,2.0788,5,264,13,393.42,11.25,31 -0.55007,20,3.97,0,0.647,7.206,91.6,1.9301,5,264,13,387.89,8.1,36.5 -0.76162,20,3.97,0,0.647,5.56,62.8,1.9865,5,264,13,392.4,10.45,22.8 -0.7857,20,3.97,0,0.647,7.014,84.6,2.1329,5,264,13,384.07,14.79,30.7 -0.57834,20,3.97,0,0.575,8.297,67,2.4216,5,264,13,384.54,7.44,50 -0.5405,20,3.97,0,0.575,7.47,52.6,2.872,5,264,13,390.3,3.16,43.5 -0.09065,20,6.96,1,0.464,5.92,61.5,3.9175,3,223,18.6,391.34,13.65,20.7 -0.29916,20,6.96,0,0.464,5.856,42.1,4.429,3,223,18.6,388.65,13,21.1 -0.16211,20,6.96,0,0.464,6.24,16.3,4.429,3,223,18.6,396.9,6.59,25.2 -0.1146,20,6.96,0,0.464,6.538,58.7,3.9175,3,223,18.6,394.96,7.73,24.4 -0.22188,20,6.96,1,0.464,7.691,51.8,4.3665,3,223,18.6,390.77,6.58,35.2 -0.05644,40,6.41,1,0.447,6.758,32.9,4.0776,4,254,17.6,396.9,3.53,32.4 -0.09604,40,6.41,0,0.447,6.854,42.8,4.2673,4,254,17.6,396.9,2.98,32 -0.10469,40,6.41,1,0.447,7.267,49,4.7872,4,254,17.6,389.25,6.05,33.2 -0.06127,40,6.41,1,0.447,6.826,27.6,4.8628,4,254,17.6,393.45,4.16,33.1 -0.07978,40,6.41,0,0.447,6.482,32.1,4.1403,4,254,17.6,396.9,7.19,29.1 -0.21038,20,3.33,0,0.4429,6.812,32.2,4.1007,5,216,14.9,396.9,4.85,35.1 -0.03578,20,3.33,0,0.4429,7.82,64.5,4.6947,5,216,14.9,387.31,3.76,45.4 -0.03705,20,3.33,0,0.4429,6.968,37.2,5.2447,5,216,14.9,392.23,4.59,35.4 -0.06129,20,3.33,1,0.4429,7.645,49.7,5.2119,5,216,14.9,377.07,3.01,46 -0.01501,90,1.21,1,0.401,7.923,24.8,5.885,1,198,13.6,395.52,3.16,50 -0.00906,90,2.97,0,0.4,7.088,20.8,7.3073,1,285,15.3,394.72,7.85,32.2 -0.01096,55,2.25,0,0.389,6.453,31.9,7.3073,1,300,15.3,394.72,8.23,22 -0.01965,80,1.76,0,0.385,6.23,31.5,9.0892,1,241,18.2,341.6,12.93,20.1 -0.03871,52.5,5.32,0,0.405,6.209,31.3,7.3172,6,293,16.6,396.9,7.14,23.2 -0.0459,52.5,5.32,0,0.405,6.315,45.6,7.3172,6,293,16.6,396.9,7.6,22.3 -0.04297,52.5,5.32,0,0.405,6.565,22.9,7.3172,6,293,16.6,371.72,9.51,24.8 -0.03502,80,4.95,0,0.411,6.861,27.9,5.1167,4,245,19.2,396.9,3.33,28.5 -0.07886,80,4.95,0,0.411,7.148,27.7,5.1167,4,245,19.2,396.9,3.56,37.3 -0.03615,80,4.95,0,0.411,6.63,23.4,5.1167,4,245,19.2,396.9,4.7,27.9 -0.08265,0,13.92,0,0.437,6.127,18.4,5.5027,4,289,16,396.9,8.58,23.9 -0.08199,0,13.92,0,0.437,6.009,42.3,5.5027,4,289,16,396.9,10.4,21.7 -0.12932,0,13.92,0,0.437,6.678,31.1,5.9604,4,289,16,396.9,6.27,28.6 -0.05372,0,13.92,0,0.437,6.549,51,5.9604,4,289,16,392.85,7.39,27.1 -0.14103,0,13.92,0,0.437,5.79,58,6.32,4,289,16,396.9,15.84,20.3 -0.06466,70,2.24,0,0.4,6.345,20.1,7.8278,5,358,14.8,368.24,4.97,22.5 -0.05561,70,2.24,0,0.4,7.041,10,7.8278,5,358,14.8,371.58,4.74,29 -0.04417,70,2.24,0,0.4,6.871,47.4,7.8278,5,358,14.8,390.86,6.07,24.8 -0.03537,34,6.09,0,0.433,6.59,40.4,5.4917,7,329,16.1,395.75,9.5,22 -0.09266,34,6.09,0,0.433,6.495,18.4,5.4917,7,329,16.1,383.61,8.67,26.4 -0.1,34,6.09,0,0.433,6.982,17.7,5.4917,7,329,16.1,390.43,4.86,33.1 -0.05515,33,2.18,0,0.472,7.236,41.1,4.022,7,222,18.4,393.68,6.93,36.1 -0.05479,33,2.18,0,0.472,6.616,58.1,3.37,7,222,18.4,393.36,8.93,28.4 -0.07503,33,2.18,0,0.472,7.42,71.9,3.0992,7,222,18.4,396.9,6.47,33.4 -0.04932,33,2.18,0,0.472,6.849,70.3,3.1827,7,222,18.4,396.9,7.53,28.2 -0.49298,0,9.9,0,0.544,6.635,82.5,3.3175,4,304,18.4,396.9,4.54,22.8 -0.3494,0,9.9,0,0.544,5.972,76.7,3.1025,4,304,18.4,396.24,9.97,20.3 -2.63548,0,9.9,0,0.544,4.973,37.8,2.5194,4,304,18.4,350.45,12.64,16.1 -0.79041,0,9.9,0,0.544,6.122,52.8,2.6403,4,304,18.4,396.9,5.98,22.1 -0.26169,0,9.9,0,0.544,6.023,90.4,2.834,4,304,18.4,396.3,11.72,19.4 -0.26938,0,9.9,0,0.544,6.266,82.8,3.2628,4,304,18.4,393.39,7.9,21.6 -0.3692,0,9.9,0,0.544,6.567,87.3,3.6023,4,304,18.4,395.69,9.28,23.8 -0.25356,0,9.9,0,0.544,5.705,77.7,3.945,4,304,18.4,396.42,11.5,16.2 -0.31827,0,9.9,0,0.544,5.914,83.2,3.9986,4,304,18.4,390.7,18.33,17.8 -0.24522,0,9.9,0,0.544,5.782,71.7,4.0317,4,304,18.4,396.9,15.94,19.8 -0.40202,0,9.9,0,0.544,6.382,67.2,3.5325,4,304,18.4,395.21,10.36,23.1 -0.47547,0,9.9,0,0.544,6.113,58.8,4.0019,4,304,18.4,396.23,12.73,21 -0.1676,0,7.38,0,0.493,6.426,52.3,4.5404,5,287,19.6,396.9,7.2,23.8 -0.18159,0,7.38,0,0.493,6.376,54.3,4.5404,5,287,19.6,396.9,6.87,23.1 -0.35114,0,7.38,0,0.493,6.041,49.9,4.7211,5,287,19.6,396.9,7.7,20.4 -0.28392,0,7.38,0,0.493,5.708,74.3,4.7211,5,287,19.6,391.13,11.74,18.5 -0.34109,0,7.38,0,0.493,6.415,40.1,4.7211,5,287,19.6,396.9,6.12,25 -0.19186,0,7.38,0,0.493,6.431,14.7,5.4159,5,287,19.6,393.68,5.08,24.6 -0.30347,0,7.38,0,0.493,6.312,28.9,5.4159,5,287,19.6,396.9,6.15,23 -0.24103,0,7.38,0,0.493,6.083,43.7,5.4159,5,287,19.6,396.9,12.79,22.2 -0.06617,0,3.24,0,0.46,5.868,25.8,5.2146,4,430,16.9,382.44,9.97,19.3 -0.06724,0,3.24,0,0.46,6.333,17.2,5.2146,4,430,16.9,375.21,7.34,22.6 -0.04544,0,3.24,0,0.46,6.144,32.2,5.8736,4,430,16.9,368.57,9.09,19.8 -0.05023,35,6.06,0,0.4379,5.706,28.4,6.6407,1,304,16.9,394.02,12.43,17.1 -0.03466,35,6.06,0,0.4379,6.031,23.3,6.6407,1,304,16.9,362.25,7.83,19.4 -0.05083,0,5.19,0,0.515,6.316,38.1,6.4584,5,224,20.2,389.71,5.68,22.2 -0.03738,0,5.19,0,0.515,6.31,38.5,6.4584,5,224,20.2,389.4,6.75,20.7 -0.03961,0,5.19,0,0.515,6.037,34.5,5.9853,5,224,20.2,396.9,8.01,21.1 -0.03427,0,5.19,0,0.515,5.869,46.3,5.2311,5,224,20.2,396.9,9.8,19.5 -0.03041,0,5.19,0,0.515,5.895,59.6,5.615,5,224,20.2,394.81,10.56,18.5 -0.03306,0,5.19,0,0.515,6.059,37.3,4.8122,5,224,20.2,396.14,8.51,20.6 -0.05497,0,5.19,0,0.515,5.985,45.4,4.8122,5,224,20.2,396.9,9.74,19 -0.06151,0,5.19,0,0.515,5.968,58.5,4.8122,5,224,20.2,396.9,9.29,18.7 -0.01301,35,1.52,0,0.442,7.241,49.3,7.0379,1,284,15.5,394.74,5.49,32.7 -0.02498,0,1.89,0,0.518,6.54,59.7,6.2669,1,422,15.9,389.96,8.65,16.5 -0.02543,55,3.78,0,0.484,6.696,56.4,5.7321,5,370,17.6,396.9,7.18,23.9 -0.03049,55,3.78,0,0.484,6.874,28.1,6.4654,5,370,17.6,387.97,4.61,31.2 -0.03113,0,4.39,0,0.442,6.014,48.5,8.0136,3,352,18.8,385.64,10.53,17.5 -0.06162,0,4.39,0,0.442,5.898,52.3,8.0136,3,352,18.8,364.61,12.67,17.2 -0.0187,85,4.15,0,0.429,6.516,27.7,8.5353,4,351,17.9,392.43,6.36,23.1 -0.01501,80,2.01,0,0.435,6.635,29.7,8.344,4,280,17,390.94,5.99,24.5 -0.02899,40,1.25,0,0.429,6.939,34.5,8.7921,1,335,19.7,389.85,5.89,26.6 -0.06211,40,1.25,0,0.429,6.49,44.4,8.7921,1,335,19.7,396.9,5.98,22.9 -0.0795,60,1.69,0,0.411,6.579,35.9,10.7103,4,411,18.3,370.78,5.49,24.1 -0.07244,60,1.69,0,0.411,5.884,18.5,10.7103,4,411,18.3,392.33,7.79,18.6 -0.01709,90,2.02,0,0.41,6.728,36.1,12.1265,5,187,17,384.46,4.5,30.1 -0.04301,80,1.91,0,0.413,5.663,21.9,10.5857,4,334,22,382.8,8.05,18.2 -0.10659,80,1.91,0,0.413,5.936,19.5,10.5857,4,334,22,376.04,5.57,20.6 -8.98296,0,18.1,1,0.77,6.212,97.4,2.1222,24,666,20.2,377.73,17.6,17.8 -3.8497,0,18.1,1,0.77,6.395,91,2.5052,24,666,20.2,391.34,13.27,21.7 -5.20177,0,18.1,1,0.77,6.127,83.4,2.7227,24,666,20.2,395.43,11.48,22.7 -4.26131,0,18.1,0,0.77,6.112,81.3,2.5091,24,666,20.2,390.74,12.67,22.6 -4.54192,0,18.1,0,0.77,6.398,88,2.5182,24,666,20.2,374.56,7.79,25 -3.83684,0,18.1,0,0.77,6.251,91.1,2.2955,24,666,20.2,350.65,14.19,19.9 -3.67822,0,18.1,0,0.77,5.362,96.2,2.1036,24,666,20.2,380.79,10.19,20.8 -4.22239,0,18.1,1,0.77,5.803,89,1.9047,24,666,20.2,353.04,14.64,16.8 -3.47428,0,18.1,1,0.718,8.78,82.9,1.9047,24,666,20.2,354.55,5.29,21.9 -4.55587,0,18.1,0,0.718,3.561,87.9,1.6132,24,666,20.2,354.7,7.12,27.5 -3.69695,0,18.1,0,0.718,4.963,91.4,1.7523,24,666,20.2,316.03,14,21.9 -13.5222,0,18.1,0,0.631,3.863,100,1.5106,24,666,20.2,131.42,13.33,23.1 -4.89822,0,18.1,0,0.631,4.97,100,1.3325,24,666,20.2,375.52,3.26,50 -5.66998,0,18.1,1,0.631,6.683,96.8,1.3567,24,666,20.2,375.33,3.73,50 -6.53876,0,18.1,1,0.631,7.016,97.5,1.2024,24,666,20.2,392.05,2.96,50 -9.2323,0,18.1,0,0.631,6.216,100,1.1691,24,666,20.2,366.15,9.53,50 -8.26725,0,18.1,1,0.668,5.875,89.6,1.1296,24,666,20.2,347.88,8.88,50 -11.1081,0,18.1,0,0.668,4.906,100,1.1742,24,666,20.2,396.9,34.77,13.8 -18.4982,0,18.1,0,0.668,4.138,100,1.137,24,666,20.2,396.9,37.97,13.8 -19.6091,0,18.1,0,0.671,7.313,97.9,1.3163,24,666,20.2,396.9,13.44,15 -15.288,0,18.1,0,0.671,6.649,93.3,1.3449,24,666,20.2,363.02,23.24,13.9 -9.82349,0,18.1,0,0.671,6.794,98.8,1.358,24,666,20.2,396.9,21.24,13.3 -23.6482,0,18.1,0,0.671,6.38,96.2,1.3861,24,666,20.2,396.9,23.69,13.1 -17.8667,0,18.1,0,0.671,6.223,100,1.3861,24,666,20.2,393.74,21.78,10.2 -88.9762,0,18.1,0,0.671,6.968,91.9,1.4165,24,666,20.2,396.9,17.21,10.4 -15.8744,0,18.1,0,0.671,6.545,99.1,1.5192,24,666,20.2,396.9,21.08,10.9 -9.18702,0,18.1,0,0.7,5.536,100,1.5804,24,666,20.2,396.9,23.6,11.3 -7.99248,0,18.1,0,0.7,5.52,100,1.5331,24,666,20.2,396.9,24.56,12.3 -20.0849,0,18.1,0,0.7,4.368,91.2,1.4395,24,666,20.2,285.83,30.63,8.8 -16.8118,0,18.1,0,0.7,5.277,98.1,1.4261,24,666,20.2,396.9,30.81,7.2 -24.3938,0,18.1,0,0.7,4.652,100,1.4672,24,666,20.2,396.9,28.28,10.5 -22.5971,0,18.1,0,0.7,5,89.5,1.5184,24,666,20.2,396.9,31.99,7.4 -14.3337,0,18.1,0,0.7,4.88,100,1.5895,24,666,20.2,372.92,30.62,10.2 -8.15174,0,18.1,0,0.7,5.39,98.9,1.7281,24,666,20.2,396.9,20.85,11.5 -6.96215,0,18.1,0,0.7,5.713,97,1.9265,24,666,20.2,394.43,17.11,15.1 -5.29305,0,18.1,0,0.7,6.051,82.5,2.1678,24,666,20.2,378.38,18.76,23.2 -11.5779,0,18.1,0,0.7,5.036,97,1.77,24,666,20.2,396.9,25.68,9.7 -8.64476,0,18.1,0,0.693,6.193,92.6,1.7912,24,666,20.2,396.9,15.17,13.8 -13.3598,0,18.1,0,0.693,5.887,94.7,1.7821,24,666,20.2,396.9,16.35,12.7 -8.71675,0,18.1,0,0.693,6.471,98.8,1.7257,24,666,20.2,391.98,17.12,13.1 -5.87205,0,18.1,0,0.693,6.405,96,1.6768,24,666,20.2,396.9,19.37,12.5 -7.67202,0,18.1,0,0.693,5.747,98.9,1.6334,24,666,20.2,393.1,19.92,8.5 -38.3518,0,18.1,0,0.693,5.453,100,1.4896,24,666,20.2,396.9,30.59,5 -9.91655,0,18.1,0,0.693,5.852,77.8,1.5004,24,666,20.2,338.16,29.97,6.3 -25.0461,0,18.1,0,0.693,5.987,100,1.5888,24,666,20.2,396.9,26.77,5.6 -14.2362,0,18.1,0,0.693,6.343,100,1.5741,24,666,20.2,396.9,20.32,7.2 -9.59571,0,18.1,0,0.693,6.404,100,1.639,24,666,20.2,376.11,20.31,12.1 -24.8017,0,18.1,0,0.693,5.349,96,1.7028,24,666,20.2,396.9,19.77,8.3 -41.5292,0,18.1,0,0.693,5.531,85.4,1.6074,24,666,20.2,329.46,27.38,8.5 -67.9208,0,18.1,0,0.693,5.683,100,1.4254,24,666,20.2,384.97,22.98,5 -20.7162,0,18.1,0,0.659,4.138,100,1.1781,24,666,20.2,370.22,23.34,11.9 -11.9511,0,18.1,0,0.659,5.608,100,1.2852,24,666,20.2,332.09,12.13,27.9 -7.40389,0,18.1,0,0.597,5.617,97.9,1.4547,24,666,20.2,314.64,26.4,17.2 -14.4383,0,18.1,0,0.597,6.852,100,1.4655,24,666,20.2,179.36,19.78,27.5 -51.1358,0,18.1,0,0.597,5.757,100,1.413,24,666,20.2,2.6,10.11,15 -14.0507,0,18.1,0,0.597,6.657,100,1.5275,24,666,20.2,35.05,21.22,17.2 -18.811,0,18.1,0,0.597,4.628,100,1.5539,24,666,20.2,28.79,34.37,17.9 -28.6558,0,18.1,0,0.597,5.155,100,1.5894,24,666,20.2,210.97,20.08,16.3 -45.7461,0,18.1,0,0.693,4.519,100,1.6582,24,666,20.2,88.27,36.98,7 -18.0846,0,18.1,0,0.679,6.434,100,1.8347,24,666,20.2,27.25,29.05,7.2 -10.8342,0,18.1,0,0.679,6.782,90.8,1.8195,24,666,20.2,21.57,25.79,7.5 -25.9406,0,18.1,0,0.679,5.304,89.1,1.6475,24,666,20.2,127.36,26.64,10.4 -73.5341,0,18.1,0,0.679,5.957,100,1.8026,24,666,20.2,16.45,20.62,8.8 -11.8123,0,18.1,0,0.718,6.824,76.5,1.794,24,666,20.2,48.45,22.74,8.4 -11.0874,0,18.1,0,0.718,6.411,100,1.8589,24,666,20.2,318.75,15.02,16.7 -7.02259,0,18.1,0,0.718,6.006,95.3,1.8746,24,666,20.2,319.98,15.7,14.2 -12.0482,0,18.1,0,0.614,5.648,87.6,1.9512,24,666,20.2,291.55,14.1,20.8 -7.05042,0,18.1,0,0.614,6.103,85.1,2.0218,24,666,20.2,2.52,23.29,13.4 -8.79212,0,18.1,0,0.584,5.565,70.6,2.0635,24,666,20.2,3.65,17.16,11.7 -15.8603,0,18.1,0,0.679,5.896,95.4,1.9096,24,666,20.2,7.68,24.39,8.3 -12.2472,0,18.1,0,0.584,5.837,59.7,1.9976,24,666,20.2,24.65,15.69,10.2 -37.6619,0,18.1,0,0.679,6.202,78.7,1.8629,24,666,20.2,18.82,14.52,10.9 -7.36711,0,18.1,0,0.679,6.193,78.1,1.9356,24,666,20.2,96.73,21.52,11 -9.33889,0,18.1,0,0.679,6.38,95.6,1.9682,24,666,20.2,60.72,24.08,9.5 -8.49213,0,18.1,0,0.584,6.348,86.1,2.0527,24,666,20.2,83.45,17.64,14.5 -10.0623,0,18.1,0,0.584,6.833,94.3,2.0882,24,666,20.2,81.33,19.69,14.1 -6.44405,0,18.1,0,0.584,6.425,74.8,2.2004,24,666,20.2,97.95,12.03,16.1 -5.58107,0,18.1,0,0.713,6.436,87.9,2.3158,24,666,20.2,100.19,16.22,14.3 -13.9134,0,18.1,0,0.713,6.208,95,2.2222,24,666,20.2,100.63,15.17,11.7 -11.1604,0,18.1,0,0.74,6.629,94.6,2.1247,24,666,20.2,109.85,23.27,13.4 -14.4208,0,18.1,0,0.74,6.461,93.3,2.0026,24,666,20.2,27.49,18.05,9.6 -15.1772,0,18.1,0,0.74,6.152,100,1.9142,24,666,20.2,9.32,26.45,8.7 -13.6781,0,18.1,0,0.74,5.935,87.9,1.8206,24,666,20.2,68.95,34.02,8.4 -9.39063,0,18.1,0,0.74,5.627,93.9,1.8172,24,666,20.2,396.9,22.88,12.8 -22.0511,0,18.1,0,0.74,5.818,92.4,1.8662,24,666,20.2,391.45,22.11,10.5 -9.72418,0,18.1,0,0.74,6.406,97.2,2.0651,24,666,20.2,385.96,19.52,17.1 -5.66637,0,18.1,0,0.74,6.219,100,2.0048,24,666,20.2,395.69,16.59,18.4 -9.96654,0,18.1,0,0.74,6.485,100,1.9784,24,666,20.2,386.73,18.85,15.4 -12.8023,0,18.1,0,0.74,5.854,96.6,1.8956,24,666,20.2,240.52,23.79,10.8 -10.6718,0,18.1,0,0.74,6.459,94.8,1.9879,24,666,20.2,43.06,23.98,11.8 -6.28807,0,18.1,0,0.74,6.341,96.4,2.072,24,666,20.2,318.01,17.79,14.9 -9.92485,0,18.1,0,0.74,6.251,96.6,2.198,24,666,20.2,388.52,16.44,12.6 -9.32909,0,18.1,0,0.713,6.185,98.7,2.2616,24,666,20.2,396.9,18.13,14.1 -7.52601,0,18.1,0,0.713,6.417,98.3,2.185,24,666,20.2,304.21,19.31,13 -6.71772,0,18.1,0,0.713,6.749,92.6,2.3236,24,666,20.2,0.32,17.44,13.4 -5.44114,0,18.1,0,0.713,6.655,98.2,2.3552,24,666,20.2,355.29,17.73,15.2 -5.09017,0,18.1,0,0.713,6.297,91.8,2.3682,24,666,20.2,385.09,17.27,16.1 -8.24809,0,18.1,0,0.713,7.393,99.3,2.4527,24,666,20.2,375.87,16.74,17.8 -9.51363,0,18.1,0,0.713,6.728,94.1,2.4961,24,666,20.2,6.68,18.71,14.9 -4.75237,0,18.1,0,0.713,6.525,86.5,2.4358,24,666,20.2,50.92,18.13,14.1 -4.66883,0,18.1,0,0.713,5.976,87.9,2.5806,24,666,20.2,10.48,19.01,12.7 -8.20058,0,18.1,0,0.713,5.936,80.3,2.7792,24,666,20.2,3.5,16.94,13.5 -7.75223,0,18.1,0,0.713,6.301,83.7,2.7831,24,666,20.2,272.21,16.23,14.9 -6.80117,0,18.1,0,0.713,6.081,84.4,2.7175,24,666,20.2,396.9,14.7,20 -4.81213,0,18.1,0,0.713,6.701,90,2.5975,24,666,20.2,255.23,16.42,16.4 -3.69311,0,18.1,0,0.713,6.376,88.4,2.5671,24,666,20.2,391.43,14.65,17.7 -6.65492,0,18.1,0,0.713,6.317,83,2.7344,24,666,20.2,396.9,13.99,19.5 -5.82115,0,18.1,0,0.713,6.513,89.9,2.8016,24,666,20.2,393.82,10.29,20.2 -7.83932,0,18.1,0,0.655,6.209,65.4,2.9634,24,666,20.2,396.9,13.22,21.4 -3.1636,0,18.1,0,0.655,5.759,48.2,3.0665,24,666,20.2,334.4,14.13,19.9 -3.77498,0,18.1,0,0.655,5.952,84.7,2.8715,24,666,20.2,22.01,17.15,19 -4.42228,0,18.1,0,0.584,6.003,94.5,2.5403,24,666,20.2,331.29,21.32,19.1 -15.5757,0,18.1,0,0.58,5.926,71,2.9084,24,666,20.2,368.74,18.13,19.1 -13.0751,0,18.1,0,0.58,5.713,56.7,2.8237,24,666,20.2,396.9,14.76,20.1 -4.34879,0,18.1,0,0.58,6.167,84,3.0334,24,666,20.2,396.9,16.29,19.9 -4.03841,0,18.1,0,0.532,6.229,90.7,3.0993,24,666,20.2,395.33,12.87,19.6 -3.56868,0,18.1,0,0.58,6.437,75,2.8965,24,666,20.2,393.37,14.36,23.2 -4.64689,0,18.1,0,0.614,6.98,67.6,2.5329,24,666,20.2,374.68,11.66,29.8 -8.05579,0,18.1,0,0.584,5.427,95.4,2.4298,24,666,20.2,352.58,18.14,13.8 -6.39312,0,18.1,0,0.584,6.162,97.4,2.206,24,666,20.2,302.76,24.1,13.3 -4.87141,0,18.1,0,0.614,6.484,93.6,2.3053,24,666,20.2,396.21,18.68,16.7 -15.0234,0,18.1,0,0.614,5.304,97.3,2.1007,24,666,20.2,349.48,24.91,12 -10.233,0,18.1,0,0.614,6.185,96.7,2.1705,24,666,20.2,379.7,18.03,14.6 -14.3337,0,18.1,0,0.614,6.229,88,1.9512,24,666,20.2,383.32,13.11,21.4 -5.82401,0,18.1,0,0.532,6.242,64.7,3.4242,24,666,20.2,396.9,10.74,23 -5.70818,0,18.1,0,0.532,6.75,74.9,3.3317,24,666,20.2,393.07,7.74,23.7 -5.73116,0,18.1,0,0.532,7.061,77,3.4106,24,666,20.2,395.28,7.01,25 -2.81838,0,18.1,0,0.532,5.762,40.3,4.0983,24,666,20.2,392.92,10.42,21.8 -2.37857,0,18.1,0,0.583,5.871,41.9,3.724,24,666,20.2,370.73,13.34,20.6 -3.67367,0,18.1,0,0.583,6.312,51.9,3.9917,24,666,20.2,388.62,10.58,21.2 -5.69175,0,18.1,0,0.583,6.114,79.8,3.5459,24,666,20.2,392.68,14.98,19.1 -4.83567,0,18.1,0,0.583,5.905,53.2,3.1523,24,666,20.2,388.22,11.45,20.6 -0.15086,0,27.74,0,0.609,5.454,92.7,1.8209,4,711,20.1,395.09,18.06,15.2 -0.18337,0,27.74,0,0.609,5.414,98.3,1.7554,4,711,20.1,344.05,23.97,7 -0.20746,0,27.74,0,0.609,5.093,98,1.8226,4,711,20.1,318.43,29.68,8.1 -0.10574,0,27.74,0,0.609,5.983,98.8,1.8681,4,711,20.1,390.11,18.07,13.6 -0.11132,0,27.74,0,0.609,5.983,83.5,2.1099,4,711,20.1,396.9,13.35,20.1 -0.17331,0,9.69,0,0.585,5.707,54,2.3817,6,391,19.2,396.9,12.01,21.8 -0.27957,0,9.69,0,0.585,5.926,42.6,2.3817,6,391,19.2,396.9,13.59,24.5 -0.17899,0,9.69,0,0.585,5.67,28.8,2.7986,6,391,19.2,393.29,17.6,23.1 -0.2896,0,9.69,0,0.585,5.39,72.9,2.7986,6,391,19.2,396.9,21.14,19.7 -0.26838,0,9.69,0,0.585,5.794,70.6,2.8927,6,391,19.2,396.9,14.1,18.3 -0.23912,0,9.69,0,0.585,6.019,65.3,2.4091,6,391,19.2,396.9,12.92,21.2 -0.17783,0,9.69,0,0.585,5.569,73.5,2.3999,6,391,19.2,395.77,15.1,17.5 -0.22438,0,9.69,0,0.585,6.027,79.7,2.4982,6,391,19.2,396.9,14.33,16.8 -0.06263,0,11.93,0,0.573,6.593,69.1,2.4786,1,273,21,391.99,9.67,22.4 -0.04527,0,11.93,0,0.573,6.12,76.7,2.2875,1,273,21,396.9,9.08,20.6 -0.06076,0,11.93,0,0.573,6.976,91,2.1675,1,273,21,396.9,5.64,23.9 -0.10959,0,11.93,0,0.573,6.794,89.3,2.3889,1,273,21,393.45,6.48,22 -0.04741,0,11.93,0,0.573,6.03,80.8,2.505,1,273,21,396.9,7.88,11.9 diff --git a/sklearn/decomposition/tests/test_incremental_pca.py b/sklearn/decomposition/tests/test_incremental_pca.py index 6bca13d0ad627..c4ea1c222901c 100644 --- a/sklearn/decomposition/tests/test_incremental_pca.py +++ b/sklearn/decomposition/tests/test_incremental_pca.py @@ -87,9 +87,9 @@ def test_incremental_pca_sparse(sparse_container): ipca.partial_fit(X_sparse) -def test_incremental_pca_check_projection(): +def test_incremental_pca_check_projection(global_random_seed): # Test that the projection of data is correct. - rng = np.random.RandomState(1999) + rng = np.random.RandomState(global_random_seed) n, p = 100, 3 X = rng.randn(n, p) * 0.1 X[:10] += np.array([3, 4, 5]) @@ -108,9 +108,9 @@ def test_incremental_pca_check_projection(): assert_almost_equal(np.abs(Yt[0][0]), 1.0, 1) -def test_incremental_pca_inverse(): +def test_incremental_pca_inverse(global_random_seed): # Test that the projection of data can be inverted. - rng = np.random.RandomState(1999) + rng = np.random.RandomState(global_random_seed) n, p = 50, 3 X = rng.randn(n, p) # spherical data X[:, 1] *= 0.00001 # make middle component relatively small @@ -217,9 +217,9 @@ def test_incremental_pca_num_features_change(): ipca.partial_fit(X2) -def test_incremental_pca_batch_signs(): +def test_incremental_pca_batch_signs(global_random_seed): # Test that components_ sign is stable over batch sizes. - rng = np.random.RandomState(1999) + rng = np.random.RandomState(global_random_seed) n_samples = 100 n_features = 3 X = rng.randn(n_samples, n_features) @@ -254,9 +254,9 @@ def test_incremental_pca_partial_fit_small_batch(): assert_allclose(pca.components_, pipca.components_, atol=1e-3) -def test_incremental_pca_batch_values(): +def test_incremental_pca_batch_values(global_random_seed): # Test that components_ values are stable over batch sizes. - rng = np.random.RandomState(1999) + rng = np.random.RandomState(global_random_seed) n_samples = 100 n_features = 3 X = rng.randn(n_samples, n_features) @@ -286,9 +286,9 @@ def test_incremental_pca_batch_rank(): assert_allclose_dense_sparse(components_i, components_j) -def test_incremental_pca_partial_fit(): +def test_incremental_pca_partial_fit(global_random_seed): # Test that fit and partial_fit get equivalent results. - rng = np.random.RandomState(1999) + rng = np.random.RandomState(global_random_seed) n, p = 50, 3 X = rng.randn(n, p) # spherical data X[:, 1] *= 0.00001 # make middle component relatively small @@ -316,9 +316,9 @@ def test_incremental_pca_against_pca_iris(): assert_almost_equal(np.abs(Y_pca), np.abs(Y_ipca), 1) -def test_incremental_pca_against_pca_random_data(): +def test_incremental_pca_against_pca_random_data(global_random_seed): # Test that IncrementalPCA and PCA are approximate (to a sign flip). - rng = np.random.RandomState(1999) + rng = np.random.RandomState(global_random_seed) n_samples = 100 n_features = 3 X = rng.randn(n_samples, n_features) + 5 * rng.rand(1, n_features) @@ -348,10 +348,10 @@ def test_explained_variances(): assert_almost_equal(pca.noise_variance_, ipca.noise_variance_, decimal=prec) -def test_singular_values(): +def test_singular_values(global_random_seed): # Check that the IncrementalPCA output has the correct singular values - rng = np.random.RandomState(0) + rng = np.random.RandomState(global_random_seed) n_samples = 1000 n_features = 100 @@ -360,7 +360,7 @@ def test_singular_values(): ) pca = PCA(n_components=10, svd_solver="full", random_state=rng).fit(X) - ipca = IncrementalPCA(n_components=10, batch_size=100).fit(X) + ipca = IncrementalPCA(n_components=10, batch_size=150).fit(X) assert_array_almost_equal(pca.singular_values_, ipca.singular_values_, 2) # Compare to the Frobenius norm @@ -382,7 +382,7 @@ def test_singular_values(): ) # Set the singular values and see what we get back - rng = np.random.RandomState(0) + rng = np.random.RandomState(global_random_seed) n_samples = 100 n_features = 110 diff --git a/sklearn/ensemble/_stacking.py b/sklearn/ensemble/_stacking.py index d7491be2f666f..2894d8f174c13 100644 --- a/sklearn/ensemble/_stacking.py +++ b/sklearn/ensemble/_stacking.py @@ -24,8 +24,8 @@ from ..model_selection import check_cv, cross_val_predict from ..preprocessing import LabelEncoder from ..utils import Bunch -from ..utils._estimator_html_repr import _VisualBlock from ..utils._param_validation import HasMethods, StrOptions +from ..utils._repr_html.estimator import _VisualBlock from ..utils.metadata_routing import ( MetadataRouter, MethodMapping, diff --git a/sklearn/ensemble/_voting.py b/sklearn/ensemble/_voting.py index e7e670dd869b6..369d3f0f5553e 100644 --- a/sklearn/ensemble/_voting.py +++ b/sklearn/ensemble/_voting.py @@ -24,8 +24,8 @@ from ..exceptions import NotFittedError from ..preprocessing import LabelEncoder from ..utils import Bunch -from ..utils._estimator_html_repr import _VisualBlock from ..utils._param_validation import StrOptions +from ..utils._repr_html.estimator import _VisualBlock from ..utils.metadata_routing import ( MetadataRouter, MethodMapping, diff --git a/sklearn/inspection/_plot/partial_dependence.py b/sklearn/inspection/_plot/partial_dependence.py index bf4975cdfd2d9..b31a5070b236b 100644 --- a/sklearn/inspection/_plot/partial_dependence.py +++ b/sklearn/inspection/_plot/partial_dependence.py @@ -25,20 +25,17 @@ class PartialDependenceDisplay: - """Partial Dependence Plot (PDP). - - This can also display individual partial dependencies which are often - referred to as: Individual Condition Expectation (ICE). + """Partial Dependence Plot (PDP) and Individual Conditional Expectation (ICE). It is recommended to use :func:`~sklearn.inspection.PartialDependenceDisplay.from_estimator` to create a - :class:`~sklearn.inspection.PartialDependenceDisplay`. All parameters are - stored as attributes. + :class:`~sklearn.inspection.PartialDependenceDisplay`. All parameters are stored + as attributes. For general information regarding `scikit-learn` visualization tools, see the :ref:`Visualization Guide `. For guidance on interpreting these plots, refer to the - :ref:`Partial Dependence and ICE plots `. + :ref:`Inspection Guide `. For an example on how to use this class, see the following example: :ref:`sphx_glr_auto_examples_miscellaneous_plot_partial_dependence_visualization_api.py`. @@ -280,17 +277,21 @@ def from_estimator( ): """Partial dependence (PD) and individual conditional expectation (ICE) plots. - Partial dependence plots, individual conditional expectation plots or an - overlay of both of them can be plotted by setting the ``kind`` - parameter. The ``len(features)`` plots are arranged in a grid with - ``n_cols`` columns. Two-way partial dependence plots are plotted as - contour plots. The deciles of the feature values will be shown with tick - marks on the x-axes for one-way plots, and on both axes for two-way - plots. - - Read more in - :ref:`sphx_glr_auto_examples_inspection_plot_partial_dependence.py` - and the :ref:`User Guide `. + Partial dependence plots, individual conditional expectation plots, or an + overlay of both can be plotted by setting the `kind` parameter. + This method generates one plot for each entry in `features`. The plots + are arranged in a grid with `n_cols` columns. For one-way partial + dependence plots, the deciles of the feature values are shown on the + x-axis. For two-way plots, the deciles are shown on both axes and PDPs + are contour plots. + + For general information regarding `scikit-learn` visualization tools, see + the :ref:`Visualization Guide `. + For guidance on interpreting these plots, refer to the + :ref:`Inspection Guide `. + + For an example on how to use this class method, see + :ref:`sphx_glr_auto_examples_inspection_plot_partial_dependence.py`. .. note:: diff --git a/sklearn/linear_model/_cd_fast.pyx b/sklearn/linear_model/_cd_fast.pyx index c4c530d907e26..ce598ebb011d2 100644 --- a/sklearn/linear_model/_cd_fast.pyx +++ b/sklearn/linear_model/_cd_fast.pyx @@ -83,6 +83,21 @@ cdef floating diff_abs_max(int n, const floating* a, floating* b) noexcept nogil return m +message_conv = ( + "Objective did not converge. You might want to increase " + "the number of iterations, check the scale of the " + "features or consider increasing regularisation." +) + + +message_ridge = ( + "Linear regression models with a zero l1 penalization " + "strength are more efficiently fitted using one of the " + "solvers implemented in " + "sklearn.linear_model.Ridge/RidgeCV instead." +) + + def enet_coordinate_descent( floating[::1] w, floating alpha, @@ -141,7 +156,7 @@ def enet_coordinate_descent( cdef floating R_norm2 cdef floating w_norm2 cdef floating l1_norm - cdef floating const + cdef floating const_ cdef floating A_norm2 cdef unsigned int ii cdef unsigned int n_iter = 0 @@ -227,19 +242,18 @@ def enet_coordinate_descent( w_norm2 = _dot(n_features, &w[0], 1, &w[0], 1) if (dual_norm_XtA > alpha): - const = alpha / dual_norm_XtA - A_norm2 = R_norm2 * (const ** 2) + const_ = alpha / dual_norm_XtA + A_norm2 = R_norm2 * (const_ ** 2) gap = 0.5 * (R_norm2 + A_norm2) else: - const = 1.0 + const_ = 1.0 gap = R_norm2 l1_norm = _asum(n_features, &w[0], 1) - # np.dot(R.T, y) gap += (alpha * l1_norm - - const * _dot(n_samples, &R[0], 1, &y[0], 1) - + 0.5 * beta * (1 + const ** 2) * (w_norm2)) + - const_ * _dot(n_samples, &R[0], 1, &y[0], 1) # np.dot(R.T, y) + + 0.5 * beta * (1 + const_ ** 2) * (w_norm2)) if gap < tol: # return if we reached desired tolerance @@ -249,18 +263,11 @@ def enet_coordinate_descent( # for/else, runs if for doesn't end with a `break` with gil: message = ( - "Objective did not converge. You might want to increase " - "the number of iterations, check the scale of the " - "features or consider increasing regularisation. " - f"Duality gap: {gap:.3e}, tolerance: {tol:.3e}" + message_conv + + f" Duality gap: {gap:.3e}, tolerance: {tol:.3e}" ) if alpha < np.finfo(np.float64).eps: - message += ( - " Linear regression models with null weight for the " - "l1 regularization term are more efficiently fitted " - "using one of the solvers implemented in " - "sklearn.linear_model.Ridge/RidgeCV instead." - ) + message += "\n" + message_ridge warnings.warn(message, ConvergenceWarning) return np.asarray(w), gap, tol, n_iter + 1 @@ -313,53 +320,50 @@ def sparse_enet_coordinate_descent( # that every calculation results as if we had rescaled y and X (and therefore also # X_mean) by sqrt(sample_weight) without actually calculating the square root. # We work with: - # yw = sample_weight + # yw = sample_weight * y # R = sample_weight * residual # norm_cols_X = np.sum(sample_weight * (X - X_mean)**2, axis=0) + if floating is float: + dtype = np.float32 + else: + dtype = np.float64 + # get the data information into easy vars cdef unsigned int n_samples = y.shape[0] cdef unsigned int n_features = w.shape[0] # compute norms of the columns of X - cdef unsigned int ii - cdef floating[:] norm_cols_X - - cdef unsigned int startptr = X_indptr[0] - cdef unsigned int endptr + cdef floating[:] norm_cols_X = np.zeros(n_features, dtype=dtype) # initial value of the residuals # R = y - Zw, weighted version R = sample_weight * (y - Zw) cdef floating[::1] R - cdef floating[::1] XtA + cdef floating[::1] XtA = np.empty(n_features, dtype=dtype) cdef const floating[::1] yw - if floating is float: - dtype = np.float32 - else: - dtype = np.float64 - - norm_cols_X = np.zeros(n_features, dtype=dtype) - XtA = np.zeros(n_features, dtype=dtype) - cdef floating tmp cdef floating w_ii cdef floating d_w_max cdef floating w_max cdef floating d_w_ii + cdef floating gap = tol + 1.0 + cdef floating d_w_tol = tol + cdef floating dual_norm_XtA cdef floating X_mean_ii cdef floating R_sum = 0.0 cdef floating R_norm2 cdef floating w_norm2 - cdef floating A_norm2 cdef floating l1_norm + cdef floating const_ + cdef floating A_norm2 cdef floating normalize_sum - cdef floating gap = tol + 1.0 - cdef floating d_w_tol = tol - cdef floating dual_norm_XtA + cdef unsigned int ii cdef unsigned int jj cdef unsigned int n_iter = 0 cdef unsigned int f_iter + cdef unsigned int startptr = X_indptr[0] + cdef unsigned int endptr cdef uint32_t rand_r_state_seed = rng.randint(0, RAND_R_MAX) cdef uint32_t* rand_r_state = &rand_r_state_seed cdef bint center = False @@ -380,6 +384,7 @@ def sparse_enet_coordinate_descent( center = True break + # R = y - np.dot(X, w) for ii in range(n_features): X_mean_ii = X_mean[ii] endptr = X_indptr[ii + 1] @@ -395,7 +400,9 @@ def sparse_enet_coordinate_descent( if center: for jj in range(n_samples): R[jj] += X_mean_ii * w_ii + R_sum += R[jj] else: + # R = sw * (y - np.dot(X, w)) for jj in range(startptr, endptr): tmp = sample_weight[X_indices[jj]] # second term will be subtracted by loop over range(n_samples) @@ -406,9 +413,14 @@ def sparse_enet_coordinate_descent( for jj in range(n_samples): normalize_sum += sample_weight[jj] * X_mean_ii ** 2 R[jj] += sample_weight[jj] * X_mean_ii * w_ii + R_sum += R[jj] norm_cols_X[ii] = normalize_sum startptr = endptr + # Note: No need to update R_sum from here on because the update terms cancel + # each other: w_ii * np.sum(X[:,ii] - X_mean[ii]) = 0. R_sum is only ever + # needed and calculated if X_mean is provided. + # tol *= np.dot(y, y) # with sample weights: tol *= y @ (sw * y) tol *= _dot(n_samples, &y[0], 1, &yw[0], 1) @@ -454,9 +466,6 @@ def sparse_enet_coordinate_descent( tmp += R[X_indices[jj]] * X_data[jj] if center: - R_sum = 0.0 - for jj in range(n_samples): - R_sum += R[jj] tmp -= R_sum * X_mean_ii if positive and tmp < 0.0: @@ -492,13 +501,8 @@ def sparse_enet_coordinate_descent( # the tolerance: check the duality gap as ultimate stopping # criterion - # sparse X.T / dense R dot product - if center: - R_sum = 0.0 - for jj in range(n_samples): - R_sum += R[jj] - # XtA = X.T @ R - beta * w + # sparse X.T / dense R dot product for ii in range(n_features): XtA[ii] = 0.0 for kk in range(X_indptr[ii], X_indptr[ii + 1]): @@ -526,21 +530,18 @@ def sparse_enet_coordinate_descent( # w_norm2 = np.dot(w, w) w_norm2 = _dot(n_features, &w[0], 1, &w[0], 1) if (dual_norm_XtA > alpha): - const = alpha / dual_norm_XtA - A_norm2 = R_norm2 * const**2 + const_ = alpha / dual_norm_XtA + A_norm2 = R_norm2 * const_**2 gap = 0.5 * (R_norm2 + A_norm2) else: - const = 1.0 + const_ = 1.0 gap = R_norm2 l1_norm = _asum(n_features, &w[0], 1) - gap += (alpha * l1_norm - const * _dot( - n_samples, - &R[0], 1, - &y[0], 1 - ) - + 0.5 * beta * (1 + const ** 2) * w_norm2) + gap += (alpha * l1_norm + - const_ * _dot(n_samples, &R[0], 1, &y[0], 1) # np.dot(R.T, y) + + 0.5 * beta * (1 + const_ ** 2) * w_norm2) if gap < tol: # return if we reached desired tolerance @@ -549,10 +550,13 @@ def sparse_enet_coordinate_descent( else: # for/else, runs if for doesn't end with a `break` with gil: - warnings.warn("Objective did not converge. You might want to " - "increase the number of iterations. Duality " - "gap: {}, tolerance: {}".format(gap, tol), - ConvergenceWarning) + message = ( + message_conv + + f" Duality gap: {gap:.3e}, tolerance: {tol:.3e}" + ) + if alpha < np.finfo(np.float64).eps: + message += "\n" + message_ridge + warnings.warn(message, ConvergenceWarning) return np.asarray(w), gap, tol, n_iter + 1 @@ -702,19 +706,19 @@ def enet_coordinate_descent_gram( w_norm2 = _dot(n_features, &w[0], 1, &w[0], 1) if (dual_norm_XtA > alpha): - const = alpha / dual_norm_XtA - A_norm2 = R_norm2 * (const ** 2) + const_ = alpha / dual_norm_XtA + A_norm2 = R_norm2 * (const_ ** 2) gap = 0.5 * (R_norm2 + A_norm2) else: - const = 1.0 + const_ = 1.0 gap = R_norm2 # The call to asum is equivalent to the L1 norm of w gap += ( alpha * _asum(n_features, &w[0], 1) - - const * y_norm2 - + const * q_dot_w - + 0.5 * beta * (1 + const ** 2) * w_norm2 + - const_ * y_norm2 + + const_ * q_dot_w + + 0.5 * beta * (1 + const_ ** 2) * w_norm2 ) if gap < tol: @@ -724,10 +728,11 @@ def enet_coordinate_descent_gram( else: # for/else, runs if for doesn't end with a `break` with gil: - warnings.warn("Objective did not converge. You might want to " - "increase the number of iterations. Duality " - "gap: {}, tolerance: {}".format(gap, tol), - ConvergenceWarning) + message = ( + message_conv + + f" Duality gap: {gap:.3e}, tolerance: {tol:.3e}" + ) + warnings.warn(message, ConvergenceWarning) return np.asarray(w), gap, tol, n_iter + 1 @@ -921,11 +926,11 @@ def enet_coordinate_descent_multi_task( R_norm = _nrm2(n_samples * n_tasks, &R[0, 0], 1) w_norm = _nrm2(n_features * n_tasks, &W[0, 0], 1) if (dual_norm_XtA > l1_reg): - const = l1_reg / dual_norm_XtA - A_norm = R_norm * const + const_ = l1_reg / dual_norm_XtA + A_norm = R_norm * const_ gap = 0.5 * (R_norm ** 2 + A_norm ** 2) else: - const = 1.0 + const_ = 1.0 gap = R_norm ** 2 # ry_sum = np.sum(R * y) @@ -938,8 +943,8 @@ def enet_coordinate_descent_multi_task( gap += ( l1_reg * l21_norm - - const * ry_sum - + 0.5 * l2_reg * (1 + const ** 2) * (w_norm ** 2) + - const_ * ry_sum + + 0.5 * l2_reg * (1 + const_ ** 2) * (w_norm ** 2) ) if gap <= tol: @@ -948,9 +953,10 @@ def enet_coordinate_descent_multi_task( else: # for/else, runs if for doesn't end with a `break` with gil: - warnings.warn("Objective did not converge. You might want to " - "increase the number of iterations. Duality " - "gap: {}, tolerance: {}".format(gap, tol), - ConvergenceWarning) + message = ( + message_conv + + f" Duality gap: {gap:.3e}, tolerance: {tol:.3e}" + ) + warnings.warn(message, ConvergenceWarning) return np.asarray(W), gap, tol, n_iter + 1 diff --git a/sklearn/linear_model/_glm/_newton_solver.py b/sklearn/linear_model/_glm/_newton_solver.py index d7c8ed8f0943d..c5c940bed6c39 100644 --- a/sklearn/linear_model/_glm/_newton_solver.py +++ b/sklearn/linear_model/_glm/_newton_solver.py @@ -178,13 +178,14 @@ def fallback_lbfgs_solve(self, X, y, sample_weight): - self.coef - self.converged """ + max_iter = self.max_iter - self.iteration opt_res = scipy.optimize.minimize( self.linear_loss.loss_gradient, self.coef, method="L-BFGS-B", jac=True, options={ - "maxiter": self.max_iter - self.iteration, + "maxiter": max_iter, "maxls": 50, # default is 20 "iprint": self.verbose - 1, "gtol": self.tol, @@ -192,7 +193,7 @@ def fallback_lbfgs_solve(self, X, y, sample_weight): }, args=(X, y, sample_weight, self.l2_reg_strength, self.n_threads), ) - self.iteration += _check_optimize_result("lbfgs", opt_res) + self.iteration += _check_optimize_result("lbfgs", opt_res, max_iter=max_iter) self.coef = opt_res.x self.converged = opt_res.status == 0 diff --git a/sklearn/linear_model/_glm/glm.py b/sklearn/linear_model/_glm/glm.py index c9e10c6378bac..7f138f420dc36 100644 --- a/sklearn/linear_model/_glm/glm.py +++ b/sklearn/linear_model/_glm/glm.py @@ -282,7 +282,9 @@ def fit(self, X, y, sample_weight=None): }, args=(X, y, sample_weight, l2_reg_strength, n_threads), ) - self.n_iter_ = _check_optimize_result("lbfgs", opt_res) + self.n_iter_ = _check_optimize_result( + "lbfgs", opt_res, max_iter=self.max_iter + ) coef = opt_res.x elif self.solver == "newton-cholesky": sol = NewtonCholeskySolver( diff --git a/sklearn/linear_model/_logistic.py b/sklearn/linear_model/_logistic.py index 89a17b7fffe0d..f0c97268c612d 100644 --- a/sklearn/linear_model/_logistic.py +++ b/sklearn/linear_model/_logistic.py @@ -337,7 +337,7 @@ def _logistic_regression_path( else: if solver in ["sag", "saga", "lbfgs", "newton-cg", "newton-cholesky"]: - # SAG, lbfgs, newton-cg and newton-cg multinomial solvers need + # SAG, lbfgs, newton-cg and newton-cholesky multinomial solvers need # LabelEncoder, not LabelBinarizer, i.e. y as a 1d-array of integers. # LabelEncoder also saves memory compared to LabelBinarizer, especially # when n_classes is large. @@ -837,9 +837,9 @@ class LogisticRegression(LinearClassifierMixin, SparseCoefMixin, BaseEstimator): the L2 penalty. The Elastic-Net regularization is only supported by the 'saga' solver. - For :term:`multiclass` problems, only 'newton-cg', 'sag', 'saga' and 'lbfgs' - handle multinomial loss. 'liblinear' and 'newton-cholesky' only handle binary - classification but can be extended to handle multiclass by using + For :term:`multiclass` problems, all solvers but 'liblinear' optimize the + (penalized) multinomial loss. 'liblinear' only handle binary classification but can + be extended to handle multiclass by using :class:`~sklearn.multiclass.OneVsRestClassifier`. Read more in the :ref:`User Guide `. @@ -957,13 +957,14 @@ class LogisticRegression(LinearClassifierMixin, SparseCoefMixin, BaseEstimator): summarizing solver/penalty supports. .. versionadded:: 0.17 - Stochastic Average Gradient descent solver. + Stochastic Average Gradient (SAG) descent solver. Multinomial support in + version 0.18. .. versionadded:: 0.19 SAGA solver. .. versionchanged:: 0.22 - The default solver changed from 'liblinear' to 'lbfgs' in 0.22. + The default solver changed from 'liblinear' to 'lbfgs' in 0.22. .. versionadded:: 1.2 - newton-cholesky solver. + newton-cholesky solver. Multinomial support in version 1.6. max_iter : int, default=100 Maximum number of iterations taken for the solvers to converge. @@ -1597,11 +1598,12 @@ class LogisticRegressionCV(LogisticRegression, LinearClassifierMixin, BaseEstima a scaler from :mod:`sklearn.preprocessing`. .. versionadded:: 0.17 - Stochastic Average Gradient descent solver. + Stochastic Average Gradient (SAG) descent solver. Multinomial support in + version 0.18. .. versionadded:: 0.19 SAGA solver. .. versionadded:: 1.2 - newton-cholesky solver. + newton-cholesky solver. Multinomial support in version 1.6. tol : float, default=1e-4 Tolerance for stopping criteria. diff --git a/sklearn/linear_model/tests/test_logistic.py b/sklearn/linear_model/tests/test_logistic.py index bbb291facdaf9..e8e41a25c6e2b 100644 --- a/sklearn/linear_model/tests/test_logistic.py +++ b/sklearn/linear_model/tests/test_logistic.py @@ -444,7 +444,7 @@ def test_logistic_regression_path_convergence_fail(): assert len(record) == 1 warn_msg = record[0].message.args[0] - assert "lbfgs failed to converge" in warn_msg + assert "lbfgs failed to converge after 1 iteration(s)" in warn_msg assert "Increase the number of iterations" in warn_msg assert "scale the data" in warn_msg assert "linear_model.html#logistic-regression" in warn_msg diff --git a/sklearn/linear_model/tests/test_ridge.py b/sklearn/linear_model/tests/test_ridge.py index 60b8a8bb3e144..24515195fb7cc 100644 --- a/sklearn/linear_model/tests/test_ridge.py +++ b/sklearn/linear_model/tests/test_ridge.py @@ -750,9 +750,8 @@ def _make_sparse_offset_regression( "n_samples,dtype,proportion_nonzero", [(20, "float32", 0.1), (40, "float32", 1.0), (20, "float64", 0.2)], ) -@pytest.mark.parametrize("seed", np.arange(3)) def test_solver_consistency( - solver, proportion_nonzero, n_samples, dtype, sparse_container, seed + solver, proportion_nonzero, n_samples, dtype, sparse_container, global_random_seed ): alpha = 1.0 noise = 50.0 if proportion_nonzero > 0.9 else 500.0 @@ -761,10 +760,9 @@ def test_solver_consistency( n_features=30, proportion_nonzero=proportion_nonzero, noise=noise, - random_state=seed, + random_state=global_random_seed, n_samples=n_samples, ) - # Manually scale the data to avoid pathological cases. We use # minmax_scale to deal with the sparse case without breaking # the sparsity pattern. @@ -778,7 +776,21 @@ def test_solver_consistency( if solver == "ridgecv": ridge = RidgeCV(alphas=[alpha]) else: - ridge = Ridge(solver=solver, tol=1e-10, alpha=alpha) + if solver.startswith("sag"): + # Avoid ConvergenceWarning for sag and saga solvers. + tol = 1e-7 + max_iter = 100_000 + else: + tol = 1e-10 + max_iter = None + + ridge = Ridge( + alpha=alpha, + solver=solver, + max_iter=max_iter, + tol=tol, + random_state=global_random_seed, + ) ridge.fit(X, y) assert_allclose(ridge.coef_, svd_ridge.coef_, atol=1e-3, rtol=1e-3) assert_allclose(ridge.intercept_, svd_ridge.intercept_, atol=1e-3, rtol=1e-3) diff --git a/sklearn/meson.build b/sklearn/meson.build index 93de0c18d99f9..30feb944029d3 100644 --- a/sklearn/meson.build +++ b/sklearn/meson.build @@ -219,7 +219,7 @@ extensions = ['_isotonic'] py.extension_module( '_isotonic', - '_isotonic.pyx', + cython_gen.process('_isotonic.pyx'), cython_args: cython_args, install: true, subdir: 'sklearn', diff --git a/sklearn/metrics/_classification.py b/sklearn/metrics/_classification.py index 65cbfbad6f01f..2e31320ddb1f4 100644 --- a/sklearn/metrics/_classification.py +++ b/sklearn/metrics/_classification.py @@ -1071,9 +1071,10 @@ def jaccard_score( numerator = MCM[:, 1, 1] denominator = MCM[:, 1, 1] + MCM[:, 0, 1] + MCM[:, 1, 0] + xp, _, device_ = get_namespace_and_device(y_true, y_pred) if average == "micro": - numerator = np.array([numerator.sum()]) - denominator = np.array([denominator.sum()]) + numerator = xp.asarray(xp.sum(numerator, keepdims=True), device=device_) + denominator = xp.asarray(xp.sum(denominator, keepdims=True), device=device_) jaccard = _prf_divide( numerator, @@ -1088,14 +1089,14 @@ def jaccard_score( return jaccard if average == "weighted": weights = MCM[:, 1, 0] + MCM[:, 1, 1] - if not np.any(weights): + if not xp.any(weights): # numerator is 0, and warning should have already been issued weights = None elif average == "samples" and sample_weight is not None: weights = sample_weight else: weights = None - return float(np.average(jaccard, weights=weights)) + return float(_average(jaccard, weights=weights, xp=xp)) @validate_params( diff --git a/sklearn/metrics/_plot/confusion_matrix.py b/sklearn/metrics/_plot/confusion_matrix.py index 63a5382f3fa2b..cee515bebe08e 100644 --- a/sklearn/metrics/_plot/confusion_matrix.py +++ b/sklearn/metrics/_plot/confusion_matrix.py @@ -15,13 +15,16 @@ class ConfusionMatrixDisplay: """Confusion Matrix visualization. - It is recommend to use + It is recommended to use :func:`~sklearn.metrics.ConfusionMatrixDisplay.from_estimator` or :func:`~sklearn.metrics.ConfusionMatrixDisplay.from_predictions` to create a :class:`ConfusionMatrixDisplay`. All parameters are stored as attributes. - Read more in the :ref:`User Guide `. + For general information regarding `scikit-learn` visualization tools, see + the :ref:`Visualization Guide `. + For guidance on interpreting these plots, refer to the + :ref:`Model Evaluation Guide `. Parameters ---------- @@ -220,7 +223,10 @@ def from_estimator( ): """Plot Confusion Matrix given an estimator and some data. - Read more in the :ref:`User Guide `. + For general information regarding `scikit-learn` visualization tools, see + the :ref:`Visualization Guide `. + For guidance on interpreting these plots, refer to the + :ref:`Model Evaluation Guide `. .. versionadded:: 1.0 @@ -365,7 +371,10 @@ def from_predictions( ): """Plot Confusion Matrix given true and predicted labels. - Read more in the :ref:`User Guide `. + For general information regarding `scikit-learn` visualization tools, see + the :ref:`Visualization Guide `. + For guidance on interpreting these plots, refer to the + :ref:`Model Evaluation Guide `. .. versionadded:: 1.0 diff --git a/sklearn/metrics/_plot/det_curve.py b/sklearn/metrics/_plot/det_curve.py index f15fe0ae9e889..590b908d91723 100644 --- a/sklearn/metrics/_plot/det_curve.py +++ b/sklearn/metrics/_plot/det_curve.py @@ -11,11 +11,14 @@ class DetCurveDisplay(_BinaryClassifierCurveDisplayMixin): """Detection Error Tradeoff (DET) curve visualization. - It is recommend to use :func:`~sklearn.metrics.DetCurveDisplay.from_estimator` + It is recommended to use :func:`~sklearn.metrics.DetCurveDisplay.from_estimator` or :func:`~sklearn.metrics.DetCurveDisplay.from_predictions` to create a visualizer. All parameters are stored as attributes. - Read more in the :ref:`User Guide `. + For general information regarding `scikit-learn` visualization tools, see + the :ref:`Visualization Guide `. + For guidance on interpreting these plots, refer to the + :ref:`Model Evaluation Guide `. .. versionadded:: 0.24 @@ -96,7 +99,10 @@ def from_estimator( ): """Plot DET curve given an estimator and data. - Read more in the :ref:`User Guide `. + For general information regarding `scikit-learn` visualization tools, see + the :ref:`Visualization Guide `. + For guidance on interpreting these plots, refer to the + :ref:`Model Evaluation Guide `. .. versionadded:: 1.0 @@ -207,7 +213,10 @@ def from_predictions( ): """Plot the DET curve given the true and predicted labels. - Read more in the :ref:`User Guide `. + For general information regarding `scikit-learn` visualization tools, see + the :ref:`Visualization Guide `. + For guidance on interpreting these plots, refer to the + :ref:`Model Evaluation Guide `. .. versionadded:: 1.0 diff --git a/sklearn/metrics/_plot/precision_recall_curve.py b/sklearn/metrics/_plot/precision_recall_curve.py index 286fc26d0e208..30dd1fba08761 100644 --- a/sklearn/metrics/_plot/precision_recall_curve.py +++ b/sklearn/metrics/_plot/precision_recall_curve.py @@ -14,7 +14,7 @@ class PrecisionRecallDisplay(_BinaryClassifierCurveDisplayMixin): """Precision Recall visualization. - It is recommend to use + It is recommended to use :func:`~sklearn.metrics.PrecisionRecallDisplay.from_estimator` or :func:`~sklearn.metrics.PrecisionRecallDisplay.from_predictions` to create a :class:`~sklearn.metrics.PrecisionRecallDisplay`. All parameters are diff --git a/sklearn/metrics/_plot/roc_curve.py b/sklearn/metrics/_plot/roc_curve.py index 4a198080e0d0a..439c6cfcdd996 100644 --- a/sklearn/metrics/_plot/roc_curve.py +++ b/sklearn/metrics/_plot/roc_curve.py @@ -1,22 +1,31 @@ # Authors: The scikit-learn developers # SPDX-License-Identifier: BSD-3-Clause + import warnings +import numpy as np + +from ...utils import _safe_indexing from ...utils._plotting import ( _BinaryClassifierCurveDisplayMixin, + _check_param_lengths, + _convert_to_list_leaving_none, + _deprecate_estimator_name, _despine, _validate_style_kwargs, ) +from ...utils._response import _get_response_values_binary from .._ranking import auc, roc_curve class RocCurveDisplay(_BinaryClassifierCurveDisplayMixin): """ROC Curve visualization. - It is recommend to use + It is recommended to use :func:`~sklearn.metrics.RocCurveDisplay.from_estimator` or - :func:`~sklearn.metrics.RocCurveDisplay.from_predictions` to create + :func:`~sklearn.metrics.RocCurveDisplay.from_predictions` or + :func:`~sklearn.metrics.RocCurveDisplay.from_cv_results` to create a :class:`~sklearn.metrics.RocCurveDisplay`. All parameters are stored as attributes. @@ -27,17 +36,40 @@ class RocCurveDisplay(_BinaryClassifierCurveDisplayMixin): Parameters ---------- - fpr : ndarray - False positive rate. + fpr : ndarray or list of ndarrays + False positive rates. Each ndarray should contain values for a single curve. + If plotting multiple curves, list should be of same length as `tpr`. - tpr : ndarray - True positive rate. + .. versionchanged:: 1.7 + Now accepts a list for plotting multiple curves. - roc_auc : float, default=None - Area under ROC curve. If None, the roc_auc score is not shown. + tpr : ndarray or list of ndarrays + True positive rates. Each ndarray should contain values for a single curve. + If plotting multiple curves, list should be of same length as `fpr`. - estimator_name : str, default=None - Name of estimator. If None, the estimator name is not shown. + .. versionchanged:: 1.7 + Now accepts a list for plotting multiple curves. + + roc_auc : float or list of floats, default=None + Area under ROC curve, used for labeling each curve in the legend. + If plotting multiple curves, should be a list of the same length as `fpr` + and `tpr`. If `None`, ROC AUC scores are not shown in the legend. + + .. versionchanged:: 1.7 + Now accepts a list for plotting multiple curves. + + name : str or list of str, default=None + Name for labeling legend entries. The number of legend entries + is determined by the `curve_kwargs` passed to `plot`. + To label each curve, provide a list of strings. To avoid labeling + individual curves that have the same appearance, this cannot be used in + conjunction with `curve_kwargs` being a dictionary or None. If a + string is provided, it will be used to either label the single legend entry + or if there are multiple legend entries, label each individual curve with + the same name. If `None`, set to `name` provided at `RocCurveDisplay` + initialization. If still `None`, no name is shown in the legend. + + .. versionadded:: 1.7 pos_label : int, float, bool or str, default=None The class considered as the positive class when computing the roc auc @@ -46,10 +78,21 @@ class RocCurveDisplay(_BinaryClassifierCurveDisplayMixin): .. versionadded:: 0.24 + estimator_name : str, default=None + Name of estimator. If None, the estimator name is not shown. + + .. deprecated:: 1.7 + `estimator_name` is deprecated and will be removed in 1.9. Use `name` + instead. + Attributes ---------- - line_ : matplotlib Artist - ROC Curve. + line_ : matplotlib Artist or list of matplotlib Artists + ROC Curves. + + .. versionchanged:: 1.7 + This attribute can now be a list of Artists, for when multiple curves + are plotted. chance_level_ : matplotlib Artist or None The chance level line. It is `None` if the chance level is not plotted. @@ -81,24 +124,52 @@ class RocCurveDisplay(_BinaryClassifierCurveDisplayMixin): >>> fpr, tpr, thresholds = metrics.roc_curve(y_true, y_score) >>> roc_auc = metrics.auc(fpr, tpr) >>> display = metrics.RocCurveDisplay(fpr=fpr, tpr=tpr, roc_auc=roc_auc, - ... estimator_name='example estimator') + ... name='example estimator') >>> display.plot() <...> >>> plt.show() """ - def __init__(self, *, fpr, tpr, roc_auc=None, estimator_name=None, pos_label=None): - self.estimator_name = estimator_name + def __init__( + self, + *, + fpr, + tpr, + roc_auc=None, + name=None, + pos_label=None, + estimator_name="deprecated", + ): self.fpr = fpr self.tpr = tpr self.roc_auc = roc_auc + self.name = _deprecate_estimator_name(estimator_name, name, "1.7") self.pos_label = pos_label + def _validate_plot_params(self, *, ax, name): + self.ax_, self.figure_, name = super()._validate_plot_params(ax=ax, name=name) + + fpr = _convert_to_list_leaving_none(self.fpr) + tpr = _convert_to_list_leaving_none(self.tpr) + roc_auc = _convert_to_list_leaving_none(self.roc_auc) + name = _convert_to_list_leaving_none(name) + + optional = {"self.roc_auc": roc_auc} + if isinstance(name, list) and len(name) != 1: + optional.update({"'name' (or self.name)": name}) + _check_param_lengths( + required={"self.fpr": fpr, "self.tpr": tpr}, + optional=optional, + class_name="RocCurveDisplay", + ) + return fpr, tpr, roc_auc, name + def plot( self, ax=None, *, name=None, + curve_kwargs=None, plot_chance_level=False, chance_level_kw=None, despine=False, @@ -106,17 +177,36 @@ def plot( ): """Plot visualization. - Extra keyword arguments will be passed to matplotlib's ``plot``. - Parameters ---------- ax : matplotlib axes, default=None Axes object to plot on. If `None`, a new figure and axes is created. - name : str, default=None - Name of ROC Curve for labeling. If `None`, use `estimator_name` if - not `None`, otherwise no labeling is shown. + name : str or list of str, default=None + Name for labeling legend entries. The number of legend entries + is determined by `curve_kwargs`. + To label each curve, provide a list of strings. To avoid labeling + individual curves that have the same appearance, this cannot be used in + conjunction with `curve_kwargs` being a dictionary or None. If a + string is provided, it will be used to either label the single legend entry + or if there are multiple legend entries, label each individual curve with + the same name. If `None`, set to `name` provided at `RocCurveDisplay` + initialization. If still `None`, no name is shown in the legend. + + .. versionadded:: 1.7 + + curve_kwargs : dict or list of dict, default=None + Keywords arguments to be passed to matplotlib's `plot` function + to draw individual ROC curves. For single curve plotting, should be + a dictionary. For multi-curve plotting, if a list is provided the + parameters are applied to the ROC curves of each CV fold + sequentially and a legend entry is added for each curve. + If a single dictionary is provided, the same parameters are applied + to all ROC curves and a single legend entry for all curves is added, + labeled with the mean ROC AUC score. + + .. versionadded:: 1.7 plot_chance_level : bool, default=False Whether to plot the chance level. @@ -137,22 +227,34 @@ def plot( **kwargs : dict Keyword arguments to be passed to matplotlib's `plot`. + .. deprecated:: 1.7 + kwargs is deprecated and will be removed in 1.9. Pass matplotlib + arguments to `curve_kwargs` as a dictionary instead. + Returns ------- display : :class:`~sklearn.metrics.RocCurveDisplay` Object that stores computed values. """ - self.ax_, self.figure_, name = self._validate_plot_params(ax=ax, name=name) - - default_line_kwargs = {} - if self.roc_auc is not None and name is not None: - default_line_kwargs["label"] = f"{name} (AUC = {self.roc_auc:0.2f})" - elif self.roc_auc is not None: - default_line_kwargs["label"] = f"AUC = {self.roc_auc:0.2f}" - elif name is not None: - default_line_kwargs["label"] = name - - line_kwargs = _validate_style_kwargs(default_line_kwargs, kwargs) + fpr, tpr, roc_auc, name = self._validate_plot_params(ax=ax, name=name) + n_curves = len(fpr) + if not isinstance(curve_kwargs, list) and n_curves > 1: + if roc_auc: + legend_metric = {"mean": np.mean(roc_auc), "std": np.std(roc_auc)} + else: + legend_metric = {"mean": None, "std": None} + else: + roc_auc = roc_auc if roc_auc is not None else [None] * n_curves + legend_metric = {"metric": roc_auc} + + curve_kwargs = self._validate_curve_kwargs( + n_curves, + name, + legend_metric, + "AUC", + curve_kwargs=curve_kwargs, + **kwargs, + ) default_chance_level_line_kw = { "label": "Chance level (AUC = 0.5)", @@ -167,7 +269,13 @@ def plot( default_chance_level_line_kw, chance_level_kw ) - (self.line_,) = self.ax_.plot(self.fpr, self.tpr, **line_kwargs) + self.line_ = [] + for fpr, tpr, line_kw in zip(fpr, tpr, curve_kwargs): + self.line_.extend(self.ax_.plot(fpr, tpr, **line_kw)) + # Return single artist if only one curve is plotted + if len(self.line_) == 1: + self.line_ = self.line_[0] + info_pos_label = ( f" (Positive label: {self.pos_label})" if self.pos_label is not None else "" ) @@ -190,9 +298,8 @@ def plot( if despine: _despine(self.ax_) - if ( - line_kwargs.get("label") is not None - or chance_level_kw.get("label") is not None + if curve_kwargs[0].get("label") is not None or ( + plot_chance_level and chance_level_kw.get("label") is not None ): self.ax_.legend(loc="lower right") @@ -211,6 +318,7 @@ def from_estimator( pos_label=None, name=None, ax=None, + curve_kwargs=None, plot_chance_level=False, chance_level_kw=None, despine=False, @@ -252,8 +360,8 @@ def from_estimator( :term:`decision_function` is tried next. pos_label : int, float, bool or str, default=None - The class considered as the positive class when computing the roc auc - metrics. By default, `estimators.classes_[1]` is considered + The class considered as the positive class when computing the ROC AUC. + By default, `estimators.classes_[1]` is considered as the positive class. name : str, default=None @@ -263,6 +371,11 @@ def from_estimator( ax : matplotlib axes, default=None Axes object to plot on. If `None`, a new figure and axes is created. + curve_kwargs : dict, default=None + Keywords arguments to be passed to matplotlib's `plot` function. + + .. versionadded:: 1.7 + plot_chance_level : bool, default=False Whether to plot the chance level. @@ -282,6 +395,10 @@ def from_estimator( **kwargs : dict Keyword arguments to be passed to matplotlib's `plot`. + .. deprecated:: 1.7 + kwargs is deprecated and will be removed in 1.9. Pass matplotlib + arguments to `curve_kwargs` as a dictionary instead. + Returns ------- display : :class:`~sklearn.metrics.RocCurveDisplay` @@ -327,6 +444,7 @@ def from_estimator( name=name, ax=ax, pos_label=pos_label, + curve_kwargs=curve_kwargs, plot_chance_level=plot_chance_level, chance_level_kw=chance_level_kw, despine=despine, @@ -344,6 +462,7 @@ def from_predictions( pos_label=None, name=None, ax=None, + curve_kwargs=None, plot_chance_level=False, chance_level_kw=None, despine=False, @@ -382,18 +501,23 @@ def from_predictions( points. pos_label : int, float, bool or str, default=None - The label of the positive class. When `pos_label=None`, if `y_true` - is in {-1, 1} or {0, 1}, `pos_label` is set to 1, otherwise an - error will be raised. + The label of the positive class when computing the ROC AUC. + When `pos_label=None`, if `y_true` is in {-1, 1} or {0, 1}, `pos_label` + is set to 1, otherwise an error will be raised. name : str, default=None - Name of ROC curve for labeling. If `None`, name will be set to + Name of ROC curve for legend labeling. If `None`, name will be set to `"Classifier"`. ax : matplotlib axes, default=None Axes object to plot on. If `None`, a new figure and axes is created. + curve_kwargs : dict, default=None + Keywords arguments to be passed to matplotlib's `plot` function. + + .. versionadded:: 1.7 + plot_chance_level : bool, default=False Whether to plot the chance level. @@ -422,6 +546,10 @@ def from_predictions( **kwargs : dict Additional keywords arguments passed to matplotlib `plot` function. + .. deprecated:: 1.7 + kwargs is deprecated and will be removed in 1.9. Pass matplotlib + arguments to `curve_kwargs` as a dictionary instead. + Returns ------- display : :class:`~sklearn.metrics.RocCurveDisplay` @@ -485,15 +613,184 @@ def from_predictions( fpr=fpr, tpr=tpr, roc_auc=roc_auc, - estimator_name=name, + name=name, pos_label=pos_label_validated, ) return viz.plot( ax=ax, - name=name, + curve_kwargs=curve_kwargs, plot_chance_level=plot_chance_level, chance_level_kw=chance_level_kw, despine=despine, **kwargs, ) + + @classmethod + def from_cv_results( + cls, + cv_results, + X, + y, + *, + sample_weight=None, + drop_intermediate=True, + response_method="auto", + pos_label=None, + ax=None, + name=None, + curve_kwargs=None, + plot_chance_level=False, + chance_level_kwargs=None, + despine=False, + ): + """Create a multi-fold ROC curve display given cross-validation results. + + .. versionadded:: 1.7 + + Parameters + ---------- + cv_results : dict + Dictionary as returned by :func:`~sklearn.model_selection.cross_validate` + using `return_estimator=True` and `return_indices=True` (i.e., dictionary + should contain the keys "estimator" and "indices"). + + X : {array-like, sparse matrix} of shape (n_samples, n_features) + Input values. + + y : array-like of shape (n_samples,) + Target values. + + sample_weight : array-like of shape (n_samples,), default=None + Sample weights. + + drop_intermediate : bool, default=True + Whether to drop some suboptimal thresholds which would not appear + on a plotted ROC curve. This is useful in order to create lighter + ROC curves. + + response_method : {'predict_proba', 'decision_function', 'auto'} \ + default='auto' + Specifies whether to use :term:`predict_proba` or + :term:`decision_function` as the target response. If set to 'auto', + :term:`predict_proba` is tried first and if it does not exist + :term:`decision_function` is tried next. + + pos_label : int, float, bool or str, default=None + The class considered as the positive class when computing the ROC AUC + metrics. By default, `estimators.classes_[1]` is considered + as the positive class. + + ax : matplotlib axes, default=None + Axes object to plot on. If `None`, a new figure and axes is + created. + + name : str or list of str, default=None + Name for labeling legend entries. The number of legend entries + is determined by `curve_kwargs`. + To label each curve, provide a list of strings. To avoid labeling + individual curves that have the same appearance, this cannot be used in + conjunction with `curve_kwargs` being a dictionary or None. If a + string is provided, it will be used to either label the single legend entry + or if there are multiple legend entries, label each individual curve with + the same name. If `None`, no name is shown in the legend. + + curve_kwargs : dict or list of dict, default=None + Keywords arguments to be passed to matplotlib's `plot` function + to draw individual ROC curves. If a list is provided the + parameters are applied to the ROC curves of each CV fold + sequentially and a legend entry is added for each curve. + If a single dictionary is provided, the same parameters are applied + to all ROC curves and a single legend entry for all curves is added, + labeled with the mean ROC AUC score. + + plot_chance_level : bool, default=False + Whether to plot the chance level. + + chance_level_kwargs : dict, default=None + Keyword arguments to be passed to matplotlib's `plot` for rendering + the chance level line. + + despine : bool, default=False + Whether to remove the top and right spines from the plot. + + Returns + ------- + display : :class:`~sklearn.metrics.RocCurveDisplay` + The multi-fold ROC curve display. + + See Also + -------- + roc_curve : Compute Receiver operating characteristic (ROC) curve. + RocCurveDisplay.from_estimator : ROC Curve visualization given an + estimator and some data. + RocCurveDisplay.from_predictions : ROC Curve visualization given the + probabilities of scores of a classifier. + roc_auc_score : Compute the area under the ROC curve. + + Examples + -------- + >>> import matplotlib.pyplot as plt + >>> from sklearn.datasets import make_classification + >>> from sklearn.metrics import RocCurveDisplay + >>> from sklearn.model_selection import cross_validate + >>> from sklearn.svm import SVC + >>> X, y = make_classification(random_state=0) + >>> clf = SVC(random_state=0) + >>> cv_results = cross_validate( + ... clf, X, y, cv=3, return_estimator=True, return_indices=True) + >>> RocCurveDisplay.from_cv_results(cv_results, X, y) + <...> + >>> plt.show() + """ + pos_label_ = cls._validate_from_cv_results_params( + cv_results, + X, + y, + sample_weight=sample_weight, + pos_label=pos_label, + ) + + fpr_folds, tpr_folds, auc_folds = [], [], [] + for estimator, test_indices in zip( + cv_results["estimator"], cv_results["indices"]["test"] + ): + y_true = _safe_indexing(y, test_indices) + y_pred, _ = _get_response_values_binary( + estimator, + _safe_indexing(X, test_indices), + response_method=response_method, + pos_label=pos_label_, + ) + sample_weight_fold = ( + None + if sample_weight is None + else _safe_indexing(sample_weight, test_indices) + ) + fpr, tpr, _ = roc_curve( + y_true, + y_pred, + pos_label=pos_label_, + sample_weight=sample_weight_fold, + drop_intermediate=drop_intermediate, + ) + roc_auc = auc(fpr, tpr) + + fpr_folds.append(fpr) + tpr_folds.append(tpr) + auc_folds.append(roc_auc) + + viz = cls( + fpr=fpr_folds, + tpr=tpr_folds, + name=name, + roc_auc=auc_folds, + pos_label=pos_label_, + ) + return viz.plot( + ax=ax, + curve_kwargs=curve_kwargs, + plot_chance_level=plot_chance_level, + chance_level_kw=chance_level_kwargs, + despine=despine, + ) diff --git a/sklearn/metrics/_plot/tests/test_common_curve_display.py b/sklearn/metrics/_plot/tests/test_common_curve_display.py index 0014a73055e41..753f2a1e7319d 100644 --- a/sklearn/metrics/_plot/tests/test_common_curve_display.py +++ b/sklearn/metrics/_plot/tests/test_common_curve_display.py @@ -132,9 +132,7 @@ def fit(self, X, y): Display.from_estimator(clf, X, y, response_method=response_method) -@pytest.mark.parametrize( - "Display", [DetCurveDisplay, PrecisionRecallDisplay, RocCurveDisplay] -) +@pytest.mark.parametrize("Display", [DetCurveDisplay, PrecisionRecallDisplay]) @pytest.mark.parametrize("constructor_name", ["from_estimator", "from_predictions"]) def test_display_curve_estimator_name_multiple_calls( pyplot, @@ -166,6 +164,8 @@ def test_display_curve_estimator_name_multiple_calls( assert clf_name in disp.line_.get_label() +# TODO: remove this test once classes moved to using `name` instead of +# `estimator_name` @pytest.mark.parametrize( "clf", [ @@ -176,10 +176,8 @@ def test_display_curve_estimator_name_multiple_calls( ), ], ) -@pytest.mark.parametrize( - "Display", [DetCurveDisplay, PrecisionRecallDisplay, RocCurveDisplay] -) -def test_display_curve_not_fitted_errors(pyplot, data_binary, clf, Display): +@pytest.mark.parametrize("Display", [DetCurveDisplay, PrecisionRecallDisplay]) +def test_display_curve_not_fitted_errors_old_name(pyplot, data_binary, clf, Display): """Check that a proper error is raised when the classifier is not fitted.""" X, y = data_binary @@ -194,6 +192,31 @@ def test_display_curve_not_fitted_errors(pyplot, data_binary, clf, Display): assert disp.estimator_name == model.__class__.__name__ +@pytest.mark.parametrize( + "clf", + [ + LogisticRegression(), + make_pipeline(StandardScaler(), LogisticRegression()), + make_pipeline( + make_column_transformer((StandardScaler(), [0, 1])), LogisticRegression() + ), + ], +) +@pytest.mark.parametrize("Display", [RocCurveDisplay]) +def test_display_curve_not_fitted_errors(pyplot, data_binary, clf, Display): + """Check that a proper error is raised when the classifier is not fitted.""" + X, y = data_binary + # clone since we parametrize the test and the classifier will be fitted + # when testing the second and subsequent plotting function + model = clone(clf) + with pytest.raises(NotFittedError): + Display.from_estimator(model, X, y) + model.fit(X, y) + disp = Display.from_estimator(model, X, y) + assert model.__class__.__name__ in disp.line_.get_label() + assert disp.name == model.__class__.__name__ + + @pytest.mark.parametrize( "Display", [DetCurveDisplay, PrecisionRecallDisplay, RocCurveDisplay] ) diff --git a/sklearn/metrics/_plot/tests/test_roc_curve_display.py b/sklearn/metrics/_plot/tests/test_roc_curve_display.py index ca0d7155e7c2c..23fa2f2e3a5e6 100644 --- a/sklearn/metrics/_plot/tests/test_roc_curve_display.py +++ b/sklearn/metrics/_plot/tests/test_roc_curve_display.py @@ -1,3 +1,5 @@ +from collections.abc import Mapping + import numpy as np import pytest from numpy.testing import assert_allclose @@ -9,10 +11,11 @@ from sklearn.exceptions import NotFittedError from sklearn.linear_model import LogisticRegression from sklearn.metrics import RocCurveDisplay, auc, roc_curve -from sklearn.model_selection import train_test_split +from sklearn.model_selection import cross_validate, train_test_split from sklearn.pipeline import make_pipeline from sklearn.preprocessing import StandardScaler -from sklearn.utils import shuffle +from sklearn.utils import _safe_indexing, shuffle +from sklearn.utils._response import _get_response_values_binary @pytest.fixture(scope="module") @@ -29,6 +32,24 @@ def data_binary(): return X, y +def _check_figure_axes_and_labels(display, pos_label): + """Check mpl axes and figure defaults are correct.""" + import matplotlib as mpl + + assert isinstance(display.ax_, mpl.axes.Axes) + assert isinstance(display.figure_, mpl.figure.Figure) + assert display.ax_.get_adjustable() == "box" + assert display.ax_.get_aspect() in ("equal", 1.0) + assert display.ax_.get_xlim() == display.ax_.get_ylim() == (-0.01, 1.01) + + expected_pos_label = 1 if pos_label is None else pos_label + expected_ylabel = f"True Positive Rate (Positive label: {expected_pos_label})" + expected_xlabel = f"False Positive Rate (Positive label: {expected_pos_label})" + + assert display.ax_.get_ylabel() == expected_ylabel + assert display.ax_.get_xlabel() == expected_xlabel + + @pytest.mark.parametrize("response_method", ["predict_proba", "decision_function"]) @pytest.mark.parametrize("with_sample_weight", [True, False]) @pytest.mark.parametrize("drop_intermediate", [True, False]) @@ -50,7 +71,7 @@ def test_roc_curve_display_plotting( constructor_name, default_name, ): - """Check the overall plotting behaviour.""" + """Check the overall plotting behaviour for single curve.""" X, y = data_binary pos_label = None @@ -78,7 +99,7 @@ def test_roc_curve_display_plotting( sample_weight=sample_weight, drop_intermediate=drop_intermediate, pos_label=pos_label, - alpha=0.8, + curve_kwargs={"alpha": 0.8}, ) else: display = RocCurveDisplay.from_predictions( @@ -87,7 +108,7 @@ def test_roc_curve_display_plotting( sample_weight=sample_weight, drop_intermediate=drop_intermediate, pos_label=pos_label, - alpha=0.8, + curve_kwargs={"alpha": 0.8}, ) fpr, tpr, _ = roc_curve( @@ -102,27 +123,509 @@ def test_roc_curve_display_plotting( assert_allclose(display.fpr, fpr) assert_allclose(display.tpr, tpr) - assert display.estimator_name == default_name + assert display.name == default_name import matplotlib as mpl + _check_figure_axes_and_labels(display, pos_label) assert isinstance(display.line_, mpl.lines.Line2D) assert display.line_.get_alpha() == 0.8 - assert isinstance(display.ax_, mpl.axes.Axes) - assert isinstance(display.figure_, mpl.figure.Figure) - assert display.ax_.get_adjustable() == "box" - assert display.ax_.get_aspect() in ("equal", 1.0) - assert display.ax_.get_xlim() == display.ax_.get_ylim() == (-0.01, 1.01) expected_label = f"{default_name} (AUC = {display.roc_auc:.2f})" assert display.line_.get_label() == expected_label - expected_pos_label = 1 if pos_label is None else pos_label - expected_ylabel = f"True Positive Rate (Positive label: {expected_pos_label})" - expected_xlabel = f"False Positive Rate (Positive label: {expected_pos_label})" - assert display.ax_.get_ylabel() == expected_ylabel - assert display.ax_.get_xlabel() == expected_xlabel +@pytest.mark.parametrize( + "params, err_msg", + [ + ( + { + "fpr": [np.array([0, 0.5, 1]), np.array([0, 0.5, 1])], + "tpr": [np.array([0, 0.5, 1])], + "roc_auc": None, + "name": None, + }, + "self.fpr and self.tpr from `RocCurveDisplay` initialization,", + ), + ( + { + "fpr": [np.array([0, 0.5, 1])], + "tpr": [np.array([0, 0.5, 1]), np.array([0, 0.5, 1])], + "roc_auc": [0.8, 0.9], + "name": None, + }, + "self.fpr, self.tpr and self.roc_auc from `RocCurveDisplay`", + ), + ( + { + "fpr": [np.array([0, 0.5, 1]), np.array([0, 0.5, 1])], + "tpr": [np.array([0, 0.5, 1]), np.array([0, 0.5, 1])], + "roc_auc": [0.8], + "name": None, + }, + "Got: self.fpr: 2, self.tpr: 2, self.roc_auc: 1", + ), + ( + { + "fpr": [np.array([0, 0.5, 1]), np.array([0, 0.5, 1])], + "tpr": [np.array([0, 0.5, 1]), np.array([0, 0.5, 1])], + "roc_auc": [0.8, 0.9], + "name": ["curve1", "curve2", "curve3"], + }, + r"self.fpr, self.tpr, self.roc_auc and 'name' \(or self.name\)", + ), + ( + { + "fpr": [np.array([0, 0.5, 1]), np.array([0, 0.5, 1])], + "tpr": [np.array([0, 0.5, 1]), np.array([0, 0.5, 1])], + "roc_auc": [0.8, 0.9], + # List of length 1 is always allowed + "name": ["curve1"], + }, + None, + ), + ], +) +def test_roc_curve_plot_parameter_length_validation(pyplot, params, err_msg): + """Check `plot` parameter length validation performed correctly.""" + display = RocCurveDisplay(**params) + if err_msg: + with pytest.raises(ValueError, match=err_msg): + display.plot() + else: + # No error should be raised + display.plot() + + +def test_validate_plot_params(pyplot): + """Check `_validate_plot_params` returns the correct variables.""" + fpr = np.array([0, 0.5, 1]) + tpr = [np.array([0, 0.5, 1])] + roc_auc = None + name = "test_curve" + + # Initialize display with test inputs + display = RocCurveDisplay( + fpr=fpr, + tpr=tpr, + roc_auc=roc_auc, + name=name, + pos_label=None, + ) + fpr_out, tpr_out, roc_auc_out, name_out = display._validate_plot_params( + ax=None, name=None + ) + + assert isinstance(fpr_out, list) + assert isinstance(tpr_out, list) + assert len(fpr_out) == 1 + assert len(tpr_out) == 1 + assert roc_auc_out is None + assert name_out == ["test_curve"] + + +def test_roc_curve_from_cv_results_param_validation(pyplot, data_binary): + """Check parameter validation is correct.""" + X, y = data_binary + + # `cv_results` missing key + cv_results_no_est = cross_validate( + LogisticRegression(), X, y, cv=3, return_estimator=True, return_indices=False + ) + cv_results_no_indices = cross_validate( + LogisticRegression(), X, y, cv=3, return_estimator=True, return_indices=False + ) + for cv_results in (cv_results_no_est, cv_results_no_indices): + with pytest.raises( + ValueError, + match="`cv_results` does not contain one of the following required", + ): + RocCurveDisplay.from_cv_results(cv_results, X, y) + + cv_results = cross_validate( + LogisticRegression(), X, y, cv=3, return_estimator=True, return_indices=True + ) + + # `X` wrong length + with pytest.raises(ValueError, match="`X` does not contain the correct"): + RocCurveDisplay.from_cv_results(cv_results, X[:10, :], y) + + # `y` not binary + y_multi = y.copy() + y_multi[0] = 2 + with pytest.raises(ValueError, match="The target `y` is not binary."): + RocCurveDisplay.from_cv_results(cv_results, X, y_multi) + + # input inconsistent length + with pytest.raises(ValueError, match="Found input variables with inconsistent"): + RocCurveDisplay.from_cv_results(cv_results, X, y[:10]) + with pytest.raises(ValueError, match="Found input variables with inconsistent"): + RocCurveDisplay.from_cv_results(cv_results, X, y, sample_weight=[1, 2]) + + # `pos_label` inconsistency + y_multi[y_multi == 1] = 2 + with pytest.raises(ValueError, match=r"y takes value in \{0, 2\}"): + RocCurveDisplay.from_cv_results(cv_results, X, y_multi) + + # `name` is list while `curve_kwargs` is None or dict + for curve_kwargs in (None, {"alpha": 0.2}): + with pytest.raises(ValueError, match="To avoid labeling individual curves"): + RocCurveDisplay.from_cv_results( + cv_results, + X, + y, + name=["one", "two", "three"], + curve_kwargs=curve_kwargs, + ) + + # `curve_kwargs` incorrect length + with pytest.raises(ValueError, match="`curve_kwargs` must be None, a dictionary"): + RocCurveDisplay.from_cv_results(cv_results, X, y, curve_kwargs=[{"alpha": 1}]) + + # `curve_kwargs` both alias provided + with pytest.raises(TypeError, match="Got both c and"): + RocCurveDisplay.from_cv_results( + cv_results, X, y, curve_kwargs={"c": "blue", "color": "red"} + ) + + +@pytest.mark.parametrize( + "curve_kwargs", + [None, {"alpha": 0.2}, [{"alpha": 0.2}, {"alpha": 0.3}, {"alpha": 0.4}]], +) +def test_roc_curve_display_from_cv_results_curve_kwargs( + pyplot, data_binary, curve_kwargs +): + """Check `curve_kwargs` correctly passed.""" + X, y = data_binary + n_cv = 3 + cv_results = cross_validate( + LogisticRegression(), X, y, cv=n_cv, return_estimator=True, return_indices=True + ) + display = RocCurveDisplay.from_cv_results( + cv_results, + X, + y, + curve_kwargs=curve_kwargs, + ) + if curve_kwargs is None: + # Default `alpha` used + assert all(line.get_alpha() == 0.5 for line in display.line_) + elif isinstance(curve_kwargs, Mapping): + # `alpha` from dict used for all curves + assert all(line.get_alpha() == 0.2 for line in display.line_) + else: + # Different `alpha` used for each curve + assert all( + line.get_alpha() == curve_kwargs[i]["alpha"] + for i, line in enumerate(display.line_) + ) + + +# TODO(1.9): Remove in 1.9 +def test_roc_curve_display_estimator_name_deprecation(pyplot): + """Check deprecation of `estimator_name`.""" + fpr = np.array([0, 0.5, 1]) + tpr = np.array([0, 0.5, 1]) + with pytest.warns(FutureWarning, match="`estimator_name` is deprecated in"): + RocCurveDisplay(fpr=fpr, tpr=tpr, estimator_name="test") + + +# TODO(1.9): Remove in 1.9 +@pytest.mark.parametrize( + "constructor_name", ["from_estimator", "from_predictions", "plot"] +) +def test_roc_curve_display_kwargs_deprecation(pyplot, data_binary, constructor_name): + """Check **kwargs deprecated correctly in favour of `curve_kwargs`.""" + X, y = data_binary + lr = LogisticRegression() + lr.fit(X, y) + fpr = np.array([0, 0.5, 1]) + tpr = np.array([0, 0.5, 1]) + + # Error when both `curve_kwargs` and `**kwargs` provided + with pytest.raises(ValueError, match="Cannot provide both `curve_kwargs`"): + if constructor_name == "from_estimator": + RocCurveDisplay.from_estimator( + lr, X, y, curve_kwargs={"alpha": 1}, label="test" + ) + elif constructor_name == "from_predictions": + RocCurveDisplay.from_predictions( + y, y, curve_kwargs={"alpha": 1}, label="test" + ) + else: + RocCurveDisplay(fpr=fpr, tpr=tpr).plot( + curve_kwargs={"alpha": 1}, label="test" + ) + + # Warning when `**kwargs`` provided + with pytest.warns(FutureWarning, match=r"`\*\*kwargs` is deprecated and will be"): + if constructor_name == "from_estimator": + RocCurveDisplay.from_estimator(lr, X, y, label="test") + elif constructor_name == "from_predictions": + RocCurveDisplay.from_predictions(y, y, label="test") + else: + RocCurveDisplay(fpr=fpr, tpr=tpr).plot(label="test") + + +@pytest.mark.parametrize( + "curve_kwargs", + [ + None, + {"color": "blue"}, + [{"color": "blue"}, {"color": "green"}, {"color": "red"}], + ], +) +@pytest.mark.parametrize("drop_intermediate", [True, False]) +@pytest.mark.parametrize("response_method", ["predict_proba", "decision_function"]) +@pytest.mark.parametrize("with_sample_weight", [True, False]) +@pytest.mark.parametrize("with_strings", [True, False]) +def test_roc_curve_display_plotting_from_cv_results( + pyplot, + data_binary, + with_strings, + with_sample_weight, + response_method, + drop_intermediate, + curve_kwargs, +): + """Check overall plotting of `from_cv_results`.""" + X, y = data_binary + + pos_label = None + if with_strings: + y = np.array(["c", "b"])[y] + pos_label = "c" + + if with_sample_weight: + rng = np.random.RandomState(42) + sample_weight = rng.randint(1, 4, size=(X.shape[0])) + else: + sample_weight = None + + cv_results = cross_validate( + LogisticRegression(), X, y, cv=3, return_estimator=True, return_indices=True + ) + display = RocCurveDisplay.from_cv_results( + cv_results, + X, + y, + sample_weight=sample_weight, + drop_intermediate=drop_intermediate, + response_method=response_method, + pos_label=pos_label, + curve_kwargs=curve_kwargs, + ) + + for idx, (estimator, test_indices) in enumerate( + zip(cv_results["estimator"], cv_results["indices"]["test"]) + ): + y_true = _safe_indexing(y, test_indices) + y_pred = _get_response_values_binary( + estimator, + _safe_indexing(X, test_indices), + response_method=response_method, + pos_label=pos_label, + )[0] + sample_weight_fold = ( + None + if sample_weight is None + else _safe_indexing(sample_weight, test_indices) + ) + fpr, tpr, _ = roc_curve( + y_true, + y_pred, + sample_weight=sample_weight_fold, + drop_intermediate=drop_intermediate, + pos_label=pos_label, + ) + assert_allclose(display.roc_auc[idx], auc(fpr, tpr)) + assert_allclose(display.fpr[idx], fpr) + assert_allclose(display.tpr[idx], tpr) + + assert display.name is None + + import matplotlib as mpl + + _check_figure_axes_and_labels(display, pos_label) + if with_sample_weight: + aggregate_expected_labels = ["AUC = 0.64 +/- 0.04", "_child1", "_child2"] + else: + aggregate_expected_labels = ["AUC = 0.61 +/- 0.05", "_child1", "_child2"] + for idx, line in enumerate(display.line_): + assert isinstance(line, mpl.lines.Line2D) + # Default alpha for `from_cv_results` + line.get_alpha() == 0.5 + if isinstance(curve_kwargs, list): + # Each individual curve labelled + assert line.get_label() == f"AUC = {display.roc_auc[idx]:.2f}" + else: + # Single aggregate label + assert line.get_label() == aggregate_expected_labels[idx] + + +@pytest.mark.parametrize("roc_auc", [[1.0, 1.0, 1.0], None]) +@pytest.mark.parametrize( + "curve_kwargs", + [None, {"color": "red"}, [{"c": "red"}, {"c": "green"}, {"c": "yellow"}]], +) +@pytest.mark.parametrize("name", [None, "single", ["one", "two", "three"]]) +def test_roc_curve_plot_legend_label(pyplot, data_binary, name, curve_kwargs, roc_auc): + """Check legend label correct with all `curve_kwargs`, `name` combinations.""" + fpr = [np.array([0, 0.5, 1]), np.array([0, 0.5, 1]), np.array([0, 0.5, 1])] + tpr = [np.array([0, 0.5, 1]), np.array([0, 0.5, 1]), np.array([0, 0.5, 1])] + if not isinstance(curve_kwargs, list) and isinstance(name, list): + with pytest.raises(ValueError, match="To avoid labeling individual curves"): + RocCurveDisplay(fpr=fpr, tpr=tpr, roc_auc=roc_auc).plot( + name=name, curve_kwargs=curve_kwargs + ) + + else: + display = RocCurveDisplay(fpr=fpr, tpr=tpr, roc_auc=roc_auc).plot( + name=name, curve_kwargs=curve_kwargs + ) + legend = display.ax_.get_legend() + if legend is None: + # No legend is created, exit test early + assert name is None + assert roc_auc is None + return + else: + legend_labels = [text.get_text() for text in legend.get_texts()] + + if isinstance(curve_kwargs, list): + # Multiple labels in legend + assert len(legend_labels) == 3 + for idx, label in enumerate(legend_labels): + if name is None: + expected_label = "AUC = 1.00" if roc_auc else None + assert label == expected_label + elif isinstance(name, str): + expected_label = "single (AUC = 1.00)" if roc_auc else "single" + assert label == expected_label + else: + # `name` is a list of different strings + expected_label = ( + f"{name[idx]} (AUC = 1.00)" if roc_auc else f"{name[idx]}" + ) + assert label == expected_label + else: + # Single label in legend + assert len(legend_labels) == 1 + if name is None: + expected_label = "AUC = 1.00 +/- 0.00" if roc_auc else None + assert legend_labels[0] == expected_label + else: + # name is single string + expected_label = "single (AUC = 1.00 +/- 0.00)" if roc_auc else "single" + assert legend_labels[0] == expected_label + + +@pytest.mark.parametrize( + "curve_kwargs", + [None, {"color": "red"}, [{"c": "red"}, {"c": "green"}, {"c": "yellow"}]], +) +@pytest.mark.parametrize("name", [None, "single", ["one", "two", "three"]]) +def test_roc_curve_from_cv_results_legend_label( + pyplot, data_binary, name, curve_kwargs +): + """Check legend label correct with all `curve_kwargs`, `name` combinations.""" + X, y = data_binary + n_cv = 3 + cv_results = cross_validate( + LogisticRegression(), X, y, cv=n_cv, return_estimator=True, return_indices=True + ) + + if not isinstance(curve_kwargs, list) and isinstance(name, list): + with pytest.raises(ValueError, match="To avoid labeling individual curves"): + RocCurveDisplay.from_cv_results( + cv_results, X, y, name=name, curve_kwargs=curve_kwargs + ) + else: + display = RocCurveDisplay.from_cv_results( + cv_results, X, y, name=name, curve_kwargs=curve_kwargs + ) + + legend = display.ax_.get_legend() + legend_labels = [text.get_text() for text in legend.get_texts()] + if isinstance(curve_kwargs, list): + # Multiple labels in legend + assert len(legend_labels) == 3 + auc = ["0.62", "0.66", "0.55"] + for idx, label in enumerate(legend_labels): + if name is None: + assert label == f"AUC = {auc[idx]}" + elif isinstance(name, str): + assert label == f"single (AUC = {auc[idx]})" + else: + # `name` is a list of different strings + assert label == f"{name[idx]} (AUC = {auc[idx]})" + else: + # Single label in legend + assert len(legend_labels) == 1 + if name is None: + assert legend_labels[0] == "AUC = 0.61 +/- 0.05" + else: + # name is single string + assert legend_labels[0] == "single (AUC = 0.61 +/- 0.05)" + + +@pytest.mark.parametrize( + "curve_kwargs", + [None, {"color": "red"}, [{"c": "red"}, {"c": "green"}, {"c": "yellow"}]], +) +def test_roc_curve_from_cv_results_curve_kwargs(pyplot, data_binary, curve_kwargs): + """Check line kwargs passed correctly in `from_cv_results`.""" + + X, y = data_binary + cv_results = cross_validate( + LogisticRegression(), X, y, cv=3, return_estimator=True, return_indices=True + ) + display = RocCurveDisplay.from_cv_results( + cv_results, X, y, curve_kwargs=curve_kwargs + ) + + for idx, line in enumerate(display.line_): + color = line.get_color() + if curve_kwargs is None: + # Default color + assert color == "blue" + elif isinstance(curve_kwargs, Mapping): + # All curves "red" + assert color == "red" + else: + assert color == curve_kwargs[idx]["c"] + + +def _check_chance_level(plot_chance_level, chance_level_kw, display): + """Check chance level line and line styles correct.""" + import matplotlib as mpl + + if plot_chance_level: + assert isinstance(display.chance_level_, mpl.lines.Line2D) + assert tuple(display.chance_level_.get_xdata()) == (0, 1) + assert tuple(display.chance_level_.get_ydata()) == (0, 1) + else: + assert display.chance_level_ is None + + # Checking for chance level line styles + if plot_chance_level and chance_level_kw is None: + assert display.chance_level_.get_color() == "k" + assert display.chance_level_.get_linestyle() == "--" + assert display.chance_level_.get_label() == "Chance level (AUC = 0.5)" + elif plot_chance_level: + if "c" in chance_level_kw: + assert display.chance_level_.get_color() == chance_level_kw["c"] + else: + assert display.chance_level_.get_color() == chance_level_kw["color"] + if "lw" in chance_level_kw: + assert display.chance_level_.get_linewidth() == chance_level_kw["lw"] + else: + assert display.chance_level_.get_linewidth() == chance_level_kw["linewidth"] + if "ls" in chance_level_kw: + assert display.chance_level_.get_linestyle() == chance_level_kw["ls"] + else: + assert display.chance_level_.get_linestyle() == chance_level_kw["linestyle"] @pytest.mark.parametrize("plot_chance_level", [True, False]) @@ -136,10 +639,7 @@ def test_roc_curve_display_plotting( {"lw": 1, "color": "blue", "ls": "-", "label": None}, ], ) -@pytest.mark.parametrize( - "constructor_name", - ["from_estimator", "from_predictions"], -) +@pytest.mark.parametrize("constructor_name", ["from_estimator", "from_predictions"]) def test_roc_curve_chance_level_line( pyplot, data_binary, @@ -148,7 +648,7 @@ def test_roc_curve_chance_level_line( label, constructor_name, ): - """Check the chance level line plotting behaviour.""" + """Check chance level plotting behavior of `from_predictions`, `from_estimator`.""" X, y = data_binary lr = LogisticRegression() @@ -162,8 +662,7 @@ def test_roc_curve_chance_level_line( lr, X, y, - label=label, - alpha=0.8, + curve_kwargs={"alpha": 0.8, "label": label}, plot_chance_level=plot_chance_level, chance_level_kw=chance_level_kw, ) @@ -171,8 +670,7 @@ def test_roc_curve_chance_level_line( display = RocCurveDisplay.from_predictions( y, y_score, - label=label, - alpha=0.8, + curve_kwargs={"alpha": 0.8, "label": label}, plot_chance_level=plot_chance_level, chance_level_kw=chance_level_kw, ) @@ -184,32 +682,10 @@ def test_roc_curve_chance_level_line( assert isinstance(display.ax_, mpl.axes.Axes) assert isinstance(display.figure_, mpl.figure.Figure) - if plot_chance_level: - assert isinstance(display.chance_level_, mpl.lines.Line2D) - assert tuple(display.chance_level_.get_xdata()) == (0, 1) - assert tuple(display.chance_level_.get_ydata()) == (0, 1) - else: - assert display.chance_level_ is None + _check_chance_level(plot_chance_level, chance_level_kw, display) - # Checking for chance level line styles - if plot_chance_level and chance_level_kw is None: - assert display.chance_level_.get_color() == "k" - assert display.chance_level_.get_linestyle() == "--" - assert display.chance_level_.get_label() == "Chance level (AUC = 0.5)" - elif plot_chance_level: - if "c" in chance_level_kw: - assert display.chance_level_.get_color() == chance_level_kw["c"] - else: - assert display.chance_level_.get_color() == chance_level_kw["color"] - if "lw" in chance_level_kw: - assert display.chance_level_.get_linewidth() == chance_level_kw["lw"] - else: - assert display.chance_level_.get_linewidth() == chance_level_kw["linewidth"] - if "ls" in chance_level_kw: - assert display.chance_level_.get_linestyle() == chance_level_kw["ls"] - else: - assert display.chance_level_.get_linestyle() == chance_level_kw["linestyle"] - # Checking for legend behaviour + # Checking for legend behaviour + if plot_chance_level and chance_level_kw is not None: if label is not None or chance_level_kw.get("label") is not None: legend = display.ax_.get_legend() assert legend is not None # Legend should be present if any label is set @@ -222,6 +698,62 @@ def test_roc_curve_chance_level_line( assert display.ax_.get_legend() is None +@pytest.mark.parametrize("plot_chance_level", [True, False]) +@pytest.mark.parametrize( + "chance_level_kw", + [ + None, + {"linewidth": 1, "color": "red", "linestyle": "-", "label": "DummyEstimator"}, + {"lw": 1, "c": "red", "ls": "-", "label": "DummyEstimator"}, + {"lw": 1, "color": "blue", "ls": "-", "label": None}, + ], +) +@pytest.mark.parametrize("curve_kwargs", [None, {"alpha": 0.8}]) +def test_roc_curve_chance_level_line_from_cv_results( + pyplot, + data_binary, + plot_chance_level, + chance_level_kw, + curve_kwargs, +): + """Check chance level plotting behavior with `from_cv_results`.""" + X, y = data_binary + n_cv = 3 + cv_results = cross_validate( + LogisticRegression(), X, y, cv=n_cv, return_estimator=True, return_indices=True + ) + + display = RocCurveDisplay.from_cv_results( + cv_results, + X, + y, + plot_chance_level=plot_chance_level, + chance_level_kwargs=chance_level_kw, + curve_kwargs=curve_kwargs, + ) + + import matplotlib as mpl + + assert all(isinstance(line, mpl.lines.Line2D) for line in display.line_) + # Ensure both curve line kwargs passed correctly as well + if curve_kwargs: + assert all(line.get_alpha() == 0.8 for line in display.line_) + assert isinstance(display.ax_, mpl.axes.Axes) + assert isinstance(display.figure_, mpl.figure.Figure) + + _check_chance_level(plot_chance_level, chance_level_kw, display) + + legend = display.ax_.get_legend() + # There is always a legend, to indicate each 'Fold' curve + assert legend is not None + legend_labels = [text.get_text() for text in legend.get_texts()] + if plot_chance_level and chance_level_kw is not None: + if chance_level_kw.get("label") is not None: + assert chance_level_kw["label"] in legend_labels + else: + assert len(legend_labels) == 1 + + @pytest.mark.parametrize( "clf", [ @@ -253,31 +785,52 @@ def test_roc_curve_display_complex_pipeline(pyplot, data_binary, clf, constructo name = "Classifier" assert name in display.line_.get_label() - assert display.estimator_name == name + assert display.name == name @pytest.mark.parametrize( - "roc_auc, estimator_name, expected_label", + "roc_auc, name, curve_kwargs, expected_labels", [ - (0.9, None, "AUC = 0.90"), - (None, "my_est", "my_est"), - (0.8, "my_est2", "my_est2 (AUC = 0.80)"), + ([0.9, 0.8], None, None, ["AUC = 0.85 +/- 0.05", "_child1"]), + ([0.9, 0.8], "Est name", None, ["Est name (AUC = 0.85 +/- 0.05)", "_child1"]), + ( + [0.8, 0.7], + ["fold1", "fold2"], + [{"c": "blue"}, {"c": "red"}], + ["fold1 (AUC = 0.80)", "fold2 (AUC = 0.70)"], + ), + (None, ["fold1", "fold2"], [{"c": "blue"}, {"c": "red"}], ["fold1", "fold2"]), ], ) def test_roc_curve_display_default_labels( - pyplot, roc_auc, estimator_name, expected_label + pyplot, roc_auc, name, curve_kwargs, expected_labels ): """Check the default labels used in the display.""" - fpr = np.array([0, 0.5, 1]) - tpr = np.array([0, 0.5, 1]) - disp = RocCurveDisplay( - fpr=fpr, tpr=tpr, roc_auc=roc_auc, estimator_name=estimator_name - ).plot() - assert disp.line_.get_label() == expected_label + fpr = [np.array([0, 0.5, 1]), np.array([0, 0.3, 1])] + tpr = [np.array([0, 0.5, 1]), np.array([0, 0.3, 1])] + disp = RocCurveDisplay(fpr=fpr, tpr=tpr, roc_auc=roc_auc, name=name).plot( + curve_kwargs=curve_kwargs + ) + for idx, expected_label in enumerate(expected_labels): + assert disp.line_[idx].get_label() == expected_label + + +def _check_auc(display, constructor_name): + roc_auc_limit = 0.95679 + roc_auc_limit_multi = [0.97007, 0.985915, 0.980952] + + if constructor_name == "from_cv_results": + for idx, roc_auc in enumerate(display.roc_auc): + assert roc_auc == pytest.approx(roc_auc_limit_multi[idx]) + else: + assert display.roc_auc == pytest.approx(roc_auc_limit) + assert trapezoid(display.tpr, display.fpr) == pytest.approx(roc_auc_limit) @pytest.mark.parametrize("response_method", ["predict_proba", "decision_function"]) -@pytest.mark.parametrize("constructor_name", ["from_estimator", "from_predictions"]) +@pytest.mark.parametrize( + "constructor_name", ["from_estimator", "from_predictions", "from_cv_results"] +) def test_plot_roc_curve_pos_label(pyplot, response_method, constructor_name): # check that we can provide the positive label and display the proper # statistics @@ -300,9 +853,13 @@ def test_plot_roc_curve_pos_label(pyplot, response_method, constructor_name): classifier = LogisticRegression() classifier.fit(X_train, y_train) + cv_results = cross_validate( + LogisticRegression(), X, y, cv=3, return_estimator=True, return_indices=True + ) - # sanity check to be sure the positive class is classes_[0] and that we - # are betrayed by the class imbalance + # Sanity check to be sure the positive class is `classes_[0]` + # Class imbalance ensures a large difference in prediction values between classes, + # allowing us to catch errors when we switch `pos_label` assert classifier.classes_.tolist() == ["cancer", "not cancer"] y_score = getattr(classifier, response_method)(X_test) @@ -311,43 +868,59 @@ def test_plot_roc_curve_pos_label(pyplot, response_method, constructor_name): y_score_cancer = -1 * y_score if y_score.ndim == 1 else y_score[:, 0] y_score_not_cancer = y_score if y_score.ndim == 1 else y_score[:, 1] + pos_label = "cancer" + y_score = y_score_cancer if constructor_name == "from_estimator": display = RocCurveDisplay.from_estimator( classifier, X_test, y_test, - pos_label="cancer", + pos_label=pos_label, response_method=response_method, ) - else: + elif constructor_name == "from_predictions": display = RocCurveDisplay.from_predictions( y_test, - y_score_cancer, - pos_label="cancer", + y_score, + pos_label=pos_label, + ) + else: + display = RocCurveDisplay.from_cv_results( + cv_results, + X, + y, + response_method=response_method, + pos_label=pos_label, ) - roc_auc_limit = 0.95679 - - assert display.roc_auc == pytest.approx(roc_auc_limit) - assert trapezoid(display.tpr, display.fpr) == pytest.approx(roc_auc_limit) + _check_auc(display, constructor_name) + pos_label = "not cancer" + y_score = y_score_not_cancer if constructor_name == "from_estimator": display = RocCurveDisplay.from_estimator( classifier, X_test, y_test, response_method=response_method, - pos_label="not cancer", + pos_label=pos_label, ) - else: + elif constructor_name == "from_predictions": display = RocCurveDisplay.from_predictions( y_test, - y_score_not_cancer, - pos_label="not cancer", + y_score, + pos_label=pos_label, + ) + else: + display = RocCurveDisplay.from_cv_results( + cv_results, + X, + y, + response_method=response_method, + pos_label=pos_label, ) - assert display.roc_auc == pytest.approx(roc_auc_limit) - assert trapezoid(display.tpr, display.fpr) == pytest.approx(roc_auc_limit) + _check_auc(display, constructor_name) # TODO(1.9): remove @@ -381,23 +954,30 @@ def test_y_pred_deprecation_warning(pyplot): @pytest.mark.parametrize("despine", [True, False]) -@pytest.mark.parametrize("constructor_name", ["from_estimator", "from_predictions"]) +@pytest.mark.parametrize( + "constructor_name", ["from_estimator", "from_predictions", "from_cv_results"] +) def test_plot_roc_curve_despine(pyplot, data_binary, despine, constructor_name): # Check that the despine keyword is working correctly X, y = data_binary lr = LogisticRegression().fit(X, y) lr.fit(X, y) + cv_results = cross_validate( + LogisticRegression(), X, y, cv=3, return_estimator=True, return_indices=True + ) y_pred = lr.decision_function(X) - # safe guard for the binary if/else construction - assert constructor_name in ("from_estimator", "from_predictions") + # safe guard for the if/else construction + assert constructor_name in ("from_estimator", "from_predictions", "from_cv_results") if constructor_name == "from_estimator": display = RocCurveDisplay.from_estimator(lr, X, y, despine=despine) - else: + elif constructor_name == "from_predictions": display = RocCurveDisplay.from_predictions(y, y_pred, despine=despine) + else: + display = RocCurveDisplay.from_cv_results(cv_results, X, y, despine=despine) for s in ["top", "right"]: assert display.ax_.spines[s].get_visible() is not despine diff --git a/sklearn/metrics/_ranking.py b/sklearn/metrics/_ranking.py index d4fba69440f13..2d0e5211c236c 100644 --- a/sklearn/metrics/_ranking.py +++ b/sklearn/metrics/_ranking.py @@ -183,6 +183,10 @@ def average_precision_score( roc_auc_score : Compute the area under the ROC curve. precision_recall_curve : Compute precision-recall pairs for different probability thresholds. + PrecisionRecallDisplay.from_estimator : Plot the precision recall curve + using an estimator and data. + PrecisionRecallDisplay.from_predictions : Plot the precision recall curve + using true and predicted labels. Notes ----- diff --git a/sklearn/metrics/_regression.py b/sklearn/metrics/_regression.py index 4c46346d63d92..0731e00ce3a1a 100644 --- a/sklearn/metrics/_regression.py +++ b/sklearn/metrics/_regression.py @@ -57,8 +57,10 @@ ] -def _check_reg_targets(y_true, y_pred, multioutput, dtype="numeric", xp=None): - """Check that y_true and y_pred belong to the same regression task. +def _check_reg_targets( + y_true, y_pred, sample_weight, multioutput, dtype="numeric", xp=None +): + """Check that y_true, y_pred and sample_weight belong to the same regression task. To reduce redundancy when calling `_find_matching_floating_dtype`, please use `_check_reg_targets_with_floating_dtype` instead. @@ -71,6 +73,9 @@ def _check_reg_targets(y_true, y_pred, multioutput, dtype="numeric", xp=None): y_pred : array-like of shape (n_samples,) or (n_samples, n_outputs) Estimated target values. + sample_weight : array-like of shape (n_samples,) or None + Sample weights. + multioutput : array-like or string in ['raw_values', uniform_average', 'variance_weighted'] or None None is accepted due to backward compatibility of r2_score(). @@ -95,6 +100,9 @@ def _check_reg_targets(y_true, y_pred, multioutput, dtype="numeric", xp=None): y_pred : array-like of shape (n_samples, n_outputs) Estimated target values. + sample_weight : array-like of shape (n_samples,) or None + Sample weights. + multioutput : array-like of shape (n_outputs) or string in ['raw_values', uniform_average', 'variance_weighted'] or None Custom output weights if ``multioutput`` is array-like or @@ -103,9 +111,11 @@ def _check_reg_targets(y_true, y_pred, multioutput, dtype="numeric", xp=None): """ xp, _ = get_namespace(y_true, y_pred, multioutput, xp=xp) - check_consistent_length(y_true, y_pred) + check_consistent_length(y_true, y_pred, sample_weight) y_true = check_array(y_true, ensure_2d=False, dtype=dtype) y_pred = check_array(y_pred, ensure_2d=False, dtype=dtype) + if sample_weight is not None: + sample_weight = _check_sample_weight(sample_weight, y_true, dtype=dtype) if y_true.ndim == 1: y_true = xp.reshape(y_true, (-1, 1)) @@ -141,14 +151,13 @@ def _check_reg_targets(y_true, y_pred, multioutput, dtype="numeric", xp=None): ) y_type = "continuous" if n_outputs == 1 else "continuous-multioutput" - return y_type, y_true, y_pred, multioutput + return y_type, y_true, y_pred, sample_weight, multioutput def _check_reg_targets_with_floating_dtype( y_true, y_pred, sample_weight, multioutput, xp=None ): - """Ensures that y_true, y_pred, and sample_weight correspond to the same - regression task. + """Ensures y_true, y_pred, and sample_weight correspond to same regression task. Extends `_check_reg_targets` by automatically selecting a suitable floating-point data type for inputs using `_find_matching_floating_dtype`. @@ -197,15 +206,10 @@ def _check_reg_targets_with_floating_dtype( """ dtype_name = _find_matching_floating_dtype(y_true, y_pred, sample_weight, xp=xp) - y_type, y_true, y_pred, multioutput = _check_reg_targets( - y_true, y_pred, multioutput, dtype=dtype_name, xp=xp + y_type, y_true, y_pred, sample_weight, multioutput = _check_reg_targets( + y_true, y_pred, sample_weight, multioutput, dtype=dtype_name, xp=xp ) - # _check_reg_targets does not accept sample_weight as input. - # Convert sample_weight's data type separately to match dtype_name. - if sample_weight is not None: - sample_weight = xp.asarray(sample_weight, dtype=dtype_name) - return y_type, y_true, y_pred, sample_weight, multioutput @@ -282,8 +286,6 @@ def mean_absolute_error( ) ) - check_consistent_length(y_true, y_pred, sample_weight) - output_errors = _average( xp.abs(y_pred - y_true), weights=sample_weight, axis=0, xp=xp ) @@ -383,7 +385,6 @@ def mean_pinball_loss( ) ) - check_consistent_length(y_true, y_pred, sample_weight) diff = y_true - y_pred sign = xp.astype(diff >= 0, diff.dtype) loss = alpha * sign * diff - (1 - alpha) * (1 - sign) * diff @@ -489,7 +490,6 @@ def mean_absolute_percentage_error( y_true, y_pred, sample_weight, multioutput, xp=xp ) ) - check_consistent_length(y_true, y_pred, sample_weight) epsilon = xp.asarray(xp.finfo(xp.float64).eps, dtype=y_true.dtype, device=device_) y_true_abs = xp.abs(y_true) mape = xp.abs(y_pred - y_true) / xp.maximum(y_true_abs, epsilon) @@ -581,7 +581,6 @@ def mean_squared_error( y_true, y_pred, sample_weight, multioutput, xp=xp ) ) - check_consistent_length(y_true, y_pred, sample_weight) output_errors = _average((y_true - y_pred) ** 2, axis=0, weights=sample_weight) if isinstance(multioutput, str): @@ -753,8 +752,10 @@ def mean_squared_log_error( """ xp, _ = get_namespace(y_true, y_pred) - _, y_true, y_pred, _, _ = _check_reg_targets_with_floating_dtype( - y_true, y_pred, sample_weight, multioutput, xp=xp + _, y_true, y_pred, sample_weight, multioutput = ( + _check_reg_targets_with_floating_dtype( + y_true, y_pred, sample_weight, multioutput, xp=xp + ) ) if xp.any(y_true <= -1) or xp.any(y_pred <= -1): @@ -829,8 +830,10 @@ def root_mean_squared_log_error( """ xp, _ = get_namespace(y_true, y_pred) - _, y_true, y_pred, _, _ = _check_reg_targets_with_floating_dtype( - y_true, y_pred, sample_weight, multioutput, xp=xp + _, y_true, y_pred, sample_weight, multioutput = ( + _check_reg_targets_with_floating_dtype( + y_true, y_pred, sample_weight, multioutput, xp=xp + ) ) if xp.any(y_true <= -1) or xp.any(y_pred <= -1): @@ -912,13 +915,12 @@ def median_absolute_error( >>> median_absolute_error(y_true, y_pred, multioutput=[0.3, 0.7]) 0.85 """ - y_type, y_true, y_pred, multioutput = _check_reg_targets( - y_true, y_pred, multioutput + _, y_true, y_pred, sample_weight, multioutput = _check_reg_targets( + y_true, y_pred, sample_weight, multioutput ) if sample_weight is None: output_errors = np.median(np.abs(y_pred - y_true), axis=0) else: - sample_weight = _check_sample_weight(sample_weight, y_pred) output_errors = _weighted_percentile( np.abs(y_pred - y_true), sample_weight=sample_weight ) @@ -1106,8 +1108,6 @@ def explained_variance_score( ) ) - check_consistent_length(y_true, y_pred, sample_weight) - y_diff_avg = _average(y_true - y_pred, weights=sample_weight, axis=0) numerator = _average( (y_true - y_pred - y_diff_avg) ** 2, weights=sample_weight, axis=0 @@ -1278,8 +1278,6 @@ def r2_score( ) ) - check_consistent_length(y_true, y_pred, sample_weight) - if _num_samples(y_pred) < 2: msg = "R^2 score is not well-defined with less than two samples." warnings.warn(msg, UndefinedMetricWarning) @@ -1343,7 +1341,9 @@ def max_error(y_true, y_pred): 1.0 """ xp, _ = get_namespace(y_true, y_pred) - y_type, y_true, y_pred, _ = _check_reg_targets(y_true, y_pred, None, xp=xp) + y_type, y_true, y_pred, _, _ = _check_reg_targets( + y_true, y_pred, sample_weight=None, multioutput=None, xp=xp + ) if y_type == "continuous-multioutput": raise ValueError("Multioutput not supported in max_error") return float(xp.max(xp.abs(y_true - y_pred))) @@ -1448,7 +1448,6 @@ def mean_tweedie_deviance(y_true, y_pred, *, sample_weight=None, power=0): ) if y_type == "continuous-multioutput": raise ValueError("Multioutput not supported in mean_tweedie_deviance") - check_consistent_length(y_true, y_pred, sample_weight) if sample_weight is not None: sample_weight = column_or_1d(sample_weight) @@ -1773,10 +1772,9 @@ def d2_pinball_score( >>> d2_pinball_score(y_true, y_true, alpha=0.1) 1.0 """ - y_type, y_true, y_pred, multioutput = _check_reg_targets( - y_true, y_pred, multioutput + _, y_true, y_pred, sample_weight, multioutput = _check_reg_targets( + y_true, y_pred, sample_weight, multioutput ) - check_consistent_length(y_true, y_pred, sample_weight) if _num_samples(y_pred) < 2: msg = "D^2 score is not well-defined with less than two samples." @@ -1796,7 +1794,6 @@ def d2_pinball_score( np.percentile(y_true, q=alpha * 100, axis=0), (len(y_true), 1) ) else: - sample_weight = _check_sample_weight(sample_weight, y_true) y_quantile = np.tile( _weighted_percentile( y_true, sample_weight=sample_weight, percentile_rank=alpha * 100 diff --git a/sklearn/metrics/tests/test_common.py b/sklearn/metrics/tests/test_common.py index 1000c988abca8..bad71e29573b8 100644 --- a/sklearn/metrics/tests/test_common.py +++ b/sklearn/metrics/tests/test_common.py @@ -1588,6 +1588,32 @@ def test_regression_sample_weight_invariance(name): check_sample_weight_invariance(name, metric, y_true, y_pred) +@pytest.mark.parametrize( + "name", + sorted( + set(ALL_METRICS).intersection(set(REGRESSION_METRICS)) + - METRICS_WITHOUT_SAMPLE_WEIGHT + ), +) +def test_regression_with_invalid_sample_weight(name): + # Check that `sample_weight` with incorrect length raises error + n_samples = 50 + random_state = check_random_state(0) + y_true = random_state.random_sample(size=(n_samples,)) + y_pred = random_state.random_sample(size=(n_samples,)) + metric = ALL_METRICS[name] + + sample_weight = random_state.random_sample(size=(n_samples - 1,)) + with pytest.raises(ValueError, match="Found input variables with inconsistent"): + metric(y_true, y_pred, sample_weight=sample_weight) + + sample_weight = random_state.random_sample(size=(n_samples * 2,)).reshape( + (n_samples, 2) + ) + with pytest.raises(ValueError, match="Sample weights must be 1D array or scalar"): + metric(y_true, y_pred, sample_weight=sample_weight) + + @pytest.mark.parametrize( "name", sorted( @@ -2147,6 +2173,11 @@ def check_array_api_metric_pairwise(metric, array_namespace, device, dtype_name) check_array_api_multiclass_classification_metric, check_array_api_multilabel_classification_metric, ], + jaccard_score: [ + check_array_api_binary_classification_metric, + check_array_api_multiclass_classification_metric, + check_array_api_multilabel_classification_metric, + ], multilabel_confusion_matrix: [ check_array_api_binary_classification_metric, check_array_api_multiclass_classification_metric, diff --git a/sklearn/metrics/tests/test_regression.py b/sklearn/metrics/tests/test_regression.py index 5e90727583189..396ae5d0ffae1 100644 --- a/sklearn/metrics/tests/test_regression.py +++ b/sklearn/metrics/tests/test_regression.py @@ -330,7 +330,9 @@ def test__check_reg_targets(): for (type1, y1, n_out1), (type2, y2, n_out2) in product(EXAMPLES, repeat=2): if type1 == type2 and n_out1 == n_out2: - y_type, y_check1, y_check2, multioutput = _check_reg_targets(y1, y2, None) + y_type, y_check1, y_check2, _, _ = _check_reg_targets( + y1, y2, sample_weight=None, multioutput=None + ) assert type1 == y_type if type1 == "continuous": assert_array_equal(y_check1, np.reshape(y1, (-1, 1))) @@ -340,7 +342,7 @@ def test__check_reg_targets(): assert_array_equal(y_check2, y2) else: with pytest.raises(ValueError): - _check_reg_targets(y1, y2, None) + _check_reg_targets(y1, y2, sample_weight=None, multioutput=None) def test__check_reg_targets_exception(): @@ -351,7 +353,7 @@ def test__check_reg_targets_exception(): ) ) with pytest.raises(ValueError, match=expected_message): - _check_reg_targets([1, 2, 3], [[1], [2], [3]], invalid_multioutput) + _check_reg_targets([1, 2, 3], [[1], [2], [3]], None, invalid_multioutput) def test_regression_multioutput_array(): diff --git a/sklearn/model_selection/_classification_threshold.py b/sklearn/model_selection/_classification_threshold.py index a5a898abdd1da..c68ed38b8819d 100644 --- a/sklearn/model_selection/_classification_threshold.py +++ b/sklearn/model_selection/_classification_threshold.py @@ -444,13 +444,8 @@ def _fit_and_score_over_thresholds( curve_scorer : scorer instance The scorer taking `classifier` and the validation set as input and outputting decision thresholds and scores as a curve. Note that this is different from - the usual scorer that output a single score value: - - * when `score_method` is one of the four constraint metrics, the curve scorer - will output a curve of two scores parametrized by the decision threshold, e.g. - TPR/TNR or precision/recall curves for each threshold; - * otherwise, the curve scorer will output a single score value for each - threshold. + the usual scorer that outputs a single score value as `curve_scorer` + outputs a single score value for each threshold. score_params : dict Parameters to pass to the `score` method of the underlying scorer. diff --git a/sklearn/model_selection/_search.py b/sklearn/model_selection/_search.py index 61dbd7c1b1d80..b6b537a68d401 100644 --- a/sklearn/model_selection/_search.py +++ b/sklearn/model_selection/_search.py @@ -31,8 +31,8 @@ get_scorer_names, ) from ..utils import Bunch, check_random_state -from ..utils._estimator_html_repr import _VisualBlock from ..utils._param_validation import HasMethods, Interval, StrOptions +from ..utils._repr_html.estimator import _VisualBlock from ..utils._tags import get_tags from ..utils.metadata_routing import ( MetadataRouter, @@ -1328,6 +1328,11 @@ class GridSearchCV(BaseSearchCV): to see how to design a custom selection strategy using a callable via `refit`. + See :ref:`this example + ` + for an example of how to use ``refit=callable`` to balance model + complexity and cross-validated score. + .. versionchanged:: 0.20 Support for callable added. @@ -1704,6 +1709,11 @@ class RandomizedSearchCV(BaseSearchCV): See ``scoring`` parameter to know more about multiple metric evaluation. + See :ref:`this example + ` + for an example of how to use ``refit=callable`` to balance model + complexity and cross-validated score. + .. versionchanged:: 0.20 Support for callable added. @@ -1936,7 +1946,7 @@ class RandomizedSearchCV(BaseSearchCV): >>> clf = RandomizedSearchCV(logistic, distributions, random_state=0) >>> search = clf.fit(iris.data, iris.target) >>> search.best_params_ - {'C': np.float64(2.2), 'penalty': 'l1'} + {'C': np.float64(2.195), 'penalty': 'l1'} """ _parameter_constraints: dict = { diff --git a/sklearn/model_selection/_search_successive_halving.py b/sklearn/model_selection/_search_successive_halving.py index da608e2bdc6f2..bcd9a83e6dc43 100644 --- a/sklearn/model_selection/_search_successive_halving.py +++ b/sklearn/model_selection/_search_successive_halving.py @@ -487,14 +487,26 @@ class HalvingGridSearchCV(BaseSuccessiveHalving): - `None`: the `estimator`'s :ref:`default evaluation criterion ` is used. - refit : bool, default=True - If True, refit an estimator using the best found parameters on the - whole dataset. + refit : bool or callable, default=True + Refit an estimator using the best found parameters on the whole + dataset. + + Where there are considerations other than maximum score in + choosing a best estimator, ``refit`` can be set to a function which + returns the selected ``best_index_`` given ``cv_results_``. In that + case, the ``best_estimator_`` and ``best_params_`` will be set + according to the returned ``best_index_`` while the ``best_score_`` + attribute will not be available. The refitted estimator is made available at the ``best_estimator_`` attribute and permits using ``predict`` directly on this ``HalvingGridSearchCV`` instance. + See :ref:`this example + ` + for an example of how to use ``refit=callable`` to balance model + complexity and cross-validated score. + error_score : 'raise' or numeric Value to assign to the score if an error occurs in estimator fitting. If set to 'raise', the error is raised. If a numeric value is given, @@ -832,14 +844,26 @@ class HalvingRandomSearchCV(BaseSuccessiveHalving): - `None`: the `estimator`'s :ref:`default evaluation criterion ` is used. - refit : bool, default=True - If True, refit an estimator using the best found parameters on the - whole dataset. + refit : bool or callable, default=True + Refit an estimator using the best found parameters on the whole + dataset. + + Where there are considerations other than maximum score in + choosing a best estimator, ``refit`` can be set to a function which + returns the selected ``best_index_`` given ``cv_results_``. In that + case, the ``best_estimator_`` and ``best_params_`` will be set + according to the returned ``best_index_`` while the ``best_score_`` + attribute will not be available. The refitted estimator is made available at the ``best_estimator_`` attribute and permits using ``predict`` directly on this ``HalvingRandomSearchCV`` instance. + See :ref:`this example + ` + for an example of how to use ``refit=callable`` to balance model + complexity and cross-validated score. + error_score : 'raise' or numeric Value to assign to the score if an error occurs in estimator fitting. If set to 'raise', the error is raised. If a numeric value is given, diff --git a/sklearn/model_selection/_validation.py b/sklearn/model_selection/_validation.py index e9aa7dc77f4c6..8b70bf42603ef 100644 --- a/sklearn/model_selection/_validation.py +++ b/sklearn/model_selection/_validation.py @@ -1929,6 +1929,11 @@ def learning_curve( Times spent for scoring in seconds. Only present if ``return_times`` is True. + See Also + -------- + LearningCurveDisplay.from_estimator : Plot a learning curve using an + estimator and data. + Examples -------- >>> from sklearn.datasets import make_classification @@ -2391,6 +2396,11 @@ def validation_curve( test_scores : array of shape (n_ticks, n_cv_folds) Scores on test set. + See Also + -------- + ValidationCurveDisplay.from_estimator : Plot the validation curve + given an estimator, the data, and the parameter to vary. + Notes ----- See :ref:`sphx_glr_auto_examples_model_selection_plot_train_error_vs_test_error.py` diff --git a/sklearn/model_selection/tests/test_search.py b/sklearn/model_selection/tests/test_search.py index 393429b29ff92..7888dd2d1766b 100644 --- a/sklearn/model_selection/tests/test_search.py +++ b/sklearn/model_selection/tests/test_search.py @@ -2662,21 +2662,21 @@ def test_search_html_repr(): search_cv = GridSearchCV(pipeline, param_grid=param_grid, refit=False) with config_context(display="diagram"): repr_html = search_cv._repr_html_() - assert "
DummyClassifier()
" in repr_html + assert "
DummyClassifier
" in repr_html # Fitted with `refit=False` shows the original pipeline search_cv.fit(X, y) with config_context(display="diagram"): repr_html = search_cv._repr_html_() - assert "
DummyClassifier()
" in repr_html + assert "
DummyClassifier
" in repr_html # Fitted with `refit=True` shows the best estimator search_cv = GridSearchCV(pipeline, param_grid=param_grid, refit=True) search_cv.fit(X, y) with config_context(display="diagram"): repr_html = search_cv._repr_html_() - assert "
DummyClassifier()
" not in repr_html - assert "
LogisticRegression()
" in repr_html + assert "
DummyClassifier
" not in repr_html + assert "
LogisticRegression
" in repr_html # Metadata Routing Tests diff --git a/sklearn/neighbors/meson.build b/sklearn/neighbors/meson.build index df2aab466500c..7993421896218 100644 --- a/sklearn/neighbors/meson.build +++ b/sklearn/neighbors/meson.build @@ -39,7 +39,7 @@ neighbors_extension_metadata = { '_partition_nodes': {'sources': [cython_gen_cpp.process('_partition_nodes.pyx')], 'dependencies': [np_dep]}, - '_quad_tree': {'sources': ['_quad_tree.pyx'], 'dependencies': [np_dep]}, + '_quad_tree': {'sources': [cython_gen.process('_quad_tree.pyx')], 'dependencies': [np_dep]}, } foreach ext_name, ext_dict : neighbors_extension_metadata diff --git a/sklearn/pipeline.py b/sklearn/pipeline.py index f3fbf1e3b3299..b291d970b1c79 100644 --- a/sklearn/pipeline.py +++ b/sklearn/pipeline.py @@ -16,9 +16,9 @@ from .exceptions import NotFittedError from .preprocessing import FunctionTransformer from .utils import Bunch -from .utils._estimator_html_repr import _VisualBlock from .utils._metadata_requests import METHODS from .utils._param_validation import HasMethods, Hidden +from .utils._repr_html.estimator import _VisualBlock from .utils._set_output import ( _get_container_adapter, _safe_set_output, diff --git a/sklearn/preprocessing/_function_transformer.py b/sklearn/preprocessing/_function_transformer.py index 3503fead2ba59..3d7592b17e2af 100644 --- a/sklearn/preprocessing/_function_transformer.py +++ b/sklearn/preprocessing/_function_transformer.py @@ -7,8 +7,8 @@ import numpy as np from ..base import BaseEstimator, TransformerMixin, _fit_context -from ..utils._estimator_html_repr import _VisualBlock from ..utils._param_validation import StrOptions +from ..utils._repr_html.estimator import _VisualBlock from ..utils._set_output import ( _get_adapter_from_container, _get_output_config, @@ -262,7 +262,7 @@ def transform(self, X): if hasattr(out, "columns") and self.feature_names_out is not None: # check the consistency between the column provided by `transform` and - # the the column names provided by `get_feature_names_out`. + # the column names provided by `get_feature_names_out`. feature_names_out = self.get_feature_names_out() if list(out.columns) != list(feature_names_out): # we can override the column names of the output if it is inconsistent diff --git a/sklearn/tests/test_base.py b/sklearn/tests/test_base.py index b65baa78802bc..e57d36351f0d4 100644 --- a/sklearn/tests/test_base.py +++ b/sklearn/tests/test_base.py @@ -992,3 +992,11 @@ def predict(self, X, prop=None): with warnings.catch_warnings(record=True) as record: CustomOutlierDetector().set_predict_request(prop=True).fit_predict([[1]], [1]) assert len(record) == 0 + + +def test_get_params_html(): + """Check the behaviour of the `_get_params_html` method.""" + est = MyEstimator(empty="test") + + assert est._get_params_html() == {"l1": 0, "empty": "test"} + assert est._get_params_html().non_default == ("empty",) diff --git a/sklearn/utils/__init__.py b/sklearn/utils/__init__.py index 941126c6b083f..8fd8a315a0be2 100644 --- a/sklearn/utils/__init__.py +++ b/sklearn/utils/__init__.py @@ -7,7 +7,6 @@ from . import metadata_routing from ._bunch import Bunch from ._chunking import gen_batches, gen_even_slices -from ._estimator_html_repr import estimator_html_repr # Make _safe_indexing importable from here for backward compat as this particular # helper is considered semi-private and typically very useful for third-party @@ -20,6 +19,8 @@ shuffle, ) from ._mask import safe_mask +from ._repr_html.base import _HTMLDocumentationLinkMixin # noqa: F401 +from ._repr_html.estimator import estimator_html_repr from ._tags import ( ClassifierTags, InputTags, diff --git a/sklearn/utils/_plotting.py b/sklearn/utils/_plotting.py index 946c95186374b..1a3883b7db7f5 100644 --- a/sklearn/utils/_plotting.py +++ b/sklearn/utils/_plotting.py @@ -1,13 +1,16 @@ # Authors: The scikit-learn developers # SPDX-License-Identifier: BSD-3-Clause +import warnings +from collections.abc import Mapping import numpy as np from . import check_consistent_length from ._optional_dependencies import check_matplotlib_support from ._response import _get_response_values_binary +from .fixes import parse_version from .multiclass import type_of_target -from .validation import _check_pos_label_consistency +from .validation import _check_pos_label_consistency, _num_samples class _BinaryClassifierCurveDisplayMixin: @@ -24,7 +27,10 @@ def _validate_plot_params(self, *, ax=None, name=None): if ax is None: _, ax = plt.subplots() - name = self.estimator_name if name is None else name + # Display classes are in process of changing from `estimator_name` to `name`. + # Try old attr name: `estimator_name` first. + if name is None: + name = getattr(self, "estimator_name", getattr(self, "name", None)) return ax, ax.figure, name @classmethod @@ -63,6 +69,186 @@ def _validate_from_predictions_params( return pos_label, name + @classmethod + def _validate_from_cv_results_params( + cls, + cv_results, + X, + y, + *, + sample_weight, + pos_label, + ): + check_matplotlib_support(f"{cls.__name__}.from_cv_results") + + required_keys = {"estimator", "indices"} + if not all(key in cv_results for key in required_keys): + raise ValueError( + "`cv_results` does not contain one of the following required keys: " + f"{required_keys}. Set explicitly the parameters " + "`return_estimator=True` and `return_indices=True` to the function" + "`cross_validate`." + ) + + train_size, test_size = ( + len(cv_results["indices"]["train"][0]), + len(cv_results["indices"]["test"][0]), + ) + + if _num_samples(X) != train_size + test_size: + raise ValueError( + "`X` does not contain the correct number of samples. " + f"Expected {train_size + test_size}, got {_num_samples(X)}." + ) + + if type_of_target(y) != "binary": + raise ValueError( + f"The target `y` is not binary. Got {type_of_target(y)} type of target." + ) + check_consistent_length(X, y, sample_weight) + + try: + pos_label = _check_pos_label_consistency(pos_label, y) + except ValueError as e: + # Adapt error message + raise ValueError(str(e).replace("y_true", "y")) + + return pos_label + + @staticmethod + def _get_legend_label(curve_legend_metric, curve_name, legend_metric_name): + """Helper to get legend label using `name` and `legend_metric`""" + if curve_legend_metric is not None and curve_name is not None: + label = f"{curve_name} ({legend_metric_name} = {curve_legend_metric:0.2f})" + elif curve_legend_metric is not None: + label = f"{legend_metric_name} = {curve_legend_metric:0.2f}" + elif curve_name is not None: + label = curve_name + else: + label = None + return label + + @staticmethod + def _validate_curve_kwargs( + n_curves, + name, + legend_metric, + legend_metric_name, + curve_kwargs, + **kwargs, + ): + """Get validated line kwargs for each curve. + + Parameters + ---------- + n_curves : int + Number of curves. + + name : list of str or None + Name for labeling legend entries. + + legend_metric : dict + Dictionary with "mean" and "std" keys, or "metric" key of metric + values for each curve. If None, "label" will not contain metric values. + + legend_metric_name : str + Name of the summary value provided in `legend_metrics`. + + curve_kwargs : dict or list of dict or None + Dictionary with keywords passed to the matplotlib's `plot` function + to draw the individual curves. If a list is provided, the + parameters are applied to the curves sequentially. If a single + dictionary is provided, the same parameters are applied to all + curves. + + **kwargs : dict + Deprecated. Keyword arguments to be passed to matplotlib's `plot`. + """ + # TODO(1.9): Remove deprecated **kwargs + if curve_kwargs and kwargs: + raise ValueError( + "Cannot provide both `curve_kwargs` and `kwargs`. `**kwargs` is " + "deprecated in 1.7 and will be removed in 1.9. Pass all matplotlib " + "arguments to `curve_kwargs` as a dictionary." + ) + if kwargs: + warnings.warn( + "`**kwargs` is deprecated and will be removed in 1.9. Pass all " + "matplotlib arguments to `curve_kwargs` as a dictionary instead.", + FutureWarning, + ) + curve_kwargs = kwargs + + if isinstance(curve_kwargs, list) and len(curve_kwargs) != n_curves: + raise ValueError( + f"`curve_kwargs` must be None, a dictionary or a list of length " + f"{n_curves}. Got: {curve_kwargs}." + ) + + # Ensure valid `name` and `curve_kwargs` combination. + if ( + isinstance(name, list) + and len(name) != 1 + and not isinstance(curve_kwargs, list) + ): + raise ValueError( + "To avoid labeling individual curves that have the same appearance, " + f"`curve_kwargs` should be a list of {n_curves} dictionaries. " + "Alternatively, set `name` to `None` or a single string to label " + "a single legend entry with mean ROC AUC score of all curves." + ) + + # Ensure `name` is of the correct length + if isinstance(name, str): + name = [name] + if isinstance(name, list) and len(name) == 1: + name = name * n_curves + name = [None] * n_curves if name is None else name + + # Ensure `curve_kwargs` is of correct length + if isinstance(curve_kwargs, Mapping): + curve_kwargs = [curve_kwargs] * n_curves + + default_multi_curve_kwargs = {"alpha": 0.5, "linestyle": "--", "color": "blue"} + if curve_kwargs is None: + if n_curves > 1: + curve_kwargs = [default_multi_curve_kwargs] * n_curves + else: + curve_kwargs = [{}] + + labels = [] + if "mean" in legend_metric: + label_aggregate = _BinaryClassifierCurveDisplayMixin._get_legend_label( + legend_metric["mean"], name[0], legend_metric_name + ) + # Note: "std" always `None` when "mean" is `None` - no metric value added + # to label in this case + if legend_metric["std"] is not None: + # Add the "+/- std" to the end (in brackets if name provided) + if name[0] is not None: + label_aggregate = ( + label_aggregate[:-1] + f" +/- {legend_metric['std']:0.2f})" + ) + else: + label_aggregate = ( + label_aggregate + f" +/- {legend_metric['std']:0.2f}" + ) + # Add `label` for first curve only, set to `None` for remaining curves + labels.extend([label_aggregate] + [None] * (n_curves - 1)) + else: + for curve_legend_metric, curve_name in zip(legend_metric["metric"], name): + labels.append( + _BinaryClassifierCurveDisplayMixin._get_legend_label( + curve_legend_metric, curve_name, legend_metric_name + ) + ) + + curve_kwargs_ = [ + _validate_style_kwargs({"label": label}, curve_kwargs[fold_idx]) + for fold_idx, label in enumerate(labels) + ] + return curve_kwargs_ + def _validate_score_name(score_name, scoring, negate_score): """Validate the `score_name` parameter. @@ -177,3 +363,57 @@ def _despine(ax): ax.spines[s].set_visible(False) for s in ["bottom", "left"]: ax.spines[s].set_bounds(0, 1) + + +def _deprecate_estimator_name(estimator_name, name, version): + """Deprecate `estimator_name` in favour of `name`.""" + version = parse_version(version) + version_remove = f"{version.major}.{version.minor + 2}" + if estimator_name != "deprecated": + if name: + raise ValueError( + "Cannot provide both `estimator_name` and `name`. `estimator_name` " + f"is deprecated in {version} and will be removed in {version_remove}. " + "Use `name` only." + ) + warnings.warn( + f"`estimator_name` is deprecated in {version} and will be removed in " + f"{version_remove}. Use `name` instead.", + FutureWarning, + ) + return estimator_name + return name + + +def _convert_to_list_leaving_none(param): + """Convert parameters to a list, leaving `None` as is.""" + if param is None: + return None + if isinstance(param, list): + return param + return [param] + + +def _check_param_lengths(required, optional, class_name): + """Check required and optional parameters are of the same length.""" + optional_provided = {} + for name, param in optional.items(): + if isinstance(param, list): + optional_provided[name] = param + + all_params = {**required, **optional_provided} + if len({len(param) for param in all_params.values()}) > 1: + param_keys = [key for key in all_params.keys()] + # Note: below code requires `len(param_keys) >= 2`, which is the case for all + # display classes + params_formatted = " and ".join([", ".join(param_keys[:-1]), param_keys[-1]]) + or_plot = "" + if "'name' (or self.name)" in param_keys: + or_plot = " (or `plot`)" + lengths_formatted = ", ".join( + f"{key}: {len(value)}" for key, value in all_params.items() + ) + raise ValueError( + f"{params_formatted} from `{class_name}` initialization{or_plot}, " + f"should all be lists of the same length. Got: {lengths_formatted}" + ) diff --git a/sklearn/utils/_repr_html/__init__.py b/sklearn/utils/_repr_html/__init__.py new file mode 100644 index 0000000000000..67dd18fb94b59 --- /dev/null +++ b/sklearn/utils/_repr_html/__init__.py @@ -0,0 +1,2 @@ +# Authors: The scikit-learn developers +# SPDX-License-Identifier: BSD-3-Clause diff --git a/sklearn/utils/_repr_html/base.py b/sklearn/utils/_repr_html/base.py new file mode 100644 index 0000000000000..28020a2a74698 --- /dev/null +++ b/sklearn/utils/_repr_html/base.py @@ -0,0 +1,152 @@ +# Authors: The scikit-learn developers +# SPDX-License-Identifier: BSD-3-Clause + +import itertools + +from ... import __version__ +from ..._config import get_config +from ..fixes import parse_version + + +class _HTMLDocumentationLinkMixin: + """Mixin class allowing to generate a link to the API documentation. + + This mixin relies on three attributes: + - `_doc_link_module`: it corresponds to the root module (e.g. `sklearn`). Using this + mixin, the default value is `sklearn`. + - `_doc_link_template`: it corresponds to the template used to generate the + link to the API documentation. Using this mixin, the default value is + `"https://scikit-learn.org/{version_url}/modules/generated/ + {estimator_module}.{estimator_name}.html"`. + - `_doc_link_url_param_generator`: it corresponds to a function that generates the + parameters to be used in the template when the estimator module and name are not + sufficient. + + The method :meth:`_get_doc_link` generates the link to the API documentation for a + given estimator. + + This useful provides all the necessary states for + :func:`sklearn.utils.estimator_html_repr` to generate a link to the API + documentation for the estimator HTML diagram. + + Examples + -------- + If the default values for `_doc_link_module`, `_doc_link_template` are not suitable, + then you can override them and provide a method to generate the URL parameters: + >>> from sklearn.base import BaseEstimator + >>> doc_link_template = "https://address.local/{single_param}.html" + >>> def url_param_generator(estimator): + ... return {"single_param": estimator.__class__.__name__} + >>> class MyEstimator(BaseEstimator): + ... # use "builtins" since it is the associated module when declaring + ... # the class in a docstring + ... _doc_link_module = "builtins" + ... _doc_link_template = doc_link_template + ... _doc_link_url_param_generator = url_param_generator + >>> estimator = MyEstimator() + >>> estimator._get_doc_link() + 'https://address.local/MyEstimator.html' + + If instead of overriding the attributes inside the class definition, you want to + override a class instance, you can use `types.MethodType` to bind the method to the + instance: + >>> import types + >>> estimator = BaseEstimator() + >>> estimator._doc_link_template = doc_link_template + >>> estimator._doc_link_url_param_generator = types.MethodType( + ... url_param_generator, estimator) + >>> estimator._get_doc_link() + 'https://address.local/BaseEstimator.html' + """ + + _doc_link_module = "sklearn" + _doc_link_url_param_generator = None + + @property + def _doc_link_template(self): + sklearn_version = parse_version(__version__) + if sklearn_version.dev is None: + version_url = f"{sklearn_version.major}.{sklearn_version.minor}" + else: + version_url = "dev" + return getattr( + self, + "__doc_link_template", + ( + f"https://scikit-learn.org/{version_url}/modules/generated/" + "{estimator_module}.{estimator_name}.html" + ), + ) + + @_doc_link_template.setter + def _doc_link_template(self, value): + setattr(self, "__doc_link_template", value) + + def _get_doc_link(self): + """Generates a link to the API documentation for a given estimator. + + This method generates the link to the estimator's documentation page + by using the template defined by the attribute `_doc_link_template`. + + Returns + ------- + url : str + The URL to the API documentation for this estimator. If the estimator does + not belong to module `_doc_link_module`, the empty string (i.e. `""`) is + returned. + """ + if self.__class__.__module__.split(".")[0] != self._doc_link_module: + return "" + + if self._doc_link_url_param_generator is None: + estimator_name = self.__class__.__name__ + # Construct the estimator's module name, up to the first private submodule. + # This works because in scikit-learn all public estimators are exposed at + # that level, even if they actually live in a private sub-module. + estimator_module = ".".join( + itertools.takewhile( + lambda part: not part.startswith("_"), + self.__class__.__module__.split("."), + ) + ) + return self._doc_link_template.format( + estimator_module=estimator_module, estimator_name=estimator_name + ) + return self._doc_link_template.format(**self._doc_link_url_param_generator()) + + +class ReprHTMLMixin: + """Mixin to handle consistently the HTML representation. + + When inheriting from this class, you need to define an attribute `_html_repr` + which is a callable that returns the HTML representation to be shown. + """ + + @property + def _repr_html_(self): + """HTML representation of estimator. + This is redundant with the logic of `_repr_mimebundle_`. The latter + should be favored in the long term, `_repr_html_` is only + implemented for consumers who do not interpret `_repr_mimbundle_`. + """ + if get_config()["display"] != "diagram": + raise AttributeError( + "_repr_html_ is only defined when the " + "'display' configuration option is set to " + "'diagram'" + ) + return self._repr_html_inner + + def _repr_html_inner(self): + """This function is returned by the @property `_repr_html_` to make + `hasattr(estimator, "_repr_html_") return `True` or `False` depending + on `get_config()["display"]`. + """ + return self._html_repr() + + def _repr_mimebundle_(self, **kwargs): + """Mime bundle used by jupyter kernels to display estimator""" + output = {"text/plain": repr(self)} + if get_config()["display"] == "diagram": + output["text/html"] = self._html_repr() + return output diff --git a/sklearn/utils/_estimator_html_repr.css b/sklearn/utils/_repr_html/estimator.css similarity index 99% rename from sklearn/utils/_estimator_html_repr.css rename to sklearn/utils/_repr_html/estimator.css index 0a8c277845cb1..ece8781c6bd76 100644 --- a/sklearn/utils/_estimator_html_repr.css +++ b/sklearn/utils/_repr_html/estimator.css @@ -178,9 +178,7 @@ clickable and can be expanded/collapsed. /* Toggleable content - dropdown */ #$id div.sk-toggleable__content { - max-height: 0; - max-width: 0; - overflow: hidden; + display: none; text-align: left; /* unfitted */ background-color: var(--sklearn-color-unfitted-level-0); @@ -206,9 +204,9 @@ clickable and can be expanded/collapsed. #$id input.sk-toggleable__control:checked~div.sk-toggleable__content { /* Expand drop-down */ - max-height: 200px; - max-width: 100%; - overflow: auto; + display: block; + width: 100%; + overflow: visible; } #$id input.sk-toggleable__control:checked~label.sk-toggleable__label-arrow:before { diff --git a/sklearn/utils/_repr_html/estimator.js b/sklearn/utils/_repr_html/estimator.js new file mode 100644 index 0000000000000..5de0a021c63bb --- /dev/null +++ b/sklearn/utils/_repr_html/estimator.js @@ -0,0 +1,42 @@ +function copyToClipboard(text, element) { + // Get the parameter prefix from the closest toggleable content + const toggleableContent = element.closest('.sk-toggleable__content'); + const paramPrefix = toggleableContent ? toggleableContent.dataset.paramPrefix : ''; + const fullParamName = paramPrefix ? `${paramPrefix}${text}` : text; + + const originalStyle = element.style; + const computedStyle = window.getComputedStyle(element); + const originalWidth = computedStyle.width; + const originalHTML = element.innerHTML.replace('Copied!', ''); + + navigator.clipboard.writeText(fullParamName) + .then(() => { + element.style.width = originalWidth; + element.style.color = 'green'; + element.innerHTML = "Copied!"; + + setTimeout(() => { + element.innerHTML = originalHTML; + element.style = originalStyle; + }, 2000); + }) + .catch(err => { + console.error('Failed to copy:', err); + element.style.color = 'red'; + element.innerHTML = "Failed!"; + setTimeout(() => { + element.innerHTML = originalHTML; + element.style = originalStyle; + }, 2000); + }); + return false; +} + +document.querySelectorAll('.fa-regular.fa-copy').forEach(function(element) { + const toggleableContent = element.closest('.sk-toggleable__content'); + const paramPrefix = toggleableContent ? toggleableContent.dataset.paramPrefix : ''; + const paramName = element.parentElement.nextElementSibling.textContent.trim(); + const fullParamName = paramPrefix ? `${paramPrefix}${paramName}` : paramName; + + element.setAttribute('title', fullParamName); +}); diff --git a/sklearn/utils/_estimator_html_repr.py b/sklearn/utils/_repr_html/estimator.py similarity index 76% rename from sklearn/utils/_estimator_html_repr.py rename to sklearn/utils/_repr_html/estimator.py index 90a700a26ce9c..7d101dde58d74 100644 --- a/sklearn/utils/_estimator_html_repr.py +++ b/sklearn/utils/_repr_html/estimator.py @@ -2,15 +2,13 @@ # SPDX-License-Identifier: BSD-3-Clause import html -import itertools from contextlib import closing from inspect import isclass from io import StringIO from pathlib import Path from string import Template -from .. import __version__, config_context -from .fixes import parse_version +from ... import config_context class _IDCounter: @@ -26,7 +24,13 @@ def get_id(self): def _get_css_style(): - return Path(__file__).with_suffix(".css").read_text(encoding="utf-8") + estimator_css_file = Path(__file__).parent / "estimator.css" + params_css_file = Path(__file__).parent / "params.css" + + estimator_css = estimator_css_file.read_text(encoding="utf-8") + params_css = params_css_file.read_text(encoding="utf-8") + + return f"{estimator_css}\n{params_css}" _CONTAINER_ID_COUNTER = _IDCounter("sk-container-id") @@ -103,6 +107,7 @@ def _sk_visual_block_(self): def _write_label_html( out, + params, name, name_details, name_caption=None, @@ -113,6 +118,7 @@ def _write_label_html( doc_link="", is_fitted_css_class="", is_fitted_icon="", + param_prefix="", ): """Write labeled html with or without a dropdown with named details. @@ -120,6 +126,10 @@ def _write_label_html( ---------- out : file-like object The file to write the HTML representation to. + params: str + If estimator has `get_params` method, this is the HTML representation + of the estimator's parameters and their values. When the estimator + does not have `get_params`, it is an empty string. name : str The label for the estimator. It corresponds either to the estimator class name for a simple estimator or in the case of a `Pipeline` and `ColumnTransformer`, @@ -151,13 +161,14 @@ def _write_label_html( is_fitted_icon : str, default="" The HTML representation to show the fitted information in the diagram. An empty string means that no information is shown. + param_prefix : str, default="" + The prefix to prepend to parameter names for nested estimators. """ out.write( f'
' ) name = html.escape(name) - if name_details is not None: name_details = html.escape(str(name_details)) checked_str = "checked" if checked else "" @@ -194,9 +205,15 @@ def _write_label_html( fmt_str = ( f'{label_html}
{name_details}'
-            "
" + f'class="sk-toggleable__content {is_fitted_css_class}" ' + f'data-param-prefix="{html.escape(param_prefix)}">' ) + + if params: + fmt_str = "".join([fmt_str, f"{params}
"]) + elif name_details and ("Pipeline" not in name): + fmt_str = "".join([fmt_str, f"
{name_details}
"]) + out.write(fmt_str) else: out.write(f"") @@ -254,6 +271,7 @@ def _write_estimator_html( is_fitted_css_class, is_fitted_icon="", first_call=False, + param_prefix="", ): """Write estimator to html in serial, parallel, or by itself (single). @@ -284,6 +302,9 @@ def _write_estimator_html( empty string. first_call : bool, default=False Whether this is the first time this function is called. + param_prefix : str, default="" + The prefix to prepend to parameter names for nested estimators. + For example, in a pipeline this might be "pipeline__stepname__". """ if first_call: est_block = _get_visual_block(estimator) @@ -302,13 +323,22 @@ def _write_estimator_html( out.write(f'
') if estimator_label: + if hasattr(estimator, "get_params") and hasattr( + estimator, "_get_params_html" + ): + params = estimator._get_params_html(deep=False)._repr_html_inner() + else: + params = "" + _write_label_html( out, + params, estimator_label, estimator_label_details, doc_link=doc_link, is_fitted_css_class=is_fitted_css_class, is_fitted_icon=is_fitted_icon, + param_prefix=param_prefix, ) kind = est_block.kind @@ -316,6 +346,17 @@ def _write_estimator_html( est_infos = zip(est_block.estimators, est_block.names, est_block.name_details) for est, name, name_details in est_infos: + # Build the parameter prefix for nested estimators + + if param_prefix and hasattr(name, "split"): + # If we already have a prefix, append the new component + new_prefix = f"{param_prefix}{name.split(':')[0]}__" + elif hasattr(name, "split"): + # If this is the first level, start the prefix + new_prefix = f"{name.split(':')[0]}__" if name else "" + else: + new_prefix = param_prefix + if kind == "serial": _write_estimator_html( out, @@ -323,6 +364,7 @@ def _write_estimator_html( name, name_details, is_fitted_css_class=is_fitted_css_class, + param_prefix=new_prefix, ) else: # parallel out.write('
') @@ -334,13 +376,20 @@ def _write_estimator_html( name, name_details, is_fitted_css_class=is_fitted_css_class, + param_prefix=new_prefix, ) out.write("
") # sk-parallel-item out.write("
") elif est_block.kind == "single": + if hasattr(estimator, "_get_params_html"): + params = estimator._get_params_html()._repr_html_inner() + else: + params = "" + _write_label_html( out, + params, est_block.names, est_block.name_details, est_block.name_caption, @@ -351,6 +400,7 @@ def _write_estimator_html( doc_link=doc_link, is_fitted_css_class=is_fitted_css_class, is_fitted_icon=is_fitted_icon, + param_prefix=param_prefix, ) @@ -371,10 +421,10 @@ def estimator_html_repr(estimator): Examples -------- - >>> from sklearn.utils._estimator_html_repr import estimator_html_repr + >>> from sklearn.utils._repr_html.estimator import estimator_html_repr >>> from sklearn.linear_model import LogisticRegression >>> estimator_html_repr(LogisticRegression()) - '" + f"" f'
' '
' f"
{html.escape(estimator_str)}
{fallback_msg}" @@ -426,7 +477,6 @@ def estimator_html_repr(estimator): ) out.write(html_template) - _write_estimator_html( out, estimator, @@ -436,114 +486,12 @@ def estimator_html_repr(estimator): is_fitted_css_class=is_fitted_css_class, is_fitted_icon=is_fitted_icon, ) - out.write("
") - - html_output = out.getvalue() - return html_output - + with open(str(Path(__file__).parent / "estimator.js"), "r") as f: + script = f.read() -class _HTMLDocumentationLinkMixin: - """Mixin class allowing to generate a link to the API documentation. + html_end = f"" - This mixin relies on three attributes: - - `_doc_link_module`: it corresponds to the root module (e.g. `sklearn`). Using this - mixin, the default value is `sklearn`. - - `_doc_link_template`: it corresponds to the template used to generate the - link to the API documentation. Using this mixin, the default value is - `"https://scikit-learn.org/{version_url}/modules/generated/ - {estimator_module}.{estimator_name}.html"`. - - `_doc_link_url_param_generator`: it corresponds to a function that generates the - parameters to be used in the template when the estimator module and name are not - sufficient. + out.write(html_end) - The method :meth:`_get_doc_link` generates the link to the API documentation for a - given estimator. - - This useful provides all the necessary states for - :func:`sklearn.utils.estimator_html_repr` to generate a link to the API - documentation for the estimator HTML diagram. - - Examples - -------- - If the default values for `_doc_link_module`, `_doc_link_template` are not suitable, - then you can override them and provide a method to generate the URL parameters: - >>> from sklearn.base import BaseEstimator - >>> doc_link_template = "https://address.local/{single_param}.html" - >>> def url_param_generator(estimator): - ... return {"single_param": estimator.__class__.__name__} - >>> class MyEstimator(BaseEstimator): - ... # use "builtins" since it is the associated module when declaring - ... # the class in a docstring - ... _doc_link_module = "builtins" - ... _doc_link_template = doc_link_template - ... _doc_link_url_param_generator = url_param_generator - >>> estimator = MyEstimator() - >>> estimator._get_doc_link() - 'https://address.local/MyEstimator.html' - - If instead of overriding the attributes inside the class definition, you want to - override a class instance, you can use `types.MethodType` to bind the method to the - instance: - >>> import types - >>> estimator = BaseEstimator() - >>> estimator._doc_link_template = doc_link_template - >>> estimator._doc_link_url_param_generator = types.MethodType( - ... url_param_generator, estimator) - >>> estimator._get_doc_link() - 'https://address.local/BaseEstimator.html' - """ - - _doc_link_module = "sklearn" - _doc_link_url_param_generator = None - - @property - def _doc_link_template(self): - sklearn_version = parse_version(__version__) - if sklearn_version.dev is None: - version_url = f"{sklearn_version.major}.{sklearn_version.minor}" - else: - version_url = "dev" - return getattr( - self, - "__doc_link_template", - ( - f"https://scikit-learn.org/{version_url}/modules/generated/" - "{estimator_module}.{estimator_name}.html" - ), - ) - - @_doc_link_template.setter - def _doc_link_template(self, value): - setattr(self, "__doc_link_template", value) - - def _get_doc_link(self): - """Generates a link to the API documentation for a given estimator. - - This method generates the link to the estimator's documentation page - by using the template defined by the attribute `_doc_link_template`. - - Returns - ------- - url : str - The URL to the API documentation for this estimator. If the estimator does - not belong to module `_doc_link_module`, the empty string (i.e. `""`) is - returned. - """ - if self.__class__.__module__.split(".")[0] != self._doc_link_module: - return "" - - if self._doc_link_url_param_generator is None: - estimator_name = self.__class__.__name__ - # Construct the estimator's module name, up to the first private submodule. - # This works because in scikit-learn all public estimators are exposed at - # that level, even if they actually live in a private sub-module. - estimator_module = ".".join( - itertools.takewhile( - lambda part: not part.startswith("_"), - self.__class__.__module__.split("."), - ) - ) - return self._doc_link_template.format( - estimator_module=estimator_module, estimator_name=estimator_name - ) - return self._doc_link_template.format(**self._doc_link_url_param_generator()) + html_output = out.getvalue() + return html_output diff --git a/sklearn/utils/_repr_html/params.css b/sklearn/utils/_repr_html/params.css new file mode 100644 index 0000000000000..df815f966ffcf --- /dev/null +++ b/sklearn/utils/_repr_html/params.css @@ -0,0 +1,63 @@ +.estimator-table summary { + padding: .5rem; + font-family: monospace; + cursor: pointer; +} + +.estimator-table details[open] { + padding-left: 0.1rem; + padding-right: 0.1rem; + padding-bottom: 0.3rem; +} + +.estimator-table .parameters-table { + margin-left: auto !important; + margin-right: auto !important; +} + +.estimator-table .parameters-table tr:nth-child(odd) { + background-color: #fff; +} + +.estimator-table .parameters-table tr:nth-child(even) { + background-color: #f6f6f6; +} + +.estimator-table .parameters-table tr:hover { + background-color: #e0e0e0; +} + +.estimator-table table td { + border: 1px solid rgba(106, 105, 104, 0.232); +} + +.user-set td { + color:rgb(255, 94, 0); + text-align: left; +} + +.user-set td.value pre { + color:rgb(255, 94, 0) !important; + background-color: transparent !important; +} + +.default td { + color: black; + text-align: left; +} + +.user-set td i, +.default td i { + color: black; +} + +.copy-paste-icon { + background-image: url(data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHZpZXdCb3g9IjAgMCA0NDggNTEyIj48IS0tIUZvbnQgQXdlc29tZSBGcmVlIDYuNy4yIGJ5IEBmb250YXdlc29tZSAtIGh0dHBzOi8vZm9udGF3ZXNvbWUuY29tIExpY2Vuc2UgLSBodHRwczovL2ZvbnRhd2Vzb21lLmNvbS9saWNlbnNlL2ZyZWUgQ29weXJpZ2h0IDIwMjUgRm9udGljb25zLCBJbmMuLS0+PHBhdGggZD0iTTIwOCAwTDMzMi4xIDBjMTIuNyAwIDI0LjkgNS4xIDMzLjkgMTQuMWw2Ny45IDY3LjljOSA5IDE0LjEgMjEuMiAxNC4xIDMzLjlMNDQ4IDMzNmMwIDI2LjUtMjEuNSA0OC00OCA0OGwtMTkyIDBjLTI2LjUgMC00OC0yMS41LTQ4LTQ4bDAtMjg4YzAtMjYuNSAyMS41LTQ4IDQ4LTQ4ek00OCAxMjhsODAgMCAwIDY0LTY0IDAgMCAyNTYgMTkyIDAgMC0zMiA2NCAwIDAgNDhjMCAyNi41LTIxLjUgNDgtNDggNDhMNDggNTEyYy0yNi41IDAtNDgtMjEuNS00OC00OEwwIDE3NmMwLTI2LjUgMjEuNS00OCA0OC00OHoiLz48L3N2Zz4=); + background-repeat: no-repeat; + background-size: 14px 14px; + background-position: 0; + display: inline-block; + width: 14px; + height: 14px; + cursor: pointer; +} diff --git a/sklearn/utils/_repr_html/params.py b/sklearn/utils/_repr_html/params.py new file mode 100644 index 0000000000000..d85bf1280a8fc --- /dev/null +++ b/sklearn/utils/_repr_html/params.py @@ -0,0 +1,83 @@ +# Authors: The scikit-learn developers +# SPDX-License-Identifier: BSD-3-Clause + +import html +import reprlib +from collections import UserDict + +from sklearn.utils._repr_html.base import ReprHTMLMixin + + +def _read_params(name, value, non_default_params): + """Categorizes parameters as 'default' or 'user-set' and formats their values. + Escapes or truncates parameter values for display safety and readability. + """ + r = reprlib.Repr() + r.maxlist = 2 # Show only first 2 items of lists + r.maxtuple = 1 # Show only first item of tuples + r.maxstring = 50 # Limit string length + cleaned_value = html.escape(r.repr(value)) + + param_type = "user-set" if name in non_default_params else "default" + + return {"param_type": param_type, "param_name": name, "param_value": cleaned_value} + + +def _params_html_repr(params): + """Generate HTML representation of estimator parameters. + + Creates an HTML table with parameter names and values, wrapped in a + collapsible details element. Parameters are styled differently based + on whether they are default or user-set values. + """ + HTML_TEMPLATE = """ +
+
+ Parameters + + + {rows} + +
+
+
+ """ + ROW_TEMPLATE = """ + + + {param_name}  + {param_value} + + """ + + rows = [ + ROW_TEMPLATE.format(**_read_params(name, value, params.non_default)) + for name, value in params.items() + ] + + return HTML_TEMPLATE.format(rows="\n".join(rows)) + + +class ParamsDict(ReprHTMLMixin, UserDict): + """Dictionary-like class to store and provide an HTML representation. + + It builds an HTML structure to be used with Jupyter notebooks or similar + environments. It allows storing metadata to track non-default parameters. + + Parameters + ---------- + params : dict, default=None + The original dictionary of parameters and their values. + + non_default : tuple + The list of non-default parameters. + """ + + _html_repr = _params_html_repr + + def __init__(self, params=None, non_default=tuple()): + super().__init__(params or {}) + self.non_default = non_default diff --git a/sklearn/utils/_repr_html/tests/__init__.py b/sklearn/utils/_repr_html/tests/__init__.py new file mode 100644 index 0000000000000..e69de29bb2d1d diff --git a/sklearn/utils/tests/test_estimator_html_repr.py b/sklearn/utils/_repr_html/tests/test_estimator.py similarity index 95% rename from sklearn/utils/tests/test_estimator_html_repr.py rename to sklearn/utils/_repr_html/tests/test_estimator.py index c1c35d29c4472..cc975d854ed8f 100644 --- a/sklearn/utils/tests/test_estimator_html_repr.py +++ b/sklearn/utils/_repr_html/tests/test_estimator.py @@ -29,10 +29,10 @@ from sklearn.preprocessing import FunctionTransformer, OneHotEncoder, StandardScaler from sklearn.svm import LinearSVC, LinearSVR from sklearn.tree import DecisionTreeClassifier -from sklearn.utils._estimator_html_repr import ( +from sklearn.utils._repr_html.base import _HTMLDocumentationLinkMixin +from sklearn.utils._repr_html.estimator import ( _get_css_style, _get_visual_block, - _HTMLDocumentationLinkMixin, _write_label_html, estimator_html_repr, ) @@ -47,10 +47,11 @@ def dummy_function(x, y): def test_write_label_html(checked): # Test checking logic and labeling name = "LogisticRegression" + params = "" tool_tip = "hello-world" with closing(StringIO()) as out: - _write_label_html(out, name, tool_tip, checked=checked) + _write_label_html(out, params, name, tool_tip, checked=checked) html_label = out.getvalue() p = ( @@ -60,9 +61,9 @@ def test_write_label_html(checked): ) re_compiled = re.compile(p) assert re_compiled.search(html_label) - assert html_label.startswith('
') assert "
hello-world
" in html_label + if checked: assert "checked>" in html_label @@ -199,9 +200,7 @@ def test_estimator_html_repr_pipeline(): # top level estimators show estimator with changes assert html.escape(str(pipe)) in html_output for _, est in pipe.steps: - assert ( - '
' + html.escape(str(est))
-        ) in html_output
+        assert html.escape(str(est))[:44] in html_output
 
     # low level estimators do not show changes
     with config_context(print_changed_only=True):
@@ -217,18 +216,19 @@ def test_estimator_html_repr_pipeline():
             assert f"" in html_output
 
         pca = feat_u.transformer_list[0][1]
-        assert f"
{html.escape(str(pca))}
" in html_output + + assert html.escape(str(pca)) in html_output tsvd = feat_u.transformer_list[1][1] first = tsvd["first"] select = tsvd["select"] - assert f"
{html.escape(str(first))}
" in html_output - assert f"
{html.escape(str(select))}
" in html_output + assert html.escape(str(first)) in html_output + assert html.escape(str(select)) in html_output # voting classifier for name, est in clf.estimators: - assert f"" in html_output - assert f"
{html.escape(str(est))}
" in html_output + assert html.escape(name) in html_output + assert html.escape(str(est)) in html_output # verify that prefers-color-scheme is implemented assert "prefers-color-scheme" in html_output @@ -248,7 +248,7 @@ def test_stacking_classifier(final_estimator): # If final_estimator's default changes from LogisticRegression # this should be updated if final_estimator is None: - assert "LogisticRegression(" in html_output + assert "LogisticRegression" in html_output else: assert final_estimator.__class__.__name__ in html_output @@ -431,7 +431,7 @@ def test_html_documentation_link_mixin_sklearn(mock_version): """ # mock the `__version__` where the mixin is located - with patch("sklearn.utils._estimator_html_repr.__version__", mock_version): + with patch("sklearn.utils._repr_html.base.__version__", mock_version): mixin = _HTMLDocumentationLinkMixin() assert mixin._doc_link_module == "sklearn" @@ -608,3 +608,9 @@ def test_function_transformer_show_caption(func, expected_name): ) re_compiled = re.compile(p) assert re_compiled.search(html_output) + + +def test_estimator_html_repr_table(): + """Check that we add the table of parameters in the HTML representation.""" + est = LogisticRegression(C=10.0, fit_intercept=False) + assert "parameters-table" in estimator_html_repr(est) diff --git a/sklearn/utils/_repr_html/tests/test_params.py b/sklearn/utils/_repr_html/tests/test_params.py new file mode 100644 index 0000000000000..dd1c7dfb9aff7 --- /dev/null +++ b/sklearn/utils/_repr_html/tests/test_params.py @@ -0,0 +1,74 @@ +import pytest + +from sklearn import config_context +from sklearn.utils._repr_html.params import ParamsDict, _params_html_repr, _read_params + + +def test_params_dict_content(): + """Check the behavior of the ParamsDict class.""" + params = ParamsDict({"a": 1, "b": 2}) + assert params["a"] == 1 + assert params["b"] == 2 + assert params.non_default == () + + params = ParamsDict({"a": 1, "b": 2}, non_default=("a",)) + assert params["a"] == 1 + assert params["b"] == 2 + assert params.non_default == ("a",) + + +def test_params_dict_repr_html_(): + params = ParamsDict({"a": 1, "b": 2}, non_default=("a",)) + out = params._repr_html_() + assert "Parameters" in out + + with config_context(display="text"): + msg = "_repr_html_ is only defined when" + with pytest.raises(AttributeError, match=msg): + params._repr_html_() + + +def test_params_dict_repr_mimebundle(): + params = ParamsDict({"a": 1, "b": 2}, non_default=("a",)) + out = params._repr_mimebundle_() + + assert "text/plain" in out + assert "text/html" in out + assert "Parameters" in out["text/html"] + assert out["text/plain"] == "{'a': 1, 'b': 2}" + + with config_context(display="text"): + out = params._repr_mimebundle_() + assert "text/plain" in out + assert "text/html" not in out + + +def test_read_params(): + """Check the behavior of the `_read_params` function.""" + out = _read_params("a", 1, tuple()) + assert out["param_type"] == "default" + assert out["param_name"] == "a" + assert out["param_value"] == "1" + + # check non-default parameters + out = _read_params("a", 1, ("a",)) + assert out["param_type"] == "user-set" + assert out["param_name"] == "a" + assert out["param_value"] == "1" + + # check that we escape html tags + tag_injection = "" + out = _read_params("a", tag_injection, tuple()) + assert ( + out["param_value"] + == ""<script>alert('xss')</script>"" + ) + assert out["param_name"] == "a" + assert out["param_type"] == "default" + + +def test_params_html_repr(): + """Check returned HTML template""" + params = ParamsDict({"a": 1, "b": 2}) + assert "parameters-table" in _params_html_repr(params) + assert "estimator-table" in _params_html_repr(params) diff --git a/sklearn/utils/fixes.py b/sklearn/utils/fixes.py index 02e723963448b..d85ef82680bbb 100644 --- a/sklearn/utils/fixes.py +++ b/sklearn/utils/fixes.py @@ -288,7 +288,7 @@ def _smallest_admissible_index_dtype(arrays=(), maxval=None, check_contents=Fals type that can hold the data in the arrays. This function returns `np.int64` if it either required by `maxval` or based on the - largest precision of the dtype of the arrays passed as argument, or by the their + largest precision of the dtype of the arrays passed as argument, or by their contents (when `check_contents is True`). If none of the condition requires `np.int64` then this function returns `np.int32`. diff --git a/sklearn/utils/meson.build b/sklearn/utils/meson.build index 9ac2454172c9a..ae490e987a4ff 100644 --- a/sklearn/utils/meson.build +++ b/sklearn/utils/meson.build @@ -20,7 +20,7 @@ utils_extension_metadata = { '_cython_blas': {'sources': [cython_gen.process('_cython_blas.pyx')]}, 'arrayfuncs': {'sources': [cython_gen.process('arrayfuncs.pyx')]}, 'murmurhash': { - 'sources': ['murmurhash.pyx', 'src' / 'MurmurHash3.cpp'], + 'sources': [cython_gen.process('murmurhash.pyx'), 'src' / 'MurmurHash3.cpp'], }, '_fast_dict': {'sources': [cython_gen_cpp.process('_fast_dict.pyx')]}, diff --git a/sklearn/utils/optimize.py b/sklearn/utils/optimize.py index cddabfd419376..a0d21b1796582 100644 --- a/sklearn/utils/optimize.py +++ b/sklearn/utils/optimize.py @@ -352,25 +352,37 @@ def _check_optimize_result(solver, result, max_iter=None, extra_warning_msg=None """ # handle both scipy and scikit-learn solver names if solver == "lbfgs": - if result.status != 0: - result_message = result.message + if max_iter is not None: + # In scipy <= 1.0.0, nit may exceed maxiter for lbfgs. + # See https://github.com/scipy/scipy/issues/7854 + n_iter_i = min(result.nit, max_iter) + else: + n_iter_i = result.nit + if result.status != 0: warning_msg = ( - "{} failed to converge (status={}):\n{}.\n\n" - "Increase the number of iterations (max_iter) " - "or scale the data as shown in:\n" + f"{solver} failed to converge after {n_iter_i} iteration(s) " + f"(status={result.status}):\n" + f"{result.message}\n" + ) + # Append a recommendation to increase iterations only when the + # number of iterations reaches the maximum allowed (max_iter), + # as this suggests the optimization may have been prematurely + # terminated due to the iteration limit. + if max_iter is not None and n_iter_i == max_iter: + warning_msg += ( + f"\nIncrease the number of iterations to improve the " + f"convergence (max_iter={max_iter})." + ) + warning_msg += ( + "\nYou might also want to scale the data as shown in:\n" " https://scikit-learn.org/stable/modules/" "preprocessing.html" - ).format(solver, result.status, result_message) + ) if extra_warning_msg is not None: warning_msg += "\n" + extra_warning_msg warnings.warn(warning_msg, ConvergenceWarning, stacklevel=2) - if max_iter is not None: - # In scipy <= 1.0.0, nit may exceed maxiter for lbfgs. - # See https://github.com/scipy/scipy/issues/7854 - n_iter_i = min(result.nit, max_iter) - else: - n_iter_i = result.nit + else: raise NotImplementedError diff --git a/sklearn/utils/tests/test_array_api.py b/sklearn/utils/tests/test_array_api.py index 164e3024a31e7..4dfbfd4d62ea1 100644 --- a/sklearn/utils/tests/test_array_api.py +++ b/sklearn/utils/tests/test_array_api.py @@ -294,7 +294,7 @@ def __init__(self, device_name): assert array1.device == device(array1, array1, array2) -# TODO: add cupy to the list of libraries once the the following upstream issue +# TODO: add cupy to the list of libraries once the following upstream issue # has been fixed: # https://github.com/cupy/cupy/issues/8180 @skip_if_array_api_compat_not_configured @@ -581,10 +581,14 @@ def test_count_nonzero( @pytest.mark.parametrize("wrap", [True, False]) def test_fill_or_add_to_diagonal(array_namespace, device_, dtype_name, wrap): xp = _array_api_for_tests(array_namespace, device_) - array_np = numpy.zeros((5, 4), dtype=numpy.int64) - array_xp = xp.asarray(array_np) - _fill_or_add_to_diagonal(array_xp, value=1, xp=xp, add_value=False, wrap=wrap) + + array_np = numpy.zeros((5, 4), dtype=dtype_name) + array_xp = xp.asarray(array_np.copy(), device=device_) + numpy.fill_diagonal(array_np, val=1, wrap=wrap) + with config_context(array_api_dispatch=True): + _fill_or_add_to_diagonal(array_xp, value=1, xp=xp, add_value=False, wrap=wrap) + assert_array_equal(_convert_to_numpy(array_xp, xp=xp), array_np) diff --git a/sklearn/utils/tests/test_optimize.py b/sklearn/utils/tests/test_optimize.py index 775da5791b9a6..f99f3a9131808 100644 --- a/sklearn/utils/tests/test_optimize.py +++ b/sklearn/utils/tests/test_optimize.py @@ -1,10 +1,13 @@ +import warnings + import numpy as np import pytest from scipy.optimize import fmin_ncg from sklearn.exceptions import ConvergenceWarning +from sklearn.utils._bunch import Bunch from sklearn.utils._testing import assert_allclose -from sklearn.utils.optimize import _newton_cg +from sklearn.utils.optimize import _check_optimize_result, _newton_cg def test_newton_cg(global_random_seed): @@ -160,3 +163,58 @@ def test_newton_cg_verbosity(capsys, verbose): ] for m in msg: assert m in captured.out + + +def test_check_optimize(): + # Mock some lbfgs output using a Bunch instance: + result = Bunch() + + # First case: no warnings + result.nit = 1 + result.status = 0 + result.message = "OK" + + with warnings.catch_warnings(): + warnings.simplefilter("error") + _check_optimize_result("lbfgs", result) + + # Second case: warning about implicit `max_iter`: do not recommend the user + # to increase `max_iter` this is not a user settable parameter. + result.status = 1 + result.message = "STOP: TOTAL NO. OF ITERATIONS REACHED LIMIT" + with pytest.warns(ConvergenceWarning) as record: + _check_optimize_result("lbfgs", result) + + assert len(record) == 1 + warn_msg = record[0].message.args[0] + assert "lbfgs failed to converge after 1 iteration(s)" in warn_msg + assert result.message in warn_msg + assert "Increase the number of iterations" not in warn_msg + assert "scale the data" in warn_msg + + # Third case: warning about explicit `max_iter`: recommend user to increase + # `max_iter`. + with pytest.warns(ConvergenceWarning) as record: + _check_optimize_result("lbfgs", result, max_iter=1) + + assert len(record) == 1 + warn_msg = record[0].message.args[0] + assert "lbfgs failed to converge after 1 iteration(s)" in warn_msg + assert result.message in warn_msg + assert "Increase the number of iterations" in warn_msg + assert "scale the data" in warn_msg + + # Fourth case: other convergence problem before reaching `max_iter`: do not + # recommend increasing `max_iter`. + result.nit = 2 + result.status = 2 + result.message = "ABNORMAL" + with pytest.warns(ConvergenceWarning) as record: + _check_optimize_result("lbfgs", result, max_iter=10) + + assert len(record) == 1 + warn_msg = record[0].message.args[0] + assert "lbfgs failed to converge after 2 iteration(s)" in warn_msg + assert result.message in warn_msg + assert "Increase the number of iterations" not in warn_msg + assert "scale the data" in warn_msg diff --git a/sklearn/utils/tests/test_plotting.py b/sklearn/utils/tests/test_plotting.py index 1f0c675577bca..db2f797ac2547 100644 --- a/sklearn/utils/tests/test_plotting.py +++ b/sklearn/utils/tests/test_plotting.py @@ -1,12 +1,388 @@ import numpy as np import pytest +from sklearn.linear_model import LogisticRegression from sklearn.utils._plotting import ( + _BinaryClassifierCurveDisplayMixin, + _deprecate_estimator_name, _despine, _interval_max_min_ratio, _validate_score_name, _validate_style_kwargs, ) +from sklearn.utils._response import _get_response_values_binary +from sklearn.utils._testing import assert_allclose + + +@pytest.mark.parametrize("ax", [None, "Ax"]) +@pytest.mark.parametrize( + "name, expected_name_out", [(None, "TestEstimator"), ("CustomName", "CustomName")] +) +def test_validate_plot_params(pyplot, ax, name, expected_name_out): + """Check `_validate_plot_params` returns the correct values.""" + display = _BinaryClassifierCurveDisplayMixin() + display.estimator_name = "TestEstimator" + if ax: + _, ax = pyplot.subplots() + ax_out, _, name_out = display._validate_plot_params(ax=ax, name=name) + + assert name_out == expected_name_out + + if ax: + assert ax == ax_out + + +@pytest.mark.parametrize("pos_label", [None, 0]) +@pytest.mark.parametrize("name", [None, "CustomName"]) +@pytest.mark.parametrize( + "response_method", ["auto", "predict_proba", "decision_function"] +) +def test_validate_and_get_response_values(pyplot, pos_label, name, response_method): + """Check `_validate_and_get_response_values` returns the correct values.""" + X = np.array([[0, 0], [1, 1], [2, 2], [3, 3]]) + y = np.array([0, 0, 2, 2]) + estimator = LogisticRegression().fit(X, y) + + y_pred, pos_label, name_out = ( + _BinaryClassifierCurveDisplayMixin._validate_and_get_response_values( + estimator, + X, + y, + response_method=response_method, + pos_label=pos_label, + name=name, + ) + ) + + expected_y_pred, expected_pos_label = _get_response_values_binary( + estimator, X, response_method=response_method, pos_label=pos_label + ) + + assert_allclose(y_pred, expected_y_pred) + assert pos_label == expected_pos_label + + # Check name is handled correctly + expected_name = name if name is not None else "LogisticRegression" + assert name_out == expected_name + + +@pytest.mark.parametrize( + "y_true, error_message", + [ + (np.array([0, 1, 2]), "The target y is not binary."), + (np.array([0, 1]), "Found input variables with inconsistent"), + (np.array([0, 2, 0, 2]), r"y_true takes value in \{0, 2\} and pos_label"), + ], +) +def test_validate_from_predictions_params_errors(pyplot, y_true, error_message): + """Check `_validate_from_predictions_params` raises the correct errors.""" + y_pred = np.array([0.1, 0.2, 0.3, 0.4]) + sample_weight = np.ones(4) + + with pytest.raises(ValueError, match=error_message): + _BinaryClassifierCurveDisplayMixin._validate_from_predictions_params( + y_true=y_true, + y_pred=y_pred, + sample_weight=sample_weight, + pos_label=None, + ) + + +@pytest.mark.parametrize("name", [None, "CustomName"]) +@pytest.mark.parametrize( + "pos_label, y_true", + [ + (None, np.array([0, 1, 0, 1])), + (2, np.array([0, 2, 0, 2])), + ], +) +def test_validate_from_predictions_params_returns(pyplot, name, pos_label, y_true): + """Check `_validate_from_predictions_params` returns the correct values.""" + y_pred = np.array([0.1, 0.2, 0.3, 0.4]) + pos_label_out, name_out = ( + _BinaryClassifierCurveDisplayMixin._validate_from_predictions_params( + y_true=y_true, + y_pred=y_pred, + sample_weight=None, + pos_label=pos_label, + name=name, + ) + ) + + # Check name is handled correctly + expected_name = name if name is not None else "Classifier" + assert name_out == expected_name + + # Check pos_label is handled correctly + expected_pos_label = pos_label if pos_label is not None else 1 + assert pos_label_out == expected_pos_label + + +@pytest.mark.parametrize( + "params, err_msg", + [ + ( + { + # Missing "indices" key + "cv_results": {"estimator": "dummy"}, + "X": np.array([[1, 2], [3, 4]]), + "y": np.array([0, 1]), + "sample_weight": None, + "pos_label": None, + }, + "`cv_results` does not contain one of the following", + ), + ( + { + "cv_results": { + "estimator": "dummy", + "indices": {"test": [[1, 2], [1, 2]], "train": [[3, 4], [3, 4]]}, + }, + # `X` wrong length + "X": np.array([[1, 2]]), + "y": np.array([0, 1]), + "sample_weight": None, + "pos_label": None, + }, + "`X` does not contain the correct number of", + ), + ( + { + "cv_results": { + "estimator": "dummy", + "indices": {"test": [[1, 2], [1, 2]], "train": [[3, 4], [3, 4]]}, + }, + "X": np.array([1, 2, 3, 4]), + # `y` not binary + "y": np.array([0, 2, 1, 3]), + "sample_weight": None, + "pos_label": None, + }, + "The target `y` is not binary", + ), + ( + { + "cv_results": { + "estimator": "dummy", + "indices": {"test": [[1, 2], [1, 2]], "train": [[3, 4], [3, 4]]}, + }, + "X": np.array([1, 2, 3, 4]), + "y": np.array([0, 1, 0, 1]), + # `sample_weight` wrong length + "sample_weight": np.array([0.5]), + "pos_label": None, + }, + "Found input variables with inconsistent", + ), + ( + { + "cv_results": { + "estimator": "dummy", + "indices": {"test": [[1, 2], [1, 2]], "train": [[3, 4], [3, 4]]}, + }, + "X": np.array([1, 2, 3, 4]), + "y": np.array([2, 3, 2, 3]), + "sample_weight": None, + # Not specified when `y` not in {0, 1} or {-1, 1} + "pos_label": None, + }, + "y takes value in {2, 3} and pos_label is not specified", + ), + ], +) +def test_validate_from_cv_results_params(pyplot, params, err_msg): + """Check parameter validation is performed correctly.""" + with pytest.raises(ValueError, match=err_msg): + _BinaryClassifierCurveDisplayMixin()._validate_from_cv_results_params(**params) + + +@pytest.mark.parametrize( + "curve_legend_metric, curve_name, expected_label", + [ + (0.85, None, "AUC = 0.85"), + (None, "Model A", "Model A"), + (0.95, "Random Forest", "Random Forest (AUC = 0.95)"), + (None, None, None), + ], +) +def test_get_legend_label(curve_legend_metric, curve_name, expected_label): + """Check `_get_legend_label` returns the correct label.""" + legend_metric_name = "AUC" + label = _BinaryClassifierCurveDisplayMixin._get_legend_label( + curve_legend_metric, curve_name, legend_metric_name + ) + assert label == expected_label + + +# TODO(1.9) : Remove +@pytest.mark.parametrize("curve_kwargs", [{"alpha": 1.0}, None]) +@pytest.mark.parametrize("kwargs", [{}, {"alpha": 1.0}]) +def test_validate_curve_kwargs_deprecate_kwargs(curve_kwargs, kwargs): + """Check `_validate_curve_kwargs` deprecates kwargs correctly.""" + n_curves = 1 + name = None + legend_metric = {"mean": 0.8, "std": 0.1} + legend_metric_name = "AUC" + + if curve_kwargs and kwargs: + with pytest.raises(ValueError, match="Cannot provide both `curve_kwargs`"): + _BinaryClassifierCurveDisplayMixin._validate_curve_kwargs( + n_curves, + name, + legend_metric, + legend_metric_name, + curve_kwargs, + **kwargs, + ) + elif kwargs: + with pytest.warns(FutureWarning, match=r"`\*\*kwargs` is deprecated and"): + _BinaryClassifierCurveDisplayMixin._validate_curve_kwargs( + n_curves, + name, + legend_metric, + legend_metric_name, + curve_kwargs, + **kwargs, + ) + else: + # No warning or error should be raised + _BinaryClassifierCurveDisplayMixin._validate_curve_kwargs( + n_curves, name, legend_metric, legend_metric_name, curve_kwargs, **kwargs + ) + + +def test_validate_curve_kwargs_error(): + """Check `_validate_curve_kwargs` performs parameter validation correctly.""" + n_curves = 3 + legend_metric = {"mean": 0.8, "std": 0.1} + legend_metric_name = "AUC" + with pytest.raises(ValueError, match="`curve_kwargs` must be None"): + _BinaryClassifierCurveDisplayMixin._validate_curve_kwargs( + n_curves=n_curves, + name=None, + legend_metric=legend_metric, + legend_metric_name=legend_metric_name, + curve_kwargs=[{"alpha": 1.0}], + ) + with pytest.raises(ValueError, match="To avoid labeling individual curves"): + name = ["one", "two", "three"] + _BinaryClassifierCurveDisplayMixin._validate_curve_kwargs( + n_curves=n_curves, + name=name, + legend_metric=legend_metric, + legend_metric_name=legend_metric_name, + curve_kwargs=None, + ) + _BinaryClassifierCurveDisplayMixin._validate_curve_kwargs( + n_curves=n_curves, + name=name, + legend_metric=legend_metric, + legend_metric_name=legend_metric_name, + curve_kwargs={"alpha": 1.0}, + ) + + +@pytest.mark.parametrize("name", [None, "curve_name", ["curve_name"]]) +@pytest.mark.parametrize( + "legend_metric", + [ + {"mean": 0.8, "std": 0.2}, + {"mean": None, "std": None}, + ], +) +@pytest.mark.parametrize("legend_metric_name", ["AUC", "AP"]) +@pytest.mark.parametrize( + "curve_kwargs", + [ + None, + {"color": "red"}, + ], +) +def test_validate_curve_kwargs_single_legend( + name, legend_metric, legend_metric_name, curve_kwargs +): + """Check `_validate_curve_kwargs` returns correct kwargs for single legend entry.""" + n_curves = 3 + curve_kwargs_out = _BinaryClassifierCurveDisplayMixin._validate_curve_kwargs( + n_curves=n_curves, + name=name, + legend_metric=legend_metric, + legend_metric_name=legend_metric_name, + curve_kwargs=curve_kwargs, + ) + + assert isinstance(curve_kwargs_out, list) + assert len(curve_kwargs_out) == n_curves + + expected_label = None + if isinstance(name, list): + name = name[0] + if name is not None: + expected_label = name + if legend_metric["mean"] is not None: + expected_label = expected_label + f" ({legend_metric_name} = 0.80 +/- 0.20)" + # `name` is None + elif legend_metric["mean"] is not None: + expected_label = f"{legend_metric_name} = 0.80 +/- 0.20" + + assert curve_kwargs_out[0]["label"] == expected_label + # All remaining curves should have None as "label" + assert curve_kwargs_out[1]["label"] is None + assert curve_kwargs_out[2]["label"] is None + + # Default multi-curve kwargs + if curve_kwargs is None: + assert all(len(kwargs) == 4 for kwargs in curve_kwargs_out) + assert all(kwargs["alpha"] == 0.5 for kwargs in curve_kwargs_out) + assert all(kwargs["linestyle"] == "--" for kwargs in curve_kwargs_out) + assert all(kwargs["color"] == "blue" for kwargs in curve_kwargs_out) + else: + assert all(len(kwargs) == 2 for kwargs in curve_kwargs_out) + assert all(kwargs["color"] == "red" for kwargs in curve_kwargs_out) + + +@pytest.mark.parametrize("name", [None, "curve_name", ["one", "two", "three"]]) +@pytest.mark.parametrize( + "legend_metric", [{"metric": [1.0, 1.0, 1.0]}, {"metric": [None, None, None]}] +) +@pytest.mark.parametrize("legend_metric_name", ["AUC", "AP"]) +def test_validate_curve_kwargs_multi_legend(name, legend_metric, legend_metric_name): + """Check `_validate_curve_kwargs` returns correct kwargs for multi legend entry.""" + n_curves = 3 + curve_kwargs = [{"color": "red"}, {"color": "yellow"}, {"color": "blue"}] + curve_kwargs_out = _BinaryClassifierCurveDisplayMixin._validate_curve_kwargs( + n_curves=n_curves, + name=name, + legend_metric=legend_metric, + legend_metric_name=legend_metric_name, + curve_kwargs=curve_kwargs, + ) + + assert isinstance(curve_kwargs_out, list) + assert len(curve_kwargs_out) == n_curves + + expected_labels = [None, None, None] + if isinstance(name, str): + expected_labels = "curve_name" + if legend_metric["metric"][0] is not None: + expected_labels = expected_labels + f" ({legend_metric_name} = 1.00)" + expected_labels = [expected_labels] * n_curves + elif isinstance(name, list) and legend_metric["metric"][0] is None: + expected_labels = name + elif isinstance(name, list) and legend_metric["metric"][0] is not None: + expected_labels = [ + f"{name_single} ({legend_metric_name} = 1.00)" for name_single in name + ] + # `name` is None + elif legend_metric["metric"][0] is not None: + expected_labels = [f"{legend_metric_name} = 1.00"] * n_curves + + for idx, expected_label in enumerate(expected_labels): + assert curve_kwargs_out[idx]["label"] == expected_label + + assert all(len(kwargs) == 2 for kwargs in curve_kwargs_out) + for curve_kwarg, curve_kwarg_out in zip(curve_kwargs, curve_kwargs_out): + assert curve_kwarg_out["color"] == curve_kwarg["color"] def metric(): @@ -138,3 +514,31 @@ def test_despine(pyplot): assert ax.spines["right"].get_visible() is False assert ax.spines["bottom"].get_bounds() == (0, 1) assert ax.spines["left"].get_bounds() == (0, 1) + + +@pytest.mark.parametrize("estimator_name", ["my_est_name", "deprecated"]) +@pytest.mark.parametrize("name", [None, "my_name"]) +def test_deprecate_estimator_name(estimator_name, name): + """Check `_deprecate_estimator_name` behaves correctly""" + version = "1.7" + version_remove = "1.9" + + if estimator_name == "deprecated": + name_out = _deprecate_estimator_name(estimator_name, name, version) + assert name_out == name + # `estimator_name` is provided and `name` is: + elif name is None: + warning_message = ( + f"`estimator_name` is deprecated in {version} and will be removed in " + f"{version_remove}. Use `name` instead." + ) + with pytest.warns(FutureWarning, match=warning_message): + result = _deprecate_estimator_name(estimator_name, name, version) + assert result == estimator_name + elif name is not None: + error_message = ( + f"Cannot provide both `estimator_name` and `name`. `estimator_name` " + f"is deprecated in {version} and will be removed in {version_remove}. " + ) + with pytest.raises(ValueError, match=error_message): + _deprecate_estimator_name(estimator_name, name, version) diff --git a/sklearn/utils/validation.py b/sklearn/utils/validation.py index 324827323168a..86bdd07c41f1c 100644 --- a/sklearn/utils/validation.py +++ b/sklearn/utils/validation.py @@ -2169,16 +2169,18 @@ def _check_sample_weight( """ n_samples = _num_samples(X) - if dtype is not None and dtype not in [np.float32, np.float64]: - dtype = np.float64 + xp, _ = get_namespace(X) + + if dtype is not None and dtype not in [xp.float32, xp.float64]: + dtype = xp.float64 if sample_weight is None: - sample_weight = np.ones(n_samples, dtype=dtype) + sample_weight = xp.ones(n_samples, dtype=dtype) elif isinstance(sample_weight, numbers.Number): - sample_weight = np.full(n_samples, sample_weight, dtype=dtype) + sample_weight = xp.full(n_samples, sample_weight, dtype=dtype) else: if dtype is None: - dtype = [np.float64, np.float32] + dtype = [xp.float64, xp.float32] sample_weight = check_array( sample_weight, accept_sparse=False, pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy