Skip to content

Fix index misalignment in char_wb ngram padding - #8429

Open
adityaanikam wants to merge 8 commits into
NVIDIA:mainfrom
adityaanikam:tfidf-char-wb-ngram-fix-8416
Open

Fix index misalignment in char_wb ngram padding#8429
adityaanikam wants to merge 8 commits into
NVIDIA:mainfrom
adityaanikam:tfidf-char-wb-ngram-fix-8416

Conversation

@adityaanikam

Copy link
Copy Markdown

Fixes #8416

Root cause

get_char_ngrams() pads each token with self.delimiter on both sides before generating character ngrams:

padding = Series(self.delimiter).repeat(len(tokens))

@adityaanikam
adityaanikam requested a review from a team as a code owner July 31, 2026 15:20
@adityaanikam
adityaanikam requested a review from jcrist July 31, 2026 15:20
@copy-pr-bot

copy-pr-bot Bot commented Jul 31, 2026

Copy link
Copy Markdown

This pull request requires additional validation before any workflows can run on NVIDIA's runners.

Pull request vetters can view their responsibilities here.

Contributors can view more details about this message here.

@github-actions github-actions Bot added the Cython / Python Cython or Python issue label Jul 31, 2026
@coderabbitai

coderabbitai Bot commented Jul 31, 2026

Copy link
Copy Markdown

Review Change Stack

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Enterprise

Run ID: b7bc9b3b-824d-4db7-901a-e3dc0d327635

📥 Commits

Reviewing files that changed from the base of the PR and between 213646a and 9eb9f3f.

📒 Files selected for processing (1)
  • python/cuml/cuml/feature_extraction/_vectorizers.py

Included review availability: Your plan provides up to 12 included reviews per hour; 11 remain after this review.


📝 Walkthrough

Summary by CodeRabbit

  • Bug Fixes

    • Improved character n-gram processing to maintain correct positional alignment, including documents with no extracted tokens.
  • Documentation

    • Updated text vectorizer usage to the current get_feature_names_out() API, which returns feature names as a NumPy array.
  • Deprecations

    • Calls to get_feature_names() now emit a FutureWarning while retaining consistent results.
  • Tests

    • Expanded coverage for word, character, and char_wb vectorizers, including alignment and feature-name compatibility checks.

Walkthrough

The vectorizer now preserves document alignment for character n-grams, including documents with zero tokens. Tests use get_feature_names_out(), verify deprecated API warnings, and compare char_wb TF-IDF results with scikit-learn.

Changes

Character n-gram alignment and regression coverage

Layer / File(s) Summary
Character n-gram alignment fix
python/cuml/cuml/feature_extraction/_vectorizers.py
The vectorizer resets token and padding indexes before concatenation. It reindexes n-gram counts across all documents and assigns zero to documents with no tokens.
Feature-name API and regression tests
python/cuml/tests/test_text_feature_extraction.py
Tests use get_feature_names_out() across word and character vectorizers. They verify deprecated get_feature_names() warnings and compare char_wb TF-IDF matrices and feature names with scikit-learn for n-gram lengths 2 through 6.

Estimated code review effort: 3 (Moderate) | ~20 minutes

Merge Risk: ⚪ Minimal · up to 9eb9f

This is a localized correction to character n-gram padding index alignment, with no actionable merge-blocking risk remaining after normal checks and review.

Suggested reviewers: jcrist, divyegala

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Title check ✅ Passed The title clearly identifies the main change: fixing index misalignment in char_wb n-gram padding.
Description check ✅ Passed The description explains the char_wb padding root cause and relates directly to the reported bug.
Linked Issues check ✅ Passed The changes fix char_wb n-gram index alignment, handle empty documents, and add regression coverage for the linked issue [#8416].
Out of Scope Changes check ✅ Passed The implementation and test updates support the linked char_wb bug fix and do not introduce unrelated code changes.
Docstring Coverage ✅ Passed Docstring check was indeterminate for this PR — some files could not be analyzed in time. Not blocking.
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

Comment @coderabbitai help to get the list of available commands.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🧹 Nitpick comments (1)
python/cuml/cuml/feature_extraction/_vectorizers.py (1)

216-224: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick win

Add an enabled char_wb Tfidf regression test.

In python/cuml/tests/test_text_feature_extraction.py, test TfidfVectorizer.fit_transform(analyzer="char_wb", ngram_range=(2, 6)). Compare the sparse output and feature names with scikit-learn using get_feature_names_out().

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@python/cuml/cuml/feature_extraction/_vectorizers.py` around lines 216 - 224,
Add an enabled regression test in test_text_feature_extraction.py covering
TfidfVectorizer with analyzer="char_wb" and ngram_range=(2, 6). Fit and
transform the same input with cuML and scikit-learn, then compare sparse outputs
and feature names using get_feature_names_out().
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Nitpick comments:
In `@python/cuml/cuml/feature_extraction/_vectorizers.py`:
- Around line 216-224: Add an enabled regression test in
test_text_feature_extraction.py covering TfidfVectorizer with analyzer="char_wb"
and ngram_range=(2, 6). Fit and transform the same input with cuML and
scikit-learn, then compare sparse outputs and feature names using
get_feature_names_out().

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Enterprise

Run ID: 80ca255e-7d3d-41f0-ab51-594df4f04c33

📥 Commits

Reviewing files that changed from the base of the PR and between 74f5ffa and 3edfa37.

📒 Files selected for processing (1)
  • python/cuml/cuml/feature_extraction/_vectorizers.py

@csadorf

csadorf commented Aug 14, 2026

Copy link
Copy Markdown
Contributor

@divyegala Can you review this, please?

@divyegala divyegala left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thank you for the contribution! Could you please add a test?

@adityaanikam
adityaanikam requested a review from a team as a code owner August 19, 2026 09:00
@adityaanikam

adityaanikam commented Aug 19, 2026

Copy link
Copy Markdown
Author

Added test_tfidf_vectorizer_char_wb_ngrams — compares cuML's TfidfVectorizer(analyzer="char_wb", ngram_range=(2, 6)) against scikit-learn's on the existing DOCS fixture (13 documents, mixed lengths, includes empty docs), checking both the output matrix and feature names via get_feature_names_out(). That corpus mix is what actually exercises the bug, since the misalignment only showed up once documents had varying token counts. Also rebased onto latest main to pick up the get_feature_names_out() API change from #8480.
This also needs bug + non-breaking labels for the Label Checker I don't have permission to add them myself.

@divyegala divyegala added bug Something isn't working non-breaking Non-breaking change labels Aug 19, 2026

@divyegala divyegala left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thank you, LGTM!

@divyegala

Copy link
Copy Markdown
Contributor

/ok to test 36f9500

@divyegala

Copy link
Copy Markdown
Contributor

/merge

@divyegala

Copy link
Copy Markdown
Contributor

Hi @adityaanikam , could you please run pre-commit and push up a new commit?

@adityaanikam

Copy link
Copy Markdown
Author

Hi @adityaanikam , could you please run pre-commit and push up a new commit?

done

@divyegala

Copy link
Copy Markdown
Contributor

/ok to test 41a6044

CI on this PR failed test_tfidf_vectorizer_char_wb_ngrams with KeyError: boolean label can not be used without a boolean index, in get_ngrams' ngram_count[not_empty_docs] filter. That test's DOCS fixture includes two empty-string documents, and this is the first char_wb test to include one.

get_char_ngrams' char_wb branch computes ngram_count via doc_id_df.groupby("doc_id", sort=True).sum(). A document that tokenizes to zero tokens never contributes a row to doc_id_df, so its doc_id is entirely absent from the groupby result's index, rather than present with a count of 0. token_count, computed separately via str_series.str.token_count(), still has an entry for every document. The two indices then disagree, and get_ngrams' later not_empty_docs boolean mask, built from token_count's full index, no longer aligns with ngram_count's shorter one.

Reindexed ngram_count onto token_count's index with fill_value=0 right after the groupby, restoring the same index for both that the other two branches (char, ngram_size == 1) already get for free since their ngram_count is arithmetic directly on token_count.

This bug predates this PR and is unrelated to the padding order change in get_char_ngrams; it was only ever latent because no earlier char_wb test included a document with zero tokens. The regression test already added in this PR (test_tfidf_vectorizer_char_wb_ngrams) exercises it directly, so no additional test is needed. Could not run this locally, cuml requires an NVIDIA GPU and CUDA runtime; verified the fix by tracing the exact index mismatch against the failing job's log and reasoning through cudf.Series.reindex semantics, and am relying on CI to confirm.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

bug Something isn't working Cython / Python Cython or Python issue non-breaking Non-breaking change

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[BUG] TfidfVectorizer with char_wb analyzer and ngrams fails

5 participants