fix: correct binary logistic marker score direction - #4348
Open
dnncha wants to merge 3 commits into
Open
Conversation
Codecov Report✅ All modified and coverable lines are covered by tests. Additional details and impacted files@@ Coverage Diff @@
## main #4348 +/- ##
==========================================
+ Coverage 81.98% 82.00% +0.01%
==========================================
Files 134 134
Lines 13235 13237 +2
==========================================
+ Hits 10851 10855 +4
+ Misses 2384 2382 -2
Flags with carried forward coverage won't be shown. Click here to find out more.
|
flying-sheep
reviewed
Sep 8, 2026
flying-sheep
left a comment
Member
There was a problem hiding this comment.
Thanks! some small nitpicks, otherwise this is a good fix!
|
|
||
| @pytest.mark.parametrize("categories", [["A", "unused", "B"], ["B", "unused", "A"]]) | ||
| @pytest.mark.parametrize("target", ["A", "B"]) | ||
| @pytest.mark.parametrize("representation", ["dense", "sparse", "raw", "layer"]) |
Member
There was a problem hiding this comment.
please remove the representation parameter, the code paths are the same for dense, sparse, …
| def test_binary_logreg_scores_point_toward_requested_group( | ||
| categories, target, representation | ||
| ): | ||
| from anndata import AnnData |
Member
There was a problem hiding this comment.
already imported in the module
Comment on lines
604
to
+606
| scores = scores_all[0] | ||
| if cat_code == clf.classes_[0]: | ||
| scores = -scores |
Member
There was a problem hiding this comment.
Suggested change
| scores = scores_all[0] | |
| if cat_code == clf.classes_[0]: | |
| scores = -scores | |
| scores = scores_all[0] if cat_code == clf.classes_[1] else -scores_all[0] |
Author
|
Thanks! |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Binary
LogisticRegression.coef_[0]points towardclf.classes_[1]. The current binary branch reports it under the first requested group without checking that group's encoded class. If the reported group has the lower category code, its marker ranking is reversed.Orient the binary coefficient vector toward the reported group's class. Existing output shape and multiclass handling are preserved.
With a two-group synthetic matrix containing distinct A and B markers, the unmodified API ranks the B marker first under A when category order is A,B; reversing the categories similarly gives A's marker under B. An explicit target/reference comparison can also flip when only category order changes.
On Scanpy's released
pbmc3k_processed()dataset, subset to 342 B cells and 1,144 CD4 T cells, run:Using the default raw expression matrix, category order
["B cells", "CD4 T cells"]returns IL32, CD3D, S100A4, LDHB and CD3E at the top of the B-cell ranking. All top 20 have higher mean expression in CD4 T cells. Reversing category order returns HLA-DRA, CD74, HLA-DPB1, HLA-DRB1 and CD79A; all top 20 have higher mean expression in B cells. The first ordering's coefficients need to be negated. After this patch, both orders return the same B-cell ranking. The issue reproduces in releases 1.11.5 and 1.12.4 and current upstream baseec374022343eb7ef80bbe3139264e37552cb79b4.Validation: 18 added public-API cases cover both category orders and target groups, default binary selection, nonconsecutive category codes, dense/sparse input, raw and layers. With the four existing logistic tests, unmodified source has 10 failures / 12 passes; patched source has 22 passes. Both ranking test files: 60 passed, 35 skipped, 1 expected failure, 32 passing subtests. These counts overlap. The full Scanpy suite was not run. Ruff lint and formatting checks pass.
Related older category-mapping discussions #273 and #2126 concern multiclass ordering; this patch addresses the binary coefficient orientation. No changed published conclusion or independent scientific review is claimed. Prepared with AI assistance. The report and downloadable reproduction scripts, results and execution records are available here.