mirror of https://github.com/gsi-upm/senpy
You cannot select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
78 lines
2.9 KiB
Python
78 lines
2.9 KiB
Python
from senpy.plugins import EmotionConversionPlugin
|
|
from senpy.models import EmotionSet, Emotion, Error
|
|
|
|
import logging
|
|
logger = logging.getLogger(__name__)
|
|
|
|
|
|
class CentroidConversion(EmotionConversionPlugin):
|
|
def __init__(self, info):
|
|
if 'centroids' not in info:
|
|
raise Error('Centroid conversion plugins should provide '
|
|
'the centroids in their senpy file')
|
|
if 'onyx:doesConversion' not in info:
|
|
if 'centroids_direction' not in info:
|
|
raise Error('Please, provide centroids direction')
|
|
|
|
cf, ct = info['centroids_direction']
|
|
info['onyx:doesConversion'] = [{
|
|
'onyx:conversionFrom': cf,
|
|
'onyx:conversionTo': ct
|
|
}, {
|
|
'onyx:conversionFrom': ct,
|
|
'onyx:conversionTo': cf
|
|
}]
|
|
|
|
if 'aliases' in info:
|
|
aliases = info['aliases']
|
|
ncentroids = {}
|
|
for k1, v1 in info['centroids'].items():
|
|
nv1 = {}
|
|
for k2, v2 in v1.items():
|
|
nv1[aliases.get(k2, k2)] = v2
|
|
ncentroids[aliases.get(k1, k1)] = nv1
|
|
info['centroids'] = ncentroids
|
|
super(CentroidConversion, self).__init__(info)
|
|
|
|
def _forward_conversion(self, original):
|
|
"""Sum the VAD value of all categories found."""
|
|
res = Emotion()
|
|
for e in original.onyx__hasEmotion:
|
|
category = e.onyx__hasEmotionCategory
|
|
if category in self.centroids:
|
|
for dim, value in self.centroids[category].items():
|
|
try:
|
|
res[dim] += value
|
|
except Exception:
|
|
res[dim] = value
|
|
return res
|
|
|
|
def _backwards_conversion(self, original):
|
|
"""Find the closest category"""
|
|
dimensions = set(c.keys() for c in centroids.values())
|
|
neutralPoint = self.get("origin", None)
|
|
neutralPoint = {k:neutralPoint[k] if k in neturalPoint else 0}
|
|
|
|
def distance(centroid):
|
|
return sum((centroid.get(k, neutralPoint[k]) - original.get(k, neutralPoint[k]))**2 for k in dimensions)
|
|
|
|
emotion = min(centroids, key=lambda x: distance(centroids[x])
|
|
|
|
result = Emotion(onyx__hasEmotionCategory=emotion)
|
|
return result
|
|
|
|
def convert(self, emotionSet, fromModel, toModel, params):
|
|
|
|
cf, ct = self.centroids_direction
|
|
logger.debug(
|
|
'{}\n{}\n{}\n{}'.format(emotionSet, fromModel, toModel, params))
|
|
e = EmotionSet()
|
|
if fromModel == cf and toModel == ct:
|
|
e.onyx__hasEmotion.append(self._forward_conversion(emotionSet))
|
|
elif fromModel == ct and toModel == cf:
|
|
for i in emotionSet.onyx__hasEmotion:
|
|
e.onyx__hasEmotion.append(self._backwards_conversion(i))
|
|
else:
|
|
raise Error('EMOTION MODEL NOT KNOWN')
|
|
yield e
|