Class: Treat::Learning::Problem

Inherits:
Object
  • Object
show all
Defined in:
lib/treat/learning/problem.rb

Overview

Defines a classification problem.

  • What question are we trying to answer?

  • What features are we going to look at to attempt to answer that question?

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(question, *exports) ⇒ Problem

Initialize the problem with a question and an arbitrary number of features. # FIXME: init with id!?



22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
# File 'lib/treat/learning/problem.rb', line 22

def initialize(question, *exports)
  unless question.is_a?(Treat::Learning::Question)
    raise Treat::Exception,
    "The first argument to initialize " +
    "should be an instance of " +
    "Treat::Learning::Question."
  end
  if exports.any? { |f| !f.is_a?(Treat::Learning::Export) }
    raise Treat::Exception,
    "The second argument and all subsequent ones " +
    "to initialize should be instances of subclasses " +
    "of Treat::Learning::Export."
  end
  @question, @id = question, object_id
  @features = exports.select do |exp|
    exp.is_a?(Treat::Learning::Feature)
  end
  if @features.size == 0
    raise Treat::Exception, 
    "Problem should be supplied with at least "+
    "one feature to work with."
  end
  @tags = exports.select do |exp|
    exp.is_a?(Treat::Learning::Tag)
  end
  @feature_labels = @features.map { |f| f.name }
  @tag_labels = @tags.map { |t| t.name }
end

Instance Attribute Details

#feature_labelsObject (readonly)

Just the labels from the features.



17
18
19
# File 'lib/treat/learning/problem.rb', line 17

def feature_labels
  @feature_labels
end

#featuresObject (readonly)

An array of features that will be looked at in trying to answer the problem’s question.



14
15
16
# File 'lib/treat/learning/problem.rb', line 14

def features
  @features
end

#idObject

A unique identifier for the problem.



8
9
10
# File 'lib/treat/learning/problem.rb', line 8

def id
  @id
end

#questionObject (readonly)

The question we are trying to answer.



10
11
12
# File 'lib/treat/learning/problem.rb', line 10

def question
  @question
end

#tag_labelsObject (readonly)

Returns the value of attribute tag_labels.



18
19
20
# File 'lib/treat/learning/problem.rb', line 18

def tag_labels
  @tag_labels
end

#tagsObject (readonly)

Returns the value of attribute tags.



15
16
17
# File 'lib/treat/learning/problem.rb', line 15

def tags
  @tags
end

Class Method Details

.from_hash(hash) ⇒ Object



117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
# File 'lib/treat/learning/problem.rb', line 117

def self.from_hash(hash)
  question = Treat::Learning::Question.new(
    hash['question']['name'], 
    hash['question']['target'],
    hash['question']['default'],
    hash['question']['type']
  )
  features = []
  hash['features'].each do |feature|
    features << Treat::Learning::Feature.new(
    feature['name'], feature['default'],
    feature['proc_string'])
  end
  tags = []
  hash['tags'].each do |tag|
    tags << Treat::Learning::Tag.new(
    tag['name'], tag['default'],
    tag['proc_string'])
  end
  features_and_tags = features + tags
  p = Treat::Learning::Problem.new(question, *features_and_tags)
  p.id = hash['id']
  p
end

Instance Method Details

#==(problem) ⇒ Object

Custom comparison for problems. Should we check for ID here ? FIXME



53
54
55
56
57
# File 'lib/treat/learning/problem.rb', line 53

def ==(problem)
  @question == problem.question &&
  @features == problem.features &&
  @tags == problem.tags
end

#export(entity, exports) ⇒ Object



81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
# File 'lib/treat/learning/problem.rb', line 81

def export(entity, exports)
  unless @question.target == entity.type
    targ, type = @question.target, entity.type
    raise Treat::Exception, 
    "This classification problem targets " +
    "#{targ}s, but a(n) #{type} " +
    "was passed to export instead."
  end
  ret = []
  exports.each do |export|
    r = export.proc ? 
    export.proc.call(entity) : 
    entity.send(export.name)
    ret << (r || export.default)
  end
  ret
end

#export_features(e, include_answer = true) ⇒ Object

Return an array of all the entity’s features, as defined by the problem. If include_answer is set to true, will append the answer to the problem after all of the features.



64
65
66
67
68
69
70
# File 'lib/treat/learning/problem.rb', line 64

def export_features(e, include_answer = true)
  features = export(e, @features)
  return features if !include_answer
  features << (e.has?(@question.name) ? 
  e.get(@question.name) : @question.default)
  features
end

#export_tags(entity) ⇒ Object



72
73
74
75
76
77
78
79
# File 'lib/treat/learning/problem.rb', line 72

def export_tags(entity)
  if @tags.empty?
    raise Treat::Exception,
    "Cannot export the tags, because " +
    "this problem doesn't have any."
  end
  export(entity, @tags)
end

#object_to_hash(obj) ⇒ Object



108
109
110
111
112
113
114
115
# File 'lib/treat/learning/problem.rb', line 108

def object_to_hash(obj)
  hash = {}
  obj.instance_variables.each do |var|
    val = obj.instance_variable_get(var)
    hash[var.to_s.delete("@")] = val
  end
  hash
end

#to_hashObject



99
100
101
102
103
104
105
106
# File 'lib/treat/learning/problem.rb', line 99

def to_hash
  {'question' => object_to_hash(@question),
  'features' => @features.map { |f| 
  object_to_hash(f.tap { |f| f.proc = nil }) },
  'tags' => @tags.map { |t| 
  object_to_hash(t.tap { |t| t.proc = nil }) },
  'id' => @id }
end