Class: OpenTox::Model::Lazar

Inherits:
Model show all
Defined in:
lib/model.rb

Direct Known Subclasses

LazarClassification, LazarRegression

Instance Method Summary collapse

Methods inherited from Model

#training_dataset

Constructor Details

#initialize(training_dataset, params = {}) ⇒ OpenTox::Model::Lazar

Create a lazar model from a training_dataset and a feature_dataset

Parameters:



34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
# File 'lib/model.rb', line 34

def initialize training_dataset, params={}

  super params

  # TODO document convention
  prediction_feature = training_dataset.features.first
  # set defaults for empty parameters
  self.prediction_feature_id ||= prediction_feature.id
  self.training_dataset_id ||= training_dataset.id
  self.name ||= "#{training_dataset.name} #{prediction_feature.name}" 
  self.neighbor_algorithm_parameters ||= {}
  self.neighbor_algorithm_parameters[:training_dataset_id] = training_dataset.id
  save
  self
end

Instance Method Details

#predict(object) ⇒ Object



75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
# File 'lib/model.rb', line 75

def predict object

  training_dataset = Dataset.find training_dataset_id

  # parse data
  compounds = []
  case object.class.to_s
  when "OpenTox::Compound"
    compounds = [object] 
  when "Array"
    compounds = object
  when "OpenTox::Dataset"
    compounds = object.compounds
  else 
    bad_request_error "Please provide a OpenTox::Compound an Array of OpenTox::Compounds or an OpenTox::Dataset as parameter."
  end

  # make predictions
  predictions = []
  predictions = compounds.collect{|c| predict_compound c}

  # serialize result
  case object.class.to_s
  when "OpenTox::Compound"
    prediction = predictions.first
    prediction[:neighbors].sort!{|a,b| b[1] <=> a[1]} # sort according to similarity
    return prediction
  when "Array"
    return predictions
  when "OpenTox::Dataset"
    # prepare prediction dataset
    measurement_feature = Feature.find prediction_feature_id

    prediction_feature = OpenTox::NumericFeature.find_or_create_by( "name" => measurement_feature.name + " (Prediction)" )
    prediction_dataset = LazarPrediction.new(
      :name => "Lazar prediction for #{prediction_feature.name}",
      :creator =>  __FILE__,
      :prediction_feature_id => prediction_feature.id

    )
    confidence_feature = OpenTox::NumericFeature.find_or_create_by( "name" => "Model RMSE" )
    warning_feature = OpenTox::NominalFeature.find_or_create_by("name" => "Warnings")
    prediction_dataset.features = [ prediction_feature, confidence_feature, measurement_feature, warning_feature ]
    prediction_dataset.compounds = compounds
    prediction_dataset.data_entries = predictions.collect{|p| [p[:value], p[:rmse] , p[:dataset_activities].to_s, p[:warning]]}
    prediction_dataset.save
    return prediction_dataset
  end

end

#predict_compound(compound) ⇒ Object



50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
# File 'lib/model.rb', line 50

def predict_compound compound
  prediction_feature = Feature.find prediction_feature_id
  neighbors = compound.send(neighbor_algorithm, neighbor_algorithm_parameters)
  # remove neighbors without prediction_feature
  # check for database activities (neighbors may include query compound)
  database_activities = nil
  prediction = {}
  if neighbors.collect{|n| n["_id"]}.include? compound.id

    database_activities = neighbors.select{|n| n["_id"] == compound.id}.first["features"][prediction_feature.id.to_s].uniq
    prediction[:database_activities] = database_activities
    prediction[:warning] = "#{database_activities.size} compounds have been removed from neighbors, because they have the same structure as the query compound."
    neighbors.delete_if{|n| n["_id"] == compound.id}
  end
  neighbors.delete_if{|n| n['features'].empty? or n['features'][prediction_feature.id.to_s] == [nil] }
  if neighbors.empty?
    prediction.merge!({:value => nil,:confidence => nil,:warning => "Could not find similar compounds with experimental data in the training dataset.",:neighbors => []})
  else
    prediction.merge!(Algorithm.run(prediction_algorithm, compound, {:neighbors => neighbors,:training_dataset_id=> training_dataset_id,:prediction_feature_id => prediction_feature.id}))
    prediction[:neighbors] = neighbors
    prediction[:neighbors] ||= []
  end
  prediction
end

#training_activitiesObject



126
127
128
129
# File 'lib/model.rb', line 126

def training_activities
  i = training_dataset.feature_ids.index prediction_feature_id
  training_dataset.data_entries.collect{|de| de[i]}
end