From 82e9ab2262a224cb99c8576fb8f3398b0e4aef88 Mon Sep 17 00:00:00 2001 From: David Buchaca Prats Date: Fri, 28 Oct 2022 17:19:17 +0200 Subject: [PATCH 01/14] feat: method for clustering new data kmeans added --- src/Clustering.jl | 2 +- src/kmeans.jl | 37 +++++++++++++++++++++++++++++++++++++ test/kmeans.jl | 7 +++++++ 3 files changed, 45 insertions(+), 1 deletion(-) diff --git a/src/Clustering.jl b/src/Clustering.jl index 2da54517..fd763402 100644 --- a/src/Clustering.jl +++ b/src/Clustering.jl @@ -29,7 +29,7 @@ module Clustering kmpp, kmpp_by_costs, # kmeans - kmeans, kmeans!, KmeansResult, + kmeans, kmeans!, KmeansResult, get_cluster_assignments, # kmedoids kmedoids, kmedoids!, KmedoidsResult, diff --git a/src/kmeans.jl b/src/kmeans.jl index 3f96403f..dbc2f05c 100644 --- a/src/kmeans.jl +++ b/src/kmeans.jl @@ -390,4 +390,41 @@ function repick_unused_centers(X::AbstractMatrix{<:Real}, # in: the data matrix colwise!(ds, distance, v, X) tcosts = min(tcosts, ds) end + +""" +get_cluster_assignments(X::Matrix{T}, R::KmeansResult; ...) -> Vector{Int} + +Perform the clustering assigment of ``n`` points into `k` clusters, +using the learned prototopyes from the input `KmeansResult`. + +Note: This method is usefull when clustering new data leveraging a fitted model. + +# Arguments +- `X`: Input data to be clustered. +- `R`: Fitted keamns result. +""" +function get_cluster_assignments( + X::Matrix{T}, + R::KmeansResult, + distance::SemiMetric=SqEuclidean()) where {F<:Function, T} + + cluster_assignments = zeros(Int, size(X,2)) + + Threads.@threads for n in axes(X,2) + min_dist = typemax(T) + cluster_assignment = 0 + + for k in axes(R.centers, 2) + dist = distance(@view(X[:,n]),@view(R.centers[:,k])) + if dist < min_dist + min_dist = dist + cluster_assignment = k + end + end + cluster_assignments[n] = cluster_assignment + end + + return cluster_assignments +end + end diff --git a/test/kmeans.jl b/test/kmeans.jl index 6c4d25e6..2033d03d 100644 --- a/test/kmeans.jl +++ b/test/kmeans.jl @@ -204,4 +204,11 @@ end end end +@testset "get cluster assigments" begin + X = rand(5, 100) + R = kmeans(X, 10; maxiter=200) + clusters_from_get_cluster_assignments = get_cluster_assignments(X, R); + @test R.assignments == clusters_from_get_cluster_assignments +end + end From 9cccfb288ba3a150a188ead0d15fb11226db3919 Mon Sep 17 00:00:00 2001 From: David Buchaca Prats Date: Fri, 28 Oct 2022 22:00:41 +0200 Subject: [PATCH 02/14] Update test/kmeans.jl Co-authored-by: Alexey Stukalov --- test/kmeans.jl | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/test/kmeans.jl b/test/kmeans.jl index 2033d03d..5a27b00c 100644 --- a/test/kmeans.jl +++ b/test/kmeans.jl @@ -207,8 +207,8 @@ end @testset "get cluster assigments" begin X = rand(5, 100) R = kmeans(X, 10; maxiter=200) - clusters_from_get_cluster_assignments = get_cluster_assignments(X, R); - @test R.assignments == clusters_from_get_cluster_assignments + reassigned_clusters = assign_clusters(X, R); + @test R.assignments == reassigned_clusters end end From 32cc28e4e586a3142e434f176b4c590030ef5e29 Mon Sep 17 00:00:00 2001 From: David Buchaca Prats Date: Fri, 28 Oct 2022 22:18:20 +0200 Subject: [PATCH 03/14] Update src/kmeans.jl Co-authored-by: Alexey Stukalov --- src/kmeans.jl | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/kmeans.jl b/src/kmeans.jl index dbc2f05c..87da86b4 100644 --- a/src/kmeans.jl +++ b/src/kmeans.jl @@ -403,10 +403,10 @@ Note: This method is usefull when clustering new data leveraging a fitted model. - `X`: Input data to be clustered. - `R`: Fitted keamns result. """ -function get_cluster_assignments( - X::Matrix{T}, - R::KmeansResult, - distance::SemiMetric=SqEuclidean()) where {F<:Function, T} +function assign_clusters( + samples::AbstractMatrix{T}, + clusters::KmeansResult, + distance::SemiMetric = SqEuclidean()) where {T} cluster_assignments = zeros(Int, size(X,2)) From 86bc0324c7db70904ce4a6197a407b9a87a59374 Mon Sep 17 00:00:00 2001 From: David Buchaca Prats Date: Fri, 28 Oct 2022 22:20:43 +0200 Subject: [PATCH 04/14] Update src/kmeans.jl Co-authored-by: Alexey Stukalov --- src/kmeans.jl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/kmeans.jl b/src/kmeans.jl index 87da86b4..b270d2c3 100644 --- a/src/kmeans.jl +++ b/src/kmeans.jl @@ -392,7 +392,7 @@ function repick_unused_centers(X::AbstractMatrix{<:Real}, # in: the data matrix end """ -get_cluster_assignments(X::Matrix{T}, R::KmeansResult; ...) -> Vector{Int} + assign_clusters(X::AbstractMatrix{<:Real}, R::ClusteringResult; ...) -> Vector{Int} Perform the clustering assigment of ``n`` points into `k` clusters, using the learned prototopyes from the input `KmeansResult`. From f33eeddb8df8f530eec8956230fa3b16c2ccd912 Mon Sep 17 00:00:00 2001 From: David Buchaca Prats Date: Fri, 28 Oct 2022 23:22:43 +0200 Subject: [PATCH 05/14] refactor: update docstring --- src/kmeans.jl | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/src/kmeans.jl b/src/kmeans.jl index b270d2c3..adef67d8 100644 --- a/src/kmeans.jl +++ b/src/kmeans.jl @@ -390,14 +390,13 @@ function repick_unused_centers(X::AbstractMatrix{<:Real}, # in: the data matrix colwise!(ds, distance, v, X) tcosts = min(tcosts, ds) end +end + """ assign_clusters(X::AbstractMatrix{<:Real}, R::ClusteringResult; ...) -> Vector{Int} -Perform the clustering assigment of ``n`` points into `k` clusters, -using the learned prototopyes from the input `KmeansResult`. - -Note: This method is usefull when clustering new data leveraging a fitted model. +Assign the samples specified as the columns of `X` to the corresponding clusters from `R`. # Arguments - `X`: Input data to be clustered. @@ -427,4 +426,3 @@ function assign_clusters( return cluster_assignments end -end From 546805d965ceccd677deb7d0dca2548f02c70cfd Mon Sep 17 00:00:00 2001 From: David Buchaca Prats Date: Fri, 28 Oct 2022 23:30:17 +0200 Subject: [PATCH 06/14] refactor: move assign clusters to utils --- src/Clustering.jl | 7 +++++-- src/kmeans.jl | 32 -------------------------------- src/utils.jl | 34 ++++++++++++++++++++++++++++++++++ 3 files changed, 39 insertions(+), 34 deletions(-) diff --git a/src/Clustering.jl b/src/Clustering.jl index fd763402..2e9e6393 100644 --- a/src/Clustering.jl +++ b/src/Clustering.jl @@ -29,7 +29,7 @@ module Clustering kmpp, kmpp_by_costs, # kmeans - kmeans, kmeans!, KmeansResult, get_cluster_assignments, + kmeans, kmeans!, KmeansResult, # kmedoids kmedoids, kmedoids!, KmedoidsResult, @@ -65,7 +65,10 @@ module Clustering Hclust, hclust, cutree, # MCL - mcl, MCLResult + mcl, MCLResult, + + # utils + assign_clusters ## source files diff --git a/src/kmeans.jl b/src/kmeans.jl index adef67d8..fff47911 100644 --- a/src/kmeans.jl +++ b/src/kmeans.jl @@ -393,36 +393,4 @@ function repick_unused_centers(X::AbstractMatrix{<:Real}, # in: the data matrix end -""" - assign_clusters(X::AbstractMatrix{<:Real}, R::ClusteringResult; ...) -> Vector{Int} - -Assign the samples specified as the columns of `X` to the corresponding clusters from `R`. - -# Arguments -- `X`: Input data to be clustered. -- `R`: Fitted keamns result. -""" -function assign_clusters( - samples::AbstractMatrix{T}, - clusters::KmeansResult, - distance::SemiMetric = SqEuclidean()) where {T} - - cluster_assignments = zeros(Int, size(X,2)) - - Threads.@threads for n in axes(X,2) - min_dist = typemax(T) - cluster_assignment = 0 - - for k in axes(R.centers, 2) - dist = distance(@view(X[:,n]),@view(R.centers[:,k])) - if dist < min_dist - min_dist = dist - cluster_assignment = k - end - end - cluster_assignments[n] = cluster_assignment - end - - return cluster_assignments -end diff --git a/src/utils.jl b/src/utils.jl index b832e86b..8ab4c14d 100644 --- a/src/utils.jl +++ b/src/utils.jl @@ -70,3 +70,37 @@ function updatemin!(r::AbstractArray, x::AbstractArray) end return r end + + +""" + assign_clusters(X::AbstractMatrix{<:Real}, R::ClusteringResult; ...) -> Vector{Int} + +Assign the samples specified as the columns of `X` to the corresponding clusters from `R`. + +# Arguments +- `X`: Input data to be clustered. +- `R`: Fitted keamns result. +""" +function assign_clusters( + samples::AbstractMatrix{T}, + clusters::ClusteringResult, + distance::SemiMetric = SqEuclidean()) where {T} + + cluster_assignments = zeros(Int, size(X, 2)) + + Threads.@threads for n in axes(X, 2) + min_dist = typemax(T) + cluster_assignment = 0 + + for k in axes(R.centers, 2) + dist = distance(@view(X[:, n]), @view(R.centers[:, k])) + if dist < min_dist + min_dist = dist + cluster_assignment = k + end + end + cluster_assignments[n] = cluster_assignment + end + + return cluster_assignments +end \ No newline at end of file From a11a636701c16505ea98b52d10e8548e4b70c4f8 Mon Sep 17 00:00:00 2001 From: David Buchaca Prats Date: Fri, 28 Oct 2022 23:34:45 +0200 Subject: [PATCH 07/14] fix: inputs to cluster_assignment --- src/utils.jl | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/utils.jl b/src/utils.jl index 8ab4c14d..56ebeb55 100644 --- a/src/utils.jl +++ b/src/utils.jl @@ -72,18 +72,18 @@ function updatemin!(r::AbstractArray, x::AbstractArray) end -""" +"""gi assign_clusters(X::AbstractMatrix{<:Real}, R::ClusteringResult; ...) -> Vector{Int} Assign the samples specified as the columns of `X` to the corresponding clusters from `R`. # Arguments - `X`: Input data to be clustered. -- `R`: Fitted keamns result. +- `R`: Fitted clustering result. """ function assign_clusters( - samples::AbstractMatrix{T}, - clusters::ClusteringResult, + X::AbstractMatrix{T}, + R::ClusteringResult, distance::SemiMetric = SqEuclidean()) where {T} cluster_assignments = zeros(Int, size(X, 2)) From ca29e80d6c06f51eaff212dd8af6cf62c591fd6e Mon Sep 17 00:00:00 2001 From: David Buchaca Prats Date: Sat, 29 Oct 2022 23:05:48 +0200 Subject: [PATCH 08/14] refactor: remove added lines --- src/kmeans.jl | 3 --- 1 file changed, 3 deletions(-) diff --git a/src/kmeans.jl b/src/kmeans.jl index fff47911..3f96403f 100644 --- a/src/kmeans.jl +++ b/src/kmeans.jl @@ -391,6 +391,3 @@ function repick_unused_centers(X::AbstractMatrix{<:Real}, # in: the data matrix tcosts = min(tcosts, ds) end end - - - From 48a8c0e537f1d292709d1d45fb9f1ce39eb79797 Mon Sep 17 00:00:00 2001 From: David Buchaca Prats Date: Sun, 9 Apr 2023 18:31:24 +0200 Subject: [PATCH 09/14] test: add not implemented check --- src/utils.jl | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/src/utils.jl b/src/utils.jl index 56ebeb55..11bff0a0 100644 --- a/src/utils.jl +++ b/src/utils.jl @@ -72,7 +72,7 @@ function updatemin!(r::AbstractArray, x::AbstractArray) end -"""gi +""" assign_clusters(X::AbstractMatrix{<:Real}, R::ClusteringResult; ...) -> Vector{Int} Assign the samples specified as the columns of `X` to the corresponding clusters from `R`. @@ -86,9 +86,13 @@ function assign_clusters( R::ClusteringResult, distance::SemiMetric = SqEuclidean()) where {T} + if typeof(R) != KmeansResult + throw("NotImplemented: assign_clusters not implemented for $(typeof(R))") + end + cluster_assignments = zeros(Int, size(X, 2)) - Threads.@threads for n in axes(X, 2) + for n in axes(X, 2) min_dist = typemax(T) cluster_assignment = 0 From 30c98f9e87e77b9966d5ff88aba9e7fb3651ce53 Mon Sep 17 00:00:00 2001 From: David Buchaca Prats Date: Sun, 9 Apr 2023 23:56:03 +0200 Subject: [PATCH 10/14] test: add test with pairwise and without it --- src/utils.jl | 43 ++++++++++++++++++++++++++----------------- test/kmeans.jl | 6 +++++- test/runtests.jl | 3 ++- test/utils.jl | 12 ++++++++++++ 4 files changed, 45 insertions(+), 19 deletions(-) create mode 100644 test/utils.jl diff --git a/src/utils.jl b/src/utils.jl index 11bff0a0..33dc27a6 100644 --- a/src/utils.jl +++ b/src/utils.jl @@ -1,6 +1,6 @@ # Common utilities - ##### common types +using Distances """ ClusteringResult @@ -80,30 +80,39 @@ Assign the samples specified as the columns of `X` to the corresponding clusters # Arguments - `X`: Input data to be clustered. - `R`: Fitted clustering result. +- `distance`: SemiMertric used to compute distances between vectors and clusters centroids. +- `pairwise_computation`: Boolean specifying whether to compute and store pairwise distances. + """ function assign_clusters( X::AbstractMatrix{T}, - R::ClusteringResult, - distance::SemiMetric = SqEuclidean()) where {T} + R::ClusteringResult; + distance::SemiMetric = SqEuclidean(), + pairwise_computation::Bool = true) where {T} - if typeof(R) != KmeansResult - throw("NotImplemented: assign_clusters not implemented for $(typeof(R))") + if !(typeof(R) <: KmeansResult) + throw(MethodError(assign_clusters, + "NotImplemented: assign_clusters not implemented for R of type $(typeof(R))")) end - cluster_assignments = zeros(Int, size(X, 2)) - - for n in axes(X, 2) - min_dist = typemax(T) - cluster_assignment = 0 - - for k in axes(R.centers, 2) - dist = distance(@view(X[:, n]), @view(R.centers[:, k])) - if dist < min_dist - min_dist = dist - cluster_assignment = k + if pairwise_computation + Xdist = pairwise(distance, X, R.centers, dims=2) + cluster_assignments = partialsortperm.(eachrow(Xdist), 1) + else + cluster_assignments = zeros(Int, size(X, 2)) + Threads.@threads for n in axes(X, 2) + min_dist = typemax(T) + cluster_assignment = 0 + + for k in axes(R.centers, 2) + dist = distance(@view(X[:, n]), @view(R.centers[:, k])) + if dist < min_dist + min_dist = dist + cluster_assignment = k + end end + cluster_assignments[n] = cluster_assignment end - cluster_assignments[n] = cluster_assignment end return cluster_assignments diff --git a/test/kmeans.jl b/test/kmeans.jl index 5a27b00c..e10756a9 100644 --- a/test/kmeans.jl +++ b/test/kmeans.jl @@ -207,8 +207,12 @@ end @testset "get cluster assigments" begin X = rand(5, 100) R = kmeans(X, 10; maxiter=200) - reassigned_clusters = assign_clusters(X, R); + reassigned_clusters = assign_clusters(X, R; pairwise_computation=true); @test R.assignments == reassigned_clusters + + reassigned_clusters2 = assign_clusters(X, R; pairwise_computation=false); + @test R.assignments == reassigned_clusters2 + end end diff --git a/test/runtests.jl b/test/runtests.jl index 1f9d483a..a074d7e3 100644 --- a/test/runtests.jl +++ b/test/runtests.jl @@ -6,7 +6,8 @@ using SparseArrays using StableRNGs using Statistics -tests = ["seeding", +tests = ["assigned_cluster", + "seeding", "kmeans", "kmedoids", "affprop", diff --git a/test/utils.jl b/test/utils.jl new file mode 100644 index 00000000..e4b3b498 --- /dev/null +++ b/test/utils.jl @@ -0,0 +1,12 @@ +using Test +using Clustering +using Distances + +@testset "get cluster assigments not implemented method" begin + + X = rand(10,3) + dist = pairwise(SqEuclidean(), X, dims=2) + R = kmedoids!(dist, [1, 2, 6]) + + @test_throws MethodError assign_clusters(X, R); +end From 022c2f7349914512cee5de7c30ed76407f896969 Mon Sep 17 00:00:00 2001 From: David Buchaca Prats Date: Mon, 10 Apr 2023 00:07:38 +0200 Subject: [PATCH 11/14] refactor: use specific kmeans method within kmeans --- src/kmeans.jl | 44 +++++++++++++++++++++++++++++++++++++++++++- src/utils.jl | 21 --------------------- test/utils.jl | 4 ++-- 3 files changed, 45 insertions(+), 24 deletions(-) diff --git a/src/kmeans.jl b/src/kmeans.jl index 3f96403f..1429156b 100644 --- a/src/kmeans.jl +++ b/src/kmeans.jl @@ -1,5 +1,5 @@ # K-means algorithm - +using Distances #### Interface # C is the type of centers, an (abstract) matrix of size (d x k) @@ -391,3 +391,45 @@ function repick_unused_centers(X::AbstractMatrix{<:Real}, # in: the data matrix tcosts = min(tcosts, ds) end end + + +""" + assign_clusters(X::AbstractMatrix{<:Real}, R::ClusteringResult; ...) -> Vector{Int} + +Assign the samples specified as the columns of `X` to the corresponding clusters from `R`. + +# Arguments +- `X`: Input data to be clustered. +- `R`: Fitted clustering result. +- `distance`: SemiMertric used to compute distances between vectors and clusters centroids. +- `pairwise_computation`: Boolean specifying whether to compute and store pairwise distances. + +""" +function assign_clusters( + X::AbstractMatrix{T}, + R::KmeansResult; + distance::SemiMetric = SqEuclidean(), + pairwise_computation::Bool = true) where {T} + + if pairwise_computation + Xdist = pairwise(distance, X, R.centers, dims=2) + cluster_assignments = partialsortperm.(eachrow(Xdist), 1) + else + cluster_assignments = zeros(Int, size(X, 2)) + Threads.@threads for n in axes(X, 2) + min_dist = typemax(T) + cluster_assignment = 0 + + for k in axes(R.centers, 2) + dist = distance(@view(X[:, n]), @view(R.centers[:, k])) + if dist < min_dist + min_dist = dist + cluster_assignment = k + end + end + cluster_assignments[n] = cluster_assignment + end + end + + return cluster_assignments +end diff --git a/src/utils.jl b/src/utils.jl index 33dc27a6..cb8568d7 100644 --- a/src/utils.jl +++ b/src/utils.jl @@ -95,25 +95,4 @@ function assign_clusters( "NotImplemented: assign_clusters not implemented for R of type $(typeof(R))")) end - if pairwise_computation - Xdist = pairwise(distance, X, R.centers, dims=2) - cluster_assignments = partialsortperm.(eachrow(Xdist), 1) - else - cluster_assignments = zeros(Int, size(X, 2)) - Threads.@threads for n in axes(X, 2) - min_dist = typemax(T) - cluster_assignment = 0 - - for k in axes(R.centers, 2) - dist = distance(@view(X[:, n]), @view(R.centers[:, k])) - if dist < min_dist - min_dist = dist - cluster_assignment = k - end - end - cluster_assignments[n] = cluster_assignment - end - end - - return cluster_assignments end \ No newline at end of file diff --git a/test/utils.jl b/test/utils.jl index e4b3b498..97917e5f 100644 --- a/test/utils.jl +++ b/test/utils.jl @@ -4,9 +4,9 @@ using Distances @testset "get cluster assigments not implemented method" begin - X = rand(10,3) + X = rand(10,5) dist = pairwise(SqEuclidean(), X, dims=2) - R = kmedoids!(dist, [1, 2, 6]) + R = kmedoids!(dist, [1, 2, 3]) @test_throws MethodError assign_clusters(X, R); end From 467b4be84496bac8620d3f48c228c11046eb3619 Mon Sep 17 00:00:00 2001 From: David Buchaca Prats Date: Mon, 10 Apr 2023 00:09:54 +0200 Subject: [PATCH 12/14] fix: runtest bad import --- test/runtests.jl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/runtests.jl b/test/runtests.jl index a074d7e3..5e2cbbb1 100644 --- a/test/runtests.jl +++ b/test/runtests.jl @@ -6,7 +6,7 @@ using SparseArrays using StableRNGs using Statistics -tests = ["assigned_cluster", +tests = ["utils", "seeding", "kmeans", "kmedoids", From 7d4b7d4e53e1beb3685c25fa4fac7731eb073018 Mon Sep 17 00:00:00 2001 From: David Buchaca Prats Date: Tue, 11 Apr 2023 11:31:55 +0200 Subject: [PATCH 13/14] refactor: separate kwargs from other args in method description --- src/kmeans.jl | 4 +++- src/utils.jl | 4 ++-- 2 files changed, 5 insertions(+), 3 deletions(-) diff --git a/src/kmeans.jl b/src/kmeans.jl index 1429156b..89061d95 100644 --- a/src/kmeans.jl +++ b/src/kmeans.jl @@ -394,13 +394,15 @@ end """ - assign_clusters(X::AbstractMatrix{<:Real}, R::ClusteringResult; ...) -> Vector{Int} + assign_clusters(X::AbstractMatrix{<:Real}, R::KmeansResult; [kwargs...])) -> Vector{Int} Assign the samples specified as the columns of `X` to the corresponding clusters from `R`. # Arguments - `X`: Input data to be clustered. - `R`: Fitted clustering result. + +# Keyword arguments - `distance`: SemiMertric used to compute distances between vectors and clusters centroids. - `pairwise_computation`: Boolean specifying whether to compute and store pairwise distances. diff --git a/src/utils.jl b/src/utils.jl index cb8568d7..71ccfe65 100644 --- a/src/utils.jl +++ b/src/utils.jl @@ -80,8 +80,8 @@ Assign the samples specified as the columns of `X` to the corresponding clusters # Arguments - `X`: Input data to be clustered. - `R`: Fitted clustering result. -- `distance`: SemiMertric used to compute distances between vectors and clusters centroids. -- `pairwise_computation`: Boolean specifying whether to compute and store pairwise distances. + +See the `assign_clusters` method in [`kmeans`](@ref) for the description of optional `kwargs`. """ function assign_clusters( From d51e5d8de754238d4581692548a2d3f5a0f1c6b1 Mon Sep 17 00:00:00 2001 From: David Buchaca Prats Date: Tue, 11 Apr 2023 11:41:03 +0200 Subject: [PATCH 14/14] refactor: rewrite kwargs description in kmeans and utils --- src/kmeans.jl | 2 +- src/utils.jl | 6 ++++-- 2 files changed, 5 insertions(+), 3 deletions(-) diff --git a/src/kmeans.jl b/src/kmeans.jl index 89061d95..7b5f6552 100644 --- a/src/kmeans.jl +++ b/src/kmeans.jl @@ -394,7 +394,7 @@ end """ - assign_clusters(X::AbstractMatrix{<:Real}, R::KmeansResult; [kwargs...])) -> Vector{Int} + assign_clusters(X::AbstractMatrix{<:Real}, R::KmeansResult; kwargs...) -> Vector{Int} Assign the samples specified as the columns of `X` to the corresponding clusters from `R`. diff --git a/src/utils.jl b/src/utils.jl index 71ccfe65..efdf2d30 100644 --- a/src/utils.jl +++ b/src/utils.jl @@ -73,7 +73,7 @@ end """ - assign_clusters(X::AbstractMatrix{<:Real}, R::ClusteringResult; ...) -> Vector{Int} + assign_clusters(X::AbstractMatrix{<:Real}, R::ClusteringResult; kwargs...) -> Vector{Int} Assign the samples specified as the columns of `X` to the corresponding clusters from `R`. @@ -81,7 +81,9 @@ Assign the samples specified as the columns of `X` to the corresponding clusters - `X`: Input data to be clustered. - `R`: Fitted clustering result. -See the `assign_clusters` method in [`kmeans`](@ref) for the description of optional `kwargs`. +# Keyword arguments +- Cluster specific keyword arguments. For example, see the `assign_clusters` method in + [`kmeans`](@ref) for the description of optional `kwargs`. """ function assign_clusters(