|
require 'csv'
module Agents
class SentimentAgent < Agent
class_attribute :anew
cannot_be_scheduled!
description <<-MD
The SentimentAgent generates `good-bad` (psychological valence or happiness index), `active-passive` (arousal),
and `strong-weak` (dominance) score. It will output a value between 1 and 9. It will only work on English content.
Make sure the content this agent is analyzing have sufficient length to get respectable results.
Provide a JSONPath in `content` field where content is residing and set `expected_receive_period_in_days` to the maximum number of days you would allow to be passed between events being received by this agent.
MD
event_description <<-MD
Events look like:
{
"content": "The quick brown fox jumps over the lazy dog.",
"valence": 6.196666666666666,
"arousal": 4.993333333333333,
"dominance": 5.63
}
MD
def default_options
{
'content' => "$.message.text[*]",
'expected_receive_period_in_days' => 1
}
end
def working?
last_receive_at && last_receive_at > options['expected_receive_period_in_days'].to_i.days.ago && !recent_error_logs?
end
def receive(incoming_events)
anew = self.class.sentiment_hash
incoming_events.each do |event|
Utils.values_at(event.payload, options['content']).each do |content|
sent_values = sentiment_values anew, content
create_event :payload => { 'content' => content,
'valence' => sent_values[0],
'arousal' => sent_values[1],
'dominance' => sent_values[2],
'original_event' => event.payload }
end
end
end
def validate_options
errors.add(:base, "content and expected_receive_period_in_days must be present") unless options['content'].present? && options['expected_receive_period_in_days'].present?
end
def self.sentiment_hash
unless self.anew
self.anew = {}
CSV.foreach Rails.root.join('data/anew.csv') do |row|
self.anew[row[0]] = row.values_at(2, 4, 6).map { |val| val.to_f }
end
end
self.anew
end
def sentiment_values(anew, text)
valence, arousal, dominance, freq = [0] * 4
text.downcase.strip.gsub(/[^a-z ]/, "").split.each do |word|
if anew.has_key? word
valence += anew[word][0]
arousal += anew[word][1]
dominance += anew[word][2]
freq += 1
end
end
if valence != 0
[valence/freq, arousal/freq, dominance/freq]
else
["Insufficient data for meaningful answer"] * 3
end
end
end
end
|