Implement tf_idf_transform (TF-IDF transform)#34
Open
rasmushenningsson wants to merge 1 commit into
Open
Conversation
Wire the TF-IDF transform into the public API. `tf_idf_transform` was declared `public` but had no binding, so the feature was unreachable. `tf_idf_transform([T,] counts; scale_factor=10_000, annotate=false)` returns a `DataMatrix` Job with the transform `log(1 + scale_factor * tf * idf)`, where `tf = counts ./ max.(1, sum(counts; dims=1))` and the inverse document frequency `idf = nobs ./ max.(1, sum(counts; dims=2))`. The idf is estimated from the base data and frozen: under projection it is remapped to the projected variables by ID (mirroring `scparams`), together with a matching var index for the matrix rows, so projecting onto reordered/subset variables works correctly. - SCPCore/transform.jl: tf_idf_idf (the idf) and tf_idf_matrix (the kernel). - Impl/transform.jl: the frozen+remapped idf Projectable, the projectable matrix transform, and the DataMatrixFunction dispatcher (annotate adds idf to var; var_filter is intentionally not supported, matching logtransform). - transform.jl: public tf_idf_transform + docstring. - test/transform.jl: eval (Float64/Float32, scale factors), annotate, and projection onto same and scattered-subset variables, against the existing simple_tf_idf_transform ground truth. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01Bg3CkLkDWLqh8zPwVZ7Ayu
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.
Implement
tf_idf_transform(TF-IDF transform)Summary
Wires the TF-IDF (term frequency-inverse document frequency) transform into the public API.
tf_idf_transformwas declaredpublicon this branch but had no binding, so the featurewas unreachable (its siblings
logtransform/sctransformare implemented;tf_idf_transformwas left as an advertised-but-missing name).
Returns a
DataMatrixJob with the transformlog(1 + scale_factor * tf * idf), where the termfrequency is
tf = counts ./ max.(1, sum(counts; dims=1))and the inverse document frequency isidf = nobs ./ max.(1, sum(counts; dims=2)).Tcontrols the eltype of the transformed matrix(
Float32to lower memory usage).Design decisions
sctransform). Theidfis estimated from the basedata and frozen. Under projection,
tf_idf_idf_printersects the base variable IDs with theprojected ones and reindexes
idf; a matchingvar_ind(
create_find_matching_ind_job(:; project_ids=:intersect)) keeps the matrix rows aligned. Soprojecting onto a dataset whose variables are reordered or a subset works correctly, and the
idfis reused (never recomputed on the projected data). This matches main's behavior.annotateexposed;var_filteromitted.annotateadds theidfas avarannotation,defaulting to
falseto match this branch'ssctransform.var_filter/var_filter_colsareintentionally not supported, consistent with how ProjectionRefactor simplified
logtransform(filter before transforming instead).
Implementation
Mirrors the
sctransformstructure, but much simpler (the frozen parameter is a singleidfvector rather than a params DataFrame, and there is no low-rank term):
src/SCPCore/transform.jl—tf_idf_idf(theidfvector) andtf_idf_matrix(theelement-wise kernel, natural
log, ported from main'stf_idf_transform_impl).src/Impl/transform.jl— the frozen + ID-remappedidfProjectable, the projectable matrixtransform (per horizontal block via
hblock_map), and theDataMatrixFunctiondispatcher(
Mat/Var/Obs); the basenobsisfetchedso it is not affected by projection.src/transform.jl— publictf_idf_transform+ docstring.tf_idf_transformwas already in thepubliclist, so no module change was needed.Testing
tf-idf testsets added to
run_transform_tests(test/transform.jl), validated against thesimple_idf/simple_tf_idf_transformground truth already present intest/test_setup.jl:Float64/Float32andscale_factor10 000 / 1 000.annotate=trueadds a correctidfcolumn; off by default.idf(verified it differs fromrecomputing
idfon the subset).name > "L", non-contiguous) —idfand matrixrows remap correctly by ID.
Full
run_transform_tests: 448/448 on both the New Disk Cache and Reused Disk Cachepasses (no regressions to
logtransform/sctransform; caching is correct). The packageprecompiles cleanly and
tf_idf_transformis exposed viapublic.🤖 Generated with Claude Code