Code Monkey home page Code Monkey logo

libsvm.jl's Introduction

LIBSVM.jl

Build Status codecov

This is a Julia interface for LIBSVM and for the linear SVM model provided by LIBLINEAR.

Features:

  • Supports all LIBSVM models: classification C-SVC, nu-SVC, regression: epsilon-SVR, nu-SVR and distribution estimation: one-class SVM
  • Model objects are represented by Julia type SVM which gives you easy access to model features and can be saved e.g. as JLD file
  • Supports ScikitLearn.jl API

Usage

LIBSVM API

This provides a lower level API similar to LIBSVM C-interface. See ?svmtrain for options.

using LIBSVM
using RDatasets
using Printf
using Statistics

# Load Fisher's classic iris data
iris = dataset("datasets", "iris")

# First four dimension of input data is features
X = Matrix(iris[:, 1:4])'

# LIBSVM handles multi-class data automatically using a one-against-one strategy
y = iris.Species

# Split the dataset into training set and testing set
Xtrain = X[:, 1:2:end]
Xtest  = X[:, 2:2:end]
ytrain = y[1:2:end]
ytest  = y[2:2:end]

# Train SVM on half of the data using default parameters. See documentation
# of svmtrain for options
model = svmtrain(Xtrain, ytrain)

# Test model on the other half of the data.
ŷ, decision_values = svmpredict(model, Xtest);

# Compute accuracy
@printf "Accuracy: %.2f%%\n" mean.== ytest) * 100

Precomputed kernel

It is possible to use different kernels than those that are provided. In such a case, it is required to provide a matrix filled with precomputed kernel values.

For training, a symmetric matrix is expected:

K = [k(x_1, x_1)  k(x_1, x_2)  ...  k(x_1, x_l);
     k(x_2, x_1)
         ...                            ...
     k(x_l, x_1)        ...         k(x_l, x_l)]

where x_i is i-th training instance and l is the number of training instances.

To predict n instances, a matrix of shape (l, n) is expected:

KK = [k(x_1, t_1)  k(x_1, t_2)  ...  k(x_1, t_n);
      k(x_2, t_1)
          ...                            ...
      k(x_l, t_1)        ...         k(x_l, t_n)]

where t_i is i-th instance to be predicted.

Example

# Training data
X = [-2 -1 -1 1 1 2;
     -1 -1 -2 1 2 1]
y = [1, 1, 1, 2, 2, 2]

# Testing data
T = [-1 2 3;
     -1 2 2]

# Precomputed matrix for training (corresponds to linear kernel)
K = X' * X

model = svmtrain(K, y, kernel=Kernel.Precomputed)

# Precomputed matrix for prediction
KK = X' * T

ỹ, _ = svmpredict(model, KK)

ScikitLearn API

You can alternatively use ScikitLearn.jl API with same options as svmtrain:

using LIBSVM
using RDatasets

# Classification C-SVM
iris = dataset("datasets", "iris")
X = Matrix(iris[:, 1:4])
y = iris.Species

Xtrain = X[1:2:end, :]
Xtest  = X[2:2:end, :]
ytrain = y[1:2:end]
ytest  = y[2:2:end]

model = fit!(SVC(), Xtrain, ytrain)
ŷ = predict(model, Xtest)
# Epsilon-Regression

whiteside = RDatasets.dataset("MASS", "whiteside")
X = Matrix(whiteside[:, 3:3])  # the `Gas` column
y = whiteside.Temp

model = fit!(EpsilonSVR(cost = 10., gamma = 1.), X, y)
ŷ = predict(model, X)

MLJ API

The MLJ interface to LIBSVM.jl consists of the following models:

  • classification: LinearSVC, SVC, NuSVC
  • regression: EpsilonSVR, NuSVR
  • outlier detection: OneClassSVM

Each model has a detailed document string, which includes examples of usage. Document strings can be accessed from MLJ without loading LIBSVM.jl (or its MLJ interface) as shown in the following example:

using MLJ     # or MLJModels 
doc("NuSVC", pkg="LIBSVM")

This assumes the version of MLJModels loaded is 0.15.5 or higher.

Credits

The LIBSVM.jl library is currently developed and maintained by Matti Pastell. It was originally developed by Simon Kornblith.

LIBSVM by Chih-Chung Chang and Chih-Jen Lin

libsvm.jl's People

Contributors

ablaom avatar aviks avatar barucden avatar benevolent0505 avatar dilumaluthge avatar femtocleaner[bot] avatar github-actions[bot] avatar iblislin avatar martinuzzifrancesco avatar mpastell avatar rdeits avatar simonbyrne avatar simonster avatar staticfloat avatar till-m avatar timholy avatar tkelman avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

libsvm.jl's Issues

julia crush when using LIBSVM on large datasets

Hi,
It happens to me that julia will crush when using LIBSVM for classification on large datasets. In Juno, the error happens when the dataset is 20002000 artificial random generated. In cmd, the error happens when dataset is 1000010000.

Here's the bug report:

Please submit a bug report with steps to reproduce this fault, and any error messages that follow (in their entirety). Thanks.
Exception: EXCEPTION_ACCESS_VIOLATION at 0x7ffea53ba5a9 -- svm_predict_values at C:\Users\inrm.julia\packages\LIBSVM\5Z99T\deps\libsvm.dll (unknown line)
in expression starting at E:\Coder\github\qisvm\qisvm.jl:705
svm_predict_values at C:\Users\inrm.julia\packages\LIBSVM\5Z99T\deps\libsvm.dll (unknown line)
vcomp_fork at C:\Windows\SYSTEM32\VCOMP140.DLL (unknown line)
vcomp_fork at C:\Windows\SYSTEM32\VCOMP140.DLL (unknown line)
vcomp_fork at C:\Windows\SYSTEM32\VCOMP140.DLL (unknown line)
svm_predict_values at C:\Users\inrm.julia\packages\LIBSVM\5Z99T\deps\libsvm.dll (unknown line)
#svmpredict#4 at C:\Users\inrm.julia\packages\LIBSVM\5Z99T\src\LIBSVM.jl:435
svmpredict at C:\Users\inrm.julia\packages\LIBSVM\5Z99T\src\LIBSVM.jl:402
_jl_invoke at /cygdrive/d/buildbot/worker/package_win64/build/src/cygdrive/d/buildbot/worker/package_win64/build/src\gf.c:2141 [inlined]
jl_apply_generic at /cygdrive/d/buildbot/worker/package_win64/build/src/cygdrive/d/buildbot/worker/package_win64/build/src\gf.c:2305
svm3 at E:\Coder\github\qisvm\qisvm.jl:362
competition at E:\Coder\github\qisvm\qisvm.jl:692
competition at E:\Coder\github\qisvm\qisvm.jl:670
unknown function (ip: 0000000001E34E8E)
_jl_invoke at /cygdrive/d/buildbot/worker/package_win64/build/src/cygdrive/d/buildbot/worker/package_win64/build/src\gf.c:2141 [inlined]
jl_apply_generic at /cygdrive/d/buildbot/worker/package_win64/build/src/cygdrive/d/buildbot/worker/package_win64/build/src\gf.c:2305
jl_apply at /cygdrive/d/buildbot/worker/package_win64/build/src/cygdrive/d/buildbot/worker/package_win64/build/src\julia.h:1631 [inlined]
do_call at /cygdrive/d/buildbot/worker/package_win64/build/src/cygdrive/d/buildbot/worker/package_win64/build/src\interpreter.c:328
eval_value at /cygdrive/d/buildbot/worker/package_win64/build/src/cygdrive/d/buildbot/worker/package_win64/build/src\interpreter.c:417
eval_stmt_value at /cygdrive/d/buildbot/worker/package_win64/build/src/cygdrive/d/buildbot/worker/package_win64/build/src\interpreter.c:368 [inlined]
eval_body at /cygdrive/d/buildbot/worker/package_win64/build/src/cygdrive/d/buildbot/worker/package_win64/build/src\interpreter.c:764
jl_interpret_toplevel_thunk_callback at /cygdrive/d/buildbot/worker/package_win64/build/src/cygdrive/d/buildbot/worker/package_win64/build/src\interpreter.c:888
unknown function (ip: FFFFFFFFFFFFFFFE)
unknown function (ip: 0000000038CDAD0F)
unknown function (ip: 0000000000000002)
jl_toplevel_eval_flex at /cygdrive/d/buildbot/worker/package_win64/build/src/cygdrive/d/buildbot/worker/package_win64/build/src\toplevel.c:814
jl_parse_eval_all at /cygdrive/d/buildbot/worker/package_win64/build/src/cygdrive/d/buildbot/worker/package_win64/build/src\ast.c:873
include_string at .\loading.jl:1075
#200 at C:\Users\inrm.julia\packages\Atom\cYxbS\src\eval.jl:166
withpath at C:\Users\inrm.julia\packages\CodeTools\kosGY\src\utils.jl:30
_jl_invoke at /cygdrive/d/buildbot/worker/package_win64/build/src/cygdrive/d/buildbot/worker/package_win64/build/src\gf.c:2141 [inlined]
jl_apply_generic at /cygdrive/d/buildbot/worker/package_win64/build/src/cygdrive/d/buildbot/worker/package_win64/build/src\gf.c:2305
withpath at C:\Users\inrm.julia\packages\Atom\cYxbS\src\eval.jl:9
#199 at C:\Users\inrm.julia\packages\Atom\cYxbS\src\eval.jl:163 [inlined]
with_logstate at .\logging.jl:395
with_logger at .\logging.jl:491 [inlined]
#198 at C:\Users\inrm.julia\packages\Atom\cYxbS\src\eval.jl:162 [inlined]
hideprompt at C:\Users\inrm.julia\packages\Atom\cYxbS\src\repl.jl:141
macro expansion at C:\Users\inrm.julia\packages\Atom\cYxbS\src\eval.jl:161 [inlined]
macro expansion at C:\Users\inrm.julia\packages\Media\ItEPc\src\dynamic.jl:24 [inlined]
evalall at C:\Users\inrm.julia\packages\Atom\cYxbS\src\eval.jl:151
_jl_invoke at /cygdrive/d/buildbot/worker/package_win64/build/src/cygdrive/d/buildbot/worker/package_win64/build/src\gf.c:2141 [inlined]
jl_apply_generic at /cygdrive/d/buildbot/worker/package_win64/build/src/cygdrive/d/buildbot/worker/package_win64/build/src\gf.c:2305
jl_apply at /cygdrive/d/buildbot/worker/package_win64/build/src/cygdrive/d/buildbot/worker/package_win64/build/src\julia.h:1631 [inlined]
jl_f__apply at /cygdrive/d/buildbot/worker/package_win64/build/src/cygdrive/d/buildbot/worker/package_win64/build/src\builtins.c:627
macro expansion at C:\Users\inrm.julia\packages\Atom\cYxbS\src\eval.jl:36 [inlined]
#172 at .\task.jl:333
unknown function (ip: 00000000182BE893)
_jl_invoke at /cygdrive/d/buildbot/worker/package_win64/build/src/cygdrive/d/buildbot/worker/package_win64/build/src\gf.c:2141 [inlined]
jl_apply_generic at /cygdrive/d/buildbot/worker/package_win64/build/src/cygdrive/d/buildbot/worker/package_win64/build/src\gf.c:2305
jl_apply at /cygdrive/d/buildbot/worker/package_win64/build/src/cygdrive/d/buildbot/worker/package_win64/build/src\julia.h:1631 [inlined]
start_task at /cygdrive/d/buildbot/worker/package_win64/build/src/cygdrive/d/buildbot/worker/package_win64/build/src\task.c:659
Allocations: 92015103 (Pool: 91992416; Big: 22687); GC: 79

you can find in the report that the errors happen in function svm_predict_values().

versioninfo()
Julia Version 1.3.1
Commit 2d5741174c (2019-12-30 21:36 UTC)
Platform Info:
OS: Windows (x86_64-w64-mingw32)
CPU: Intel(R) Core(TM) i5-8300H CPU @ 2.30GHz
WORD_SIZE: 64
LIBM: libopenlibm
LLVM: libLLVM-6.0.1 (ORCJIT, skylake)
Environment:
JULIA_EDITOR = "C:\Users\inrm\AppData\Local\atom\app-1.43.0\atom.exe" -a
JULIA_FFTW_PROVIDER = MKL
JULIA_NUM_THREADS = 4

I am using LIBSVM v0.4.0.

Thanks a lot if you can check it!

ScikitLearn API example gives MethodError

julia> svrmod = fit!(EpsilonSVR(cost = 10., gamma = 1.), X, y)
ERROR: MethodError: no method matching fit!(::LIBSVM.EpsilonSVR, ::Array{Float64,1}, ::Array{Float64,1})
Closest candidates are:
  fit!(::Union{LIBSVM.AbstractSVC, LIBSVM.AbstractSVR}, ::AbstractArray{T,2} where T, ::Array{T,1} where T) at /Users/dilum/.julia/v0.6/LIBSVM/src/ScikitLearnAPI.jl:70
  fit!(::Union{LIBSVM.AbstractSVC, LIBSVM.AbstractSVR}, ::AbstractArray{T,2} where T) at /Users/dilum/.julia/v0.6/LIBSVM/src/ScikitLearnAPI.jl:70
  fit!(::LIBSVM.LinearSVC, ::AbstractArray{T,2} where T, ::Array{T,1} where T) at /Users/dilum/.julia/v0.6/LIBSVM/src/ScikitLearnAPI.jl:101

More segfaults with boolean labels

Similar to #23 but with a slightly different set of data:

using LIBSVM
for i in 1:10000
    data = rand(20, 20)
    labels = rand(Bool, 20)
    model = svmtrain(data[:, 1:2:end], labels[1:2:end],);
    (predicted_labels, decision_values) = svmpredict(model, data[:, 2:2:end]);
end

fails with:

signal (11): Segmentation fault
while loading /home/rdeits/.julia/v0.5/LIBSVM/test.jl, in expression starting on line 2
#svmtrain#3 at /home/rdeits/.julia/v0.5/LIBSVM/src/LIBSVM.jl:359
unknown function (ip: 0x7f4ca4a0813c)
macro expansion; at /home/rdeits/.julia/v0.5/LIBSVM/test.jl:5 [inlined]
anonymous at ./<missing> (unknown line)
unknown function (ip: 0x7f4ca4a05d4f)
jl_call_method_internal at /home/centos/buildbot/slave/package_tarball64/build/src/julia_internal.h:210 [inlined]
jl_toplevel_eval_flex at /home/centos/buildbot/slave/package_tarball64/build/src/toplevel.c:569
jl_parse_eval_all at /home/centos/buildbot/slave/package_tarball64/build/src/ast.c:717
jl_load at /home/centos/buildbot/slave/package_tarball64/build/src/toplevel.c:596
jl_load_ at /home/centos/buildbot/slave/package_tarball64/build/src/toplevel.c:605
include_from_node1 at ./loading.jl:488
unknown function (ip: 0x7f4ec8f4234b)
jl_call_method_internal at /home/centos/buildbot/slave/package_tarball64/build/src/julia_internal.h:210 [inlined]
jl_apply_generic at /home/centos/buildbot/slave/package_tarball64/build/src/gf.c:1950
process_options at ./client.jl:265
_start at ./client.jl:321
unknown function (ip: 0x7f4ec8f67888)
jl_call_method_internal at /home/centos/buildbot/slave/package_tarball64/build/src/julia_internal.h:210 [inlined]
jl_apply_generic at /home/centos/buildbot/slave/package_tarball64/build/src/gf.c:1950
unknown function (ip: 0x401b3d)
unknown function (ip: 0x401446)
__libc_start_main at /build/eglibc-MjiXCM/eglibc-2.19/csu/libc-start.c:287
unknown function (ip: 0x40148c)
Allocations: 2757178 (Pool: 2751954; Big: 5224); GC: 3
[1]    20793 segmentation fault (core dumped)  julia test.jl

(this is with LIBSVM.jl master on Julia v0.5.1 on Ubuntu 14.04).

julia> versioninfo()
Julia Version 0.5.1
Commit 6445c82 (2017-03-05 13:25 UTC)
Platform Info:
  OS: Linux (x86_64-pc-linux-gnu)
  CPU: Intel(R) Core(TM) i7-5820K CPU @ 3.30GHz
  WORD_SIZE: 64
  BLAS: libopenblas (USE64BITINT DYNAMIC_ARCH NO_AFFINITY Haswell)
  LAPACK: libopenblas64_
  LIBM: libopenlibm
  LLVM: libLLVM-3.7.1 (ORCJIT, haswell)

crash with Julia 1.8.4 under Windows 11

I am using LIBSVM.jl v0.8.0, under Windows 11.

It works fine with Julia 1.8.3:

julia> versioninfo()
Julia Version 1.8.3
Commit 0434deb161 (2022-11-14 20:14 UTC)
Platform Info:
OS: Windows (x86_64-w64-mingw32)
CPU: 16 × Intel(R) Core(TM) i9-10885H CPU @ 2.40GHz
WORD_SIZE: 64
LIBM: libopenlibm
LLVM: libLLVM-13.0.1 (ORCJIT, skylake)
Threads: 8 on 16 virtual cores
Environment:
JULIA_EDITOR = code
JULIA_NUM_THREADS = 8

But when I uses Julia 1.8.4:

julia> versioninfo()
Julia Version 1.8.4
Commit 00177ebc4f (2022-12-23 21:32 UTC)
Platform Info:
OS: Windows (x86_64-w64-mingw32)
CPU: 16 × Intel(R) Core(TM) i9-10885H CPU @ 2.40GHz
WORD_SIZE: 64
LIBM: libopenlibm
LLVM: libLLVM-13.0.1 (ORCJIT, skylake)
Threads: 8 on 16 virtual cores
Environment:
JULIA_EDITOR = code
JULIA_NUM_THREADS = 8`

running any function kills my Julia session, for instance after doing:

using LIBSVM
(X, y) = (randn(100,4), randn(100))

and then the command below;

svmtrain(X', y)

kills the process and closes directly Julia.

Did somebody observe the same problem and know what is happening?

Occasional segfaults with libsvm

The following script reliably segfaults when run with Julia v0.5 on macOS:

using LIBSVM
for i in 1:10000
    labels = [2, 2, 2, 13, 1, 4, 14, 15, 1, 9, 12]
    data = rand(Bool, 20, length(labels))
    model = svmtrain(labels[1:2:end], data[:, 1:2:end]);
    (predicted_labels, decision_values) = svmpredict(model, data[:, 2:2:end]);
end

LLDB shows:

Process 23010 launched: '/usr/local/bin/julia' (x86_64)
libjulia.0.5.1.dylib was compiled with optimization - stepping may behave oddly; variables may not be available.
Process 23010 stopped
* thread #1: tid = 0x40e766, 0x0000000100054dc9 libjulia.0.5.1.dylib`jl_gc_pool_alloc(ptls=<unavailable>, pool_offset=<unavailable>, osize=<unavailable>) + 73 at gc.c:838, queue = 'com.apple.main-thread', stop reason = EXC_BAD_ACCESS (code=EXC_I386_GPFLT)
    frame #0: 0x0000000100054dc9 libjulia.0.5.1.dylib`jl_gc_pool_alloc(ptls=<unavailable>, pool_offset=<unavailable>, osize=<unavailable>) + 73 at gc.c:838 [opt]
(lldb) bt
* thread #1: tid = 0x40e766, 0x0000000100054dc9 libjulia.0.5.1.dylib`jl_gc_pool_alloc(ptls=<unavailable>, pool_offset=<unavailable>, osize=<unavailable>) + 73 at gc.c:838, queue = 'com.apple.main-thread', stop reason = EXC_BAD_ACCESS (code=EXC_I386_GPFLT)
  * frame #0: 0x0000000100054dc9 libjulia.0.5.1.dylib`jl_gc_pool_alloc(ptls=<unavailable>, pool_offset=<unavailable>, osize=<unavailable>) + 73 at gc.c:838 [opt]
    frame #1: 0x00000001000576da libjulia.0.5.1.dylib`jl_gc_alloc [inlined] jl_gc_alloc_(sz=<unavailable>) + 177 at julia_internal.h:169 [opt]
    frame #2: 0x0000000100057629 libjulia.0.5.1.dylib`jl_gc_alloc(ptls=<unavailable>, sz=<unavailable>, ty=0x00000001089145b0) + 9 at gc.c:1906 [opt]
    frame #3: 0x0000000100034db9 libjulia.0.5.1.dylib`_new_array_(atype=0x00000001089145b0, ndims=2, dims=0x00007fff5fbfe250, isunboxed=1, elsz=8) + 361 at array.c:95 [opt]
    frame #4: 0x0000000100035600 libjulia.0.5.1.dylib`jl_alloc_array_2d [inlined] _new_array(atype=<unavailable>, ndims=2, dims=0x0000000000000004) + 97 at array.c:149 [opt]
    frame #5: 0x000000010003559f libjulia.0.5.1.dylib`jl_alloc_array_2d(atype=<unavailable>, nr=<unavailable>, nc=<unavailable>) + 31 at array.c:353 [opt]
    frame #6: 0x00000003193f60fb
    frame #7: 0x00000003193f6537
    frame #8: 0x0000000100016608 libjulia.0.5.1.dylib`jl_apply_generic [inlined] jl_call_method_internal(args=<unavailable>, nargs=<unavailable>) + 72 at julia_internal.h:210 [opt]
    frame #9: 0x00000001000165c0 libjulia.0.5.1.dylib`jl_apply_generic(args=<unavailable>, nargs=<unavailable>) + 928 at gf.c:1950 [opt]
    frame #10: 0x00000003193f1439
    frame #11: 0x00000003193f1510
    frame #12: 0x0000000100042a03 libjulia.0.5.1.dylib`jl_toplevel_eval_flex [inlined] jl_call_method_internal(nargs=1) + 71 at julia_internal.h:210 [opt]
    frame #13: 0x00000001000429bc libjulia.0.5.1.dylib`jl_toplevel_eval_flex(e=<unavailable>, fast=<unavailable>, expanded=<unavailable>) + 1276 at toplevel.c:569 [opt]
    frame #14: 0x00000001000204fe libjulia.0.5.1.dylib`jl_parse_eval_all(fname=<unavailable>, content=<unavailable>, contentlen=<unavailable>) + 1214 at ast.c:717 [opt]
    frame #15: 0x000000010004313b libjulia.0.5.1.dylib`jl_load_ [inlined] jl_load(fname="/Users/rdeits/locomotion/explorations/hybrid-correlations/test.jl") + 187 at toplevel.c:596 [opt]
    frame #16: 0x00000001000430e0 libjulia.0.5.1.dylib`jl_load_(str=<unavailable>) + 96 at toplevel.c:605 [opt]
    frame #17: 0x000000010493e77b sys.dylib`julia_include_from_node1_20229(#self#=<unavailable>, _path=<unavailable>) + 491 [opt]
    frame #18: 0x000000010493e98c sys.dylib`jlcall_include_from_node1_20229 + 12
    frame #19: 0x0000000100016608 libjulia.0.5.1.dylib`jl_apply_generic [inlined] jl_call_method_internal(args=<unavailable>, nargs=<unavailable>) + 72 at julia_internal.h:210 [opt]
    frame #20: 0x00000001000165c0 libjulia.0.5.1.dylib`jl_apply_generic(args=<unavailable>, nargs=<unavailable>) + 928 at gf.c:1950 [opt]
    frame #21: 0x0000000104962221 sys.dylib`julia_process_options_21584(#self#=<unavailable>, opts=<unavailable>) + 2513 [opt]
    frame #22: 0x0000000104963dc1 sys.dylib`julia__start_21575(#self#=<unavailable>) + 1313 [opt]
    frame #23: 0x00000001049647c9 sys.dylib`jlcall__start_21575 + 9
    frame #24: 0x0000000100016608 libjulia.0.5.1.dylib`jl_apply_generic [inlined] jl_call_method_internal(args=<unavailable>, nargs=<unavailable>) + 72 at julia_internal.h:210 [opt]
    frame #25: 0x00000001000165c0 libjulia.0.5.1.dylib`jl_apply_generic(args=<unavailable>, nargs=<unavailable>) + 928 at gf.c:1950 [opt]
    frame #26: 0x00000001000011e8 julia`true_main + 104
    frame #27: 0x000000010000115c julia`main + 108
    frame #28: 0x00000001000010d4 julia`start + 52

SVR doesn't seem to work properly

Hi @simonster,

neither epsilon-SVR nor nu-SVR seem to work properly. Here's an example:

import PyPlot
import LIBSVM

N = 150
X = reshape(collect(1:float(N)), N, 1)
y = reshape(map(x->x^2, X), N)
idx = collect(1:N)
shuffle!(idx)
X_tr = X[idx[1:120], :]
y_tr = y[idx[1:120]]
X_test = X[idx[121:end], :]
y_test = y[idx[121:end]]

svm = LIBSVM.svmtrain(y_tr, X_tr'; svm_type=Int32(4), C=1000.)
y_pr_tr = LIBSVM.svmpredict(svm, X_tr')[1]
y_pr_test = LIBSVM.svmpredict(svm, X_test')[1]

PyPlot.scatter(X_tr, y_tr; color="blue")
PyPlot.scatter(X_tr, y_pr_tr; color="red")
PyPlot.scatter(X_test, y_pr_test; color="green")
PyPlot.show()

That code results in the following plot:
svr-fail

The training points in red are predicted seemingly perfectly. The predictions on the test set are scattered though.
Playing around with the parameters doesn't seem to make it any better. In fact, some combinations of parameters lead to errors. For example,

svm = LIBSVM.svmtrain(y_tr, X_tr'; svm_type=Int32(4), C=1000., gamma=0.01)

leads to

ERROR: LoadError: BoundsError: attempt to access 120-element Array{Float64,1}:
16129.0
16384.0
6241.0
9409.0
121.0
11236.0
4624.0
4.0
4489.0
3025.0

17689.0
5929.0
21316.0
1681.0
9.0
2809.0
9604.0
2601.0
1764.0
at index [128]
in svmpredict at /home/peter/.julia/v0.4/LIBSVM/src/LIBSVM.jl:365
in include at ./boot.jl:261
in include_from_node1 at ./loading.jl:320
in process_options at ./client.jl:280
in _start at ./client.jl:378
while loading /home/peter/dev/jlearn/sandbox.jl, in expression starting on line 15

.

Cannot install LIBSVM

(@v1.4) pkg> add LIBSVM RDatasets
   Updating registry at `~/.julia/registries/General`
   Updating git-repo `https://github.com/JuliaRegistries/General.git`
  Resolving package versions...
  Installed XML2_jll ──────── v2.9.9+4
  Installed Libiconv_jll ──── v1.16.0+2
  Installed Mocking ───────── v0.7.1
  Installed ScikitLearnBase ─ v0.5.0
  Installed LIBSVM ────────── v0.4.0
  Installed RData ─────────── v0.7.1
  Installed TimeZones ─────── v1.2.0
  Installed LIBLINEAR ─────── v0.5.1
  Installed RDatasets ─────── v0.6.8
   Updating `~/.julia/environments/v1.4/Project.toml`
  [b1bec4e5] + LIBSVM v0.4.0
  [ce6b1742] + RDatasets v0.6.8
   Updating `~/.julia/environments/v1.4/Manifest.toml`
  [8f5d6c58] + EzXML v1.1.0
  [2d691ee1] + LIBLINEAR v0.5.1
  [b1bec4e5] + LIBSVM v0.4.0
  [94ce4f54] + Libiconv_jll v1.16.0+2
  [78c3b35d] + Mocking v0.7.1
  [df47a6cb] + RData v0.7.1
  [ce6b1742] + RDatasets v0.6.8
  [6e75b9c4] + ScikitLearnBase v0.5.0
  [f269a46b] + TimeZones v1.2.0
  [02c8fc9c] + XML2_jll v2.9.9+4
   Building LIBLINEAR → `~/.julia/packages/LIBLINEAR/yTdp5/deps/build.log`
┌ Error: Error building `LIBLINEAR`: 
│ rm -f *~ zz.o
│ g++ -Wall -Wconversion -O3 -fPIC -c -o zz.o zz.cpp
│ make: g++: Command not found
│ Makefile:16: recipe for target 'zz.o' failed
│ make: *** [zz.o] Error 127
│ ERROR: LoadError: failed process: Process(`make lib`, ProcessExited(2)) [2]
│ 
│ Stacktrace:
│  [1] pipeline_error at ./process.jl:525 [inlined]
│  [2] run(::Cmd; wait::Bool) at ./process.jl:440
│  [3] run(::Cmd) at ./process.jl:438
│  [4] top-level scope at /home/cossio/.julia/packages/LIBLINEAR/yTdp5/deps/build.jl:4
│  [5] include(::String) at ./client.jl:439
│  [6] top-level scope at none:5
│ in expression starting at /home/cossio/.julia/packages/LIBLINEAR/yTdp5/deps/build.jl:1
└ @ Pkg.Operations /buildworker/worker/package_linux64/build/usr/share/julia/stdlib/v1.4/Pkg/src/Operations.jl:899
   Building LIBSVM ───→ `~/.julia/packages/LIBSVM/5Z99T/deps/build.log`
┌ Error: Error building `LIBSVM`: 
│ make lib_normal || make lib_fallback
│ make[1]: Entering directory '/home/cossio/.julia/packages/LIBSVM/5Z99T/deps/libsvm-3.22'
│ make svm.o_normal || make svm.o_fallback
│ make[2]: Entering directory '/home/cossio/.julia/packages/LIBSVM/5Z99T/deps/libsvm-3.22'
│ g++ -Wall -Wconversion -O3 -fPIC -DENABLEOPENMP -fopenmp -c svm.cpp
│ make[2]: g++: Command not found
│ Makefile:41: recipe for target 'svm.o_normal' failed
│ make[2]: *** [svm.o_normal] Error 127
│ make[2]: Leaving directory '/home/cossio/.julia/packages/LIBSVM/5Z99T/deps/libsvm-3.22'
│ make[2]: Entering directory '/home/cossio/.julia/packages/LIBSVM/5Z99T/deps/libsvm-3.22'
│ g++  -c svm.cpp
│ make[2]: g++: Command not found
│ Makefile:44: recipe for target 'svm.o_fallback' failed
│ make[2]: *** [svm.o_fallback] Error 127
│ make[2]: Leaving directory '/home/cossio/.julia/packages/LIBSVM/5Z99T/deps/libsvm-3.22'
│ Makefile:38: recipe for target 'svm.o' failed
│ make[1]: *** [svm.o] Error 2
│ make[1]: Leaving directory '/home/cossio/.julia/packages/LIBSVM/5Z99T/deps/libsvm-3.22'
│ make[1]: Entering directory '/home/cossio/.julia/packages/LIBSVM/5Z99T/deps/libsvm-3.22'
│ make svm.o_normal || make svm.o_fallback
│ make[2]: Entering directory '/home/cossio/.julia/packages/LIBSVM/5Z99T/deps/libsvm-3.22'
│ g++ -Wall -Wconversion -O3 -fPIC -DENABLEOPENMP -fopenmp -c svm.cpp
│ make[2]: g++: Command not found
│ Makefile:41: recipe for target 'svm.o_normal' failed
│ make[2]: *** [svm.o_normal] Error 127
│ make[2]: Leaving directory '/home/cossio/.julia/packages/LIBSVM/5Z99T/deps/libsvm-3.22'
│ make[2]: Entering directory '/home/cossio/.julia/packages/LIBSVM/5Z99T/deps/libsvm-3.22'
│ g++  -c svm.cpp
│ make[2]: g++: Command not found
│ Makefile:44: recipe for target 'svm.o_fallback' failed
│ make[2]: *** [svm.o_fallback] Error 127
│ make[2]: Leaving directory '/home/cossio/.julia/packages/LIBSVM/5Z99T/deps/libsvm-3.22'
│ Makefile:38: recipe for target 'svm.o' failed
│ make[1]: *** [svm.o] Error 2
│ make[1]: Leaving directory '/home/cossio/.julia/packages/LIBSVM/5Z99T/deps/libsvm-3.22'
│ Makefile:10: recipe for target 'lib' failed
│ make: *** [lib] Error 2
│ ERROR: LoadError: failed process: Process(`make lib`, ProcessExited(2)) [2]
│ 
│ Stacktrace:
│  [1] pipeline_error at ./process.jl:525 [inlined]
│  [2] run(::Cmd; wait::Bool) at ./process.jl:440
│  [3] run(::Cmd) at ./process.jl:438
│  [4] top-level scope at /home/cossio/.julia/packages/LIBSVM/5Z99T/deps/build.jl:12
│  [5] include(::String) at ./client.jl:439
│  [6] top-level scope at none:5
│ in expression starting at /home/cossio/.julia/packages/LIBSVM/5Z99T/deps/build.jl:2
└ @ Pkg.Operations /buildworker/worker/package_linux64/build/usr/share/julia/stdlib/v1.4/Pkg/src/Operations.jl:899
   Building TimeZones → `~/.julia/packages/TimeZones/OjMoF/deps/build.log`

(@v1.4) pkg> 

Windows?

Hi @simonster ,

Just tried to get someone set up with this on Windows. I tried dropping in the .dll from http://www.csie.ntu.edu.tw/~cjlin/libsvm/ but it reported "module not found" which is worrying - I have no idea if that .dll is 32-bit or 64-bit so thats not a great start. Have you had any experience with this?

Can not find weight in model when i want to build a SVM-RFE model

Hello!
I want to bulid a SVM model about recursive feature elimination!
However , after I use the demo model=svmtrain(instances[:, 1:2:end], vectorlabels[1:2:end]);, i could not find the Coefficient of the features.

there are 3 class and 4 feature in The data about iris. So i think i can get 12 Coefficient of the features. Could you tell me where are they?
Thank you very much!

Can't build LIBSVM on Appveyor

Hi,

I'm not quite sure where to report this but my Appveyor CI jobs are failing because of some error that shows up when trying to build LIBSVM.

See e.g. https://ci.appveyor.com/project/JonasIsensee/jld2-jl/builds/35694287/job/1qy2o7xu763iws6d

Building LIBSVM ───→ `C:\Users\appveyor\.julia\packages\LIBSVM\5Z99T\deps\build.log`
┌ Error: Error building `LIBSVM`: 
│ Exception calling "DownloadFile" with "2" argument(s): "The remote server 
│ returned an error: (403) Forbidden."
│ At line:1 char:96
│ + ... pe]::Tls12; (New-Object System.Net.Webclient).DownloadFile('http://we ...
│ +                 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
│     + CategoryInfo          : NotSpecified: (:) [], MethodInvocationException
│     + FullyQualifiedErrorId : WebException
│  
│ [ Info: Downloading LIBSVM binary
│ ERROR: LoadError: failed process: Process(`'C:\windows\System32\WindowsPowerShell\v1.0\powershell.exe' -Version 3 -NoProfile -Command "[System.Net.ServicePointManager]::SecurityProtocol = [System.Net.SecurityProtocolType]::Tls12; (New-Object System.Net.Webclient).DownloadFile('http://web.ics.purdue.edu/~finej/libsvm32-3.22_1.dll', 'C:\Users\appveyor\.julia\packages\LIBSVM\5Z99T\deps\libsvm.dll')"`, ProcessExited(1)) [1]
│ Stacktrace:
│  [1] error(::String, ::Base.Process, ::String, ::Int64, ::String) at .\error.jl:42
│  [2] pipeline_error at .\process.jl:705 [inlined]
│  [3] download(::String, ::String) at .\download.jl:20
│  [4] top-level scope at C:\Users\appveyor\.julia\packages\LIBSVM\5Z99T\deps\build.jl:8
│  [5] include at .\boot.jl:317 [inlined]
│  [6] include_relative(::Module, ::String) at .\loading.jl:1044
│  [7] include(::Module, ::String) at .\sysimg.jl:29
│  [8] include(::String) at .\client.jl:392
│  [9] top-level scope at none:0
│ in expression starting at C:\Users\appveyor\.julia\packages\LIBSVM\5Z99T\deps\build.jl:2
└ @ Pkg.Operations C:\cygwin\home\Administrator\buildbot\worker\package_win32\build\usr\share\julia\stdlib\v1.0\Pkg\src\Operations.jl:1096

Error building LIBSVM

When I try to install the LIBSVM, error occurred in building process.

   Building LIBSVM ───→ `E:\iCode\.julia\packages\LIBSVM\5Z99T\deps\build.log`
┌ Error: Error building `LIBSVM`:
│ [ Info: Downloading LIBSVM binary
│ ┌ Error: Download failed: curl: (22) The requested URL returned error: 403 Forbidden
│ └ @ Base download.jl:43
│ ERROR: LoadError: failed process: Process(`'C:\Windows\System32\curl.exe' -s -S -g -L -f -o 'E:\iCode\.julia\packages\LIBSVM\5Z99T\deps\libsvm.dll' 'http://web.ics.purdue.edu/~finej/libsvm-3.22_1.dll'`, ProcessExited(22)) [22]
│
│ Stacktrace:
│  [1] pipeline_error at .\process.jl:525 [inlined]
│  [2] download_curl(::String, ::String, ::String) at .\download.jl:44
│  [3] download(::String, ::String) at .\download.jl:62
│  [4] top-level scope at E:\iCode\.julia\packages\LIBSVM\5Z99T\deps\build.jl:6
│  [5] include(::String) at .\client.jl:439
│  [6] top-level scope at none:5
│ in expression starting at E:\iCode\.julia\packages\LIBSVM\5Z99T\deps\build.jl:2
└ @ Pkg.Operations D:\buildbot\worker\package_win64\build\usr\share\julia\stdlib\v1.4\Pkg\src\Operations.jl:892

From the error message, we can clear see that it was stopped in the download step.
So I try to visit the URL. http://web.ics.purdue.edu/~finej/libsvm-3.22_1.dll

The webpage returns 403 Forbidden error. It seems that file is no longer available.
Detailed message:

Forbidden
You don't have permission to access /~finej/libsvm-3.22_1.dll on this server.

So, is there any other way to obtain the libsvm-3.22_1.dll file.
Thank you.

coef0 does not contain the intercept

After training a SVM model, I was able to extract the model coefficients from svm.coefs, but svm.coef0 stays 0.0 after training. I am assuming the intercept is supposed to be contained in coef0 when training a svm model. If the intercept coefficient is stored somewhere else after training, then I am not able to find it.

Update to allow Compat = 3.0 in REQUIRE or, better, upgrade to Julia 1.0

MLJ currently provides a wrapper for the LIBSVM.jl models. For reasons I don't yet understand (JuliaAI/MLJModels.jl#155) it appears a recent update of Compat to 3.0 is going to break this wrapper.

I wonder if there is any chance someone is interested in giving this package a little love. If not, MLJ may have discontinue support.

It is worth noting that MLJ also wraps the ScikitLearn SVM models (which, in turn, wrap the same C libraries wrapped here, I believe) so maybe this is not a great loss. Nevertheless, it would be nicer to skip the python layer.

@ValdarT @DilumAluthge @simonster @mpastell

Serializability of SVMs with user-defined/callable kernels

As has been noted by @barucden in #88, SVMs with user-defined/callable kernels are generally not (de-)serializable. Since the issue has recently been brought up again in conjunction with downstream changes in JuliaAI/MLJLIBSVMInterface.jl#13 it would probably be worth having an issue one can reference to track the problem and collate discussion.

Current situation:

An SVM with a user-defined/callable kernel can be serialized and deserialized without problem, while the kernel function is available:

using LIBSVM
using Serialization

X = [-2 -1 -1 1 1 2;
     -1 -1 -2 1 2 1]
y = [1, 1, 1, 2, 2, 2]

kernel(x1, x2) = x1' * x2

model = svmtrain(X, y, kernel=kernel)

ỹ, _ = svmpredict(model, X)
print(y == ỹ) #true

serialize("serialized_svm.jls", model)

model = deserialize("serialized_svm.jls")
T = [-1 2 3;
     -1 2 2]

ŷ, _ = svmpredict(model, T)
print([1, 2, 2] == ŷ) #ŧrue

After exiting and re-entering REPL, kernel is undefined:

using LIBSVM
using Serialization

model = deserialize("serialized_svm.jls") #error

execution fails with

model = deserialize("serialized_svm.jls")
ERROR: UndefVarError: #kernel not defined
Stacktrace:
 [1] open(f::typeof(deserialize), args::String; kwargs::Base.Pairs{Symbol, Union{}, Tuple{}, NamedTuple{(), Tuple{}}})
   @ Base ./io.jl:330
 [2] open
   @ ./io.jl:328 [inlined]
 [3] deserialize(filename::String)
   @ Serialization /usr/share/julia/stdlib/v1.7/Serialization/src/Serialization.jl:798
 [4] top-level scope
   @ REPL[3]:1

If kernel is defined at the time deserialize is called, the code works:

using LIBSVM
using Serialization

kernel(x1, x2) = x1' * x2

model = deserialize("serialized_svm.jls")
T = [-1 2 3;
     -1 2 2]

ỹ, _ = svmpredict(model, T)

print([1, 2, 2] == ỹ) #true

In contrast, serialization using built-in kernels works without a problem:

using LIBSVM
using Serialization

X = [-2 -1 -1 1 1 2;
     -1 -1 -2 1 2 1]
y = [1, 1, 1, 2, 2, 2]

model = svmtrain(X, y, kernel=Kernel.Linear)

ỹ, _ = svmpredict(model, X)

print(y == ỹ) #true

serialize("serialized_svm.jls", model)

After exiting and re-entering REPL:

using LIBSVM
using Serialization

model = deserialize("serialized_svm.jls")
T = [-1 2 3;
     -1 2 2]

ỹ, _ = svmpredict(model, T)

print([1, 2, 2] == ỹ) #true

Possible Courses

I don't have too much experience with Julia and Serialization.jl in particular, but I see a few ways of tackling this issue:

  • Leaving the current state, since there is no "misleading" behaviour. The error message seems pretty clear, at least to me.
  • Additionally, adding a note in the README mentioning that serialization doesn't work for user-defined/callable kernels (I haven't gotten around to #89, will try to work on that over easter or slightly after)
  • Maybe it is possible to provide custom serialization strategies that allow us to properly serialize trained models with custom/user-defined kernels. This is probably not possible using Serialization.jl, since its functionality seems to be rather restricted, but JLD.jl can do it, I think?

Missing dependency on Windows

I was having some trouble getting this package working on a minimal Windows test machine. I kept getting the error

could not load library "libsvm.dll"
The specified module could not be found.

It turns out the libsvm.dll that is downloaded has a dependency on vcomp140.dll, which was not present on my fresh Windows 10 install. Everything works after installing a VC++ runtime from here: https://www.microsoft.com/en-us/download/details.aspx?id=48145

Just wanted to leave a note in case others had the same problem

Support Julia 1.0

Currently, import LIBSVM works on Julia 0.6 and Julia 0.7, but fails on Julia 1.0.

Could we add support for using LIBSVM.jl on Julia 1.0?

cc: @mpastell

TagBot trigger issue

This issue is used to trigger TagBot; feel free to unsubscribe.

If you haven't already, you should update your TagBot.yml to include issue comment triggers.
Please see this post on Discourse for instructions and more details.

If you'd like for me to do this for you, comment TagBot fix on this issue.
I'll open a PR within a few hours, please be patient!

[PkgEval] LIBSVM may have a testing issue on Julia 0.3 (2014-05-27)

PackageEvaluator.jl is a script that runs nightly. It attempts to load all Julia packages and run their tests (if available) on both the stable version of Julia (0.2) and the nightly build of the unstable version (0.3). The results of this script are used to generate a package listing enhanced with testing results.

On Julia 0.3

  • On 2014-05-26 the testing status was Tests pass..
  • On 2014-05-27 the testing status changed to Tests fail, but package loads..

Tests pass. means that PackageEvaluator found the tests for your package, executed them, and they all passed.

Tests fail, but package loads. means that PackageEvaluator found the tests for your package, executed them, and they didn't pass. However, trying to load your package with using worked.

This issue was filed because your testing status became worse. No additional issues will be filed if your package remains in this state, and no issue will be filed if it improves. If you'd like to opt-out of these status-change messages, reply to this message saying you'd like to and @IainNZ will add an exception. If you'd like to discuss PackageEvaluator.jl please file an issue at the repository. For example, your package may be untestable on the test machine due to a dependency - an exception can be added.

Keep SVMProblem from being garbage-collected

From libsvm help:

NOTE Because svm_model contains pointers to svm_problem, you can
not free the memory used by svm_problem if you are still using the
svm_model produced by svm_train().

This causes LIBSVM package to randomly fail if julia garbage-collects the SVMProblem and nodes before calling svmpredict.

This patch solves the isue:

diff --git a/src/LIBSVM.jl b/src/LIBSVM.jl
index f50b760..b1d72e5 100644
--- a/src/LIBSVM.jl
+++ b/src/LIBSVM.jl
@@ -66,6 +66,9 @@ end
 type SVMModel{T}
     ptr::Ptr{Void}
     param::Vector{SVMParameter}
+    problem::Vector{SVMProblem}
+    nodes::Array{SVMNode,2}
+    nodeptr::Vector{Ptr{SVMNode}}
     labels::Vector{T}
     weight_labels::Vector{Int32}
     weights::Vector{Float64}
@@ -224,7 +227,7 @@ function svmtrain{T, U<:Real}(labels::AbstractVector{T},
     ptr = ccall(svm_train(), Ptr{Void}, (Ptr{SVMProblem},
         Ptr{SVMParameter}), problem, param)

-    model = SVMModel(ptr, param, reverse_labels, weight_labels, weights,
+    model = SVMModel(ptr, param, problem, nodes, nodeptrs, reverse_labels, weight_labels, weights,
         size(instances, 1), verbose)
     finalizer(model, svmfree)
     model

Can I get coefficients from the trained model?

I want to plot the decision boundary, and it seems I have to compute w and b first.

According to the documents of LIBSVM, I need to get sv_coef, rho and SVs from the model.

Can I get these values in this package?

Predict Doesn't work with one class SVM

The code for running a classical SVM -- which is directly from the documentation-- works fine:
using RDatasets, LIBSVM iris = dataset("datasets", "iris"); labels = iris[:Species]; instances = array(iris[:, 1:4])'; model = svmtrain(labels[1:2:end], instances[:, 1:2:end],svm_type=int32(0),kernel_type=int32(2)); (predicted_labels, decision_values) = svmpredict(model, instances[:, 2:2:end]); @printf "Accuracy: %.2f%%\n" mean((predicted_labels .== labels[2:2:end]))*100;

However, attempting to run a single-class SVM (by changing the "svm_type" to 2) fails. This is true even in simplest case, where i tweak the Iris dataset so all labels of train and test set are identical.
using RDatasets, LIBSVM; iris = dataset("datasets", "iris"); labels = iris[:Species]; labels[1:end]="setosa"; instances = array(iris[:, 1:4])'; model = svmtrain(labels[1:2:end], instances[:, 1:2:end],svm_type=int32(2),kernel_type=int32(2)); (predicted_labels, decision_values) = svmpredict(model, instances[:, 2:2:end]); @printf "Accuracy: %.2f%%\n" mean((predicted_labels .== labels[2:2:end]))*100;

The problem appears to come from the following section of svmpredict()
output = ccall(fn, Float64, (Ptr{Void}, Ptr{SVMNode}, Ptr{Float64}), model.ptr, nodeptrs[i], pointer(decvalues, nlabels*(i-1)+1)); class[i] = model.labels[int(output)]

For the single class SVM case, the output can sometimes be "-1", whereas there is (obviously) no model label located in position -1 of the array. I'm not sure if "-1" is supposed to represent "the other" class (upon which we haven't trained), or if it's representing an error in the ccall.

Segfault in svmpredict with @btime

I'm running into a segfault when trying to benchmark svmpredict. My config:

  • LIBSVM 0.4.0 (build dependency libsvm 3.22)
  • Ubuntu 19.10
  • Julia 1.2.0, 1.3.0 and 1.4.0-DEV.662 (2019-12-25)

Following MWE (taken from the unit tests of LIBSVM):

   _       _ _(_)_     |  Documentation: https://docs.julialang.org
  (_)     | (_) (_)    |
   _ _   _| |_  __ _   |  Type "?" for help, "]?" for Pkg help.
  | | | | | | |/ _` |  |
  | | |_| | | | (_| |  |  Version 1.3.0 (2019-11-26)
 _/ |\__'_|_|_|\__'_|  |  Official https://julialang.org/ release
|__/                   |


julia> using DelimitedFiles, LIBSVM, BenchmarkTools

julia> iris = readdlm(joinpath(dirname(@__FILE__), "iris.csv"), ',')

julia> labels = iris[:, 5];

julia> tinstances = convert(Matrix{Float64}, iris[:, 1:4]');

julia> model = svmtrain(tinstances[:, 1:2:end], labels[1:2:end]; verbose=false);

julia> @btime (class, decvalues) = svmpredict(model, tinstances[:, 2:2:end])
59.607 μs (16 allocations: 15.50 KiB)
(Any["setosa", "setosa", "setosa", "setosa", "setosa", "setosa", "setosa", "setosa", "setosa", "setosa"  …  "virginica", "versicolor", "virginica", "virginica", "virginica", "virginica", "virginica", "virginica", "virginica", "virginica"], [1.0795373127217927 1.076285347307982 … -0.8977486201494332 -0.9364766069276098; 1.1004210525961036 1.0767138900115194 … -1.0382989966396097 -1.0734485152396267; 0.26369235850072076 0.2543044167727957 … -0.5718494685608961 -0.31568093085243765])

julia> @btime (class, decvalues) = svmpredict(model, tinstances[:, 2:2:end])

signal (11): Segmentation fault
in expression starting at REPL[6]:1
_ZN6Kernel10k_functionEPK8svm_nodeS2_RK13svm_parameter at /home/gerhard/.julia/packages/LIBSVM/5Z99T/src/../deps/libsvm.so.2 (unknown line)
unknown function (ip: 0x7efdf43d386f)
Allocations: 14234478 (Pool: 13915011; Big: 319467); GC: 58
Segmentation fault (core dumped)

Sometimes I've to run the last line a couple of times to get the segfault. Anything else I can test?

Build fails on macOS with default clang compiler

The build step fails on macOS if the default (Apple-supplied) clang compiler is used, because Apple’s clang does not support the -fopenmp flag.

Thus, installing LIBLINEAR.jl currently fails on Travis macOS.

Can we add a conditional statement to the Makefile that disables multithreading if the operating system is macOS and the compiler is clang?

I’m happy to make the pull request!

Sent with GitHawk

Support LIBLinear

This is a great package, and it will be very important for machine learning.

I am wondering whether you plan to wrap LibLinear also (http://www.csie.ntu.edu.tw/~cjlin/liblinear/), which is developed by the same authors of LIBSVM.

It is amazingly fast(much faster than LIBSVM with linear kernel).

Small improvement

It is recommended to replace:

convert(Array,iris[:, 1:4])'

with

convert(Matrix,iris[:, 1:4])'

in your tutorial.

[PackageEvaluator.jl] Your package LIBSVM may have a testing issue.

This issue is being filed by a script, but if you reply, I will see it.

PackageEvaluator.jl is a script that runs nightly. It attempts to load all Julia packages and run their test (if available) on both the stable version of Julia (0.2) and the nightly build of the unstable version (0.3).

The results of this script are used to generate a package listing enhanced with testing results.

The status of this package, LIBSVM, on...

  • Julia 0.2 is 'Tests fail, but package loads.' PackageEvaluator.jl
  • Julia 0.3 is 'Tests fail, but package loads.' PackageEvaluator.jl

'No tests, but package loads.' can be due to their being no tests (you should write some if you can!) but can also be due to PackageEvaluator not being able to find your tests. Consider adding a test/runtests.jl file.

'Package doesn't load.' is the worst-case scenario. Sometimes this arises because your package doesn't have BinDeps support, or needs something that can't be installed with BinDeps. If this is the case for your package, please file an issue and an exception can be made so your package will not be tested.

This automatically filed issue is a one-off message. Starting soon, issues will only be filed when the testing status of your package changes in a negative direction (gets worse). If you'd like to opt-out of these status-change messages, reply to this message.

Read datasets from libsvm

Is it possible to read datasets from libsvm webpage in Julia ?

Here is an example of data (text file)

751.0 5:1 8:0.0 10:0.652913 11:0.701456 12:0.682039 13:0.677184 14:0.599515 15:0.589806 16:0.631068
703.0 6:1 8:0.0 10:0.696601941748 11:0.652913 12:0.701456 13:0.682039 14:0.677184 15:0.599515 16:0.589806
677.0 8:0.0 10:0.580097087379 11:0.696601941748 12:0.652913 13:0.701456 14:0.682039 15:0.677184 16:0.599515
718.0 1:1 8:0.0 10:0.516990291262 11:0.580097087379 12:0.696601941748 13:0.652913 14:0.701456 15:0.682039 16:0.677184

I couldn't find a direct way using CSV.jl or LIBSVM.jl, did I miss something ?

Thank you
Matthias

problem with example

I ran the Iris example on the GitHub page using Julia 1.4.1 (run from Atom on Ubuntu) and got :
ERROR: MethodError: no method matching LIBSVM.SupportVectors(::Int32, ::Array{Int32,1}, ::CategoricalArray{String,1,UInt8,String,CategoricalValue{String,UInt8},Union{}}, ::Array{Float64,2}, ::Array{Int32,1}, ::Array{LIBSVM.SVMNode,1})
Closest candidates are:
LIBSVM.SupportVectors(::Int32, ::Array{Int32,1}, ::Array{T,1}, ::AbstractArray{U,2}, ::Array{Int32,1}, ::Array{LIBSVM.SVMNode,1}) where {T, U} at /home/benny/.julia/packages/LIBSVM/5Z99T/src/LIBSVM.jl:18
LIBSVM.SupportVectors(::LIBSVM.SVMModel, ::Any, ::Any) at /home/benny/.julia/packages/LIBSVM/5Z99T/src/LIBSVM.jl:27
Stacktrace:
[1] LIBSVM.SupportVectors(::LIBSVM.SVMModel, ::CategoricalArray{String,1,UInt8,String,CategoricalValue{String,UInt8},Union{}}, ::Array{Float64,2}) at /home/benny/.julia/packages/LIBSVM/5Z99T/src/LIBSVM.jl:40
[2] LIBSVM.SVM(::LIBSVM.SVMModel, ::CategoricalArray{String,1,UInt8,String,CategoricalValue{String,UInt8},Union{}}, ::Array{Float64,2}, ::Nothing, ::Array{CategoricalValue{String,UInt8},1}, ::Type{T} where T, ::LIBSVM.Kernel.KERNEL) at /home/benny/.julia/packages/LIBSVM/5Z99T/src/LIBSVM.jl:73
[3] svmtrain(::Array{Float64,2}, ::CategoricalArray{String,1,UInt8,String,CategoricalValue{String,UInt8},Union{}}; svmtype::Type{T} where T, kernel::LIBSVM.Kernel.KERNEL, degree::Int64, gamma::Float64, coef0::Float64, cost::Float64, nu::Float64, epsilon::Float64, tolerance::Float64, shrinking::Bool, probability::Bool, weights::Nothing, cachesize::Float64, verbose::Bool, nt::Int64) at /home/benny/.julia/packages/LIBSVM/5Z99T/src/LIBSVM.jl:386
[4] svmtrain(::Array{Float64,2}, ::CategoricalArray{String,1,UInt8,String,CategoricalValue{String,UInt8},Union{}}) at /home/benny/.julia/packages/LIBSVM/5Z99T/src/LIBSVM.jl:347
[5] top-level scope at /home/benny/.julia/scripts/10_06_2020/15_06_2020.jl:80

precomputed kernel

Hi,
how is a precomputed kernel to be used? I would have assumed that the following would do exactly the same as in the readme example. However it assigns the same label to all test instances. Also, with bigger data I get a crash from the garbage collector after calling svmpredict in this way.

using RDatasets, LIBSVM

# prepare the data

iris = dataset("datasets", "iris")
labels = iris[:Species]
instances = array(iris[:, 1:4])'

# compute the kernel on all instances

gamma = 1.0/size(instances, 1)
N = size(instances, 2)
kernel = Array(Float64, N, N)
for i=1:N, j=1:N
    kernel[i,j] = exp(-gamma * sum(abs2(instances[:,i] - instances[:,j])))
end

# train using half the instances

model = svmtrain(labels[1:2:end], kernel[1:2:end, 1:2:end], kernel_type=LIBSVM.Precomputed)

# test against rest of the instances

(predicted_labels, decision_values) = svmpredict(model, kernel[1:2:end, 2:2:end])

# display result

@printf "Accuracy: %.2f%%\n" mean((predicted_labels .== labels[2:2:end]))*100

error using LIBSVM in Julia v0.5

Hi

Apologies if I miss something obvious. Just trying to get any svm package to work in Julia. I've installed LIBSVM and used Pkg.checkout("LIBSVM") as a suggestion from one of the members from Junolab. No issues when I compile for the first time i.e. using LIBSVM, but I get the following error when I apply svmtrain:

julia> svmtrain(labels,vars2["X"]')
ERROR: could not load library "C:\Users\user.julia\v0.5\LIBSVM\deps\libsvm.so.2"
The specified module could not be found.

in dlopen(::String, ::UInt32) at .\libdl.jl:90
in get_libsvm() at C:\Users\user.julia\v0.5\LIBSVM\src\LIBSVM.jl:86
in svm_train() at C:\Users\user.julia\v0.5\LIBSVM\src\LIBSVM.jl:101
in #svmtrain#1(::Int32, ::Int32, ::Int64, ::Float64, ::Float64, ::Float64, ::Float64, ::Float64, ::Float64, ::Float64, ::Bool, ::Bool, ::Void, ::Bool, ::LIBSVM.#svmtrain, ::Array{Float64,1}, ::Array{Float64,2}) at C:\Users\user.julia\v0.5\LIBSVM\src\LIBSVM.jl:227
in svmtrain(::Array{Float64,1}, ::Array{Float64,2}) at C:\Users\user.julia\v0.5\LIBSVM\src\LIBSVM.jl:210

Thanks in advance

Save and load model to/from file

The MATLAB bindings to libsvm has the functions libsvmwrite and libsvmread. The R bindings has write.svm.

Is it possible to add methods to save and load the model to/from file?

"int32 not defined" when trying to use LIBSVM

Hello,

I installed the package using Pkg.add, which worked fine, but when I try to use it with: using LIBSVM, I get the following error:

julia> using LIBSVM
ERROR: LoadError: UndefVarError: int32 not defined
 in include_from_node1(::String) at ./loading.jl:488
 in eval(::Module, ::Any) at ./boot.jl:234
 in require(::Symbol) at ./loading.jl:415
while loading /home/xlambein/.julia/v0.5/LIBSVM/src/LIBSVM.jl, in expression starting on line 5

Do you have any idea what I might be doing wrong?

Using Kernels.Precomputed, svmpredict doesn't verify the dimensions of the input

Current behavior

It is possible to provide malformed gram matrices to svmpredict when using precomputed kernels:

using LIBSVM

# Training data
X = [-2 -1 -1 1 1 2;
     -1 -1 -2 1 2 1]
y = [1, 1, 1, 2, 2, 2]

# Testing data
T = [-1 2 3;
     -1 2 2]

# Precomputed matrix for training (corresponds to linear kernel)
K = X' * X

model = svmtrain(K, y, kernel=Kernel.Precomputed)

# Precomputed matrix for prediction
KK = X' * T

# truncate KK
KK_malformed = KK[1:1,:]

ỹ, decision_values = svmpredict(model, KK_malformed)

Output:

julia> ỹ
3-element Vector{Int64}:
 2
 2
 2

julia> decision_values
2×3 Matrix{Float64}:
 NaN    NaN    NaN
   0.0    0.0    0.0

Expected behavior

As described in the README, the gram matrix should have dimensions (l, n) when predicting n items on l training vectors and produce an error otherwise. Alternatively, it could also accept gram matrices of shape (k, n) where k is the number of support vectors of the model.

Error in Readme example

Just running the example from the README:

using RDatasets, LIBSVM

# Load Fisher's classic iris data
iris = dataset("datasets", "iris")

# LIBSVM handles multi-class data automatically using a one-against-one strategy
labels = convert(Vector, iris[:Species])

# First dimension of input data is features; second is instances
instances = convert(Array, iris[:, 1:4])'

# Train SVM on half of the data using default parameters. See documentation
# of svmtrain for options
model = svmtrain(instances[:, 1:2:end], labels[1:2:end]);

I got this error:

ERROR: MethodError: no method matching LIBSVM.SupportVectors(::Int32, ::Array{Int32,1}, ::CategoricalArray{String,1,UInt8,String,CategoricalString{UInt8},Union{}}, ::Array{Float64,2}, ::Array{Int32,1}, ::Array{LIBSVM.SVMNode,1})
Closest candidates are:
  LIBSVM.SupportVectors(::Int32, ::Array{Int32,1}, ::Array{T,1}, ::AbstractArray{U,2}, ::Array{Int32,1}, ::Array{LIBSVM.SVMNode,1}) where {T, U} at /home/cossio/.julia/packages/LIBSVM/Zv8gE/src/LIBSVM.jl:17
  LIBSVM.SupportVectors(::LIBSVM.SVMModel, ::Any, ::Any) at /home/cossio/.julia/packages/LIBSVM/Zv8gE/src/LIBSVM.jl:25
Stacktrace:
 [1] LIBSVM.SupportVectors(::LIBSVM.SVMModel, ::CategoricalArray{String,1,UInt8,String,CategoricalString{UInt8},Union{}}, ::Array{Float64,2}) at /home/cossio/.julia/packages/LIBSVM/Zv8gE/src/LIBSVM.jl:39
 [2] LIBSVM.SVM(::LIBSVM.SVMModel, ::CategoricalArray{String,1,UInt8,String,CategoricalString{UInt8},Union{}}, ::Array{Float64,2}, ::Nothing, ::Array{CategoricalString{UInt8},1}, ::Type{T} where T, ::LIBSVM.Kernel.KERNEL) at /home/cossio/.julia/packages/LIBSVM/Zv8gE/src/LIBSVM.jl:72
 [3] svmtrain(::Array{Float64,2}, ::CategoricalArray{String,1,UInt8,String,CategoricalString{UInt8},Union{}}; svmtype::Type{T} where T, kernel::LIBSVM.Kernel.KERNEL, degree::Int64, gamma::Float64, coef0::Float64, cost::Float64, nu::Float64, epsilon::Float64, tolerance::Float64, shrinking::Bool, probability::Bool, weights::Nothing, cachesize::Float64, verbose::Bool, nt::Int64) at /home/cossio/.julia/packages/LIBSVM/Zv8gE/src/LIBSVM.jl:352
 [4] svmtrain(::Array{Float64,2}, ::CategoricalArray{String,1,UInt8,String,CategoricalString{UInt8},Union{}}) at /home/cossio/.julia/packages/LIBSVM/Zv8gE/src/LIBSVM.jl:313
 [5] top-level scope at REPL[8]:3

Trained model size depends on the training data size

I am training SVM on quite big dataset, and after training I save the model. The size of the model depends on the size of the dataset. The size of my training data is 12MB and size of the model is 66 MB. Do I understand correctly that this depends on number of the support vectors and that model doesn't save training data itself?

Failed to build on Windows 7

Version 0.3.1 (2014-09-21 21:30 UTC)
x86_64-w64-mingw32

julia> Pkg.build("LIBSVM")
INFO: Building LIBSVM
===============================[ ERROR: LIBSVM ]================================
could not spawn 'make lib': no such file or directory (ENOENT)
while loading C:\Users\Adrian.julia\v0.3\LIBSVM\deps\build.jl, in expression starting on line 2
================================[ BUILD ERRORS ]================================
WARNING: LIBSVM had build errors.

  • packages with build errors remain installed in C:\Users\Adrian.julia\v0.3
  • build a package and all its dependencies with 'Pkg.build(pkg)'
  • build a single package by running its 'deps/build.jl' script

Cut a new release

@simonster The latest release on METADATA is from 2014, and doesn't work on Julia v0.5 anymore. Can we cut a new release?

ROC support

Hi,

I believe we have no support for computing ROC, yet. Would you, @mpastell, be interested in having something in that direction implemented?

I have implemented a function for computing TPRs and FPRs (and AUC), and I am happy to share it if you'd like me to.

LIBSVM.jl webpage : example not working

Hi,

The example on the LIBSVM.jl webpage gives some errors on my system.

LIBSVM v0.4.0
Julia 1.3.1

julia> labels = convert(Vector, iris[:Species])
┌ Warning: `getindex(df::DataFrame, col_ind::ColumnIndex)` is deprecated, use `df[!, col_ind]` instead.
│   caller = top-level scope at REPL[9]:1
└ @ Core REPL[9]:1
150-element Array{CategoricalString{UInt8},1}:
 "setosa"   
 "setosa"       
 "setosa"   
 ⋮          
 "virginica"
 "virginica"
 "virginica"

julia> instances = convert(Array, iris[:, 1:4])'
4×150 LinearAlgebra.Adjoint{Float64,Array{Float64,2}}:
 5.1  4.9  4.7  4.6  5.0  5.4  4.6  5.0  4.4  4.9  …  6.9  5.8  6.8  6.7  6.7  6.3  6.5  6.2  5.9
 3.5  3.0  3.2  3.1  3.6  3.9  3.4  3.4  2.9  3.1     3.1  2.7  3.2  3.3  3.0  2.5  3.0  3.4  3.0
 1.4  1.4  1.3  1.5  1.4  1.7  1.4  1.5  1.4  1.5     5.1  5.1  5.9  5.7  5.2  5.0  5.2  5.4  5.1
 0.2  0.2  0.2  0.2  0.2  0.4  0.3  0.2  0.2  0.1     2.3  1.9  2.3  2.5  2.3  1.9  2.0  2.3  1.8

julia> model = svmtrain(instances[:, 1:2:end], labels[1:2:end]);
ERROR: MethodError: no method matching LIBSVM.SupportVectors(::Int32, ::Array{Int32,1}, ::CategoricalArray{String,1,UInt8,String,CategoricalString{UInt8},Union{}}, ::Array{Float64,2}, ::Array{Int32,1}, ::Array{LIBSVM.SVMNode,1})
Closest candidates are:
  LIBSVM.SupportVectors(::Int32, ::Array{Int32,1}, ::Array{T,1}, ::AbstractArray{U,2}, ::Array{Int32,1}, ::Array{LIBSVM.SVMNode,1}) where {T, U} at /home/fred/.julia/packages/LIBSVM/5Z99T/src/LIBSVM.jl:18
  LIBSVM.SupportVectors(::LIBSVM.SVMModel, ::Any, ::Any) at /home/fred/.julia/packages/LIBSVM/5Z99T/src/LIBSVM.jl:27

Allow callable as kernel argument

For the built-in kernels you supply the data and the kernel you want to use, i.e.

model = svmtrain(Xtrain, ytrain, kernel=Kernel.Polynomial)

svmpredict(model, Xtest)

For a custom kernel you need to calculate the gram matrix manually:

K = make_gram(Xtrain, my_kernel)
model = svmtrain(K, ytrain, kernel=Kernel.Precomputed)

KK = make_gram(Xtrain, Xtest, my_kernel)
svmpredict(model, KK)

I think a more desirable way to do this would be to allow a callable as kernel argument (and calculate the gram matrix internally), i.e.

model = svmtrain(Xtrain, ytrain, kernel=my_kernel)

svmpredict(model, Xtest)

which is more syntactically consistent with the way the built-in kernels are used. Scikit-learn, for example, allows this in addition to precomputed gram matrices.

Bug in One-Class SVM implementation

Because of some suspicious results in attempting to use OneClassSVM with linear kernel, I constructed a toy example which is solveable without error, but despite svmtrain claiming convergence, the solution was incorrect.

I double-checked by projecting the problem into a 2-class one and running svmtrain with (default) SVC and the correct solution was quickly found by the routine. This is an acceptable workaround but much slower, especially for large datasets.

It looks to me like OneClassSVM has a fundamental bug.

Here is how to reproduce:
generate 500 random 2-vectors x standard normal, and keep only the ones for which x1-x2 >1 [there should be 120 to 130 of them]. Next, run OneClassSVM on these which should be able to bound all of the observations by a plane, but it does not, despite claiming convergence.

I would appreciate someone verifying this bug (and hopefully it being put on the 'to-do' list).

Thank you!

Code in Readme.md does not work.

I use julia 1.6.1
I installed LIBSVM.jl in Ubuntu as
] add LIBSVM

After that, I run the following source code in README.md.

using LIBSVM
using RDatasets

# Classification C-SVM
iris = dataset("datasets", "iris")
X = Matrix(iris[:, 1:4])
y = iris.Species

Xtrain = X[1:2:end, :]
Xtest  = X[2:2:end, :]
ytrain = y[1:2:end]
ytest  = y[2:2:end]

model = fit!(SVC(), Xtrain, ytrain)
ŷ = predict(model, Xtest)

But I get the following error.

ERROR: LoadError: MethodError: no method matching fit!(::SVC, ::Matrix{Float64}, ::CategoricalArrays.CategoricalVector{String, UInt8, String, CategoricalArrays.CategoricalValue{String, UInt8}, Union{}})
Closest candidates are:
  fit!(::Union{LIBSVM.AbstractSVC, LIBSVM.AbstractSVR}, ::AbstractMatrix{T} where T) at /home/****/.julia/packages/LIBSVM/5Z99T/src/ScikitLearnAPI.jl:68
  fit!(::Union{LIBSVM.AbstractSVC, LIBSVM.AbstractSVR}, ::AbstractMatrix{T} where T, ::Vector{T} where T) at /home/*****/.julia/packages/LIBSVM/5Z99T/src/ScikitLearnAPI.jl:68
  fit!(::LinearSVC, ::AbstractMatrix{T} where T, ::Vector{T} where T) at /home/******/.julia/packages/LIBSVM/5Z99T/src/ScikitLearnAPI.jl:100
Stacktrace:
 [1] top-level scope
   @ ~/***/***/***.jl:14
in expression starting at /home/*****/****/****/****.jl:14

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.