lenskit / lkpy

Python recommendation toolkit
https://lkpy.lenskit.org
MIT License
270 stars 61 forks source link

Implement ranking metrics with item lists #500

Closed mdekstrand closed 4 weeks ago

mdekstrand commented 4 weeks ago

This adds item list versions of the ranking metrics (right now in parallel with the old metrics, until more eval code is updated).

Moves the ball on #489.

Also renames the prediction metrics to uppercase like the top-N ones.

github-actions[bot] commented 4 weeks ago

The LensKit 🤖 has run the tests on your PR.

✅ Tests covered 96.58% of diff.

✅ Coverage increased 0.11% from 92.40% to 92.51%.

origin/main...HEAD, staged and unstaged changes - lenskit/lenskit/data/items.py (100%) - lenskit/lenskit/metrics/ranking/__init__.py (100%) - lenskit/lenskit/metrics/ranking/_base.py (90.0%): Missing lines 32,41 - lenskit/lenskit/metrics/ranking/_dcg.py (97.8%): Missing lines 65 - lenskit/lenskit/metrics/ranking/_hit.py (100%) - lenskit/lenskit/metrics/ranking/_pr.py (100%) - lenskit/lenskit/metrics/ranking/_rbp.py (95.8%): Missing lines 54 - lenskit/lenskit/metrics/ranking/_recip.py (92.9%): Missing lines 23 ## Summary - **Total**: 146 lines - **Missing**: 5 lines - **Coverage**: 96%
Source Coverage Report | Name | Stmts | Miss | Cover | |------------------------------------------------ | -------: | -------: | ------: | | lenskit/lenskit/util/envcheck.py | 57 | 44 | 23% | | lenskit/lenskit/data/fetch.py | 38 | 28 | 26% | | lenskit/lenskit/data/types.py | 38 | 13 | 66% | | lenskit/lenskit/util/\_\_init\_\_.py | 72 | 19 | 74% | | lenskit/lenskit/splitting/split.py | 25 | 6 | 76% | | lenskit/lenskit/topn.py | 109 | 25 | 77% | | lenskit/lenskit/data/movielens.py | 97 | 18 | 81% | | lenskit/lenskit/util/test.py | 104 | 19 | 82% | | lenskit/lenskit/pipeline/state.py | 44 | 8 | 82% | | lenskit/lenskit/parallel/config.py | 65 | 11 | 83% | | lenskit/lenskit/parallel/pool.py | 54 | 9 | 83% | | lenskit/lenskit/algorithms/svd.py | 75 | 12 | 84% | | lenskit/lenskit/basic/composite.py | 20 | 3 | 85% | | lenskit/lenskit/algorithms/ranking.py | 75 | 11 | 85% | | lenskit/lenskit/algorithms/\_\_init\_\_.py | 67 | 8 | 88% | | lenskit/lenskit/util/random.py | 34 | 4 | 88% | | lenskit-implicit/lenskit/implicit.py | 94 | 10 | 89% | | lenskit/lenskit/metrics/ranking/\_base.py | 20 | 2 | 90% | | lenskit/lenskit/batch/\_recommend.py | 46 | 4 | 91% | | lenskit/lenskit/data/items.py | 213 | 18 | 92% | | lenskit/lenskit/data/vocab.py | 84 | 7 | 92% | | lenskit/lenskit/metrics/predict.py | 72 | 6 | 92% | | lenskit/lenskit/metrics/ranking/\_recip.py | 14 | 1 | 93% | | lenskit/lenskit/splitting/holdout.py | 56 | 4 | 93% | | lenskit/lenskit/parallel/worker.py | 43 | 3 | 93% | | lenskit/lenskit/batch/\_predict.py | 30 | 2 | 93% | | lenskit/lenskit/math/sparse.py | 60 | 4 | 93% | | lenskit/lenskit/parallel/invoker.py | 31 | 2 | 94% | | lenskit/lenskit/algorithms/knn/user.py | 177 | 11 | 94% | | lenskit/lenskit/basic/popularity.py | 34 | 2 | 94% | | lenskit/lenskit/pipeline/components.py | 51 | 3 | 94% | | lenskit/lenskit/pipeline/types.py | 86 | 5 | 94% | | lenskit/lenskit/algorithms/knn/item.py | 302 | 17 | 94% | | lenskit/lenskit/data/dataset.py | 131 | 7 | 95% | | lenskit/lenskit/data/mtarray.py | 57 | 3 | 95% | | lenskit/lenskit/data/matrix.py | 233 | 12 | 95% | | lenskit/lenskit/parallel/chunking.py | 20 | 1 | 95% | | lenskit/lenskit/basic/bias.py | 93 | 4 | 96% | | lenskit-funksvd/lenskit/funksvd.py | 187 | 8 | 96% | | lenskit/lenskit/metrics/ranking/\_rbp.py | 24 | 1 | 96% | | lenskit/lenskit/basic/topn.py | 26 | 1 | 96% | | lenskit/lenskit/pipeline/\_\_init\_\_.py | 291 | 11 | 96% | | lenskit/lenskit/data/lazy.py | 34 | 1 | 97% | | lenskit/lenskit/algorithms/basic.py | 161 | 4 | 98% | | lenskit/lenskit/algorithms/als/explicit.py | 121 | 3 | 98% | | lenskit/lenskit/metrics/ranking/\_dcg.py | 46 | 1 | 98% | | lenskit/lenskit/algorithms/bias.py | 150 | 3 | 98% | | lenskit/lenskit/parallel/serialize.py | 51 | 1 | 98% | | lenskit/lenskit/algorithms/als/common.py | 128 | 2 | 98% | | lenskit/lenskit/crossfold.py | 136 | 2 | 99% | | lenskit/lenskit/pipeline/config.py | 83 | 1 | 99% | | lenskit/lenskit/pipeline/runner.py | 98 | 1 | 99% | | lenskit/lenskit/algorithms/als/implicit.py | 112 | 1 | 99% | | lenskit/lenskit/metrics/topn.py | 212 | 1 | 99% | | lenskit-hpf/lenskit/hpf.py | 24 | 0 | 100% | | lenskit/lenskit/algorithms/als/\_\_init\_\_.py | 3 | 0 | 100% | | lenskit/lenskit/algorithms/knn/\_\_init\_\_.py | 3 | 0 | 100% | | lenskit/lenskit/algorithms/mf\_common.py | 61 | 0 | 100% | | lenskit/lenskit/basic/\_\_init\_\_.py | 6 | 0 | 100% | | lenskit/lenskit/basic/candidates.py | 25 | 0 | 100% | | lenskit/lenskit/basic/history.py | 60 | 0 | 100% | | lenskit/lenskit/basic/random.py | 25 | 0 | 100% | | lenskit/lenskit/batch/\_\_init\_\_.py | 2 | 0 | 100% | | lenskit/lenskit/data/\_\_init\_\_.py | 10 | 0 | 100% | | lenskit/lenskit/data/checks.py | 37 | 0 | 100% | | lenskit/lenskit/data/convert.py | 50 | 0 | 100% | | lenskit/lenskit/data/query.py | 27 | 0 | 100% | | lenskit/lenskit/data/tables.py | 25 | 0 | 100% | | lenskit/lenskit/diagnostics.py | 4 | 0 | 100% | | lenskit/lenskit/math/\_\_init\_\_.py | 0 | 0 | 100% | | lenskit/lenskit/math/solve.py | 6 | 0 | 100% | | lenskit/lenskit/metrics/\_\_init\_\_.py | 0 | 0 | 100% | | lenskit/lenskit/metrics/ranking/\_\_init\_\_.py | 6 | 0 | 100% | | lenskit/lenskit/metrics/ranking/\_hit.py | 9 | 0 | 100% | | lenskit/lenskit/metrics/ranking/\_pr.py | 21 | 0 | 100% | | lenskit/lenskit/parallel/\_\_init\_\_.py | 4 | 0 | 100% | | lenskit/lenskit/parallel/sequential.py | 22 | 0 | 100% | | lenskit/lenskit/pipeline/common.py | 18 | 0 | 100% | | lenskit/lenskit/pipeline/nodes.py | 47 | 0 | 100% | | lenskit/lenskit/splitting/\_\_init\_\_.py | 4 | 0 | 100% | | lenskit/lenskit/splitting/records.py | 57 | 0 | 100% | | lenskit/lenskit/splitting/users.py | 61 | 0 | 100% | | lenskit/lenskit/types.py | 5 | 0 | 100% | | lenskit/lenskit/util/logging.py | 19 | 0 | 100% | | lenskit/lenskit/util/timing.py | 28 | 0 | 100% | | **TOTAL** | **5450** | **408** | **93%** |
codecov[bot] commented 4 weeks ago

Codecov Report

Attention: Patch coverage is 96.91358% with 5 lines in your changes missing coverage. Please review.

Project coverage is 92.75%. Comparing base (f50cbdc) to head (52ef6da). Report is 17 commits behind head on main.

Files with missing lines Patch % Lines
lenskit/lenskit/metrics/ranking/_base.py 90.90% 2 Missing :warning:
lenskit/lenskit/metrics/ranking/_dcg.py 97.87% 1 Missing :warning:
lenskit/lenskit/metrics/ranking/_rbp.py 96.00% 1 Missing :warning:
lenskit/lenskit/metrics/ranking/_recip.py 93.33% 1 Missing :warning:
Additional details and impacted files ```diff @@ Coverage Diff @@ ## main #500 +/- ## ========================================== + Coverage 92.64% 92.75% +0.11% ========================================== Files 78 85 +7 Lines 5478 5632 +154 ========================================== + Hits 5075 5224 +149 - Misses 403 408 +5 ```

:umbrella: View full report in Codecov by Sentry.
:loudspeaker: Have feedback on the report? Share it here.

github-actions[bot] commented 4 weeks ago

The LensKit 🤖 has run the tests on your PR.

✅ Tests covered 96.58% of diff.

✅ Coverage increased 0.11% from 92.40% to 92.51%.

origin/main...HEAD, staged and unstaged changes - lenskit/lenskit/data/items.py (100%) - lenskit/lenskit/metrics/ranking/__init__.py (100%) - lenskit/lenskit/metrics/ranking/_base.py (90.0%): Missing lines 32,41 - lenskit/lenskit/metrics/ranking/_dcg.py (97.8%): Missing lines 65 - lenskit/lenskit/metrics/ranking/_hit.py (100%) - lenskit/lenskit/metrics/ranking/_pr.py (100%) - lenskit/lenskit/metrics/ranking/_rbp.py (95.8%): Missing lines 54 - lenskit/lenskit/metrics/ranking/_recip.py (92.9%): Missing lines 23 ## Summary - **Total**: 146 lines - **Missing**: 5 lines - **Coverage**: 96%
Source Coverage Report | Name | Stmts | Miss | Cover | |------------------------------------------------ | -------: | -------: | ------: | | lenskit/lenskit/util/envcheck.py | 57 | 44 | 23% | | lenskit/lenskit/data/fetch.py | 38 | 28 | 26% | | lenskit/lenskit/data/types.py | 38 | 13 | 66% | | lenskit/lenskit/util/\_\_init\_\_.py | 72 | 19 | 74% | | lenskit/lenskit/splitting/split.py | 25 | 6 | 76% | | lenskit/lenskit/topn.py | 109 | 25 | 77% | | lenskit/lenskit/data/movielens.py | 97 | 18 | 81% | | lenskit/lenskit/util/test.py | 104 | 19 | 82% | | lenskit/lenskit/pipeline/state.py | 44 | 8 | 82% | | lenskit/lenskit/parallel/config.py | 65 | 11 | 83% | | lenskit/lenskit/parallel/pool.py | 54 | 9 | 83% | | lenskit/lenskit/algorithms/svd.py | 75 | 12 | 84% | | lenskit/lenskit/basic/composite.py | 20 | 3 | 85% | | lenskit/lenskit/algorithms/ranking.py | 75 | 11 | 85% | | lenskit/lenskit/algorithms/\_\_init\_\_.py | 67 | 8 | 88% | | lenskit/lenskit/util/random.py | 34 | 4 | 88% | | lenskit-implicit/lenskit/implicit.py | 94 | 10 | 89% | | lenskit/lenskit/metrics/ranking/\_base.py | 20 | 2 | 90% | | lenskit/lenskit/batch/\_recommend.py | 46 | 4 | 91% | | lenskit/lenskit/data/items.py | 213 | 18 | 92% | | lenskit/lenskit/data/vocab.py | 84 | 7 | 92% | | lenskit/lenskit/metrics/predict.py | 72 | 6 | 92% | | lenskit/lenskit/metrics/ranking/\_recip.py | 14 | 1 | 93% | | lenskit/lenskit/splitting/holdout.py | 56 | 4 | 93% | | lenskit/lenskit/parallel/worker.py | 43 | 3 | 93% | | lenskit/lenskit/batch/\_predict.py | 30 | 2 | 93% | | lenskit/lenskit/math/sparse.py | 60 | 4 | 93% | | lenskit/lenskit/parallel/invoker.py | 31 | 2 | 94% | | lenskit/lenskit/algorithms/knn/user.py | 177 | 11 | 94% | | lenskit/lenskit/basic/popularity.py | 34 | 2 | 94% | | lenskit/lenskit/pipeline/components.py | 51 | 3 | 94% | | lenskit/lenskit/pipeline/types.py | 86 | 5 | 94% | | lenskit/lenskit/algorithms/knn/item.py | 302 | 17 | 94% | | lenskit/lenskit/data/dataset.py | 131 | 7 | 95% | | lenskit/lenskit/data/mtarray.py | 57 | 3 | 95% | | lenskit/lenskit/data/matrix.py | 233 | 12 | 95% | | lenskit/lenskit/parallel/chunking.py | 20 | 1 | 95% | | lenskit/lenskit/basic/bias.py | 93 | 4 | 96% | | lenskit-funksvd/lenskit/funksvd.py | 187 | 8 | 96% | | lenskit/lenskit/metrics/ranking/\_rbp.py | 24 | 1 | 96% | | lenskit/lenskit/basic/topn.py | 26 | 1 | 96% | | lenskit/lenskit/pipeline/\_\_init\_\_.py | 291 | 11 | 96% | | lenskit/lenskit/data/lazy.py | 34 | 1 | 97% | | lenskit/lenskit/algorithms/basic.py | 161 | 4 | 98% | | lenskit/lenskit/algorithms/als/explicit.py | 121 | 3 | 98% | | lenskit/lenskit/metrics/ranking/\_dcg.py | 46 | 1 | 98% | | lenskit/lenskit/algorithms/bias.py | 150 | 3 | 98% | | lenskit/lenskit/parallel/serialize.py | 51 | 1 | 98% | | lenskit/lenskit/algorithms/als/common.py | 128 | 2 | 98% | | lenskit/lenskit/crossfold.py | 136 | 2 | 99% | | lenskit/lenskit/pipeline/config.py | 83 | 1 | 99% | | lenskit/lenskit/pipeline/runner.py | 98 | 1 | 99% | | lenskit/lenskit/algorithms/als/implicit.py | 112 | 1 | 99% | | lenskit/lenskit/metrics/topn.py | 212 | 1 | 99% | | lenskit-hpf/lenskit/hpf.py | 24 | 0 | 100% | | lenskit/lenskit/algorithms/als/\_\_init\_\_.py | 3 | 0 | 100% | | lenskit/lenskit/algorithms/knn/\_\_init\_\_.py | 3 | 0 | 100% | | lenskit/lenskit/algorithms/mf\_common.py | 61 | 0 | 100% | | lenskit/lenskit/basic/\_\_init\_\_.py | 6 | 0 | 100% | | lenskit/lenskit/basic/candidates.py | 25 | 0 | 100% | | lenskit/lenskit/basic/history.py | 60 | 0 | 100% | | lenskit/lenskit/basic/random.py | 25 | 0 | 100% | | lenskit/lenskit/batch/\_\_init\_\_.py | 2 | 0 | 100% | | lenskit/lenskit/data/\_\_init\_\_.py | 10 | 0 | 100% | | lenskit/lenskit/data/checks.py | 37 | 0 | 100% | | lenskit/lenskit/data/convert.py | 50 | 0 | 100% | | lenskit/lenskit/data/query.py | 27 | 0 | 100% | | lenskit/lenskit/data/tables.py | 25 | 0 | 100% | | lenskit/lenskit/diagnostics.py | 4 | 0 | 100% | | lenskit/lenskit/math/\_\_init\_\_.py | 0 | 0 | 100% | | lenskit/lenskit/math/solve.py | 6 | 0 | 100% | | lenskit/lenskit/metrics/\_\_init\_\_.py | 0 | 0 | 100% | | lenskit/lenskit/metrics/ranking/\_\_init\_\_.py | 6 | 0 | 100% | | lenskit/lenskit/metrics/ranking/\_hit.py | 9 | 0 | 100% | | lenskit/lenskit/metrics/ranking/\_pr.py | 21 | 0 | 100% | | lenskit/lenskit/parallel/\_\_init\_\_.py | 4 | 0 | 100% | | lenskit/lenskit/parallel/sequential.py | 22 | 0 | 100% | | lenskit/lenskit/pipeline/common.py | 18 | 0 | 100% | | lenskit/lenskit/pipeline/nodes.py | 47 | 0 | 100% | | lenskit/lenskit/splitting/\_\_init\_\_.py | 4 | 0 | 100% | | lenskit/lenskit/splitting/records.py | 57 | 0 | 100% | | lenskit/lenskit/splitting/users.py | 61 | 0 | 100% | | lenskit/lenskit/types.py | 5 | 0 | 100% | | lenskit/lenskit/util/logging.py | 19 | 0 | 100% | | lenskit/lenskit/util/timing.py | 28 | 0 | 100% | | **TOTAL** | **5450** | **408** | **93%** |
github-actions[bot] commented 4 weeks ago

The LensKit 🤖 has run the tests on your PR.

✅ Tests covered 96.73% of diff.

✅ Coverage increased 0.11% from 92.40% to 92.52%.

origin/main...HEAD, staged and unstaged changes - lenskit/lenskit/data/items.py (100%) - lenskit/lenskit/metrics/predict.py (100%) - lenskit/lenskit/metrics/ranking/__init__.py (100%) - lenskit/lenskit/metrics/ranking/_base.py (90.0%): Missing lines 32,41 - lenskit/lenskit/metrics/ranking/_dcg.py (97.8%): Missing lines 65 - lenskit/lenskit/metrics/ranking/_hit.py (100%) - lenskit/lenskit/metrics/ranking/_pr.py (100%) - lenskit/lenskit/metrics/ranking/_rbp.py (95.8%): Missing lines 54 - lenskit/lenskit/metrics/ranking/_recip.py (92.9%): Missing lines 23 ## Summary - **Total**: 153 lines - **Missing**: 5 lines - **Coverage**: 96%
Source Coverage Report | Name | Stmts | Miss | Cover | |------------------------------------------------ | -------: | -------: | ------: | | lenskit/lenskit/util/envcheck.py | 57 | 44 | 23% | | lenskit/lenskit/data/fetch.py | 38 | 28 | 26% | | lenskit/lenskit/data/types.py | 38 | 13 | 66% | | lenskit/lenskit/util/\_\_init\_\_.py | 72 | 19 | 74% | | lenskit/lenskit/splitting/split.py | 25 | 6 | 76% | | lenskit/lenskit/topn.py | 109 | 25 | 77% | | lenskit/lenskit/data/movielens.py | 97 | 18 | 81% | | lenskit/lenskit/util/test.py | 104 | 19 | 82% | | lenskit/lenskit/pipeline/state.py | 44 | 8 | 82% | | lenskit/lenskit/parallel/config.py | 65 | 11 | 83% | | lenskit/lenskit/parallel/pool.py | 54 | 9 | 83% | | lenskit/lenskit/algorithms/svd.py | 75 | 12 | 84% | | lenskit/lenskit/basic/composite.py | 20 | 3 | 85% | | lenskit/lenskit/algorithms/ranking.py | 75 | 11 | 85% | | lenskit/lenskit/algorithms/\_\_init\_\_.py | 67 | 8 | 88% | | lenskit/lenskit/util/random.py | 34 | 4 | 88% | | lenskit-implicit/lenskit/implicit.py | 94 | 10 | 89% | | lenskit/lenskit/metrics/ranking/\_base.py | 20 | 2 | 90% | | lenskit/lenskit/batch/\_recommend.py | 46 | 4 | 91% | | lenskit/lenskit/data/items.py | 213 | 18 | 92% | | lenskit/lenskit/data/vocab.py | 84 | 7 | 92% | | lenskit/lenskit/metrics/predict.py | 72 | 6 | 92% | | lenskit/lenskit/metrics/ranking/\_recip.py | 14 | 1 | 93% | | lenskit/lenskit/splitting/holdout.py | 56 | 4 | 93% | | lenskit/lenskit/parallel/worker.py | 43 | 3 | 93% | | lenskit/lenskit/batch/\_predict.py | 30 | 2 | 93% | | lenskit/lenskit/math/sparse.py | 60 | 4 | 93% | | lenskit/lenskit/parallel/invoker.py | 31 | 2 | 94% | | lenskit/lenskit/algorithms/knn/user.py | 177 | 11 | 94% | | lenskit/lenskit/basic/popularity.py | 34 | 2 | 94% | | lenskit/lenskit/pipeline/components.py | 51 | 3 | 94% | | lenskit/lenskit/pipeline/types.py | 86 | 5 | 94% | | lenskit/lenskit/algorithms/knn/item.py | 302 | 17 | 94% | | lenskit/lenskit/data/dataset.py | 131 | 7 | 95% | | lenskit/lenskit/data/mtarray.py | 57 | 3 | 95% | | lenskit/lenskit/data/matrix.py | 233 | 12 | 95% | | lenskit/lenskit/parallel/chunking.py | 20 | 1 | 95% | | lenskit/lenskit/basic/bias.py | 93 | 4 | 96% | | lenskit-funksvd/lenskit/funksvd.py | 187 | 8 | 96% | | lenskit/lenskit/metrics/ranking/\_rbp.py | 24 | 1 | 96% | | lenskit/lenskit/basic/topn.py | 26 | 1 | 96% | | lenskit/lenskit/pipeline/\_\_init\_\_.py | 291 | 11 | 96% | | lenskit/lenskit/data/lazy.py | 34 | 1 | 97% | | lenskit/lenskit/algorithms/basic.py | 161 | 4 | 98% | | lenskit/lenskit/algorithms/als/explicit.py | 121 | 3 | 98% | | lenskit/lenskit/metrics/ranking/\_dcg.py | 46 | 1 | 98% | | lenskit/lenskit/algorithms/bias.py | 150 | 3 | 98% | | lenskit/lenskit/parallel/serialize.py | 51 | 1 | 98% | | lenskit/lenskit/algorithms/als/common.py | 128 | 2 | 98% | | lenskit/lenskit/crossfold.py | 136 | 2 | 99% | | lenskit/lenskit/pipeline/config.py | 83 | 1 | 99% | | lenskit/lenskit/pipeline/runner.py | 98 | 1 | 99% | | lenskit/lenskit/algorithms/als/implicit.py | 112 | 1 | 99% | | lenskit/lenskit/metrics/topn.py | 212 | 1 | 99% | | lenskit-hpf/lenskit/hpf.py | 24 | 0 | 100% | | lenskit/lenskit/algorithms/als/\_\_init\_\_.py | 3 | 0 | 100% | | lenskit/lenskit/algorithms/knn/\_\_init\_\_.py | 3 | 0 | 100% | | lenskit/lenskit/algorithms/mf\_common.py | 61 | 0 | 100% | | lenskit/lenskit/basic/\_\_init\_\_.py | 6 | 0 | 100% | | lenskit/lenskit/basic/candidates.py | 25 | 0 | 100% | | lenskit/lenskit/basic/history.py | 60 | 0 | 100% | | lenskit/lenskit/basic/random.py | 25 | 0 | 100% | | lenskit/lenskit/batch/\_\_init\_\_.py | 2 | 0 | 100% | | lenskit/lenskit/data/\_\_init\_\_.py | 10 | 0 | 100% | | lenskit/lenskit/data/checks.py | 37 | 0 | 100% | | lenskit/lenskit/data/convert.py | 50 | 0 | 100% | | lenskit/lenskit/data/query.py | 27 | 0 | 100% | | lenskit/lenskit/data/tables.py | 25 | 0 | 100% | | lenskit/lenskit/diagnostics.py | 4 | 0 | 100% | | lenskit/lenskit/math/\_\_init\_\_.py | 0 | 0 | 100% | | lenskit/lenskit/math/solve.py | 6 | 0 | 100% | | lenskit/lenskit/metrics/\_\_init\_\_.py | 0 | 0 | 100% | | lenskit/lenskit/metrics/ranking/\_\_init\_\_.py | 7 | 0 | 100% | | lenskit/lenskit/metrics/ranking/\_hit.py | 9 | 0 | 100% | | lenskit/lenskit/metrics/ranking/\_pr.py | 21 | 0 | 100% | | lenskit/lenskit/parallel/\_\_init\_\_.py | 4 | 0 | 100% | | lenskit/lenskit/parallel/sequential.py | 22 | 0 | 100% | | lenskit/lenskit/pipeline/common.py | 18 | 0 | 100% | | lenskit/lenskit/pipeline/nodes.py | 47 | 0 | 100% | | lenskit/lenskit/splitting/\_\_init\_\_.py | 4 | 0 | 100% | | lenskit/lenskit/splitting/records.py | 57 | 0 | 100% | | lenskit/lenskit/splitting/users.py | 61 | 0 | 100% | | lenskit/lenskit/types.py | 5 | 0 | 100% | | lenskit/lenskit/util/logging.py | 19 | 0 | 100% | | lenskit/lenskit/util/timing.py | 28 | 0 | 100% | | **TOTAL** | **5451** | **408** | **93%** |
github-actions[bot] commented 4 weeks ago

The LensKit 🤖 has run the tests on your PR.

✅ Tests covered 96.73% of diff.

✅ Coverage increased 0.11% from 92.40% to 92.52%.

origin/main...HEAD, staged and unstaged changes - lenskit/lenskit/data/items.py (100%) - lenskit/lenskit/metrics/predict.py (100%) - lenskit/lenskit/metrics/ranking/__init__.py (100%) - lenskit/lenskit/metrics/ranking/_base.py (90.0%): Missing lines 32,41 - lenskit/lenskit/metrics/ranking/_dcg.py (97.8%): Missing lines 65 - lenskit/lenskit/metrics/ranking/_hit.py (100%) - lenskit/lenskit/metrics/ranking/_pr.py (100%) - lenskit/lenskit/metrics/ranking/_rbp.py (95.8%): Missing lines 54 - lenskit/lenskit/metrics/ranking/_recip.py (92.9%): Missing lines 23 ## Summary - **Total**: 153 lines - **Missing**: 5 lines - **Coverage**: 96%
Source Coverage Report | Name | Stmts | Miss | Cover | |------------------------------------------------ | -------: | -------: | ------: | | lenskit/lenskit/util/envcheck.py | 57 | 44 | 23% | | lenskit/lenskit/data/fetch.py | 38 | 28 | 26% | | lenskit/lenskit/data/types.py | 38 | 13 | 66% | | lenskit/lenskit/util/\_\_init\_\_.py | 72 | 19 | 74% | | lenskit/lenskit/splitting/split.py | 25 | 6 | 76% | | lenskit/lenskit/topn.py | 109 | 25 | 77% | | lenskit/lenskit/data/movielens.py | 97 | 18 | 81% | | lenskit/lenskit/util/test.py | 104 | 19 | 82% | | lenskit/lenskit/pipeline/state.py | 44 | 8 | 82% | | lenskit/lenskit/parallel/config.py | 65 | 11 | 83% | | lenskit/lenskit/parallel/pool.py | 54 | 9 | 83% | | lenskit/lenskit/algorithms/svd.py | 75 | 12 | 84% | | lenskit/lenskit/basic/composite.py | 20 | 3 | 85% | | lenskit/lenskit/algorithms/ranking.py | 75 | 11 | 85% | | lenskit/lenskit/algorithms/\_\_init\_\_.py | 67 | 8 | 88% | | lenskit/lenskit/util/random.py | 34 | 4 | 88% | | lenskit-implicit/lenskit/implicit.py | 94 | 10 | 89% | | lenskit/lenskit/metrics/ranking/\_base.py | 20 | 2 | 90% | | lenskit/lenskit/batch/\_recommend.py | 46 | 4 | 91% | | lenskit/lenskit/data/items.py | 213 | 18 | 92% | | lenskit/lenskit/data/vocab.py | 84 | 7 | 92% | | lenskit/lenskit/metrics/predict.py | 72 | 6 | 92% | | lenskit/lenskit/metrics/ranking/\_recip.py | 14 | 1 | 93% | | lenskit/lenskit/splitting/holdout.py | 56 | 4 | 93% | | lenskit/lenskit/parallel/worker.py | 43 | 3 | 93% | | lenskit/lenskit/batch/\_predict.py | 30 | 2 | 93% | | lenskit/lenskit/math/sparse.py | 60 | 4 | 93% | | lenskit/lenskit/parallel/invoker.py | 31 | 2 | 94% | | lenskit/lenskit/algorithms/knn/user.py | 177 | 11 | 94% | | lenskit/lenskit/basic/popularity.py | 34 | 2 | 94% | | lenskit/lenskit/pipeline/components.py | 51 | 3 | 94% | | lenskit/lenskit/pipeline/types.py | 86 | 5 | 94% | | lenskit/lenskit/algorithms/knn/item.py | 302 | 17 | 94% | | lenskit/lenskit/data/dataset.py | 131 | 7 | 95% | | lenskit/lenskit/data/mtarray.py | 57 | 3 | 95% | | lenskit/lenskit/data/matrix.py | 233 | 12 | 95% | | lenskit/lenskit/parallel/chunking.py | 20 | 1 | 95% | | lenskit/lenskit/basic/bias.py | 93 | 4 | 96% | | lenskit-funksvd/lenskit/funksvd.py | 187 | 8 | 96% | | lenskit/lenskit/metrics/ranking/\_rbp.py | 24 | 1 | 96% | | lenskit/lenskit/basic/topn.py | 26 | 1 | 96% | | lenskit/lenskit/pipeline/\_\_init\_\_.py | 291 | 11 | 96% | | lenskit/lenskit/data/lazy.py | 34 | 1 | 97% | | lenskit/lenskit/algorithms/basic.py | 161 | 4 | 98% | | lenskit/lenskit/algorithms/als/explicit.py | 121 | 3 | 98% | | lenskit/lenskit/metrics/ranking/\_dcg.py | 46 | 1 | 98% | | lenskit/lenskit/algorithms/bias.py | 150 | 3 | 98% | | lenskit/lenskit/parallel/serialize.py | 51 | 1 | 98% | | lenskit/lenskit/algorithms/als/common.py | 128 | 2 | 98% | | lenskit/lenskit/crossfold.py | 136 | 2 | 99% | | lenskit/lenskit/pipeline/config.py | 83 | 1 | 99% | | lenskit/lenskit/pipeline/runner.py | 98 | 1 | 99% | | lenskit/lenskit/algorithms/als/implicit.py | 112 | 1 | 99% | | lenskit/lenskit/metrics/topn.py | 212 | 1 | 99% | | lenskit-hpf/lenskit/hpf.py | 24 | 0 | 100% | | lenskit/lenskit/algorithms/als/\_\_init\_\_.py | 3 | 0 | 100% | | lenskit/lenskit/algorithms/knn/\_\_init\_\_.py | 3 | 0 | 100% | | lenskit/lenskit/algorithms/mf\_common.py | 61 | 0 | 100% | | lenskit/lenskit/basic/\_\_init\_\_.py | 6 | 0 | 100% | | lenskit/lenskit/basic/candidates.py | 25 | 0 | 100% | | lenskit/lenskit/basic/history.py | 60 | 0 | 100% | | lenskit/lenskit/basic/random.py | 25 | 0 | 100% | | lenskit/lenskit/batch/\_\_init\_\_.py | 2 | 0 | 100% | | lenskit/lenskit/data/\_\_init\_\_.py | 10 | 0 | 100% | | lenskit/lenskit/data/checks.py | 37 | 0 | 100% | | lenskit/lenskit/data/convert.py | 50 | 0 | 100% | | lenskit/lenskit/data/query.py | 27 | 0 | 100% | | lenskit/lenskit/data/tables.py | 25 | 0 | 100% | | lenskit/lenskit/diagnostics.py | 4 | 0 | 100% | | lenskit/lenskit/math/\_\_init\_\_.py | 0 | 0 | 100% | | lenskit/lenskit/math/solve.py | 6 | 0 | 100% | | lenskit/lenskit/metrics/\_\_init\_\_.py | 0 | 0 | 100% | | lenskit/lenskit/metrics/ranking/\_\_init\_\_.py | 7 | 0 | 100% | | lenskit/lenskit/metrics/ranking/\_hit.py | 9 | 0 | 100% | | lenskit/lenskit/metrics/ranking/\_pr.py | 21 | 0 | 100% | | lenskit/lenskit/parallel/\_\_init\_\_.py | 4 | 0 | 100% | | lenskit/lenskit/parallel/sequential.py | 22 | 0 | 100% | | lenskit/lenskit/pipeline/common.py | 18 | 0 | 100% | | lenskit/lenskit/pipeline/nodes.py | 47 | 0 | 100% | | lenskit/lenskit/splitting/\_\_init\_\_.py | 4 | 0 | 100% | | lenskit/lenskit/splitting/records.py | 57 | 0 | 100% | | lenskit/lenskit/splitting/users.py | 61 | 0 | 100% | | lenskit/lenskit/types.py | 5 | 0 | 100% | | lenskit/lenskit/util/logging.py | 19 | 0 | 100% | | lenskit/lenskit/util/timing.py | 28 | 0 | 100% | | **TOTAL** | **5451** | **408** | **93%** |