Commit 852bcc72 authored by J. Fernando Sánchez's avatar J. Fernando Sánchez
Browse files

Better centroid conversion

Also added **simple** tests for backward and forward conversion.
In future versions we should add thorough tests.

Should close gsi-upm/senpy#31
parent bf5ed1bd
...@@ -44,32 +44,27 @@ class CentroidConversion(EmotionConversionPlugin): ...@@ -44,32 +44,27 @@ class CentroidConversion(EmotionConversionPlugin):
self.neutralPoints[i] = self.get("neutralValue", 0) 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 weighted by intensity. """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. Intensities are scaled by onyx:maxIntensityValue if it is present, else maxIntensityValue
Emotion entries that do not have onxy:hasEmotionIntensity specified are assumed to have maxIntensityValue. is assumed to be one. Emotion entries that do not have onxy:hasEmotionIntensity specified
Emotion entries that do not have onyx:hasEmotionCategory specified are ignored.""" 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)) maxIntensity = float(original.get("onyx:maxIntensityValue", 1))
neutralPoint = self.get("origin",None)
for e in original.onyx__hasEmotion: for e in original.onyx__hasEmotion:
category = e.get("onyx__hasEmotionCategory", None) category = e.get("onyx:hasEmotionCategory", None)
if category is None: if not category:
continue continue
intensity = e.get("onyx__hasEmotionIntensity",maxIntensity)/maxIntensity intensity = e.get("onyx:hasEmotionIntensity", maxIntensity) / maxIntensity
if intensity == 0: if not intensity:
continue continue
centoid = self.centroids.get(category,None) centroid = self.centroids.get(category, None)
if centroid: if centroid:
for dim, value in centroid.items(): for dim, value in centroid.items():
if neutralPoint: neutral = self.neutralPoints[dim]
value -= neutralPoint[dim] if dim not in res:
try: res[dim] = 0
res[dim] += value * intensity res[dim] += (value - neutral) * intensity + neutral
except KeyError:
res[dim] = value * intensity
if neutralPoint:
for dim in res:
res[dim] += neutralPoint[dim]
return res return res
def _backwards_conversion(self, original): def _backwards_conversion(self, original):
...@@ -88,6 +83,7 @@ class CentroidConversion(EmotionConversionPlugin): ...@@ -88,6 +83,7 @@ class CentroidConversion(EmotionConversionPlugin):
emotion = min(centroids, key=lambda x: distance(centroids[x])) emotion = min(centroids, key=lambda x: distance(centroids[x]))
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):
......
--- ---
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
......
--- ---
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
......
...@@ -6,8 +6,9 @@ import shutil ...@@ -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): ...@@ -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"
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment