Module: Abstractor::Methods::Models::AbstractorSubject::InstanceMethods
- Included in:
- AbstractorSubject
- Defined in:
- lib/abstractor/methods/models/abstractor_subject.rb
Instance Method Summary collapse
-
#abstract(about) ⇒ void
Creates or finds an instance of an Abstractor::AbstractorAbstraction.
- #abstract_canonical_name_value(about, abstractor_abstraction, abstractor_abstraction_source) ⇒ Object
-
#abstract_custom_nlp_suggestion(about, abstractor_abstraction, abstractor_abstraction_source) ⇒ void
Looks up a suggestion endpoint to submit text to an external custom NLP provider for the delegation of suggestion generation.
-
#abstract_custom_suggestion(about, abstractor_abstraction, abstractor_abstraction_source) ⇒ void
Creates instances of Abstractor::AbstractorSuggestion and Abstractor::AbstractorSuggestionSource based on calling the method configured by the AbstractorAbstractionSource#custom_method attribute.
-
#abstract_indirect_source(about, abstractor_abstraction, abstractor_abstraction_source) ⇒ void
Creates an instance of Abstractor::AbstractorIndirectSource – if one does not already exist – for the abstractor_abstraction and abstraction_source parameters.
- #abstract_name_value(about, abstractor_abstraction, abstractor_abstraction_source) ⇒ Object
-
#abstract_nlp_suggestion(about, abstractor_abstraction, abstractor_abstraction_source) ⇒ void
Creates instances of Abstractor::AbstractorSuggestion and Abstractor::AbstractorSuggestionSource based on natural languange processing (nlp).
- #abstract_sentential_name_value(about, abstractor_abstraction, abstractor_abstraction_source) ⇒ Object
- #abstract_sentential_value(about, abstractor_abstraction, abstractor_abstraction_source) ⇒ Object
- #abstract_unknown(about, abstractor_abstraction, abstractor_abstraction_source) ⇒ Object
- #abstract_value(about, abstractor_abstraction, abstractor_abstraction_source) ⇒ Object
- #abstractor_object_value?(suggested_value) ⇒ Boolean
- #create_unknown_abstractor_suggestion(about, abstractor_abstraction, abstractor_abstraction_source) ⇒ Object
- #create_unknown_abstractor_suggestion_name_only(about, abstractor_abstraction, abstractor_abstraction_source) ⇒ Object
- #groupable? ⇒ Boolean
- #suggest(abstractor_abstraction, abstractor_abstraction_source, match_value, sentence_match_value, source_id, source_type, source_method, section_name, suggested_value, unknown, not_applicable, custom_method, custom_explanation) ⇒ Object
Instance Method Details
#abstract(about) ⇒ void
This method returns an undefined value.
Creates or finds an instance of an Abstractor::AbstractorAbstraction. The method will create instances of Abstractor::AbstractorSuggestion and Abstractor::AbstractorSuggestionSource for the abstractable entity passed via the about parameter.
The method cycles through each Abstractor::AbstractorAbstractionSource setup for the instance of the Abstractor::AbstractorSubject. The Abstractor::AbstractorSubject#abstractor_abstraction_source_type attribute determines the abstraction strategy:
-
‘nlp suggestion’: creates instances of Abstractor::AbstractorSuggestion based on natural language processing (nlp) logic searching the text provided by the Abstractor::AbstractorSubject#from_methd attribute.
-
‘custom suggestion’: creates instances of Abstractor::AbstractorSuggestion based on custom logic delegated to the method configured in AbstractorAbstractionSource#custom_method.
-
‘indirect’: creates an instance of Abstractor::AbstractorIndirectSource wih null source_type, source_id, source_method attributes – all waiting to be set upon selection of an indirect source.
-
‘custom nlp suggestion’: looks up a suggestion endpoint to submit text, object values and object value variants to an external, custom NLP provider for the delegation of suggestion generation.
45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 |
# File 'lib/abstractor/methods/models/abstractor_subject.rb', line 45 def abstract(about) abstractor_abstraction = about.find_or_create_abstractor_abstraction(abstractor_abstraction_schema, self) abstractor_abstraction_sources.each do |abstractor_abstraction_source| case abstractor_abstraction_source.abstractor_abstraction_source_type.name when 'nlp suggestion' abstract_nlp_suggestion(about, abstractor_abstraction, abstractor_abstraction_source) when 'custom suggestion' abstract_custom_suggestion(about, abstractor_abstraction, abstractor_abstraction_source) when 'indirect' abstract_indirect_source(about, abstractor_abstraction, abstractor_abstraction_source) when 'custom nlp suggestion' abstract_custom_nlp_suggestion(about, abstractor_abstraction, abstractor_abstraction_source) end end end |
#abstract_canonical_name_value(about, abstractor_abstraction, abstractor_abstraction_source) ⇒ Object
248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 |
# File 'lib/abstractor/methods/models/abstractor_subject.rb', line 248 def abstract_canonical_name_value(about, abstractor_abstraction, abstractor_abstraction_source) abstractor_abstraction_source.normalize_from_method_to_sources(about).each do |source| abstractor_text = Abstractor::AbstractorAbstractionSource.abstractor_text(source) parser = Abstractor::Parser.new(abstractor_text) abstractor_abstraction_schema.predicate_variants.each do |predicate_variant| abstractor_abstraction_schema.abstractor_object_values.each do |abstractor_object_value| abstractor_object_value.object_variants.each do |object_variant| match_value = "#{Regexp.escape(predicate_variant)}:\s*#{Regexp.escape(object_variant)}" matches = parser.scan(match_value, word_boundary: true).uniq matches.each do |match| suggest(abstractor_abstraction, abstractor_abstraction_source, match, match, source[:source_id], source[:source_type].to_s, source[:source_method], source[:section_name], abstractor_object_value, nil, nil, nil, nil) end match_value = "#{Regexp.escape(predicate_variant)}#{Regexp.escape(object_variant)}" matches = parser.scan(match_value, word_boundary: true).uniq matches.each do |match| suggest(abstractor_abstraction, abstractor_abstraction_source, match, match, source[:source_id], source[:source_type].to_s, source[:source_method], source[:seciton_name], abstractor_object_value, nil, nil, nil, nil) end end end end end end |
#abstract_custom_nlp_suggestion(about, abstractor_abstraction, abstractor_abstraction_source) ⇒ void
This method returns an undefined value.
Looks up a suggestion endpoint to submit text to an external custom NLP provider for the delegation of suggestion generation.
The method will determine an endpoint by looking in config/abstractor/custom_nlp_providers.yml based on the current environment and the value of the AbstractorAbstractionSource#custom_nlp_provider attribute.
A template configratuon file can be generated in the the host application by calling the rake task abstractor:custom_nlp_provider. The configuration is expected to provide different endpoints per environment, per provider. Abstractor will format a JSON body to post to the discovered endpoint. The custom NLP provider will be expected to generate suggestions and post them back to /abstractor_abstractions/:abstractor_abstraction_id/abstractor_suggestions/
169 170 171 172 173 174 175 176 |
# File 'lib/abstractor/methods/models/abstractor_subject.rb', line 169 def abstract_custom_nlp_suggestion(about, abstractor_abstraction, abstractor_abstraction_source) suggestion_endpoint = CustomNlpProvider.determine_suggestion_endpoint(abstractor_abstraction_source.custom_nlp_provider) abstractor_abstraction_source.normalize_from_method_to_sources(about).each do |source| abstractor_text = Abstractor::AbstractorAbstractionSource.abstractor_text(source) body = Abstractor::CustomNlpProvider.format_body_for_suggestion_endpoint(abstractor_abstraction, abstractor_abstraction_source, abstractor_text, source) HTTParty.post(suggestion_endpoint, body: body.to_json, headers: { 'Content-Type' => 'application/json' }) end end |
#abstract_custom_suggestion(about, abstractor_abstraction, abstractor_abstraction_source) ⇒ void
This method returns an undefined value.
Creates instances of Abstractor::AbstractorSuggestion and Abstractor::AbstractorSuggestionSource based on calling the method configured by the AbstractorAbstractionSource#custom_method attribute. The method is called on the abstractable entity passed via the about parameter.
Setting up an Abstractor::AbstractorSubject with an AbstractorAbstractionSource with an AbstractorAbstractionSource#abstractor_abstraction_source_type attribute set to ‘custom suggestion’ obligates the developer to implement an instance method on the abstractable entitty to make suggestions as appropriate. The ‘custom suggestion’ source type is intended to faciliate the generation of suggestions in a customizable way. The method implemented by the developer should return an array of hashes, each has with 2 keys, like so
- { suggestion: ‘a suggestion’, explanation: ‘why i made the suggestion}
-
The suggestion will be presented to the user as possible answer for the abstraction. The explanation will be displayed to the user to explain how the sytem arrived at the suggestion.
133 134 135 136 137 138 139 |
# File 'lib/abstractor/methods/models/abstractor_subject.rb', line 133 def abstract_custom_suggestion(about, abstractor_abstraction, abstractor_abstraction_source) suggestions = about.send(abstractor_abstraction_source.custom_method, abstractor_abstraction) suggestions.each do |suggestion| suggest(abstractor_abstraction, abstractor_abstraction_source, nil, nil, about.id, about.class.to_s, abstractor_abstraction_source.from_method, abstractor_abstraction_source.section_name, suggestion[:suggestion], nil, nil, abstractor_abstraction_source.custom_method, suggestion[:explanation]) end create_unknown_abstractor_suggestion(about, abstractor_abstraction, abstractor_abstraction_source) end |
#abstract_indirect_source(about, abstractor_abstraction, abstractor_abstraction_source) ⇒ void
This method returns an undefined value.
Creates an instance of Abstractor::AbstractorIndirectSource – if one does not already exist – for the abstractor_abstraction and abstraction_source parameters. An ‘indirect’ Abstractor::AbstractorAbstractionSources give developers the ability to define a pool of documents that are indrectly related to an abstraction. The developer is responsible for implementing a method on the abstractable enttiy specified in Abstractor::AbstractorAbstractionSource#from_method. The method should return a hash with the following keys populated:
- Array <ActiveRecord::Base>
-
:sources An array of active record objects that constitute the list of indirect sources.
- Symbol
-
:source_id A method specifying the primary key of each member in sources.
- Symbol
-
:source_method A method specifying the source text of each member in sources.
79 80 81 82 83 84 85 |
# File 'lib/abstractor/methods/models/abstractor_subject.rb', line 79 def abstract_indirect_source(about, abstractor_abstraction, abstractor_abstraction_source) if !abstractor_abstraction.detect_abstractor_indirect_source(abstractor_abstraction_source) source = about.send(abstractor_abstraction_source.from_method) abstractor_abstraction.abstractor_indirect_sources.build(abstractor_abstraction_source: abstractor_abstraction_source, source_type: source[:source_type], source_method: source[:source_method]) abstractor_abstraction.save! end end |
#abstract_name_value(about, abstractor_abstraction, abstractor_abstraction_source) ⇒ Object
241 242 243 244 245 246 |
# File 'lib/abstractor/methods/models/abstractor_subject.rb', line 241 def abstract_name_value(about, abstractor_abstraction, abstractor_abstraction_source) abstract_canonical_name_value(about, abstractor_abstraction, abstractor_abstraction_source) abstract_sentential_name_value(about, abstractor_abstraction, abstractor_abstraction_source) create_unknown_abstractor_suggestion_name_only(about, abstractor_abstraction, abstractor_abstraction_source) create_unknown_abstractor_suggestion(about, abstractor_abstraction, abstractor_abstraction_source) end |
#abstract_nlp_suggestion(about, abstractor_abstraction, abstractor_abstraction_source) ⇒ void
This method returns an undefined value.
Creates instances of Abstractor::AbstractorSuggestion and Abstractor::AbstractorSuggestionSource based on natural languange processing (nlp).
The Abstractor::AbstractorSubject#abstractor_rule_type attribute determines the nlp strategy to employ:
-
‘name/value’: attempts to search for non-negated sentences mentioning of an Abstractor::AbstractorAbstractionSchema#predicate and an Abstractor::AbstractorObjectValue
-
‘value’: attempts to search for non-negated sentences mentioning an Abstractor::AbstractorObjectValue
-
‘unknown’: will automatically create an ‘unknown’ Abstractor::AbstractorSuggestion
101 102 103 104 105 106 107 108 109 110 |
# File 'lib/abstractor/methods/models/abstractor_subject.rb', line 101 def abstract_nlp_suggestion(about, abstractor_abstraction, abstractor_abstraction_source) case abstractor_abstraction_source.abstractor_rule_type.name when 'name/value' abstract_name_value(about, abstractor_abstraction, abstractor_abstraction_source) when 'value' abstract_value(about, abstractor_abstraction, abstractor_abstraction_source) when 'unknown' abstract_unknown(about, abstractor_abstraction, abstractor_abstraction_source) end end |
#abstract_sentential_name_value(about, abstractor_abstraction, abstractor_abstraction_source) ⇒ Object
272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 |
# File 'lib/abstractor/methods/models/abstractor_subject.rb', line 272 def abstract_sentential_name_value(about, abstractor_abstraction, abstractor_abstraction_source) abstractor_abstraction_source.normalize_from_method_to_sources(about).each do |source| abstractor_text = Abstractor::AbstractorAbstractionSource.abstractor_text(source) parser = Abstractor::Parser.new(abstractor_text) abstractor_abstraction_schema.predicate_variants.each do |predicate_variant| ranges = parser.range_all(Regexp.escape(predicate_variant)) if ranges.any? ranges.each do |range| sentence = parser.find_sentence(range) if sentence abstractor_abstraction_schema.abstractor_object_values.each do |abstractor_object_value| abstractor_object_value.object_variants.each do |object_variant| match = parser.match_sentence(sentence[:sentence], Regexp.escape(object_variant)) if match scoped_sentence = Abstractor::NegationDetection.parse_negation_scope(sentence[:sentence]) reject = ( Abstractor::NegationDetection.negated_match_value?(scoped_sentence[:scoped_sentence], predicate_variant) || Abstractor::NegationDetection.manual_negated_match_value?(sentence[:sentence], predicate_variant) || Abstractor::NegationDetection.negated_match_value?(scoped_sentence[:scoped_sentence], object_variant) || Abstractor::NegationDetection.manual_negated_match_value?(sentence[:sentence], object_variant) ) if !reject suggest(abstractor_abstraction, abstractor_abstraction_source, sentence[:sentence], sentence[:sentence], source[:source_id], source[:source_type].to_s, source[:source_method], source[:section_name], abstractor_object_value, nil, nil, nil, nil) end end end end end end end end end end |
#abstract_sentential_value(about, abstractor_abstraction, abstractor_abstraction_source) ⇒ Object
187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 |
# File 'lib/abstractor/methods/models/abstractor_subject.rb', line 187 def abstract_sentential_value(about, abstractor_abstraction, abstractor_abstraction_source) abstractor_abstraction_source.normalize_from_method_to_sources(about).each do |source| abstractor_text = Abstractor::AbstractorAbstractionSource.abstractor_text(source) abstractor_object_value_ids = abstractor_abstraction_schema.abstractor_object_values.map(&:id) abstractor_object_values = [] abstractor_object_value_variants = [] target_abstractor_object_values =[] target_abstractor_object_value_variants = Abstractor::AbstractorObjectValueVariant.where("abstractor_object_value_id in (?)", abstractor_object_value_ids).to_a at = nil at = abstractor_text.downcase unless abstractor_text.blank? target_abstractor_object_value_variants.each do |abstractor_object_value_variant| re = Regexp.new('\b' + Regexp.escape(abstractor_object_value_variant.value.downcase) + '\b') if re =~ at abstractor_object_value_variants << abstractor_object_value_variant abstractor_object_values << abstractor_object_value_variant.abstractor_object_value end end target_abstractor_object_values = abstractor_abstraction_schema.abstractor_object_values target_abstractor_object_values = target_abstractor_object_values - abstractor_object_values target_abstractor_object_values.each do |abstractor_object_value| re = Regexp.new('\b' + Regexp.escape(abstractor_object_value.value.downcase) + '\b') if re =~ at abstractor_object_values << abstractor_object_value end end parser = Abstractor::Parser.new(abstractor_text) abstractor_object_values.each do |abstractor_object_value| object_variants(abstractor_object_value, abstractor_object_value_variants).each do |object_variant| ranges = parser.range_all(Regexp.escape(object_variant.downcase)) if ranges.any? ranges.each do |range| sentence = parser.find_sentence(range) if sentence scoped_sentence = Abstractor::NegationDetection.parse_negation_scope(sentence[:sentence]) reject = ( Abstractor::NegationDetection.negated_match_value?(scoped_sentence[:scoped_sentence], object_variant) || Abstractor::NegationDetection.manual_negated_match_value?(sentence[:sentence], object_variant) ) if !reject suggest(abstractor_abstraction, abstractor_abstraction_source, object_variant.downcase, sentence[:sentence], source[:source_id], source[:source_type].to_s, source[:source_method], source[:section_name], abstractor_object_value, nil, nil, nil, nil) end end end end end end end end |
#abstract_unknown(about, abstractor_abstraction, abstractor_abstraction_source) ⇒ Object
178 179 180 |
# File 'lib/abstractor/methods/models/abstractor_subject.rb', line 178 def abstract_unknown(about, abstractor_abstraction, abstractor_abstraction_source) create_unknown_abstractor_suggestion(about, abstractor_abstraction, abstractor_abstraction_source) end |
#abstract_value(about, abstractor_abstraction, abstractor_abstraction_source) ⇒ Object
182 183 184 185 |
# File 'lib/abstractor/methods/models/abstractor_subject.rb', line 182 def abstract_value(about, abstractor_abstraction, abstractor_abstraction_source) abstract_sentential_value(about, abstractor_abstraction, abstractor_abstraction_source) create_unknown_abstractor_suggestion(about, abstractor_abstraction, abstractor_abstraction_source) end |
#abstractor_object_value?(suggested_value) ⇒ Boolean
345 346 347 |
# File 'lib/abstractor/methods/models/abstractor_subject.rb', line 345 def abstractor_object_value?(suggested_value) suggested_value.instance_of?(Abstractor::AbstractorObjectValue) end |
#create_unknown_abstractor_suggestion(about, abstractor_abstraction, abstractor_abstraction_source) ⇒ Object
377 378 379 380 381 382 383 384 |
# File 'lib/abstractor/methods/models/abstractor_subject.rb', line 377 def create_unknown_abstractor_suggestion(about, abstractor_abstraction, abstractor_abstraction_source) #Create an 'unknown' suggestion based on matching nothing only if we have not made a suggstion abstractor_abstraction_source.normalize_from_method_to_sources(about).each do |source| if abstractor_abstraction.abstractor_suggestions(true).select { |abstractor_suggestion| abstractor_suggestion.unknown != true }.empty? suggest(abstractor_abstraction, abstractor_abstraction_source, nil, nil, source[:source_id], source[:source_type].to_s, source[:source_method],source[:section_name], nil, true, nil, nil, nil) end end end |
#create_unknown_abstractor_suggestion_name_only(about, abstractor_abstraction, abstractor_abstraction_source) ⇒ Object
349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 |
# File 'lib/abstractor/methods/models/abstractor_subject.rb', line 349 def create_unknown_abstractor_suggestion_name_only(about, abstractor_abstraction, abstractor_abstraction_source) abstractor_abstraction_source.normalize_from_method_to_sources(about).each do |source| abstractor_text = Abstractor::AbstractorAbstractionSource.abstractor_text(source) parser = Abstractor::Parser.new(abstractor_text) #Create an 'unknown' suggestion based on match name only if we have not made a suggstion if abstractor_abstraction.abstractor_suggestions(true).empty? abstractor_abstraction_schema.predicate_variants.each do |predicate_variant| ranges = parser.range_all(Regexp.escape(predicate_variant)) if ranges ranges.each do |range| sentence = parser.find_sentence(range) if sentence scoped_sentence = Abstractor::NegationDetection.parse_negation_scope(sentence[:sentence]) reject = ( Abstractor::NegationDetection.negated_match_value?(scoped_sentence[:scoped_sentence], predicate_variant) || Abstractor::NegationDetection.manual_negated_match_value?(sentence[:sentence], predicate_variant) ) if !reject suggest(abstractor_abstraction, abstractor_abstraction_source, predicate_variant.downcase, sentence[:sentence], source[:source_id], source[:source_type].to_s, source[:source_method], source[:section_name], nil, true, nil, nil, nil) end end end end end end end end |
#groupable? ⇒ Boolean
386 387 388 |
# File 'lib/abstractor/methods/models/abstractor_subject.rb', line 386 def groupable? !abstractor_subject_group_member.nil? end |
#suggest(abstractor_abstraction, abstractor_abstraction_source, match_value, sentence_match_value, source_id, source_type, source_method, section_name, suggested_value, unknown, not_applicable, custom_method, custom_explanation) ⇒ Object
306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 |
# File 'lib/abstractor/methods/models/abstractor_subject.rb', line 306 def suggest(abstractor_abstraction, abstractor_abstraction_source, match_value, sentence_match_value, source_id, source_type, source_method, section_name, suggested_value, unknown, not_applicable, custom_method, custom_explanation) match_value.strip! unless match_value.nil? sentence_match_value.strip! unless sentence_match_value.nil? if abstractor_object_value?(suggested_value) abstractor_object_value = suggested_value suggested_value = suggested_value.value end abstractor_suggestion = abstractor_abstraction.detect_abstractor_suggestion(suggested_value, unknown, not_applicable) if !abstractor_suggestion abstractor_suggestion_status_needs_review = Abstractor::AbstractorSuggestionStatus.where(name: 'Needs review').first abstractor_suggestion = Abstractor::AbstractorSuggestion.create( abstractor_abstraction: abstractor_abstraction, abstractor_suggestion_status: abstractor_suggestion_status_needs_review, suggested_value: suggested_value, unknown: unknown, not_applicable: not_applicable ) abstractor_suggestion.abstractor_suggestion_object_value = Abstractor::AbstractorSuggestionObjectValue.new(abstractor_object_value: abstractor_object_value) if abstractor_object_value end abstractor_suggestion_source = abstractor_suggestion.detect_abstractor_suggestion_source(abstractor_abstraction_source, sentence_match_value, source_id, source_type, source_method, section_name) if !abstractor_suggestion_source Abstractor::AbstractorSuggestionSource.create( abstractor_abstraction_source: abstractor_abstraction_source, abstractor_suggestion: abstractor_suggestion, match_value: match_value, sentence_match_value: sentence_match_value, source_id: source_id, source_type: source_type, source_method: source_method, section_name: section_name, custom_method: custom_method, custom_explanation: custom_explanation ) end abstractor_suggestion end |