mirror of https://github.com/gsi-upm/senpy
Merged into monorepo
parent
e51b659030
commit
c52a894017
@ -1,15 +1,9 @@
|
||||
[submodule "sentiment-meaningCloud"]
|
||||
path = sentiment-meaningCloud
|
||||
url = https://lab.cluster.gsi.dit.upm.es/senpy/sentiment-meaningCloud/
|
||||
[submodule "sentiment-vader"]
|
||||
path = sentiment-vader
|
||||
url = https://lab.cluster.gsi.dit.upm.es/senpy/sentiment-vader/
|
||||
[submodule "emotion-wnaffect"]
|
||||
path = emotion-wnaffect
|
||||
url = https://lab.cluster.gsi.dit.upm.es/senpy/emotion-wnaffect
|
||||
[submodule "emotion-anew"]
|
||||
path = emotion-anew
|
||||
url = https://lab.cluster.gsi.dit.upm.es/senpy/emotion-anew
|
||||
[submodule "sentiment-basic"]
|
||||
path = sentiment-basic
|
||||
url = https://lab.cluster.gsi.dit.upm.es/senpy/sentiment-basic
|
||||
[submodule "emotion-anew/data"]
|
||||
path = emotion-anew/data
|
||||
url = https://lab.cluster.gsi.dit.upm.es/senpy/data/emotion-anew.git
|
||||
[submodule "emotion-wnaffect/data"]
|
||||
path = emotion-wnaffect/data
|
||||
url = https://lab.cluster.gsi.dit.upm.es/senpy/data/emotion-wnaffect.git
|
||||
[submodule "sentiment-basic/data"]
|
||||
path = sentiment-basic/data
|
||||
url = https://lab.cluster.gsi.dit.upm.es/senpy/data/sentiment-basic.git
|
||||
|
@ -1,9 +1,10 @@
|
||||
from gsiupm/senpy:0.8.7-python2.7
|
||||
from gsiupm/senpy:0.10.5-python2.7
|
||||
|
||||
RUN python -m nltk.downloader stopwords
|
||||
RUN python -m nltk.downloader punkt
|
||||
RUN python -m nltk.downloader maxent_treebank_pos_tagger
|
||||
RUN python -m nltk.downloader wordnet
|
||||
RUN python -m nltk.downloader omw
|
||||
|
||||
ADD . /senpy-plugins
|
||||
|
||||
|
@ -1,3 +0,0 @@
|
||||
[submodule "data"]
|
||||
path = data
|
||||
url = ../data/emotion-anew
|
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()
|
@ -1,3 +0,0 @@
|
||||
[submodule "data"]
|
||||
path = data
|
||||
url = ../data/emotion-wnaffect
|
@ -1,19 +0,0 @@
|
||||
from senpy.plugins import SentimentPlugin
|
||||
from senpy.models import Response, Entry
|
||||
|
||||
import logging
|
||||
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
class ExamplePlugin(SentimentPlugin):
|
||||
|
||||
def analyse(self, *args, **kwargs):
|
||||
logger.warn('Analysing with the example.')
|
||||
logger.warn('The answer to this response is: %s.' % kwargs['parameter'])
|
||||
resp = Response()
|
||||
ent = Entry(kwargs['input'])
|
||||
ent['example:reversed'] = kwargs['input'][::-1]
|
||||
ent['example:the_answer'] = kwargs['parameter']
|
||||
resp.entries.append(ent)
|
||||
|
||||
return resp
|
@ -1,17 +0,0 @@
|
||||
{
|
||||
"name": "ExamplePlugin",
|
||||
"module": "example",
|
||||
"description": "I am just an example",
|
||||
"author": "@balkian",
|
||||
"version": "0.1",
|
||||
"extra_params": {
|
||||
"parameter": {
|
||||
"@id": "parameter",
|
||||
"aliases": ["parameter", "param"],
|
||||
"required": true,
|
||||
"default": 42
|
||||
}
|
||||
},
|
||||
"requirements": ["noop"],
|
||||
"custom_attribute": "42"
|
||||
}
|
@ -0,0 +1,37 @@
|
||||
from senpy.plugins import Analysis
|
||||
from senpy.models import Response, Entry
|
||||
|
||||
import logging
|
||||
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
class ExamplePlugin(Analysis):
|
||||
'''A *VERY* simple plugin that exemplifies the development of Senpy Plugins'''
|
||||
name = "example-plugin"
|
||||
author = "@balkian"
|
||||
version = "0.1"
|
||||
extra_params = {
|
||||
"parameter": {
|
||||
"@id": "parameter",
|
||||
"aliases": ["parameter", "param"],
|
||||
"required": True,
|
||||
"default": 42
|
||||
}
|
||||
}
|
||||
custom_attribute = "42"
|
||||
|
||||
def analyse_entry(self, entry, params):
|
||||
logger.debug('Analysing with the example.')
|
||||
logger.debug('The answer to this response is: %s.' % params['parameter'])
|
||||
resp = Response()
|
||||
entry['example:reversed'] = entry.text[::-1]
|
||||
entry['example:the_answer'] = params['parameter']
|
||||
|
||||
yield entry
|
||||
|
||||
test_cases = [{
|
||||
'input': 'hello',
|
||||
'expected': {
|
||||
'example:reversed': 'olleh'
|
||||
}
|
||||
}]
|
@ -1,23 +0,0 @@
|
||||
import unittest
|
||||
from flask import Flask
|
||||
import os
|
||||
|
||||
from senpy.extensions import Senpy
|
||||
|
||||
class emoTextWAFTest(unittest.TestCase):
|
||||
|
||||
def setUp(self):
|
||||
self.app = Flask("Example")
|
||||
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("ExamplePlugin", sync=True)
|
||||
|
||||
def test_analyse(self):
|
||||
assert len(self.senpy.plugins.keys()) == 1
|
||||
assert True
|
||||
|
||||
if __name__ == '__main__':
|
||||
unittest.main()
|
@ -1,3 +0,0 @@
|
||||
[submodule "data"]
|
||||
path = data
|
||||
url = ../data/sentiment-basic
|
@ -1,24 +1,7 @@
|
||||
{
|
||||
"name": "sentiment-basic",
|
||||
"module": "sentiment-basic",
|
||||
"description": "Sentiment classifier using rule-based classification for Spanish. Based on english to spanish translation and SentiWordNet sentiment knowledge. This is a demo plugin that uses only some features from the TASS 2015 classifier. To use the entirely functional classifier you can use the service in: http://senpy.cluster.gsi.dit.upm.es.",
|
||||
"author": "github.com/nachtkatze",
|
||||
"version": "0.1",
|
||||
"requirements": [
|
||||
"nltk>=3.0.5",
|
||||
"scipy>=0.14.0",
|
||||
"textblob"
|
||||
],
|
||||
"extra_params": {
|
||||
"language": {
|
||||
"aliases": ["language", "l"],
|
||||
"required": true,
|
||||
"options": ["en","es", "it", "fr", "auto"],
|
||||
"default": "auto"
|
||||
},
|
||||
},
|
||||
"sentiword_path": "data/SentiWordNet_3.0.txt",
|
||||
"pos_path": "data/unigram_spanish.pickle",
|
||||
"maxPolarityValue": "1",
|
||||
"minPolarityValue": "-1"
|
||||
}
|
||||
---
|
||||
module: sentiment-basic
|
||||
requirements:
|
||||
- nltk>=3.0.5
|
||||
- scipy>=0.14.0
|
||||
- textblob
|
||||
|
||||
|
@ -1,42 +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
|
||||
|
||||
class SentiTextTest(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("SentiText", sync=True)
|
||||
|
||||
def test_analyse(self):
|
||||
plugin = self.senpy.plugins["SentiText"]
|
||||
plugin.activate()
|
||||
|
||||
texts = {'Odio ir al cine' : 'marl:Neutral',
|
||||
'El cielo esta nublado' : 'marl:Positive',
|
||||
'Esta tarta esta muy buena' : 'marl:Neutral'}
|
||||
|
||||
for text in texts:
|
||||
response = plugin.analyse(input=text)
|
||||
sentimentSet = response.entries[0].sentiments[0]
|
||||
print sentimentSet
|
||||
expected = texts[text]
|
||||
|
||||
assert sentimentSet['marl:hasPolarity'] == expected
|
||||
|
||||
plugin.deactivate()
|
||||
|
||||
if __name__ == '__main__':
|
||||
unittest.main()
|
@ -1,11 +0,0 @@
|
||||
{
|
||||
"name": "sentiment-meaningcloud",
|
||||
"module": "sentiment_meaningcloud",
|
||||
"description": "Sentiment analysis with meaningCloud service. To use this plugin, you need to obtain an API key from meaningCloud signing up here: https://www.meaningcloud.com/developer/login. When you had obtained the meaningCloud API Key, you have to provide it to the plugin, using param apiKey. Example request: http://senpy.cluster.gsi.dit.upm.es/api/?algo=meaningCloud&language=en&apiKey=<put here your API key>&input=I%20love%20Madrid.",
|
||||
"author": "GSI UPM",
|
||||
"version": "1.0",
|
||||
"requirements": {},
|
||||
"maxPolarityValue": "1",
|
||||
"minPolarityValue": "-1"
|
||||
|
||||
}
|
@ -1,16 +0,0 @@
|
||||
==========
|
||||
|
||||
This README file describes the plugin vaderSentiment.
|
||||
|
||||
For developing this plugin, it has been used the module vaderSentiment, which is described in the paper:
|
||||
VADER: A Parsimonious Rule-based Model for Sentiment Analysis of Social Media Text
|
||||
C.J. Hutto and Eric Gilbert
|
||||
Eighth International Conference on Weblogs and Social Media (ICWSM-14). Ann Arbor, MI, June 2014.
|
||||
|
||||
If you use this plugin in your research, please cite the above paper
|
||||
|
||||
For more information about the functionality, check the official repository
|
||||
|
||||
https://github.com/cjhutto/vaderSentiment
|
||||
|
||||
========
|
@ -1,25 +0,0 @@
|
||||
{
|
||||
"name": "sentiment-vader",
|
||||
"module": "sentiment-vader",
|
||||
"description": "Sentiment classifier using vaderSentiment module. Params accepted: Language: {en, es}. The output uses Marl ontology developed at GSI UPM for semantic web.",
|
||||
"author": "@icorcuera",
|
||||
"version": "0.1",
|
||||
"extra_params": {
|
||||
"language": {
|
||||
"@id": "lang_rand",
|
||||
"aliases": ["language", "l"],
|
||||
"required": false,
|
||||
"options": ["es", "en", "auto"]
|
||||
},
|
||||
|
||||
"aggregate": {
|
||||
"aliases": ["aggregate","agg"],
|
||||
"options": ["true", "false"],
|
||||
"required": false,
|
||||
"default": false
|
||||
|
||||
}
|
||||
|
||||
},
|
||||
"requirements": {}
|
||||
}
|
@ -1,44 +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
|
||||
from flask.ext.testing import TestCase
|
||||
import unittest
|
||||
|
||||
class vaderTest(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("vaderSentiment", sync=True)
|
||||
|
||||
def test_analyse(self):
|
||||
plugin = self.senpy.plugins["vaderSentiment"]
|
||||
plugin.activate()
|
||||
|
||||
texts = {'I am tired :(' : 'marl:Negative',
|
||||
'I love pizza' : 'marl:Positive',
|
||||
'I like going to the cinema :)' : 'marl:Positive',
|
||||
'This cake is disgusting' : 'marl:Negative'}
|
||||
|
||||
for text in texts:
|
||||
response = plugin.analyse(input=text)
|
||||
expected = texts[text]
|
||||
sentimentSet = response.entries[0].sentiments
|
||||
|
||||
max_sentiment = max(sentimentSet, key=lambda x: x['marl:polarityValue'])
|
||||
assert max_sentiment['marl:hasPolarity'] == expected
|
||||
|
||||
plugin.deactivate()
|
||||
|
||||
if __name__ == '__main__':
|
||||
unittest.main()
|
Loading…
Reference in New Issue