From 4c8a9e3e5acc62c210f2d09631b65caf350eb0af Mon Sep 17 00:00:00 2001 From: Rishabh Jain Date: Thu, 9 May 2013 19:15:22 +0530 Subject: [PATCH] Realtime Analyzing in SentimentAgent --- app/models/agents/sentiment_agent.rb | 83 ++++++++++++++++++++++++++++ 1 file changed, 83 insertions(+) create mode 100644 app/models/agents/sentiment_agent.rb diff --git a/app/models/agents/sentiment_agent.rb b/app/models/agents/sentiment_agent.rb new file mode 100644 index 00000000..7c71e57d --- /dev/null +++ b/app/models/agents/sentiment_agent.rb @@ -0,0 +1,83 @@ +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. + + 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 + 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]} + 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 \ No newline at end of file