Skip to content

feat(operator): give the KNN trainers' metric and metric_params a working converter - #7598

Open
kz930 wants to merge 1 commit into
apache:mainfrom
kz930:fix/7593-knn-metric-converters
Open

feat(operator): give the KNN trainers' metric and metric_params a working converter#7598
kz930 wants to merge 1 commit into
apache:mainfrom
kz930:fix/7593-knn-metric-converters

Conversation

@kz930

@kz930 kz930 commented Aug 12, 2026

Copy link
Copy Markdown
Contributor

What changes were proposed in this PR?

SklearnAdvancedKNNParameters pairs each hyperparameter with the Python callable that converts what the user typed. Two of the seven named one that cannot produce what scikit-learn accepts, so picking either failed the run whatever was entered, from the same dropdown as the five that work. Both trainers share the enum, so both were affected.

metric was declared int. Its accepted values are words, so int("minkowski") raises before scikit-learn sees anything, and a number that does convert is rejected as not one of the accepted names. It is now str, which weights and algorithm beside it already are.

metric_params takes a mapping of extra keyword arguments for the metric, and none of int, float or str returns one, so a well-formed {"p": 2} arrived as that same text. It now names json.loads. The type has never been limited to builtins, since the SVC and SVR trainers already name an inline lambda for their boolean parameters, but json.loads needs the module, so the generated template imports json. Unconditionally rather than when such a parameter is present: the alternative is threading each converter's imports through every ParamClass for one parameter of one operator.

Any related issues, documentation, discussions?

Fixes #7593.

How was this PR tested?

  • Reproduced against scikit-learn both ways. Before: int("minkowski") raises ValueError, and metric=int("3") reaches the estimator and is rejected as not an accepted metric name. After: minkowski with metric_params {"p": 3} fits and predicts with the mapping arriving as a dict, chebyshev fits on the regressor, and mahalanobis with a VI matrix fits, which is the case metric_params exists for.
  • The KNN classifier spec asserts which callable each value is handed to in the emitted model call, not only in the parameter summary beside it. Values travel base64-encoded, so the assertion is on the converter rather than the literal.
  • The base descriptor's spec covers the template's new import.
  • WorkflowOperator/testOnly *sklearnAdvanced*: 7 suites, 40 tests, none failed. scalafmtCheckAll and both scalafix checks clean.

Was this PR authored or co-authored using generative AI tooling?

Generated-by: Claude Code (Claude Opus 5)

…king converter

SklearnAdvancedKNNParameters pairs each hyperparameter with the Python callable
that converts what the user typed. Two of the seven named one that cannot
produce what scikit-learn accepts, so picking either failed the run whatever was
entered, from the same dropdown as the five that work. Both trainers share the
enum, so both were affected.

metric was declared int. Its accepted values are words, so int("minkowski")
raises before scikit-learn sees anything, and a number that does convert is
rejected as not one of the accepted names. It is now str, which weights and
algorithm beside it already are.

metric_params takes a mapping of extra keyword arguments for the metric, and
none of int, float or str returns one, so a well-formed {"p": 2} arrived as that
same text. It now names json.loads. The type has never been limited to builtins
(SVC and SVR name an inline lambda for their boolean parameters), but json.loads
needs the module, so the generated template imports json. Unconditionally rather
than when such a parameter is present: the alternative is threading each
converter's imports through every ParamClass for one parameter of one operator.

Checked against scikit-learn both ways. Before: int("minkowski") raises
ValueError, and metric=int("3") reaches the estimator and is rejected as not an
accepted metric name. After: minkowski with metric_params {"p": 3} fits and
predicts with the mapping arriving as a dict, chebyshev fits on the regressor,
and mahalanobis with a VI matrix fits, which is what metric_params is for.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
@github-actions

Copy link
Copy Markdown
Contributor

Automated Reviewer Suggestions

Based on the git blame history of the changed files, we recommend the following reviewers:

  • Contributors with relevant context: @Yicong-Huang, @carloea2, @aglinxinyuan
    You can notify them by mentioning @Yicong-Huang, @carloea2, @aglinxinyuan in a comment.

@codecov-commenter

codecov-commenter commented Aug 12, 2026

Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 88.64%. Comparing base (7daf8d7) to head (b0e2e59).

Additional details and impacted files
@@            Coverage Diff            @@
##               main    #7598   +/-   ##
=========================================
  Coverage     88.63%   88.64%           
- Complexity     4346     4347    +1     
=========================================
  Files          1177     1177           
  Lines         46896    46896           
  Branches       5230     5230           
=========================================
+ Hits          41568    41569    +1     
+ Misses         3568     3567    -1     
  Partials       1760     1760           
Flag Coverage Δ *Carryforward flag
access-control-service 70.00% <ø> (ø)
agent-service 98.62% <ø> (ø) Carriedforward from 7daf8d7
amber 84.72% <100.00%> (+<0.01%) ⬆️
computing-unit-managing-service 60.38% <ø> (ø)
config-service 77.31% <ø> (ø)
file-service 69.05% <ø> (ø)
frontend 89.98% <ø> (ø) Carriedforward from 7daf8d7
notebook-migration-service 78.89% <ø> (ø)
pyamber 97.52% <ø> (ø) Carriedforward from 7daf8d7
workflow-compiling-service 57.89% <ø> (ø)

*This pull request uses carry forward flags. Click here to find out more.

☔ View full report in Codecov by Harness.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

@github-actions

Copy link
Copy Markdown
Contributor

⚠️ Benchmark changes need a look

🟢 0 better · 🔴 10 worse · ⚪ 5 noise (<±5%) · 0 without baseline

Compared against main 7daf8d7 benchmarked on this same runner, so the delta is largely free of cross-runner hardware noise. The "7d avg" column still reflects the gh-pages dashboard. Treat <±5% as noise unless repeated.

Dashboard · Run

config throughput MB/s latency max Δ latest / 7d
🔴 bs=10 sw=10 sl=64 693 0.423 15,336/17,511/17,511 us 🔴 +26.5% / 🔴 +20.3%
🔴 bs=100 sw=10 sl=64 1,613 0.984 62,180/82,583/82,583 us 🔴 +8.4% / 🟢 +61.2%
🔴 bs=1000 sw=10 sl=64 2,059 1.257 483,282/541,119/541,119 us 🔴 +6.1% / 🟢 +100.7%
Baseline details

Latest main 7daf8d7 from same runner

config metric PR latest main 7d avg Δ latest Δ 7d
bs=10 sw=10 sl=64 throughput 693 tuples/sec 849 tuples/sec 775.33 tuples/sec -18.4% -10.6%
bs=10 sw=10 sl=64 MB/s 0.423 MB/s 0.518 MB/s 0.473 MB/s -18.3% -10.6%
bs=10 sw=10 sl=64 p50 15,336 us 12,124 us 12,743 us +26.5% +20.3%
bs=10 sw=10 sl=64 p95 17,511 us 16,192 us 16,310 us +8.1% +7.4%
bs=10 sw=10 sl=64 p99 17,511 us 16,192 us 18,926 us +8.1% -7.5%
bs=100 sw=10 sl=64 throughput 1,613 tuples/sec 1,732 tuples/sec 1,001 tuples/sec -6.9% +61.2%
bs=100 sw=10 sl=64 MB/s 0.984 MB/s 1.057 MB/s 0.611 MB/s -6.9% +61.1%
bs=100 sw=10 sl=64 p50 62,180 us 57,381 us 101,399 us +8.4% -38.7%
bs=100 sw=10 sl=64 p95 82,583 us 85,702 us 108,206 us -3.6% -23.7%
bs=100 sw=10 sl=64 p99 82,583 us 85,702 us 118,195 us -3.6% -30.1%
bs=1000 sw=10 sl=64 throughput 2,059 tuples/sec 2,097 tuples/sec 1,026 tuples/sec -1.8% +100.6%
bs=1000 sw=10 sl=64 MB/s 1.257 MB/s 1.28 MB/s 0.626 MB/s -1.8% +100.7%
bs=1000 sw=10 sl=64 p50 483,282 us 473,870 us 996,304 us +2.0% -51.5%
bs=1000 sw=10 sl=64 p95 541,119 us 510,053 us 1,042,531 us +6.1% -48.1%
bs=1000 sw=10 sl=64 p99 541,119 us 510,053 us 1,074,934 us +6.1% -49.7%
Raw CSV
config_idx,batch_size,schema_width,string_len,num_batches,total_ms,total_tuples,total_bytes,tuples_per_sec,mb_per_sec,lat_p50_us,lat_p95_us,lat_p99_us
0,10,10,64,20,288.76,200,128000,693,0.423,15335.59,17510.87,17510.87
1,100,10,64,20,1240.04,2000,1280000,1613,0.984,62179.78,82582.90,82582.90
2,1000,10,64,20,9715.09,20000,12800000,2059,1.257,483282.44,541119.47,541119.47

@kz930

kz930 commented Aug 12, 2026

Copy link
Copy Markdown
Contributor Author

@carloea2, @aglinxinyuan May you take a look at this?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

The KNN trainers' metric and metric_params cannot be given a working value

2 participants