From cc64f674a3e267f5da7ddd08e372ecb1386eb4ad Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Paul=20Go=CC=88tze?= Date: Tue, 21 Jun 2016 01:53:45 +0200 Subject: [PATCH 01/28] Clean up code regarding default Rubocop recommendations --- Rakefile | 10 +++--- bin/console | 8 ++--- .../attribute_selection.rb | 5 ++- lib/weka/class_builder.rb | 10 +++--- lib/weka/classifiers/evaluation.rb | 36 +++++++++---------- lib/weka/classifiers/utils.rb | 3 +- lib/weka/clusterers/cluster_evaluation.rb | 6 ++-- lib/weka/clusterers/utils.rb | 4 +-- lib/weka/concerns/buildable.rb | 2 -- lib/weka/concerns/describable.rb | 1 - lib/weka/concerns/optionizable.rb | 3 +- lib/weka/concerns/persistent.rb | 5 +-- lib/weka/concerns/serializable.rb | 3 +- lib/weka/core/attribute.rb | 3 +- lib/weka/core/dense_instance.rb | 12 +++---- lib/weka/core/instances.rb | 26 +++++++------- lib/weka/core/loader.rb | 1 - lib/weka/core/saver.rb | 1 - lib/weka/core/serialization_helper.rb | 5 ++- lib/weka/filters/filter.rb | 1 - lib/weka/filters/supervised/attribute.rb | 5 ++- lib/weka/filters/utils.rb | 1 - lib/weka/jars.rb | 1 - lib/weka/version.rb | 2 +- .../attribute_selection_spec.rb | 1 - spec/attribute_selection/evaluator_spec.rb | 7 ++-- spec/attribute_selection/search_spec.rb | 1 - spec/attribute_selection_spec.rb | 3 +- spec/class_builder_spec.rb | 7 ++-- spec/classifiers/bayes_spec.rb | 1 - spec/classifiers/evaluation_spec.rb | 3 +- spec/classifiers/functions_spec.rb | 1 - spec/classifiers/lazy_spec.rb | 1 - spec/classifiers/meta_spec.rb | 1 - spec/classifiers/rules_spec.rb | 1 - spec/classifiers/trees_spec.rb | 1 - spec/classifiers/utils_spec.rb | 8 ++--- spec/clusterers/cluster_evaluation_spec.rb | 2 -- spec/clusterers/utils_spec.rb | 34 ++++++++++-------- spec/clusterers_spec.rb | 1 - spec/concerns/buildable_spec.rb | 3 +- spec/concerns/describable_spec.rb | 3 +- spec/concerns/optionizable_spec.rb | 3 +- spec/concerns/persistent_spec.rb | 1 - spec/concerns/serializable_spec.rb | 1 - spec/core/attribute_spec.rb | 17 +++++---- spec/core/converters_spec.rb | 1 - spec/core/dense_instance_spec.rb | 10 +++--- spec/core/instances_spec.rb | 29 +++++++-------- spec/core/loader_spec.rb | 8 ++--- spec/core/saver_spec.rb | 4 +-- spec/core/serialization_helper_spec.rb | 1 - .../supervised/attribute_selection_spec.rb | 1 - spec/filters/supervised/attribute_spec.rb | 1 - spec/filters/supervised/instance_spec.rb | 1 - spec/filters/unsupervised/attribute_spec.rb | 1 - spec/filters/unsupervised/instance_spec.rb | 1 - spec/filters/utils_spec.rb | 1 - spec/support/instances_helpers.rb | 1 - spec/support/shared_examples/class_builder.rb | 1 - weka.gemspec | 4 +-- 61 files changed, 132 insertions(+), 188 deletions(-) diff --git a/Rakefile b/Rakefile index d398b34..fc1b0a9 100644 --- a/Rakefile +++ b/Rakefile @@ -1,10 +1,10 @@ -require "bundler/gem_tasks" -require "rspec/core/rake_task" +require 'bundler/gem_tasks' +require 'rspec/core/rake_task' RSpec::Core::RakeTask.new(:spec) -task :default => :prepare -task :install => :prepare +task default: :prepare +task install: :prepare desc 'Install weka jars & dependencies' task :prepare do @@ -15,7 +15,7 @@ task :prepare do LockJar.install('Jarfile.lock', local_repo: jars_dir) end -desc "Start an irb session with the gem loaded" +desc 'Start an irb session with the gem loaded' task :irb do sh 'irb -I ./lib -r weka' end diff --git a/bin/console b/bin/console index ba6ddc4..5b022bf 100755 --- a/bin/console +++ b/bin/console @@ -1,14 +1,14 @@ #!/usr/bin/env ruby -require "bundler/setup" -require "weka" +require 'bundler/setup' +require 'weka' # You can add fixtures and/or initialization code here to make experimenting # with your gem easier. You can also use a different console, if you like. # (If you use this, don't forget to add pry to your Gemfile!) -# require "pry" +# require 'pry' # Pry.start -require "irb" +require 'irb' IRB.start diff --git a/lib/weka/attribute_selection/attribute_selection.rb b/lib/weka/attribute_selection/attribute_selection.rb index 573c99e..585aab7 100644 --- a/lib/weka/attribute_selection/attribute_selection.rb +++ b/lib/weka/attribute_selection/attribute_selection.rb @@ -3,9 +3,8 @@ module AttributeSelection java_import 'weka.attributeSelection.AttributeSelection' class AttributeSelection - - alias :summary :to_results_string - alias :selected_attributes_count :number_attributes_selected + alias summary to_results_string + alias selected_attributes_count number_attributes_selected end end end diff --git a/lib/weka/class_builder.rb b/lib/weka/class_builder.rb index a912a15..6ccd57d 100644 --- a/lib/weka/class_builder.rb +++ b/lib/weka/class_builder.rb @@ -8,7 +8,6 @@ module ClassBuilder extend ActiveSupport::Concern module ClassMethods - def build_class(class_name, weka_module: nil, include_concerns: true) java_import java_class_path(class_name, weka_module) define_class(class_name, weka_module, include_concerns: include_concerns) @@ -37,7 +36,7 @@ def java_super_modules end def super_modules - toplevel_module? ? self.name : self.name.deconstantize + toplevel_module? ? name : name.deconstantize end def java_including_module @@ -45,11 +44,11 @@ def java_including_module end def including_module - self.name.demodulize unless toplevel_module? + name.demodulize unless toplevel_module? end def toplevel_module? - self.name.scan('::').count == 1 + name.scan('::').count == 1 end def define_class(class_name, weka_module, include_concerns: true) @@ -66,7 +65,7 @@ def include_serializable_for(class_name, weka_module) class_path = java_class_path(class_name, weka_module) serializable = Weka::Core::SerializationHelper.serializable?(class_path) - "include Weka::Concerns::Serializable" if serializable + 'include Weka::Concerns::Serializable' if serializable end def include_utils @@ -91,6 +90,5 @@ def downcase_first_char(string) string[0].downcase + string[1..-1] end end - end end diff --git a/lib/weka/classifiers/evaluation.rb b/lib/weka/classifiers/evaluation.rb index ee0529d..7e8e9c1 100644 --- a/lib/weka/classifiers/evaluation.rb +++ b/lib/weka/classifiers/evaluation.rb @@ -3,35 +3,33 @@ module Classifiers java_import 'weka.classifiers.Evaluation' class Evaluation - # Use both nomenclatures f_measure and fmeasure for consistency # due to jruby's auto method generation of 'fMeasure' to 'f_measure' and # 'weightedFMeasure' to 'weighted_fmeasure'. - alias :weighted_f_measure :weighted_fmeasure - alias :fmeasure :f_measure + alias weighted_f_measure weighted_fmeasure + alias fmeasure f_measure - alias :summary :to_summary_string - alias :class_details :to_class_details_string + alias summary to_summary_string + alias class_details to_class_details_string - alias :instance_count :num_instances - alias :correct_count :correct - alias :incorrect_count :incorrect - alias :unclassified_count :unclassified + alias instance_count num_instances + alias correct_count correct + alias incorrect_count incorrect + alias unclassified_count unclassified - alias :correct_percentage :pct_correct - alias :incorrect_percentage :pct_incorrect - alias :unclassified_percentage :pct_unclassified + alias correct_percentage pct_correct + alias incorrect_percentage pct_incorrect + alias unclassified_percentage pct_unclassified - alias :true_negative_count :num_true_negatives - alias :false_negative_count :num_false_negatives - alias :true_positive_count :num_true_positives - alias :false_positive_count :num_false_positives - alias :average_cost :avg_cost + alias true_negative_count num_true_negatives + alias false_negative_count num_false_negatives + alias true_positive_count num_true_positives + alias false_positive_count num_false_positives + alias average_cost avg_cost - alias :cumulative_margin_distribution :to_cumulative_margin_distribution_string + alias cumulative_margin_distribution to_cumulative_margin_distribution_string end Java::WekaClassifiers::Evaluation.__persistent__ = true - end end diff --git a/lib/weka/classifiers/utils.rb b/lib/weka/classifiers/utils.rb index c0e845d..e375ae9 100644 --- a/lib/weka/classifiers/utils.rb +++ b/lib/weka/classifiers/utils.rb @@ -63,7 +63,7 @@ def add_training_instance(instance) end def add_training_data(data) - values = self.training_instances.internal_values_of(data) + values = training_instances.internal_values_of(data) instance = Weka::Core::DenseInstance.new(values) add_training_instance(instance) end @@ -132,7 +132,6 @@ def class_distributions_from(distributions) end end end - end end end diff --git a/lib/weka/clusterers/cluster_evaluation.rb b/lib/weka/clusterers/cluster_evaluation.rb index e4837b5..83320ff 100644 --- a/lib/weka/clusterers/cluster_evaluation.rb +++ b/lib/weka/clusterers/cluster_evaluation.rb @@ -3,12 +3,10 @@ module Clusterers java_import 'weka.clusterers.ClusterEvaluation' class ClusterEvaluation - - alias :summary :cluster_results_to_string - alias :clusters_count :num_clusters + alias summary cluster_results_to_string + alias clusters_count num_clusters end Java::WekaClusterers::ClusterEvaluation.__persistent__ = true - end end diff --git a/lib/weka/clusterers/utils.rb b/lib/weka/clusterers/utils.rb index 8f1bcb8..55a7694 100644 --- a/lib/weka/clusterers/utils.rb +++ b/lib/weka/clusterers/utils.rb @@ -61,7 +61,7 @@ def add_training_instance(instance) end def add_training_data(data) - values = self.training_instances.internal_values_of(data) + values = training_instances.internal_values_of(data) instance = Weka::Core::DenseInstance.new(values) add_training_instance(instance) end @@ -96,8 +96,6 @@ def clusterable_instance_from(instance_or_values) instances.first end end - end end end - diff --git a/lib/weka/concerns/buildable.rb b/lib/weka/concerns/buildable.rb index 6eaa6f1..de1a88a 100644 --- a/lib/weka/concerns/buildable.rb +++ b/lib/weka/concerns/buildable.rb @@ -6,14 +6,12 @@ module Buildable extend ActiveSupport::Concern module ClassMethods - def build(&block) instance = new instance.instance_eval(&block) if block_given? instance end end - end end end diff --git a/lib/weka/concerns/describable.rb b/lib/weka/concerns/describable.rb index 58c09ac..1d77892 100644 --- a/lib/weka/concerns/describable.rb +++ b/lib/weka/concerns/describable.rb @@ -6,7 +6,6 @@ module Describable extend ActiveSupport::Concern module ClassMethods - def description new.global_info end diff --git a/lib/weka/concerns/optionizable.rb b/lib/weka/concerns/optionizable.rb index ee7d911..5850369 100644 --- a/lib/weka/concerns/optionizable.rb +++ b/lib/weka/concerns/optionizable.rb @@ -6,7 +6,7 @@ module Optionizable extend ActiveSupport::Concern included do - java_import "weka.core.Utils" + java_import 'weka.core.Utils' def use_options(*single_options, **hash_options) joined_options = join_options(single_options, hash_options) @@ -43,7 +43,6 @@ def default_options new.get_options.to_a.join(' ') end end - end end end diff --git a/lib/weka/concerns/persistent.rb b/lib/weka/concerns/persistent.rb index 387f3c6..2066bd9 100644 --- a/lib/weka/concerns/persistent.rb +++ b/lib/weka/concerns/persistent.rb @@ -6,11 +6,8 @@ module Persistent extend ActiveSupport::Concern included do - if self.respond_to?(:__persistent__=) - self.__persistent__ = true - end + self.__persistent__ = true if respond_to?(:__persistent__=) end - end end end diff --git a/lib/weka/concerns/serializable.rb b/lib/weka/concerns/serializable.rb index 1fe11c2..629857d 100644 --- a/lib/weka/concerns/serializable.rb +++ b/lib/weka/concerns/serializable.rb @@ -11,7 +11,6 @@ def serialize(filename) Weka::Core::SerializationHelper.write(filename, self) end end - end end -end \ No newline at end of file +end diff --git a/lib/weka/core/attribute.rb b/lib/weka/core/attribute.rb index 28b7daa..2f6e383 100644 --- a/lib/weka/core/attribute.rb +++ b/lib/weka/core/attribute.rb @@ -1,9 +1,8 @@ module Weka module Core - java_import "weka.core.Attribute" + java_import 'weka.core.Attribute' class Attribute - def values enumerate_values.to_a end diff --git a/lib/weka/core/dense_instance.rb b/lib/weka/core/dense_instance.rb index d06360c..8d9d6ad 100644 --- a/lib/weka/core/dense_instance.rb +++ b/lib/weka/core/dense_instance.rb @@ -1,13 +1,13 @@ module Weka module Core - java_import "weka.core.DenseInstance" + java_import 'weka.core.DenseInstance' class DenseInstance - java_import "java.util.Date" - java_import "java.text.SimpleDateFormat" + java_import 'java.util.Date' + java_import 'java.text.SimpleDateFormat' def initialize(data, weight: 1.0) - if data.kind_of?(Integer) + if data.is_a?(Integer) super(data) else super(weight, to_java_double(data)) @@ -38,8 +38,8 @@ def to_a end end - alias :values :to_a - alias :values_count :num_values + alias values to_a + alias values_count num_values private diff --git a/lib/weka/core/instances.rb b/lib/weka/core/instances.rb index 5ab45b0..cd25a67 100644 --- a/lib/weka/core/instances.rb +++ b/lib/weka/core/instances.rb @@ -6,13 +6,13 @@ module Weka module Core - java_import "weka.core.Instances" - java_import "weka.core.FastVector" + java_import 'weka.core.Instances' + java_import 'weka.core.FastVector' class Instances include Weka::Concerns::Serializable - DEFAULT_RELATION_NAME = 'Instances' + DEFAULT_RELATION_NAME = 'Instances'.freeze class << self def from_arff(file) @@ -48,13 +48,13 @@ def attribute_names end def add_attributes(&block) - self.instance_eval(&block) if block + instance_eval(&block) if block self end - alias :with_attributes :add_attributes - alias :instances_count :num_instances - alias :attributes_count :num_attributes + alias with_attributes add_attributes + alias instances_count num_instances + alias attributes_count num_attributes def each if block_given? @@ -129,10 +129,10 @@ def class_attribute=(name) end end - alias :add_numeric_attribute :numeric - alias :add_string_attribute :string - alias :add_nominal_attribute :nominal - alias :add_date_attribute :date + alias add_numeric_attribute numeric + alias add_string_attribute string + alias add_nominal_attribute nominal + alias add_date_attribute date def class_attribute classAttribute if class_attribute_defined? @@ -187,7 +187,7 @@ def ensure_attribute_defined!(name) return if attribute_names.include?(name.to_s) error = "\"#{name}\" is not defined." - hint = "Only defined attributes can be used as class attribute!" + hint = 'Only defined attributes can be used as class attribute!' message = "#{error} #{hint}" raise ArgumentError, message @@ -198,7 +198,7 @@ def attribute_with_name(name) end def instance_from(instance_or_values, weight:) - if instance_or_values.kind_of?(Java::WekaCore::Instance) + if instance_or_values.is_a?(Java::WekaCore::Instance) instance_or_values.weight = weight instance_or_values else diff --git a/lib/weka/core/loader.rb b/lib/weka/core/loader.rb index f9d6579..4e1dd4c 100644 --- a/lib/weka/core/loader.rb +++ b/lib/weka/core/loader.rb @@ -27,6 +27,5 @@ def load_with(loader_class, file:) end end end - end end diff --git a/lib/weka/core/saver.rb b/lib/weka/core/saver.rb index d4c4696..9936397 100644 --- a/lib/weka/core/saver.rb +++ b/lib/weka/core/saver.rb @@ -29,6 +29,5 @@ def save_with(saver_class, file:, instances:) end end end - end end diff --git a/lib/weka/core/serialization_helper.rb b/lib/weka/core/serialization_helper.rb index 8fb6f5f..91e6ccd 100644 --- a/lib/weka/core/serialization_helper.rb +++ b/lib/weka/core/serialization_helper.rb @@ -3,10 +3,9 @@ module Core java_import 'weka.core.SerializationHelper' class SerializationHelper - class << self - alias :deserialize :read - alias :serialize :write + alias deserialize read + alias serialize write end end end diff --git a/lib/weka/filters/filter.rb b/lib/weka/filters/filter.rb index 250924e..488b8d6 100644 --- a/lib/weka/filters/filter.rb +++ b/lib/weka/filters/filter.rb @@ -4,6 +4,5 @@ module Filters class Filter end - end end diff --git a/lib/weka/filters/supervised/attribute.rb b/lib/weka/filters/supervised/attribute.rb index 4608504..5560dbd 100644 --- a/lib/weka/filters/supervised/attribute.rb +++ b/lib/weka/filters/supervised/attribute.rb @@ -16,10 +16,9 @@ module Attribute :PartitionMembership class AttributeSelection - alias :use_evaluator :set_evaluator - alias :use_search :set_search + alias use_evaluator set_evaluator + alias use_search set_search end - end end end diff --git a/lib/weka/filters/utils.rb b/lib/weka/filters/utils.rb index a01474a..bf3852e 100644 --- a/lib/weka/filters/utils.rb +++ b/lib/weka/filters/utils.rb @@ -11,7 +11,6 @@ def filter(instances) Filter.use_filter(instances, self) end end - end end end diff --git a/lib/weka/jars.rb b/lib/weka/jars.rb index 12e557c..1f4e774 100644 --- a/lib/weka/jars.rb +++ b/lib/weka/jars.rb @@ -14,6 +14,5 @@ module Jars LockJar.install(lockfile, local_repo: jars_dir) LockJar.load(lockfile, local_repo: jars_dir) end - end end diff --git a/lib/weka/version.rb b/lib/weka/version.rb index 159eb8a..13b997f 100644 --- a/lib/weka/version.rb +++ b/lib/weka/version.rb @@ -1,3 +1,3 @@ module Weka - VERSION = "0.3.0" + VERSION = '0.3.0'.freeze end diff --git a/spec/attribute_selection/attribute_selection_spec.rb b/spec/attribute_selection/attribute_selection_spec.rb index 014b730..bb3ee9c 100644 --- a/spec/attribute_selection/attribute_selection_spec.rb +++ b/spec/attribute_selection/attribute_selection_spec.rb @@ -1,7 +1,6 @@ require 'spec_helper' describe Weka::AttributeSelection::AttributeSelection do - describe 'aliases:' do { to_results_string: :summary, diff --git a/spec/attribute_selection/evaluator_spec.rb b/spec/attribute_selection/evaluator_spec.rb index 9c74a69..432cdb4 100644 --- a/spec/attribute_selection/evaluator_spec.rb +++ b/spec/attribute_selection/evaluator_spec.rb @@ -1,7 +1,6 @@ require 'spec_helper' describe Weka::AttributeSelection::Evaluator do - subject { described_class } it_behaves_like 'class builder' @@ -28,7 +27,7 @@ end end - it "should define a class PrincipalComponents" do - expect(subject.const_defined?(:PrincipalComponents)).to be true - end + it 'should define a class PrincipalComponents' do + expect(subject.const_defined?(:PrincipalComponents)).to be true + end end diff --git a/spec/attribute_selection/search_spec.rb b/spec/attribute_selection/search_spec.rb index 5d32fae..0aa0634 100644 --- a/spec/attribute_selection/search_spec.rb +++ b/spec/attribute_selection/search_spec.rb @@ -1,7 +1,6 @@ require 'spec_helper' describe Weka::AttributeSelection::Search do - subject { described_class } it_behaves_like 'class builder' diff --git a/spec/attribute_selection_spec.rb b/spec/attribute_selection_spec.rb index b9d1fc0..b146899 100644 --- a/spec/attribute_selection_spec.rb +++ b/spec/attribute_selection_spec.rb @@ -1,8 +1,7 @@ require 'spec_helper' describe Weka::AttributeSelection do - - it "should define a class AttributeSelection" do + it 'should define a class AttributeSelection' do expect(described_class.const_defined?(:AttributeSelection)).to be true end end diff --git a/spec/class_builder_spec.rb b/spec/class_builder_spec.rb index 8b28f74..0215411 100644 --- a/spec/class_builder_spec.rb +++ b/spec/class_builder_spec.rb @@ -1,7 +1,6 @@ require 'spec_helper' describe Weka::ClassBuilder do - subject do module Some module Weka @@ -14,7 +13,7 @@ module Module end end - let(:class_name){ :SomeClass } + let(:class_name) { :SomeClass } before { allow(subject).to receive(:java_import).and_return('') } @@ -124,7 +123,7 @@ module Module describe '.build_classes' do context 'without a given weka_module' do it 'should run .build_class for each of the given classes' do - class_names = %i{ SomeClass SomeOtherClass } + class_names = %i(SomeClass SomeOtherClass) expect(subject).to receive(:build_class).exactly(class_names.count).times subject.build_classes(*class_names) @@ -133,7 +132,7 @@ module Module context 'with a given weka_module' do it 'should run .build_class for each of the given classes' do - class_names = %i{ SomeClass SomeOtherClass } + class_names = %i(SomeClass SomeOtherClass) expect(subject).to receive(:build_class).exactly(class_names.count).times subject.build_classes(*class_names, weka_module: 'weka.module') diff --git a/spec/classifiers/bayes_spec.rb b/spec/classifiers/bayes_spec.rb index 5489f06..ab50064 100644 --- a/spec/classifiers/bayes_spec.rb +++ b/spec/classifiers/bayes_spec.rb @@ -1,7 +1,6 @@ require 'spec_helper' describe Weka::Classifiers::Bayes do - it_behaves_like 'class builder' [ diff --git a/spec/classifiers/evaluation_spec.rb b/spec/classifiers/evaluation_spec.rb index a54cfed..0e94c26 100644 --- a/spec/classifiers/evaluation_spec.rb +++ b/spec/classifiers/evaluation_spec.rb @@ -1,7 +1,6 @@ require 'spec_helper' describe Weka::Classifiers::Evaluation do - subject do instances = load_instances('weather.arff') instances.class_attribute = :play @@ -28,7 +27,7 @@ unclassified_count: :unclassified, unclassified_percentage: :pct_unclassified, weighted_f_measure: :weighted_fmeasure, - cumulative_margin_distribution: :toCumulativeMarginDistributionString, + cumulative_margin_distribution: :toCumulativeMarginDistributionString }.each do |alias_method, method| it "should define the alias ##{alias_method} for ##{method}" do expect(subject.method(method)).to eq subject.method(alias_method) diff --git a/spec/classifiers/functions_spec.rb b/spec/classifiers/functions_spec.rb index 28cc3bc..08ac615 100644 --- a/spec/classifiers/functions_spec.rb +++ b/spec/classifiers/functions_spec.rb @@ -1,7 +1,6 @@ require 'spec_helper' describe Weka::Classifiers::Functions do - it_behaves_like 'class builder' [ diff --git a/spec/classifiers/lazy_spec.rb b/spec/classifiers/lazy_spec.rb index b10fc5d..24d5832 100644 --- a/spec/classifiers/lazy_spec.rb +++ b/spec/classifiers/lazy_spec.rb @@ -1,7 +1,6 @@ require 'spec_helper' describe Weka::Classifiers::Lazy do - it_behaves_like 'class builder' [ diff --git a/spec/classifiers/meta_spec.rb b/spec/classifiers/meta_spec.rb index 00b8bf3..d5a20ac 100644 --- a/spec/classifiers/meta_spec.rb +++ b/spec/classifiers/meta_spec.rb @@ -1,7 +1,6 @@ require 'spec_helper' describe Weka::Classifiers::Meta do - it_behaves_like 'class builder' [ diff --git a/spec/classifiers/rules_spec.rb b/spec/classifiers/rules_spec.rb index 1c9e92d..2482a77 100644 --- a/spec/classifiers/rules_spec.rb +++ b/spec/classifiers/rules_spec.rb @@ -1,7 +1,6 @@ require 'spec_helper' describe Weka::Classifiers::Rules do - it_behaves_like 'class builder' [ diff --git a/spec/classifiers/trees_spec.rb b/spec/classifiers/trees_spec.rb index 3020eab..6d1e3a0 100644 --- a/spec/classifiers/trees_spec.rb +++ b/spec/classifiers/trees_spec.rb @@ -1,7 +1,6 @@ require 'spec_helper' describe Weka::Classifiers::Trees do - it_behaves_like 'class builder' [ diff --git a/spec/classifiers/utils_spec.rb b/spec/classifiers/utils_spec.rb index 067a2fe..70713ee 100644 --- a/spec/classifiers/utils_spec.rb +++ b/spec/classifiers/utils_spec.rb @@ -1,7 +1,6 @@ require 'spec_helper' describe Weka::Classifiers::Utils do - let(:including_class) do Class.new do def build_classifier(instances) @@ -82,7 +81,7 @@ def distribution_for_instance end it 'should return itself' do - expect(subject.add_training_instance(instance)).to be_kind_of subject.class + expect(subject.add_training_instance(instance)).to be_a subject.class end end @@ -274,7 +273,9 @@ def distribution_for_instance let(:class_distributions) { { 'yes' => distributions[0], 'no' => distributions[1] } } before do - allow(subject).to receive(:distribution_for_instance).and_return(distributions) + allow(subject) + .to receive(:distribution_for_instance) + .and_return(distributions) end context 'with a given instance' do @@ -314,5 +315,4 @@ def distribution_for_instance end end end - end diff --git a/spec/clusterers/cluster_evaluation_spec.rb b/spec/clusterers/cluster_evaluation_spec.rb index 06280c8..e6aecc9 100644 --- a/spec/clusterers/cluster_evaluation_spec.rb +++ b/spec/clusterers/cluster_evaluation_spec.rb @@ -1,7 +1,6 @@ require 'spec_helper' describe Weka::Clusterers::ClusterEvaluation do - it { is_expected.to be_kind_of(Java::WekaClusterers::ClusterEvaluation) } describe 'aliases:' do @@ -14,5 +13,4 @@ end end end - end diff --git a/spec/clusterers/utils_spec.rb b/spec/clusterers/utils_spec.rb index 0e07b91..d8c4a89 100644 --- a/spec/clusterers/utils_spec.rb +++ b/spec/clusterers/utils_spec.rb @@ -1,7 +1,6 @@ require 'spec_helper' describe Weka::Clusterers::Utils do - let(:including_class) do Class.new do def build_clusterer(instances) @@ -66,11 +65,10 @@ def distribution_for_instance end it 'should return itself' do - expect(subject.add_training_instance(instance)).to be_kind_of subject.class + expect(subject.add_training_instance(instance)).to be_a subject.class end end - describe '#add_training_data' do let(:values) { [:sunny, 85, 85, :FALSE, :no] } @@ -88,7 +86,7 @@ def distribution_for_instance end it 'should return itself' do - expect(subject.add_training_data(values)).to be_kind_of subject.class + expect(subject.add_training_data(values)).to be_a subject.class end end @@ -136,7 +134,9 @@ def build_clusterer(instances) end it 'should run Java‘s #cross_validate_model on a ClusterEvaluation' do - expect(Weka::Clusterers::ClusterEvaluation).to receive(:cross_validate_model).once + expect(Weka::Clusterers::ClusterEvaluation) + .to receive(:cross_validate_model).once + subject.cross_validate end @@ -184,7 +184,9 @@ def build_clusterer(instances) end context 'without training instances' do - before { allow(subject).to receive(:training_instances).and_return(nil) } + before do + allow(subject).to receive(:training_instances).and_return(nil) + end it 'should raise an UnassignedTrainingInstancesError' do expect { subject.cross_validate } @@ -197,7 +199,8 @@ def build_clusterer(instances) describe '#evaluate' do before do allow(subject).to receive(:training_instances).and_return(instances) - allow_any_instance_of(Weka::Clusterers::ClusterEvaluation).to receive(:evaluate_clusterer) + allow_any_instance_of(Weka::Clusterers::ClusterEvaluation) + .to receive(:evaluate_clusterer) end it 'should return a Weka::Clusterers::ClusterEvaluation' do @@ -224,9 +227,9 @@ def build_clusterer(instances) end describe '#cluster' do - let(:instance) { instances.first } - let(:values) { [:overcast, 83, 86, :FALSE, :yes] } - let(:cluster) { 1 } + let(:instance) { instances.first } + let(:values) { [:overcast, 83, 86, :FALSE, :yes] } + let(:cluster) { 1 } before do allow(subject).to receive(:cluster_instance).and_return(cluster) @@ -271,12 +274,14 @@ def build_clusterer(instances) end describe '#distribution_for' do - let(:instance) { instances.first } - let(:values) { [:overcast, 83, 86, :FALSE, :yes] } - let(:distributions) { [0.543684388757196, 0.4563156112428039] } + let(:instance) { instances.first } + let(:values) { [:overcast, 83, 86, :FALSE, :yes] } + let(:distributions) { [0.543684388757196, 0.4563156112428039] } before do - allow(subject).to receive(:distribution_for_instance).and_return(distributions) + allow(subject) + .to receive(:distribution_for_instance) + .and_return(distributions) end context 'with a given instance' do @@ -316,5 +321,4 @@ def build_clusterer(instances) end end end - end diff --git a/spec/clusterers_spec.rb b/spec/clusterers_spec.rb index f44d79c..2c51879 100644 --- a/spec/clusterers_spec.rb +++ b/spec/clusterers_spec.rb @@ -1,7 +1,6 @@ require 'spec_helper' describe Weka::Clusterers do - it_behaves_like 'class builder' [ diff --git a/spec/concerns/buildable_spec.rb b/spec/concerns/buildable_spec.rb index adf97a1..84ce492 100644 --- a/spec/concerns/buildable_spec.rb +++ b/spec/concerns/buildable_spec.rb @@ -1,7 +1,6 @@ require 'spec_helper' describe Weka::Concerns::Buildable do - subject do Class.new { include Weka::Concerns::Buildable } end @@ -21,7 +20,7 @@ subject.build { a_public_method } end - it "should return an instance of the including class" do + it 'should return an instance of the including class' do instance = subject.build { a_public_method } expect(instance).to be_kind_of subject end diff --git a/spec/concerns/describable_spec.rb b/spec/concerns/describable_spec.rb index 5f0d837..06fde6c 100644 --- a/spec/concerns/describable_spec.rb +++ b/spec/concerns/describable_spec.rb @@ -1,7 +1,6 @@ require 'spec_helper' describe Weka::Concerns::Describable do - subject do Class.new { include Weka::Concerns::Describable } end @@ -31,7 +30,7 @@ end it 'should return a string' do - expect(subject.options).to be_kind_of String + expect(subject.options).to be_a String end end end diff --git a/spec/concerns/optionizable_spec.rb b/spec/concerns/optionizable_spec.rb index 7554dcf..bca2ef4 100644 --- a/spec/concerns/optionizable_spec.rb +++ b/spec/concerns/optionizable_spec.rb @@ -1,7 +1,6 @@ require 'spec_helper' describe Weka::Concerns::Optionizable do - subject do Class.new { include Weka::Concerns::Optionizable }.new end @@ -104,7 +103,7 @@ before do allow_any_instance_of(subject.class) .to receive(:get_options) - .and_return(['-C', 'last', '-Z', '-P', '10', '-M', '-B', '0.1']) + .and_return(%w(-C last -Z -P 10 -M -B 0.1)) end it 'should receive Java‘s #get_options' do diff --git a/spec/concerns/persistent_spec.rb b/spec/concerns/persistent_spec.rb index 94a3b08..7b93694 100644 --- a/spec/concerns/persistent_spec.rb +++ b/spec/concerns/persistent_spec.rb @@ -1,7 +1,6 @@ require 'spec_helper' describe Weka::Concerns::Persistent do - describe 'if included' do subject { Class.new } diff --git a/spec/concerns/serializable_spec.rb b/spec/concerns/serializable_spec.rb index d8bb8ad..aca31c3 100644 --- a/spec/concerns/serializable_spec.rb +++ b/spec/concerns/serializable_spec.rb @@ -1,7 +1,6 @@ require 'spec_helper' describe Weka::Concerns::Serializable do - subject do Class.new { include Weka::Concerns::Serializable } end diff --git a/spec/core/attribute_spec.rb b/spec/core/attribute_spec.rb index fe60c0f..bb25d82 100644 --- a/spec/core/attribute_spec.rb +++ b/spec/core/attribute_spec.rb @@ -1,8 +1,7 @@ require 'spec_helper' describe Weka::Core::Attribute do - - let(:values) { ['yes', 'no'] } + let(:values) { %w(yes no) } subject { Weka::Core::Attribute.new('class', values) } it { is_expected.to respond_to :values } @@ -19,7 +18,7 @@ let(:attribute) { Weka::Core::Attribute.new('numeric attribute') } it 'should return the value as a float' do - expect(attribute.internal_value_of(3.5)).to eq 3.5 + expect(attribute.internal_value_of(3.5)).to eq 3.5 end it 'should return the value as a float if given as string' do @@ -35,12 +34,12 @@ end it 'should return NaN if the given value is "?"' do - expect(attribute.internal_value_of("?")).to be Float::NAN + expect(attribute.internal_value_of('?')).to be Float::NAN end end context 'a nominal attribute' do - let(:attribute) { Weka::Core::Attribute.new('class', ['true', 'false']) } + let(:attribute) { Weka::Core::Attribute.new('class', %w(true false)) } it 'should return the correct internal index' do expect(attribute.internal_value_of('true')).to eq 0 @@ -64,14 +63,14 @@ end it 'should return NaN if the given value is "?"' do - expect(attribute.internal_value_of("?")).to be Float::NAN + expect(attribute.internal_value_of('?')).to be Float::NAN end end context 'a data attribute' do let(:attribute) { Weka::Core::Attribute.new('date', 'yyyy-MM-dd HH:mm') } let(:datetime) { '2015-12-24 11:11' } - let(:unix_timestamp) { 1450955460000.0 } + let(:unix_timestamp) { 1_450_955_460_000.0 } before do allow(attribute) @@ -93,8 +92,8 @@ end it 'should return NaN if the given value is "?"' do - expect(attribute.internal_value_of("?")).to be Float::NAN + expect(attribute.internal_value_of('?')).to be Float::NAN end end end -end \ No newline at end of file +end diff --git a/spec/core/converters_spec.rb b/spec/core/converters_spec.rb index 53427b2..83d25fa 100644 --- a/spec/core/converters_spec.rb +++ b/spec/core/converters_spec.rb @@ -1,7 +1,6 @@ require 'spec_helper' describe Weka::Core::Converters do - it_behaves_like 'class builder' [ diff --git a/spec/core/dense_instance_spec.rb b/spec/core/dense_instance_spec.rb index d381abc..8318767 100644 --- a/spec/core/dense_instance_spec.rb +++ b/spec/core/dense_instance_spec.rb @@ -1,11 +1,10 @@ require 'spec_helper' describe Weka::Core::DenseInstance do - subject do instances = load_instances('weather.arff') instances.add_date_attribute('recorded_at') - instances.add_instance(['rainy',50, 50,'TRUE','no','2015-12-24 11:11']) + instances.add_instance(['rainy', 50, 50, 'TRUE', 'no', '2015-12-24 11:11']) instances.instances.last end @@ -47,7 +46,7 @@ end describe '#to_a' do - let(:values) { ['rainy',50.0, 50.0,'TRUE','no','2015-12-24 11:11'] } + let(:values) { ['rainy', 50.0, 50.0, 'TRUE', 'no', '2015-12-24 11:11'] } it 'should return an Array with the values of the instance' do expect(subject.to_a).to eq values @@ -74,7 +73,7 @@ expect(attributes).to be_an Array all_kind_of_attribute = attributes.reduce(true) do |result, attribute| - result &&= attribute.kind_of?(Java::WekaCore::Attribute) + result && attribute.is_a?(Java::WekaCore::Attribute) end expect(all_kind_of_attribute).to be true @@ -118,5 +117,4 @@ end end end - -end \ No newline at end of file +end diff --git a/spec/core/instances_spec.rb b/spec/core/instances_spec.rb index bbcdb96..6d0083c 100644 --- a/spec/core/instances_spec.rb +++ b/spec/core/instances_spec.rb @@ -2,7 +2,6 @@ require 'fileutils' describe Weka::Core::Instances do - subject { load_instances('weather.arff') } it { is_expected.to respond_to :each } @@ -35,7 +34,7 @@ it { is_expected.to respond_to :serialize } describe 'aliases:' do - let (:instances) { described_class.new } + let(:instances) { described_class.new } { numeric: :add_numeric_attribute, @@ -94,7 +93,7 @@ expect(objects).to be_an Array all_kind_of_instance = objects.reduce(true) do |result, object| - result &&= object.kind_of?(Java::WekaCore::DenseInstance) + result && object.is_a?(Java::WekaCore::DenseInstance) end expect(all_kind_of_instance).to be true @@ -107,7 +106,7 @@ expect(objects).to be_an Array all_kind_of_attribute = objects.reduce(true) do |result, object| - result &&= object.kind_of?(Java::WekaCore::Attribute) + result && object.is_a?(Java::WekaCore::Attribute) end expect(all_kind_of_attribute).to be true @@ -116,7 +115,7 @@ describe '#attribute_names' do it 'should return an Array of the attribute names' do - names = %w{ outlook temperature humidity windy play } + names = %w(outlook temperature humidity windy play) expect(subject.attribute_names).to eq names end end @@ -148,13 +147,13 @@ describe '#nominal' do it 'can be used to add a nominal attribute' do - instances.nominal(name, values: ['yes', 'no']) + instances.nominal(name, values: %w(yes no)) expect(instances.attributes.first).to be_nominal end context 'with the class_attribute option' do it 'should define the attribute as class attribute' do - instances.nominal(name, values: ['yes', 'no'], class_attribute: true) + instances.nominal(name, values: %w(yes no), class_attribute: true) expect(instances.class_attribute.name).to eq name end end @@ -202,7 +201,7 @@ it 'should convert the options into strings' do instances.nominal(:attribute_name, values: [true, false]) - expect(instances.attributes.first.values).to eq ['true', 'false'] + expect(instances.attributes.first.values).to eq %w(true false) end end @@ -290,7 +289,7 @@ expect { instances.add_attributes do numeric 'attribute' - nominal 'class', values: ['YES', 'NO'] + nominal 'class', values: %w(YES NO) end }.to change { instances.attributes.count }.from(0).to(2) end @@ -300,16 +299,16 @@ instances.add_attributes do numeric 'attribute' - nominal 'class', values: ['YES', 'NO'] + nominal 'class', values: %w(YES NO) end - expect(instances.attributes.map(&:name)).to eq ['attribute', 'class'] + expect(instances.attributes.map(&:name)).to eq %w(attribute class) end end describe '#initialize' do it 'should take a relation_name as argument' do - name = 'name' + name = 'name' instances = Weka::Core::Instances.new(relation_name: name) expect(instances.relation_name).to eq name @@ -494,7 +493,10 @@ it 'should return the result of .merge_instance' do merged = double('instances') - allow(Weka::Core::Instances).to receive(:merge_instances).and_return(merged) + + allow(Weka::Core::Instances) + .to receive(:merge_instances) + .and_return(merged) expect(instances_a.merge(instances_b)).to eq merged end @@ -514,5 +516,4 @@ end end end - end diff --git a/spec/core/loader_spec.rb b/spec/core/loader_spec.rb index a6ffd64..dc77974 100644 --- a/spec/core/loader_spec.rb +++ b/spec/core/loader_spec.rb @@ -1,8 +1,7 @@ require 'spec_helper' describe Weka::Core::Loader do - - CLASS_METHODS = %i{ load_arff load_csv load_json } + CLASS_METHODS = %i(load_arff load_csv load_json).freeze CLASS_METHODS.each do |method| it "responds to .#{method}" do @@ -14,7 +13,9 @@ method = "load_#{type}" describe "##{method}" do - let(:file) { File.expand_path("../../support/resources/weather.#{type}", __FILE__) } + let(:file) do + File.expand_path("../../support/resources/weather.#{type}", __FILE__) + end it "returns an Instances object for a given #{type.upcase} file" do instances = described_class.send(method, file) @@ -22,5 +23,4 @@ end end end - end diff --git a/spec/core/saver_spec.rb b/spec/core/saver_spec.rb index 3fac735..f6cd056 100644 --- a/spec/core/saver_spec.rb +++ b/spec/core/saver_spec.rb @@ -1,13 +1,12 @@ require 'spec_helper' describe Weka::Core::Saver do - let(:instances) { load_instances('weather.arff') } before(:all) { @tmp_dir = File.expand_path('../../tmp/', __FILE__) } after(:all) { FileUtils.remove_dir(@tmp_dir, true) } - CLASS_METHODS = %i{ save_arff save_csv save_json } + CLASS_METHODS = %i(save_arff save_csv save_json).freeze CLASS_METHODS.each do |method| it "responds to .#{method}" do @@ -28,5 +27,4 @@ end end end - end diff --git a/spec/core/serialization_helper_spec.rb b/spec/core/serialization_helper_spec.rb index dcbaddc..a312afa 100644 --- a/spec/core/serialization_helper_spec.rb +++ b/spec/core/serialization_helper_spec.rb @@ -1,7 +1,6 @@ require 'spec_helper' describe Weka::Core::SerializationHelper do - it { is_expected.to be_kind_of Java::WekaCore::SerializationHelper } describe 'aliases:' do diff --git a/spec/filters/supervised/attribute_selection_spec.rb b/spec/filters/supervised/attribute_selection_spec.rb index 48c75c1..84629c9 100644 --- a/spec/filters/supervised/attribute_selection_spec.rb +++ b/spec/filters/supervised/attribute_selection_spec.rb @@ -1,7 +1,6 @@ require 'spec_helper' describe Weka::Filters::Supervised::Attribute::AttributeSelection do - describe 'aliases:' do { set_evaluator: :use_evaluator, diff --git a/spec/filters/supervised/attribute_spec.rb b/spec/filters/supervised/attribute_spec.rb index d00caa9..c556f09 100644 --- a/spec/filters/supervised/attribute_spec.rb +++ b/spec/filters/supervised/attribute_spec.rb @@ -1,7 +1,6 @@ require 'spec_helper' describe Weka::Filters::Supervised::Attribute do - it_behaves_like 'class builder' [ diff --git a/spec/filters/supervised/instance_spec.rb b/spec/filters/supervised/instance_spec.rb index d686a1e..f2f4fab 100644 --- a/spec/filters/supervised/instance_spec.rb +++ b/spec/filters/supervised/instance_spec.rb @@ -1,7 +1,6 @@ require 'spec_helper' describe Weka::Filters::Supervised::Instance do - it_behaves_like 'class builder' [ diff --git a/spec/filters/unsupervised/attribute_spec.rb b/spec/filters/unsupervised/attribute_spec.rb index 8c57a6e..ef1b905 100644 --- a/spec/filters/unsupervised/attribute_spec.rb +++ b/spec/filters/unsupervised/attribute_spec.rb @@ -1,7 +1,6 @@ require 'spec_helper' describe Weka::Filters::Unsupervised::Attribute do - it_behaves_like 'class builder' [ diff --git a/spec/filters/unsupervised/instance_spec.rb b/spec/filters/unsupervised/instance_spec.rb index d83d06a..05348a6 100644 --- a/spec/filters/unsupervised/instance_spec.rb +++ b/spec/filters/unsupervised/instance_spec.rb @@ -1,7 +1,6 @@ require 'spec_helper' describe Weka::Filters::Unsupervised::Instance do - it_behaves_like 'class builder' [ diff --git a/spec/filters/utils_spec.rb b/spec/filters/utils_spec.rb index fc22172..7e28beb 100644 --- a/spec/filters/utils_spec.rb +++ b/spec/filters/utils_spec.rb @@ -1,7 +1,6 @@ require 'spec_helper' describe Weka::Filters::Utils do - subject do Class.new { include Weka::Filters::Utils }.new end diff --git a/spec/support/instances_helpers.rb b/spec/support/instances_helpers.rb index 59374d6..6abec79 100644 --- a/spec/support/instances_helpers.rb +++ b/spec/support/instances_helpers.rb @@ -1,5 +1,4 @@ module InstancesHelpers - def load_instances(file_name) file = File.expand_path("./../resources/#{file_name}", __FILE__) Weka::Core::Loader.send("load_#{File.extname(file_name)[1..-1]}", file) diff --git a/spec/support/shared_examples/class_builder.rb b/spec/support/shared_examples/class_builder.rb index f485596..6b9f57a 100644 --- a/spec/support/shared_examples/class_builder.rb +++ b/spec/support/shared_examples/class_builder.rb @@ -1,5 +1,4 @@ shared_examples 'class builder' do - subject { described_class } it { is_expected.to respond_to :build_class } diff --git a/weka.gemspec b/weka.gemspec index 334453a..f8c10a3 100644 --- a/weka.gemspec +++ b/weka.gemspec @@ -9,8 +9,8 @@ Gem::Specification.new do |spec| spec.authors = ['Paul Götze'] spec.email = ['paul.christoph.goetze@gmail.com'] - spec.summary = %q{Machine Learning & Data Mining with JRuby.} - spec.description = %q{A JRuby wrapper for the Weka library (http://www.cs.waikato.ac.nz/ml/weka/)} + spec.summary = 'Machine Learning & Data Mining with JRuby.' + spec.description = 'A JRuby wrapper for the Weka library (http://www.cs.waikato.ac.nz/ml/weka/)' spec.homepage = 'https://github.com/paulgoetze/weka-jruby' spec.license = 'MIT' From 729e37448fd8df3b0c1d29ed6032b82a21702357 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Paul=20Go=CC=88tze?= Date: Tue, 21 Jun 2016 02:08:59 +0200 Subject: [PATCH 02/28] Remove should from spec descriptions and fix apostrophes --- README.md | 4 +- .../attribute_selection_spec.rb | 2 +- spec/attribute_selection/evaluator_spec.rb | 6 +- spec/attribute_selection/search_spec.rb | 2 +- spec/attribute_selection_spec.rb | 2 +- spec/class_builder_spec.rb | 22 ++--- spec/classifiers/bayes_spec.rb | 2 +- spec/classifiers/evaluation_spec.rb | 2 +- spec/classifiers/functions_spec.rb | 2 +- spec/classifiers/lazy_spec.rb | 2 +- spec/classifiers/meta_spec.rb | 2 +- spec/classifiers/rules_spec.rb | 2 +- spec/classifiers/trees_spec.rb | 2 +- spec/classifiers/utils_spec.rb | 58 ++++++------ spec/clusterers/cluster_evaluation_spec.rb | 2 +- spec/clusterers/utils_spec.rb | 54 +++++------ spec/clusterers_spec.rb | 2 +- spec/concerns/buildable_spec.rb | 8 +- spec/concerns/describable_spec.rb | 6 +- spec/concerns/optionizable_spec.rb | 20 ++-- spec/concerns/persistent_spec.rb | 2 +- spec/concerns/serializable_spec.rb | 4 +- spec/core/attribute_spec.rb | 30 +++--- spec/core/converters_spec.rb | 2 +- spec/core/dense_instance_spec.rb | 22 ++--- spec/core/instances_spec.rb | 93 +++++++++---------- spec/core/serialization_helper_spec.rb | 2 +- .../supervised/attribute_selection_spec.rb | 2 +- spec/filters/supervised/attribute_spec.rb | 2 +- spec/filters/supervised/instance_spec.rb | 2 +- spec/filters/unsupervised/attribute_spec.rb | 2 +- spec/filters/unsupervised/instance_spec.rb | 2 +- spec/filters/utils_spec.rb | 4 +- 33 files changed, 185 insertions(+), 186 deletions(-) diff --git a/README.md b/README.md index f2a5261..f17f344 100644 --- a/README.md +++ b/README.md @@ -33,7 +33,7 @@ The weka gem tries to carry over the namespaces defined in Weka and enhances som The idea behind keeping the namespaces is, that you can also use the [Weka documentation](http://weka.sourceforge.net/doc.dev/) for looking up functionality and classes. -Please refer to [the gem‘s Wiki](https://github.com/paulgoetze/weka-jruby/wiki) for +Please refer to [the gem’s Wiki](https://github.com/paulgoetze/weka-jruby/wiki) for detailed information about how to use weka with JRuby and some examplary code snippets. ## Development @@ -49,7 +49,7 @@ Bug reports and pull requests are welcome on GitHub at https://github.com/paulgo For development we use the [git branching model](http://nvie.com/posts/a-successful-git-branching-model/) described by [nvie](https://github.com/nvie). -Here's how to contribute: +Here’s how to contribute: 1. Fork it ( https://github.com/paulgoetze/weka-jruby/fork ) 2. Create your feature branch (`git checkout -b feature/my-new-feature develop`) diff --git a/spec/attribute_selection/attribute_selection_spec.rb b/spec/attribute_selection/attribute_selection_spec.rb index bb3ee9c..79ff0ed 100644 --- a/spec/attribute_selection/attribute_selection_spec.rb +++ b/spec/attribute_selection/attribute_selection_spec.rb @@ -6,7 +6,7 @@ to_results_string: :summary, number_attributes_selected: :selected_attributes_count }.each do |method, alias_method| - it "should define the alias ##{alias_method} for ##{method}" do + it "defines the alias ##{alias_method} for ##{method}" do expect(subject.method(method)).to eq subject.method(alias_method) end end diff --git a/spec/attribute_selection/evaluator_spec.rb b/spec/attribute_selection/evaluator_spec.rb index 432cdb4..af8580d 100644 --- a/spec/attribute_selection/evaluator_spec.rb +++ b/spec/attribute_selection/evaluator_spec.rb @@ -15,11 +15,11 @@ :SymmetricalUncertAttribute => :SymmetricalUncertAttributeEval, :WrapperSubset => :WrapperSubsetEval }.each do |class_name, super_class_name| - it "should define a class #{class_name}" do + it "defines a class #{class_name}" do expect(subject.const_defined?(class_name)).to be true end - it "should inherit class #{class_name} from #{super_class_name}" do + it "inherits class #{class_name} from #{super_class_name}" do evaluator_class = "#{subject}::#{class_name}".constantize super_class = "#{subject}::#{super_class_name}".constantize @@ -27,7 +27,7 @@ end end - it 'should define a class PrincipalComponents' do + it 'defines a class PrincipalComponents' do expect(subject.const_defined?(:PrincipalComponents)).to be true end end diff --git a/spec/attribute_selection/search_spec.rb b/spec/attribute_selection/search_spec.rb index 0aa0634..008816a 100644 --- a/spec/attribute_selection/search_spec.rb +++ b/spec/attribute_selection/search_spec.rb @@ -10,7 +10,7 @@ :Ranker, :BestFirst ].each do |class_name| - it "should define a class #{class_name}" do + it "defines a class #{class_name}" do expect(subject.const_defined?(class_name)).to be true end end diff --git a/spec/attribute_selection_spec.rb b/spec/attribute_selection_spec.rb index b146899..6f3d2c6 100644 --- a/spec/attribute_selection_spec.rb +++ b/spec/attribute_selection_spec.rb @@ -1,7 +1,7 @@ require 'spec_helper' describe Weka::AttributeSelection do - it 'should define a class AttributeSelection' do + it 'defines a class AttributeSelection' do expect(described_class.const_defined?(:AttributeSelection)).to be true end end diff --git a/spec/class_builder_spec.rb b/spec/class_builder_spec.rb index 0215411..833d814 100644 --- a/spec/class_builder_spec.rb +++ b/spec/class_builder_spec.rb @@ -18,13 +18,13 @@ module Module before { allow(subject).to receive(:java_import).and_return('') } [:build_class, :build_classes].each do |method| - it "should define .#{method} if included" do + it "defines .#{method} if included" do expect(subject).to respond_to method end end describe '.build_class' do - it 'should run java_import with the right resolved class path' do + it 'runs java_import with the right resolved class path' do class_path = "some.weka.customCamelCased.module.#{class_name}" expect(subject).to receive(:java_import).once.with(class_path) @@ -36,7 +36,7 @@ module Module describe 'built class including Describable functionality' do Weka::Concerns::Describable::ClassMethods.instance_methods.each do |method| - it "should respond to .#{method}" do + it "responds to .#{method}" do expect(built_class).to respond_to method end end @@ -44,7 +44,7 @@ module Module describe 'built class including Buildable functionality' do Weka::Concerns::Buildable::ClassMethods.instance_methods.each do |method| - it "should respond to .#{method}" do + it "responds to .#{method}" do expect(built_class).to respond_to method end end @@ -53,12 +53,12 @@ module Module describe 'built class including Optionizable functionality' do let(:built_class_instance) { built_class.new } - it 'should respond to .default_options' do + it 'responds to .default_options' do expect(built_class).to respond_to :default_options end [:use_options, :options].each do |method| - it "should respond to ##{method}" do + it "responds to ##{method}" do expect(built_class_instance).to respond_to method end end @@ -77,7 +77,7 @@ def shared_method end end - it 'should include them in the defined class' do + it 'includes them in the defined class' do built_class = subject.build_class(class_name) expect(built_class.public_method_defined?(:shared_method)).to be true end @@ -102,7 +102,7 @@ module Module .and_return(subject.module_eval("class #{class_name}; end")) end - it 'should not include extra methods in the defined class' do + it 'does not include extra methods in the defined class' do built_class = subject.build_class(class_name) expect(built_class.public_method_defined?(:shared_method)).to be false end @@ -111,7 +111,7 @@ module Module context 'with a defined Weka module' do let(:weka_module) { 'explicitly.defined.module' } - it 'should import the given classes from the defined module' do + it 'imports the given classes from the defined module' do class_path = "#{weka_module}.#{class_name}" expect(subject).to receive(:java_import).once.with(class_path) @@ -122,7 +122,7 @@ module Module describe '.build_classes' do context 'without a given weka_module' do - it 'should run .build_class for each of the given classes' do + it 'runs .build_class for each of the given classes' do class_names = %i(SomeClass SomeOtherClass) expect(subject).to receive(:build_class).exactly(class_names.count).times @@ -131,7 +131,7 @@ module Module end context 'with a given weka_module' do - it 'should run .build_class for each of the given classes' do + it 'runs .build_class for each of the given classes' do class_names = %i(SomeClass SomeOtherClass) expect(subject).to receive(:build_class).exactly(class_names.count).times diff --git a/spec/classifiers/bayes_spec.rb b/spec/classifiers/bayes_spec.rb index ab50064..1279424 100644 --- a/spec/classifiers/bayes_spec.rb +++ b/spec/classifiers/bayes_spec.rb @@ -11,7 +11,7 @@ :NaiveBayesMultinomialUpdateable, :NaiveBayesUpdateable ].each do |class_name| - it "should define a class #{class_name}" do + it "defines a class #{class_name}" do expect(described_class.const_defined?(class_name)).to be true end end diff --git a/spec/classifiers/evaluation_spec.rb b/spec/classifiers/evaluation_spec.rb index 0e94c26..2bb9f54 100644 --- a/spec/classifiers/evaluation_spec.rb +++ b/spec/classifiers/evaluation_spec.rb @@ -29,7 +29,7 @@ weighted_f_measure: :weighted_fmeasure, cumulative_margin_distribution: :toCumulativeMarginDistributionString }.each do |alias_method, method| - it "should define the alias ##{alias_method} for ##{method}" do + it "defines the alias ##{alias_method} for ##{method}" do expect(subject.method(method)).to eq subject.method(alias_method) end end diff --git a/spec/classifiers/functions_spec.rb b/spec/classifiers/functions_spec.rb index 08ac615..234f17a 100644 --- a/spec/classifiers/functions_spec.rb +++ b/spec/classifiers/functions_spec.rb @@ -16,7 +16,7 @@ :SMOreg, :VotedPerceptron ].each do |class_name| - it "should define a class #{class_name}" do + it "defines a class #{class_name}" do expect(described_class.const_defined?(class_name)).to be true end end diff --git a/spec/classifiers/lazy_spec.rb b/spec/classifiers/lazy_spec.rb index 24d5832..c2b7383 100644 --- a/spec/classifiers/lazy_spec.rb +++ b/spec/classifiers/lazy_spec.rb @@ -8,7 +8,7 @@ :KStar, :LWL ].each do |class_name| - it "should defines a class #{class_name}" do + it "definess a class #{class_name}" do expect(described_class.const_defined?(class_name)).to be true end end diff --git a/spec/classifiers/meta_spec.rb b/spec/classifiers/meta_spec.rb index d5a20ac..4c09994 100644 --- a/spec/classifiers/meta_spec.rb +++ b/spec/classifiers/meta_spec.rb @@ -24,7 +24,7 @@ :Stacking, :Vote ].each do |class_name| - it "should define a class #{class_name}" do + it "defines a class #{class_name}" do expect(described_class.const_defined?(class_name)).to be true end end diff --git a/spec/classifiers/rules_spec.rb b/spec/classifiers/rules_spec.rb index 2482a77..038b2a8 100644 --- a/spec/classifiers/rules_spec.rb +++ b/spec/classifiers/rules_spec.rb @@ -11,7 +11,7 @@ :PART, :ZeroR ].each do |class_name| - it "should define a class #{class_name}" do + it "defines a class #{class_name}" do expect(described_class.const_defined?(class_name)).to be true end end diff --git a/spec/classifiers/trees_spec.rb b/spec/classifiers/trees_spec.rb index 6d1e3a0..9b0b006 100644 --- a/spec/classifiers/trees_spec.rb +++ b/spec/classifiers/trees_spec.rb @@ -13,7 +13,7 @@ :RandomTree, :REPTree ].each do |class_name| - it "should define a class #{class_name}" do + it "defines a class #{class_name}" do expect(described_class.const_defined?(class_name)).to be true end end diff --git a/spec/classifiers/utils_spec.rb b/spec/classifiers/utils_spec.rb index 70713ee..ec8d896 100644 --- a/spec/classifiers/utils_spec.rb +++ b/spec/classifiers/utils_spec.rb @@ -35,24 +35,24 @@ def distribution_for_instance it { is_expected.to respond_to :classify } describe '#train_with_instances' do - it 'should call Java‘s #build_classifier' do + it 'calls Java’s #build_classifier' do expect(subject).to receive(:build_classifier).once.with(instances) subject.train_with_instances(instances) end - it 'should set the training_instances' do + it 'sets the training_instances' do subject = including_class.new expect(subject.training_instances).to be_nil subject.train_with_instances(instances) expect(subject.training_instances).to eq instances end - it 'should return itself' do + it 'returns itself' do expect(subject.train_with_instances(instances)).to be subject end context 'without an assigned class attribute on instances' do - it 'should raise an UnassignedClassError' do + it 'raises an UnassignedClassError' do instances = load_instances('weather.arff') expect { including_class.new.train_with_instances(instances) } @@ -69,18 +69,18 @@ def distribution_for_instance subject.train_with_instances(instances) end - it 'should call Java‘s #update_classifier' do + it 'calls Java’s #update_classifier' do expect(subject).to receive(:update_classifier).once.with(instance) subject.add_training_instance(instance) end - it 'should add the instance to training_instances' do + it 'adds the instance to training_instances' do expect { subject.add_training_instance(instance) } .to change { subject.training_instances.count } .by(1) end - it 'should return itself' do + it 'returns itself' do expect(subject.add_training_instance(instance)).to be_a subject.class end end @@ -93,7 +93,7 @@ def distribution_for_instance subject.train_with_instances(instances) end - it 'should call #add_training_instance' do + it 'calls #add_training_instance' do expect(subject) .to receive(:add_training_instance).once .with(an_instance_of(Weka::Core::DenseInstance)) @@ -101,7 +101,7 @@ def distribution_for_instance subject.add_training_data(values) end - it 'should return itself' do + it 'returns itself' do expect(subject.add_training_data(values)).to be_kind_of subject.class end end @@ -115,19 +115,19 @@ def distribution_for_instance .to receive(:cross_validate_model) end - it 'should return a Weka::Classifiers::Evaluation' do + it 'returns a Weka::Classifiers::Evaluation' do return_value = subject.cross_validate expect(return_value).to be_kind_of Weka::Classifiers::Evaluation end - it 'should run Java‘s #cross_validate_model on an Evaluation' do + it 'runs Java’s #cross_validate_model on an Evaluation' do expect_any_instance_of(Weka::Classifiers::Evaluation) .to receive(:cross_validate_model).once subject.cross_validate end - it 'should use 3 folds and the training instances as default test instances' do + it 'uses 3 folds and the training instances as default test instances' do expect_any_instance_of(Weka::Classifiers::Evaluation) .to receive(:cross_validate_model).once .with( @@ -143,7 +143,7 @@ def distribution_for_instance context 'with given folds' do let(:folds) { default_folds + 1 } - it 'should use the given number of folds' do + it 'uses the given number of folds' do expect_any_instance_of(Weka::Classifiers::Evaluation) .to receive(:cross_validate_model).once .with( @@ -156,7 +156,7 @@ def distribution_for_instance subject.cross_validate(folds: folds) end - it 'should use the folds as an integer value' do + it 'uses the folds as an integer value' do expect_any_instance_of(Weka::Classifiers::Evaluation) .to receive(:cross_validate_model).once .with( @@ -173,7 +173,7 @@ def distribution_for_instance context 'without training instances' do before { allow(subject).to receive(:training_instances).and_return(nil) } - it 'should raise an UnassignedTrainingInstancesError' do + it 'raises an UnassignedTrainingInstancesError' do expect { subject.cross_validate } .to raise_error Weka::UnassignedTrainingInstancesError end @@ -186,12 +186,12 @@ def distribution_for_instance allow_any_instance_of(Weka::Classifiers::Evaluation).to receive(:evaluate_model) end - it 'should return a Weka::Classifiers::Evaluation' do + it 'returns a Weka::Classifiers::Evaluation' do return_value = subject.evaluate(instances) expect(return_value).to be_kind_of Weka::Classifiers::Evaluation end - it 'should run Java‘s #evaluate_model on an Evaluation' do + it 'runs Java’s #evaluate_model on an Evaluation' do expect_any_instance_of(Weka::Classifiers::Evaluation) .to receive(:evaluate_model).once .with(subject, instances) @@ -200,7 +200,7 @@ def distribution_for_instance end context 'without an assigned class attribute on test instances' do - it 'should raise an UnassignedClassError' do + it 'raises an UnassignedClassError' do instances = load_instances('weather.arff') expect { subject.evaluate(instances) } @@ -211,7 +211,7 @@ def distribution_for_instance context 'without training instances' do before { allow(subject).to receive(:training_instances).and_return(nil) } - it 'should raise an UnassignedTrainingInstancesError' do + it 'raises an UnassignedTrainingInstancesError' do expect { subject.evaluate(instances) } .to raise_error Weka::UnassignedTrainingInstancesError end @@ -229,7 +229,7 @@ def distribution_for_instance end context 'with a given instance' do - it 'should call Java‘s #classify_instance' do + it 'calls Java’s #classify_instance' do expect(subject) .to receive(:classify_instance).once .with(an_instance_of(instance.class)) @@ -237,13 +237,13 @@ def distribution_for_instance subject.classify(instance) end - it 'should return the predicted class value of the instance' do + it 'returns the predicted class value of the instance' do expect(subject.classify(instance)).to eq class_value end end context 'with a given array of values' do - it 'should call Java‘s #classify_instance' do + it 'calls Java’s #classify_instance' do expect(subject) .to receive(:classify_instance).once .with(an_instance_of(Weka::Core::DenseInstance)) @@ -251,7 +251,7 @@ def distribution_for_instance subject.classify(values) end - it 'should return the predicted class value of the instance' do + it 'returns the predicted class value of the instance' do expect(subject.classify(values)).to eq class_value end end @@ -259,7 +259,7 @@ def distribution_for_instance context 'without training instances' do before { allow(subject).to receive(:training_instances).and_return(nil) } - it 'should raise an UnassignedTrainingInstancesError' do + it 'raises an UnassignedTrainingInstancesError' do expect { subject.classify(instance) } .to raise_error Weka::UnassignedTrainingInstancesError end @@ -279,7 +279,7 @@ def distribution_for_instance end context 'with a given instance' do - it 'should call Java‘s #distribution_for_instance' do + it 'calls Java’s #distribution_for_instance' do expect(subject) .to receive(:distribution_for_instance).once .with(an_instance_of(instance.class)) @@ -287,13 +287,13 @@ def distribution_for_instance subject.distribution_for(instance) end - it 'should return the predicted class distributions of the instance' do + it 'returns the predicted class distributions of the instance' do expect(subject.distribution_for(instance)).to eq class_distributions end end context 'with a given array of values' do - it 'should call Java‘s #distribution_for_instance' do + it 'calls Java’s #distribution_for_instance' do expect(subject) .to receive(:distribution_for_instance).once .with(an_instance_of(Weka::Core::DenseInstance)) @@ -301,7 +301,7 @@ def distribution_for_instance subject.distribution_for(values) end - it 'should return the predicted class distributions of the instance' do + it 'returns the predicted class distributions of the instance' do expect(subject.distribution_for(values)).to eq class_distributions end end @@ -309,7 +309,7 @@ def distribution_for_instance context 'without training instances' do before { allow(subject).to receive(:training_instances).and_return(nil) } - it 'should raise an UnassignedTrainingInstancesError' do + it 'raises an UnassignedTrainingInstancesError' do expect { subject.distribution_for(instance) } .to raise_error Weka::UnassignedTrainingInstancesError end diff --git a/spec/clusterers/cluster_evaluation_spec.rb b/spec/clusterers/cluster_evaluation_spec.rb index e6aecc9..0b856e3 100644 --- a/spec/clusterers/cluster_evaluation_spec.rb +++ b/spec/clusterers/cluster_evaluation_spec.rb @@ -8,7 +8,7 @@ summary: :cluster_results_to_string, clusters_count: :num_clusters }.each do |alias_method, method| - it "should define the alias ##{alias_method} for ##{method}" do + it "defines the alias ##{alias_method} for ##{method}" do expect(subject.method(method)).to eq subject.method(alias_method) end end diff --git a/spec/clusterers/utils_spec.rb b/spec/clusterers/utils_spec.rb index d8c4a89..36e9a96 100644 --- a/spec/clusterers/utils_spec.rb +++ b/spec/clusterers/utils_spec.rb @@ -28,19 +28,19 @@ def distribution_for_instance it { is_expected.to respond_to :evaluate } describe '#train_with_instances' do - it 'should call Java‘s #build_classifier' do + it 'calls Java’s #build_classifier' do expect(subject).to receive(:build_clusterer).once.with(instances) subject.train_with_instances(instances) end - it 'should set the training_instances' do + it 'sets the training_instances' do subject = including_class.new expect(subject.training_instances).to be_nil subject.train_with_instances(instances) expect(subject.training_instances).to eq instances end - it 'should return itself' do + it 'returns itself' do expect(subject.train_with_instances(instances)).to be subject end end @@ -53,18 +53,18 @@ def distribution_for_instance subject.train_with_instances(instances) end - it 'should call Java‘s #update_classifier' do + it 'calls Java’s #update_classifier' do expect(subject).to receive(:update_clusterer).once.with(instance) subject.add_training_instance(instance) end - it 'should add the instance to training_instances' do + it 'adds the instance to training_instances' do expect { subject.add_training_instance(instance) } .to change { subject.training_instances.count } .by(1) end - it 'should return itself' do + it 'returns itself' do expect(subject.add_training_instance(instance)).to be_a subject.class end end @@ -77,7 +77,7 @@ def distribution_for_instance subject.train_with_instances(instances) end - it 'should call #add_training_instance' do + it 'calls #add_training_instance' do expect(subject) .to receive(:add_training_instance).once .with(an_instance_of(Weka::Core::DenseInstance)) @@ -85,7 +85,7 @@ def distribution_for_instance subject.add_training_data(values) end - it 'should return itself' do + it 'returns itself' do expect(subject.add_training_data(values)).to be_a subject.class end end @@ -128,19 +128,19 @@ def build_clusterer(instances) it { is_expected.to respond_to :cross_validate } - it 'should return a Weka::Clusterers::ClusterEvaluation' do + it 'returns a Weka::Clusterers::ClusterEvaluation' do return_value = subject.cross_validate expect(return_value).to eq cross_validation_result end - it 'should run Java‘s #cross_validate_model on a ClusterEvaluation' do + it 'runs Java’s #cross_validate_model on a ClusterEvaluation' do expect(Weka::Clusterers::ClusterEvaluation) .to receive(:cross_validate_model).once subject.cross_validate end - it 'should use 3 folds and the training instances as default test instances' do + it 'uses 3 folds and the training instances as default test instances' do expect(Weka::Clusterers::ClusterEvaluation) .to receive(:cross_validate_model).once .with( @@ -156,7 +156,7 @@ def build_clusterer(instances) context 'with given folds' do let(:folds) { default_folds + 1 } - it 'should use the given number of folds' do + it 'uses the given number of folds' do expect(Weka::Clusterers::ClusterEvaluation) .to receive(:cross_validate_model).once .with( @@ -169,7 +169,7 @@ def build_clusterer(instances) subject.cross_validate(folds: folds) end - it 'should use the folds as an integer value' do + it 'uses the folds as an integer value' do expect(Weka::Clusterers::ClusterEvaluation) .to receive(:cross_validate_model).once .with( @@ -188,7 +188,7 @@ def build_clusterer(instances) allow(subject).to receive(:training_instances).and_return(nil) end - it 'should raise an UnassignedTrainingInstancesError' do + it 'raises an UnassignedTrainingInstancesError' do expect { subject.cross_validate } .to raise_error Weka::UnassignedTrainingInstancesError end @@ -203,12 +203,12 @@ def build_clusterer(instances) .to receive(:evaluate_clusterer) end - it 'should return a Weka::Clusterers::ClusterEvaluation' do + it 'returns a Weka::Clusterers::ClusterEvaluation' do return_value = subject.evaluate(instances) expect(return_value).to be_kind_of Weka::Clusterers::ClusterEvaluation end - it 'should run Java‘s #evaluate_model on an Evaluation' do + it 'runs Java’s #evaluate_model on an Evaluation' do expect_any_instance_of(Weka::Clusterers::ClusterEvaluation) .to receive(:evaluate_clusterer).once .with(instances) @@ -219,7 +219,7 @@ def build_clusterer(instances) context 'without training instances' do before { allow(subject).to receive(:training_instances).and_return(nil) } - it 'should raise an UnassignedTrainingInstancesError' do + it 'raises an UnassignedTrainingInstancesError' do expect { subject.evaluate(instances) } .to raise_error Weka::UnassignedTrainingInstancesError end @@ -236,7 +236,7 @@ def build_clusterer(instances) end context 'with a given instance' do - it 'should call Java‘s #cluster_instance' do + it 'calls Java’s #cluster_instance' do expect(subject) .to receive(:cluster_instance).once .with(an_instance_of(instance.class)) @@ -244,13 +244,13 @@ def build_clusterer(instances) subject.cluster(instance) end - it 'should return the predicted class value of the instance' do + it 'returns the predicted class value of the instance' do expect(subject.cluster(instance)).to eq cluster end end context 'with a given array of values' do - it 'should call Java‘s #cluster_instance' do + it 'calls Java’s #cluster_instance' do expect(subject) .to receive(:cluster_instance).once .with(an_instance_of(Weka::Core::DenseInstance)) @@ -258,7 +258,7 @@ def build_clusterer(instances) subject.cluster(values) end - it 'should return the predicted class value of the instance' do + it 'returns the predicted class value of the instance' do expect(subject.cluster(values)).to eq cluster end end @@ -266,7 +266,7 @@ def build_clusterer(instances) context 'without training instances' do before { allow(subject).to receive(:training_instances).and_return(nil) } - it 'should raise an UnassignedTrainingInstancesError' do + it 'raises an UnassignedTrainingInstancesError' do expect { subject.cluster(instance) } .to raise_error Weka::UnassignedTrainingInstancesError end @@ -285,7 +285,7 @@ def build_clusterer(instances) end context 'with a given instance' do - it 'should call Java‘s #distribution_for_instance' do + it 'calls Java’s #distribution_for_instance' do expect(subject) .to receive(:distribution_for_instance).once .with(an_instance_of(instance.class)) @@ -293,13 +293,13 @@ def build_clusterer(instances) subject.distribution_for(instance) end - it 'should return the predicted cluster distributions of the instance' do + it 'returns the predicted cluster distributions of the instance' do expect(subject.distribution_for(instance)).to eq distributions end end context 'with a given array of values' do - it 'should call Java‘s #distribution_for_instance' do + it 'calls Java’s #distribution_for_instance' do expect(subject) .to receive(:distribution_for_instance).once .with(an_instance_of(Weka::Core::DenseInstance)) @@ -307,7 +307,7 @@ def build_clusterer(instances) subject.distribution_for(values) end - it 'should return the predicted cluster distributions of the instance' do + it 'returns the predicted cluster distributions of the instance' do expect(subject.distribution_for(values)).to eq distributions end end @@ -315,7 +315,7 @@ def build_clusterer(instances) context 'without training instances' do before { allow(subject).to receive(:training_instances).and_return(nil) } - it 'should raise an UnassignedTrainingInstancesError' do + it 'raises an UnassignedTrainingInstancesError' do expect { subject.distribution_for(instance) } .to raise_error Weka::UnassignedTrainingInstancesError end diff --git a/spec/clusterers_spec.rb b/spec/clusterers_spec.rb index 2c51879..5a29afc 100644 --- a/spec/clusterers_spec.rb +++ b/spec/clusterers_spec.rb @@ -11,7 +11,7 @@ :HierarchicalClusterer, :SimpleKMeans ].each do |class_name| - it "should define a class #{class_name}" do + it "defines a class #{class_name}" do expect(described_class.const_defined?(class_name)).to be true end end diff --git a/spec/concerns/buildable_spec.rb b/spec/concerns/buildable_spec.rb index 84ce492..74b1c06 100644 --- a/spec/concerns/buildable_spec.rb +++ b/spec/concerns/buildable_spec.rb @@ -5,7 +5,7 @@ Class.new { include Weka::Concerns::Buildable } end - it 'should respond to .build' do + it 'responds to .build' do expect(subject).to respond_to :build end @@ -15,19 +15,19 @@ allow_any_instance_of(subject).to receive(:a_public_method) end - it 'should evaluate the given block on a new class instance' do + it 'evaluates the given block on a new class instance' do expect_any_instance_of(subject).to receive(:a_public_method).once subject.build { a_public_method } end - it 'should return an instance of the including class' do + it 'returns an instance of the including class' do instance = subject.build { a_public_method } expect(instance).to be_kind_of subject end end context 'called without a block' do - it 'should return an instance of the including class' do + it 'returns an instance of the including class' do expect(subject.build).to be_kind_of subject end end diff --git a/spec/concerns/describable_spec.rb b/spec/concerns/describable_spec.rb index 06fde6c..ece06c8 100644 --- a/spec/concerns/describable_spec.rb +++ b/spec/concerns/describable_spec.rb @@ -13,7 +13,7 @@ allow_any_instance_of(subject).to receive(:global_info).and_return('') end - it 'should call Weka’s #global_info on a new instance' do + it 'calls Weka’s #global_info on a new instance' do expect_any_instance_of(subject).to receive(:global_info).once subject.description end @@ -24,12 +24,12 @@ allow_any_instance_of(subject).to receive(:list_options).and_return([]) end - it 'should call Weka’s #list_options on a new instance' do + it 'calls Weka’s #list_options on a new instance' do expect_any_instance_of(subject).to receive(:list_options).once subject.options end - it 'should return a string' do + it 'returns a string' do expect(subject.options).to be_a String end end diff --git a/spec/concerns/optionizable_spec.rb b/spec/concerns/optionizable_spec.rb index bca2ef4..7db99d1 100644 --- a/spec/concerns/optionizable_spec.rb +++ b/spec/concerns/optionizable_spec.rb @@ -8,7 +8,7 @@ it { is_expected.to respond_to :use_options } it { is_expected.to respond_to :options } - it 'should respond to .default_options' do + it 'responds to .default_options' do expect(subject.class).to respond_to :default_options end @@ -21,7 +21,7 @@ end context 'when called with hash options' do - it 'should set the given options' do + it 'sets the given options' do expect(Java::WekaCore::Utils) .to receive(:split_options).once .with('-I 100 -K 0') @@ -32,7 +32,7 @@ end context 'when called with single options' do - it 'should set the given options' do + it 'sets the given options' do expect(Java::WekaCore::Utils) .to receive(:split_options).once .with('-O -B') @@ -43,7 +43,7 @@ end context 'when called with single options & hash options' do - it 'should set the given options' do + it 'sets the given options' do expect(Java::WekaCore::Utils) .to receive(:split_options).once .with('-O -I 100') @@ -54,7 +54,7 @@ end context 'when called with a string' do - it 'should set the given options' do + it 'sets the given options' do expect(Java::WekaCore::Utils) .to receive(:split_options).once .with('-O -I 100') @@ -71,7 +71,7 @@ context 'if both single options & hash option are defined' do before { subject.use_options(:O, :B, I: 100) } - it 'should return the defined options' do + it 'returns the defined options' do expect(subject.options).to eq '-O -B -I 100' end end @@ -79,7 +79,7 @@ context 'if only single options are defined' do before { subject.use_options(:O, :B) } - it 'should not include an empty hash' do + it 'does not include an empty hash' do expect(subject.options).to eq '-O -B' end end @@ -93,7 +93,7 @@ .and_return(default_options) end - it 'should return the default options' do + it 'returns the default options' do expect(subject.options).to eq default_options end end @@ -106,12 +106,12 @@ .and_return(%w(-C last -Z -P 10 -M -B 0.1)) end - it 'should receive Java‘s #get_options' do + it 'receives Java’s #get_options' do expect_any_instance_of(subject.class).to receive(:get_options).once subject.class.default_options end - it 'should return a string with the default options' do + it 'returns a string with the default options' do options = '-C last -Z -P 10 -M -B 0.1' expect(subject.class.default_options).to eq options end diff --git a/spec/concerns/persistent_spec.rb b/spec/concerns/persistent_spec.rb index 7b93694..0799dae 100644 --- a/spec/concerns/persistent_spec.rb +++ b/spec/concerns/persistent_spec.rb @@ -4,7 +4,7 @@ describe 'if included' do subject { Class.new } - it 'should set __persistent__ to true' do + it 'sets __persistent__ to true' do expect(subject).to receive(:__persistent__=).with(true).once subject.include(Weka::Concerns::Persistent) end diff --git a/spec/concerns/serializable_spec.rb b/spec/concerns/serializable_spec.rb index aca31c3..75c6602 100644 --- a/spec/concerns/serializable_spec.rb +++ b/spec/concerns/serializable_spec.rb @@ -7,12 +7,12 @@ let(:filename) { 'file.model' } - it 'should respond to #serialize' do + it 'responds to #serialize' do expect(subject.new).to respond_to :serialize end describe '#serialize' do - it 'should call Weka::Core::SerializationHelper.write' do + it 'calls Weka::Core::SerializationHelper.write' do expect(Weka::Core::SerializationHelper) .to receive(:write) .with(filename, subject) diff --git a/spec/core/attribute_spec.rb b/spec/core/attribute_spec.rb index bb25d82..719b816 100644 --- a/spec/core/attribute_spec.rb +++ b/spec/core/attribute_spec.rb @@ -8,7 +8,7 @@ it { is_expected.to respond_to :internal_value_of } describe '#values' do - it 'should return an array of the values' do + it 'returns an array of the values' do expect(subject.values).to eq values end end @@ -17,23 +17,23 @@ context 'a numeric attribute' do let(:attribute) { Weka::Core::Attribute.new('numeric attribute') } - it 'should return the value as a float' do + it 'returns the value as a float' do expect(attribute.internal_value_of(3.5)).to eq 3.5 end - it 'should return the value as a float if given as string' do + it 'returns 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 + it 'returns 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 + it 'returns 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 + it 'returns NaN if the given value is "?"' do expect(attribute.internal_value_of('?')).to be Float::NAN end end @@ -41,12 +41,12 @@ context 'a nominal attribute' do let(:attribute) { Weka::Core::Attribute.new('class', %w(true false)) } - it 'should return the correct internal index' do + it 'returns the correct internal index' do expect(attribute.internal_value_of('true')).to eq 0 expect(attribute.internal_value_of('false')).to eq 1 end - it 'should return the correct internal index as given as a non-String' do + it 'returns the correct internal index as given as a non-String' do expect(attribute.internal_value_of(true)).to eq 0 expect(attribute.internal_value_of(false)).to eq 1 @@ -54,15 +54,15 @@ expect(attribute.internal_value_of(:false)).to eq 1 end - it 'should return NaN if the given value is Float::NAN' do + it 'returns 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 + it 'returns 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 + it 'returns NaN if the given value is "?"' do expect(attribute.internal_value_of('?')).to be Float::NAN end end @@ -79,19 +79,19 @@ .and_return(unix_timestamp) end - it 'should return the right date timestamp value' do + it 'returns 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 + it 'returns 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 + it 'returns 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 + it 'returns NaN if the given value is "?"' do expect(attribute.internal_value_of('?')).to be Float::NAN end end diff --git a/spec/core/converters_spec.rb b/spec/core/converters_spec.rb index 83d25fa..df7f1f8 100644 --- a/spec/core/converters_spec.rb +++ b/spec/core/converters_spec.rb @@ -11,7 +11,7 @@ :JSONLoader, :JSONSaver ].each do |class_name| - it "should define a class #{class_name}" do + it "defines a class #{class_name}" do expect(described_class.const_defined?(class_name)).to be true end end diff --git a/spec/core/dense_instance_spec.rb b/spec/core/dense_instance_spec.rb index 8318767..966b362 100644 --- a/spec/core/dense_instance_spec.rb +++ b/spec/core/dense_instance_spec.rb @@ -18,7 +18,7 @@ values: :to_a, values_count: :num_values }.each do |method, alias_method| - it "should define the alias ##{alias_method} for ##{method}" do + it "defines the alias ##{alias_method} for ##{method}" do expect(subject.method(method)).to eq subject.method(alias_method) end end @@ -26,19 +26,19 @@ describe 'instantiation' do describe 'with an Integer value' do - it 'should create a instance with only missing values' do + it 'creates 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 + it 'creates 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 + it 'handles "?" values or nil values' do values = Weka::Core::DenseInstance.new([1, '?', nil, 4]).values expect(values).to eq [1, '?', '?', 4] end @@ -48,7 +48,7 @@ describe '#to_a' do let(:values) { ['rainy', 50.0, 50.0, 'TRUE', 'no', '2015-12-24 11:11'] } - it 'should return an Array with the values of the instance' do + it 'returns an Array with the values of the instance' do expect(subject.to_a).to eq values end @@ -61,14 +61,14 @@ instances.instances.last end - it 'should return an Array with the values of the instance' do + it 'returns an Array with the values of the instance' do expect(subject.to_a).to eq values end end end describe '#attributes' do - it 'should return an Array of Attributes' do + it 'returns an Array of Attributes' do attributes = subject.attributes expect(attributes).to be_an Array @@ -84,7 +84,7 @@ before { @result = nil } describe '#each_attribute' do - it 'should run a block on each attribute' do + it 'runs a block on each attribute' do subject.each_attribute do |attribute| @result = attribute.name unless @result end @@ -93,7 +93,7 @@ end context 'without a given block' do - it 'should return a WekaEnumerator' do + it 'returns a WekaEnumerator' do expect(subject.each_attribute) .to be_kind_of(Java::WekaCore::WekaEnumeration) end @@ -101,7 +101,7 @@ end describe '#each_attribute_with_index' do - it 'should run a block on each attribute' do + it 'runs a block on each attribute' do subject.each_attribute_with_index do |attribute, index| @result = "#{attribute.name}, #{index}" if index == 0 end @@ -110,7 +110,7 @@ end context 'without a given block' do - it 'should return a WekaEnumerator' do + it 'returns a WekaEnumerator' do expect(subject.each_attribute_with_index) .to be_kind_of(Java::WekaCore::WekaEnumeration) end diff --git a/spec/core/instances_spec.rb b/spec/core/instances_spec.rb index 6d0083c..6570eeb 100644 --- a/spec/core/instances_spec.rb +++ b/spec/core/instances_spec.rb @@ -45,7 +45,7 @@ instances_count: :num_instances, attributes_count: :num_attributes }.each do |method, alias_method| - it "should define the alias ##{alias_method} for ##{method}" do + it "defines the alias ##{alias_method} for ##{method}" do expect(instances.method(method)).to eq instances.method(alias_method) end end @@ -58,7 +58,7 @@ end describe ".from_#{type}" do - it "should call the Weka::Core::Loader#load_#{type}" do + it "calls the Weka::Core::Loader#load_#{type}" do expect(Weka::Core::Loader) .to receive(:"load_#{type}").once .with("test.#{type}") @@ -76,7 +76,7 @@ end describe "#to_#{type}" do - it "should call the Weka::Core::Saver#save_#{type}" do + it "calls the Weka::Core::Saver#save_#{type}" do expect(Weka::Core::Saver) .to receive(:"save_#{type}").once .with(file: "test.#{type}", instances: subject) @@ -88,7 +88,7 @@ end describe '#instances' do - it 'should return an Array of DenseInstance objects' do + it 'returns an Array of DenseInstance objects' do objects = subject.instances expect(objects).to be_an Array @@ -101,7 +101,7 @@ end describe '#attributes' do - it 'should return an Array of Attribute objects' do + it 'returns an Array of Attribute objects' do objects = subject.attributes expect(objects).to be_an Array @@ -114,7 +114,7 @@ end describe '#attribute_names' do - it 'should return an Array of the attribute names' do + it 'returns an Array of the attribute names' do names = %w(outlook temperature humidity windy play) expect(subject.attribute_names).to eq names end @@ -131,7 +131,7 @@ end context 'with the class_attribute option' do - it 'should define the attribute as class attribute' do + it 'defines the attribute as class attribute' do instances.numeric(name, class_attribute: true) expect(instances.class_attribute.name).to eq name end @@ -152,7 +152,7 @@ end context 'with the class_attribute option' do - it 'should define the attribute as class attribute' do + it 'defines the attribute as class attribute' do instances.nominal(name, values: %w(yes no), class_attribute: true) expect(instances.class_attribute.name).to eq name end @@ -166,7 +166,7 @@ end context 'with the class_attribute option' do - it 'should define the attribute as class attribute' do + it 'defines the attribute as class attribute' do instances.date(name, class_attribute: true) expect(instances.class_attribute.name).to eq name end @@ -194,12 +194,12 @@ expect(instances.attributes.first).to be_nominal end - it 'should convert a single option into an Array' do + it 'converts a single option into an Array' do instances.nominal(:attribute_name, values: 'yes') expect(instances.attributes.first.values).to eq ['yes'] end - it 'should convert the options into strings' do + it 'converts the options into strings' do instances.nominal(:attribute_name, values: [true, false]) expect(instances.attributes.first.values).to eq %w(true false) end @@ -220,7 +220,7 @@ expect(subject.class_attribute.name).to eq 'play' end - it 'should reset the class attribute if it assigns nil' do + it 'resets the class attribute if it assigns nil' do subject.class_attribute = :play expect { subject.class_attribute = nil } @@ -229,7 +229,7 @@ .to(nil) end - it 'should raise an ArgumentError if the given attribute is not defined' do + it 'raises an ArgumentError if the given attribute is not defined' do expect { subject.class_attribute = :not_existing_attribute } .to raise_error(ArgumentError) end @@ -239,19 +239,18 @@ context 'if class attribute is set' do before { subject.class_attribute = :play } - it 'should return the Attribute' do + it 'returns the Attribute' do expect(subject.class_attribute).to be_kind_of Weka::Core::Attribute expect(subject.class_attribute.name).to eq 'play' end end context 'if class attribute is not set' do - it 'should not raise a Java::WekaCore::UnassignedClassException' do - expect { subject.class_attribute } - .not_to raise_error Java::WekaCore::UnassignedClassException + it 'does not raise a Java::WekaCore::UnassignedClassException' do + expect { subject.class_attribute }.not_to raise_error end - it 'should return nil' do + it 'returns nil' do expect(subject.class_attribute).to be_nil end end @@ -261,13 +260,13 @@ context 'if class_attribute is set' do before { subject.class_attribute = :outlook } - it 'should return true' do + it 'returns true' do expect(subject.class_attribute_defined?).to be true end end context 'if class_attribute is not set' do - it 'should return false' do + it 'returns false' do expect(subject.class_attribute_defined?).to be false end end @@ -276,14 +275,14 @@ describe '#reset_class_attribute' do before { subject.class_attribute = :play } - it 'should reset the class attribute' do + it 'resets the class attribute' do expect { subject.reset_class_attribute } .to change { subject.class_attribute }.to(nil) end end describe '#add_attributes' do - it 'should add the numbers of attributes given in the block' do + it 'adds the numbers of attributes given in the block' do instances = Weka::Core::Instances.new expect { @@ -294,7 +293,7 @@ }.to change { instances.attributes.count }.from(0).to(2) end - it 'should add the types of attributes given in the block' do + it 'adds the types of attributes given in the block' do instances = Weka::Core::Instances.new instances.add_attributes do @@ -307,18 +306,18 @@ end describe '#initialize' do - it 'should take a relation_name as argument' do + it 'takes a relation_name as argument' do name = 'name' instances = Weka::Core::Instances.new(relation_name: name) expect(instances.relation_name).to eq name end - it 'should have a default relation_name of "Instances"' do + it 'has a default relation_name of "Instances"' do expect(Weka::Core::Instances.new.relation_name).to eq 'Instances' end - it 'should take attributes as argument' do + it 'takes attributes as argument' do attributes = subject.attributes instances = Weka::Core::Instances.new(attributes: attributes) @@ -330,7 +329,7 @@ before { @result = nil } describe '#each' do - it 'should run a block on each instance' do + it 'runs a block on each instance' do subject.each do |instance| @result = instance.value(0) unless @result end @@ -339,7 +338,7 @@ end context 'without a given block' do - it 'should return a WekaEnumerator' do + it 'returns a WekaEnumerator' do expect(subject.each) .to be_kind_of(Java::WekaCore::WekaEnumeration) end @@ -347,7 +346,7 @@ end describe '#each_with_index' do - it 'should run a block on each instance' do + it 'runs a block on each instance' do subject.each_with_index do |instance, index| @result = "#{instance.value(0)}, #{index}" if index == 0 end @@ -356,7 +355,7 @@ end context 'without a given block' do - it 'should return a WekaEnumerator' do + it 'returns a WekaEnumerator' do expect(subject.each_with_index) .to be_kind_of(Java::WekaCore::WekaEnumeration) end @@ -364,7 +363,7 @@ end describe '#each_attribute' do - it 'should run a block on each attribute' do + it 'runs a block on each attribute' do subject.each_attribute do |attribute| @result = attribute.name unless @result end @@ -373,7 +372,7 @@ end context 'without a given block' do - it 'should return a WekaEnumerator' do + it 'returns a WekaEnumerator' do expect(subject.each_attribute) .to be_kind_of(Java::WekaCore::WekaEnumeration) end @@ -381,7 +380,7 @@ end describe '#each_attribute_with_index' do - it 'should run a block on each attribute' do + it 'runs a block on each attribute' do subject.each_attribute_with_index do |attribute, index| @result = "#{attribute.name}, #{index}" if index == 0 end @@ -390,7 +389,7 @@ end context 'without a given block' do - it 'should return a WekaEnumerator' do + it 'returns a WekaEnumerator' do expect(subject.each_attribute_with_index) .to be_kind_of(Java::WekaCore::WekaEnumeration) end @@ -399,27 +398,27 @@ end describe '#add_instance' do - it 'should add an instance from given values to the Instances object' do + it 'adds an instance from given values to the Instances object' do data = [:sunny, 70, 80, 'TRUE', :yes] subject.add_instance(data) expect(subject.instances.last.to_s).to eq data.join(',') end - it 'should add a given instance to the Instances object' do + it 'adds a given instance to the Instances object' do data = subject.first subject.add_instance(data) expect(subject.instances.last.to_s).to eq data.to_s end - it 'should add a given instance with only missing values' do + it 'adds 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 + it 'adds a given instance with partly missing values' do data = [:sunny, 70, nil, '?', Float::NAN] subject.add_instance(data) @@ -432,20 +431,20 @@ [[:sunny, 70, 80, :TRUE, :yes], [:overcast, 80, 85, :FALSE, :yes]] end - it 'should add the data to the Instances object' do + it 'adds the data to the Instances object' do expect { subject.add_instances(data) } .to change { subject.instances_count } .by(data.count) end - it 'should call #add_instance internally' do + it 'calls #add_instance internally' do expect(subject).to receive(:add_instance).exactly(data.count).times subject.add_instances(data) end end describe '#internal_values_of' do - it 'should return the internal values of the given values' do + it 'returns the internal values of the given values' do values = [:sunny, 85, 85, :FALSE, :no] internal_values = [0, 85.0, 85.0, 1, 1] @@ -457,7 +456,7 @@ let(:filter) { double('filter') } before { allow(filter).to receive(:filter).and_return(subject) } - it 'should call the given filter‘s #filter method' do + it 'calls the given filter‘s #filter method' do expect(filter).to receive(:filter).once.with(subject) subject.apply_filter(filter) end @@ -467,7 +466,7 @@ let(:filter) { double('filter') } before { allow(filter).to receive(:filter).and_return(subject) } - it 'should call the given filters‘ #filter methods' do + it 'calls the given filters‘ #filter methods' do expect(filter).to receive(:filter).twice.with(subject) subject.apply_filters(filter, filter) end @@ -483,7 +482,7 @@ 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 + it 'calls .merge_instance of Weka::Core::Instances' do expect(Weka::Core::Instances) .to receive(:merge_instances) .with(instances_a, instances_b) @@ -491,7 +490,7 @@ instances_a.merge(instances_b) end - it 'should return the result of .merge_instance' do + it 'returns the result of .merge_instance' do merged = double('instances') allow(Weka::Core::Instances) @@ -503,12 +502,12 @@ end context 'when merging multiple instances' do - it 'should call .merge_instances mutliple times' do + it 'calls .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 + it 'returns the merged instances' do merged = instances_a.merge(instances_b, instances_c) merged_attributes = [attribute_a, attribute_b, attribute_c] diff --git a/spec/core/serialization_helper_spec.rb b/spec/core/serialization_helper_spec.rb index a312afa..6fbe724 100644 --- a/spec/core/serialization_helper_spec.rb +++ b/spec/core/serialization_helper_spec.rb @@ -8,7 +8,7 @@ write: :serialize, read: :deserialize }.each do |method, alias_method| - it "should define the alias .#{alias_method} for .#{method}" do + it "defines the alias .#{alias_method} for .#{method}" do expect(Weka::Core::SerializationHelper.public_class_method(method)) .to eq Weka::Core::SerializationHelper.public_class_method(alias_method) end diff --git a/spec/filters/supervised/attribute_selection_spec.rb b/spec/filters/supervised/attribute_selection_spec.rb index 84629c9..52137fc 100644 --- a/spec/filters/supervised/attribute_selection_spec.rb +++ b/spec/filters/supervised/attribute_selection_spec.rb @@ -6,7 +6,7 @@ set_evaluator: :use_evaluator, set_search: :use_search }.each do |method, alias_method| - it "should define the alias ##{alias_method} for ##{method}" do + it "defines the alias ##{alias_method} for ##{method}" do expect(subject.method(method)).to eq subject.method(alias_method) end end diff --git a/spec/filters/supervised/attribute_spec.rb b/spec/filters/supervised/attribute_spec.rb index c556f09..6bfffaf 100644 --- a/spec/filters/supervised/attribute_spec.rb +++ b/spec/filters/supervised/attribute_spec.rb @@ -13,7 +13,7 @@ :NominalToBinary, :PartitionMembership ].each do |class_name| - it "should define a class #{class_name}" do + it "defines a class #{class_name}" do expect(described_class.const_defined?(class_name)).to be true end end diff --git a/spec/filters/supervised/instance_spec.rb b/spec/filters/supervised/instance_spec.rb index f2f4fab..20618ef 100644 --- a/spec/filters/supervised/instance_spec.rb +++ b/spec/filters/supervised/instance_spec.rb @@ -9,7 +9,7 @@ :SpreadSubsample, :StratifiedRemoveFolds ].each do |class_name| - it "should define a class #{class_name}" do + it "defines a class #{class_name}" do expect(described_class.const_defined?(class_name)).to be true end end diff --git a/spec/filters/unsupervised/attribute_spec.rb b/spec/filters/unsupervised/attribute_spec.rb index ef1b905..e8344b0 100644 --- a/spec/filters/unsupervised/attribute_spec.rb +++ b/spec/filters/unsupervised/attribute_spec.rb @@ -60,7 +60,7 @@ :TimeSeriesTranslate, :Transpose ].each do |class_name| - it "should define a class #{class_name}" do + it "defines a class #{class_name}" do expect(described_class.const_defined?(class_name)).to be true end end diff --git a/spec/filters/unsupervised/instance_spec.rb b/spec/filters/unsupervised/instance_spec.rb index 05348a6..6777f28 100644 --- a/spec/filters/unsupervised/instance_spec.rb +++ b/spec/filters/unsupervised/instance_spec.rb @@ -18,7 +18,7 @@ :SparseToNonSparse, :SubsetByExpression ].each do |class_name| - it "should define a class #{class_name}" do + it "defines a class #{class_name}" do expect(described_class.const_defined?(class_name)).to be true end end diff --git a/spec/filters/utils_spec.rb b/spec/filters/utils_spec.rb index 7e28beb..42db8fe 100644 --- a/spec/filters/utils_spec.rb +++ b/spec/filters/utils_spec.rb @@ -15,12 +15,12 @@ allow(Weka::Filters::Filter).to receive(:use_filter).and_return(nil) end - it 'should set the filter input format' do + it 'sets the filter input format' do expect(subject).to receive(:set_input_format).with(instances) subject.filter(instances) end - it 'should apply the including filter' do + it 'applies the including filter' do expect(Weka::Filters::Filter) .to receive(:use_filter) .with(instances, subject) From 1945b2258df09d1eb32dcdea3143b3359cd85bdc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Paul=20Go=CC=88tze?= Date: Tue, 21 Jun 2016 02:26:28 +0200 Subject: [PATCH 03/28] Fix order of before_install commands for travis-ci --- .travis.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.travis.yml b/.travis.yml index 502bde2..d2aef9b 100644 --- a/.travis.yml +++ b/.travis.yml @@ -8,8 +8,8 @@ cache: - bundler before_install: - - gem install bundler - rvm get head - rvm use jruby-9.0.1.0 --install + - gem install bundler script: bundle exec rake spec From 01b2c08fe0779605cfe2da16f8e940531f3abd5e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Paul=20Go=CC=88tze?= Date: Thu, 23 Jun 2016 22:17:58 +0200 Subject: [PATCH 04/28] Drop ActiveSupport as a dependency --- lib/weka/class_builder.rb | 28 +++-- lib/weka/classifiers/utils.rb | 174 +++++++++++++++--------------- lib/weka/clusterers/utils.rb | 127 +++++++++++----------- lib/weka/concerns.rb | 13 +-- lib/weka/concerns/buildable.rb | 6 +- lib/weka/concerns/describable.rb | 6 +- lib/weka/concerns/optionizable.rb | 52 ++++----- lib/weka/concerns/persistent.rb | 10 +- lib/weka/concerns/serializable.rb | 11 +- lib/weka/filters/utils.rb | 14 ++- lib/weka/jars.rb | 20 ++-- weka.gemspec | 1 - 12 files changed, 231 insertions(+), 231 deletions(-) diff --git a/lib/weka/class_builder.rb b/lib/weka/class_builder.rb index 6ccd57d..adc3ad2 100644 --- a/lib/weka/class_builder.rb +++ b/lib/weka/class_builder.rb @@ -1,11 +1,11 @@ -require 'active_support/concern' -require 'active_support/core_ext/string' -require 'active_support/core_ext/module' +#require 'active_support/core_ext/module' require 'weka/concerns' module Weka module ClassBuilder - extend ActiveSupport::Concern + def self.included(base) + base.extend(ClassMethods) + end module ClassMethods def build_class(class_name, weka_module: nil, include_concerns: true) @@ -36,7 +36,11 @@ def java_super_modules end def super_modules - toplevel_module? ? name : name.deconstantize + toplevel_module? ? name : deconstantize(name) + end + + def deconstantize(name) + name.split('::')[0...-1].join('::') end def java_including_module @@ -44,7 +48,11 @@ def java_including_module end def including_module - name.demodulize unless toplevel_module? + demodulize(name) unless toplevel_module? + end + + def demodulize(name) + name.split('::').last end def toplevel_module? @@ -74,7 +82,11 @@ def include_utils end def utils_defined? - utils_super_modules.constantize.const_defined?(:Utils) + constantize(utils_super_modules).const_defined?(:Utils) + end + + def constantize(module_names) + Object.module_eval("::#{module_names}") end def utils @@ -86,7 +98,7 @@ def utils_super_modules end def downcase_first_char(string) - return if string.blank? + return if string.nil? || string.empty? string[0].downcase + string[1..-1] end end diff --git a/lib/weka/classifiers/utils.rb b/lib/weka/classifiers/utils.rb index e375ae9..b9c7407 100644 --- a/lib/weka/classifiers/utils.rb +++ b/lib/weka/classifiers/utils.rb @@ -6,129 +6,129 @@ module Weka module Classifiers module Utils - extend ActiveSupport::Concern + def self.included(base) + base.class_eval do + java_import 'java.util.Random' - included do - java_import 'java.util.Random' + if instance_methods.include?(:build_classifier) + attr_reader :training_instances - if instance_methods.include?(:build_classifier) - attr_reader :training_instances + def train_with_instances(instances) + ensure_class_attribute_assigned!(instances) - def train_with_instances(instances) - ensure_class_attribute_assigned!(instances) + @training_instances = instances + build_classifier(instances) - @training_instances = instances - build_classifier(instances) + self + end - self - end - - def cross_validate(folds: 3) - ensure_trained_with_instances! + def cross_validate(folds: 3) + ensure_trained_with_instances! - evaluation = Evaluation.new(training_instances) - random = Java::JavaUtil::Random.new(1) + evaluation = Evaluation.new(training_instances) + random = Java::JavaUtil::Random.new(1) - evaluation.cross_validate_model(self, training_instances, folds.to_i, random) - evaluation - end + evaluation.cross_validate_model(self, training_instances, folds.to_i, random) + evaluation + end - def evaluate(test_instances) - ensure_trained_with_instances! - ensure_class_attribute_assigned!(test_instances) + def evaluate(test_instances) + ensure_trained_with_instances! + ensure_class_attribute_assigned!(test_instances) - evaluation = Evaluation.new(training_instances) - evaluation.evaluate_model(self, test_instances) - evaluation + evaluation = Evaluation.new(training_instances) + evaluation.evaluate_model(self, test_instances) + evaluation + end end - end - if instance_methods.include?(:classify_instance) - def classify(instance_or_values) - ensure_trained_with_instances! + if instance_methods.include?(:classify_instance) + def classify(instance_or_values) + ensure_trained_with_instances! - instance = classifiable_instance_from(instance_or_values) - index = classify_instance(instance) + instance = classifiable_instance_from(instance_or_values) + index = classify_instance(instance) - class_value_of_index(index) + class_value_of_index(index) + end end - end - if instance_methods.include?(:update_classifier) - def add_training_instance(instance) - training_instances.add(instance) - update_classifier(instance) + if instance_methods.include?(:update_classifier) + def add_training_instance(instance) + training_instances.add(instance) + update_classifier(instance) - self - end + self + end - def add_training_data(data) - values = training_instances.internal_values_of(data) - instance = Weka::Core::DenseInstance.new(values) - add_training_instance(instance) + def add_training_data(data) + values = training_instances.internal_values_of(data) + instance = Weka::Core::DenseInstance.new(values) + add_training_instance(instance) + end end - end - if instance_methods.include?(:distribution_for_instance) - def distribution_for(instance_or_values) - ensure_trained_with_instances! + if instance_methods.include?(:distribution_for_instance) + def distribution_for(instance_or_values) + ensure_trained_with_instances! - instance = classifiable_instance_from(instance_or_values) - distributions = distribution_for_instance(instance) + instance = classifiable_instance_from(instance_or_values) + distributions = distribution_for_instance(instance) - class_distributions_from(distributions).with_indifferent_access + class_distributions_from(distributions).with_indifferent_access + end end - end - private + private - def ensure_class_attribute_assigned!(instances) - return if instances.class_attribute_defined? + def ensure_class_attribute_assigned!(instances) + return if instances.class_attribute_defined? - error = 'Class attribute is not assigned for Instances.' - hint = 'You can assign a class attribute with #class_attribute=.' - message = "#{error} #{hint}" + error = 'Class attribute is not assigned for Instances.' + hint = 'You can assign a class attribute with #class_attribute=.' + message = "#{error} #{hint}" - raise UnassignedClassError, message - end + raise UnassignedClassError, message + end - def ensure_trained_with_instances! - return unless training_instances.nil? + def ensure_trained_with_instances! + return unless training_instances.nil? - error = 'Classifier is not trained with Instances.' - hint = 'You can set the training instances with #train_with_instances.' - message = "#{error} #{hint}" + error = 'Classifier is not trained with Instances.' + hint = 'You can set the training instances with #train_with_instances.' + message = "#{error} #{hint}" - raise UnassignedTrainingInstancesError, message - end + raise UnassignedTrainingInstancesError, message + end - def classifiable_instance_from(instance_or_values) - attributes = training_instances.attributes - instances = Weka::Core::Instances.new(attributes: attributes) + def classifiable_instance_from(instance_or_values) + attributes = training_instances.attributes + instances = Weka::Core::Instances.new(attributes: attributes) - class_attribute = training_instances.class_attribute - class_index = training_instances.class_index - instances.insert_attribute_at(class_attribute, class_index) + class_attribute = training_instances.class_attribute + class_index = training_instances.class_index + instances.insert_attribute_at(class_attribute, class_index) - instances.class_index = training_instances.class_index - instances.add_instance(instance_or_values) + instances.class_index = training_instances.class_index + instances.add_instance(instance_or_values) - instance = instances.first - instance.set_class_missing - instance - end + instance = instances.first + instance.set_class_missing + instance + end - def class_value_of_index(index) - training_instances.class_attribute.value(index) - end + def class_value_of_index(index) + training_instances.class_attribute.value(index) + end - def class_distributions_from(distributions) - class_values = training_instances.class_attribute.values + def class_distributions_from(distributions) + class_values = training_instances.class_attribute.values - distributions.each_with_index.reduce({}) do |result, (distribution, index)| - class_value = class_values[index].to_sym - result[class_value] = distribution - result + distributions.each_with_index.reduce({}) do |result, (distribution, index)| + class_value = class_values[index].to_sym + result[class_value] = distribution + result + end end end end diff --git a/lib/weka/clusterers/utils.rb b/lib/weka/clusterers/utils.rb index 55a7694..b08c11a 100644 --- a/lib/weka/clusterers/utils.rb +++ b/lib/weka/clusterers/utils.rb @@ -1,99 +1,98 @@ -require 'active_support/concern' require 'weka/clusterers/cluster_evaluation' require 'weka/core/instances' module Weka module Clusterers module Utils - extend ActiveSupport::Concern + def self.included(base) + base.class_eval do + java_import 'java.util.Random' - included do - java_import 'java.util.Random' + if instance_methods.include?(:build_clusterer) + attr_reader :training_instances - if instance_methods.include?(:build_clusterer) - attr_reader :training_instances + def train_with_instances(instances) + @training_instances = instances + build_clusterer(instances) - def train_with_instances(instances) - @training_instances = instances - build_clusterer(instances) + self + end - self - end + if ancestors.include?(Java::WekaClusterers::DensityBasedClusterer) + def cross_validate(folds: 3) + ensure_trained_with_instances! + + ClusterEvaluation.cross_validate_model( + self, + training_instances, + folds.to_i, + Java::JavaUtil::Random.new(1) + ) + end + end - if ancestors.include?(Java::WekaClusterers::DensityBasedClusterer) - def cross_validate(folds: 3) + def evaluate(test_instances) ensure_trained_with_instances! - ClusterEvaluation.cross_validate_model( - self, - training_instances, - folds.to_i, - Java::JavaUtil::Random.new(1) - ) + ClusterEvaluation.new.tap do |evaluation| + evaluation.clusterer = self + evaluation.evaluate_clusterer(test_instances) + end end end - def evaluate(test_instances) - ensure_trained_with_instances! + if instance_methods.include?(:cluster_instance) + def cluster(instance_or_values) + ensure_trained_with_instances! - ClusterEvaluation.new.tap do |evaluation| - evaluation.clusterer = self - evaluation.evaluate_clusterer(test_instances) + instance = clusterable_instance_from(instance_or_values) + cluster_instance(instance) end end - end - - if instance_methods.include?(:cluster_instance) - def cluster(instance_or_values) - ensure_trained_with_instances! - - instance = clusterable_instance_from(instance_or_values) - cluster_instance(instance) - end - end - if instance_methods.include?(:update_clusterer) - def add_training_instance(instance) - training_instances.add(instance) - update_clusterer(instance) + if instance_methods.include?(:update_clusterer) + def add_training_instance(instance) + training_instances.add(instance) + update_clusterer(instance) - self - end + self + end - def add_training_data(data) - values = training_instances.internal_values_of(data) - instance = Weka::Core::DenseInstance.new(values) - add_training_instance(instance) + def add_training_data(data) + values = training_instances.internal_values_of(data) + instance = Weka::Core::DenseInstance.new(values) + add_training_instance(instance) + end end - end - if instance_methods.include?(:distribution_for_instance) - def distribution_for(instance_or_values) - ensure_trained_with_instances! + if instance_methods.include?(:distribution_for_instance) + def distribution_for(instance_or_values) + ensure_trained_with_instances! - instance = clusterable_instance_from(instance_or_values) - distribution_for_instance(instance).to_a + instance = clusterable_instance_from(instance_or_values) + distribution_for_instance(instance).to_a + end end - end - private + private - def ensure_trained_with_instances! - return unless training_instances.nil? + def ensure_trained_with_instances! + return unless training_instances.nil? - error = 'Clusterer is not trained with Instances.' - hint = 'You can set the training instances with #train_with_instances.' - message = "#{error} #{hint}" + error = 'Clusterer is not trained with Instances.' + hint = 'You can set the training instances with #train_with_instances.' + message = "#{error} #{hint}" - raise UnassignedTrainingInstancesError, message - end + raise UnassignedTrainingInstancesError, message + end - def clusterable_instance_from(instance_or_values) - attributes = training_instances.attributes - instances = Weka::Core::Instances.new(attributes: attributes) + def clusterable_instance_from(instance_or_values) + attributes = training_instances.attributes + instances = Weka::Core::Instances.new(attributes: attributes) - instances.add_instance(instance_or_values) - instances.first + instances.add_instance(instance_or_values) + instances.first + end end end end diff --git a/lib/weka/concerns.rb b/lib/weka/concerns.rb index d5bebb8..9a9b468 100644 --- a/lib/weka/concerns.rb +++ b/lib/weka/concerns.rb @@ -1,4 +1,3 @@ -require 'active_support/concern' require 'weka/concerns/buildable' require 'weka/concerns/describable' require 'weka/concerns/optionizable' @@ -7,13 +6,11 @@ module Weka module Concerns - extend ActiveSupport::Concern - - included do - include Buildable - include Describable - include Optionizable - include Persistent + def self.included(base) + base.include Buildable + base.include Describable + base.include Optionizable + base.include Persistent end end end diff --git a/lib/weka/concerns/buildable.rb b/lib/weka/concerns/buildable.rb index de1a88a..eb7bf40 100644 --- a/lib/weka/concerns/buildable.rb +++ b/lib/weka/concerns/buildable.rb @@ -1,9 +1,9 @@ -require 'active_support/concern' - module Weka module Concerns module Buildable - extend ActiveSupport::Concern + def self.included(base) + base.extend ClassMethods + end module ClassMethods def build(&block) diff --git a/lib/weka/concerns/describable.rb b/lib/weka/concerns/describable.rb index 1d77892..e13d8ee 100644 --- a/lib/weka/concerns/describable.rb +++ b/lib/weka/concerns/describable.rb @@ -1,9 +1,9 @@ -require 'active_support/concern' - module Weka module Concerns module Describable - extend ActiveSupport::Concern + def self.included(base) + base.extend ClassMethods + end module ClassMethods def description diff --git a/lib/weka/concerns/optionizable.rb b/lib/weka/concerns/optionizable.rb index 5850369..1300eae 100644 --- a/lib/weka/concerns/optionizable.rb +++ b/lib/weka/concerns/optionizable.rb @@ -1,40 +1,40 @@ -require 'active_support/concern' - module Weka module Concerns module Optionizable - extend ActiveSupport::Concern + def self.included(base) + base.extend(ClassMethods) - included do - java_import 'weka.core.Utils' + base.class_eval do + java_import 'weka.core.Utils' - def use_options(*single_options, **hash_options) - joined_options = join_options(single_options, hash_options) - options = Java::WekaCore::Utils.split_options(joined_options) + def use_options(*single_options, **hash_options) + joined_options = join_options(single_options, hash_options) + options = Java::WekaCore::Utils.split_options(joined_options) - set_options(options) - @options = joined_options - end + set_options(options) + @options = joined_options + end - def options - @options || self.class.default_options - end + def options + @options || self.class.default_options + end - private + private - def join_options(*single_options, **hash_options) - [ - join_single_options(*single_options), - join_hash_options(**hash_options) - ].reject(&:empty?).join(' ') - end + def join_options(*single_options, **hash_options) + [ + join_single_options(*single_options), + join_hash_options(**hash_options) + ].reject(&:empty?).join(' ') + end - def join_single_options(options) - options.map { |option| "-#{option.to_s.sub(/^-/, '')}" }.join(' ') - end + def join_single_options(options) + options.map { |option| "-#{option.to_s.sub(/^-/, '')}" }.join(' ') + end - def join_hash_options(options) - options.map { |key, value| "-#{key} #{value}" }.join(' ') + def join_hash_options(options) + options.map { |key, value| "-#{key} #{value}" }.join(' ') + end end end diff --git a/lib/weka/concerns/persistent.rb b/lib/weka/concerns/persistent.rb index 2066bd9..367b6d8 100644 --- a/lib/weka/concerns/persistent.rb +++ b/lib/weka/concerns/persistent.rb @@ -1,12 +1,10 @@ -require 'active_support/concern' - module Weka module Concerns module Persistent - extend ActiveSupport::Concern - - included do - self.__persistent__ = true if respond_to?(:__persistent__=) + def self.included(base) + base.class_eval do + self.__persistent__ = true if respond_to?(:__persistent__=) + end end end end diff --git a/lib/weka/concerns/serializable.rb b/lib/weka/concerns/serializable.rb index 629857d..9b2bf85 100644 --- a/lib/weka/concerns/serializable.rb +++ b/lib/weka/concerns/serializable.rb @@ -1,14 +1,13 @@ -require 'active_support/concern' require 'weka/core/serialization_helper' module Weka module Concerns module Serializable - extend ActiveSupport::Concern - - included do - def serialize(filename) - Weka::Core::SerializationHelper.write(filename, self) + def self.included(base) + base.class_eval do + def serialize(filename) + Weka::Core::SerializationHelper.write(filename, self) + end end end end diff --git a/lib/weka/filters/utils.rb b/lib/weka/filters/utils.rb index bf3852e..70f5955 100644 --- a/lib/weka/filters/utils.rb +++ b/lib/weka/filters/utils.rb @@ -1,14 +1,12 @@ -require 'active_support/concern' - module Weka module Filters module Utils - extend ActiveSupport::Concern - - included do - def filter(instances) - set_input_format(instances) - Filter.use_filter(instances, self) + def self.included(base) + base.class_eval do + def filter(instances) + set_input_format(instances) + Filter.use_filter(instances, self) + end end end end diff --git a/lib/weka/jars.rb b/lib/weka/jars.rb index 1f4e774..0d90f55 100644 --- a/lib/weka/jars.rb +++ b/lib/weka/jars.rb @@ -1,18 +1,16 @@ -require 'active_support/concern' - module Weka module Jars - extend ActiveSupport::Concern - - included do - require 'lock_jar' + def self.included(base) + base.class_eval do + require 'lock_jar' - lib_path = File.expand_path('../../', File.dirname(__FILE__)) - lockfile = File.join(lib_path, 'Jarfile.lock') - jars_dir = File.join(lib_path, 'jars') + lib_path = File.expand_path('../../', File.dirname(__FILE__)) + lockfile = File.join(lib_path, 'Jarfile.lock') + jars_dir = File.join(lib_path, 'jars') - LockJar.install(lockfile, local_repo: jars_dir) - LockJar.load(lockfile, local_repo: jars_dir) + LockJar.install(lockfile, local_repo: jars_dir) + LockJar.load(lockfile, local_repo: jars_dir) + end end end end diff --git a/weka.gemspec b/weka.gemspec index f8c10a3..a7eba1e 100644 --- a/weka.gemspec +++ b/weka.gemspec @@ -23,7 +23,6 @@ Gem::Specification.new do |spec| spec.require_paths = ['lib'] spec.add_runtime_dependency 'lock_jar', '~> 0.13' - spec.add_runtime_dependency 'activesupport', '~> 4.0' spec.add_development_dependency 'bundler', '~> 1.6' spec.add_development_dependency 'rake', '~> 10.0' From 5903fdc4a79e3867cd27d94452f8dae9136dbb32 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Paul=20G=C3=B6tze?= Date: Sun, 26 Jun 2016 02:00:59 +0200 Subject: [PATCH 05/28] Add C45 loader --- lib/weka/core/converters.rb | 1 + lib/weka/core/instances.rb | 10 ++++++++++ lib/weka/core/loader.rb | 10 ++++++++++ spec/core/instances_spec.rb | 16 +++++++++++++++- spec/core/loader_spec.rb | 24 ++++++++++++++++++++++-- spec/support/resources/weather.data | 14 ++++++++++++++ spec/support/resources/weather.names | 5 +++++ 7 files changed, 77 insertions(+), 3 deletions(-) create mode 100644 spec/support/resources/weather.data create mode 100644 spec/support/resources/weather.names diff --git a/lib/weka/core/converters.rb b/lib/weka/core/converters.rb index 137e43d..0836b39 100644 --- a/lib/weka/core/converters.rb +++ b/lib/weka/core/converters.rb @@ -11,6 +11,7 @@ module Converters :CSVSaver, :JSONLoader, :JSONSaver, + :C45Loader, include_concerns: false end end diff --git a/lib/weka/core/instances.rb b/lib/weka/core/instances.rb index cd25a67..221ad23 100644 --- a/lib/weka/core/instances.rb +++ b/lib/weka/core/instances.rb @@ -26,6 +26,16 @@ def from_csv(file) def from_json(file) Loader.load_json(file) end + + # Loads instances based on a given *.names file (holding the attribute + # values) or a given *.data file (holding the attribute values). + # The respective other file is loaded from the same directory. + # + # See http://www.cs.washington.edu/dm/vfml/appendixes/c45.htm for more + # information about the C4.5 file format. + def from_c45(file) + Loader.load_c45(file) + end end def initialize(relation_name: DEFAULT_RELATION_NAME, attributes: [], &block) diff --git a/lib/weka/core/loader.rb b/lib/weka/core/loader.rb index 4e1dd4c..dc9f237 100644 --- a/lib/weka/core/loader.rb +++ b/lib/weka/core/loader.rb @@ -18,6 +18,16 @@ def load_json(file) load_with(Converters::JSONLoader, file: file) end + # Takes either a *.names or a *.data file and loads the respective other + # file from the same directory automatically. + # Returns a Weka::Core::Instances object. + # + # See http://www.cs.washington.edu/dm/vfml/appendixes/c45.htm for more + # information about the C4.5 file format. + def load_c45(file) + load_with(Converters::C45Loader, file: file) + end + private def load_with(loader_class, file:) diff --git a/spec/core/instances_spec.rb b/spec/core/instances_spec.rb index 6570eeb..88605f9 100644 --- a/spec/core/instances_spec.rb +++ b/spec/core/instances_spec.rb @@ -58,7 +58,7 @@ end describe ".from_#{type}" do - it "calls the Weka::Core::Loader#load_#{type}" do + it "calls Weka::Core::Loader#load_#{type}" do expect(Weka::Core::Loader) .to receive(:"load_#{type}").once .with("test.#{type}") @@ -67,6 +67,20 @@ end end end + + describe '.from_c45' do + let(:file) { 'example.data' } + + before { allow(Weka::Core::Loader).to receive(:load_c45).and_return('') } + + it "calls Weka::Core::Loader#load_c45" do + expect(Weka::Core::Loader) + .to receive(:load_c45).once + .with(file) + + described_class.send(:from_c45, file) + end + end end describe 'saver' do diff --git a/spec/core/loader_spec.rb b/spec/core/loader_spec.rb index dc77974..5c34914 100644 --- a/spec/core/loader_spec.rb +++ b/spec/core/loader_spec.rb @@ -1,7 +1,7 @@ require 'spec_helper' describe Weka::Core::Loader do - CLASS_METHODS = %i(load_arff load_csv load_json).freeze + CLASS_METHODS = %i(load_arff load_csv load_json load_c45).freeze CLASS_METHODS.each do |method| it "responds to .#{method}" do @@ -19,8 +19,28 @@ it "returns an Instances object for a given #{type.upcase} file" do instances = described_class.send(method, file) - expect(instances).to be_kind_of Weka::Core::Instances + expect(instances).to be_a Weka::Core::Instances end end end + + describe '#load_c45' do + let(:names_file) do + File.expand_path('../../support/resources/weather.names', __FILE__) + end + + let(:data_file) do + File.expand_path('../../support/resources/weather.data', __FILE__) + end + + it 'returns an Instances object for a given *.names file' do + instances = described_class.load_c45(names_file) + expect(instances).to be_a Weka::Core::Instances + end + + it 'returns an Instances object for a given *.data file' do + instances = described_class.load_c45(data_file) + expect(instances).to be_a Weka::Core::Instances + end + end end diff --git a/spec/support/resources/weather.data b/spec/support/resources/weather.data new file mode 100644 index 0000000..8e004e6 --- /dev/null +++ b/spec/support/resources/weather.data @@ -0,0 +1,14 @@ +sunny,85.0,85.0,FALSE,no +sunny,80.0,90.0,TRUE,no +overcast,83.0,86.0,FALSE,yes +rainy,70.0,96.0,FALSE,yes +rainy,68.0,80.0,FALSE,yes +rainy,65.0,70.0,TRUE,no +overcast,64.0,65.0,TRUE,yes +sunny,72.0,95.0,FALSE,no +sunny,69.0,70.0,FALSE,yes +rainy,75.0,80.0,FALSE,yes +sunny,75.0,70.0,TRUE,yes +overcast,72.0,90.0,TRUE,yes +overcast,81.0,75.0,FALSE,yes +rainy,71.0,91.0,TRUE,no diff --git a/spec/support/resources/weather.names b/spec/support/resources/weather.names new file mode 100644 index 0000000..bef3a43 --- /dev/null +++ b/spec/support/resources/weather.names @@ -0,0 +1,5 @@ +yes,no. +outlook: sunny,overcast,rainy. +temperature: continuous. +humidity: continuous. +windy: TRUE,FALSE. From 0be76c4dc54df4841164fb582cf6df2297e1b6eb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Paul=20Go=CC=88tze?= Date: Tue, 28 Jun 2016 23:16:19 +0200 Subject: [PATCH 06/28] Add C45 saver --- lib/weka/core/converters.rb | 1 + lib/weka/core/instances.rb | 13 +++++++++++++ lib/weka/core/saver.rb | 21 +++++++++++++++++++++ spec/core/instances_spec.rb | 20 ++++++++++++++++++-- spec/core/saver_spec.rb | 23 +++++++++++++++++++++++ spec/support/instances_helpers.rb | 6 ++++-- 6 files changed, 80 insertions(+), 4 deletions(-) diff --git a/lib/weka/core/converters.rb b/lib/weka/core/converters.rb index 0836b39..fe66f3c 100644 --- a/lib/weka/core/converters.rb +++ b/lib/weka/core/converters.rb @@ -12,6 +12,7 @@ module Converters :JSONLoader, :JSONSaver, :C45Loader, + :C45Saver, include_concerns: false end end diff --git a/lib/weka/core/instances.rb b/lib/weka/core/instances.rb index 221ad23..747e0a3 100644 --- a/lib/weka/core/instances.rb +++ b/lib/weka/core/instances.rb @@ -106,6 +106,19 @@ def to_json(file) Saver.save_json(file: file, instances: self) end + # Creates a file with the istances's attribute values and a *.data file + # with the actual data. + # + # You should choose another file extension than .data (preferably + # *.names) for the file, else it will just be overwritten with the + # automatically created *.data file. + # + # See http://www.cs.washington.edu/dm/vfml/appendixes/c45.htm for more + # information about the C4.5 file format. + def to_c45(file) + Saver.save_c45(file: file, instances: self) + end + def numeric(name, class_attribute: false) attribute = Attribute.new(name.to_s) add_attribute(attribute) diff --git a/lib/weka/core/saver.rb b/lib/weka/core/saver.rb index 9936397..d79a1ba 100644 --- a/lib/weka/core/saver.rb +++ b/lib/weka/core/saver.rb @@ -18,6 +18,27 @@ def save_json(file:, instances:) save_with(Converters::JSONSaver, file: file, instances: instances) end + # Saves the given `instances` into a file with the given name and a + # *.data file in the same directory. + # The file with the given file name includes the instances's attribute + # values, the *.data file holds the actual data. + # + # Example: + # + # Weka::Core::Saver.save_c45( + # file: './path/to/example.names', + # instances: instances + # ) + # + # creates an example.names file and an example.data file in the + # ./path/to/ directory. + # + # See: http://www.cs.washington.edu/dm/vfml/appendixes/c45.htm for more + # information about the C4.5 file format. + def save_c45(file:, instances:) + save_with(Converters::C45Saver, file: file, instances: instances) + end + private def save_with(saver_class, file:, instances:) diff --git a/spec/core/instances_spec.rb b/spec/core/instances_spec.rb index 88605f9..5d7639b 100644 --- a/spec/core/instances_spec.rb +++ b/spec/core/instances_spec.rb @@ -73,7 +73,7 @@ before { allow(Weka::Core::Loader).to receive(:load_c45).and_return('') } - it "calls Weka::Core::Loader#load_c45" do + it 'calls Weka::Core::Loader#load_c45' do expect(Weka::Core::Loader) .to receive(:load_c45).once .with(file) @@ -90,7 +90,7 @@ end describe "#to_#{type}" do - it "calls the Weka::Core::Saver#save_#{type}" do + it "calls the Weka::Core::Saver.save_#{type}" do expect(Weka::Core::Saver) .to receive(:"save_#{type}").once .with(file: "test.#{type}", instances: subject) @@ -99,6 +99,22 @@ end end end + + describe '#to_c45' do + let(:file) { 'test.names' } + + before do + allow(Weka::Core::Saver).to receive(:save_c45).and_return('') + end + + it 'calls the Weka::Core::Saver.save_c45' do + expect(Weka::Core::Saver) + .to receive(:save_c45).once + .with(file: file, instances: subject) + + subject.to_c45(file) + end + end end describe '#instances' do diff --git a/spec/core/saver_spec.rb b/spec/core/saver_spec.rb index f6cd056..2378f15 100644 --- a/spec/core/saver_spec.rb +++ b/spec/core/saver_spec.rb @@ -27,4 +27,27 @@ end end end + + describe '#save_c45' do + let(:file) { "#{@tmp_dir}/test" } + let(:names_file) { "#{file}.names" } + let(:data_file) { "#{file}.data" } + + before { instances.class_attribute = :play } + + after do + FileUtils.rm_f(names_file) + FileUtils.rm_f(data_file) + end + + it 'creates a *.names file and a *.data file' do + expect(File.exist?(names_file)).to be false + expect(File.exist?(data_file)).to be false + + described_class.save_c45(file: names_file, instances: instances) + + expect(File.exist?(names_file)).to be true + expect(File.exist?(data_file)).to be true + end + end end diff --git a/spec/support/instances_helpers.rb b/spec/support/instances_helpers.rb index 6abec79..77a15f4 100644 --- a/spec/support/instances_helpers.rb +++ b/spec/support/instances_helpers.rb @@ -1,6 +1,8 @@ module InstancesHelpers def load_instances(file_name) - file = File.expand_path("./../resources/#{file_name}", __FILE__) - Weka::Core::Loader.send("load_#{File.extname(file_name)[1..-1]}", file) + file = File.expand_path("./../resources/#{file_name}", __FILE__) + file_extension = File.extname(file_name)[1..-1] + + Weka::Core::Loader.send("load_#{file_extension}", file) end end From 15c23e19e437ddf2d4ac205f449d983f70ba505f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Paul=20Go=CC=88tze?= Date: Sat, 16 Jul 2016 10:03:30 +0200 Subject: [PATCH 07/28] Allow adding string attributes to instances --- lib/weka/core/instances.rb | 7 ++++++- spec/core/instances_spec.rb | 8 ++++---- 2 files changed, 10 insertions(+), 5 deletions(-) diff --git a/lib/weka/core/instances.rb b/lib/weka/core/instances.rb index 747e0a3..ccc856f 100644 --- a/lib/weka/core/instances.rb +++ b/lib/weka/core/instances.rb @@ -132,7 +132,12 @@ def nominal(name, values:, class_attribute: false) end def string(name, class_attribute: false) - attribute = Attribute.new(name.to_s, []) + constructor = Attribute.java_class.declared_constructor( + java.lang.String, + java.util.List + ) + + attribute = constructor.new_instance(name.to_s, nil) add_attribute(attribute) self.class_attribute = name if class_attribute end diff --git a/spec/core/instances_spec.rb b/spec/core/instances_spec.rb index 5d7639b..fdfaa14 100644 --- a/spec/core/instances_spec.rb +++ b/spec/core/instances_spec.rb @@ -168,7 +168,7 @@ end end - xdescribe '#string' do + describe '#string' do it 'can be used to add a string attribute' do instances.string(name) expect(instances.attributes.first).to be_string @@ -211,7 +211,7 @@ end end - xdescribe '#string' do + describe '#string' do it 'can be used to add a string attribute' do instances.string(:attribute_name) expect(instances.attributes.first).to be_string @@ -486,7 +486,7 @@ let(:filter) { double('filter') } before { allow(filter).to receive(:filter).and_return(subject) } - it 'calls the given filter‘s #filter method' do + it 'calls the given filter’s #filter method' do expect(filter).to receive(:filter).once.with(subject) subject.apply_filter(filter) end @@ -496,7 +496,7 @@ let(:filter) { double('filter') } before { allow(filter).to receive(:filter).and_return(subject) } - it 'calls the given filters‘ #filter methods' do + it 'calls the given filters’s #filter methods' do expect(filter).to receive(:filter).twice.with(subject) subject.apply_filters(filter, filter) end From 04d5af01545ecc29179934cd9547550c8b999d34 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Paul=20Go=CC=88tze?= Date: Sat, 16 Jul 2016 13:47:38 +0200 Subject: [PATCH 08/28] Move constructor logic into Attribute class Adds a .new_ method for each attribute type to Weka::Core::Attribute: .new_numeric(name) .new_nominal(name, values) .new_date(name, format) .new_string(name) --- lib/weka/core/attribute.rb | 49 ++++++++++++++++++++++++++++++++-- lib/weka/core/instances.rb | 13 +++------- spec/core/attribute_spec.rb | 52 ++++++++++++++++++++++++++++++++++++- 3 files changed, 102 insertions(+), 12 deletions(-) diff --git a/lib/weka/core/attribute.rb b/lib/weka/core/attribute.rb index 2f6e383..50d9ac4 100644 --- a/lib/weka/core/attribute.rb +++ b/lib/weka/core/attribute.rb @@ -1,12 +1,59 @@ +require 'weka/concerns/persistent' + module Weka module Core java_import 'weka.core.Attribute' class Attribute + include Weka::Concerns::Persistent + + TYPES = %(numeric nominal string date).freeze + + class << self + def new_numeric(name) + new(name.to_s) + end + + def new_nominal(name, values) + new(name.to_s, Array(values).map(&:to_s)) + end + + def new_date(name, format) + new(name.to_s, format.to_s) + end + + ## + # Creates a new Attribute instance of type string. + # + # The java class defines the same constructor: + # Attribute(java.lang.String, java.util.List) + # for nominal and string attributes and handles the type internally + # based on the second argument. + # + # In Java you would write following code to create a string Attribute: + # Attribute attribute = new Attribute("name", (FastVector) null); + # + # When we use a similar approach in JRuby: + # attribute = Attribute.new('name', nil) + # then a Java::JavaLang::NullPointerException is thrown. + # + # Thus, we use refelection here and call the contructor explicitly, see + # https://github.com/jruby/jruby/wiki/CallingJavaFromJRuby#constructors + def new_string(name) + constructor = Attribute.java_class.declared_constructor( + java.lang.String, + java.util.List + ) + + constructor.new_instance(name.to_s, nil) + end + end + def values enumerate_values.to_a end + ## # The order of the if statements is important here, because a date is also # a numeric. def internal_value_of(value) @@ -17,7 +64,5 @@ def internal_value_of(value) return index_of_value(value.to_s) if nominal? end end - - Weka::Core::Attribute.__persistent__ = true end end diff --git a/lib/weka/core/instances.rb b/lib/weka/core/instances.rb index ccc856f..66e84b1 100644 --- a/lib/weka/core/instances.rb +++ b/lib/weka/core/instances.rb @@ -120,30 +120,25 @@ def to_c45(file) end def numeric(name, class_attribute: false) - attribute = Attribute.new(name.to_s) + attribute = Attribute.new_numeric(name) add_attribute(attribute) self.class_attribute = name if class_attribute end def nominal(name, values:, class_attribute: false) - attribute = Attribute.new(name.to_s, Array(values).map(&:to_s)) + attribute = Attribute.new_nominal(name, values) add_attribute(attribute) self.class_attribute = name if class_attribute end def string(name, class_attribute: false) - constructor = Attribute.java_class.declared_constructor( - java.lang.String, - java.util.List - ) - - attribute = constructor.new_instance(name.to_s, nil) + attribute = Attribute.new_string(name) add_attribute(attribute) self.class_attribute = name if class_attribute end def date(name, format: 'yyyy-MM-dd HH:mm', class_attribute: false) - attribute = Attribute.new(name.to_s, format) + attribute = Attribute.new_date(name, format) add_attribute(attribute) self.class_attribute = name if class_attribute end diff --git a/spec/core/attribute_spec.rb b/spec/core/attribute_spec.rb index 719b816..f9ae5bb 100644 --- a/spec/core/attribute_spec.rb +++ b/spec/core/attribute_spec.rb @@ -2,11 +2,61 @@ describe Weka::Core::Attribute do let(:values) { %w(yes no) } - subject { Weka::Core::Attribute.new('class', values) } + let(:name) { 'name' } + + subject { Weka::Core::Attribute.new(name, values) } it { is_expected.to respond_to :values } it { is_expected.to respond_to :internal_value_of } + describe '.new_numeric' do + subject { Weka::Core::Attribute.new_numeric(name) } + + it 'returns a numeric Attribute' do + expect(subject.numeric?).to be true + end + + it 'returns an Attribute with the given name' do + expect(subject.name).to eq name + end + end + + describe '.new_nominal' do + subject { Weka::Core::Attribute.new_nominal(name, values) } + + it 'returns a nominal Attribute' do + expect(subject.nominal?).to be true + end + + it 'returns an Attribute with the given name' do + expect(subject.name).to eq name + end + end + + describe '.new_date' do + subject { Weka::Core::Attribute.new_date(name, 'yyyy-MM-dd HH:mm') } + + it 'returns a date Attribute' do + expect(subject.date?).to be true + end + + it 'returns an Attribute with the given name' do + expect(subject.name).to eq name + end + end + + xdescribe '.new_string' do + subject { Weka::Core::Attribute.new_string(name) } + + it 'returns a string Attribute' do + expect(subject.string?).to be true + end + + it 'returns an Attribute with the given name' do + expect(subject.name).to eq name + end + end + describe '#values' do it 'returns an array of the values' do expect(subject.values).to eq values From 9ad856a3f3473ba9f4061c23d70b9d95465e4684 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Paul=20Go=CC=88tze?= Date: Sat, 16 Jul 2016 13:51:19 +0200 Subject: [PATCH 09/28] Overwrite type method for Attributes to return string representation --- lib/weka/core/attribute.rb | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/lib/weka/core/attribute.rb b/lib/weka/core/attribute.rb index 50d9ac4..35dc1dd 100644 --- a/lib/weka/core/attribute.rb +++ b/lib/weka/core/attribute.rb @@ -53,6 +53,14 @@ def values enumerate_values.to_a end + ## + # Returns the string representation of the attribute's type. + # Overwrites the weka.core.Attribute type Java method, which returns an + # integer representation of the type based on the defined type constants. + def type + self.class.type_to_string(self) + end + ## # The order of the if statements is important here, because a date is also # a numeric. From dd84ede0b7dfae68a76de04cf90bfd4db4d0785a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Paul=20Go=CC=88tze?= Date: Mon, 18 Jul 2016 08:15:17 +0200 Subject: [PATCH 10/28] Add specs for attribute type and string attribute --- spec/core/attribute_spec.rb | 100 ++++++++++++++++++++++++++---------- 1 file changed, 73 insertions(+), 27 deletions(-) diff --git a/spec/core/attribute_spec.rb b/spec/core/attribute_spec.rb index f9ae5bb..bc45011 100644 --- a/spec/core/attribute_spec.rb +++ b/spec/core/attribute_spec.rb @@ -1,8 +1,9 @@ require 'spec_helper' describe Weka::Core::Attribute do - let(:values) { %w(yes no) } + let(:values) { %w(true false) } let(:name) { 'name' } + let(:format) { 'yyyy-MM-dd HH:mm' } subject { Weka::Core::Attribute.new(name, values) } @@ -34,7 +35,7 @@ end describe '.new_date' do - subject { Weka::Core::Attribute.new_date(name, 'yyyy-MM-dd HH:mm') } + subject { Weka::Core::Attribute.new_date(name, format) } it 'returns a date Attribute' do expect(subject.date?).to be true @@ -64,85 +65,130 @@ end describe '#internal_value_of' do - context 'a numeric attribute' do - let(:attribute) { Weka::Core::Attribute.new('numeric attribute') } + context 'for a numeric attribute' do + subject { Weka::Core::Attribute.new_numeric(name) } it 'returns the value as a float' do - expect(attribute.internal_value_of(3.5)).to eq 3.5 + expect(subject.internal_value_of(3.5)).to eq 3.5 end it 'returns the value as a float if given as string' do - expect(attribute.internal_value_of('3.5')).to eq 3.5 + expect(subject.internal_value_of('3.5')).to eq 3.5 end it 'returns NaN if the given value is Float::NAN' do - expect(attribute.internal_value_of(Float::NAN)).to be Float::NAN + expect(subject.internal_value_of(Float::NAN)).to be Float::NAN end it 'returns NaN if the given value is nil' do - expect(attribute.internal_value_of(nil)).to be Float::NAN + expect(subject.internal_value_of(nil)).to be Float::NAN end it 'returns NaN if the given value is "?"' do - expect(attribute.internal_value_of('?')).to be Float::NAN + expect(subject.internal_value_of('?')).to be Float::NAN end end - context 'a nominal attribute' do - let(:attribute) { Weka::Core::Attribute.new('class', %w(true false)) } + context 'for a nominal attribute' do + subject { Weka::Core::Attribute.new_nominal(name, values) } it 'returns the correct internal index' do - expect(attribute.internal_value_of('true')).to eq 0 - expect(attribute.internal_value_of('false')).to eq 1 + expect(subject.internal_value_of('true')).to eq 0 + expect(subject.internal_value_of('false')).to eq 1 end it 'returns the correct internal index as given as a non-String' do - expect(attribute.internal_value_of(true)).to eq 0 - expect(attribute.internal_value_of(false)).to eq 1 + expect(subject.internal_value_of(true)).to eq 0 + expect(subject.internal_value_of(false)).to eq 1 - expect(attribute.internal_value_of(:true)).to eq 0 - expect(attribute.internal_value_of(:false)).to eq 1 + expect(subject.internal_value_of(:true)).to eq 0 + expect(subject.internal_value_of(:false)).to eq 1 end it 'returns NaN if the given value is Float::NAN' do - expect(attribute.internal_value_of(Float::NAN)).to be Float::NAN + expect(subject.internal_value_of(Float::NAN)).to be Float::NAN end it 'returns NaN if the given value is nil' do - expect(attribute.internal_value_of(nil)).to be Float::NAN + expect(subject.internal_value_of(nil)).to be Float::NAN end it 'returns NaN if the given value is "?"' do - expect(attribute.internal_value_of('?')).to be Float::NAN + expect(subject.internal_value_of('?')).to be Float::NAN end end - context 'a data attribute' do - let(:attribute) { Weka::Core::Attribute.new('date', 'yyyy-MM-dd HH:mm') } + context 'for a data attribute' do let(:datetime) { '2015-12-24 11:11' } let(:unix_timestamp) { 1_450_955_460_000.0 } + subject { Weka::Core::Attribute.new_date(name, format) } + before do - allow(attribute) + allow(subject) .to receive(:parse_date) .with(datetime) .and_return(unix_timestamp) end it 'returns the right date timestamp value' do - expect(attribute.internal_value_of(datetime)).to eq unix_timestamp + expect(subject.internal_value_of(datetime)).to eq unix_timestamp end it 'returns NaN if the given value is Float::NAN' do - expect(attribute.internal_value_of(Float::NAN)).to be Float::NAN + expect(subject.internal_value_of(Float::NAN)).to be Float::NAN end it 'returns NaN if the given value is nil' do - expect(attribute.internal_value_of(nil)).to be Float::NAN + expect(subject.internal_value_of(nil)).to be Float::NAN end it 'returns NaN if the given value is "?"' do - expect(attribute.internal_value_of('?')).to be Float::NAN + expect(subject.internal_value_of('?')).to be Float::NAN + end + end + end + + describe '#type' do + context 'for a numeric attribute' do + subject { Weka::Core::Attribute.new_numeric(name) } + + it 'returns "numeric"' do + expect(subject.type).to eq 'numeric' + end + end + + context 'for a nominal attribute' do + subject { Weka::Core::Attribute.new_nominal(name, values) } + + it 'returns "nominal"' do + expect(subject.type).to eq 'nominal' + end + end + + xcontext 'for a string attribute' do + subject { Weka::Core::Attribute.new_string(name) } + + it 'returns "string"' do + expect(subject.type).to eq 'string' + end + end + + context 'for a data attribute' do + let(:datetime) { '2015-12-24 11:11' } + let(:unix_timestamp) { 1_450_955_460_000.0 } + + subject { Weka::Core::Attribute.new_date(name, format) } + + before do + allow(subject) + .to receive(:parse_date) + .with(datetime) + .and_return(unix_timestamp) + end + + it 'returns "date"' do + expect(subject.type).to eq 'date' end end end From f6fd168c49df2a055f5224ff126435f44ffc2797 Mon Sep 17 00:00:00 2001 From: Kai-Chun Ning Date: Fri, 2 Dec 2016 19:47:07 +0100 Subject: [PATCH 11/28] feature/string-attributes: fixed issue#12 --- lib/weka/core/attribute.rb | 19 ++++++++++++++++++- spec/core/attribute_spec.rb | 4 ++-- 2 files changed, 20 insertions(+), 3 deletions(-) diff --git a/lib/weka/core/attribute.rb b/lib/weka/core/attribute.rb index 35dc1dd..9838449 100644 --- a/lib/weka/core/attribute.rb +++ b/lib/weka/core/attribute.rb @@ -39,13 +39,19 @@ def new_date(name, format) # # Thus, we use refelection here and call the contructor explicitly, see # https://github.com/jruby/jruby/wiki/CallingJavaFromJRuby#constructors + # + # The object return from Java constructor only has class + # Java::JavaObject so we need to cast it to the proper class + # + # See also: + # https://stackoverflow.com/questions/1792495/casting-objects-in-jruby def new_string(name) constructor = Attribute.java_class.declared_constructor( java.lang.String, java.util.List ) - constructor.new_instance(name.to_s, nil) + constructor.new_instance(name.to_s, nil).to_java(Attribute) end end @@ -70,6 +76,17 @@ def internal_value_of(value) return parse_date(value.to_s) if date? return value.to_f if numeric? return index_of_value(value.to_s) if nominal? + + if string? + # string has unlimited range of possible values. We check if + # it has been added. If yes then we simply return the index + if (idx = index_of_value(value.to_s)) != -1 + idx + else + # else we add the value to the range and return its new index + add_string_value(value.to_s) + end + end end end end diff --git a/spec/core/attribute_spec.rb b/spec/core/attribute_spec.rb index bc45011..c54c875 100644 --- a/spec/core/attribute_spec.rb +++ b/spec/core/attribute_spec.rb @@ -46,7 +46,7 @@ end end - xdescribe '.new_string' do + describe '.new_string' do subject { Weka::Core::Attribute.new_string(name) } it 'returns a string Attribute' do @@ -166,7 +166,7 @@ end end - xcontext 'for a string attribute' do + context 'for a string attribute' do subject { Weka::Core::Attribute.new_string(name) } it 'returns "string"' do From 109f21a94de26b4a7d656318eba29e1c5b7d9ad8 Mon Sep 17 00:00:00 2001 From: Kai-Chun Ning Date: Sat, 3 Dec 2016 14:57:08 +0100 Subject: [PATCH 12/28] feature/string-attributes: refactored Attribute --- lib/weka/core/attribute.rb | 22 +++++++++++----------- 1 file changed, 11 insertions(+), 11 deletions(-) diff --git a/lib/weka/core/attribute.rb b/lib/weka/core/attribute.rb index 9838449..a0ccbf8 100644 --- a/lib/weka/core/attribute.rb +++ b/lib/weka/core/attribute.rb @@ -40,7 +40,7 @@ def new_date(name, format) # Thus, we use refelection here and call the contructor explicitly, see # https://github.com/jruby/jruby/wiki/CallingJavaFromJRuby#constructors # - # The object return from Java constructor only has class + # The object return from Java constructor only has class # Java::JavaObject so we need to cast it to the proper class # # See also: @@ -76,17 +76,17 @@ def internal_value_of(value) return parse_date(value.to_s) if date? return value.to_f if numeric? return index_of_value(value.to_s) if nominal? + return index_of_string(value) if string? + end - if string? - # string has unlimited range of possible values. We check if - # it has been added. If yes then we simply return the index - if (idx = index_of_value(value.to_s)) != -1 - idx - else - # else we add the value to the range and return its new index - add_string_value(value.to_s) - end - end + private + + def index_of_string(value) + # string has unlimited range of possible values. We check if + # it has been added. If yes then we simply return the index + # else we add the value to the range and return its new index + index = index_of_value(value.to_s) + index != -1 ? index : add_string_value(value.to_s) end end end From 1a3392d17a94472c7f9df2bdd65b1f1938a1e3cb Mon Sep 17 00:00:00 2001 From: Kai-Chun Ning Date: Sat, 3 Dec 2016 16:36:26 +0100 Subject: [PATCH 13/28] feature/string-attributes: add spec for Attribute#internal_value_of() --- spec/core/attribute_spec.rb | 42 +++++++++++++++++++++++++++++++++++++ 1 file changed, 42 insertions(+) diff --git a/spec/core/attribute_spec.rb b/spec/core/attribute_spec.rb index c54c875..559e9ed 100644 --- a/spec/core/attribute_spec.rb +++ b/spec/core/attribute_spec.rb @@ -147,6 +147,48 @@ expect(subject.internal_value_of('?')).to be Float::NAN end end + + context 'for a string attribute' do + let(:string_values) { ['first_string', 'second_string'] } + let(:phantom_string_value) { 'i_do_not_exist' } + + subject do + attribute = Weka::Core::Attribute.new_string(name) + string_values.each { |value| attribute.add_string_value(value) } + attribute + end + + it 'returns the correct internal index' do + expect(subject.internal_value_of(string_values[0])).to eq 0 + expect(subject.internal_value_of(string_values[1])).to eq 1 + end + + it 'returns -1 as internal index for non-existent string values' do + expect(subject.internal_value_of(phantom_string_value)).to eq(-1) + end + + it 'returns the correct internal index as given as a non-String' do + expect(subject.internal_value_of(:first_string)).to eq 0 + expect(subject.internal_value_of(:second_string)).to eq 1 + end + + it 'returns -1 as internal index for non-existent non-String values' do + expect(subject.internal_value_of(:phantom_string_value)).to eq(-1) + end + + it 'returns NaN if the given value is Float::NAN' do + expect(subject.internal_value_of(Float::NAN)).to be Float::NAN + end + + it 'returns NaN if the given value is nil' do + expect(subject.internal_value_of(nil)).to be Float::NAN + end + + it 'returns NaN if the given value is "?"' do + expect(subject.internal_value_of('?')).to be Float::NAN + end + + end end describe '#type' do From 7ad78b80b492dac592b23897d8fabe3677bae737 Mon Sep 17 00:00:00 2001 From: Kai-Chun Ning Date: Sat, 3 Dec 2016 16:38:57 +0100 Subject: [PATCH 14/28] feature/string-attributes: bug fix Attribute#add_string_value() should not be called inside Attribute#internal_value_of(). The method call is moved into Instances#instance_from(). --- lib/weka/core/attribute.rb | 12 +----------- lib/weka/core/instances.rb | 10 ++++++++++ 2 files changed, 11 insertions(+), 11 deletions(-) diff --git a/lib/weka/core/attribute.rb b/lib/weka/core/attribute.rb index a0ccbf8..7d2e58e 100644 --- a/lib/weka/core/attribute.rb +++ b/lib/weka/core/attribute.rb @@ -76,17 +76,7 @@ def internal_value_of(value) return parse_date(value.to_s) if date? return value.to_f if numeric? return index_of_value(value.to_s) if nominal? - return index_of_string(value) if string? - end - - private - - def index_of_string(value) - # string has unlimited range of possible values. We check if - # it has been added. If yes then we simply return the index - # else we add the value to the range and return its new index - index = index_of_value(value.to_s) - index != -1 ? index : add_string_value(value.to_s) + return index_of_value(value.to_s) if string? end end end diff --git a/lib/weka/core/instances.rb b/lib/weka/core/instances.rb index 66e84b1..c522e72 100644 --- a/lib/weka/core/instances.rb +++ b/lib/weka/core/instances.rb @@ -226,6 +226,16 @@ def instance_from(instance_or_values, weight:) instance_or_values else data = internal_values_of(instance_or_values) + # string attribute has unlimited range of possible values. + # Check the return index, if it is -1 then add the value to + # the attribute before creating the instance + data.map!.with_index do |value, index| + if value == -1 and attribute(index).string? + attribute(index).add_string_value(instance_or_values[index].to_s) + else + value + end + end DenseInstance.new(data, weight: weight) end end From b44ee9b786b85a9b70212e6fa489a4fc1a87d6a8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Paul=20G=C3=B6tze?= Date: Sun, 4 Dec 2016 11:59:09 +0100 Subject: [PATCH 15/28] Minor style changes to please Rubocop --- lib/weka/core/attribute.rb | 3 +-- lib/weka/core/instances.rb | 4 +++- spec/core/attribute_spec.rb | 5 ++--- 3 files changed, 6 insertions(+), 6 deletions(-) diff --git a/lib/weka/core/attribute.rb b/lib/weka/core/attribute.rb index 7d2e58e..5a02d2b 100644 --- a/lib/weka/core/attribute.rb +++ b/lib/weka/core/attribute.rb @@ -75,8 +75,7 @@ def internal_value_of(value) 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? - return index_of_value(value.to_s) if string? + return index_of_value(value.to_s) if nominal? || string? end end end diff --git a/lib/weka/core/instances.rb b/lib/weka/core/instances.rb index c522e72..1787c28 100644 --- a/lib/weka/core/instances.rb +++ b/lib/weka/core/instances.rb @@ -226,16 +226,18 @@ def instance_from(instance_or_values, weight:) instance_or_values else data = internal_values_of(instance_or_values) + # string attribute has unlimited range of possible values. # Check the return index, if it is -1 then add the value to # the attribute before creating the instance data.map!.with_index do |value, index| - if value == -1 and attribute(index).string? + if value == -1 && attribute(index).string? attribute(index).add_string_value(instance_or_values[index].to_s) else value end end + DenseInstance.new(data, weight: weight) end end diff --git a/spec/core/attribute_spec.rb b/spec/core/attribute_spec.rb index 559e9ed..53ac527 100644 --- a/spec/core/attribute_spec.rb +++ b/spec/core/attribute_spec.rb @@ -149,8 +149,8 @@ end context 'for a string attribute' do - let(:string_values) { ['first_string', 'second_string'] } - let(:phantom_string_value) { 'i_do_not_exist' } + let(:string_values) { %w(first_string second_string) } + let(:phantom_string_value) { 'i_do_not_exist' } subject do attribute = Weka::Core::Attribute.new_string(name) @@ -187,7 +187,6 @@ it 'returns NaN if the given value is "?"' do expect(subject.internal_value_of('?')).to be Float::NAN end - end end From 569bcea7ab9f097ac9bc977b567d0bdc363f0a87 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Paul=20G=C3=B6tze?= Date: Sun, 4 Dec 2016 13:31:11 +0100 Subject: [PATCH 16/28] Remove missed ActiveSupport dependencies --- lib/weka/class_builder.rb | 1 - lib/weka/classifiers/utils.rb | 6 ++---- spec/attribute_selection/evaluator_spec.rb | 4 ++-- 3 files changed, 4 insertions(+), 7 deletions(-) diff --git a/lib/weka/class_builder.rb b/lib/weka/class_builder.rb index adc3ad2..a842b36 100644 --- a/lib/weka/class_builder.rb +++ b/lib/weka/class_builder.rb @@ -1,4 +1,3 @@ -#require 'active_support/core_ext/module' require 'weka/concerns' module Weka diff --git a/lib/weka/classifiers/utils.rb b/lib/weka/classifiers/utils.rb index b9c7407..7e8096a 100644 --- a/lib/weka/classifiers/utils.rb +++ b/lib/weka/classifiers/utils.rb @@ -1,5 +1,3 @@ -require 'active_support/concern' -require 'active_support/core_ext/hash' require 'weka/classifiers/evaluation' require 'weka/core/instances' @@ -75,7 +73,7 @@ def distribution_for(instance_or_values) instance = classifiable_instance_from(instance_or_values) distributions = distribution_for_instance(instance) - class_distributions_from(distributions).with_indifferent_access + class_distributions_from(distributions) end end @@ -125,7 +123,7 @@ def class_distributions_from(distributions) class_values = training_instances.class_attribute.values distributions.each_with_index.reduce({}) do |result, (distribution, index)| - class_value = class_values[index].to_sym + class_value = class_values[index] result[class_value] = distribution result end diff --git a/spec/attribute_selection/evaluator_spec.rb b/spec/attribute_selection/evaluator_spec.rb index af8580d..4412ca1 100644 --- a/spec/attribute_selection/evaluator_spec.rb +++ b/spec/attribute_selection/evaluator_spec.rb @@ -20,8 +20,8 @@ end it "inherits class #{class_name} from #{super_class_name}" do - evaluator_class = "#{subject}::#{class_name}".constantize - super_class = "#{subject}::#{super_class_name}".constantize + evaluator_class = Object.module_eval("#{subject}::#{class_name}") + super_class = Object.module_eval("#{subject}::#{super_class_name}") expect(evaluator_class.new).to be_kind_of super_class end From 5797111addc04d2d073cb59b4826629d32c2392e Mon Sep 17 00:00:00 2001 From: Kai-Chun Ning Date: Fri, 9 Dec 2016 12:01:40 +0100 Subject: [PATCH 17/28] Rspec: randomize the order of examples --- .rspec | 1 + 1 file changed, 1 insertion(+) diff --git a/.rspec b/.rspec index 8c18f1a..333d91e 100644 --- a/.rspec +++ b/.rspec @@ -1,2 +1,3 @@ --format documentation --color +--order rand From 7fb2925cf63b5cb6825de12f08d57883e2b1b135 Mon Sep 17 00:00:00 2001 From: Kai-Chun Ning Date: Fri, 9 Dec 2016 12:05:17 +0100 Subject: [PATCH 18/28] Fixtures: add testbench for string attribute --- spec/support/resources/weather.string.arff | 24 ++++++++++++++++++++++ 1 file changed, 24 insertions(+) create mode 100644 spec/support/resources/weather.string.arff diff --git a/spec/support/resources/weather.string.arff b/spec/support/resources/weather.string.arff new file mode 100644 index 0000000..a1ca36e --- /dev/null +++ b/spec/support/resources/weather.string.arff @@ -0,0 +1,24 @@ +@relation weather + +@attribute outlook {sunny, overcast, rainy} +@attribute description string +@attribute temperature real +@attribute humidity real +@attribute windy {TRUE, FALSE} +@attribute play {yes, no} + +@data +sunny,'Sunny. High near 40F. Winds WNW at 15 to 25 mph.',85,85,FALSE,no +sunny,'Sunny skies. High 39F. Winds WNW at 10 to 15 mph.',80,90,FALSE,no +overcast,'Partly cloudy. Low 27F. Winds NW at 5 to 10 mph.',83,86,FALSE,yes +rainy,'Clear skies. Low 27F. Winds WNW at 10 to 15 mph.',70,96,FALSE,yes +rainy,'Cloudy and damp with rain in the morning...then becoming partly cloudy. High 58F. Winds SW at 10 to 15 mph. Chance of rain 100%.',68,80,FALSE,yes +rainy,'Cloudy early with showers for the afternoon hours. High near 45F. Winds NW at 5 to 10 mph. Chance of rain 50%.',65,70,FALSE,no +overcast,'Cloudy. High 41F. Winds SE at 5 to 10 mph.',64,65,TRUE,yes +sunny,'Sunny skies. High 39F. Winds WNW at 10 to 15 mph.',72,95,FALSE,no +sunny,'Except for a few afternoon clouds, mainly sunny. High 34F. Winds WNW at 5 to 10 mph.',69,70,FALSE,yes +rainy,'Rain showers early mixing with snow showers later in the day. Temps nearly steady in the upper 30s. Winds WNW at 5 to 10 mph. Chance of precip 40%. Snow accumulations less than one inch.',75,80,FALSE,yes +overcast,'Partly cloudy skies in the morning will give way to cloudy skies during the afternoon. High 46F. Winds NW at 25 to 30 mph.',75,70,TRUE,yes +overcast,'Partly cloudy. Low 27F. Winds NW at 5 to 10 mph.',72,90,TRUE,yes +overcast,'Considerable clouds early. Some decrease in clouds late. Low 34F. Winds light and variable',81,75,FALSE,yes +rainy,'Overcast with rain showers at times. Low 36F. Winds light and variable. Chance of rain 60%.',71,91,TRUE,no \ No newline at end of file From 8d26e3ba2fd7ad279d0ea931c605f845a22cb182 Mon Sep 17 00:00:00 2001 From: Kai-Chun Ning Date: Fri, 9 Dec 2016 12:06:30 +0100 Subject: [PATCH 19/28] DenseInstance: 1) add support for string attribute 2) add spec for string attribute --- lib/weka/core/dense_instance.rb | 2 ++ spec/core/dense_instance_spec.rb | 25 ++++++++++++++++++++++++- 2 files changed, 26 insertions(+), 1 deletion(-) diff --git a/lib/weka/core/dense_instance.rb b/lib/weka/core/dense_instance.rb index 8d9d6ad..992b1cf 100644 --- a/lib/weka/core/dense_instance.rb +++ b/lib/weka/core/dense_instance.rb @@ -63,6 +63,8 @@ def value_from(value, index) value elsif attribute.nominal? attribute.value(value) + elsif attribute.string? + attribute.value(value) end end diff --git a/spec/core/dense_instance_spec.rb b/spec/core/dense_instance_spec.rb index 966b362..995194d 100644 --- a/spec/core/dense_instance_spec.rb +++ b/spec/core/dense_instance_spec.rb @@ -26,7 +26,7 @@ describe 'instantiation' do describe 'with an Integer value' do - it 'creates a instance with only missing values' do + it 'creates an instance with only missing values' do values = Weka::Core::DenseInstance.new(2).values expect(values).to eq ['?', '?'] end @@ -65,6 +65,29 @@ expect(subject.to_a).to eq values end end + + context 'with string attribute' do + let(:values) do + ['overcast', + 'Wind increasing. A few clouds from time to time. High 32F. Winds WNW at 20 to 30 mph.', + 15.0, + 40.0, + 'TRUE', + 'no' + ] + end + + subject do + instances = load_instances('weather.string.arff') + instances.add_instance(values) + instances.class_attribute = :play + instances.instances.last + end + + it 'returns an Array with the values of the instance' do + expect(subject.to_a).to eq values + end + end end describe '#attributes' do From 50adfd59a7af017695272dededee44c04a33dbe8 Mon Sep 17 00:00:00 2001 From: Kai-Chun Ning Date: Fri, 9 Dec 2016 12:10:46 +0100 Subject: [PATCH 20/28] fixed a typo --- lib/weka/core/attribute.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/weka/core/attribute.rb b/lib/weka/core/attribute.rb index 5a02d2b..71bba71 100644 --- a/lib/weka/core/attribute.rb +++ b/lib/weka/core/attribute.rb @@ -40,7 +40,7 @@ def new_date(name, format) # Thus, we use refelection here and call the contructor explicitly, see # https://github.com/jruby/jruby/wiki/CallingJavaFromJRuby#constructors # - # The object return from Java constructor only has class + # The object returned from Java constructor only has class # Java::JavaObject so we need to cast it to the proper class # # See also: From fcf3b270174d1375e5770a81e2f90e044730aff7 Mon Sep 17 00:00:00 2001 From: Kai-Chun Ning Date: Fri, 9 Dec 2016 14:16:19 +0100 Subject: [PATCH 21/28] Instances: 1) add support for checking if a certain type of attribute exists 2) add spec for the new methods --- lib/weka/core/attribute.rb | 2 +- lib/weka/core/instances.rb | 45 +++++++++++++- spec/core/instances_spec.rb | 118 +++++++++++++++++++++++++++++++++--- 3 files changed, 154 insertions(+), 11 deletions(-) diff --git a/lib/weka/core/attribute.rb b/lib/weka/core/attribute.rb index 71bba71..6e67b25 100644 --- a/lib/weka/core/attribute.rb +++ b/lib/weka/core/attribute.rb @@ -7,7 +7,7 @@ module Core class Attribute include Weka::Concerns::Persistent - TYPES = %(numeric nominal string date).freeze + TYPES = %i(numeric nominal string date) class << self def new_numeric(name) diff --git a/lib/weka/core/instances.rb b/lib/weka/core/instances.rb index 1787c28..db40b86 100644 --- a/lib/weka/core/instances.rb +++ b/lib/weka/core/instances.rb @@ -62,9 +62,30 @@ def add_attributes(&block) self end - alias with_attributes add_attributes - alias instances_count num_instances - alias attributes_count num_attributes + alias with_attributes add_attributes + alias instances_count num_instances + alias attributes_count num_attributes + alias has_string_attribute? check_for_string_attributes + + ## Check if the instances has any attribute of the given type + # @param [String, Symbol, Integer] type type of the attribute to check + # String and Symbol argument are converted to corresponding type + # defined in Weka::Core::Attribute + # + # @example Passing String + # instances.has_attribute_type?('string') + # instances.has_attribute_type?('String') + # + # @example Passing Symbol + # instances.has_attribute_type?(:String) + # + # @example Passing Integer + # instances.has_attribute_type?(Attribute::STRING) + def has_attribute_type?(type) + type = map_attribute_type(type) unless type.is_a? Integer + return false if type.nil? + check_for_attribute_type(type) + end def each if block_given? @@ -241,6 +262,24 @@ def instance_from(instance_or_values, weight:) DenseInstance.new(data, weight: weight) end end + + def map_attribute_type(type) + type = type.downcase.to_sym + return nil unless Attribute::TYPES.include? type + + case type + when :numeric + Attribute::NUMERIC + when :nominal + Attribute::NOMINAL + when :string + Attribute::STRING + when :date + Attribute::DATE + else + # error, ring the bell? + end + end end Java::WekaCore::Instances.__persistent__ = true diff --git a/spec/core/instances_spec.rb b/spec/core/instances_spec.rb index fdfaa14..8a96318 100644 --- a/spec/core/instances_spec.rb +++ b/spec/core/instances_spec.rb @@ -37,13 +37,14 @@ let(:instances) { described_class.new } { - numeric: :add_numeric_attribute, - string: :add_string_attribute, - nominal: :add_nominal_attribute, - date: :add_date_attribute, - add_attributes: :with_attributes, - instances_count: :num_instances, - attributes_count: :num_attributes + numeric: :add_numeric_attribute, + string: :add_string_attribute, + nominal: :add_nominal_attribute, + date: :add_date_attribute, + add_attributes: :with_attributes, + instances_count: :num_instances, + attributes_count: :num_attributes, + has_string_attribute?: :check_for_string_attributes }.each do |method, alias_method| it "defines the alias ##{alias_method} for ##{method}" do expect(instances.method(method)).to eq instances.method(alias_method) @@ -173,6 +174,13 @@ instances.string(name) expect(instances.attributes.first).to be_string end + + context 'with the class_attribute option' do + it 'defines the attribute as class attribute' do + instances.string(name, class_attribute: true) + expect(instances.class_attribute.name).to eq name + end + end end describe '#nominal' do @@ -545,4 +553,100 @@ end end end + + describe '#has_string_attribute?' do + it 'returns false if no string attribute exists' do + expect(subject.has_string_attribute?).to be false + end + + context 'dataset has string attribute' do + subject { load_instances('weather.string.arff') } + + it 'returns true if string attribute exists' do + expect(subject.has_string_attribute?).to be true + end + end + end + + describe '#has_attribute_type?' do + subject { load_instances('weather.string.arff') } + let(:type) { 'nominal' } + + it 'calls the underlying Java method .check_for_attribute_type' do + expect(subject) + .to receive(:check_for_attribute_type) + .with(subject.send(:map_attribute_type, type)) + + subject.has_attribute_type?(type) + end + + context 'checking with String argument' do + %w(string numeric nominal date).each do |type| + if type == 'date' + it 'returns false if the attribute type does not exist' do + expect(subject.has_attribute_type?(type)).to be false + end + else + it 'returns true if the attribute type exists' do + expect(subject.has_attribute_type?(type)).to be true + end + end + end + + it 'handles attribute type in uppercase' do + expect(subject.has_attribute_type?('STRING')).to be true + end + + it 'returns false for undefined attribute type' do + expect(subject.has_attribute_type?('I_DO_NOT_EXIST')).to be false + end + end + + context 'checking with Symbol argument' do + Weka::Core::Attribute::TYPES.each do |type| + if type == :date + it 'returns false if the attribute type does not exist' do + expect(subject.has_attribute_type?(type)).to be false + end + else + it 'returns true if the attribute type exists' do + expect(subject.has_attribute_type?(type)).to be true + end + end + end + + it 'handles attribute type in uppercase' do + expect(subject.has_attribute_type?(:STRING)).to be true + end + + it 'returns false for undefined attribute type' do + expect(subject.has_attribute_type?(:I_DO_NOT_EXIST)).to be false + end + end + + context 'checking with Integer argument' do + attribute_types = [ + Weka::Core::Attribute::NUMERIC, + Weka::Core::Attribute::NOMINAL, + Weka::Core::Attribute::STRING, + Weka::Core::Attribute::DATE + ] + + attribute_types.each do |type| + if type == Weka::Core::Attribute::DATE + it 'returns false if the attribute type does not exist' do + expect(subject.has_attribute_type?(type)).to be false + end + else + it 'returns true if the attribute type exists' do + expect(subject.has_attribute_type?(type)).to be true + end + end + end + + it 'returns false for undefined attribute type' do + expect(subject.has_attribute_type?(1000)).to be false + end + end + end end From 709b367021604322e699fe6ccebf54b17d482bdb Mon Sep 17 00:00:00 2001 From: Kai-Chun Ning Date: Wed, 14 Dec 2016 22:19:49 +0100 Subject: [PATCH 22/28] Evaluation: add alias for to_matrix_string --- lib/weka/classifiers/evaluation.rb | 1 + spec/classifiers/evaluation_spec.rb | 3 ++- 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/lib/weka/classifiers/evaluation.rb b/lib/weka/classifiers/evaluation.rb index 7e8e9c1..f8cfa2d 100644 --- a/lib/weka/classifiers/evaluation.rb +++ b/lib/weka/classifiers/evaluation.rb @@ -11,6 +11,7 @@ class Evaluation alias summary to_summary_string alias class_details to_class_details_string + alias confusion_matrix to_matrix_string alias instance_count num_instances alias correct_count correct diff --git a/spec/classifiers/evaluation_spec.rb b/spec/classifiers/evaluation_spec.rb index 2bb9f54..601b053 100644 --- a/spec/classifiers/evaluation_spec.rb +++ b/spec/classifiers/evaluation_spec.rb @@ -27,7 +27,8 @@ unclassified_count: :unclassified, unclassified_percentage: :pct_unclassified, weighted_f_measure: :weighted_fmeasure, - cumulative_margin_distribution: :toCumulativeMarginDistributionString + cumulative_margin_distribution: :toCumulativeMarginDistributionString, + confusion_matrix: :to_matrix_string }.each do |alias_method, method| it "defines the alias ##{alias_method} for ##{method}" do expect(subject.method(method)).to eq subject.method(alias_method) From 0fc8c0dd8f209c1597bd0ff3bec883e9a05d609c Mon Sep 17 00:00:00 2001 From: Kai-Chun Ning Date: Tue, 20 Dec 2016 16:35:16 +0100 Subject: [PATCH 23/28] minor fix: keep it DRY --- lib/weka/core/attribute.rb | 2 +- lib/weka/core/dense_instance.rb | 4 +--- lib/weka/core/instances.rb | 27 +++++++-------------------- 3 files changed, 9 insertions(+), 24 deletions(-) diff --git a/lib/weka/core/attribute.rb b/lib/weka/core/attribute.rb index 6e67b25..93dfaa5 100644 --- a/lib/weka/core/attribute.rb +++ b/lib/weka/core/attribute.rb @@ -7,7 +7,7 @@ module Core class Attribute include Weka::Concerns::Persistent - TYPES = %i(numeric nominal string date) + TYPES = %i(numeric nominal string date).freeze class << self def new_numeric(name) diff --git a/lib/weka/core/dense_instance.rb b/lib/weka/core/dense_instance.rb index 992b1cf..2332b23 100644 --- a/lib/weka/core/dense_instance.rb +++ b/lib/weka/core/dense_instance.rb @@ -61,9 +61,7 @@ def value_from(value, index) format_date(value, attribute.date_format) elsif attribute.numeric? value - elsif attribute.nominal? - attribute.value(value) - elsif attribute.string? + elsif attribute.nominal? || attribute.string? attribute.value(value) end end diff --git a/lib/weka/core/instances.rb b/lib/weka/core/instances.rb index db40b86..29399fa 100644 --- a/lib/weka/core/instances.rb +++ b/lib/weka/core/instances.rb @@ -62,10 +62,10 @@ def add_attributes(&block) self end - alias with_attributes add_attributes - alias instances_count num_instances - alias attributes_count num_attributes - alias has_string_attribute? check_for_string_attributes + alias with_attributes add_attributes + alias instances_count num_instances + alias attributes_count num_attributes + alias has_string_attribute? check_for_string_attributes ## Check if the instances has any attribute of the given type # @param [String, Symbol, Integer] type type of the attribute to check @@ -82,7 +82,7 @@ def add_attributes(&block) # @example Passing Integer # instances.has_attribute_type?(Attribute::STRING) def has_attribute_type?(type) - type = map_attribute_type(type) unless type.is_a? Integer + type = map_attribute_type(type) unless type.is_a?(Integer) return false if type.nil? check_for_attribute_type(type) end @@ -264,21 +264,8 @@ def instance_from(instance_or_values, weight:) end def map_attribute_type(type) - type = type.downcase.to_sym - return nil unless Attribute::TYPES.include? type - - case type - when :numeric - Attribute::NUMERIC - when :nominal - Attribute::NOMINAL - when :string - Attribute::STRING - when :date - Attribute::DATE - else - # error, ring the bell? - end + return unless Attribute::TYPES.include?(type.downcase.to_sym) + Attribute.const_get(type.upcase) end end From 0a92a21ec02e70600c73b2f853f8864fc350fbc5 Mon Sep 17 00:00:00 2001 From: Kai-Chun Ning Date: Tue, 20 Dec 2016 17:00:13 +0100 Subject: [PATCH 24/28] minor fix: make spec more verbose --- spec/core/instances_spec.rb | 18 ++++++++++-------- spec/support/resources/weather.string.arff | 2 +- 2 files changed, 11 insertions(+), 9 deletions(-) diff --git a/spec/core/instances_spec.rb b/spec/core/instances_spec.rb index 8a96318..35e4e0b 100644 --- a/spec/core/instances_spec.rb +++ b/spec/core/instances_spec.rb @@ -555,14 +555,16 @@ end describe '#has_string_attribute?' do - it 'returns false if no string attribute exists' do - expect(subject.has_string_attribute?).to be false + context 'if no string attribute exists' do + it 'returns false' do + expect(subject.has_string_attribute?).to be false + end end - context 'dataset has string attribute' do + context 'if dataset has string attribute' do subject { load_instances('weather.string.arff') } - it 'returns true if string attribute exists' do + it 'returns true' do expect(subject.has_string_attribute?).to be true end end @@ -580,8 +582,8 @@ subject.has_attribute_type?(type) end - context 'checking with String argument' do - %w(string numeric nominal date).each do |type| + context 'when given String argument' do + Weka::Core::Attribute::TYPES.map(&:to_s).each do |type| if type == 'date' it 'returns false if the attribute type does not exist' do expect(subject.has_attribute_type?(type)).to be false @@ -602,7 +604,7 @@ end end - context 'checking with Symbol argument' do + context 'when given Symbol argument' do Weka::Core::Attribute::TYPES.each do |type| if type == :date it 'returns false if the attribute type does not exist' do @@ -624,7 +626,7 @@ end end - context 'checking with Integer argument' do + context 'when given Integer argument' do attribute_types = [ Weka::Core::Attribute::NUMERIC, Weka::Core::Attribute::NOMINAL, diff --git a/spec/support/resources/weather.string.arff b/spec/support/resources/weather.string.arff index a1ca36e..158a688 100644 --- a/spec/support/resources/weather.string.arff +++ b/spec/support/resources/weather.string.arff @@ -21,4 +21,4 @@ rainy,'Rain showers early mixing with snow showers later in the day. Temps nearl overcast,'Partly cloudy skies in the morning will give way to cloudy skies during the afternoon. High 46F. Winds NW at 25 to 30 mph.',75,70,TRUE,yes overcast,'Partly cloudy. Low 27F. Winds NW at 5 to 10 mph.',72,90,TRUE,yes overcast,'Considerable clouds early. Some decrease in clouds late. Low 34F. Winds light and variable',81,75,FALSE,yes -rainy,'Overcast with rain showers at times. Low 36F. Winds light and variable. Chance of rain 60%.',71,91,TRUE,no \ No newline at end of file +rainy,'Overcast with rain showers at times. Low 36F. Winds light and variable. Chance of rain 60%.',71,91,TRUE,no From 09daddaba35f54b18690f44473359d8f7f73acf1 Mon Sep 17 00:00:00 2001 From: Kai-Chun Ning Date: Tue, 20 Dec 2016 17:03:30 +0100 Subject: [PATCH 25/28] Fixtures: add missing EOFEL --- spec/support/resources/weather.string.arff | 1 + 1 file changed, 1 insertion(+) diff --git a/spec/support/resources/weather.string.arff b/spec/support/resources/weather.string.arff index 158a688..1dac96a 100644 --- a/spec/support/resources/weather.string.arff +++ b/spec/support/resources/weather.string.arff @@ -22,3 +22,4 @@ overcast,'Partly cloudy skies in the morning will give way to cloudy skies durin overcast,'Partly cloudy. Low 27F. Winds NW at 5 to 10 mph.',72,90,TRUE,yes overcast,'Considerable clouds early. Some decrease in clouds late. Low 34F. Winds light and variable',81,75,FALSE,yes rainy,'Overcast with rain showers at times. Low 36F. Winds light and variable. Chance of rain 60%.',71,91,TRUE,no + From d64de778437cd67c933845fb1901e839b487fe5e Mon Sep 17 00:00:00 2001 From: Kai-Chun Ning Date: Thu, 22 Dec 2016 13:47:46 +0100 Subject: [PATCH 26/28] Instances: remove redundant statement --- lib/weka/core/instances.rb | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/lib/weka/core/instances.rb b/lib/weka/core/instances.rb index 29399fa..f098c51 100644 --- a/lib/weka/core/instances.rb +++ b/lib/weka/core/instances.rb @@ -83,7 +83,6 @@ def add_attributes(&block) # instances.has_attribute_type?(Attribute::STRING) def has_attribute_type?(type) type = map_attribute_type(type) unless type.is_a?(Integer) - return false if type.nil? check_for_attribute_type(type) end @@ -264,7 +263,7 @@ def instance_from(instance_or_values, weight:) end def map_attribute_type(type) - return unless Attribute::TYPES.include?(type.downcase.to_sym) + return -1 unless Attribute::TYPES.include?(type.downcase.to_sym) Attribute.const_get(type.upcase) end end From 3b59edc2a0199f37ef492ef1c567918aad55dbe3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Paul=20G=C3=B6tze?= Date: Thu, 22 Dec 2016 20:16:55 +0100 Subject: [PATCH 27/28] Bump version to 0.4.0 --- lib/weka/version.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/weka/version.rb b/lib/weka/version.rb index 13b997f..af7625d 100644 --- a/lib/weka/version.rb +++ b/lib/weka/version.rb @@ -1,3 +1,3 @@ module Weka - VERSION = '0.3.0'.freeze + VERSION = '0.4.0'.freeze end From 042e5b8603c11ba2a683eafb7e0f988655ef0475 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Paul=20G=C3=B6tze?= Date: Thu, 22 Dec 2016 20:17:32 +0100 Subject: [PATCH 28/28] Add hint on Rubocop usage for code style recommendations --- README.md | 3 +++ 1 file changed, 3 insertions(+) diff --git a/README.md b/README.md index f17f344..acb6708 100644 --- a/README.md +++ b/README.md @@ -59,6 +59,9 @@ Here’s how to contribute: Please try to add RSpec tests along with your new features. This will ensure that your code does not break existing functionality and that your feature is working as expected. +We use [Rubocop](https://github.com/bbatsov/rubocop) for code style recommendations. +Please make sure your contributions comply with the default config of Rubocop. + ## Acknowledgement The original ideas for wrapping Weka in JRuby come from [@arrigonialberto86](https://github.com/arrigonialberto86) and his [ruby-band](https://github.com/arrigonialberto86/ruby-band) gem. Great thanks!