Merge branch '36-estimate-vad'

pull/39/merge 0.8.9
J. Fernando Sánchez 7 years ago
commit c9bc485535

@ -84,7 +84,15 @@ deploy:
only: only:
- master - master
clean_docker : push-github:
stage: deploy
script:
- make -e push-github
only:
- master
- triggers
clean :
stage: clean stage: clean
script: script:
- make -e clean - make -e clean

@ -12,6 +12,7 @@ DEVPORT=5000
TARNAME=$(NAME)-$(VERSION).tar.gz TARNAME=$(NAME)-$(VERSION).tar.gz
action="test-${PYMAIN}" action="test-${PYMAIN}"
GITHUB_REPO=git@github.com:gsi-upm/senpy.git
KUBE_CA_PEM_FILE="" KUBE_CA_PEM_FILE=""
KUBE_URL="" KUBE_URL=""

@ -32,36 +32,58 @@ class CentroidConversion(EmotionConversionPlugin):
nv1[aliases.get(k2, k2)] = v2 nv1[aliases.get(k2, k2)] = v2
ncentroids[aliases.get(k1, k1)] = nv1 ncentroids[aliases.get(k1, k1)] = nv1
info['centroids'] = ncentroids info['centroids'] = ncentroids
super(CentroidConversion, self).__init__(info) super(CentroidConversion, self).__init__(info)
self.dimensions = set()
for c in self.centroids.values():
self.dimensions.update(c.keys())
self.neutralPoints = self.get("neutralPoints", dict())
if not self.neutralPoints:
for i in self.dimensions:
self.neutralPoints[i] = self.get("neutralValue", 0)
def _forward_conversion(self, original): def _forward_conversion(self, original):
"""Sum the VAD value of all categories found.""" """Sum the VAD value of all categories found weighted by intensity.
Intensities are scaled by onyx:maxIntensityValue if it is present, else maxIntensityValue
is assumed to be one. Emotion entries that do not have onxy:hasEmotionIntensity specified
are assumed to have maxIntensityValue. Emotion entries that do not have
onyx:hasEmotionCategory specified are ignored."""
res = Emotion() res = Emotion()
maxIntensity = float(original.get("onyx:maxIntensityValue", 1))
for e in original.onyx__hasEmotion: for e in original.onyx__hasEmotion:
category = e.onyx__hasEmotionCategory category = e.get("onyx:hasEmotionCategory", None)
if category in self.centroids: if not category:
for dim, value in self.centroids[category].items(): continue
try: intensity = e.get("onyx:hasEmotionIntensity", maxIntensity) / maxIntensity
res[dim] += value if not intensity:
except Exception: continue
res[dim] = value centroid = self.centroids.get(category, None)
if centroid:
for dim, value in centroid.items():
neutral = self.neutralPoints[dim]
if dim not in res:
res[dim] = 0
res[dim] += (value - neutral) * intensity + neutral
return res return res
def _backwards_conversion(self, original): def _backwards_conversion(self, original):
"""Find the closest category""" """Find the closest category"""
dimensions = list(self.centroids.values())[0] centroids = self.centroids
neutralPoints = self.neutralPoints
dimensions = self.dimensions
def distance_k(centroid, original, k):
# k component of the distance between the value and a given centroid
return (centroid.get(k, neutralPoints[k]) - original.get(k, neutralPoints[k]))**2
def distance(centroid):
return sum(distance_k(centroid, original, k) for k in dimensions)
def distance(e1, e2): emotion = min(centroids, key=lambda x: distance(centroids[x]))
return sum((e1[k] - e2.get(k, 0)) for k in dimensions)
emotion = ''
mindistance = 10000000000000000000000.0
for state in self.centroids:
d = distance(self.centroids[state], original)
if d < mindistance:
mindistance = d
emotion = state
result = Emotion(onyx__hasEmotionCategory=emotion) result = Emotion(onyx__hasEmotionCategory=emotion)
result.onyx__algorithmConfidence = distance(centroids[emotion])
return result return result
def convert(self, emotionSet, fromModel, toModel, params): def convert(self, emotionSet, fromModel, toModel, params):

@ -1,6 +1,6 @@
--- ---
name: Ekman2FSRE name: Ekman2FSRE
module: senpy.plugins.conversion.centroids module: senpy.plugins.conversion.emotion.centroids
description: Plugin to convert emotion sets from Ekman to VAD description: Plugin to convert emotion sets from Ekman to VAD
version: 0.1 version: 0.1
# No need to specify onyx:doesConversion because centroids.py adds it automatically from centroids_direction # No need to specify onyx:doesConversion because centroids.py adds it automatically from centroids_direction

@ -1,9 +1,14 @@
--- ---
name: Ekman2PAD name: Ekman2PAD
module: senpy.plugins.conversion.centroids module: senpy.plugins.conversion.emotion.centroids
description: Plugin to convert emotion sets from Ekman to VAD description: Plugin to convert emotion sets from Ekman to VAD
version: 0.1 version: 0.1
# No need to specify onyx:doesConversion because centroids.py adds it automatically from centroids_direction # No need to specify onyx:doesConversion because centroids.py adds it automatically from centroids_direction
origin:
# Point in VAD space with no emotion (aka Neutral)
A: 5.0
D: 5.0
V: 5.0
centroids: centroids:
anger: anger:
A: 6.95 A: 6.95
@ -36,4 +41,4 @@ aliases: # These are aliases for any key in the centroid, to avoid repeating a l
disgust: emoml:big6disgust disgust: emoml:big6disgust
fear: emoml:big6fear fear: emoml:big6fear
happiness: emoml:big6happiness happiness: emoml:big6happiness
sadness: emoml:big6sadness sadness: emoml:big6sadness

@ -11,7 +11,7 @@ def read_version(versionfile=DEFAULT_FILE):
try: try:
with open(versionfile) as f: with open(versionfile) as f:
return f.read().strip() return f.read().strip()
except IOError: except IOError: # pragma: no cover
logger.error('Running an unknown version of senpy. Be careful!.') logger.error('Running an unknown version of senpy. Be careful!.')
return '0.0' return '0.0'

@ -6,8 +6,9 @@ import shutil
import tempfile import tempfile
from unittest import TestCase from unittest import TestCase
from senpy.models import Results, Entry from senpy.models import Results, Entry, EmotionSet, Emotion
from senpy.plugins import SentimentPlugin, ShelfMixin from senpy.plugins import SentimentPlugin, ShelfMixin
from senpy.plugins.conversion.emotion.centroids import CentroidConversion
class ShelfDummyPlugin(SentimentPlugin, ShelfMixin): class ShelfDummyPlugin(SentimentPlugin, ShelfMixin):
@ -152,3 +153,52 @@ class PluginsTest(TestCase):
} }
}) })
assert 'example' in a.extra_params assert 'example' in a.extra_params
def test_conversion_centroids(self):
info = {
"name": "CentroidTest",
"description": "Centroid test",
"version": 0,
"centroids": {
"c1": {"V1": 0.5,
"V2": 0.5},
"c2": {"V1": -0.5,
"V2": 0.5},
"c3": {"V1": -0.5,
"V2": -0.5},
"c4": {"V1": 0.5,
"V2": -0.5}},
"aliases": {
"V1": "X-dimension",
"V2": "Y-dimension"
},
"centroids_direction": ["emoml:big6", "emoml:fsre-dimensions"]
}
c = CentroidConversion(info)
es1 = EmotionSet()
e1 = Emotion()
e1.onyx__hasEmotionCategory = "c1"
es1.onyx__hasEmotion.append(e1)
res = c._forward_conversion(es1)
assert res["X-dimension"] == 0.5
assert res["Y-dimension"] == 0.5
e2 = Emotion()
e2.onyx__hasEmotionCategory = "c2"
es1.onyx__hasEmotion.append(e2)
res = c._forward_conversion(es1)
assert res["X-dimension"] == 0
assert res["Y-dimension"] == 1
e = Emotion()
e["X-dimension"] = -0.2
e["Y-dimension"] = -0.3
res = c._backwards_conversion(e)
assert res["onyx:hasEmotionCategory"] == "c3"
e = Emotion()
e["X-dimension"] = -0.2
e["Y-dimension"] = 0.3
res = c._backwards_conversion(e)
assert res["onyx:hasEmotionCategory"] == "c2"

Loading…
Cancel
Save