FEATURE: Order by emotion on /filter (#913)
This commit is contained in:
parent
823e8ef490
commit
5026ab52d0
|
@ -0,0 +1,76 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
module DiscourseAi
|
||||
module Sentiment
|
||||
class EmotionFilterOrder
|
||||
def self.register!(plugin)
|
||||
emotions = %w[
|
||||
admiration
|
||||
amusement
|
||||
anger
|
||||
annoyance
|
||||
approval
|
||||
caring
|
||||
confusion
|
||||
curiosity
|
||||
desire
|
||||
disappointment
|
||||
disapproval
|
||||
disgust
|
||||
embarrassment
|
||||
excitement
|
||||
fear
|
||||
gratitude
|
||||
grief
|
||||
joy
|
||||
love
|
||||
nervousness
|
||||
neutral
|
||||
optimism
|
||||
pride
|
||||
realization
|
||||
relief
|
||||
remorse
|
||||
sadness
|
||||
surprise
|
||||
]
|
||||
|
||||
emotions.each do |emotion|
|
||||
filter_order_emotion = ->(scope, order_direction) do
|
||||
emotion_clause = <<~SQL
|
||||
SUM(
|
||||
CASE
|
||||
WHEN (classification_results.classification::jsonb->'#{emotion}')::float > 0.1
|
||||
THEN 1
|
||||
ELSE 0
|
||||
END
|
||||
)::float / COUNT(posts.id)
|
||||
SQL
|
||||
scope
|
||||
.joins(:posts)
|
||||
.joins(<<~SQL)
|
||||
INNER JOIN classification_results
|
||||
ON classification_results.target_id = posts.id
|
||||
AND classification_results.target_type = 'Post'
|
||||
AND classification_results.model_used = 'SamLowe/roberta-base-go_emotions'
|
||||
SQL
|
||||
.where(<<~SQL)
|
||||
topics.archetype = 'regular'
|
||||
AND topics.deleted_at IS NULL
|
||||
AND posts.deleted_at IS NULL
|
||||
AND posts.post_type = 1
|
||||
SQL
|
||||
.select(<<~SQL)
|
||||
topics.*,
|
||||
#{emotion_clause} AS emotion_#{emotion}
|
||||
SQL
|
||||
.group("1")
|
||||
.having("#{emotion_clause} > 0.05")
|
||||
.order("#{emotion_clause} #{order_direction}")
|
||||
end
|
||||
plugin.add_filter_custom_filter("order:emotion_#{emotion}", &filter_order_emotion)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
|
@ -14,6 +14,8 @@ module DiscourseAi
|
|||
plugin.on(:post_created, &sentiment_analysis_cb)
|
||||
plugin.on(:post_edited, &sentiment_analysis_cb)
|
||||
|
||||
EmotionFilterOrder.register!(plugin)
|
||||
|
||||
plugin.add_report("overall_sentiment") do |report|
|
||||
report.modes = [:stacked_chart]
|
||||
threshold = 0.6
|
||||
|
|
|
@ -0,0 +1,210 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
require "rails_helper"
|
||||
|
||||
RSpec.describe DiscourseAi::Sentiment::EmotionFilterOrder do
|
||||
let(:plugin) { Plugin::Instance.new }
|
||||
let(:model_used) { "SamLowe/roberta-base-go_emotions" }
|
||||
let(:post_1) { Fabricate(:post) }
|
||||
let(:post_2) { Fabricate(:post) }
|
||||
let(:post_3) { Fabricate(:post) }
|
||||
let(:classification_1) do
|
||||
{
|
||||
love: 0.9444406,
|
||||
admiration: 0.013724019,
|
||||
surprise: 0.010188869,
|
||||
excitement: 0.007888741,
|
||||
curiosity: 0.006301749,
|
||||
joy: 0.004060776,
|
||||
confusion: 0.0028238264,
|
||||
approval: 0.0018160914,
|
||||
realization: 0.001174849,
|
||||
neutral: 0.0008561869,
|
||||
amusement: 0.00075853954,
|
||||
disapproval: 0.0006987994,
|
||||
disappointment: 0.0006166883,
|
||||
anger: 0.0006000542,
|
||||
annoyance: 0.0005615011,
|
||||
desire: 0.00046368592,
|
||||
fear: 0.00045117878,
|
||||
sadness: 0.00041727215,
|
||||
gratitude: 0.00041727215,
|
||||
optimism: 0.00037112957,
|
||||
disgust: 0.00035552034,
|
||||
nervousness: 0.00022954118,
|
||||
embarrassment: 0.0002049572,
|
||||
caring: 0.00017737568,
|
||||
remorse: 0.00011407586,
|
||||
grief: 0.0001006716,
|
||||
pride: 0.00009681493,
|
||||
relief: 0.00008919009,
|
||||
}
|
||||
end
|
||||
let(:classification_2) do
|
||||
{
|
||||
love: 0.8444406,
|
||||
admiration: 0.113724019,
|
||||
surprise: 0.010188869,
|
||||
excitement: 0.007888741,
|
||||
curiosity: 0.006301749,
|
||||
joy: 0.004060776,
|
||||
confusion: 0.0028238264,
|
||||
approval: 0.0018160914,
|
||||
realization: 0.001174849,
|
||||
neutral: 0.0008561869,
|
||||
amusement: 0.00075853954,
|
||||
disapproval: 0.0006987994,
|
||||
disappointment: 0.0006166883,
|
||||
anger: 0.0006000542,
|
||||
annoyance: 0.0005615011,
|
||||
desire: 0.00046368592,
|
||||
fear: 0.00045117878,
|
||||
sadness: 0.00041727215,
|
||||
gratitude: 0.00041727215,
|
||||
optimism: 0.00037112957,
|
||||
disgust: 0.00035552034,
|
||||
nervousness: 0.00022954118,
|
||||
embarrassment: 0.0002049572,
|
||||
caring: 0.00017737568,
|
||||
remorse: 0.00011407586,
|
||||
grief: 0.0001006716,
|
||||
pride: 0.00009681493,
|
||||
relief: 0.00008919009,
|
||||
}
|
||||
end
|
||||
let(:classification_3) do
|
||||
{
|
||||
anger: 0.8503682,
|
||||
annoyance: 0.08113059,
|
||||
disgust: 0.020593312,
|
||||
disapproval: 0.013718102,
|
||||
neutral: 0.0074148285,
|
||||
disappointment: 0.005785964,
|
||||
sadness: 0.0028253668,
|
||||
curiosity: 0.0028253668,
|
||||
confusion: 0.0023885092,
|
||||
surprise: 0.001524171,
|
||||
embarrassment: 0.0012784768,
|
||||
love: 0.001177788,
|
||||
admiration: 0.0010892758,
|
||||
realization: 0.001080799,
|
||||
approval: 0.00102328,
|
||||
fear: 0.00097261387,
|
||||
amusement: 0.0007724123,
|
||||
excitement: 0.00059921003,
|
||||
gratitude: 0.00055852515,
|
||||
joy: 0.00054986606,
|
||||
optimism: 0.00050458545,
|
||||
desire: 0.00046849172,
|
||||
caring: 0.00037205798,
|
||||
remorse: 0.00028415458,
|
||||
grief: 0.00025973833,
|
||||
nervousness: 0.00024305031,
|
||||
pride: 0.00011661681,
|
||||
relief: 0.00007470753,
|
||||
}
|
||||
end
|
||||
let!(:classification_result_1) do
|
||||
Fabricate(
|
||||
:sentiment_classification,
|
||||
target: post_1,
|
||||
model_used: model_used,
|
||||
classification: classification_1,
|
||||
)
|
||||
end
|
||||
let!(:classification_result_2) do
|
||||
Fabricate(
|
||||
:sentiment_classification,
|
||||
target: post_2,
|
||||
model_used: model_used,
|
||||
classification: classification_2,
|
||||
)
|
||||
end
|
||||
let!(:classification_result_3) do
|
||||
Fabricate(
|
||||
:sentiment_classification,
|
||||
target: post_3,
|
||||
model_used: model_used,
|
||||
classification: classification_3,
|
||||
)
|
||||
end
|
||||
|
||||
before { described_class.register!(plugin) }
|
||||
|
||||
it "registers emotion filters" do
|
||||
emotions = %w[
|
||||
disappointment
|
||||
sadness
|
||||
annoyance
|
||||
neutral
|
||||
disapproval
|
||||
realization
|
||||
nervousness
|
||||
approval
|
||||
joy
|
||||
anger
|
||||
embarrassment
|
||||
caring
|
||||
remorse
|
||||
disgust
|
||||
grief
|
||||
confusion
|
||||
relief
|
||||
desire
|
||||
admiration
|
||||
optimism
|
||||
fear
|
||||
love
|
||||
excitement
|
||||
curiosity
|
||||
amusement
|
||||
surprise
|
||||
gratitude
|
||||
pride
|
||||
]
|
||||
|
||||
filters = DiscoursePluginRegistry.custom_filter_mappings.reduce(Hash.new, :merge)
|
||||
|
||||
emotions.each { |emotion| expect(filters).to include("order:emotion_#{emotion}") }
|
||||
end
|
||||
|
||||
it "filters topics by emotion" do
|
||||
emotion = "joy"
|
||||
scope = Topic.all
|
||||
order_direction = "desc"
|
||||
|
||||
filter =
|
||||
DiscoursePluginRegistry
|
||||
.custom_filter_mappings
|
||||
.find { _1.keys.include? "order:emotion_#{emotion}" }
|
||||
.values
|
||||
.first
|
||||
result = filter.call(scope, order_direction)
|
||||
|
||||
expect(result.to_sql).to include("INNER JOIN classification_results")
|
||||
expect(result.to_sql).to include(
|
||||
"classification_results.model_used = 'SamLowe/roberta-base-go_emotions'",
|
||||
)
|
||||
expect(result.to_sql).to include("topics.archetype = 'regular'")
|
||||
expect(result.to_sql).to include("ORDER BY")
|
||||
expect(result.to_sql).to include("->'#{emotion}'")
|
||||
expect(result.to_sql).to include("desc")
|
||||
end
|
||||
|
||||
it "sorts emotion in ascending order" do
|
||||
expect(
|
||||
TopicsFilter
|
||||
.new(guardian: Guardian.new)
|
||||
.filter_from_query_string("order:emotion_love-asc")
|
||||
.pluck(:id),
|
||||
).to contain_exactly(post_2.topic.id, post_1.topic.id)
|
||||
end
|
||||
it "sorts emotion in default descending order" do
|
||||
expect(
|
||||
TopicsFilter
|
||||
.new(guardian: Guardian.new)
|
||||
.filter_from_query_string("order:emotion_love")
|
||||
.pluck(:id),
|
||||
).to contain_exactly(post_1.topic.id, post_2.topic.id)
|
||||
end
|
||||
end
|
Loading…
Reference in New Issue