Skip to content

Commit

Permalink
Merge branch 'release/0.3.0'
Browse files Browse the repository at this point in the history
  • Loading branch information
paulgoetze committed Feb 10, 2016
2 parents 88b3f58 + 90d7655 commit 1e355bc
Show file tree
Hide file tree
Showing 8 changed files with 158 additions and 687 deletions.
672 changes: 3 additions & 669 deletions README.md

Large diffs are not rendered by default.

14 changes: 7 additions & 7 deletions lib/weka/core/attribute.rb
Original file line number Diff line number Diff line change
Expand Up @@ -11,14 +11,14 @@ def values
# The order of the if statements is important here, because a date is also
# a numeric.
def internal_value_of(value)
if date?
parse_date(value.to_s)
elsif numeric?
value.to_f
elsif nominal?
index_of_value(value.to_s)
end
return value if value === Float::NAN
return Float::NAN if [nil, '?'].include?(value)
return parse_date(value.to_s) if date?
return value.to_f if numeric?
return index_of_value(value.to_s) if nominal?
end
end

Weka::Core::Attribute.__persistent__ = true
end
end
39 changes: 29 additions & 10 deletions lib/weka/core/dense_instance.rb
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,11 @@ class DenseInstance
java_import "java.text.SimpleDateFormat"

def initialize(data, weight: 1.0)
super(weight, data.to_java(:double))
if data.kind_of?(Integer)
super(data)
else
super(weight, to_java_double(data))
end
end

def attributes
Expand All @@ -30,15 +34,7 @@ def each_attribute_with_index

def to_a
to_double_array.each_with_index.map do |value, index|
attribute = attribute_at(index)

if attribute.date?
format_date(value, attribute.date_format)
elsif attribute.numeric?
value
elsif attribute.nominal?
attribute.value(value)
end
value_from(value, index)
end
end

Expand All @@ -47,6 +43,29 @@ def to_a

private

def to_java_double(values)
data = values.map do |value|
['?', nil].include?(value) ? Float::NAN : value
end

data.to_java(:double)
end

def value_from(value, index)
return '?' if value.nan?
return value if dataset.nil?

attribute = attribute_at(index)

if attribute.date?
format_date(value, attribute.date_format)
elsif attribute.numeric?
value
elsif attribute.nominal?
attribute.value(value)
end
end

def attribute_at(index)
return attributes[index] unless dataset.class_attribute_defined?

Expand Down
6 changes: 6 additions & 0 deletions lib/weka/core/instances.rb
Original file line number Diff line number Diff line change
Expand Up @@ -171,6 +171,12 @@ def apply_filters(*filters)
end
end

def merge(*instances)
instances.inject(self) do |merged_instances, dataset|
self.class.merge_instances(merged_instances, dataset)
end
end

private

def add_attribute(attribute)
Expand Down
2 changes: 1 addition & 1 deletion lib/weka/version.rb
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
module Weka
VERSION = "0.2.0"
VERSION = "0.3.0"
end
36 changes: 36 additions & 0 deletions spec/core/attribute_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,18 @@
it 'should return the value as a float if given as string' do
expect(attribute.internal_value_of('3.5')).to eq 3.5
end

it 'should return NaN if the given value is Float::NAN' do
expect(attribute.internal_value_of(Float::NAN)).to be Float::NAN
end

it 'should return NaN if the given value is nil' do
expect(attribute.internal_value_of(nil)).to be Float::NAN
end

it 'should return NaN if the given value is "?"' do
expect(attribute.internal_value_of("?")).to be Float::NAN
end
end

context 'a nominal attribute' do
Expand All @@ -42,6 +54,18 @@
expect(attribute.internal_value_of(:true)).to eq 0
expect(attribute.internal_value_of(:false)).to eq 1
end

it 'should return NaN if the given value is Float::NAN' do
expect(attribute.internal_value_of(Float::NAN)).to be Float::NAN
end

it 'should return NaN if the given value is nil' do
expect(attribute.internal_value_of(nil)).to be Float::NAN
end

it 'should return NaN if the given value is "?"' do
expect(attribute.internal_value_of("?")).to be Float::NAN
end
end

context 'a data attribute' do
Expand All @@ -59,6 +83,18 @@
it 'should return the right date timestamp value' do
expect(attribute.internal_value_of(datetime)).to eq unix_timestamp
end

it 'should return NaN if the given value is Float::NAN' do
expect(attribute.internal_value_of(Float::NAN)).to be Float::NAN
end

it 'should return NaN if the given value is nil' do
expect(attribute.internal_value_of(nil)).to be Float::NAN
end

it 'should return NaN if the given value is "?"' do
expect(attribute.internal_value_of("?")).to be Float::NAN
end
end
end
end
21 changes: 21 additions & 0 deletions spec/core/dense_instance_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,27 @@
end
end

describe 'instantiation' do
describe 'with an Integer value' do
it 'should create a instance with only missing values' do
values = Weka::Core::DenseInstance.new(2).values
expect(values).to eq ['?', '?']
end
end

describe 'with an array' do
it 'should create an instance with the given values' do
values = Weka::Core::DenseInstance.new([1, 2, 3]).values
expect(values).to eq [1, 2, 3]
end

it 'should handle "?" values or nil values' do
values = Weka::Core::DenseInstance.new([1, '?', nil, 4]).values
expect(values).to eq [1, '?', '?', 4]
end
end
end

describe '#to_a' do
let(:values) { ['rainy',50.0, 50.0,'TRUE','no','2015-12-24 11:11'] }

Expand Down
55 changes: 55 additions & 0 deletions spec/core/instances_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@
it { is_expected.to respond_to :add_instance }
it { is_expected.to respond_to :apply_filter }
it { is_expected.to respond_to :apply_filters }
it { is_expected.to respond_to :merge }

it { is_expected.to respond_to :class_attribute= }
it { is_expected.to respond_to :class_attribute }
Expand Down Expand Up @@ -412,6 +413,19 @@

expect(subject.instances.last.to_s).to eq data.to_s
end

it 'should add a given instance with only missing values' do
data = Weka::Core::DenseInstance.new(subject.size)
subject.add_instance(data)
expect(subject.instances.last.to_s).to eq data.to_s
end

it 'should add a given instance with partly missing values' do
data = [:sunny, 70, nil, '?', Float::NAN]
subject.add_instance(data)

expect(subject.instances.last.to_s).to eq 'sunny,70,?,?,?'
end
end

describe '#add_instances' do
Expand Down Expand Up @@ -460,4 +474,45 @@
end
end

describe '#merge' do
let(:attribute_a) { subject.attributes[0] }
let(:attribute_b) { subject.attributes[1] }
let(:attribute_c) { subject.attributes[2] }

let(:instances_a) { Weka::Core::Instances.new(attributes: [attribute_a]) }
let(:instances_b) { Weka::Core::Instances.new(attributes: [attribute_b]) }
let(:instances_c) { Weka::Core::Instances.new(attributes: [attribute_c]) }

context 'when merging one instances object' do
it 'should call .merge_instance of Weka::Core::Instances' do
expect(Weka::Core::Instances)
.to receive(:merge_instances)
.with(instances_a, instances_b)

instances_a.merge(instances_b)
end

it 'should return the result of .merge_instance' do
merged = double('instances')
allow(Weka::Core::Instances).to receive(:merge_instances).and_return(merged)

expect(instances_a.merge(instances_b)).to eq merged
end
end

context 'when merging multiple instances' do
it 'should call .merge_instances mutliple times' do
expect(Weka::Core::Instances).to receive(:merge_instances).twice
instances_a.merge(instances_b, instances_c)
end

it 'should return the merged instances' do
merged = instances_a.merge(instances_b, instances_c)
merged_attributes = [attribute_a, attribute_b, attribute_c]

expect(merged.attributes).to match_array merged_attributes
end
end
end

end

0 comments on commit 1e355bc

Please sign in to comment.