diff --git a/senpy/plugins/conversion/emotion/__init__.py b/senpy/plugins/conversion/emotion/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/senpy/plugins/conversion/centroids.py b/senpy/plugins/conversion/emotion/centroids.py similarity index 76% rename from senpy/plugins/conversion/centroids.py rename to senpy/plugins/conversion/emotion/centroids.py index ef08976..fe400cd 100644 --- a/senpy/plugins/conversion/centroids.py +++ b/senpy/plugins/conversion/emotion/centroids.py @@ -44,32 +44,27 @@ class CentroidConversion(EmotionConversionPlugin): self.neutralPoints[i] = self.get("neutralValue", 0) def _forward_conversion(self, original): - """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.""" + """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() - maxIntensity = float(original.get("onyx__maxIntensityValue",1)) - neutralPoint = self.get("origin",None) + maxIntensity = float(original.get("onyx:maxIntensityValue", 1)) for e in original.onyx__hasEmotion: - category = e.get("onyx__hasEmotionCategory", None) - if category is None: + category = e.get("onyx:hasEmotionCategory", None) + if not category: continue - intensity = e.get("onyx__hasEmotionIntensity",maxIntensity)/maxIntensity - if intensity == 0: + intensity = e.get("onyx:hasEmotionIntensity", maxIntensity) / maxIntensity + if not intensity: continue - centoid = self.centroids.get(category,None) + centroid = self.centroids.get(category, None) if centroid: for dim, value in centroid.items(): - if neutralPoint: - value -= neutralPoint[dim] - try: - res[dim] += value * intensity - except KeyError: - res[dim] = value * intensity - if neutralPoint: - for dim in res: - res[dim] += neutralPoint[dim] + neutral = self.neutralPoints[dim] + if dim not in res: + res[dim] = 0 + res[dim] += (value - neutral) * intensity + neutral return res def _backwards_conversion(self, original): @@ -88,6 +83,7 @@ class CentroidConversion(EmotionConversionPlugin): emotion = min(centroids, key=lambda x: distance(centroids[x])) result = Emotion(onyx__hasEmotionCategory=emotion) + result.onyx__algorithmConfidence = distance(centroids[emotion]) return result def convert(self, emotionSet, fromModel, toModel, params): diff --git a/senpy/plugins/conversion/emotion/ekman2fsre.senpy b/senpy/plugins/conversion/emotion/ekman2fsre.senpy index 3cc0c17..0606183 100644 --- a/senpy/plugins/conversion/emotion/ekman2fsre.senpy +++ b/senpy/plugins/conversion/emotion/ekman2fsre.senpy @@ -1,6 +1,6 @@ --- name: Ekman2FSRE -module: senpy.plugins.conversion.centroids +module: senpy.plugins.conversion.emotion.centroids description: Plugin to convert emotion sets from Ekman to VAD version: 0.1 # No need to specify onyx:doesConversion because centroids.py adds it automatically from centroids_direction diff --git a/senpy/plugins/conversion/emotion/ekman2vad.senpy b/senpy/plugins/conversion/emotion/ekman2vad.senpy index e9eac74..9af84ba 100644 --- a/senpy/plugins/conversion/emotion/ekman2vad.senpy +++ b/senpy/plugins/conversion/emotion/ekman2vad.senpy @@ -1,6 +1,6 @@ --- name: Ekman2PAD -module: senpy.plugins.conversion.centroids +module: senpy.plugins.conversion.emotion.centroids description: Plugin to convert emotion sets from Ekman to VAD version: 0.1 # No need to specify onyx:doesConversion because centroids.py adds it automatically from centroids_direction diff --git a/tests/test_plugins.py b/tests/test_plugins.py index dbfe60d..fe8ee1c 100644 --- a/tests/test_plugins.py +++ b/tests/test_plugins.py @@ -6,8 +6,9 @@ import shutil import tempfile 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.conversion.emotion.centroids import CentroidConversion class ShelfDummyPlugin(SentimentPlugin, ShelfMixin): @@ -152,3 +153,52 @@ class PluginsTest(TestCase): } }) 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"