UNPKG

soul-mirror

Version:

🔮 融合千年易学智慧与现代AI技术,为程序员量身打造的命理情绪分析工具。94.1%情绪识别准确率,秒级响应,支持五行人格分析与实时运势指导。

297 lines (266 loc) 8.47 kB
/** * 时间与语境修正模块 * @module ContextEmotionCorrector * @since 0.8.0 */ // 昼夜节律对情绪的影响系数 const TIME_EMOTION_WEIGHTS = { 'morning': { // 6:00-11:00 '高兴': 1.2, '愤怒': 0.8, '悲伤': 0.7, '焦虑': 0.9, '平静': 1.1, '疲惫': 0.6, '惊讶': 1.0, '无聊': 0.8 }, // 下午 (11:00-17:00) - 情绪相对平衡 'afternoon': { '高兴': 1.0, '愤怒': 1.0, '悲伤': 1.0, '焦虑': 1.1, '平静': 1.0, '疲惫': 1.2, '惊讶': 1.0, '无聊': 1.1 }, // 傍晚 (17:00-22:00) - 更容易疲惫和放松 'evening': { '高兴': 1.1, '愤怒': 1.1, '悲伤': 1.0, '焦虑': 1.2, '平静': 1.2, '疲惫': 1.3, '惊讶': 0.9, '无聊': 1.0 }, // 深夜 (22:00-6:00) - 更容易负面情绪 'night': { '高兴': 0.8, '愤怒': 1.2, '悲伤': 1.3, '焦虑': 1.4, '平静': 0.9, '疲惫': 1.5, '惊讶': 0.8, '无聊': 1.2 } }; // 上下文关键词修正规则 const CONTEXT_CORRECTION_RULES = { // 工作相关上下文 'work': { keywords: ['代码', '项目', '工作', 'bug', '加班', '开发', '程序', '系统', '功能', 'deadline', 'review'], adjustments: { '高兴': { bonus: 0.1, reason: '工作成就感加成' }, '愤怒': { bonus: 0.2, reason: '工作压力放大' }, '焦虑': { bonus: 0.2, reason: '工作焦虑加强' }, '疲惫': { bonus: 0.3, reason: '工作疲劳明显' } } }, // 学习相关上下文 'learning': { keywords: ['学习', '掌握', '理解', '搞懂', '弄明白', '学会', '教程', '文档', '知识'], adjustments: { '高兴': { bonus: 0.2, reason: '学习成就感' }, '焦虑': { bonus: 0.1, reason: '学习压力' }, '惊讶': { bonus: 0.2, reason: '学习发现' } } }, // 社交相关上下文 'social': { keywords: ['团队', '同事', '朋友', '聊天', '交流', '讨论', '分享', '合作'], adjustments: { '高兴': { bonus: 0.1, reason: '社交正面情绪' }, '愤怒': { bonus: 0.1, reason: '人际冲突' }, '悲伤': { bonus: 0.1, reason: '社交压力' } } }, // 成就相关上下文 'achievement': { keywords: ['完成', '成功', '搞定', '解决', '实现', '达成', '通过', '拿下'], adjustments: { '高兴': { bonus: 0.3, reason: '成就感强烈' }, '平静': { bonus: 0.1, reason: '完成后的平静' } } }, // 问题相关上下文 'problem': { keywords: ['问题', '错误', '失败', '崩溃', '报错', '异常', '故障', '卡住'], adjustments: { '愤怒': { bonus: 0.2, reason: '问题带来挫折' }, '焦虑': { bonus: 0.2, reason: '问题引发焦虑' }, '疲惫': { bonus: 0.1, reason: '解决问题的疲劳' } } } }; // 情绪强度修正词汇 const INTENSITY_MODIFIERS = { 'extreme': { keywords: ['超级', '特别', '非常', '巨', '极', '死了', '疯了', '炸了', '爆了', '翻了'], multiplier: 1.5 }, 'high': { keywords: ['很', '太', '好', '挺', '蛮', '相当', '真的'], multiplier: 1.2 }, 'mild': { keywords: ['有点', '稍微', '还行', '一般', '不太', '略'], multiplier: 0.8 } }; class ContextEmotionCorrector { constructor() { this.debugMode = false; } /** * 对情绪识别结果进行上下文修正 * @param {string} originalText - 原始文本 * @param {Object} emotionResult - 原始情绪识别结果 * @returns {Object} 修正后的情绪结果 */ correctWithContext(originalText, emotionResult) { const corrections = { timeWeight: 1.0, contextBonus: 0, intensityMultiplier: 1.0, appliedRules: [] }; // 1. 时间段修正 const timeWeight = this._getTimeWeight(emotionResult.main); corrections.timeWeight = timeWeight; // 2. 上下文修正 const contextCorrection = this._getContextCorrection(originalText, emotionResult.main); corrections.contextBonus = contextCorrection.bonus; corrections.appliedRules.push(...contextCorrection.rules); // 3. 强度修正 const intensityMultiplier = this._getIntensityMultiplier(originalText); corrections.intensityMultiplier = intensityMultiplier; // 4. 重新计算所有情绪得分 const correctedScores = {}; Object.keys(emotionResult.scores).forEach(emotion => { let score = emotionResult.scores[emotion]; // 应用时间权重 const emotionTimeWeight = this._getTimeWeight(emotion); score *= emotionTimeWeight; // 应用上下文加成 const emotionContext = this._getContextCorrection(originalText, emotion); score += emotionContext.bonus; // 应用强度修正 score *= intensityMultiplier; correctedScores[emotion] = Math.max(0, score); }); // 5. 重新确定主情绪 const sortedEmotions = Object.keys(correctedScores) .sort((a, b) => correctedScores[b] - correctedScores[a]); const newMainEmotion = sortedEmotions[0]; const newSecondaryEmotions = sortedEmotions.slice(1).filter(e => correctedScores[e] > 0); // 6. 重新计算置信度 const maxScore = correctedScores[newMainEmotion]; const totalScore = Object.values(correctedScores).reduce((sum, score) => sum + score, 0); const newConfidence = totalScore > 0 ? Math.min(95, Math.max(15, Math.round((maxScore / totalScore) * 100))) : emotionResult.confidence; return { ...emotionResult, main: newMainEmotion, secondary: newSecondaryEmotions.slice(0, 2), scores: correctedScores, confidence: newConfidence, corrections: corrections, _originalResult: emotionResult }; } /** * 获取当前时间段的情绪权重 * @private */ _getTimeWeight(emotion) { const hour = new Date().getHours(); let timeSlot; if (hour >= 6 && hour < 11) { timeSlot = 'morning'; } else if (hour >= 11 && hour < 17) { timeSlot = 'afternoon'; } else if (hour >= 17 && hour < 22) { timeSlot = 'evening'; } else { timeSlot = 'night'; } return TIME_EMOTION_WEIGHTS[timeSlot][emotion] || 1.0; } /** * 获取上下文修正 * @private */ _getContextCorrection(text, emotion) { let totalBonus = 0; const appliedRules = []; Object.entries(CONTEXT_CORRECTION_RULES).forEach(([contextType, rule]) => { const matchedKeywords = rule.keywords.filter(keyword => text.toLowerCase().includes(keyword.toLowerCase()) ); if (matchedKeywords.length > 0) { const adjustment = rule.adjustments[emotion]; if (adjustment) { // 匹配关键词越多,加成越大,但有上限 const keywordBonus = Math.min(matchedKeywords.length * adjustment.bonus, adjustment.bonus * 2); totalBonus += keywordBonus; appliedRules.push({ context: contextType, keywords: matchedKeywords, bonus: keywordBonus, reason: adjustment.reason }); } } }); return { bonus: totalBonus, rules: appliedRules }; } /** * 获取强度修正倍数 * @private */ _getIntensityMultiplier(text) { const lowerText = text.toLowerCase(); // 检查极强强度词汇 for (const keyword of INTENSITY_MODIFIERS.extreme.keywords) { if (lowerText.includes(keyword)) { return INTENSITY_MODIFIERS.extreme.multiplier; } } // 检查高强度词汇 for (const keyword of INTENSITY_MODIFIERS.high.keywords) { if (lowerText.includes(keyword)) { return INTENSITY_MODIFIERS.high.multiplier; } } // 检查轻度强度词汇 for (const keyword of INTENSITY_MODIFIERS.mild.keywords) { if (lowerText.includes(keyword)) { return INTENSITY_MODIFIERS.mild.multiplier; } } return 1.0; } /** * 设置调试模式 */ setDebugMode(enabled) { this.debugMode = enabled; } /** * 获取当前时间段描述 */ getCurrentTimeSlot() { const hour = new Date().getHours(); if (hour >= 6 && hour < 11) return '早晨'; if (hour >= 11 && hour < 17) return '下午'; if (hour >= 17 && hour < 22) return '傍晚'; return '深夜'; } } module.exports = ContextEmotionCorrector;