rb-libsvm 1.0.5 → 1.0.6
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/.travis.yml +4 -2
- data/LIBSVM-LICENSE +30 -0
- data/MIT-LICENSE +1 -1
- data/README.md +6 -1
- data/examples/text.rb +53 -0
- data/ext/rb-libsvm/svm.cpp +71 -31
- data/ext/rb-libsvm/svm.h +1 -1
- data/lib/libsvm.rb +1 -43
- data/lib/libsvm/node.rb +40 -0
- data/lib/rb-libsvm/version.rb +1 -1
- data/rb-libsvm.gemspec +1 -0
- data/spec/.usage_spec.rb.swp +0 -0
- data/spec/model_spec.rb +79 -79
- data/spec/node_spec.rb +52 -52
- data/spec/parameter_spec.rb +59 -59
- data/spec/problem_spec.rb +30 -30
- data/spec/spec_helper.rb +1 -1
- data/spec/usage_spec.rb +32 -32
- metadata +17 -7
data/.travis.yml
CHANGED
data/LIBSVM-LICENSE
ADDED
@@ -0,0 +1,30 @@
|
|
1
|
+
Copyright (c) 2000-2012 Chih-Chung Chang and Chih-Jen Lin
|
2
|
+
All rights reserved.
|
3
|
+
|
4
|
+
Redistribution and use in source and binary forms, with or without
|
5
|
+
modification, are permitted provided that the following conditions
|
6
|
+
are met:
|
7
|
+
|
8
|
+
1. Redistributions of source code must retain the above copyright
|
9
|
+
notice, this list of conditions and the following disclaimer.
|
10
|
+
|
11
|
+
2. Redistributions in binary form must reproduce the above copyright
|
12
|
+
notice, this list of conditions and the following disclaimer in the
|
13
|
+
documentation and/or other materials provided with the distribution.
|
14
|
+
|
15
|
+
3. Neither name of copyright holders nor the names of its contributors
|
16
|
+
may be used to endorse or promote products derived from this software
|
17
|
+
without specific prior written permission.
|
18
|
+
|
19
|
+
|
20
|
+
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
21
|
+
``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
22
|
+
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
23
|
+
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR
|
24
|
+
CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
25
|
+
EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
26
|
+
PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
|
27
|
+
PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
|
28
|
+
LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
29
|
+
NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
30
|
+
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
data/MIT-LICENSE
CHANGED
data/README.md
CHANGED
@@ -52,9 +52,14 @@ Currently using libsvm version 3.1
|
|
52
52
|
Written by C. Florian Ebeling. This software can be freely used under
|
53
53
|
the terms of the MIT license, see file MIT-LICENSE.
|
54
54
|
|
55
|
+
This package includes the source of LIBSVM, which is free to use under
|
56
|
+
the license in the file LIBSVM-LICENSE.
|
57
|
+
|
55
58
|
## Contributors
|
56
59
|
|
57
|
-
Rimas Silkaitis
|
60
|
+
[Rimas Silkaitis](https://github.com/neovintage)
|
61
|
+
|
62
|
+
[Aleksander Pohl](https://github.com/apohllo)
|
58
63
|
|
59
64
|
### Posts about SVMs and Ruby
|
60
65
|
|
data/examples/text.rb
ADDED
@@ -0,0 +1,53 @@
|
|
1
|
+
# In this example let's have 3 documents. 2 of the documents
|
2
|
+
# will go into our training set and 1 will be used as our
|
3
|
+
# test set
|
4
|
+
#
|
5
|
+
# Before we can actually classify the documents we need to
|
6
|
+
# create integer representations of each of the documents.
|
7
|
+
# The best way to do this would be to use ruby to accomplish
|
8
|
+
# the task.
|
9
|
+
#
|
10
|
+
require 'libsvm'
|
11
|
+
|
12
|
+
# Let take our documents and create word vectors out of them.
|
13
|
+
# I've included labels for these already. 1 signifies that
|
14
|
+
# the document was funny 0 means that it wasn't
|
15
|
+
#
|
16
|
+
documents = [[1, "Why did the chicken cross the road? Because a car was coming"],
|
17
|
+
[0, "You're an elevator tech? I bet that job has its ups and downs"]]
|
18
|
+
|
19
|
+
# Lets create a dictionary of unique words and then we can
|
20
|
+
# create our vectors. This is a very simple example. If
|
21
|
+
# you were doing this in a production system you'd do things
|
22
|
+
# like stemming and removing all punctuation.
|
23
|
+
#
|
24
|
+
dictionary = documents.map(&:last).flatten.uniq
|
25
|
+
dictionary = dictionary.map { |x| x.gsub(/\?|,|\.|\-/,'') }
|
26
|
+
|
27
|
+
training_set = []
|
28
|
+
docments.each do |doc|
|
29
|
+
training_set << [doc.first, Libsvm::Node.features(dictionary.map { |x| doc.include?(x) ? 1 : 0 })]
|
30
|
+
end
|
31
|
+
|
32
|
+
# Lets set up libsvm so that we can test our prediction
|
33
|
+
# using the test set
|
34
|
+
#
|
35
|
+
problem = Libsvm::Problem.new
|
36
|
+
parameter = Libsvm::SvmParameter.new
|
37
|
+
|
38
|
+
parameter.cache_size = 1 # in megabytes
|
39
|
+
parameter.eps = 0.001
|
40
|
+
parameter.c = 10
|
41
|
+
|
42
|
+
# train classifier using training set
|
43
|
+
#
|
44
|
+
problem.set_examples(training_set.map(&:first), training_set.map(&:last))
|
45
|
+
model = Libsvm::Model.train(problem, parameter)
|
46
|
+
|
47
|
+
# Now lets test our classifier using the test set
|
48
|
+
#
|
49
|
+
test_set = [1, "Why did the chicken cross the road? To get the worm"]
|
50
|
+
test_document = test_set.last.split(' ').map{ |x| x.gsub(/\?|,|\.|\-/,'') }
|
51
|
+
|
52
|
+
pred = model.predict(Libsvm::Node.features(dictionary.map{|x| test_document.include?(x) }))
|
53
|
+
puts "Predicted #{pred}"
|
data/ext/rb-libsvm/svm.cpp
CHANGED
@@ -5,6 +5,8 @@
|
|
5
5
|
#include <float.h>
|
6
6
|
#include <string.h>
|
7
7
|
#include <stdarg.h>
|
8
|
+
#include <limits.h>
|
9
|
+
#include <locale.h>
|
8
10
|
#include "svm.h"
|
9
11
|
int libsvm_version = LIBSVM_VERSION;
|
10
12
|
typedef float Qfloat;
|
@@ -42,7 +44,7 @@ static void print_string_stdout(const char *s)
|
|
42
44
|
fflush(stdout);
|
43
45
|
}
|
44
46
|
static void (*svm_print_string) (const char *) = &print_string_stdout;
|
45
|
-
#if
|
47
|
+
#if 0
|
46
48
|
static void info(const char *fmt,...)
|
47
49
|
{
|
48
50
|
char buf[BUFSIZ];
|
@@ -474,7 +476,7 @@ void Solver::reconstruct_gradient()
|
|
474
476
|
nr_free++;
|
475
477
|
|
476
478
|
if(2*nr_free < active_size)
|
477
|
-
info("\
|
479
|
+
info("\nWARNING: using -h 0 may be faster\n");
|
478
480
|
|
479
481
|
if (nr_free*l > 2*active_size*(l-active_size))
|
480
482
|
{
|
@@ -556,9 +558,10 @@ void Solver::Solve(int l, const QMatrix& Q, const double *p_, const schar *y_,
|
|
556
558
|
// optimization step
|
557
559
|
|
558
560
|
int iter = 0;
|
561
|
+
int max_iter = max(10000000, l>INT_MAX/100 ? INT_MAX : 100*l);
|
559
562
|
int counter = min(l,1000)+1;
|
560
|
-
|
561
|
-
while(
|
563
|
+
|
564
|
+
while(iter < max_iter)
|
562
565
|
{
|
563
566
|
// show progress and do shrinking
|
564
567
|
|
@@ -576,7 +579,7 @@ void Solver::Solve(int l, const QMatrix& Q, const double *p_, const schar *y_,
|
|
576
579
|
reconstruct_gradient();
|
577
580
|
// reset active set size and check
|
578
581
|
active_size = l;
|
579
|
-
|
582
|
+
info("*");
|
580
583
|
if(select_working_set(i,j)!=0)
|
581
584
|
break;
|
582
585
|
else
|
@@ -725,6 +728,18 @@ void Solver::Solve(int l, const QMatrix& Q, const double *p_, const schar *y_,
|
|
725
728
|
}
|
726
729
|
}
|
727
730
|
|
731
|
+
if(iter >= max_iter)
|
732
|
+
{
|
733
|
+
if(active_size < l)
|
734
|
+
{
|
735
|
+
// reconstruct the whole gradient to calculate objective value
|
736
|
+
reconstruct_gradient();
|
737
|
+
active_size = l;
|
738
|
+
info("*");
|
739
|
+
}
|
740
|
+
info("\nWARNING: reaching max number of iterations");
|
741
|
+
}
|
742
|
+
|
728
743
|
// calculate rho
|
729
744
|
|
730
745
|
si->rho = calculate_rho();
|
@@ -756,7 +771,7 @@ void Solver::Solve(int l, const QMatrix& Q, const double *p_, const schar *y_,
|
|
756
771
|
si->upper_bound_p = Cp;
|
757
772
|
si->upper_bound_n = Cn;
|
758
773
|
|
759
|
-
|
774
|
+
info("\noptimization finished, #iter = %d\n",iter);
|
760
775
|
|
761
776
|
delete[] p;
|
762
777
|
delete[] y;
|
@@ -929,7 +944,7 @@ void Solver::do_shrinking()
|
|
929
944
|
unshrink = true;
|
930
945
|
reconstruct_gradient();
|
931
946
|
active_size = l;
|
932
|
-
|
947
|
+
info("*");
|
933
948
|
}
|
934
949
|
|
935
950
|
for(i=0;i<active_size;i++)
|
@@ -1448,7 +1463,7 @@ static void solve_c_svc(
|
|
1448
1463
|
sum_alpha += alpha[i];
|
1449
1464
|
|
1450
1465
|
if (Cp==Cn)
|
1451
|
-
|
1466
|
+
info("nu = %f\n", sum_alpha/(Cp*prob->l));
|
1452
1467
|
|
1453
1468
|
for(i=0;i<l;i++)
|
1454
1469
|
alpha[i] *= y[i];
|
@@ -1498,7 +1513,7 @@ static void solve_nu_svc(
|
|
1498
1513
|
alpha, 1.0, 1.0, param->eps, si, param->shrinking);
|
1499
1514
|
double r = si->r;
|
1500
1515
|
|
1501
|
-
|
1516
|
+
info("C = %f\n",1/r);
|
1502
1517
|
|
1503
1518
|
for(i=0;i<l;i++)
|
1504
1519
|
alpha[i] *= y[i]/r;
|
@@ -1575,7 +1590,7 @@ static void solve_epsilon_svr(
|
|
1575
1590
|
alpha[i] = alpha2[i] - alpha2[i+l];
|
1576
1591
|
sum_alpha += fabs(alpha[i]);
|
1577
1592
|
}
|
1578
|
-
|
1593
|
+
info("nu = %f\n",sum_alpha/(param->C*l));
|
1579
1594
|
|
1580
1595
|
delete[] alpha2;
|
1581
1596
|
delete[] linear_term;
|
@@ -1610,7 +1625,7 @@ static void solve_nu_svr(
|
|
1610
1625
|
s.Solve(2*l, SVR_Q(*prob,*param), linear_term, y,
|
1611
1626
|
alpha2, C, C, param->eps, si, param->shrinking);
|
1612
1627
|
|
1613
|
-
|
1628
|
+
info("epsilon = %f\n",-si->r);
|
1614
1629
|
|
1615
1630
|
for(i=0;i<l;i++)
|
1616
1631
|
alpha[i] = alpha2[i] - alpha2[i+l];
|
@@ -1654,7 +1669,7 @@ static decision_function svm_train_one(
|
|
1654
1669
|
break;
|
1655
1670
|
}
|
1656
1671
|
|
1657
|
-
|
1672
|
+
info("obj = %f, rho = %f\n",si.obj,si.rho);
|
1658
1673
|
|
1659
1674
|
// output SVs
|
1660
1675
|
|
@@ -1678,7 +1693,7 @@ static decision_function svm_train_one(
|
|
1678
1693
|
}
|
1679
1694
|
}
|
1680
1695
|
|
1681
|
-
|
1696
|
+
info("nSV = %d, nBSV = %d\n",nSV,nBSV);
|
1682
1697
|
|
1683
1698
|
decision_function f;
|
1684
1699
|
f.alpha = alpha;
|
@@ -2114,7 +2129,10 @@ svm_model *svm_train(const svm_problem *prob, const svm_parameter *param)
|
|
2114
2129
|
int *perm = Malloc(int,l);
|
2115
2130
|
|
2116
2131
|
// group training data of the same class
|
2117
|
-
svm_group_classes(prob,&nr_class,&label,&start,&count,perm);
|
2132
|
+
svm_group_classes(prob,&nr_class,&label,&start,&count,perm);
|
2133
|
+
if(nr_class == 1)
|
2134
|
+
info("WARNING: training data in only one class. See README for details.\n");
|
2135
|
+
|
2118
2136
|
svm_node **x = Malloc(svm_node *,l);
|
2119
2137
|
int i;
|
2120
2138
|
for(i=0;i<l;i++)
|
@@ -2132,7 +2150,7 @@ svm_model *svm_train(const svm_problem *prob, const svm_parameter *param)
|
|
2132
2150
|
if(param->weight_label[i] == label[j])
|
2133
2151
|
break;
|
2134
2152
|
if(j == nr_class)
|
2135
|
-
fprintf(stderr,"
|
2153
|
+
fprintf(stderr,"WARNING: class label %d specified in weight is not found\n", param->weight_label[i]);
|
2136
2154
|
else
|
2137
2155
|
weighted_C[j] *= param->weight[i];
|
2138
2156
|
}
|
@@ -2232,7 +2250,7 @@ svm_model *svm_train(const svm_problem *prob, const svm_parameter *param)
|
|
2232
2250
|
nz_count[i] = nSV;
|
2233
2251
|
}
|
2234
2252
|
|
2235
|
-
|
2253
|
+
info("Total nSV = %d\n",total_sv);
|
2236
2254
|
|
2237
2255
|
model->l = total_sv;
|
2238
2256
|
model->SV = Malloc(svm_node *,total_sv);
|
@@ -2440,13 +2458,14 @@ double svm_get_svr_probability(const svm_model *model)
|
|
2440
2458
|
|
2441
2459
|
double svm_predict_values(const svm_model *model, const svm_node *x, double* dec_values)
|
2442
2460
|
{
|
2461
|
+
int i;
|
2443
2462
|
if(model->param.svm_type == ONE_CLASS ||
|
2444
2463
|
model->param.svm_type == EPSILON_SVR ||
|
2445
2464
|
model->param.svm_type == NU_SVR)
|
2446
2465
|
{
|
2447
2466
|
double *sv_coef = model->sv_coef[0];
|
2448
2467
|
double sum = 0;
|
2449
|
-
for(
|
2468
|
+
for(i=0;i<model->l;i++)
|
2450
2469
|
sum += sv_coef[i] * Kernel::k_function(x,model->SV[i],model->param);
|
2451
2470
|
sum -= model->rho[0];
|
2452
2471
|
*dec_values = sum;
|
@@ -2458,7 +2477,6 @@ double svm_predict_values(const svm_model *model, const svm_node *x, double* dec
|
|
2458
2477
|
}
|
2459
2478
|
else
|
2460
2479
|
{
|
2461
|
-
int i;
|
2462
2480
|
int nr_class = model->nr_class;
|
2463
2481
|
int l = model->l;
|
2464
2482
|
|
@@ -2583,6 +2601,9 @@ int svm_save_model(const char *model_file_name, const svm_model *model)
|
|
2583
2601
|
FILE *fp = fopen(model_file_name,"w");
|
2584
2602
|
if(fp==NULL) return -1;
|
2585
2603
|
|
2604
|
+
char *old_locale = strdup(setlocale(LC_ALL, NULL));
|
2605
|
+
setlocale(LC_ALL, "C");
|
2606
|
+
|
2586
2607
|
const svm_parameter& param = model->param;
|
2587
2608
|
|
2588
2609
|
fprintf(fp,"svm_type %s\n", svm_type_table[param.svm_type]);
|
@@ -2661,6 +2682,10 @@ int svm_save_model(const char *model_file_name, const svm_model *model)
|
|
2661
2682
|
}
|
2662
2683
|
fprintf(fp, "\n");
|
2663
2684
|
}
|
2685
|
+
|
2686
|
+
setlocale(LC_ALL, old_locale);
|
2687
|
+
free(old_locale);
|
2688
|
+
|
2664
2689
|
if (ferror(fp) != 0 || fclose(fp) != 0) return -1;
|
2665
2690
|
else return 0;
|
2666
2691
|
}
|
@@ -2690,7 +2715,10 @@ svm_model *svm_load_model(const char *model_file_name)
|
|
2690
2715
|
{
|
2691
2716
|
FILE *fp = fopen(model_file_name,"rb");
|
2692
2717
|
if(fp==NULL) return NULL;
|
2693
|
-
|
2718
|
+
|
2719
|
+
char *old_locale = strdup(setlocale(LC_ALL, NULL));
|
2720
|
+
setlocale(LC_ALL, "C");
|
2721
|
+
|
2694
2722
|
// read parameters
|
2695
2723
|
|
2696
2724
|
svm_model *model = Malloc(svm_model,1);
|
@@ -2721,6 +2749,9 @@ svm_model *svm_load_model(const char *model_file_name)
|
|
2721
2749
|
if(svm_type_table[i] == NULL)
|
2722
2750
|
{
|
2723
2751
|
fprintf(stderr,"unknown svm type.\n");
|
2752
|
+
|
2753
|
+
setlocale(LC_ALL, old_locale);
|
2754
|
+
free(old_locale);
|
2724
2755
|
free(model->rho);
|
2725
2756
|
free(model->label);
|
2726
2757
|
free(model->nSV);
|
@@ -2743,6 +2774,9 @@ svm_model *svm_load_model(const char *model_file_name)
|
|
2743
2774
|
if(kernel_type_table[i] == NULL)
|
2744
2775
|
{
|
2745
2776
|
fprintf(stderr,"unknown kernel function.\n");
|
2777
|
+
|
2778
|
+
setlocale(LC_ALL, old_locale);
|
2779
|
+
free(old_locale);
|
2746
2780
|
free(model->rho);
|
2747
2781
|
free(model->label);
|
2748
2782
|
free(model->nSV);
|
@@ -2807,6 +2841,9 @@ svm_model *svm_load_model(const char *model_file_name)
|
|
2807
2841
|
else
|
2808
2842
|
{
|
2809
2843
|
fprintf(stderr,"unknown text in model file: [%s]\n",cmd);
|
2844
|
+
|
2845
|
+
setlocale(LC_ALL, old_locale);
|
2846
|
+
free(old_locale);
|
2810
2847
|
free(model->rho);
|
2811
2848
|
free(model->label);
|
2812
2849
|
free(model->nSV);
|
@@ -2879,6 +2916,9 @@ svm_model *svm_load_model(const char *model_file_name)
|
|
2879
2916
|
}
|
2880
2917
|
free(line);
|
2881
2918
|
|
2919
|
+
setlocale(LC_ALL, old_locale);
|
2920
|
+
free(old_locale);
|
2921
|
+
|
2882
2922
|
if (ferror(fp) != 0 || fclose(fp) != 0)
|
2883
2923
|
return NULL;
|
2884
2924
|
|
@@ -2888,13 +2928,13 @@ svm_model *svm_load_model(const char *model_file_name)
|
|
2888
2928
|
|
2889
2929
|
void svm_free_model_content(svm_model* model_ptr)
|
2890
2930
|
{
|
2891
|
-
|
2892
|
-
|
2893
|
-
|
2894
|
-
|
2895
|
-
|
2896
|
-
|
2897
|
-
|
2931
|
+
if(model_ptr->free_sv && model_ptr->l > 0 && model_ptr->SV != NULL)
|
2932
|
+
free((void *)(model_ptr->SV[0]));
|
2933
|
+
if(model_ptr->sv_coef)
|
2934
|
+
{
|
2935
|
+
for(int i=0;i<model_ptr->nr_class-1;i++)
|
2936
|
+
free(model_ptr->sv_coef[i]);
|
2937
|
+
}
|
2898
2938
|
|
2899
2939
|
free(model_ptr->SV);
|
2900
2940
|
model_ptr->SV = NULL;
|
@@ -2920,12 +2960,12 @@ void svm_free_model_content(svm_model* model_ptr)
|
|
2920
2960
|
|
2921
2961
|
void svm_free_and_destroy_model(svm_model** model_ptr_ptr)
|
2922
2962
|
{
|
2923
|
-
|
2924
|
-
|
2925
|
-
|
2963
|
+
if(model_ptr_ptr != NULL && *model_ptr_ptr != NULL)
|
2964
|
+
{
|
2965
|
+
svm_free_model_content(*model_ptr_ptr);
|
2926
2966
|
free(*model_ptr_ptr);
|
2927
|
-
|
2928
|
-
|
2967
|
+
*model_ptr_ptr = NULL;
|
2968
|
+
}
|
2929
2969
|
}
|
2930
2970
|
|
2931
2971
|
void svm_destroy_param(svm_parameter* param)
|
data/ext/rb-libsvm/svm.h
CHANGED
data/lib/libsvm.rb
CHANGED
@@ -1,8 +1,8 @@
|
|
1
1
|
require 'rb-libsvm/version'
|
2
2
|
require 'rb-libsvm/libsvm'
|
3
|
+
require 'libsvm/node'
|
3
4
|
|
4
5
|
module Libsvm
|
5
|
-
|
6
6
|
module CoreExtensions
|
7
7
|
module Collection
|
8
8
|
def to_example
|
@@ -10,48 +10,6 @@ module Libsvm
|
|
10
10
|
end
|
11
11
|
end
|
12
12
|
end
|
13
|
-
|
14
|
-
class Node
|
15
|
-
|
16
|
-
class << self
|
17
|
-
|
18
|
-
def features(*vargs)
|
19
|
-
array_of_nodes = []
|
20
|
-
if vargs.size == 1
|
21
|
-
if vargs.first.class == Array
|
22
|
-
vargs.first.each_with_index do |value, index|
|
23
|
-
array_of_nodes << Node.new(index.to_i, value.to_f)
|
24
|
-
end
|
25
|
-
elsif vargs.first.class == Hash
|
26
|
-
vargs.first.each do |index, value|
|
27
|
-
array_of_nodes << Node.new(index.to_i, value.to_f)
|
28
|
-
end
|
29
|
-
else
|
30
|
-
raise(ArgumentError.new("Node features need to be a Hash, Array or Floats"))
|
31
|
-
end
|
32
|
-
else
|
33
|
-
vargs.each_with_index do |value, index|
|
34
|
-
array_of_nodes << Node.new(index.to_i, value.to_f)
|
35
|
-
end
|
36
|
-
end
|
37
|
-
array_of_nodes
|
38
|
-
end
|
39
|
-
|
40
|
-
def [](index, value)
|
41
|
-
new(index, value)
|
42
|
-
end
|
43
|
-
end
|
44
|
-
|
45
|
-
def initialize(index=0, value=0.0)
|
46
|
-
self.index = index
|
47
|
-
self.value = value
|
48
|
-
end
|
49
|
-
|
50
|
-
def ==(other)
|
51
|
-
index == other.index && value == other.value
|
52
|
-
end
|
53
|
-
end
|
54
|
-
|
55
13
|
end
|
56
14
|
|
57
15
|
|
data/lib/libsvm/node.rb
ADDED
@@ -0,0 +1,40 @@
|
|
1
|
+
module Libsvm
|
2
|
+
class Node
|
3
|
+
class << self
|
4
|
+
def features(*vargs)
|
5
|
+
array_of_nodes = []
|
6
|
+
if vargs.size == 1
|
7
|
+
if vargs.first.class == Array
|
8
|
+
vargs.first.each_with_index do |value, index|
|
9
|
+
array_of_nodes << Node.new(index.to_i, value.to_f)
|
10
|
+
end
|
11
|
+
elsif vargs.first.class == Hash
|
12
|
+
vargs.first.each do |index, value|
|
13
|
+
array_of_nodes << Node.new(index.to_i, value.to_f)
|
14
|
+
end
|
15
|
+
else
|
16
|
+
raise(ArgumentError.new("Node features need to be a Hash, Array or Floats"))
|
17
|
+
end
|
18
|
+
else
|
19
|
+
vargs.each_with_index do |value, index|
|
20
|
+
array_of_nodes << Node.new(index.to_i, value.to_f)
|
21
|
+
end
|
22
|
+
end
|
23
|
+
array_of_nodes
|
24
|
+
end
|
25
|
+
|
26
|
+
def [](index, value)
|
27
|
+
new(index, value)
|
28
|
+
end
|
29
|
+
end
|
30
|
+
|
31
|
+
def initialize(index=0, value=0.0)
|
32
|
+
self.index = index
|
33
|
+
self.value = value
|
34
|
+
end
|
35
|
+
|
36
|
+
def ==(other)
|
37
|
+
index == other.index && value == other.value
|
38
|
+
end
|
39
|
+
end
|
40
|
+
end
|
data/lib/rb-libsvm/version.rb
CHANGED
data/rb-libsvm.gemspec
CHANGED
@@ -18,6 +18,7 @@ Gem::Specification.new do |s|
|
|
18
18
|
s.executables = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) }
|
19
19
|
s.require_paths = ["lib"]
|
20
20
|
|
21
|
+
|
21
22
|
# specify any dependencies here; for example:
|
22
23
|
s.add_development_dependency('rake-compiler')
|
23
24
|
s.add_development_dependency('rspec', '>= 2.7.0')
|
Binary file
|
data/spec/model_spec.rb
CHANGED
@@ -2,94 +2,94 @@ require "spec_helper"
|
|
2
2
|
|
3
3
|
module ModelSpecHelper
|
4
4
|
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
5
|
+
def create_example
|
6
|
+
Node.features(0.2, 0.3, 0.4, 0.5)
|
7
|
+
end
|
8
|
+
|
9
|
+
def create_problem
|
10
|
+
problem = Problem.new
|
11
|
+
features = [Node.features([0.2,0.3,0.4,0.4]),
|
12
|
+
Node.features([0.1,0.5,0.1,0.9]),
|
13
|
+
Node.features([0.2,0.2,0.6,0.5]),
|
14
|
+
Node.features([0.3,0.1,0.5,0.9])]
|
15
|
+
problem.set_examples([1,2,1,2], features)
|
16
|
+
problem
|
17
|
+
end
|
18
|
+
|
19
|
+
def create_parameter
|
20
|
+
parameter = SvmParameter.new
|
21
|
+
parameter.cache_size = 50 # mb
|
22
|
+
parameter.eps = 0.01
|
23
|
+
parameter.c = 10
|
24
|
+
parameter
|
25
|
+
end
|
26
26
|
|
27
27
|
end
|
28
28
|
|
29
29
|
describe "The Libsvm::Model class interface" do
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
30
|
+
include ModelSpecHelper
|
31
|
+
|
32
|
+
before(:each) do
|
33
|
+
@problem = create_problem
|
34
|
+
@parameter = create_parameter
|
35
|
+
end
|
36
|
+
|
37
|
+
it "results from training on a problem under a certain parameter set" do
|
38
|
+
model = Model.train(@problem,@parameter)
|
39
|
+
model.should_not be_nil
|
40
|
+
end
|
41
|
+
|
42
|
+
it "can do cross-validation" do
|
43
|
+
labels = Model.cross_validation(@problem, @parameter, fold=2)
|
44
|
+
labels.should == [anything, anything, anything, anything]
|
45
|
+
end
|
46
46
|
end
|
47
47
|
|
48
48
|
describe "A saved model" do
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
-
|
49
|
+
include ModelSpecHelper
|
50
|
+
|
51
|
+
before(:each) do
|
52
|
+
@filename = "svm_model.model"
|
53
|
+
model = Model.train(create_problem, create_parameter)
|
54
|
+
model.save(@filename)
|
55
|
+
end
|
56
|
+
|
57
|
+
it "can be loaded" do
|
58
|
+
model = Model.load(@filename)
|
59
|
+
model.should_not be_nil
|
60
|
+
end
|
61
|
+
|
62
|
+
after(:each) do
|
63
|
+
File.delete(@filename) rescue nil
|
64
|
+
end
|
65
65
|
end
|
66
66
|
|
67
67
|
describe "An Libsvm model" do
|
68
|
-
|
69
|
-
|
70
|
-
|
71
|
-
|
72
|
-
|
73
|
-
|
74
|
-
|
75
|
-
|
76
|
-
|
77
|
-
|
78
|
-
|
79
|
-
|
80
|
-
|
81
|
-
|
82
|
-
|
83
|
-
|
84
|
-
|
85
|
-
|
86
|
-
|
87
|
-
|
88
|
-
|
89
|
-
|
90
|
-
|
91
|
-
|
92
|
-
|
93
|
-
|
68
|
+
include ModelSpecHelper
|
69
|
+
|
70
|
+
before(:each) do
|
71
|
+
@problem = create_problem
|
72
|
+
@parameter = create_parameter
|
73
|
+
@model = Model.train(@problem, @parameter)
|
74
|
+
end
|
75
|
+
|
76
|
+
it "can be saved to a file" do
|
77
|
+
file_path = "svm_model.model"
|
78
|
+
@model.save(file_path)
|
79
|
+
File.exist?(file_path).should be_true
|
80
|
+
end
|
81
|
+
|
82
|
+
it "can be asked for it's svm_type" do
|
83
|
+
@model.svm_type.should == SvmType::C_SVC
|
84
|
+
end
|
85
|
+
|
86
|
+
it "can be asked for it's number of classes (aka. labels)" do
|
87
|
+
@model.classes.should == 2
|
88
|
+
end
|
89
|
+
|
90
|
+
it "can predict" do
|
91
|
+
prediction = @model.predict(create_example)
|
92
|
+
prediction.should_not be_nil
|
93
|
+
end
|
94
94
|
end
|
95
95
|
|
data/spec/node_spec.rb
CHANGED
@@ -1,68 +1,68 @@
|
|
1
1
|
require "spec_helper"
|
2
2
|
|
3
3
|
describe "construction of a Node" do
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
4
|
+
it "using the properties" do
|
5
|
+
n = Node.new
|
6
|
+
n.index = 11
|
7
|
+
n.value = 0.11
|
8
|
+
n.index.should == 11
|
9
|
+
n.value.should be_within(0.0001).of(0.11)
|
10
|
+
end
|
11
11
|
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
12
|
+
it "using the :[] method" do
|
13
|
+
n = Node[12, 0.12]
|
14
|
+
n.index.should == 12
|
15
|
+
n.value.should be_within(0.00001).of(0.12)
|
16
|
+
end
|
17
17
|
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
18
|
+
it "using the constructor parameters" do
|
19
|
+
n = Node.new(14, 0.14)
|
20
|
+
n.index.should == 14
|
21
|
+
n.value.should be_within(0.0001).of(0.14)
|
22
|
+
end
|
23
23
|
end
|
24
24
|
|
25
25
|
describe "A Node" do
|
26
|
-
|
27
|
-
|
28
|
-
|
26
|
+
before do
|
27
|
+
@node = Node.new
|
28
|
+
end
|
29
29
|
|
30
|
-
|
31
|
-
|
32
|
-
|
30
|
+
it "can be created" do
|
31
|
+
@node.should_not be_nil
|
32
|
+
end
|
33
33
|
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
34
|
+
it "does not segfault on setting properties" do
|
35
|
+
@node.index = 99
|
36
|
+
@node.index.should == 99
|
37
|
+
@node.value = 3.141
|
38
|
+
@node.value.should be_within(0.00001).of(3.141)
|
39
|
+
end
|
40
40
|
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
41
|
+
it "has inited properties" do
|
42
|
+
@node.index.should == 0
|
43
|
+
@node.value.should be_within(0.00001).of(0)
|
44
|
+
end
|
45
45
|
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
46
|
+
it "class can create nodes from an array" do
|
47
|
+
ary = Node.features([0.1, 0.2, 0.3, 0.4, 0.5])
|
48
|
+
ary.map {|n| n.class.should == Node}
|
49
|
+
ary.map {|n| n.value }.should == [0.1, 0.2, 0.3, 0.4, 0.5]
|
50
|
+
end
|
51
51
|
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
|
52
|
+
it "class can create nodes from variable parameters" do
|
53
|
+
ary = Node.features(0.1, 0.2, 0.3, 0.4, 0.5)
|
54
|
+
ary.map {|n| Node.should === n }
|
55
|
+
ary.map {|n| n.value }.should == [0.1, 0.2, 0.3, 0.4, 0.5]
|
56
|
+
end
|
57
57
|
|
58
|
-
|
59
|
-
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
|
58
|
+
it "class can create nodes from hash" do
|
59
|
+
ary = Node.features(3=>0.3, 5=>0.5, 6=>0.6, 10=>1.0)
|
60
|
+
ary.map {|n| n.class.should == Node}
|
61
|
+
ary.map {|n| n.value }.sort.should == [0.3, 0.5, 0.6, 1.0]
|
62
|
+
ary.map {|n| n.index }.sort.should == [3, 5, 6, 10]
|
63
|
+
end
|
64
64
|
|
65
|
-
|
66
|
-
|
67
|
-
|
65
|
+
it "implements a value-like equality, not identity-notion" do
|
66
|
+
Node[1, 0.1].should == Node[1, 0.1]
|
67
|
+
end
|
68
68
|
end
|
data/spec/parameter_spec.rb
CHANGED
@@ -1,76 +1,76 @@
|
|
1
1
|
require "spec_helper"
|
2
2
|
|
3
3
|
describe "A Parameter has accessors for" do
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
4
|
+
before do
|
5
|
+
@p = Libsvm::SvmParameter.new
|
6
|
+
end
|
7
|
+
it "int svm_type" do
|
8
|
+
SvmType::C_SVC.should == 0
|
9
|
+
@p.svm_type = SvmType::C_SVC
|
10
|
+
@p.svm_type.should == SvmType::C_SVC
|
11
|
+
end
|
12
12
|
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
13
|
+
it "int kernel_type" do
|
14
|
+
KernelType::RBF.should == 2
|
15
|
+
@p.kernel_type = KernelType::RBF
|
16
|
+
@p.kernel_type.should == KernelType::RBF
|
17
|
+
end
|
18
18
|
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
19
|
+
it "int degree" do
|
20
|
+
@p.degree = 99
|
21
|
+
@p.degree.should == 99
|
22
|
+
end
|
23
23
|
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
24
|
+
it "double gamma" do
|
25
|
+
@p.gamma = 0.33
|
26
|
+
@p.gamma.should == 0.33
|
27
|
+
end
|
28
28
|
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
29
|
+
it "double coef0" do
|
30
|
+
@p.coef0 = 0.99
|
31
|
+
@p.coef0.should == 0.99
|
32
|
+
end
|
33
33
|
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
34
|
+
it "double cache_size" do
|
35
|
+
@p.cache_size = 0.77
|
36
|
+
@p.cache_size.should == 0.77
|
37
|
+
end
|
38
38
|
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
39
|
+
it "double eps" do
|
40
|
+
@p.eps = 0.111
|
41
|
+
@p.eps.should == 0.111
|
42
|
+
@p.eps = 0.112
|
43
|
+
@p.eps.should == 0.112
|
44
|
+
end
|
45
45
|
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
46
|
+
it "double C" do
|
47
|
+
@p.c = 3.141
|
48
|
+
@p.c.should == 3.141
|
49
|
+
end
|
50
50
|
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
|
51
|
+
it "can set and read weights (weight, weight_label, nr_weight members from struct)" do
|
52
|
+
@p.label_weights = {1=> 1.2, 3=>0.2, 5=>0.888}
|
53
|
+
@p.label_weights.should == {1=> 1.2, 3=>0.2, 5=>0.888}
|
54
|
+
end
|
55
55
|
|
56
56
|
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
|
57
|
+
it "double nu" do
|
58
|
+
@p.nu = 1.1
|
59
|
+
@p.nu.should == 1.1
|
60
|
+
end
|
61
61
|
|
62
|
-
|
63
|
-
|
64
|
-
|
65
|
-
|
62
|
+
it "double p" do
|
63
|
+
@p.p = 0.123
|
64
|
+
@p.p.should == 0.123
|
65
|
+
end
|
66
66
|
|
67
|
-
|
68
|
-
|
69
|
-
|
70
|
-
|
67
|
+
it "int shrinking" do
|
68
|
+
@p.shrinking = 22
|
69
|
+
@p.shrinking.should == 22
|
70
|
+
end
|
71
71
|
|
72
|
-
|
73
|
-
|
74
|
-
|
75
|
-
|
72
|
+
it "int probability" do
|
73
|
+
@p.probability = 35
|
74
|
+
@p.probability.should == 35
|
75
|
+
end
|
76
76
|
end
|
data/spec/problem_spec.rb
CHANGED
@@ -1,37 +1,37 @@
|
|
1
1
|
require 'spec_helper'
|
2
2
|
|
3
3
|
describe "A Problem" do
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
4
|
+
before(:each) do
|
5
|
+
@problem = Problem.new
|
6
|
+
@features = [ Node.features(0.2,0.3,0.4,0.4),
|
7
|
+
Node.features(0.1,0.5,0.1,0.9),
|
8
|
+
Node.features(0.2,0.2,0.6,0.5),
|
9
|
+
Node.features(0.3,0.1,0.5,0.9) ]
|
10
|
+
end
|
11
11
|
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
12
|
+
it "examples get stored and retrieved" do
|
13
|
+
@problem.set_examples([1,2,1,2], @features)
|
14
|
+
labels, examples = @problem.examples
|
15
|
+
labels.size.should == 4
|
16
|
+
examples.size.should == 4
|
17
|
+
examples.map {|x|x.size}.should == [4,4,4,4]
|
18
|
+
examples.first.map {|node| node.index}.should == [0,1,2,3]
|
19
|
+
examples.first.map {|node| node.value}.should == [0.2,0.3,0.4,0.4]
|
20
|
+
end
|
21
21
|
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
22
|
+
it "can be populated" do
|
23
|
+
examples = [Node.features(0.2,0.3,0.4,0.4),
|
24
|
+
Node.features(0.1,0.5,0.1,0.9),
|
25
|
+
Node.features(0.2,0.2,0.6,0.5),
|
26
|
+
Node.features(0.3,0.1,0.5,0.9)]
|
27
|
+
@problem.set_examples([1,2,1,2], examples)
|
28
|
+
end
|
29
|
+
|
30
|
+
it "can be set twice over" do
|
31
|
+
features = [Node.features(0.2, 0.3, 0.4, 0.4), Node.features(0.3,0.1,0.5,0.9)]
|
32
|
+
@problem.set_examples([1,2], features)
|
33
|
+
features = [Node.features(0.2, 0.3, 0.4, 0.4), Node.features(0.3,0.1,0.5,0.9)]
|
34
|
+
@problem.set_examples([8,2], features)
|
35
|
+
end
|
29
36
|
|
30
|
-
it "can be set twice over" do
|
31
|
-
features = [Node.features(0.2, 0.3, 0.4, 0.4), Node.features(0.3,0.1,0.5,0.9)]
|
32
|
-
@problem.set_examples([1,2], features)
|
33
|
-
features = [Node.features(0.2, 0.3, 0.4, 0.4), Node.features(0.3,0.1,0.5,0.9)]
|
34
|
-
@problem.set_examples([8,2], features)
|
35
|
-
end
|
36
|
-
|
37
37
|
end
|
data/spec/spec_helper.rb
CHANGED
data/spec/usage_spec.rb
CHANGED
@@ -1,47 +1,47 @@
|
|
1
1
|
require 'spec_helper'
|
2
2
|
|
3
3
|
describe "Basic usage" do
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
|
4
|
+
before do
|
5
|
+
@problem = Problem.new
|
6
|
+
@parameter = SvmParameter.new
|
7
|
+
@parameter.cache_size = 1 # mb
|
8
8
|
|
9
|
-
|
10
|
-
|
11
|
-
|
9
|
+
# "eps is the stopping criterion (we usually use 0.00001 in nu-SVC,
|
10
|
+
# 0.001 in others)." (from README)
|
11
|
+
@parameter.eps = 0.001
|
12
12
|
|
13
|
-
|
14
|
-
|
13
|
+
@parameter.c = 10
|
14
|
+
end
|
15
15
|
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
16
|
+
it "has a nice API" do
|
17
|
+
example = {11 => 0.11, 21 => 0.21, 101 => 0.99 }.to_example
|
18
|
+
example.should == Node.features({11 => 0.11, 21 => 0.21, 101 => 0.99 })
|
19
|
+
end
|
20
20
|
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
21
|
+
it "is as in [PCI,217]" do
|
22
|
+
examples = [ [1,0,1], [-1,0,-1] ].map {|ary| Node.features(ary) }
|
23
|
+
labels = [1, -1]
|
24
|
+
@problem.set_examples(labels, examples)
|
25
25
|
|
26
|
-
|
26
|
+
model = Model.train(@problem, @parameter)
|
27
27
|
|
28
|
-
|
29
|
-
|
28
|
+
pred = model.predict(Node.features(1, 1, 1))
|
29
|
+
pred.should == 1.0
|
30
30
|
|
31
|
-
|
32
|
-
|
31
|
+
pred = model.predict(Node.features(-1, 1, -1))
|
32
|
+
pred.should == -1.0
|
33
33
|
|
34
|
-
|
35
|
-
|
36
|
-
|
34
|
+
pred = model.predict(Node.features(-1, 55, -1))
|
35
|
+
pred.should == -1.0
|
36
|
+
end
|
37
37
|
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
38
|
+
it "kernel parameter use" do
|
39
|
+
@parameter.kernel_type = SvmParameter::KernelType::RBF
|
40
|
+
examples = [[1, 2, 3], [-2, -2, -2]].map {|ary| Node.features(ary) }
|
41
|
+
@problem.set_examples([1, 2], examples)
|
42
42
|
|
43
|
-
|
43
|
+
model = Model.train(@problem, @parameter)
|
44
44
|
|
45
|
-
|
46
|
-
|
45
|
+
model.predict(Node.features(1, 2, 3)).should == 2
|
46
|
+
end
|
47
47
|
end
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: rb-libsvm
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.0.
|
4
|
+
version: 1.0.6
|
5
5
|
prerelease:
|
6
6
|
platform: ruby
|
7
7
|
authors:
|
@@ -10,11 +10,11 @@ authors:
|
|
10
10
|
autorequire:
|
11
11
|
bindir: bin
|
12
12
|
cert_chain: []
|
13
|
-
date:
|
13
|
+
date: 2012-05-11 00:00:00.000000000Z
|
14
14
|
dependencies:
|
15
15
|
- !ruby/object:Gem::Dependency
|
16
16
|
name: rake-compiler
|
17
|
-
requirement: &
|
17
|
+
requirement: &70287710299640 !ruby/object:Gem::Requirement
|
18
18
|
none: false
|
19
19
|
requirements:
|
20
20
|
- - ! '>='
|
@@ -22,10 +22,10 @@ dependencies:
|
|
22
22
|
version: '0'
|
23
23
|
type: :development
|
24
24
|
prerelease: false
|
25
|
-
version_requirements: *
|
25
|
+
version_requirements: *70287710299640
|
26
26
|
- !ruby/object:Gem::Dependency
|
27
27
|
name: rspec
|
28
|
-
requirement: &
|
28
|
+
requirement: &70287710298620 !ruby/object:Gem::Requirement
|
29
29
|
none: false
|
30
30
|
requirements:
|
31
31
|
- - ! '>='
|
@@ -33,7 +33,7 @@ dependencies:
|
|
33
33
|
version: 2.7.0
|
34
34
|
type: :development
|
35
35
|
prerelease: false
|
36
|
-
version_requirements: *
|
36
|
+
version_requirements: *70287710298620
|
37
37
|
description: libsvm and ruby without using swig
|
38
38
|
email:
|
39
39
|
- neovintage@gmail.com
|
@@ -46,9 +46,11 @@ files:
|
|
46
46
|
- .rvmrc
|
47
47
|
- .travis.yml
|
48
48
|
- Gemfile
|
49
|
+
- LIBSVM-LICENSE
|
49
50
|
- MIT-LICENSE
|
50
51
|
- README.md
|
51
52
|
- Rakefile
|
53
|
+
- examples/text.rb
|
52
54
|
- examples/toy.rb
|
53
55
|
- ext/rb-libsvm/extconf.rb
|
54
56
|
- ext/rb-libsvm/libsvm.c
|
@@ -57,8 +59,10 @@ files:
|
|
57
59
|
- ext/rb-libsvm/svm.h
|
58
60
|
- ferret_valgrind.supp
|
59
61
|
- lib/libsvm.rb
|
62
|
+
- lib/libsvm/node.rb
|
60
63
|
- lib/rb-libsvm/version.rb
|
61
64
|
- rb-libsvm.gemspec
|
65
|
+
- spec/.usage_spec.rb.swp
|
62
66
|
- spec/model_spec.rb
|
63
67
|
- spec/node_spec.rb
|
64
68
|
- spec/parameter_spec.rb
|
@@ -77,15 +81,21 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
77
81
|
- - ! '>='
|
78
82
|
- !ruby/object:Gem::Version
|
79
83
|
version: '0'
|
84
|
+
segments:
|
85
|
+
- 0
|
86
|
+
hash: 932394419047004720
|
80
87
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
81
88
|
none: false
|
82
89
|
requirements:
|
83
90
|
- - ! '>='
|
84
91
|
- !ruby/object:Gem::Version
|
85
92
|
version: '0'
|
93
|
+
segments:
|
94
|
+
- 0
|
95
|
+
hash: 932394419047004720
|
86
96
|
requirements: []
|
87
97
|
rubyforge_project: rb-libsvm
|
88
|
-
rubygems_version: 1.8.
|
98
|
+
rubygems_version: 1.8.10
|
89
99
|
signing_key:
|
90
100
|
specification_version: 3
|
91
101
|
summary: Ruby language bindings for LIBSVM
|