Outdated egg!

This is an egg for CHICKEN 4, the unsupported old release. You're almost certainly looking for the CHICKEN 5 version of this egg, if it exists.

If it does not exist, there may be equivalent functionality provided by another egg; have a look at the egg index. Otherwise, please consider porting this egg to the current version of CHICKEN.

libsvm

Support Vector Machines (SVMs) are one of the most important algorithms for machine learning and data mining applications. This egg provides an interface to the widely-used libsvm library. For more information on SVMs, and how to use the functions provided by libsvm, you should read the guide provided by the libsvm authors.

Constants

svm_type
C-SVC NU-SVC ONE-CLASS EPSILON-SVR NU-SVR
kernel_type
LINEAR POLY RBF SIGMOID PRECOMPUTED

Procedures

[procedure] (make-problem definition)

Returns a pointer to an instance of svm_problem, created using the given definition. The definition can be in one of two forms. In both forms, the definition is a list of instances. The instance description is one of:

[procedure] (make-svm-node index value)

Returns a pointer to an instance of svm_node.

[procedure] (make-svm-parameter #!key (svm-type C-SVC) (kernel-type LINEAR) (degree 3) (gamma 0.0) (coef0 0.0) (cache-size 100.0) (eps 0.001) (C 1.0) (nr-weight 0) (nu 0.5) (p 0.1) (shrinking 1) (probability 0))

Returns a pointer to an instance of svm_parameter.

[procedure] (problem-get-instance problem index)

Return a pointer to the data which defines the indexed instance in problem set.

[procedure] (problem-get-instance-values instance)

Return a list of (index value) pairs for the data defining the given instance.

[procedure] (problem-get-label problem index)

Returns the label for the indexed instance in problem set.

[procedure] (problem-num-instances problem)

Returns the number of instances in the given problem.

[procedure] (read-problem filename)

Returns a pointer to an instance of svm_problem for problem read from filename.

[procedure] (svm-check-parameter problem parameter)

Returns #f if parameter set is ok, else a string giving description of error.

[procedure] (svm-check-probability-model model)
[procedure] (svm-destroy model-array)
[procedure] (svm-destroy-param parameter)
[procedure] (svm-free-model-content model)
[procedure] (svm-get-nr-class model)

Returns the number of classes for given model.

[procedure] (svm-get-svm-type model)

Returns the svm-type of the given model.

[procedure] (svm-get-svr-probability model)

Returns the SVR probability from given model.

[procedure] (svm-load-model filename)

Reads model definition from given filename and returns a pointer to the model.

[procedure] (svm-no-print-function)

Turns off printing of information during model training.

[procedure] (svm-predict model svm-node-array)

Returns prediction of model for given svm-node-array.

[procedure] (svm-save-model filename model)

Saves given model to a file called filename. Returns 0 if OK, else 1 if error.

[procedure] (svm-train problem parameter)

Returns a pointer an SVM model trained using given problem and parameter set.

Examples

The following example uses a file from libsvm examples; this example and others can be found in the svn repository for this egg. The program reads in the datafile, constructs a model, and then reports all details of the dataset and performance.

(require-extension format)
(require-extension libsvm)
(require-extension srfi-42)

;; read in a sample dataset in svm-light format
(define problem (read-problem "australian_scale.txt"))

(format #t "Problem has ~d instances~&"
       (problem-num-instances problem))

;; create a model from dataset - uses default parameters
(define svm-model (svm-train problem (make-svm-parameter)))

;; display instances with actual and predicted class
(define *correct* 
  (sum-ec (: i (problem-num-instances problem))
          (begin
            (let ((actual (problem-get-label problem i))
                  (predicted (svm-predict svm-model (problem-get-instance problem i))))
              (format #t "Instance ~d: values ~a, class ~2d, predicted ~f ~a~&"
                      (+ 1 i)
                      (problem-get-instance-values (problem-get-instance problem i))
                      actual
                      predicted
                      (if (= actual predicted) 
                        "Y"
                        ""))
              ;; return a '1' for each correct prediction
              (if (= actual predicted) 1 0)))))

;; display summary of performance
(format #t "Proportion correct: ~4,1f%~&" 
        (/ (* 100 *correct*) (problem-num-instances problem)))

Output:

Problem has 690 instances
.......*......*
optimization finished, #iter = 9453
nu = 0.290834
obj = -199.649812, rho = 1.025147
nSV = 210, nBSV = 193
Total nSV = 210
Instance 1: values ((1 1.0) (2 -0.749474) (3 -0.181429) (5 -0.538462) (6 -0.25) (7 -0.888772) (8 -1.0) (9 -1.0) 
(10 -1.0)  (11 1.0) (13 -0.9) (14 -0.97576)), class -1, predicted -1.0 Y
. . . INFORMATION FOR OTHER INSTANCES . . . 
Instance 690: values ((1 1.0) (2 -0.180451) (3 -0.997143) (5 0.384615) (6 -0.25) (7 -0.997193) (8 -1.0) (9 1.0) 
(10 -0.970149) (11 -1.0) (12 -1.0) (13 -0.44) (14 -1.0)), class  1, predicted -1.0
Proportion correct: 85.7%

The following example shows how to construct a problem set from individual data values:

;;; This program illustrates how to construct a problem set for use in libsvm
;;; Written by Peter Lane, 2010

(require-extension srfi-1)
(require-extension srfi-42)
(require-extension format)
(require-extension libsvm)

(format #t "Classification with LIBSVM~&")
(format #t "--------------------------~&")
 
;; Sample dataset: the 'Play Tennis' dataset 
;; from T. Mitchell, Machine Learning (1997)
;; --------------------------------------------
;; Labels for each instance in the training set
;;    1 = Play, 0 = Not

(define labels '(0 0 1 1 1 0 1 0 1 1 1 1 1 0))

;; Recoding the attribute values into range [0, 1]
(define instances '((0.0 1.0 1.0 0.0)
                    (0.0 1.0 1.0 1.0)
                    (0.5 1.0 1.0 0.0)
                    (1.0 0.5 1.0 0.0)
                    (1.0 0.0 0.0 0.0)
                    (1.0 0.0 0.0 1.0)
                    (0.5 0.0 0.0 1.0)
                    (0.0 0.5 1.0 0.0)
                    (0.0 0.0 0.0 0.0)
                    (1.0 0.5 0.0 0.0)
                    (0.0 0.5 0.0 1.0)
                    (0.5 0.5 1.0 1.0)
                    (0.5 1.0 0.0 0.0)
                    (.0 0.5 1.0 1.0)))

;; create some arbitrary train/test split
(define training-labels (take labels 10))
(define training-instances (take instances 10))
(define test-labels (drop labels 10))
(define test-instances (drop instances 10))

;; pair the instances with their labels in required form for making problem set
(define training-problem 
  (make-problem (map cons training-labels training-instances)))
(define test-problem 
  (make-problem (map cons test-labels test-instances)))

(define (report-results svm-model problem)
  ;; display instances with actual and predicted class
  (define *correct* 
    (sum-ec (: i (problem-num-instances problem))
            (begin
              (let ((actual (problem-get-label problem i))
                    (predicted (svm-predict svm-model (problem-get-instance problem i))))
                (format #t "Instance ~d: values ~a, class ~2d, predicted ~f ~a~&"
                        (+ 1 i)
                        (problem-get-instance-values (problem-get-instance problem i))
                        actual
                        predicted
                        (if (= actual predicted) 
                          "Y"
                          ""))
                ;; return a '1' for each correct prediction
                (if (= actual predicted) 1 0)))))

  ;; display summary of performance
  (format #t "Proportion correct: ~4,1f%~&" 
          (/ (* 100 *correct*) (problem-num-instances problem))))

(for-each ;; train and test a model for each type of kernel
  (lambda (kernel name)
    (let* ((parameters (make-svm-parameter kernel-type: kernel
                                           svm-type: NU-SVC
                                           degree: 1
                                           gamma: 100.0
                                           C: 10))
           (model (svm-train training-problem parameters)))
      (format #t "Kernel: ~a~&" name)
      (format #t "Results on training set~&")
      (report-results model training-problem)
      (format #t "Results on test set~&")
      (report-results model test-problem)))
  (list LINEAR POLY RBF SIGMOID)
  (list "Linear" "Polynomial" "Radial-Basis Function" "Sigmoid"))

Author

Peter Lane.

License

GPL version 3.0.

Requirements

You must have the libsvm library installed. You should download the source code for version 3.0 and use make followed by make lib to construct the shared library. Then, place the shared library and the svm.h header file in the usual include locations so chicken-install can find them (on linux systems, this is /usr/local/lib, /usr/local/include, or /usr/lib, /usr/include).

This library is tested against version 3.0 of libsvm.

Version History