sentiment_agent.rb 2.8KB

    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