/
node.rb
111 lines (105 loc) · 3.47 KB
/
node.rb
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
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
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
module Libsvm
# This class represents a feature.
#
# A feature has an index and a value.
#
# An array of features (Libsvm::Node instances) represents an
# example which can be classified, or in greater number can
# constitute the main part of a training set (Libsvm::Prolem).
#
# This class represents the struct
# svm_node[https://github.com/cjlin1/libsvm/blob/master/README#L357].
#
# @see Libsvm::Problem Libsvm::Problem, the training set class
class Node
class << self
# Create an array of features from collection or variable number
# of float values.
#
# Indices are converted to Integer, values are converted to
# Float. When passed a variable number of Float values or an
# array of Floast, the index is implied by the arguments
# position. Collection of tuples of hash arguments afford sparse
# feature arrays. These can represent features which don't have
# consecutive indices starting at zero.
#
# @overload features(0.3, 0.7, 0.8, ...)
# @param vararg variable number of value arguments, or
#
# @overload features([0.3, 0.7, 0.8, ...])
# @param array an array of values, or
#
# @overload features([[0, 0.3], [1, 0.7], [2, 0.8], ...])
# @param array an array of [index, value] tuples, or
#
# @overload features(0 => 0.3, 1 => 0.7, 2 => 0.8, 99 => 0.1)
# @param hash a hash from index to value
#
# @return [Array<Libsvm::Node>] example, i.e. an array of features
def features(*vargs)
array_of_nodes = []
if vargs.size == 1
argument = vargs.first
if argument.class == Array
case argument.first
when Array
argument.each do |pair|
array_of_nodes << Node.new(pair.first.to_i, pair.last.to_f)
end
else
argument.each_with_index do |value, index|
array_of_nodes << Node.new(index.to_i, value.to_f)
end
end
elsif argument.class == Hash
argument.each do |index, value|
array_of_nodes << Node.new(index.to_i, value.to_f)
end
else
raise(ArgumentError.new("Node features need to be a Hash, Array or Floats"))
end
else
vargs.each_with_index do |value, index|
array_of_nodes << Node.new(index.to_i, value.to_f)
end
end
array_of_nodes
end
# Create a feature node.
#
# Libsvm::Node[0, 1.1] # => #<Libsvm::Node: index=0, value=1.1>
#
# @return [Libsvm::Node]
def [](index, value)
new(index, value)
end
end
# @!attribute index
# The index identifies the feature for which this node represents a value.
# @!attribute value
# The value of this feature in this instance.
# Create a new feature node.
#
# Libsvm::Node.new(0, 1.1) # => #<Libsvm::Node: index=0, value=1.1>
def initialize(index=0, value=0.0)
self.index = index
self.value = value
end
# Compare feature node for equality.
#
# Nodes with equal index and value are equal.
#
# @return [Boolean]
def == (other)
other.class == self.class &&
index == other.index &&
value == other.value
end
def inspect
vars = %w(index value).map { |name|
"#{name}=#{send(name)}"
}.join(", ")
"#<#{self.class}: #{vars}>"
end
end
end