mirror of
https://github.com/gsi-upm/senpy
synced 2025-08-24 02:22:20 +00:00
Merged into monorepo
This commit is contained in:
3
emotion-anew/.gitmodules
vendored
3
emotion-anew/.gitmodules
vendored
@@ -1,3 +0,0 @@
|
||||
[submodule "data"]
|
||||
path = data
|
||||
url = ../data/emotion-anew
|
@@ -23,12 +23,81 @@ from senpy.plugins import SentimentPlugin, SenpyPlugin
|
||||
from senpy.models import Results, EmotionSet, Entry, Emotion
|
||||
|
||||
|
||||
class EmotionTextPlugin(SentimentPlugin):
|
||||
class ANEW(SentimentPlugin):
|
||||
description = "This plugin consists on an emotion classifier using ANEW lexicon dictionary to calculate VAD (valence-arousal-dominance) of the sentence and determinate which emotion is closer to this value. Each emotion has a centroid, calculated according to this article: http://www.aclweb.org/anthology/W10-0208. The plugin is going to look for the words in the sentence that appear in the ANEW dictionary and calculate the average VAD score for the sentence. Once this score is calculated, it is going to seek the emotion that is closest to this value."
|
||||
author = "@icorcuera"
|
||||
version = "0.5.1"
|
||||
name = "emotion-anew"
|
||||
|
||||
extra_params = {
|
||||
"language": {
|
||||
"aliases": ["language", "l"],
|
||||
"required": True,
|
||||
"options": ["es","en"],
|
||||
"default": "en"
|
||||
}
|
||||
}
|
||||
|
||||
anew_path_es = "Dictionary/Redondo(2007).csv"
|
||||
anew_path_en = "Dictionary/ANEW2010All.txt"
|
||||
centroids = {
|
||||
"anger": {
|
||||
"A": 6.95,
|
||||
"D": 5.1,
|
||||
"V": 2.7
|
||||
},
|
||||
"disgust": {
|
||||
"A": 5.3,
|
||||
"D": 8.05,
|
||||
"V": 2.7
|
||||
},
|
||||
"fear": {
|
||||
"A": 6.5,
|
||||
"D": 3.6,
|
||||
"V": 3.2
|
||||
},
|
||||
"joy": {
|
||||
"A": 7.22,
|
||||
"D": 6.28,
|
||||
"V": 8.6
|
||||
},
|
||||
"sadness": {
|
||||
"A": 5.21,
|
||||
"D": 2.82,
|
||||
"V": 2.21
|
||||
}
|
||||
}
|
||||
emotions_ontology = {
|
||||
"anger": "http://gsi.dit.upm.es/ontologies/wnaffect/ns#anger",
|
||||
"disgust": "http://gsi.dit.upm.es/ontologies/wnaffect/ns#disgust",
|
||||
"fear": "http://gsi.dit.upm.es/ontologies/wnaffect/ns#negative-fear",
|
||||
"joy": "http://gsi.dit.upm.es/ontologies/wnaffect/ns#joy",
|
||||
"neutral": "http://gsi.dit.upm.es/ontologies/wnaffect/ns#neutral-emotion",
|
||||
"sadness": "http://gsi.dit.upm.es/ontologies/wnaffect/ns#sadness"
|
||||
}
|
||||
onyx__usesEmotionModel = "emoml:big6"
|
||||
nltk_resources = ['stopwords']
|
||||
|
||||
def activate(self, *args, **kwargs):
|
||||
nltk.download('stopwords')
|
||||
self._stopwords = stopwords.words('english')
|
||||
self._local_path=os.path.dirname(os.path.abspath(__file__))
|
||||
dictionary={}
|
||||
dictionary['es'] = {}
|
||||
with self.open(self.anew_path_es,'rb') as tabfile:
|
||||
reader = csv.reader(tabfile, delimiter='\t')
|
||||
for row in reader:
|
||||
dictionary['es'][row[2]]={}
|
||||
dictionary['es'][row[2]]['V']=row[3]
|
||||
dictionary['es'][row[2]]['A']=row[5]
|
||||
dictionary['es'][row[2]]['D']=row[7]
|
||||
dictionary['en'] = {}
|
||||
with self.open(self.anew_path_en,'rb') as tabfile:
|
||||
reader = csv.reader(tabfile, delimiter='\t')
|
||||
for row in reader:
|
||||
dictionary['en'][row[0]]={}
|
||||
dictionary['en'][row[0]]['V']=row[2]
|
||||
dictionary['en'][row[0]]['A']=row[4]
|
||||
dictionary['en'][row[0]]['D']=row[6]
|
||||
self._dictionary = dictionary
|
||||
|
||||
def _my_preprocessor(self, text):
|
||||
|
||||
@@ -63,8 +132,8 @@ class EmotionTextPlugin(SentimentPlugin):
|
||||
for token in sentence:
|
||||
if token[0].lower() not in self._stopwords:
|
||||
unigrams_words.append(token[0].lower())
|
||||
unigrams_lemmas.append(token[4])
|
||||
pos_tagged.append(token[1])
|
||||
unigrams_lemmas.append(token[4])
|
||||
pos_tagged.append(token[1])
|
||||
|
||||
return unigrams_lemmas,unigrams_words,pos_tagged
|
||||
|
||||
@@ -83,7 +152,7 @@ class EmotionTextPlugin(SentimentPlugin):
|
||||
value=new_value
|
||||
emotion=state
|
||||
return emotion
|
||||
|
||||
|
||||
def _extract_features(self, tweet,dictionary,lang):
|
||||
feature_set={}
|
||||
ngrams_lemmas,ngrams_words,pos_tagged = self._extract_ngrams(tweet,lang)
|
||||
@@ -116,41 +185,76 @@ class EmotionTextPlugin(SentimentPlugin):
|
||||
|
||||
def analyse_entry(self, entry, params):
|
||||
|
||||
text_input = entry.get("text", None)
|
||||
text_input = entry.text
|
||||
|
||||
text= self._my_preprocessor(text_input)
|
||||
dictionary={}
|
||||
lang = params.get("language", "auto")
|
||||
if lang == 'es':
|
||||
with open(self._local_path + self.anew_path_es,'rb') as tabfile:
|
||||
reader = csv.reader(tabfile, delimiter='\t')
|
||||
for row in reader:
|
||||
dictionary[row[2]]={}
|
||||
dictionary[row[2]]['V']=row[3]
|
||||
dictionary[row[2]]['A']=row[5]
|
||||
dictionary[row[2]]['D']=row[7]
|
||||
else:
|
||||
with open(self._local_path + self.anew_path_en,'rb') as tabfile:
|
||||
reader = csv.reader(tabfile, delimiter='\t')
|
||||
for row in reader:
|
||||
dictionary[row[0]]={}
|
||||
dictionary[row[0]]['V']=row[2]
|
||||
dictionary[row[0]]['A']=row[4]
|
||||
dictionary[row[0]]['D']=row[6]
|
||||
text = self._my_preprocessor(text_input)
|
||||
dictionary = self._dictionary[params['language']]
|
||||
|
||||
feature_set=self._extract_features(text,dictionary,lang)
|
||||
feature_set=self._extract_features(text, dictionary, params['language'])
|
||||
|
||||
emotions = EmotionSet()
|
||||
emotions.id = "Emotions0"
|
||||
|
||||
emotion1 = Emotion(id="Emotion0")
|
||||
|
||||
emotion1["onyx:hasEmotionCategory"] = self.emotions_ontology[feature_set['emotion']]
|
||||
emotion1["http://www.gsi.dit.upm.es/ontologies/onyx/vocabularies/anew/ns#valence"] = feature_set['V']
|
||||
emotion1["http://www.gsi.dit.upm.es/ontologies/onyx/vocabularies/anew/ns#arousal"] = feature_set['A']
|
||||
emotion1["http://www.gsi.dit.upm.es/ontologies/onyx/vocabularies/anew/ns#dominance"] = feature_set['D']
|
||||
|
||||
emotion1.prov(self)
|
||||
emotions.prov(self)
|
||||
|
||||
emotions.onyx__hasEmotion.append(emotion1)
|
||||
entry.emotions = [emotions,]
|
||||
entry.emotions = [emotions, ]
|
||||
|
||||
yield entry
|
||||
|
||||
ontology = "http://gsi.dit.upm.es/ontologies/wnaffect/ns#"
|
||||
test_cases = [
|
||||
{
|
||||
'input': 'I hate you',
|
||||
'expected': {
|
||||
'emotions': [{
|
||||
'onyx:hasEmotion': [{
|
||||
'onyx:hasEmotionCategory': ontology + 'anger',
|
||||
}]
|
||||
}]
|
||||
}
|
||||
}, {
|
||||
'input': 'i am sad',
|
||||
'expected': {
|
||||
'emotions': [{
|
||||
'onyx:hasEmotion': [{
|
||||
'onyx:hasEmotionCategory': ontology + 'sadness',
|
||||
}]
|
||||
}]
|
||||
}
|
||||
}, {
|
||||
'input': 'i am happy with my marks',
|
||||
'expected': {
|
||||
'emotions': [{
|
||||
'onyx:hasEmotion': [{
|
||||
'onyx:hasEmotionCategory': ontology + 'joy',
|
||||
}]
|
||||
}]
|
||||
}
|
||||
}, {
|
||||
'input': 'This movie is scary',
|
||||
'expected': {
|
||||
'emotions': [{
|
||||
'onyx:hasEmotion': [{
|
||||
'onyx:hasEmotionCategory': ontology + 'negative-fear',
|
||||
}]
|
||||
}]
|
||||
}
|
||||
}, {
|
||||
'input': 'this cake is disgusting' ,
|
||||
'expected': {
|
||||
'emotions': [{
|
||||
'onyx:hasEmotion': [{
|
||||
'onyx:hasEmotionCategory': ontology + 'negative-fear',
|
||||
}]
|
||||
}]
|
||||
}
|
||||
}
|
||||
]
|
||||
|
Binary file not shown.
@@ -1,64 +1,12 @@
|
||||
{
|
||||
"name": "emotion-anew",
|
||||
"module": "emotion-anew",
|
||||
"description": "This plugin consists on an emotion classifier using ANEW lexicon dictionary to calculate VAD (valence-arousal-dominance) of the sentence and determinate which emotion is closer to this value. Each emotion has a centroid, calculated according to this article: http://www.aclweb.org/anthology/W10-0208. The plugin is going to look for the words in the sentence that appear in the ANEW dictionary and calculate the average VAD score for the sentence. Once this score is calculated, it is going to seek the emotion that is closest to this value.",
|
||||
"author": "@icorcuera",
|
||||
"version": "0.5",
|
||||
"extra_params": {
|
||||
"language": {
|
||||
"aliases": ["language", "l"],
|
||||
"required": true,
|
||||
"options": ["es","en"],
|
||||
"default": "en"
|
||||
}
|
||||
},
|
||||
"requirements": {},
|
||||
"anew_path_es": "/data/Dictionary/Redondo(2007).csv",
|
||||
"anew_path_en": "/data/Dictionary/ANEW2010All.txt",
|
||||
"centroids": {
|
||||
"anger": {
|
||||
"A": 6.95,
|
||||
"D": 5.1,
|
||||
"V": 2.7
|
||||
},
|
||||
"disgust": {
|
||||
"A": 5.3,
|
||||
"D": 8.05,
|
||||
"V": 2.7
|
||||
},
|
||||
"fear": {
|
||||
"A": 6.5,
|
||||
"D": 3.6,
|
||||
"V": 3.2
|
||||
},
|
||||
"joy": {
|
||||
"A": 7.22,
|
||||
"D": 6.28,
|
||||
"V": 8.6
|
||||
},
|
||||
"sadness": {
|
||||
"A": 5.21,
|
||||
"D": 2.82,
|
||||
"V": 2.21
|
||||
}
|
||||
},
|
||||
"emotions_ontology": {
|
||||
"anger": "http://gsi.dit.upm.es/ontologies/wnaffect/ns#anger",
|
||||
"disgust": "http://gsi.dit.upm.es/ontologies/wnaffect/ns#disgust",
|
||||
"fear": "http://gsi.dit.upm.es/ontologies/wnaffect/ns#negative-fear",
|
||||
"joy": "http://gsi.dit.upm.es/ontologies/wnaffect/ns#joy",
|
||||
"neutral": "http://gsi.dit.upm.es/ontologies/wnaffect/ns#neutral-emotion",
|
||||
"sadness": "http://gsi.dit.upm.es/ontologies/wnaffect/ns#sadness"
|
||||
},
|
||||
"requirements": [
|
||||
"numpy",
|
||||
"pandas",
|
||||
"nltk",
|
||||
"scipy",
|
||||
"scikit-learn",
|
||||
"textblob",
|
||||
"pattern",
|
||||
"lxml"
|
||||
],
|
||||
"onyx:usesEmotionModel": "emoml:big6",
|
||||
}
|
||||
---
|
||||
module: emotion-anew
|
||||
requirements:
|
||||
- numpy
|
||||
- pandas
|
||||
- nltk
|
||||
- scipy
|
||||
- scikit-learn
|
||||
- textblob
|
||||
- pattern
|
||||
- lxml
|
||||
onyx:usesEmotionModel: "emoml:big6"
|
||||
|
@@ -1,45 +0,0 @@
|
||||
import os
|
||||
import logging
|
||||
logging.basicConfig()
|
||||
try:
|
||||
import unittest.mock as mock
|
||||
except ImportError:
|
||||
import mock
|
||||
from senpy.extensions import Senpy
|
||||
from flask import Flask
|
||||
import unittest
|
||||
import re
|
||||
|
||||
class emoTextANEWTest(unittest.TestCase):
|
||||
|
||||
def setUp(self):
|
||||
self.app = Flask("test_plugin")
|
||||
self.dir = os.path.join(os.path.dirname(__file__))
|
||||
self.senpy = Senpy(plugin_folder=self.dir, default_plugins=False)
|
||||
self.senpy.init_app(self.app)
|
||||
|
||||
def tearDown(self):
|
||||
self.senpy.deactivate_plugin("EmoTextANEW", sync=True)
|
||||
|
||||
def test_analyse(self):
|
||||
plugin = self.senpy.plugins["EmoTextANEW"]
|
||||
plugin.activate()
|
||||
|
||||
ontology = "http://gsi.dit.upm.es/ontologies/wnaffect/ns#"
|
||||
texts = {'I hate you': 'anger',
|
||||
'i am sad': 'sadness',
|
||||
'i am happy with my marks': 'joy',
|
||||
'This movie is scary': 'negative-fear',
|
||||
'this cake is disgusting' : 'negative-fear'}
|
||||
|
||||
for text in texts:
|
||||
response = plugin.analyse(input=text)
|
||||
expected = texts[text]
|
||||
emotionSet = response.entries[0].emotions[0]
|
||||
|
||||
assert emotionSet['onyx:hasEmotion'][0]['onyx:hasEmotionCategory'] == ontology+expected
|
||||
|
||||
plugin.deactivate()
|
||||
|
||||
if __name__ == '__main__':
|
||||
unittest.main()
|
Reference in New Issue
Block a user