|
""" |
|
modules/analyzer.py - Emotionsanalyse-Modul für den Dr. Franz Psychochatbot |
|
|
|
Dieses Modul analysiert die Nutzereingaben, um Emotionen und Themen zu erkennen: |
|
- Emotionserkennung über API |
|
- Themenidentifikation |
|
- Anpassung der Antwortstrategien |
|
""" |
|
|
|
import requests |
|
import random |
|
from typing import Dict, Any, Optional, List, Tuple |
|
|
|
|
|
import config |
|
|
|
class Analyzer: |
|
"""Klasse zur Analyse von Nutzereingaben""" |
|
|
|
def __init__(self, api_token: str = config.API_TOKEN): |
|
"""Initialisiert den Analyzer mit API-Token""" |
|
self.api_token = api_token |
|
|
|
self.positive_words = [ |
|
"glücklich", "froh", "zufrieden", "gut", "großartig", "toll", "wunderbar", |
|
"fantastisch", "begeistert", "erfreut", "dankbar", "hoffnungsvoll", "optimistisch" |
|
] |
|
self.negative_words = [ |
|
"traurig", "wütend", "verärgert", "frustriert", "enttäuscht", "ängstlich", |
|
"besorgt", "verzweifelt", "hoffnungslos", "deprimiert", "unglücklich", "schlecht", |
|
"hasse", "Angst", "Sorge", "Problem", "schwierig", "schlimm", "schrecklich" |
|
] |
|
self.neutral_words = [ |
|
"denke", "glaube", "meine", "verstehe", "sehe", "höre", "fühle", |
|
"normal", "gewöhnlich", "alltäglich", "regelmäßig" |
|
] |
|
|
|
def analyze_emotion(self, text: str) -> str: |
|
""" |
|
Analysiert die Emotion in einem Text ohne ML-Bibliotheken |
|
|
|
Args: |
|
text: Der zu analysierende Text |
|
|
|
Returns: |
|
"positive", "negative" oder "neutral" |
|
""" |
|
text = text.lower() |
|
|
|
|
|
positive_count = sum(1 for word in self.positive_words if word in text) |
|
negative_count = sum(1 for word in self.negative_words if word in text) |
|
neutral_count = sum(1 for word in self.neutral_words if word in text) |
|
|
|
|
|
negative_count *= 1.5 |
|
|
|
|
|
if negative_count > positive_count: |
|
return "negative" |
|
elif positive_count > negative_count and positive_count > neutral_count: |
|
return "positive" |
|
else: |
|
return "neutral" |
|
|
|
def analyze_themes(self, text: str) -> Dict[str, Any]: |
|
""" |
|
Identifiziert psychologisch relevante Themen und ihre manipulative Nutzung |
|
|
|
Args: |
|
text: Der zu analysierende Text |
|
|
|
Returns: |
|
Dictionary mit Themen und manipulativen Aspekten |
|
""" |
|
text = text.lower() |
|
analysis = { |
|
"themes": [], |
|
"manipulative_aspects": {}, |
|
"vulnerabilities": [] |
|
} |
|
|
|
|
|
theme_keywords = { |
|
"Familie": { |
|
"keywords": ["familie", "mutter", "vater", "eltern", "kind"], |
|
"manipulation": "Die familiären Beziehungen sind ein perfektes Terrain für Projektion und Verdrängung." |
|
}, |
|
"Beziehungen": { |
|
"keywords": ["beziehung", "partner", "freund", "ehe"], |
|
"manipulation": "Beziehungen sind ideale Spiegel für unbewusste Konflikte." |
|
}, |
|
"Selbstwert": { |
|
"keywords": ["selbstwert", "stolz", "scham"], |
|
"manipulation": "Der Selbstwert ist empfänglich für Schuldzuweisungen und Gaslighting." |
|
}, |
|
"Ängste": { |
|
"keywords": ["angst", "sorge", "panik"], |
|
"manipulation": "Ängste können verstärkt werden, um Kontrolle auszuüben." |
|
} |
|
} |
|
|
|
|
|
for theme, data in theme_keywords.items(): |
|
if any(keyword in text for keyword in data["keywords"]): |
|
analysis["themes"].append(theme) |
|
analysis["manipulative_aspects"][theme] = data["manipulation"] |
|
|
|
|
|
if "schuld" in text or "scham" in text: |
|
analysis["vulnerabilities"].append(f"{theme}_guilt") |
|
if "angst" in text: |
|
analysis["vulnerabilities"].append(f"{theme}_fear") |
|
|
|
return analysis |
|
|
|
def analyze_complexity(self, text: str) -> int: |
|
""" |
|
Bewertet die Komplexität der Nutzereingabe (1-5) |
|
|
|
Args: |
|
text: Der zu analysierende Text |
|
|
|
Returns: |
|
Komplexitätsstufe von 1 (einfach) bis 5 (komplex) |
|
""" |
|
|
|
words = text.split() |
|
word_count = len(words) |
|
avg_word_length = sum(len(word) for word in words) / max(1, word_count) |
|
sentence_count = text.count('.') + text.count('!') + text.count('?') |
|
|
|
|
|
complex_indicators = [ |
|
"weil", "obwohl", "trotzdem", "dennoch", "allerdings", |
|
"einerseits", "andererseits", "jedoch", "nichtsdestotrotz", |
|
"möglicherweise", "vielleicht", "wahrscheinlich", "vermutlich" |
|
] |
|
|
|
complex_count = sum(1 for word in complex_indicators if word in text.lower()) |
|
|
|
|
|
if word_count < 5: |
|
return 1 |
|
elif word_count < 15 and complex_count == 0: |
|
return 2 |
|
elif word_count < 30 and complex_count <= 1: |
|
return 3 |
|
elif word_count < 50 and complex_count <= 2: |
|
return 4 |
|
else: |
|
return 5 |
|
|
|
def get_analysis_result(self, text: str) -> Dict[str, Any]: |
|
""" |
|
Führt eine vollständige Analyse des Textes durch |
|
|
|
Args: |
|
text: Der zu analysierende Text |
|
|
|
Returns: |
|
Dictionary mit Analyseergebnissen |
|
""" |
|
emotion = self.analyze_emotion(text) |
|
themes = self.analyze_themes(text) |
|
complexity = self.analyze_complexity(text) |
|
|
|
return { |
|
"emotion": emotion, |
|
"themes": themes, |
|
"complexity": complexity, |
|
"suggested_intensity": min(complexity + (1 if emotion == "negative" else 0), 5) |
|
} |
|
|