Skip to content

Commit

Permalink
Solves issue #32: KernelPerceptron non working with a single class in…
Browse files Browse the repository at this point in the history
… training
  • Loading branch information
sylvaticus committed Jun 10, 2022
1 parent 767f697 commit ea06f92
Show file tree
Hide file tree
Showing 2 changed files with 14 additions and 8 deletions.
2 changes: 1 addition & 1 deletion Project.toml
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
name = "BetaML"
uuid = "024491cd-cc6b-443e-8034-08ea7eb7db2b"
authors = ["Antonello Lobianco <antonello@lobianco.org>"]
version = "0.6.0"
version = "0.6.1"

[deps]
CategoricalArrays = "324d7699-5711-5eae-9e2f-1d82baa6b597"
Expand Down
20 changes: 13 additions & 7 deletions src/Perceptron/Perceptron.jl
Original file line number Diff line number Diff line change
Expand Up @@ -200,7 +200,7 @@ Train a multiclass kernel classifier "perceptron" algorithm based on x and y.
# Parameters:
* `x`: Feature matrix of the training data (n × d)
* `y`: Associated labels of the training data, in the format of ⨦ 1
* `y`: Associated labels of the training data
* `K`: Kernel function to employ. See `?radialKernel` or `?polynomialKernel`for details or check `?BetaML.Utils` to verify if other kernels are defined (you can alsways define your own kernel) [def: [`radialKernel`](@ref)]
* `T`: Maximum number of iterations (aka "epochs") across the whole set (if the set is not fully classified earlier) [def: 100]
* `α`: Initial distribution of the errors [def: `zeros(length(y))`]
Expand All @@ -220,9 +220,8 @@ Train a multiclass kernel classifier "perceptron" algorithm based on x and y.
# Example:
```jldoctest
julia> model = kernelPerceptron([1.1 2.1; 5.3 4.2; 1.8 1.7], [-1,1,-1])
julia> ŷtrain = Perceptron.predict(xtrain,model.x,model.y,model.α, model.classes,K=model.K)
julia> ϵtrain = error(ytrain, mode(ŷtrain))
julia> model = kernelPerceptron([1.1 1.1; 5.3 4.2; 1.8 1.7; 7.5 5.2;], ["a","c","b","c"])
julia> ŷtest = Perceptron.predict([10 10; 2.2 2.5; 1 1],model.x,model.y,model.α, model.classes,K=model.K)
```
"""
function kernelPerceptron(x, y; K=radialKernel, T=100, α=zeros(Int64,length(y)), nMsgs=0, shuffle=false, rng = Random.GLOBAL_RNG)
Expand All @@ -234,11 +233,10 @@ function kernelPerceptron(x, y; K=radialKernel, T=100, α=zeros(Int64,length(y))
outX = Array{typeof(x),1}(undef,nModels)
outY = Array{Array{Int64,1},1}(undef,nModels)
outα = Array{Array{Int64,1},1}(undef,nModels)

modelCounter = 1
for (i,c) in enumerate(yclasses)
for (i2,c2) in enumerate(yclasses)
if i2 <= i continue end
if i2 <= i continue end # never false with a single class (always "continue")
ids = ( (y .== c) .| (y .== c2) )
thisx = x[ids,:]
thisy = y[ids]
Expand All @@ -257,7 +255,7 @@ end
"""
kernelPerceptronBinary(x,y;K,T,α,nMsgs,shuffle)
Train a multiclass kernel classifier "perceptron" algorithm based on x and y
Train a binary kernel classifier "perceptron" algorithm based on x and y
# Parameters:
* `x`: Feature matrix of the training data (n × d)
Expand Down Expand Up @@ -578,6 +576,10 @@ function predict(x,xtrain,ytrain,α;K=radialKernel)
(n,d) = size(x)
(ntrain,d2) = size(xtrain)
if (d2 != d) error("xtrain and x must have the same dimensions."); end
# corner case all one category
if length(unique(ytrain)) == 1
return fill(unique(ytrain)[1],n)
end
if ( length(ytrain) != ntrain || length(α) != ntrain) error("xtrain, ytrain and α must all have the same length."); end
y = zeros(Int64,n)
for i in 1:n
Expand Down Expand Up @@ -616,6 +618,10 @@ function predict(x,xtrain,ytrain,α;K=radialKernel)
(n,d) = size(x)
nCl = length(classes)
y = Array{Dict{Tcl,Float64},1}(undef,n)
# corner case single class in training
if nCl == 1
return fill(Dict(classes[1] => 100.0),n)
end
nModels = Int((nCl * (nCl - 1)) / 2)
if !(nModels == length(xtrain) == length(ytrain) == length(α)) error("xtrain, ytrain or α have a length not compatible with the number of classes in this model."); end
x = makeMatrix(x)
Expand Down

2 comments on commit ea06f92

@sylvaticus
Copy link
Owner Author

Choose a reason for hiding this comment

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

@JuliaRegistrator register

Release notes:

bugfix in Kernel Perceptron (binary and multi-class) when a single class is present in training (issue #32)

@JuliaRegistrator
Copy link

Choose a reason for hiding this comment

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

Registration pull request created: JuliaRegistries/General/62122

After the above pull request is merged, it is recommended that a tag is created on this repository for the registered package version.

This will be done automatically if the Julia TagBot GitHub Action is installed, or can be done manually through the github interface, or via:

git tag -a v0.6.1 -m "<description of version>" ea06f92ca479a5934553ad37c29c51f17faf191a
git push origin v0.6.1

Please sign in to comment.