Feature: Football Emotion Classifier
Relevant source files
The following files were used as context for generating this wiki page:The Football Emotion Classifier is a specialized module designed to perform nuanced emotional analysis on text comments related to Indonesian football. It moves beyond simple positive/negative/neutral sentiment to classify comments into six distinct, football-specific emotional categories. This provides deeper, more actionable insights into public opinion regarding players, coaching, and team performance.
The classified data is used to power the "Emotion Insights" (/emotions) page on the dashboard, which is dedicated to the in-depth analysis of emotions found in the comments. This allows users to understand not just if the public is negative, but why—are they disappointed, frustrated with strategy, or expressing patriotic sadness?
Sources: src/analysis/football_emotion_classifier.py:1-12, dashboard-next/DASHBOARD_STRUCTURE.md:29-39
Architecture Overview
The Football Emotion Classifier is a multi-stage system that involves offline processing, data storage in CSV files, API data serving, and frontend visualization.
The overall data flow is as follows:
- The
FootballEmotionClassifierPython class processes raw text comments. - It uses predefined keywords and regex patterns from
sentiment_config.pyand its own internal logic to assign an emotion label and confidence score. - The results are saved to processed CSV files (e.g.,
comments_fixed_labels.csv). - Next.js API routes (
/api/layersand/api/stats) read these CSV files. - The APIs process, aggregate, and format the emotion data into JSON.
- The frontend dashboard, particularly the
/emotionspage, fetches data from these APIs to render visualizations like bar charts and radar charts.
This diagram illustrates the high-level architecture of the emotion classification and visualization pipeline.
Python Classifier
The core of the feature is the FootballEmotionClassifier class, which handles the logic for classifying text into one of the defined emotional categories.
Sources: src/analysis/football_emotion_classifier.py:15-22
Emotion Categories
The classifier identifies six primary football-specific emotions, plus a neutral category. These are defined with specific keywords, regex patterns, and weights to ensure accurate, context-aware classification.
| Emotion Label | Description | Example Keywords |
|---|---|---|
passionate_disappointment | Deep disappointment from passionate fans. | kecewa berat, patah hati, hancur, nyesek |
strategic_frustration | Frustration with tactical decisions. | salah strategi, formasi salah, substitusi aneh |
patriotic_sadness | Nationalistic sadness about the country's team failure. | malu, negara, bangsa, merah putih, garuda |
constructive_anger | Anger that leads to constructive discussion or suggestions. | marah tapi, seharusnya, perlu, harus, kritik membangun |
respectful_acknowledgment | Acknowledging the opponent's strength or the reality of the situation. | lawan kuat, memang lebih baik, realistis, mengakui |
future_hope | Hope for future improvement and upcoming matches. | masih ada waktu, piala berikutnya, masa depan, optimis |
Sources: src/analysis/football_emotion_classifier.py:25-144, config/sentiment_config.py:42-101
Classification Logic
The classification process within the classify_emotion method follows a scoring-based approach.
- Scoring: For a given text, the
_calculate_emotion_scoresmethod calculates a score for each of the six emotions. - Keyword & Pattern Matching: The score is a sum of matches found:
- Simple keyword matches have a weight of
1. - Regex pattern matches have a weight of
2, giving them higher importance.
- Simple keyword matches have a weight of
- Primary Emotion: The emotion with the highest total score is selected as the primary emotion.
- Confidence Calculation:
- A base confidence is calculated as the ratio of the top score to the sum of all scores (
max_score / total_score). - This confidence is then adjusted based on the absolute value of the highest score (e.g., a score >= 3 boosts confidence).
- Finally, the confidence is adjusted again based on the
core_sentimentof the comment. For example, if the core sentiment is 'negative', the confidence for emotions likepassionate_disappointmentis increased.
- A base confidence is calculated as the ratio of the top score to the sum of all scores (
- Default Case: If no keywords or patterns match (max score is 0), the emotion is classified as
neutral_observation.
This flowchart details the logic within the classify_emotion method.
API Endpoints
The classified emotion data is exposed to the frontend via several API endpoints.
/api/layers
This endpoint reads the comments_fixed_labels.csv file to provide aggregated statistics for various classification layers, including emotions.
- Functionality: It reads the CSV, finds the
emotion_simplecolumn, and counts the occurrences of each unique emotion. - Output: The data is formatted into a JSON array, where each object represents an emotion and includes its name, count, percentage, color, and model accuracy.
Example JSON Response Snippet for emotion:
{
"emotion": [
{ "name": "Neutral", "value": 9057, "percentage": 47.1, "color": "#6b7280", "accuracy": 91.0 },
{ "name": "Hopeful", "value": 4260, "percentage": 22.2, "color": "#22c55e", "accuracy": 91.0 },
{ "name": "Disappointed", "value": 4134, "percentage": 21.5, "color": "#ef4444", "accuracy": 91.0 },
{ "name": "Frustrated", "value": 1300, "percentage": 6.8, "color": "#f59e0b", "accuracy": 91.0 },
{ "name": "Supportive", "value": 477, "percentage": 2.5, "color": "#3b82f6", "accuracy": 91.0 }
]
}
Sources: dashboard-next/app/api/layers/route.ts:39-50, 83-87
/api/stats
This endpoint reads comments_cleaned_readme_spec.csv and performs a more specific grouping of the football_emotion labels for the main dashboard's "Top Emotions" display.
- Functionality: It maps the granular emotion labels from the classifier into broader, more digestible categories.
- Grouping Logic: The endpoint aggregates multiple specific emotions into a single parent category.
The following table shows the mapping from the classifier's output to the API's grouped output.
Granular Emotion (football_emotion) | Grouped Emotion (topEmotions) |
|---|---|
passionate_disappointment | Kekecewaan |
strategic_frustration | Kemarahan |
patriotic_sadness | Kemarahan |
constructive_anger | Kemarahan |
future_hope | Harapan & Tuntutan |
respectful_acknowledgment | Dukungan |
neutral_observation | Kebanggaan |
Sources: dashboard-next/app/api/stats/route.ts:59-70, 142-152
Frontend Visualization
The processed emotion data is primarily visualized on the Emotion Insights page (/emotions), which is designed for a deep-dive analysis of the emotional landscape of the comments.
The page uses the following components to display the data:
- Horizontal Bar Chart: Shows the distribution percentage for each of the 5+ emotion categories.
- Radar Chart: Visualizes the intensity of different emotions.
- Emotion Cards: Provides detailed counts and percentages for each individual emotion.
This structured approach follows the design philosophy of "Progressive Disclosure," allowing users to move from a high-level overview on the main dashboard to a detailed emotional breakdown on this dedicated page.
Sources: dashboard-next/DASHBOARD_STRUCTURE.md:29-39, dashboard-next/MENU_GUIDE.md:69-95