From d0e31d4d0927124b91724bef2355c5d5f23a5a97 Mon Sep 17 00:00:00 2001 From: "Anthony D. Blaom" Date: Tue, 1 Sep 2026 09:08:41 +1200 Subject: [PATCH 1/5] compathelper -> dependabot --- .github/dependabot.yml | 15 +++++++++++++++ .github/workflows/CompatHelper.yml | 19 ------------------- 2 files changed, 15 insertions(+), 19 deletions(-) create mode 100644 .github/dependabot.yml delete mode 100644 .github/workflows/CompatHelper.yml diff --git a/.github/dependabot.yml b/.github/dependabot.yml new file mode 100644 index 0000000..7d5a7df --- /dev/null +++ b/.github/dependabot.yml @@ -0,0 +1,15 @@ +# https://docs.github.com/github/administering-a-repository/configuration-options-for-dependency-updates +version: 2 +updates: + - package-ecosystem: "github-actions" + directory: "/" # Location of package manifests + schedule: + interval: "monthly" + - package-ecosystem: "julia" + directories: # Location of Julia projects + - "/" + - "/docs" + schedule: + interval: "weekly" + ignore: + - dependency-name: "NearestNeighborModels" diff --git a/.github/workflows/CompatHelper.yml b/.github/workflows/CompatHelper.yml deleted file mode 100644 index b856114..0000000 --- a/.github/workflows/CompatHelper.yml +++ /dev/null @@ -1,19 +0,0 @@ -name: CompatHelper - -on: - schedule: - - cron: '00 00 * * *' - workflow_dispatch: -jobs: - CompatHelper: - runs-on: ubuntu-latest - steps: - - uses: julia-actions/setup-julia@latest - with: - version: 1.3 - - name: Pkg.add("CompatHelper") - run: julia -e 'using Pkg; Pkg.add("CompatHelper")' - - name: CompatHelper.main - env: - GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} - run: julia -e 'using CompatHelper; CompatHelper.main(; master_branch = "dev")' From bc31ea3e8aaeb5e5d76cb8bcd0cb6d82f67d28c8 Mon Sep 17 00:00:00 2001 From: "Anthony D. Blaom" Date: Tue, 1 Sep 2026 09:09:01 +1200 Subject: [PATCH 2/5] update Documenter version, doc tests, and address #62 --- docs/Project.toml | 8 +++--- docs/make.jl | 10 +++---- docs/src/index.md | 68 ++++++++++++++++++++++++++--------------------- 3 files changed, 47 insertions(+), 39 deletions(-) diff --git a/docs/Project.toml b/docs/Project.toml index c1bb6c4..50dd616 100644 --- a/docs/Project.toml +++ b/docs/Project.toml @@ -5,7 +5,7 @@ NearestNeighborModels = "636a865e-7cf4-491e-846c-de09b730eb36" StableRNGs = "860ef19b-820b-49d6-a774-d7a799459cd3" [compat] -Documenter = "^0.24" -MLJBase = "^0.19" -StableRNGs = "^1.0" -julia = "^1.0" +Documenter = "1" +MLJBase = "1" +StableRNGs = "1.0" +julia = "1.10" diff --git a/docs/make.jl b/docs/make.jl index 7c46482..6e7329a 100644 --- a/docs/make.jl +++ b/docs/make.jl @@ -2,21 +2,21 @@ using Documenter, MLJBase, NearestNeighborModels makedocs(; authors = """ - Anthony D. Blaom , - Sebastian Vollmer , - Thibaut Lienart and Okon Samuel + Thibaut Lienart and + Anthony D. Blaom , + Sebastian Vollmer , """, format = Documenter.HTML(; prettyurls= get(ENV, "CI", "false") == "true" ), modules = [NearestNeighborModels], - pages=[ + pages = [ "Home" => "index.md", "API" => "api.md" ], doctest = false, # don't runt doctest as doctests are automatically run separately in ci. - repo = "https://github.com/JuliaAI/NearestNeighborModels.jl/blob/{commit}{path}#L{line}", + repo = Remotes.GitHub("JuliaAI", "NearestNeighborModels"), sitename = "NearestNeighborModels.jl", ) diff --git a/docs/src/index.md b/docs/src/index.md index 6f927b8..e4f116e 100644 --- a/docs/src/index.md +++ b/docs/src/index.md @@ -1,16 +1,15 @@ # NearestNeighborModels - Docs -NearestNeighborModels is a julia package providing implemtation of various -k-nearest-neighbor classifiers and regressors models for use with -[MLJ](https://alan-turing-institute.github.io/MLJ.jl/dev/) machine learning -framework. It also provides users with an array of weighting kernels to choose -from for prediction. +NearestNeighborModels is a julia package providing implemtation of various +k-nearest-neighbor classifiers and regressors models for use with +[MLJ](https://juliaml.ai) machine learning framework. It also provides users with an array +of weighting kernels to choose from for prediction. -NearestNeighborModels builds on Kristoffer Carlsson's -[NearestNeighbors](https://github.com/KristofferC/NearestNeighbors.jl) package(for -performing efficient nearest neighbor searches) and earlier contributions from Thibaut -Lienart originally residing in -[MLJModels.jl](https://github.com/alan-turing-institute/MLJModels.jl/blob/98618d7be53f72054de284fa1796c5292d9071bb/src/NearestNeighbors.jl#L1). +NearestNeighborModels builds on Kristoffer Carlsson's +[NearestNeighbors](https://github.com/KristofferC/NearestNeighbors.jl) package(for +performing efficient nearest neighbor searches) and earlier contributions from Thibaut +Lienart originally residing in +[MLJModels.jl](https://github.com/JuliaAI/MLJModels.jl/blob/98618d7be53f72054de284fa1796c5292d9071bb/src/NearestNeighbors.jl#L1). # Installation @@ -20,28 +19,30 @@ as shown below. ```julia using Pkg -Pkg.add("NearestNeighborModels") +Pkg.add("NearestNeighborModels") ``` # Usage -To use any model implemented in this package, the model must first be wrapped in an MLJ -machine alongside the required data. Users also get additional features from MLJ including +To use any model implemented in this package, the model must first be wrapped in an MLJ +machine alongside the required data. Users also get additional features from MLJ including performance evaluation, hyper-parameter tuning, stacking etc. The following example shows how to train a `KNNClassifier` on the crabs dataset. ```julia -using NearestNeighborModels, MLJBase -X, y = @load_crabs; # loads the crabs dataset from MLJBase +import NearestNeighborModels: KNNClassifier, Inverse +import MLJBase: @load_crabs, fit!, machine, nrows, partition, predict, predict_mode +X, y = @load_crabs; # a table and a vector train_inds, test_inds = partition(1:nrows(X), 0.7, shuffle=false); knnc = KNNClassifier(weights = Inverse()) # KNNClassifier instantiation -knnc_mach = machine(knnc, X, y) # wrap model and required data in an MLJ machine -fit!(knnc_mach, rows=train_inds) # train machine on a subset of the wrapped data `X` +knnc_mach = machine(knnc, X, y) # wrap model and required data in an MLJ machine +fit!(knnc_mach, rows=train_inds) # train machine on a subset of the wrapped data `X` ``` `UnivariateFinite` predictions can be obtained from the trained machine as shown below ```@meta -DocTestSetup = quote - using NearestNeighborModels, MLJBase + DocTestSetup = quote + import NearestNeighborModels: KNNClassifier, Inverse + import MLJBase: @load_crabs, fit!, machine, nrows, partition, predict, predict_mode X, y = @load_crabs; train_inds, test_inds = partition(1:nrows(X), 0.7, shuffle=false); knnc = KNNClassifier(weights = Inverse()) @@ -51,7 +52,7 @@ end ``` ```jldoctest ex1 julia> predict(knnc_mach, rows=test_inds) -60-element UnivariateFiniteVector{Multiclass{2}, String, UInt32, Float64}: +60-element CategoricalDistributions.UnivariateFiniteVector{ScientificTypesBase.Multiclass{2}, String, UInt32, Float64}: UnivariateFinite{Multiclass{2}}(B=>0.315, O=>0.685) UnivariateFinite{Multiclass{2}}(B=>1.0, O=>0.0) UnivariateFinite{Multiclass{2}}(B=>1.0, O=>0.0) @@ -114,15 +115,18 @@ function custom_kernel(dists::AbstractMatrix) return weights end -# Then we wrap it in a `UserDefinedKernel` -# `sort = true` because our `custom_kernel` function relies on `dists` being sorted in +# Then we wrap it in a `UserDefinedKernel` with +# `sort = true` because our `custom_kernel` function relies on `dists` being sorted in # ascending order. +import NearestNeighborModels.UserDefinedKernel weighting_kernel = UserDefinedKernel(func=custom_kernel, sort=true) ``` -We will now train a `MultitargetKNNRegressor` that makes use of our simple custom-defined +We will now train a `MultitargetKNNRegressor` that makes use of our simple custom-defined `weighting_kernel` for prediction. ```julia -using NearestNeighborModels, MLJBase +import NearestNeighborModels: MultitargetKNNRegressor, Inverse +import MLJBase: @load_crabs, fit!, machine, nrows, partition, predict, predict_mode +import MLJBase using StableRNGs #for reproducibility of this example n = 50 @@ -130,8 +134,8 @@ p = 5 l = 2 rng = StableRNG(100) # `table` converts an `AbstractMatrix` into a `Tables.jl` compactible table -X = table(randn(rng, (n, p))) # feature table -Y = table(randn(rng, (n, l))) # target table +X = MLJBase.table(randn(rng, (n, p))) # feature table +Y = MLJBase.table(randn(rng, (n, l))) # target table train_inds, test_inds = partition(1:nrows(X), 0.8, shuffle=false); multi_knnr = MultitargetKNNRegressor(weights=weighting_kernel) @@ -141,7 +145,11 @@ fit!(multi_knnr_mach, rows=train_inds) # train machine on a subset of the wrappe And of course predicting with the test-dataset gives: ```@meta DocTestSetup = quote - using NearestNeighborModels, MLJBase, StableRNGs + import NearestNeighborModels: MultitargetKNNRegressor, Inverse + import NearestNeighborModels.UserDefinedKernel + import MLJBase: @load_crabs, fit!, machine, nrows, partition, predict, predict_mode + import MLJBase + using StableRNGs function custom_kernel(dists::AbstractMatrix) weights = similar(Array{Float16}, size(dists)) weights[:, 1] .= 2.0 @@ -153,8 +161,8 @@ DocTestSetup = quote p = 5 l = 2 rng = StableRNG(100) - X = table(randn(rng, (n, p))) # feature table - Y = table(randn(rng, (n, l))) # target table + X = MLJBase.table(randn(rng, (n, p))) # feature table + Y = MLJBase.table(randn(rng, (n, l))) # target table train_inds, test_inds = partition(1:nrows(X), 0.8, shuffle=false); multi_knnr = MultitargetKNNRegressor(weights=weighting_kernel) multi_knnr_mach = machine(multi_knnr, X, Y) #wrap model and required data in an MLJ machine @@ -183,5 +191,5 @@ julia> MLJBase.matrix(table_predictions) ```@meta DocTestSetup = nothing ``` -see [MLJ docs](https://alan-turing-institute.github.io/MLJ.jl/dev/) for help on additional +see [MLJ docs](https://JuliaAI.github.io/MLJ.jl/stable/) for help on additional features such as hyper-parameter tuning, performance evaluation, stacking etc. From c57182097ca8001909390282c2e973987955b1c5 Mon Sep 17 00:00:00 2001 From: "Anthony D. Blaom" Date: Tue, 1 Sep 2026 09:14:02 +1200 Subject: [PATCH 3/5] use julia-actions/cache --- .github/workflows/ci.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 3199c74..9679e26 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -29,7 +29,7 @@ jobs: with: version: ${{ matrix.version }} arch: ${{ matrix.arch }} - - uses: actions/cache@v1 + - uses: julia-actions/cache@v2 env: cache-name: cache-artifacts with: From 3b494d766cf97c33c72575c4da624dfdad83f96a Mon Sep 17 00:00:00 2001 From: "Anthony D. Blaom" Date: Tue, 1 Sep 2026 09:18:28 +1200 Subject: [PATCH 4/5] dump testing for unsupported julia 1.6 --- .github/workflows/ci.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 9679e26..2ac2b59 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -17,7 +17,7 @@ jobs: fail-fast: false matrix: version: - - '1.6' + - 'lts' - '1' os: - ubuntu-latest From 2c4b6a1231a84a4790abf775bbfa0d5f3cbbaa79 Mon Sep 17 00:00:00 2001 From: "Anthony D. Blaom" Date: Tue, 1 Sep 2026 09:21:06 +1200 Subject: [PATCH 5/5] use setup-julia@v3 --- .github/workflows/ci.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 2ac2b59..71227db 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -25,7 +25,7 @@ jobs: - x64 steps: - uses: actions/checkout@v3 - - uses: julia-actions/setup-julia@v1 + - uses: julia-actions/setup-julia@v3 with: version: ${{ matrix.version }} arch: ${{ matrix.arch }}