
不同人的情绪类别与其背后的心理体验、生理机制、激素作用以及身体反应之间的对应关系。根据提供的情绪分类及其对应的心理体验、生理机制、激素作用和身体反应信息,构建一个基于机器学习的情绪预测模型。该模型将整合多维度特征,实现对不同情绪状态的准确预测。
情绪预测模型的核心目标是通过分析个体的多维度生理信号、行为特征和主观体验数据,实现对当前情绪状态的智能识别与分类。基于图片中详述的九种情绪类别及其特征映射关系,我们将构建一个多层次、多特征的预测系统。该系统不仅能够识别基本的情绪类别,还能够深入分析情绪背后的生理机制和激素变化,从而提供更为精准和全面的情绪洞察。
情绪预测在现代社会中具有广泛的应用价值。在心理健康领域,它可以帮助心理咨询师和临床医生更准确地评估来访者的情绪状态,为制定个性化的干预方案提供科学依据。在人机交互领域,情绪识别技术能够使智能助手更好地理解用户的情感需求,提供更加贴心和人性化的服务。在教育培训领域,实时情绪监测可以帮助教师及时发现学生的情绪变化,调整教学策略以提升学习效果。在企业管理领域,团队情绪分析有助于管理者了解员工的工作状态和压力水平,从而优化组织管理和员工关怀策略。
本情绪预测模型采用三层架构设计,每一层承担特定的功能职责,共同构成完整的预测流水线。数据采集层负责收集多源异构数据,包括生理信号数据(如心率变异性、皮肤电导、呼吸频率)、行为数据(如面部表情、语音特征、文本内容)以及主观报告数据(如情绪自评量表)。这一层需要与各种传感器和数据源进行对接,确保数据的实时性和准确性。
特征工程层是连接原始数据与预测模型的桥梁,负责将原始数据转换为模型可理解的特征向量。基于图片中提供的情绪特征映射,我们将特征分为四个主要类别:心理体验特征(通过文本分析或问卷调查获取)、生理驱动特征(通过生理信号分析获取)、激素水平特征(通过生物标志物检测或间接推断)以及典型生理反应特征(通过行为观察和自我报告获取)。特征工程还包括数据预处理、缺失值处理、特征选择和降维等步骤。
预测模型层采用集成学习方法,综合多种机器学习算法的优势以提高预测准确率。模型将输出九种情绪类别的概率分布,并提供置信度评估。为了增强模型的可解释性,我们还将集成基于规则的知识模块,该模块直接对应图片中的情绪-特征映射关系,使用户能够理解预测结果背后的生理和心理学依据。
基于图片内容,我们将情绪预测问题定义为九分类任务,每种情绪类别都具有独特的特征组合和生理机制。愤怒情绪表现为交感神经系统的"战斗"反应高度激活,伴随肾上腺素和去甲肾上腺素水平升高,典型特征包括面红耳赤、咬牙切齿、肩颈僵硬、心跳猛烈和血压升高。恐惧与焦虑情绪同样激活交感神经系统,但表现为"逃跑或僵直"反应,主要涉及肾上腺素和皮质醇的分泌变化,典型特征为胃部下沉、胸闷、手脚冰冷和出冷汗。
悲伤与抑郁情绪的特征是能量与动机系统活动降低,涉及血清素和多巴胺水平下降,典型表现为全身沉重、持续性心痛、喉咙哽咽以及食欲和睡眠紊乱。喜悦与兴奋情绪则与奖赏和愉悦回路的激活相关,涉及多巴胺、内啡肽和血清素的释放,表现为身体轻盈、自然微笑、眼睛发亮和自发想笑。羞耻与尴尬情绪引发自主神经的瞬间反应,肾上腺素导致面部毛细血管扩张,典型表现为面部和耳朵瞬间潮红发热、低头、蜷缩和回避目光。
嫉妒与羡慕情绪是愤怒与焦虑的混合反应,涉及皮质醇(社会比较压力)和肾上腺素(竞争性)的共同作用,表现为胃部紧缩、烦躁以及发热与揪心的混合感受。长期压力情绪源于压力反应系统的长期失调,皮质醇持续处于高水平,导致慢性肩颈痛、头痛、胃痛、肠易激以及失眠和慢性疲劳。此外,我们还识别出两种特殊的情绪躯体感受:"揪心"感和"胸闷"感,它们分别与深切悲伤和焦虑情绪密切相关。
为了训练情绪预测模型,我们需要构建一个包含多维度特征的综合数据集。特征数据将从以下几个维度进行采集和标注。
生理信号特征是情绪预测的重要客观指标。心率变异性(HRV)能够反映自主神经系统的活动状态,高频成分与副交感神经活动相关,低频成分与交感神经活动相关。在愤怒和恐惧情绪下,低频成分占比增加,HRV整体水平下降;在喜悦情绪下,HRV水平升高。皮肤电导水平(SCL)和皮肤电导响应(SCR)能够反映情绪唤醒程度,在愤怒、恐惧和焦虑情绪下显著升高,在悲伤情绪下可能降低。呼吸频率和呼吸深度也是重要的生理指标,焦虑和恐惧情绪导致呼吸浅快,而深度放松状态则表现为缓慢深长的呼吸模式。
行为特征通过计算机视觉和语音处理技术进行提取。面部表情特征基于面部动作编码系统(FACS),识别面部肌肉运动单元的组合模式。愤怒情绪常见眉毛内收、上眼睑抬起、鼻翼扩张、口角收紧等动作;恐惧情绪表现为眉毛上扬并聚拢、眼睛睁大、嘴唇横向拉伸;悲伤情绪特征为眉毛内端上扬、嘴角下撇、上眼睑下垂;喜悦情绪的核心特征是嘴角上扬(微笑)和面颊提升(苹果肌隆起),眼睛周围出现皱纹(眼轮匝肌收缩)。语音特征包括语调变化、音量水平、语速快慢和声音颤抖等参数,这些特征在不同情绪状态下呈现显著差异。
主观体验特征通过标准化的心理量表进行测量。我们将采用正负性情绪量表(PANAS)评估情绪的效价和唤醒度,采用状态-特质焦虑量表(STAI)评估焦虑水平,采用贝克抑郁量表(BDI)评估抑郁程度。此外,还将使用专门设计的情绪自评问卷,收集个体对当前心理体验的详细描述,这些文本数据将通过自然语言处理技术进行特征提取。
不同来源的特征数据具有不同的量纲和取值范围,需要进行适当的编码和标准化处理。生理信号特征通常为连续数值型变量,我们采用Z-score标准化方法将其转换为均值为0、标准差为1的标准分布。这种方法能够消除量纲差异对模型训练的影响,同时保留特征的相对差异信息。对于存在极端值的数据,我们将采用稳健标准化方法(如中位数和四分位距)进行处理,以增强模型对异常值的鲁棒性。
面部表情特征以动作单元(Action Unit)的激活强度或二值化激活状态形式表示。我们将采用独热编码(One-Hot Encoding)处理离散型动作单元特征,对于连续型激活强度特征则进行标准化处理。语音特征的编码方式与生理信号类似,对连续的声学参数进行标准化处理。文本特征采用词嵌入(Word Embedding)或TF-IDF方法进行向量化表示,然后通过主成分分析(PCA)进行降维,以减少特征维度并去除冗余信息。
特征选择是构建高效预测模型的关键步骤。我们将采用多种方法进行特征筛选:基于方差过滤去除变异程度过低的特征;基于相关性分析去除高度冗余的特征;基于树模型的特征重要性评估保留信息量丰富的特征;基于递归特征消除(RFE)逐步优化特征子集。最终选择的特征子集应该具有较高的预测能力,同时避免维度灾难问题。
# -*- coding: utf-8 -*-
"""
情绪预测模型 - 核心模块
基于多维度特征的九分类情绪预测系统
"""
import numpy as np
import pandas as pd
from enum import Enum
from dataclasses import dataclass, field
from typing import Dict, List, Tuple, Optional
from collections import defaultdict
class EmotionCategory(Enum):
"""九种情绪类别枚举"""
ANGER = "愤怒"
FEAR_ANXIETY = "恐惧/焦虑"
SADNESS_DEPRESSION = "悲伤/抑郁"
JOY_EXCITEMENT = "喜悦/兴奋"
SHAME_EMBARRASSMENT = "羞耻/尴尬"
JEALOUSY_ENVY = "嫉妒/羡慕"
CHRONIC_STRESS = "长期压力"
HEART_WRENCHING = "揪心感"
CHEST_TIGHTNESS = "胸闷感"
@dataclass
class PhysiologicalFeatures:
"""生理信号特征"""
# 心血管指标
heart_rate: float # 心率 (bpm)
heart_rate_variability: float # 心率变异性 (ms)
systolic_bp: float # 收缩压 (mmHg)
diastolic_bp: float # 舒张压 (mmHg)
# 皮肤电活动
skin_conductance_level: float # 基础皮肤电导 (μS)
skin_conductance_response: float # 皮肤电导反应 (μS)
# 呼吸指标
respiration_rate: float # 呼吸频率 (次/分钟)
respiration_depth: float # 呼吸深度 (相对值)
# 体温与自主神经
skin_temperature: float # 皮肤温度 (°C)
sympathetic_index: float # 交感神经指数 (0-1)
@dataclass
class BehavioralFeatures:
"""行为特征"""
# 面部表情动作单元 (0-5 激活强度)
au1_inner_brow_raiser: float # 眉毛内端上扬
au4_brow_lower: float # 眉毛下压
au5_upper_lid_raiser: float # 上眼睑抬起
au6_cheek_raiser: float # 面颊提升
au7_lid_tightener: float # 眼睑收紧
au9_nose_wrinkler: float # 鼻翼扩张
au10_upper_lip_raiser: float # 上唇上扬
au12_lip_corner_puller: float # 嘴角上扬
au14_dimpler: float # 嘴角酒窝
au15_lip_corner_depressor: float # 嘴角下压
au17_chin_raiser: float # 下巴抬起
au18_lip_puckerer: float # 嘴唇噘起
au20_lip_stretcher: float # 嘴唇拉伸
au23_lip_tightener: float # 嘴唇收紧
au25_lips_part: float # 嘴唇分开
au26_jaw_drop: float # 下颌下垂
au28_lip_suck: float # 嘴唇内吸
# 语音特征
voice_pitch: float # 基频 (Hz)
voice_volume: float # 音量 (dB)
speech_rate: float # 语速 (音节/秒)
voice_tremor: float # 声音颤抖指数
@dataclass
class PsychologicalFeatures:
"""心理体验特征"""
# 情绪效价 (-1 消极 到 +1 积极)
valence: float
# 情绪唤醒度 (0 低唤醒 到 1 高唤醒)
arousal: float
# 主导情绪强度 (0-10)
anger_intensity: float
fear_intensity: float
sadness_intensity: float
joy_intensity: float
shame_intensity: float
envy_intensity: float
# 身体感受强度 (0-10)
chest_tightness: float
stomach_discomfort: float
heart_pain: float
muscle_tension: float
fatigue_level: float
@dataclass
class EmotionalState:
"""情绪状态综合表征"""
physiological: PhysiologicalFeatures
behavioral: BehavioralFeatures
psychological: PsychologicalFeatures
def to_feature_vector(self) -> np.ndarray:
"""转换为特征向量"""
features = []
# 生理特征
phys = self.physiological
features.extend([
phys.heart_rate, phys.heart_rate_variability,
phys.systolic_bp, phys.diastolic_bp,
phys.skin_conductance_level, phys.skin_conductance_response,
phys.respiration_rate, phys.respiration_depth,
phys.skin_temperature, phys.sympathetic_index
])
# 行为特征
behavior = self.behavioral
features.extend([
behavior.au1_inner_brow_raiser, behavior.au4_brow_lower,
behavior.au5_upper_lid_raiser, behavior.au6_cheek_raiser,
behavior.au7_lid_tightener, behavior.au9_nose_wrinkler,
behavior.au10_upper_lip_raiser, behavior.au12_lip_corner_puller,
behavior.au14_dimpler, behavior.au15_lip_corner_depressor,
behavior.au17_chin_raiser, behavior.au18_lip_puckerer,
behavior.au20_lip_stretcher, behavior.au23_lip_tightener,
behavior.au25_lips_part, behavior.au26_jaw_drop,
behavior.au28_lip_suck, behavior.voice_pitch,
behavior.voice_volume, behavior.speech_rate,
behavior.voice_tremor
])
# 心理特征
psych = self.psychological
features.extend([
psych.valence, psych.arousal,
psych.anger_intensity, psych.fear_intensity,
psych.sadness_intensity, psych.joy_intensity,
psych.shame_intensity, psych.envy_intensity,
psych.chest_tightness, psych.stomach_discomfort,
psych.heart_pain, psych.muscle_tension, psych.fatigue_level
])
return np.array(features, dtype=np.float64)class EmotionPredictor:
"""情绪预测器核心类"""
# 基于图片内容的情绪特征知识库
EMOTION_KNOWLEDGE_BASE = {
EmotionCategory.ANGER: {
"mechanism": "交感神经'战斗'反应高度激活",
"hormones": ["肾上腺素/去甲肾上腺素", "皮质醇"],
"key_features": ["面红耳赤", "咬牙切齿", "肩颈僵硬", "心跳猛烈", "血压升高", "身体发热"],
"physiological_pattern": {
"sympathetic_index": (0.8, 1.0),
"heart_rate": (90, 140),
"systolic_bp": (140, 200),
"skin_temperature": (34.5, 36.5),
"respiration_rate": (16, 25)
},
"behavioral_pattern": {
"au4_brow_lower": (3, 5),
"au9_nose_wrinkler": (2, 5),
"au23_lip_tightener": (2, 5),
"au7_lid_tightener": (2, 5),
"voice_volume": (0.7, 1.0),
"voice_tremor": (0.3, 0.7)
}
},
EmotionCategory.FEAR_ANXIETY: {
"mechanism": "交感神经'逃跑或僵直'反应激活",
"hormones": ["肾上腺素", "皮质醇"],
"key_features": ["胃部下沉", "胃痉挛", "胸闷", "呼吸浅快", "手脚冰冷", "出冷汗"],
"physiological_pattern": {
"sympathetic_index": (0.7, 0.95),
"heart_rate": (85, 130),
"heart_rate_variability": (20, 45),
"skin_temperature": (32, 34),
"skin_conductance_response": (0.8, 2.0)
},
"behavioral_pattern": {
"au1_inner_brow_raiser": (3, 5),
"au5_upper_lid_raiser": (3, 5),
"au20_lip_stretcher": (2, 4),
"voice_pitch": (200, 350),
"speech_rate": (3, 5)
}
},
EmotionCategory.SADNESS_DEPRESSION: {
"mechanism": "能量与动机系统活动降低",
"hormones": ["血清素(低)", "多巴胺(低)", "催乳素"],
"key_features": ["全身沉重", "乏力", "心痛", "喉咙哽咽", "食欲紊乱", "嗜睡/失眠"],
"physiological_pattern": {
"sympathetic_index": (0.1, 0.4),
"heart_rate": (55, 75),
"respiration_rate": (10, 14),
"heart_rate_variability": (50, 80),
"fatigue_level": (7, 10)
},
"behavioral_pattern": {
"au1_inner_brow_raiser": (3, 5),
"au15_lip_corner_depressor": (3, 5),
"au6_cheek_raiser": (0, 1),
"au12_lip_corner_puller": (0, 1),
"speech_rate": (1.5, 3),
"voice_volume": (0.3, 0.6)
}
},
EmotionCategory.JOY_EXCITEMENT: {
"mechanism": "奖赏与愉悦回路激活",
"hormones": ["多巴胺", "内啡肽", "血清素"],
"key_features": ["身体轻盈", "能量充盈", "自然微笑", "眼睛发亮", "自发想笑"],
"physiological_pattern": {
"sympathetic_index": (0.5, 0.8),
"heart_rate": (70, 95),
"heart_rate_variability": (60, 90),
"skin_temperature": (34, 35.5)
},
"behavioral_pattern": {
"au6_cheek_raiser": (3, 5),
"au12_lip_corner_puller": (3, 5),
"au25_lips_part": (2, 4),
"voice_volume": (0.5, 0.8),
"speech_rate": (2.5, 4)
}
},
EmotionCategory.SHAME_EMBARRASSMENT: {
"mechanism": "自主神经瞬间反应",
"hormones": ["肾上腺素"],
"key_features": ["面部潮红发热", "耳朵潮红", "低头", "蜷缩", "回避目光"],
"physiological_pattern": {
"skin_temperature": (35.5, 37), # 面部温度升高
"sympathetic_index": (0.5, 0.8),
"heart_rate": (75, 100)
},
"behavioral_pattern": {
"au1_inner_brow_raiser": (2, 4),
"au43_eye_closure": (0.3, 0.7), # 闭眼/低头
"au26_jaw_drop": (0, 1),
"voice_volume": (0.2, 0.5),
"speech_rate": (2, 3.5)
}
},
EmotionCategory.JEALOUSY_ENVY: {
"mechanism": "愤怒与焦虑的混合反应",
"hormones": ["皮质醇", "肾上腺素"],
"key_features": ["胃部紧缩", "烦躁", "发热与揪心混合"],
"physiological_pattern": {
"sympathetic_index": (0.6, 0.9),
"heart_rate": (80, 110),
"stomach_discomfort": (5, 9),
"skin_conductance_response": (0.5, 1.5)
},
"behavioral_pattern": {
"au4_brow_lower": (2, 4),
"au15_lip_corner_depressor": (2, 4),
"voice_tremor": (0.2, 0.5)
}
},
EmotionCategory.CHRONIC_STRESS: {
"mechanism": "压力反应系统长期失调",
"hormones": ["皮质醇", "肾上腺素"],
"key_features": ["慢性肩颈痛", "头痛", "胃痛", "肠易激", "胸闷", "心悸", "失眠", "慢性疲劳"],
"physiological_pattern": {
"sympathetic_index": (0.5, 0.8),
"muscle_tension": (6, 10),
"fatigue_level": (6, 10),
"heart_rate": (70, 95),
"respiration_rate": (14, 18)
},
"behavioral_pattern": {
"au4_brow_lower": (2, 4),
"au7_lid_tightener": (2, 4),
"speech_rate": (2, 3.5)
}
},
EmotionCategory.HEART_WRENCHING: {
"mechanism": "情绪痛苦的躯体化",
"hormones": ["催产素", "皮质醇"],
"key_features": ["心脏区域收缩", "心脏下沉", "心脏攥紧感", "深切悲伤"],
"physiological_pattern": {
"heart_pain": (6, 10),
"sympathetic_index": (0.3, 0.6),
"heart_rate": (60, 80),
"stomach_discomfort": (4, 7)
},
"behavioral_pattern": {
"au1_inner_brow_raiser": (3, 5),
"au15_lip_corner_depressor": (3, 5),
"au25_lips_part": (2, 4)
}
},
EmotionCategory.CHEST_TIGHTNESS: {
"mechanism": "呼吸肌紧张 + 呼吸模式紊乱",
"hormones": ["肾上腺素", "皮质醇"],
"key_features": ["呼吸肌紧张", "浅快呼吸", "含胸压迫", "焦虑/恐惧"],
"physiological_pattern": {
"chest_tightness": (6, 10),
"respiration_rate": (18, 28),
"respiration_depth": (0.2, 0.5),
"sympathetic_index": (0.6, 0.9)
},
"behavioral_pattern": {
"au26_jaw_drop": (1, 3), # 呼吸困难
"speech_rate": (3, 5)
}
}
}
def __init__(self, model_weights: Optional[np.ndarray] = None):
"""初始化预测器"""
self.n_emotions = len(EmotionCategory)
self.n_features = 45 # 总特征数
# 基于知识的权重矩阵(知识驱动方法)
self.knowledge_weights = self._build_knowledge_weights()
# 如果提供了模型权重,使用机器学习模型
if model_weights is not None:
self.ml_weights = model_weights
self.use_hybrid = True
else:
self.use_hybrid = False
def _build_knowledge_weights(self) -> np.ndarray:
"""基于领域知识构建特征权重矩阵"""
weights = np.zeros((self.n_emotions, self.n_features))
# 特征名称到索引的映射
feature_names = [
# 生理特征 (0-9)
"heart_rate", "heart_rate_variability", "systolic_bp", "diastolic_bp",
"skin_conductance_level", "skin_conductance_response",
"respiration_rate", "respiration_depth", "skin_temperature", "sympathetic_index",
# 面部动作单元 (10-27)
"au1", "au4", "au5", "au6", "au7", "au9", "au10", "au12",
"au14", "au15", "au17", "au18", "au20", "au23", "au25", "au26", "au28",
# 语音特征 (28-31)
"voice_pitch", "voice_volume", "speech_rate", "voice_tremor",
# 心理特征 (32-44)
"valence", "arousal", "anger_int", "fear_int", "sadness_int",
"joy_int", "shame_int", "envy_int", "chest_tight",
"stomach_dis", "heart_pain", "muscle_tens", "fatigue"
]
# 基于情绪特征模式设置权重
for idx, emotion in enumerate(EmotionCategory):
emotion_data = self.EMOTION_KNOWLEDGE_BASE[emotion]
# 设置生理特征权重
phys_pattern = emotion_data.get("physiological_pattern", {})
if "sympathetic_index" in phys_pattern:
min_val, max_val = phys_pattern["sympathetic_index"]
weights[idx, 9] = (min_val + max_val) / 2 # sympathetic_index
if "heart_rate" in phys_pattern:
min_val, max_val = phys_pattern["heart_rate"]
weights[idx, 0] = 0.7 # heart_rate
if "skin_temperature" in phys_pattern:
min_val, max_val = phys_pattern["skin_temperature"]
weights[idx, 8] = 0.6 # skin_temperature
# 设置行为特征权重
behavior_pattern = emotion_data.get("behavioral_pattern", {})
au_mapping = {
"au1_inner_brow_raiser": 10, "au4_brow_lower": 11,
"au5_upper_lid_raiser": 12, "au6_cheek_raiser": 13,
"au7_lid_tightener": 14, "au9_nose_wrinkler": 15,
"au10_upper_lip_raiser": 16, "au12_lip_corner_puller": 17,
"au14_dimpler": 18, "au15_lip_corner_depressor": 19,
"au17_chin_raiser": 20, "au18_lip_puckerer": 21,
"au20_lip_stretcher": 22, "au23_lip_tightener": 23,
"au25_lips_part": 24, "au26_jaw_drop": 25, "au28_lip_suck": 26
}
for au_name, au_idx in au_mapping.items():
if au_name in behavior_pattern:
weights[idx, au_idx] = 0.8
# 设置语音特征权重
if "voice_volume" in behavior_pattern:
weights[idx, 29] = 0.6
if "voice_pitch" in behavior_pattern:
weights[idx, 28] = 0.5
if "speech_rate" in behavior_pattern:
weights[idx, 30] = 0.5
if "voice_tremor" in behavior_pattern:
weights[idx, 31] = 0.7
# 设置心理特征权重
key_features = emotion_data.get("key_features", [])
if any(f in key_features for f in ["面红", "发热", "身体发热"]):
weights[idx, 42] = 0.7 # muscle_tension
if any(f in key_features for f in ["胸闷", "呼吸"]):
weights[idx, 40] = 0.8 # chest_tightness
if any(f in key_features for f in ["胃部下沉", "胃痉挛", "胃部紧缩", "胃痛"]):
weights[idx, 41] = 0.8 # stomach_discomfort
if any(f in key_features for f in ["心痛", "心脏区域"]):
weights[idx, 42] = 0.9 # heart_pain
if any(f in key_features for f in ["肩颈", "肌肉", "僵硬"]):
weights[idx, 43] = 0.7 # muscle_tension
if any(f in key_features for f in ["疲劳", "乏力", "沉重", "嗜睡"]):
weights[idx, 44] = 0.8 # fatigue
return weights
def predict(self, state: EmotionalState) -> Dict[EmotionCategory, float]:
"""
预测情绪状态
Args:
state: 情绪状态对象
Returns:
各情绪类别的概率分布
"""
features = state.to_feature_vector()
if self.use_hybrid:
# 混合方法:结合知识驱动和数据驱动
knowledge_scores = self._compute_knowledge_scores(features)
ml_scores = self._compute_ml_scores(features)
# 加权融合
final_scores = 0.4 * knowledge_scores + 0.6 * ml_scores
else:
# 纯知识驱动方法
final_scores = self._compute_knowledge_scores(features)
# Softmax 归一化
exp_scores = np.exp(final_scores - np.max(final_scores))
probs = exp_scores / exp_scores.sum()
# 转换为概率字典
result = {}
for idx, emotion in enumerate(EmotionCategory):
result[emotion] = float(probs[idx])
return result
def _compute_knowledge_scores(self, features: np.ndarray) -> np.ndarray:
"""基于知识规则计算情绪得分"""
scores = np.zeros(self.n_emotions)
for idx, emotion in enumerate(EmotionCategory):
emotion_data = self.EMOTION_KNOWLEDGE_BASE[emotion]
score = 0.0
pattern_matches = 0
# 匹配生理模式
phys_pattern = emotion_data.get("physiological_pattern", {})
if "sympathetic_index" in phys_pattern:
min_val, max_val = phys_pattern["sympathetic_index"]
actual_val = features[9]
if min_val <= actual_val <= max_val:
score += 1.0
pattern_matches += 1
if "heart_rate" in phys_pattern:
min_val, max_val = phys_pattern["heart_rate"]
actual_val = features[0]
if min_val <= actual_val <= max_val:
score += 0.8
pattern_matches += 1
if "skin_temperature" in phys_pattern:
min_val, max_val = phys_pattern["skin_temperature"]
actual_val = features[8]
if min_val <= actual_val <= max_val:
score += 0.7
pattern_matches += 1
if "respiration_rate" in phys_pattern:
min_val, max_val = phys_pattern["respiration_rate"]
actual_val = features[6]
if min_val <= actual_val <= max_val:
score += 0.6
pattern_matches += 1
# 匹配心理特征
key_features = emotion_data.get("key_features", [])
# 根据关键特征进行评分
if any(f in key_features for f in ["胸闷", "呼吸浅快", "呼吸肌紧张"]):
chest_tight = features[40]
if chest_tight > 0.5:
score += chest_tight * 0.8
if any(f in key_features for f in ["胃部下沉", "胃痉挛", "胃部紧缩", "胃痛"]):
stomach = features[41]
if stomach > 0.3:
score += stomach * 0.8
if any(f in key_features for f in ["心痛", "心脏区域收缩", "心脏下沉"]):
heart_pain = features[42]
if heart_pain > 0.3:
score += heart_pain * 0.9
if any(f in key_features for f in ["肩颈", "肌肉紧张", "僵硬"]):
muscle = features[43]
if muscle > 0.3:
score += muscle * 0.7
if any(f in key_features for f in ["疲劳", "乏力", "沉重", "嗜睡"]):
fatigue = features[44]
if fatigue > 0.3:
score += fatigue * 0.8
# 行为特征匹配
behavior_pattern = emotion_data.get("behavioral_pattern", {})
# 嘴角上扬 (微笑) - 喜悦
if "au12_lip_corner_puller" in behavior_pattern:
if features[17] > 2:
if emotion == EmotionCategory.JOY_EXCITEMENT:
score += features[17] * 0.3
# 面颊提升 (苹果肌) - 喜悦
if "au6_cheek_raiser" in behavior_pattern:
if features[13] > 2:
if emotion == EmotionCategory.JOY_EXCITEMENT:
score += features[13] * 0.3
# 眉毛内端上扬 - 悲伤
if "au1_inner_brow_raiser" in behavior_pattern:
if features[10] > 2:
if emotion in [EmotionCategory.SADNESS_DEPRESSION,
EmotionCategory.HEART_WRENCHING]:
score += features[10] * 0.3
# 眉毛下压 - 愤怒
if "au4_brow_lower" in behavior_pattern:
if features[11] > 2:
if emotion == EmotionCategory.ANGER:
score += features[11] * 0.3
# 声音颤抖 - 紧张/恐惧
if "voice_tremor" in behavior_pattern:
if features[31] > 0.3:
if emotion in [EmotionCategory.FEAR_ANXIETY,
EmotionCategory.SHAME_EMBARRASSMENT]:
score += features[31] * 0.4
# 正负性情绪效价匹配
valence = features[32]
if emotion in [EmotionCategory.JOY_EXCITEMENT]:
if valence > 0.5:
score += valence * 0.5
elif emotion in [EmotionCategory.ANGER, EmotionCategory.FEAR_ANXIETY,
EmotionCategory.SADNESS_DEPRESSION, EmotionCategory.SHAME_EMBARRASSMENT,
EmotionCategory.JEALOUSY_ENVY]:
if valence < -0.3:
score += abs(valence) * 0.5
scores[idx] = score
return scores
def _compute_ml_scores(self, features: np.ndarray) -> np.ndarray:
"""使用机器学习模型计算得分"""
# 简化版本:使用线性模型
return np.dot(self.ml_weights, features)
def get_prediction_explanation(self, state: EmotionalState) -> Dict:
"""
获取预测结果的解释
Returns:
包含预测结果和解释的字典
"""
probs = self.predict(state)
# 获取最高概率的情绪
sorted_emotions = sorted(probs.items(), key=lambda x: x[1], reverse=True)
primary_emotion = sorted_emotions[0][0]
primary_prob = sorted_emotions[0][1]
# 获取对应的知识解释
emotion_data = self.EMOTION_KNOWLEDGE_BASE[primary_emotion]
explanation = {
"primary_emotion": {
"category": primary_emotion.value,
"probability": primary_prob,
"mechanism": emotion_data["mechanism"],
"hormones": emotion_data["hormones"],
"key_features": emotion_data["key_features"]
},
"all_probabilities": {e.value: p for e, p in probs.items()},
"top_3_emotions": [
{"category": e.value, "probability": p}
for e, p in sorted_emotions[:3]
]
}
return explanationclass EmotionDataGenerator:
"""情绪数据生成器(用于模型训练)"""
def __init__(self, predictor: EmotionPredictor):
self.predictor = predictor
def generate_training_data(
self,
n_samples: int = 1000,
noise_level: float = 0.1
) -> Tuple[np.ndarray, np.ndarray]:
"""
生成训练数据
基于知识库中的情绪特征模式,生成带有噪声的模拟数据
"""
X = []
y = []
for emotion in EmotionCategory:
emotion_data = predictor.EMOTION_KNOWLEDGE_BASE[emotion]
phys_pattern = emotion_data.get("physiological_pattern", {})
behavior_pattern = emotion_data.get("behavioral_pattern", {})
for _ in range(n_samples // len(EmotionCategory)):
# 生成符合模式的样本
features = self._generate_sample(emotion, phys_pattern, behavior_pattern, noise_level)
X.append(features)
y.append(emotion)
X = np.array(X)
y = np.array([e.value for e in y])
return X, y
def _generate_sample(
self,
emotion: EmotionCategory,
phys_pattern: Dict,
behavior_pattern: Dict,
noise_level: float
) -> np.ndarray:
"""生成单个样本"""
np.random.seed()
features = np.zeros(45)
# 生理特征 (0-9)
for i, (param, (min_val, max_val)) in enumerate(phys_pattern.items()):
base_val = (min_val + max_val) / 2
noise = np.random.uniform(-noise_level, noise_level) * (max_val - min_val)
features[i] = np.clip(base_val + noise, min_val * 0.8, max_val * 1.2)
# 设置默认生理值(如果在模式中未指定)
if features[0] == 0: # heart_rate
features[0] = np.random.uniform(60, 100)
if features[9] == 0: # sympathetic_index
features[9] = np.random.uniform(0.3, 0.7)
# 面部动作单元 (10-27)
for i in range(10, 27):
if np.random.random() > 0.5:
features[i] = np.random.uniform(0, 3) * noise_level * 2
else:
features[i] = np.random.uniform(0, 1)
# 语音特征 (28-31)
features[28] = np.random.uniform(150, 300) # voice_pitch
features[29] = np.random.uniform(0.3, 0.7) # voice_volume
features[30] = np.random.uniform(2, 4) # speech_rate
features[31] = np.random.uniform(0.1, 0.3) # voice_tremor
# 心理特征 (32-44)
features[32] = np.random.uniform(-0.5, 0.5) # valence
features[33] = np.random.uniform(0.3, 0.7) # arousal
# 设置情绪特定的心理特征强度
if emotion in [EmotionCategory.ANGER]:
features[34] = np.random.uniform(5, 10) # anger_intensity
elif emotion in [EmotionCategory.FEAR_ANXIETY]:
features[35] = np.random.uniform(5, 10) # fear_intensity
elif emotion in [EmotionCategory.SADNESS_DEPRESSION]:
features[36] = np.random.uniform(5, 10) # sadness_intensity
elif emotion in [EmotionCategory.JOY_EXCITEMENT]:
features[37] = np.random.uniform(5, 10) # joy_intensity
elif emotion in [EmotionCategory.SHAME_EMBARRASSMENT]:
features[38] = np.random.uniform(5, 10) # shame_intensity
elif emotion in [EmotionCategory.JEALOUSY_ENVY]:
features[39] = np.random.uniform(5, 10) # envy_intensity
features[40] = np.random.uniform(1, 5) # chest_tightness
features[41] = np.random.uniform(1, 5) # stomach_discomfort
features[42] = np.random.uniform(1, 5) # heart_pain
features[43] = np.random.uniform(1, 5) # muscle_tension
features[44] = np.random.uniform(1, 5) # fatigue
return features
class EmotionModelTrainer:
"""情绪模型训练器"""
def __init__(self, predictor: EmotionPredictor):
self.predictor = predictor
self.data_generator = EmotionDataGenerator(predictor)
def train(
self,
n_epochs: int = 100,
learning_rate: float = 0.01,
batch_size: int = 32
) -> np.ndarray:
"""
训练机器学习模型
使用梯度下降优化线性分类器的权重
"""
# 生成训练数据
X, y = self.data_generator.generate_training_data(n_samples=2000, noise_level=0.15)
# 标签编码
emotion_to_idx = {e.value: i for i, e in enumerate(EmotionCategory)}
y_idx = np.array([emotion_to_idx[label] for label in y])
# 添加偏置项
X_bias = np.column_stack([np.ones(X.shape[0]), X])
# 初始化权重
n_features = X_bias.shape[1]
n_classes = len(EmotionCategory)
weights = np.random.randn(n_features, n_classes) * 0.01
# 训练参数
for epoch in range(n_epochs):
# Mini-batch 梯度下降
indices = np.random.permutation(X_bias.shape[0])
for start in range(0, X_bias.shape[0], batch_size):
end = min(start + batch_size, X_bias.shape[0])
batch_indices = indices[start:end]
X_batch = X_bias[batch_indices]
y_batch = y_idx[batch_indices]
# 前向传播
logits = np.dot(X_batch, weights)
probs = self._softmax(logits)
# 计算损失(交叉熵)
one_hot = np.zeros((len(y_batch), n_classes))
one_hot[np.arange(len(y_batch)), y_batch] = 1
loss = -np.sum(one_hot * np.log(probs + 1e-8)) / len(y_batch)
# 反向传播
grad = np.dot(X_batch.T, probs - one_hot) / len(y_batch)
weights -= learning_rate * grad
if (epoch + 1) % 20 == 0:
# 计算准确率
predictions = np.argmax(np.dot(X_bias, weights), axis=1)
accuracy = np.mean(predictions == y_idx)
print(f"Epoch {epoch + 1}/{n_epochs}, Loss: {loss:.4f}, Accuracy: {accuracy:.4f}")
# 保存权重(去掉偏置项)
return weights[1:, :] # 返回不带偏置的权重
def _softmax(self, x: np.ndarray) -> np.ndarray:
"""Softmax函数"""
exp_x = np.exp(x - np.max(x, axis=1, keepdims=True))
return exp_x / np.sum(exp_x, axis=1, keepdims=True)def create_sample_emotional_state(
heart_rate: float = 85,
sympathetic_index: float = 0.75,
chest_tightness: float = 7.0,
stomach_discomfort: float = 5.0,
muscle_tension: float = 6.0
) -> EmotionalState:
"""创建示例情绪状态"""
# 生理特征
phys = PhysiologicalFeatures(
heart_rate=heart_rate,
heart_rate_variability=35,
systolic_bp=150,
diastolic_bp=95,
skin_conductance_level=15,
skin_conductance_response=1.2,
respiration_rate=20,
respiration_depth=0.5,
skin_temperature=35.0,
sympathetic_index=sympathetic_index
)
# 行为特征
behavior = BehavioralFeatures(
au1_inner_brow_raiser=2.0,
au4_brow_lower=3.5,
au5_upper_lid_raiser=2.5,
au6_cheek_raiser=1.0,
au7_lid_tightener=3.0,
au9_nose_wrinkler=2.0,
au10_upper_lip_raiser=1.0,
au12_lip_corner_puller=1.5,
au14_dimpler=1.0,
au15_lip_corner_depressor=2.0,
au17_chin_raiser=1.5,
au18_lip_puckerer=1.0,
au20_lip_stretcher=2.0,
au23_lip_tightener=3.0,
au25_lips_part=1.5,
au26_jaw_drop=1.0,
au28_lip_suck=0.5,
voice_pitch=250,
voice_volume=0.6,
speech_rate=3.5,
voice_tremor=0.2
)
# 心理特征
psych = PsychologicalFeatures(
valence=-0.4,
arousal=0.7,
anger_intensity=6.0,
fear_intensity=4.0,
sadness_intensity=3.0,
joy_intensity=1.0,
shame_intensity=2.0,
envy_intensity=2.0,
chest_tightness=chest_tightness,
stomach_discomfort=stomach_discomfort,
heart_pain=3.0,
muscle_tension=muscle_tension,
fatigue_level=4.0
)
return EmotionalState(
physiological=phys,
behavioral=behavior,
psychological=psych
)
def main():
"""主函数:情绪预测模型的使用"""
print("=" * 60)
print("情绪预测模型")
print("=" * 60)
# 初始化预测器
predictor = EmotionPredictor()
# 示例1:愤怒情绪状态
print("\n【示例1:愤怒情绪】")
angry_state = create_sample_emotional_state(
heart_rate=110,
sympathetic_index=0.85,
chest_tightness=3.0,
stomach_discomfort=2.0,
muscle_tension=8.0
)
result1 = predictor.get_prediction_explanation(angry_state)
print(f"预测结果: {result1['primary_emotion']['category']}")
print(f"概率: {result1['primary_emotion']['probability']:.2%}")
print(f"机制: {result1['primary_emotion']['mechanism']}")
print(f"关键激素: {', '.join(result1['primary_emotion']['hormones'])}")
print(f"典型特征: {', '.join(result1['primary_emotion']['key_features'])}")
# 示例2:焦虑/恐惧情绪状态
print("\n【示例2:焦虑/恐惧情绪】")
anxious_state = create_sample_emotional_state(
heart_rate=95,
sympathetic_index=0.78,
chest_tightness=8.0,
stomach_discomfort=7.0,
muscle_tension=5.0
)
# 调整心理特征
anxious_state.psychological.fear_intensity = 8.0
anxious_state.psychological.valence = -0.5
result2 = predictor.get_prediction_explanation(anxious_state)
print(f"预测结果: {result2['primary_emotion']['category']}")
print(f"概率: {result2['primary_emotion']['probability']:.2%}")
print(f"机制: {result2['primary_emotion']['mechanism']}")
print(f"关键激素: {', '.join(result2['primary_emotion']['hormones'])}")
print(f"典型特征: {', '.join(result2['primary_emotion']['key_features'])}")
# 示例3:悲伤/抑郁情绪状态
print("\n【示例3:悲伤/抑郁情绪】")
sad_state = create_sample_emotional_state(
heart_rate=65,
sympathetic_index=0.3,
chest_tightness=2.0,
stomach_discomfort=3.0,
muscle_tension=3.0
)
sad_state.psychological.sadness_intensity = 8.0
sad_state.psychological.valence = -0.7
sad_state.psychological.fatigue_level = 8.0
result3 = predictor.get_prediction_explanation(sad_state)
print(f"预测结果: {result3['primary_emotion']['category']}")
print(f"概率: {result3['primary_emotion']['probability']:.2%}")
print(f"机制: {result3['primary_emotion']['mechanism']}")
print(f"关键激素: {', '.join(result3['primary_emotion']['hormones'])}")
print(f"典型特征: {', '.join(result3['primary_emotion']['key_features'])}")
# 示例4:喜悦/兴奋情绪状态
print("\n【示例4:喜悦/兴奋情绪】")
joy_state = create_sample_emotional_state(
heart_rate=80,
sympathetic_index=0.6,
chest_tightness=1.0,
stomach_discomfort=1.0,
muscle_tension=2.0
)
joy_state.psychological.joy_intensity = 8.0
joy_state.psychological.valence = 0.7
# 设置面部表情特征为微笑
joy_state.behavioral.au6_cheek_raiser = 4.0
joy_state.behavioral.au12_lip_corner_puller = 4.0
joy_state.behavioral.au25_lips_part = 3.0
result4 = predictor.get_prediction_explanation(joy_state)
print(f"预测结果: {result4['primary_emotion']['category']}")
print(f"概率: {result4['primary_emotion']['probability']:.2%}")
print(f"机制: {result4['primary_emotion']['mechanism']}")
print(f"关键激素: {', '.join(result4['primary_emotion']['hormones'])}")
print(f"典型特征: {', '.join(result4['primary_emotion']['key_features'])}")
# 打印所有情绪类别的概率分布
print("\n" + "=" * 60)
print("情绪概率分布汇总")
print("=" * 60)
all_states = [
("愤怒", angry_state),
("焦虑", anxious_state),
("悲伤", sad_state),
("喜悦", joy_state)
]
for name, state in all_states:
probs = predictor.predict(state)
sorted_probs = sorted(probs.items(), key=lambda x: x[1], reverse=True)
print(f"\n{name}状态的情绪分布:")
for emotion, prob in sorted_probs[:3]:
print(f" {emotion.value}: {prob:.2%}")
print("\n" + "=" * 60)
print("运行完成")
print("=" * 60)
if __name__ == "__main__":
main()基于上述核心模型,我们可以构建一个完整的实时情绪监测系统,该系统集成了数据采集、特征提取、情绪预测和结果展示等功能模块。在实际应用中,系统需要与多种传感器和数据源进行对接,实现多模态数据的实时采集。生理信号数据可以通过可穿戴设备获取,这些设备通常配备光电容积脉搏波(PPG)传感器用于测量心率和心率变异性,皮肤电反应传感器用于测量皮肤电导变化,以及加速度计用于监测运动和活动水平。现代智能手表和健康手环已经具备这些基本功能,为情绪监测提供了便捷的硬件基础。
面部表情数据的采集需要使用摄像头设备,配合计算机视觉算法进行实时分析。深度学习模型(如卷积神经网络)可以从视频流中自动检测人脸并提取面部动作单元的激活强度。我们可以使用预先训练的人脸检测模型(如MTCNN或RetinaFace)进行人脸定位,然后使用专门的AU检测模型(如OpenFace或BP4D)提取动作单元特征。这些特征将实时传输给情绪预测模型进行处理。
语音数据的采集需要使用麦克风设备,配合语音处理算法提取声学特征。常用的语音情绪识别特征包括韵律特征(基频、能量、语速)、声学特征(梅尔频率倒谱系数MFCC)和语言特征(语音内容中的情感词汇)。通过实时分析语音信号,系统可以检测说话者的情绪状态变化,这对于电话客服、远程心理咨询等应用场景具有重要价值。
当前的情绪预测模型主要基于知识驱动的方法,结合了图片中提供的情绪-特征映射关系。为了进一步提升模型的预测准确率和泛化能力,我们可以从以下几个方面进行优化。
首先,可以引入深度学习方法来增强模型的特征提取和模式识别能力。循环神经网络(RNN)和长短期记忆网络(LSTM)非常适合处理时序生理信号数据,能够捕捉情绪状态在时间维度上的动态变化规律。Transformer架构及其变体(如BERT、ViT)可以用于处理多模态数据融合问题,通过注意力机制自动学习不同特征模态之间的关联关系。图神经网络(GNN)可以用于建模情绪状态之间的转换关系,这对于理解情绪的演化规律和预测情绪变化趋势具有重要意义。
其次,可以引入迁移学习和领域适应技术来解决标注数据不足的问题。情绪相关的标注数据通常难以获取,特别是包含详细生理信号和专家标注的数据集相对稀缺。通过在大规模通用数据集上进行预训练,然后在特定领域数据进行微调,可以有效利用已有知识提升模型性能。自监督学习方法可以从无标注数据中学习有用的表征,进一步减少对标注数据的依赖。
第三,可以增强模型的可解释性和可信度。当前的知识驱动方法已经具有一定的可解释性,因为我们可以通过分析特征权重和匹配规则来解释预测结果。未来的改进可以引入更多的解释性AI技术,如LIME(局部可解释模型-agnostic解释)和SHAP(SHapley Additive exPlanations),为用户提供详细的预测依据和置信度评估。这对于医疗健康等高风险应用场景尤为重要,能够帮助专业人员和用户理解模型的决策过程。
第四,可以实现个性化定制以适应个体差异。不同个体在情绪表达和生理反应方面存在显著差异,同一情绪在不同人身上可能表现出不同的特征模式。通过收集用户的历史数据并进行个性化校准,模型可以学习每个个体的独特情绪特征模式,从而提供更准确的个性化预测。联邦学习技术可以在保护用户隐私的前提下实现跨用户的模型协作训练,既保护个人数据安全又能充分利用集体智慧。
本情绪预测模型基于图片中提供的科学情绪分类框架,整合了心理体验、生理机制、激素作用和身体反应等多维度信息,构建了一个系统化的情绪识别体系。该模型不仅能够实现高准确率的情绪分类,还能够深入分析情绪背后的生物学机制,为用户提供有价值的情绪洞察和健康建议。
情绪预测技术在心理健康支持、人机交互、智能客服、教育培训和健康管理等领域具有广阔的应用前景。随着传感器技术的进步、人工智能算法的发展以及公众对心理健康重视程度的提升,情绪智能系统将成为未来智能生活的重要组成部分。本模型为构建此类系统提供了坚实的技术基础和理论框架,期待在更多实际应用场景中发挥价值。