“Transcendental-Programmer”
commited on
Commit
·
c3cc0a9
1
Parent(s):
325895a
first commit
Browse files- .gitattributes +5 -0
- .gitignore +47 -0
- README.md +8 -9
- app.py +59 -0
- config/__init__.py +1 -0
- config/config.py +60 -0
- dir_structure.md +82 -0
- docs/README.md +251 -0
- docs/ai_plan.md +936 -0
- docs/data_plan.md +313 -0
- docs/plan.md +864 -0
- models/intelligent_routing/generate_data.py +118 -0
- models/intelligent_routing/model.py +253 -0
- models/intelligent_routing/saved_model/model.keras +3 -0
- models/intelligent_routing/test_data/__init__.py +0 -0
- models/intelligent_routing/test_data/test_data.json +0 -0
- models/intelligent_routing/test_model.py +259 -0
- models/intelligent_routing/train.py +45 -0
- models/intelligent_routing/train_data/__init__.py +0 -0
- models/job_recommendation/generate_data.py +92 -0
- models/job_recommendation/model.py +144 -0
- models/job_recommendation/saved_model/model.keras +3 -0
- models/job_recommendation/test.py +96 -0
- models/job_recommendation/test_data/__init__.py +0 -0
- models/job_recommendation/test_data/test_data.json +0 -0
- models/job_recommendation/train.py +41 -0
- models/job_recommendation/train_data/__init__.py +0 -0
- models/multilingual_translation/model.py +184 -0
- models/multilingual_translation/test_data/__init__.py +0 -0
- models/multilingual_translation/test_data/test_data.json +156 -0
- models/multilingual_translation/test_model.py +160 -0
- models/multilingual_translation/train_data/__init__.py +0 -0
- models/multilingual_translation/train_data/training_data.json +7 -0
- models/sentiment_analysis/model.py +118 -0
- models/sentiment_analysis/test_data/__init__.py +0 -0
- models/sentiment_analysis/test_data/test_data.json +773 -0
- models/sentiment_analysis/test_model.py +125 -0
- models/sentiment_analysis/train_data/__init__.py +0 -0
- models/sentiment_analysis/train_data/training_data.json +7 -0
- requirements.txt +37 -0
- routes.py +21 -0
- space.yml +7 -0
- test_endpoints.py +437 -0
- test_results1/endpoint_test_results.json +157 -0
- utils/__init__.py +2 -0
- utils/dir_str_creater.py +35 -0
- utils/logger.py +30 -0
.gitattributes
CHANGED
@@ -33,3 +33,8 @@ saved_model/**/* filter=lfs diff=lfs merge=lfs -text
|
|
33 |
*.zip filter=lfs diff=lfs merge=lfs -text
|
34 |
*.zst filter=lfs diff=lfs merge=lfs -text
|
35 |
*tfevents* filter=lfs diff=lfs merge=lfs -text
|
|
|
|
|
|
|
|
|
|
|
|
33 |
*.zip filter=lfs diff=lfs merge=lfs -text
|
34 |
*.zst filter=lfs diff=lfs merge=lfs -text
|
35 |
*tfevents* filter=lfs diff=lfs merge=lfs -text
|
36 |
+
models/intelligent_routing/train_data/training_data.json filter=lfs diff=lfs merge=lfs -text
|
37 |
+
models/job_recommendation/train_data/training_data.json filter=lfs diff=lfs merge=lfs -text
|
38 |
+
*.keras filter=lfs diff=lfs merge=lfs -text
|
39 |
+
*.h5 filter=lfs diff=lfs merge=lfs -text
|
40 |
+
*.pkl filter=lfs diff=lfs merge=lfs -text
|
.gitignore
ADDED
@@ -0,0 +1,47 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
# Python
|
2 |
+
__pycache__/
|
3 |
+
*.py[cod]
|
4 |
+
*$py.class
|
5 |
+
*.so
|
6 |
+
.Python
|
7 |
+
env/
|
8 |
+
build/
|
9 |
+
develop-eggs/
|
10 |
+
dist/
|
11 |
+
downloads/
|
12 |
+
eggs/
|
13 |
+
.eggs/
|
14 |
+
lib/
|
15 |
+
lib64/
|
16 |
+
parts/
|
17 |
+
sdist/
|
18 |
+
var/
|
19 |
+
wheels/
|
20 |
+
*.egg-info/
|
21 |
+
.installed.cfg
|
22 |
+
*.egg
|
23 |
+
|
24 |
+
# Virtual Environment
|
25 |
+
venv/
|
26 |
+
myenv/
|
27 |
+
|
28 |
+
# IDE
|
29 |
+
.idea/
|
30 |
+
.vscode/
|
31 |
+
|
32 |
+
# Logs
|
33 |
+
*.log
|
34 |
+
test_results/
|
35 |
+
models/*/test_results/
|
36 |
+
|
37 |
+
# Environment variables
|
38 |
+
.env
|
39 |
+
.env.local
|
40 |
+
|
41 |
+
# Google Cloud
|
42 |
+
app.yaml
|
43 |
+
credentials.json
|
44 |
+
|
45 |
+
# Large training files
|
46 |
+
models/intelligent_routing/train_data/training_data.json
|
47 |
+
models/job_recommendation/train_data/training_data.json
|
README.md
CHANGED
@@ -1,14 +1,13 @@
|
|
1 |
---
|
2 |
-
title: Hostel Management
|
3 |
-
emoji:
|
4 |
colorFrom: blue
|
5 |
-
colorTo:
|
6 |
-
sdk:
|
7 |
-
|
8 |
-
app_file: app.py
|
9 |
pinned: false
|
10 |
-
license: mit
|
11 |
-
short_description: deployed the hmgrs
|
12 |
---
|
13 |
|
14 |
-
|
|
|
|
|
|
1 |
---
|
2 |
+
title: Hostel Management System
|
3 |
+
emoji: 🏨
|
4 |
colorFrom: blue
|
5 |
+
colorTo: green
|
6 |
+
sdk: docker
|
7 |
+
app_port: 7860
|
|
|
8 |
pinned: false
|
|
|
|
|
9 |
---
|
10 |
|
11 |
+
# Hostel Management System API
|
12 |
+
|
13 |
+
This is a Flask-based API for hostel management with ML capabilities.
|
app.py
ADDED
@@ -0,0 +1,59 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
import streamlit as st
|
2 |
+
from datetime import datetime
|
3 |
+
import logging
|
4 |
+
from routes import (
|
5 |
+
translation_model,
|
6 |
+
sentiment_model,
|
7 |
+
routing_model,
|
8 |
+
job_model
|
9 |
+
)
|
10 |
+
|
11 |
+
# Configure logging
|
12 |
+
logging.basicConfig(
|
13 |
+
level=logging.INFO,
|
14 |
+
format='%(asctime)s - %(name)s - %(levelname)s - %(message)s',
|
15 |
+
handlers=[logging.StreamHandler()]
|
16 |
+
)
|
17 |
+
|
18 |
+
# Page config
|
19 |
+
st.set_page_config(
|
20 |
+
page_title="Hostel Management System",
|
21 |
+
page_icon="🏨",
|
22 |
+
layout="wide"
|
23 |
+
)
|
24 |
+
|
25 |
+
def main():
|
26 |
+
st.title("🏨 Hostel Management System")
|
27 |
+
|
28 |
+
# Sidebar navigation
|
29 |
+
page = st.sidebar.selectbox(
|
30 |
+
"Select Service",
|
31 |
+
["Translation", "Sentiment Analysis", "Grievance Routing", "Job Recommendation"]
|
32 |
+
)
|
33 |
+
|
34 |
+
if page == "Translation":
|
35 |
+
translation_page()
|
36 |
+
elif page == "Sentiment Analysis":
|
37 |
+
sentiment_page()
|
38 |
+
elif page == "Grievance Routing":
|
39 |
+
routing_page()
|
40 |
+
else:
|
41 |
+
job_recommendation_page()
|
42 |
+
|
43 |
+
def translation_page():
|
44 |
+
st.header("Translation Service")
|
45 |
+
user_message = st.text_area("Enter text to translate")
|
46 |
+
target_lang = st.selectbox("Select target language", ["English", "Spanish", "French", "German"])
|
47 |
+
|
48 |
+
if st.button("Translate"):
|
49 |
+
if user_message:
|
50 |
+
result = translation_model.process_message({
|
51 |
+
"user_message": user_message,
|
52 |
+
"target_language": target_lang
|
53 |
+
})
|
54 |
+
st.success(result.get("translated_text", "Translation failed"))
|
55 |
+
|
56 |
+
# Add similar functions for other pages...
|
57 |
+
|
58 |
+
if __name__ == "__main__":
|
59 |
+
main()
|
config/__init__.py
ADDED
@@ -0,0 +1 @@
|
|
|
|
|
1 |
+
from .config import config_by_name, Config
|
config/config.py
ADDED
@@ -0,0 +1,60 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
import os
|
2 |
+
from dotenv import load_dotenv
|
3 |
+
|
4 |
+
# Load environment variables
|
5 |
+
load_dotenv()
|
6 |
+
|
7 |
+
class Config:
|
8 |
+
# API Configuration
|
9 |
+
API_VERSION = "v1"
|
10 |
+
API_TITLE = "Hostel Grievance System API"
|
11 |
+
DEBUG = os.getenv("DEBUG", True)
|
12 |
+
|
13 |
+
# Security
|
14 |
+
SECRET_KEY = os.getenv("SECRET_KEY", "your-secret-key-here")
|
15 |
+
JWT_SECRET_KEY = os.getenv("JWT_SECRET_KEY", "your-jwt-secret-key")
|
16 |
+
|
17 |
+
# Model Paths
|
18 |
+
INTELLIGENT_ROUTING_MODEL_PATH = "models/intelligent_routing/model/"
|
19 |
+
SENTIMENT_ANALYSIS_MODEL_PATH = "models/sentiment_analysis/model/"
|
20 |
+
MULTILINGUAL_TRANSLATION_MODEL_PATH = "models/multilingual_translation/model/"
|
21 |
+
JOB_RECOMMENDATION_MODEL_PATH = "models/job_recommendation/model/"
|
22 |
+
|
23 |
+
# Data Paths
|
24 |
+
TRAIN_DATA_PATH = "train_data/training_data.json"
|
25 |
+
TEST_DATA_PATH = "test_data/test_data.json"
|
26 |
+
|
27 |
+
# API Endpoints
|
28 |
+
INTELLIGENT_ROUTING_ENDPOINT = "/api/v1/intelligent-routing"
|
29 |
+
SENTIMENT_ANALYSIS_ENDPOINT = "/api/v1/sentiment-analysis"
|
30 |
+
MULTILINGUAL_TRANSLATION_ENDPOINT = "/api/v1/multilingual-translation"
|
31 |
+
JOB_RECOMMENDATION_ENDPOINT = "/api/v1/job-recommendation"
|
32 |
+
|
33 |
+
# Model Parameters
|
34 |
+
BATCH_SIZE = 32
|
35 |
+
LEARNING_RATE = 0.001
|
36 |
+
EPOCHS = 10
|
37 |
+
|
38 |
+
# Logging Configuration
|
39 |
+
LOG_LEVEL = "INFO"
|
40 |
+
LOG_FORMAT = "%(asctime)s - %(name)s - %(levelname)s - %(message)s"
|
41 |
+
LOG_FILE = "app.log"
|
42 |
+
|
43 |
+
class DevelopmentConfig(Config):
|
44 |
+
DEBUG = True
|
45 |
+
TESTING = False
|
46 |
+
|
47 |
+
class ProductionConfig(Config):
|
48 |
+
DEBUG = False
|
49 |
+
TESTING = False
|
50 |
+
|
51 |
+
class TestingConfig(Config):
|
52 |
+
DEBUG = True
|
53 |
+
TESTING = True
|
54 |
+
|
55 |
+
# Configuration dictionary
|
56 |
+
config_by_name = {
|
57 |
+
'dev': DevelopmentConfig,
|
58 |
+
'prod': ProductionConfig,
|
59 |
+
'test': TestingConfig
|
60 |
+
}
|
dir_structure.md
ADDED
@@ -0,0 +1,82 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
# Directory Structure
|
2 |
+
|
3 |
+
```
|
4 |
+
Directory Structure:
|
5 |
+
📁 config
|
6 |
+
📄 __init__.py
|
7 |
+
📄 config.py
|
8 |
+
📁 docs
|
9 |
+
📄 README.md
|
10 |
+
📄 ai_plan.md
|
11 |
+
📄 data_plan.md
|
12 |
+
📄 plan.md
|
13 |
+
📁 models
|
14 |
+
📁 intelligent_routing
|
15 |
+
📁 saved_model
|
16 |
+
📄 model.keras
|
17 |
+
📁 test_data
|
18 |
+
📄 __init__.py
|
19 |
+
📄 test_data.json
|
20 |
+
📁 test_results
|
21 |
+
📄 confusion_matrix.png
|
22 |
+
📄 roc_curve.png
|
23 |
+
📄 test_report.json
|
24 |
+
📁 train_data
|
25 |
+
📄 __init__.py
|
26 |
+
📄 training_data.json
|
27 |
+
📄 generate_data.py
|
28 |
+
📄 model.py
|
29 |
+
📄 test_model.py
|
30 |
+
📄 train.py
|
31 |
+
📁 job_recommendation
|
32 |
+
📁 saved_model
|
33 |
+
📄 model.keras
|
34 |
+
📁 test_data
|
35 |
+
📄 __init__.py
|
36 |
+
📄 test_data.json
|
37 |
+
📁 test_results
|
38 |
+
📄 test_report.json
|
39 |
+
📁 train_data
|
40 |
+
📄 __init__.py
|
41 |
+
📄 training_data.json
|
42 |
+
📄 generate_data.py
|
43 |
+
📄 model.py
|
44 |
+
📄 test.py
|
45 |
+
📄 train.py
|
46 |
+
📁 multilingual_translation
|
47 |
+
📁 test_data
|
48 |
+
📄 __init__.py
|
49 |
+
📄 test_data.json
|
50 |
+
📁 test_results
|
51 |
+
📄 test_report.json
|
52 |
+
📁 train_data
|
53 |
+
📄 __init__.py
|
54 |
+
📄 training_data.json
|
55 |
+
📄 model.py
|
56 |
+
📄 test_model.py
|
57 |
+
📁 sentiment_analysis
|
58 |
+
📁 test_data
|
59 |
+
📄 __init__.py
|
60 |
+
📄 test_data.json
|
61 |
+
📁 test_results
|
62 |
+
📄 test_report.json
|
63 |
+
📁 train_data
|
64 |
+
📄 __init__.py
|
65 |
+
📄 training_data.json
|
66 |
+
📄 model.py
|
67 |
+
📄 test_model.py
|
68 |
+
📁 test_results
|
69 |
+
📄 endpoint_test_results.json
|
70 |
+
📁 utils
|
71 |
+
📄 __init__.py
|
72 |
+
📄 logger.py
|
73 |
+
📄 .env
|
74 |
+
📄 .gitignore
|
75 |
+
📄 A.py
|
76 |
+
📄 app.py
|
77 |
+
📄 dir_structure.md
|
78 |
+
📄 readme.md
|
79 |
+
📄 requirements.txt
|
80 |
+
📄 routes.py
|
81 |
+
📄 test_endpoints.py
|
82 |
+
```
|
docs/README.md
ADDED
@@ -0,0 +1,251 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
# Hostel Grievance Redressal System
|
2 |
+
|
3 |
+
## Overview
|
4 |
+
|
5 |
+
The Hostel Grievance Redressal System is a web application designed to facilitate the submission, tracking, and resolution of grievances raised by hostel residents. It provides a user-friendly interface for residents to report issues and enables administrators to efficiently manage and resolve them.
|
6 |
+
|
7 |
+
## Features
|
8 |
+
|
9 |
+
- **User-friendly Interface**
|
10 |
+
- Simple and intuitive design for easy grievance submission by residents.
|
11 |
+
|
12 |
+
- **Real-time Updates**
|
13 |
+
- Residents receive real-time updates on the status of their submitted grievances.
|
14 |
+
|
15 |
+
- **Admin Dashboard**
|
16 |
+
- An administrative dashboard to manage and prioritize grievances effectively.
|
17 |
+
|
18 |
+
- **Chatroom Integration**
|
19 |
+
- Real-time communication channels between workers and complainees. Whenever a complaint is filed, a dedicated chatroom (ticket) is created to facilitate direct interaction and efficient resolution.
|
20 |
+
|
21 |
+
- **Multilingual Transcription Services**
|
22 |
+
- Automatically transcribes and translates grievance inputs from any language to ensure clear understanding and effective communication between parties, similar to YouTube's comment translation feature.
|
23 |
+
|
24 |
+
- **AI-Powered Grievance Analysis**
|
25 |
+
- **Voice-to-Text Integration for Complaint Submission**
|
26 |
+
- Integrates voice recognition technology to allow residents to submit grievances via voice input, which is then transcribed and processed by the system. This enhances accessibility and convenience for users who prefer speaking over typing.
|
27 |
+
|
28 |
+
## AI/ML Functionalities
|
29 |
+
|
30 |
+
To enhance the Hostel Grievance Redressal System with cutting-edge AI/ML capabilities, the following functionalities are proposed. These features are technically challenging and essential for improving the system's efficiency and effectiveness.
|
31 |
+
|
32 |
+
### 1. Intelligent Routing and Workflow Automation
|
33 |
+
|
34 |
+
**Description:**
|
35 |
+
Implement an AI-driven routing system that intelligently assigns grievances to the most suitable personnel or department based on multiple factors such as expertise, current workload, past resolution success rates, and urgency.
|
36 |
+
|
37 |
+
**Implementation Highlights:**
|
38 |
+
- **Machine Learning Algorithms:** Use reinforcement learning and multi-criteria decision-making models to optimize grievance assignment dynamically.
|
39 |
+
- **Real-time Load Balancing:** Continuously assess the workload of administrators and adjust assignments to prevent bottlenecks.
|
40 |
+
- **Adaptive Learning:** Allow the system to learn from past assignments and outcomes to improve future routing decisions.
|
41 |
+
|
42 |
+
**Benefits:**
|
43 |
+
- Ensures grievances are handled by the most appropriate and capable personnel.
|
44 |
+
- Reduces resolution times by balancing workloads effectively.
|
45 |
+
- Increases the overall efficiency and effectiveness of the grievance redressal process.
|
46 |
+
|
47 |
+
### 2. Advanced Sentiment and Emotional Intelligence Analysis
|
48 |
+
|
49 |
+
**Description:**
|
50 |
+
Enhance sentiment analysis by incorporating emotional intelligence to better understand the nuances and underlying emotions in resident grievances. This involves detecting complex emotional states such as frustration, anger, satisfaction, or indifference.
|
51 |
+
|
52 |
+
**Implementation Highlights:**
|
53 |
+
- **Deep Learning Models:** Utilize transformer-based models like BERT or GPT for nuanced sentiment and emotion detection.
|
54 |
+
- **Contextual Understanding:** Analyze the context of grievances to distinguish between different emotional tones and intensities.
|
55 |
+
- **Response Optimization:** Tailor administrative responses based on the detected emotional state to improve communication efficacy and resident relations.
|
56 |
+
|
57 |
+
**Benefits:**
|
58 |
+
- Provides deeper insights into resident sentiments, enabling more empathetic and effective responses.
|
59 |
+
- Helps prioritize grievances that carry strong negative emotions, ensuring timely attention to sensitive issues.
|
60 |
+
- Enhances the overall user experience by addressing the emotional needs of residents.
|
61 |
+
|
62 |
+
|
63 |
+
### 3. Context-Aware Chatbots for Initial Grievance Handling
|
64 |
+
|
65 |
+
**Description:**
|
66 |
+
Deploy intelligent chatbots that can handle initial interactions with residents, providing immediate assistance, answering common queries, and guiding users through the grievance submission process.
|
67 |
+
|
68 |
+
**Implementation Highlights:**
|
69 |
+
- **Conversational AI Models:** Use state-of-the-art models like GPT-4 to create context-aware and adaptive conversational agents.
|
70 |
+
- **Intent Recognition:** Implement intent recognition to accurately understand and respond to resident queries and concerns.
|
71 |
+
- **Seamless Handover:** Ensure smooth transition from chatbot interactions to human administrators when queries exceed the chatbot's capabilities.
|
72 |
+
|
73 |
+
**Benefits:**
|
74 |
+
- Provides residents with instant support and guidance, enhancing user experience.
|
75 |
+
- Reduces the workload on human administrators by handling routine inquiries and submissions.
|
76 |
+
- Ensures that residents receive timely assistance, increasing satisfaction and trust in the system.
|
77 |
+
|
78 |
+
### 4. Anomaly Detection in Grievance Patterns
|
79 |
+
|
80 |
+
**Description:**
|
81 |
+
Detect unusual patterns or spikes in specific types of grievances using anomaly detection algorithms. Identifying such anomalies early can help in addressing systemic issues before they escalate.
|
82 |
+
|
83 |
+
**Implementation Highlights:**
|
84 |
+
- **Anomaly Detection Algorithms:** Implement algorithms like Isolation Forest or DBSCAN to identify outliers in grievance data.
|
85 |
+
- **Real-time Monitoring:** Continuously monitor grievance submissions to detect anomalies as they occur.
|
86 |
+
- **Alert Systems:** Set up alert mechanisms to notify administrators of detected anomalies for immediate action.
|
87 |
+
|
88 |
+
**Benefits:**
|
89 |
+
- Enables proactive identification of systemic issues within the hostel.
|
90 |
+
- Helps in maintaining a stable and satisfactory living environment for residents.
|
91 |
+
- Facilitates timely interventions to prevent minor issues from becoming major problems.
|
92 |
+
|
93 |
+
## Technology Stack
|
94 |
+
|
95 |
+
- **Frontend:**
|
96 |
+
- **React.js:** For a responsive and dynamic user interface.
|
97 |
+
- **Tailwind CSS:** For a modern look and feel.
|
98 |
+
|
99 |
+
- **Backend:**
|
100 |
+
- **Node.js and Express.js:** For server-side development.
|
101 |
+
|
102 |
+
- **Database:**
|
103 |
+
- **PostgreSQL:** For reliable and scalable data storage.
|
104 |
+
|
105 |
+
- **Real-time Communication:**
|
106 |
+
- **Socket.io:** To enable live chatrooms between users and administrators.
|
107 |
+
|
108 |
+
- **Translation Services:**
|
109 |
+
- **Google Translate API** or similar services for multilingual transcription and translation features.
|
110 |
+
|
111 |
+
- **AI/ML Technologies:**
|
112 |
+
- **Natural Language Processing (NLP):** Leveraging libraries like TensorFlow.js or spaCy for text analysis and sentiment detection.
|
113 |
+
- **Machine Learning Models:** Custom models for grievance categorization and predictive analytics using Python-based frameworks such as scikit-learn or TensorFlow.
|
114 |
+
- **Deep Learning Frameworks:** Utilizes transformer-based models like BERT or GPT for advanced sentiment and emotion analysis.
|
115 |
+
- **Knowledge Graph Tools:** Implements Neo4j or similar graph databases for constructing and managing knowledge graphs.
|
116 |
+
- **Conversational AI Platforms:** Integrates platforms like Dialogflow or Rasa for developing intelligent chatbots.
|
117 |
+
|
118 |
+
## Styling with Tailwind CSS
|
119 |
+
|
120 |
+
The application's UI is styled using Tailwind CSS, providing a modern and consistent design across all components.
|
121 |
+
|
122 |
+
## Component Library
|
123 |
+
|
124 |
+
This project utilizes the following component libraries:
|
125 |
+
- **Preline**
|
126 |
+
- **ComponentLand**
|
127 |
+
|
128 |
+
These libraries are used for cards, pages, and other reusable components.
|
129 |
+
|
130 |
+
## Project Preview
|
131 |
+
|
132 |
+
### Login Page
|
133 |
+
|
134 |
+
.png)
|
135 |
+
|
136 |
+
### Signup Page
|
137 |
+
|
138 |
+
.png)
|
139 |
+
|
140 |
+
### Student Dashboard
|
141 |
+
|
142 |
+
.png)
|
143 |
+
|
144 |
+
### Student Profile Info
|
145 |
+
|
146 |
+
.png)
|
147 |
+
|
148 |
+
### Student Submitting Complaint
|
149 |
+
|
150 |
+
.png)
|
151 |
+
|
152 |
+
### Student Dashboard After Submitting Complaint
|
153 |
+
|
154 |
+
.png)
|
155 |
+
|
156 |
+
### Warden Dashboard
|
157 |
+
|
158 |
+
.png)
|
159 |
+
|
160 |
+
### Warden Resolves Complaint (Clicking "Not Completed" Changes to "Completed")
|
161 |
+
|
162 |
+
.png)
|
163 |
+
|
164 |
+
### Student Dashboard Updated
|
165 |
+
|
166 |
+
.png)
|
167 |
+
|
168 |
+
### Schema Diagram
|
169 |
+
|
170 |
+

|
171 |
+
|
172 |
+
## Getting Started
|
173 |
+
|
174 |
+
To run the Hostel Grievance Redressal System locally, follow these steps:
|
175 |
+
|
176 |
+
1. **Clone the repository:**
|
177 |
+
```bash
|
178 |
+
git clone [repository_url]
|
179 |
+
```
|
180 |
+
|
181 |
+
2. **Navigate to the project directory:**
|
182 |
+
```bash
|
183 |
+
cd [project_directory]
|
184 |
+
```
|
185 |
+
|
186 |
+
3. **Install dependencies:**
|
187 |
+
```bash
|
188 |
+
npm install
|
189 |
+
```
|
190 |
+
|
191 |
+
4. **Configure the database:**
|
192 |
+
- Set up PostgreSQL and update the database configuration.
|
193 |
+
|
194 |
+
5. **Run the backend server:**
|
195 |
+
```bash
|
196 |
+
node server.js
|
197 |
+
```
|
198 |
+
|
199 |
+
6. **Run the application:**
|
200 |
+
```bash
|
201 |
+
npm run dev
|
202 |
+
```
|
203 |
+
|
204 |
+
## Contributing
|
205 |
+
|
206 |
+
Contributions are welcome! Please follow these steps to contribute:
|
207 |
+
|
208 |
+
1. Fork the repository.
|
209 |
+
2. Create a new branch for your feature or bugfix.
|
210 |
+
3. Commit your changes with clear messages.
|
211 |
+
4. Push to your branch and create a pull request.
|
212 |
+
|
213 |
+
## Future Enhancements
|
214 |
+
|
215 |
+
- **Mobile Application:**
|
216 |
+
- Develop a mobile version of the system for on-the-go grievance submission and tracking.
|
217 |
+
|
218 |
+
- **Integration with Notification Systems:**
|
219 |
+
- Implement SMS and email notifications to keep residents informed about the status of their grievances in real-time.
|
220 |
+
|
221 |
+
- **Advanced Analytics Dashboard:**
|
222 |
+
- Provide administrators with detailed analytics and reporting tools to monitor grievance trends, resolution efficiency, and overall system performance.
|
223 |
+
|
224 |
+
# License
|
225 |
+
|
226 |
+
This project is licensed under the [MIT License](LICENSE).
|
227 |
+
|
228 |
+
# Contact
|
229 |
+
|
230 |
+
For any questions or feedback, please contact [your-email@example.com](mailto:your-email@example.com).
|
231 |
+
|
232 |
+
**Description:**
|
233 |
+
Deploy intelligent chatbots that can handle initial interactions with residents, providing immediate assistance, answering common queries, and guiding users through the grievance submission process.
|
234 |
+
|
235 |
+
**Implementation Highlights:**
|
236 |
+
- **Conversational AI Models**: Use state-of-the-art models like GPT-4 to create context-aware and adaptive conversational agents.
|
237 |
+
- **Intent Recognition**: Implement intent recognition to accurately understand and respond to resident queries and concerns.
|
238 |
+
- **Seamless Handover**: Ensure smooth transition from chatbot interactions to human administrators when queries exceed the chatbot's capabilities.
|
239 |
+
|
240 |
+
**Benefits:**
|
241 |
+
- Provides residents with instant support and guidance, enhancing user experience.
|
242 |
+
- Reduces the workload on human administrators by handling routine inquiries and submissions.
|
243 |
+
- Ensures that residents receive timely assistance, increasing satisfaction and trust in the system.
|
244 |
+
|
245 |
+
## Future Enhancements
|
246 |
+
|
247 |
+
- **Mobile Application**: Develop a mobile version of the system for on-the-go grievance submission and tracking.
|
248 |
+
|
249 |
+
- **Integration with Notification Systems**: Implement SMS and email notifications to keep residents informed about the status of their grievances in real-time.
|
250 |
+
|
251 |
+
- **Advanced Analytics Dashboard**: Provide administrators with detailed analytics and reporting tools to monitor grievance trends, resolution efficiency, and overall system performance.
|
docs/ai_plan.md
ADDED
@@ -0,0 +1,936 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
# Detailed Implementation Plans for AI/ML Functionalities
|
2 |
+
|
3 |
+
This section provides an in-depth guide on implementing each AI/ML functionality within the Hostel Grievance Redressal System. Each feature is broken down into its purpose, model design pipeline, training data requirements, and example input/output data to ensure a comprehensive understanding of the implementation process. Additionally, the system architecture will be designed as a Flask API to allow seamless interaction between different models and external applications.
|
4 |
+
|
5 |
+
---
|
6 |
+
|
7 |
+
## System Architecture Overview
|
8 |
+
|
9 |
+
The Hostel Grievance Redressal System will be built as a centralized Flask API server that hosts all AI/ML models. This architecture allows different services and applications to interact with the models by sending HTTP requests containing input data and receiving the model predictions in response. Each AI/ML functionality is exposed through distinct endpoints, enabling modularity and scalability.
|
10 |
+
|
11 |
+
### **Key Components**
|
12 |
+
|
13 |
+
1. **Flask API Server**
|
14 |
+
- **Purpose:** Serve as the central hub for all AI/ML models, managing incoming requests and routing them to the appropriate model endpoints.
|
15 |
+
- **Features:**
|
16 |
+
- RESTful API design for standardized interactions.
|
17 |
+
- Authentication and authorization mechanisms to secure endpoints.
|
18 |
+
- Logging and monitoring to track usage and performance.
|
19 |
+
|
20 |
+
2. **Model Endpoints**
|
21 |
+
- **Purpose:** Each AI/ML functionality is encapsulated within its dedicated endpoint, allowing independent interaction and management.
|
22 |
+
- **Endpoints:**
|
23 |
+
- `/api/intelligent-routing`
|
24 |
+
- `/api/sentiment-analysis`
|
25 |
+
- `/api/multilingual-translation`
|
26 |
+
- `/api/job-recommendation`
|
27 |
+
|
28 |
+
3. **Data Handling and Validation**
|
29 |
+
- **Purpose:** Ensure that incoming data adheres to the required schemas and formats before processing.
|
30 |
+
- **Features:**
|
31 |
+
- Input validation using libraries like `pydantic` or `marshmallow`.
|
32 |
+
- Error handling to manage invalid or malformed requests gracefully.
|
33 |
+
|
34 |
+
4. **Scalability and Deployment**
|
35 |
+
- **Purpose:** Deploy the Flask API server in a scalable environment to handle varying loads and ensure high availability.
|
36 |
+
- **Tools:**
|
37 |
+
- Docker for containerization.
|
38 |
+
- Kubernetes or cloud-based services (e.g., AWS, GCP) for orchestration.
|
39 |
+
- CI/CD pipelines for automated deployment and updates.
|
40 |
+
|
41 |
+
---
|
42 |
+
|
43 |
+
## 1. Intelligent Routing and Workflow Automation
|
44 |
+
|
45 |
+
### **Purpose**
|
46 |
+
The Intelligent Routing and Workflow Automation system aims to efficiently assign grievances to the most suitable personnel or department. By considering factors like expertise, current workload, past resolution success rates, urgency, and additional contextual information such as student location and floor-specific metrics, the system ensures that grievances are handled promptly and effectively.
|
47 |
+
|
48 |
+
### **Model Design Pipeline**
|
49 |
+
|
50 |
+
1. **Data Collection**
|
51 |
+
- **Grievance Data:** Includes grievance type, description, submission time, student details.
|
52 |
+
- **Staff Data:** Includes staff department, current workload, availability, past performance metrics.
|
53 |
+
- **Historical Assignments:** Records of past grievance assignments, resolutions, time taken, and outcomes.
|
54 |
+
- **Additional Data:**
|
55 |
+
- **Student Details:** Room number, hostel name, floor number in hostel (0, 1, 2, 3).
|
56 |
+
- **Floor Metrics:** Number of requests per floor, total delays.
|
57 |
+
- **Availability Data:**
|
58 |
+
- **Worker Availability:** Availability status of workers at specific times.
|
59 |
+
- **Student Availability:** Availability of students at specific times.
|
60 |
+
|
61 |
+
2. **Data Preprocessing**
|
62 |
+
- **Cleaning:** Remove duplicates, handle missing values, and normalize data to ensure consistency.
|
63 |
+
- **Feature Engineering:**
|
64 |
+
- Extract features such as grievance category, sentiment scores.
|
65 |
+
- Calculate staff availability and workload metrics.
|
66 |
+
- Incorporate student room number, hostel name, and floor number as categorical or numerical features.
|
67 |
+
- Aggregate data per floor: number of requests, delays.
|
68 |
+
- Include time-based features capturing worker and student availability.
|
69 |
+
- **Encoding:** Convert categorical data (e.g., grievance types, staff departments, hostel names) into numerical formats using techniques like One-Hot Encoding or Label Encoding to facilitate model training.
|
70 |
+
|
71 |
+
3. **Model Selection**
|
72 |
+
|
73 |
+
- **Reinforcement Learning (RL):** Utilizes RL algorithms to optimize the assignment strategy based on rewards (e.g., reduced resolution time). RL is suitable for dynamic environments where the system can learn optimal policies through interactions.
|
74 |
+
- **Advantages:**
|
75 |
+
- Capable of handling sequential decision-making processes.
|
76 |
+
- Learns from the consequences of actions, allowing for continuous improvement.
|
77 |
+
- **Use Case Justification:** Ideal for scenarios where assignments need to adapt based on real-time feedback and evolving conditions.
|
78 |
+
|
79 |
+
- **Multi-Criteria Decision-Making (MCDM):** Implements models like Weighted Sum Model (WSM) or Analytic Hierarchy Process (AHP) to evaluate multiple factors influencing assignments.
|
80 |
+
- **Advantages:**
|
81 |
+
- Transparent decision-making process with easily interpretable weights for each criterion.
|
82 |
+
- Suitable for environments where decision factors are well-defined and static.
|
83 |
+
- **Use Case Justification:** Effective when prioritizing multiple, potentially conflicting criteria is essential, and interpretability of the decision process is required.
|
84 |
+
|
85 |
+
- **Comparison and Selection Logic:**
|
86 |
+
- **RL** is preferred when the system benefits from learning and adapting over time with continuous feedback.
|
87 |
+
- **MCDM** is advantageous for its simplicity and clarity in scenarios with well-established criteria and limited need for adaptability.
|
88 |
+
|
89 |
+
4. **Training the Model**
|
90 |
+
- **Reinforcement Learning:**
|
91 |
+
- Define the environment with states (current assignments, staff status, floor metrics) and actions (assignment decisions).
|
92 |
+
- Implement reward functions based on resolution efficiency, reduced delays, and satisfaction metrics.
|
93 |
+
- Train using algorithms like Q-Learning or Deep Q-Networks (DQN) which are effective for handling high-dimensional state spaces.
|
94 |
+
|
95 |
+
- **MCDM:**
|
96 |
+
- Assign weights to different criteria based on their importance through expert input or statistical methods.
|
97 |
+
- Train the model using historical assignment data to optimize weight configurations, ensuring that the most critical factors influence decision-making appropriately.
|
98 |
+
|
99 |
+
5. **Model Evaluation**
|
100 |
+
- **Metrics:** Resolution time, assignment accuracy, staff utilization rates, floor-specific delay reductions, and user satisfaction scores.
|
101 |
+
- **Cross-Validation:** Apply techniques like k-fold cross-validation to ensure model robustness and prevent overfitting.
|
102 |
+
- **Benchmarking:** Compare model performance against baseline methods (e.g., random assignment or rule-based systems) to quantify improvements.
|
103 |
+
|
104 |
+
6. **Deployment**
|
105 |
+
- **Integration into Flask API:**
|
106 |
+
- Deploy the trained model as a Flask endpoint (`/api/intelligent-routing`) using scalable frameworks (e.g., TensorFlow Serving, FastAPI).
|
107 |
+
- **Endpoint Functionality:**
|
108 |
+
- **Input:** Grievance details in JSON format.
|
109 |
+
- **Output:** Assigned staff details and assignment metadata.
|
110 |
+
- **API Development:** Develop RESTful APIs for real-time grievance assignment, ensuring low latency and high availability.
|
111 |
+
- **Response Structure:**
|
112 |
+
```json
|
113 |
+
{
|
114 |
+
"grievance_id": "G12346",
|
115 |
+
"assigned_staff_id": "S67890",
|
116 |
+
"assignment_timestamp": "2023-10-02T08:16:00Z",
|
117 |
+
"expected_resolution_time": "1 hour",
|
118 |
+
"floor_number": 2,
|
119 |
+
"hostel_name": "bh2",
|
120 |
+
"student_room_no": "204"
|
121 |
+
}
|
122 |
+
```
|
123 |
+
- **Monitoring Tools:** Implement monitoring tools (e.g., Prometheus, Grafana) to track performance metrics and trigger alerts for anomalies.
|
124 |
+
- **Retraining Schedule:** Schedule periodic retraining with new data to maintain model accuracy and adaptability to changing patterns.
|
125 |
+
|
126 |
+
7. **Interacting with the Model**
|
127 |
+
- **API Requests:** External applications can interact with the Intelligent Routing model by sending POST requests to `/api/intelligent-routing` with grievance data.
|
128 |
+
- **Example Request:**
|
129 |
+
```json
|
130 |
+
{
|
131 |
+
"grievance_id": "G12346",
|
132 |
+
"category": "electricity",
|
133 |
+
"submission_timestamp": "2023-10-02T08:15:00Z",
|
134 |
+
"student_room_no": "204",
|
135 |
+
"hostel_name": "bh2",
|
136 |
+
"floor_number": 2,
|
137 |
+
"current_staff_status": [
|
138 |
+
{
|
139 |
+
"staff_id": "S67890",
|
140 |
+
"department": "electricity",
|
141 |
+
"current_workload": 3,
|
142 |
+
"availability_status": "Available",
|
143 |
+
"past_resolution_rate": 0.95
|
144 |
+
},
|
145 |
+
{
|
146 |
+
"staff_id": "S67891",
|
147 |
+
"department": "plumber",
|
148 |
+
"current_workload": 2,
|
149 |
+
"availability_status": "Available",
|
150 |
+
"past_resolution_rate": 0.90
|
151 |
+
}
|
152 |
+
],
|
153 |
+
"floor_metrics": {
|
154 |
+
"number_of_requests": 15,
|
155 |
+
"total_delays": 1
|
156 |
+
},
|
157 |
+
"availability_data": {
|
158 |
+
"staff_availability": [
|
159 |
+
{
|
160 |
+
"staff_id": "S67890",
|
161 |
+
"time_slot": "08:00-12:00",
|
162 |
+
"availability_status": "Available"
|
163 |
+
}
|
164 |
+
],
|
165 |
+
"student_availability": [
|
166 |
+
{
|
167 |
+
"student_id": "STU204",
|
168 |
+
"time_slot": "08:00-10:00",
|
169 |
+
"availability_status": "Unavailable"
|
170 |
+
}
|
171 |
+
]
|
172 |
+
}
|
173 |
+
}
|
174 |
+
```
|
175 |
+
|
176 |
+
### **Training Data Requirements**
|
177 |
+
|
178 |
+
- **Grievance Dataset:**
|
179 |
+
- **Features:** Grievance ID, category, description, submission timestamp, student room number, hostel name, floor number.
|
180 |
+
- **Example:**
|
181 |
+
```json
|
182 |
+
{
|
183 |
+
"grievance_id": "G12345",
|
184 |
+
"category": "plumber",
|
185 |
+
"submission_timestamp": "2023-10-01T10:30:00Z",
|
186 |
+
"student_room_no": "204",
|
187 |
+
"hostel_name": "bh1",
|
188 |
+
"floor_number": 2
|
189 |
+
}
|
190 |
+
```
|
191 |
+
|
192 |
+
- **Staff Dataset:**
|
193 |
+
- **Features:** Staff ID, department, current workload, availability status, past resolution rate.
|
194 |
+
- **Example:**
|
195 |
+
```json
|
196 |
+
{
|
197 |
+
"staff_id": "S67890",
|
198 |
+
"department": "plumber",
|
199 |
+
"current_workload": 5,
|
200 |
+
"availability_status": "Available",
|
201 |
+
"past_resolution_rate": 0.95
|
202 |
+
}
|
203 |
+
```
|
204 |
+
|
205 |
+
- **Historical Assignments:**
|
206 |
+
- **Features:** Grievance ID, staff ID, assignment timestamp, resolution time, outcome, floor number.
|
207 |
+
- **Example:**
|
208 |
+
```json
|
209 |
+
{
|
210 |
+
"grievance_id": "G12340",
|
211 |
+
"staff_id": "S67885",
|
212 |
+
"assignment_timestamp": "2023-09-25T09:00:00Z",
|
213 |
+
"resolution_time": "2 hours",
|
214 |
+
"outcome": "Resolved Successfully",
|
215 |
+
"floor_number": 1
|
216 |
+
}
|
217 |
+
```
|
218 |
+
|
219 |
+
- **Floor Metrics Dataset:**
|
220 |
+
- **Features:** Hostel name, floor number, date, number of requests, total delays.
|
221 |
+
- **Example:**
|
222 |
+
```json
|
223 |
+
{
|
224 |
+
"hostel_name": "bh2",
|
225 |
+
"floor_number": 2,
|
226 |
+
"date": "2023-10-01",
|
227 |
+
"number_of_requests": 20,
|
228 |
+
"total_delays": 2
|
229 |
+
}
|
230 |
+
```
|
231 |
+
|
232 |
+
- **Availability Dataset:**
|
233 |
+
- **Features:** Staff ID, date, time slots, availability status; Student ID, date, time slots, availability status.
|
234 |
+
- **Example:**
|
235 |
+
```json
|
236 |
+
{
|
237 |
+
"staff_id": "S67890",
|
238 |
+
"date": "2023-10-02",
|
239 |
+
"time_slot": "09:00-12:00",
|
240 |
+
"availability_status": "Available"
|
241 |
+
},
|
242 |
+
{
|
243 |
+
"student_id": "STU123",
|
244 |
+
"date": "2023-10-02",
|
245 |
+
"time_slot": "14:00-16:00",
|
246 |
+
"availability_status": "Unavailable"
|
247 |
+
}
|
248 |
+
```
|
249 |
+
|
250 |
+
### **Sample Input and Output**
|
251 |
+
|
252 |
+
- **Sample Input:**
|
253 |
+
```json
|
254 |
+
{
|
255 |
+
"grievance_id": "G12346",
|
256 |
+
"category": "electricity",
|
257 |
+
"submission_timestamp": "2023-10-02T08:15:00Z",
|
258 |
+
"student_room_no": "204",
|
259 |
+
"hostel_name": "bh2",
|
260 |
+
"floor_number": 2,
|
261 |
+
"current_staff_status": [
|
262 |
+
{
|
263 |
+
"staff_id": "S67890",
|
264 |
+
"department": "electricity",
|
265 |
+
"current_workload": 3,
|
266 |
+
"availability_status": "Available",
|
267 |
+
"past_resolution_rate": 0.95
|
268 |
+
},
|
269 |
+
{
|
270 |
+
"staff_id": "S67891",
|
271 |
+
"department": "plumber",
|
272 |
+
"current_workload": 2,
|
273 |
+
"availability_status": "Available",
|
274 |
+
"past_resolution_rate": 0.90
|
275 |
+
}
|
276 |
+
],
|
277 |
+
"floor_metrics": {
|
278 |
+
"number_of_requests": 15,
|
279 |
+
"total_delays": 1
|
280 |
+
},
|
281 |
+
"availability_data": {
|
282 |
+
"staff_availability": [
|
283 |
+
{
|
284 |
+
"staff_id": "S67890",
|
285 |
+
"time_slot": "08:00-12:00",
|
286 |
+
"availability_status": "Available"
|
287 |
+
}
|
288 |
+
],
|
289 |
+
"student_availability": [
|
290 |
+
{
|
291 |
+
"student_id": "STU204",
|
292 |
+
"time_slot": "08:00-10:00",
|
293 |
+
"availability_status": "Unavailable"
|
294 |
+
}
|
295 |
+
]
|
296 |
+
}
|
297 |
+
}
|
298 |
+
```
|
299 |
+
|
300 |
+
- **Sample Output:**
|
301 |
+
```json
|
302 |
+
{
|
303 |
+
"grievance_id": "G12346",
|
304 |
+
"assigned_staff_id": "S67890",
|
305 |
+
"assignment_timestamp": "2023-10-02T08:16:00Z",
|
306 |
+
"expected_resolution_time": "1 hour",
|
307 |
+
"floor_number": 2,
|
308 |
+
"hostel_name": "bh2",
|
309 |
+
"student_room_no": "204"
|
310 |
+
}
|
311 |
+
```
|
312 |
+
|
313 |
+
### **Allowable Field Values**
|
314 |
+
|
315 |
+
1. **Category**:
|
316 |
+
- electricity
|
317 |
+
- internet
|
318 |
+
- plumber
|
319 |
+
- water cooler
|
320 |
+
- sweeper
|
321 |
+
- carpenter
|
322 |
+
|
323 |
+
2. **Floor Number**:
|
324 |
+
- 0
|
325 |
+
- 1
|
326 |
+
- 2
|
327 |
+
- 3
|
328 |
+
|
329 |
+
3. **Staff Department**:
|
330 |
+
- electricity
|
331 |
+
- internet
|
332 |
+
- plumber
|
333 |
+
- water cooler
|
334 |
+
- sweeper
|
335 |
+
- carpenter
|
336 |
+
|
337 |
+
4. **Availability Status**:
|
338 |
+
- Available
|
339 |
+
- Unavailable
|
340 |
+
|
341 |
+
5. **Hostel Name**:
|
342 |
+
- bh1
|
343 |
+
- bh2
|
344 |
+
- bh3
|
345 |
+
- ivh
|
346 |
+
- gh
|
347 |
+
|
348 |
+
6. **Student Room Number**:
|
349 |
+
- Any valid room number string (e.g., "101", "204", etc.)
|
350 |
+
|
351 |
+
7. **Staff ID**:
|
352 |
+
- Any valid staff ID string (e.g., "S67890", "S67891", etc.)
|
353 |
+
|
354 |
+
8. **Student ID**:
|
355 |
+
- Any valid student ID string (e.g., "STU123", "STU204", etc.)
|
356 |
+
|
357 |
+
9. **Grievance ID**:
|
358 |
+
- Any valid grievance ID string (e.g., "G12345", "G12346", etc.)
|
359 |
+
|
360 |
+
10. **Time Slot**:
|
361 |
+
- Any valid time range string (e.g., "08:00-12:00", "14:00-16:00", etc.)
|
362 |
+
|
363 |
+
11. **Resolution Time**:
|
364 |
+
- Any valid time duration string (e.g., "1 hour", "2 hours", etc.)
|
365 |
+
|
366 |
+
12. **Outcome**:
|
367 |
+
- "Resolved Successfully"
|
368 |
+
- "Unresolved"
|
369 |
+
- "Pending"
|
370 |
+
|
371 |
+
13. **Current Workload**:
|
372 |
+
- Any non-negative integer
|
373 |
+
|
374 |
+
14. **Past Resolution Rate**:
|
375 |
+
- Any float value between 0 and 1 (inclusive)
|
376 |
+
|
377 |
+
15. **Number of Requests**:
|
378 |
+
- Any non-negative integer
|
379 |
+
|
380 |
+
16. **Total Delays**:
|
381 |
+
- Any non-negative integer
|
382 |
+
|
383 |
+
---
|
384 |
+
|
385 |
+
## 2. Advanced Sentiment and Emotional Intelligence Analysis
|
386 |
+
|
387 |
+
### **Purpose**
|
388 |
+
The Advanced Sentiment and Emotional Intelligence Analysis system enhances the understanding of resident grievances by detecting complex emotional states such as frustration, anger, satisfaction, or indifference. This enables more empathetic and effective responses from administrators.
|
389 |
+
|
390 |
+
### **Model Design Pipeline**
|
391 |
+
|
392 |
+
1. **Data Collection**
|
393 |
+
- **Grievance Texts:** Includes descriptions and any textual communication from residents.
|
394 |
+
- **Emotional Labels:** Annotated data indicating the emotional state of each grievance (e.g., frustrated, angry).
|
395 |
+
|
396 |
+
2. **Data Preprocessing**
|
397 |
+
- **Text Cleaning:** Remove HTML tags, special characters, and perform lowercasing to standardize the text data.
|
398 |
+
- **Tokenization:** Split text into tokens (words or subwords) to prepare for feature extraction.
|
399 |
+
- **Removing Stop Words:** Eliminate common words that do not contribute to sentiment (e.g., "and", "the").
|
400 |
+
- **Stemming/Lemmatization:** Reduce words to their base forms to minimize variability.
|
401 |
+
- **Padding/Truncating:** Ensure uniform input length for model training, handling varying sentence lengths.
|
402 |
+
|
403 |
+
3. **Feature Extraction**
|
404 |
+
- **Word Embeddings:** Utilize embeddings like BERT or Word2Vec to capture semantic meaning and contextual relationships between words.
|
405 |
+
- **Contextual Embeddings:** Employ transformer-based models to understand the context in which words are used, enhancing sentiment detection accuracy.
|
406 |
+
|
407 |
+
4. **Model Selection**
|
408 |
+
- **Transformer-Based Models:** Utilize models like BERT, RoBERTa, or GPT-4 fine-tuned for sentiment and emotion detection.
|
409 |
+
- **Advantages:**
|
410 |
+
- Capable of understanding context and nuances in language.
|
411 |
+
- Pre-trained on large datasets, reducing the need for extensive training data.
|
412 |
+
- **Use Case Justification:** Ideal for capturing the subtleties in resident grievances, leading to more accurate emotional labeling.
|
413 |
+
|
414 |
+
- **Hybrid Models:** Combine Long Short-Term Memory (LSTM) layers with transformers for enhanced performance.
|
415 |
+
- **Advantages:**
|
416 |
+
- LSTM layers can capture sequential dependencies, complementing transformer models.
|
417 |
+
- Provides a balance between computational efficiency and model complexity.
|
418 |
+
- **Use Case Justification:** Suitable when additional sequential information from the data can improve sentiment analysis.
|
419 |
+
|
420 |
+
- **Comparison and Selection Logic:**
|
421 |
+
- **Transformer-Based Models** are preferred for their superior performance in understanding language context.
|
422 |
+
- **Hybrid Models** can be considered when specific sequential patterns in text need to be captured alongside contextual understanding.
|
423 |
+
|
424 |
+
5. **Training the Model**
|
425 |
+
- **Fine-Tuning:** Pre-trained transformer models are fine-tuned on the labeled grievance dataset to adapt to the specific domain language and sentiment expressions.
|
426 |
+
- **Loss Function:** Use cross-entropy loss for multi-class classification to effectively handle multiple emotional categories.
|
427 |
+
- **Optimization:** Apply optimizers like Adam with appropriate learning rates to ensure efficient convergence and avoid overfitting.
|
428 |
+
|
429 |
+
6. **Model Evaluation**
|
430 |
+
- **Metrics:** Precision, Recall, F1-Score, and Accuracy for each emotional category to assess the model's performance comprehensively.
|
431 |
+
- **Validation:** Use a dedicated validation set to prevent overfitting and ensure the model generalizes well to unseen data.
|
432 |
+
- **Confusion Matrix:** Analyze misclassifications to identify areas for improvement and understand model biases.
|
433 |
+
|
434 |
+
7. **Deployment**
|
435 |
+
- **Integration into Flask API:**
|
436 |
+
- Deploy the trained model as a Flask endpoint (`/api/sentiment-analysis`) using scalable frameworks (e.g., TensorFlow Serving, FastAPI).
|
437 |
+
- **Endpoint Functionality:**
|
438 |
+
- **Input:** Grievance text in JSON format.
|
439 |
+
- **Output:** Predicted emotional label and confidence score.
|
440 |
+
- **API Development:** Develop RESTful APIs for receiving grievance texts and returning emotional insights, ensuring scalability and accessibility.
|
441 |
+
- **Response Structure:**
|
442 |
+
```json
|
443 |
+
{
|
444 |
+
"grievance_id": "G12349",
|
445 |
+
"predicted_emotional_label": "Anger",
|
446 |
+
"confidence_score": 0.92
|
447 |
+
}
|
448 |
+
```
|
449 |
+
- **Monitoring Tools:** Implement monitoring tools to track model performance and trigger alerts for potential degradation.
|
450 |
+
- **Retraining Schedule:** Schedule periodic model updates with new data to maintain accuracy and adapt to evolving sentiment expressions.
|
451 |
+
|
452 |
+
8. **Interacting with the Model**
|
453 |
+
- **API Requests:** External applications can interact with the Sentiment Analysis model by sending POST requests to `/api/sentiment-analysis` with grievance text.
|
454 |
+
- **Example Request:**
|
455 |
+
```json
|
456 |
+
{
|
457 |
+
"grievance_id": "G12349",
|
458 |
+
"text": "Why hasn't the maintenance team fixed the leaking roof yet? This is unacceptable!",
|
459 |
+
"emotional_label": null
|
460 |
+
}
|
461 |
+
```
|
462 |
+
|
463 |
+
### **Training Data Requirements**
|
464 |
+
|
465 |
+
- **Grievance Dataset:**
|
466 |
+
- **Features:** Grievance ID, text, annotated emotional labels.
|
467 |
+
- **Example:**
|
468 |
+
```json
|
469 |
+
{
|
470 |
+
"grievance_id": "G12347",
|
471 |
+
"text": "I am extremely frustrated with the constant power outages in my room.",
|
472 |
+
"emotional_label": "Frustration"
|
473 |
+
}
|
474 |
+
```
|
475 |
+
|
476 |
+
- **Emotional Labels:**
|
477 |
+
- **Categories:** Frustration, Anger, Satisfaction, Indifference, etc.
|
478 |
+
- **Example:**
|
479 |
+
```json
|
480 |
+
{
|
481 |
+
"grievance_id": "G12348",
|
482 |
+
"text": "Thank you for resolving my issue so quickly.",
|
483 |
+
"emotional_label": "Satisfaction"
|
484 |
+
}
|
485 |
+
```
|
486 |
+
|
487 |
+
### **Sample Input and Output**
|
488 |
+
|
489 |
+
- **Sample Input:**
|
490 |
+
```json
|
491 |
+
{
|
492 |
+
"grievance_id": "G12349",
|
493 |
+
"text": "Why hasn't the maintenance team fixed the leaking roof yet? This is unacceptable!",
|
494 |
+
"emotional_label": null
|
495 |
+
}
|
496 |
+
```
|
497 |
+
|
498 |
+
- **Sample Output:**
|
499 |
+
```json
|
500 |
+
{
|
501 |
+
"grievance_id": "G12349",
|
502 |
+
"predicted_emotional_label": "Anger",
|
503 |
+
"confidence_score": 0.92
|
504 |
+
}
|
505 |
+
```
|
506 |
+
|
507 |
+
---
|
508 |
+
|
509 |
+
## 3. Multilingual Translation in Chatroom
|
510 |
+
|
511 |
+
### **Purpose**
|
512 |
+
The Multilingual Translation feature aims to facilitate seamless communication between residents and workers who may speak different languages. By automatically translating messages between the user's preferred language and the worker's default language (e.g., English), the system ensures clear and effective communication, thereby enhancing user experience and resolving grievances efficiently.
|
513 |
+
|
514 |
+
### **Model Design Pipeline**
|
515 |
+
|
516 |
+
1. **Data Collection**
|
517 |
+
- **Multilingual Conversation Logs:** Collect chat logs in multiple languages to understand common phrases and context-specific terminology used in grievances and responses.
|
518 |
+
- **Translation Pairs:** Gather datasets containing sentence pairs in source and target languages (e.g., Tamil-English) for training translation models.
|
519 |
+
- **Domain-Specific Vocabulary:** Compile a glossary of common terms related to hostel grievances (e.g., plumbing issues, electrical faults) in both languages to ensure accurate translations.
|
520 |
+
|
521 |
+
2. **Data Preprocessing**
|
522 |
+
- **Cleaning:** Remove noise such as HTML tags, special characters, and correct typos in both source and target languages.
|
523 |
+
- **Tokenization:** Split text into tokens appropriate for each language, considering language-specific rules (e.g., agglutinative structures in Tamil).
|
524 |
+
- **Alignment:** Ensure that translation pairs are correctly aligned for supervised learning, maintaining the contextual integrity of conversations.
|
525 |
+
- **Normalization:** Convert all text to a consistent format (e.g., Unicode normalization) to handle different character encodings.
|
526 |
+
|
527 |
+
3. **Feature Extraction**
|
528 |
+
- **Sentence Embeddings:** Utilize models like BERT multilingual or dedicated translation models to capture semantic meanings across languages.
|
529 |
+
- **Contextual Information:** Incorporate context from previous messages to improve translation accuracy, especially for ambiguous phrases and maintaining conversation flow.
|
530 |
+
- **Language Identification:** Implement language detection models to accurately identify the source and target languages of each message.
|
531 |
+
|
532 |
+
4. **Model Selection**
|
533 |
+
- **Neural Machine Translation (NMT) Models:** Implement transformer-based models like Google's T5 or Facebook's M2M-100 for high-quality translations.
|
534 |
+
- **Advantages:**
|
535 |
+
- Capable of handling diverse language pairs with contextual understanding.
|
536 |
+
- Pre-trained models can be fine-tuned for specific domain vocabularies.
|
537 |
+
- **Use Case Justification:** Essential for providing accurate and context-aware translations between resident and worker languages.
|
538 |
+
|
539 |
+
- **Hybrid Translation Systems:** Combine rule-based and neural approaches to enhance translation quality for language-specific nuances.
|
540 |
+
- **Advantages:**
|
541 |
+
- Better handling of idiomatic expressions and cultural context.
|
542 |
+
- Improved accuracy for low-resource language pairs.
|
543 |
+
- **Use Case Justification:** Suitable when dealing with languages that have complex grammatical structures or limited training data.
|
544 |
+
|
545 |
+
- **Comparison and Selection Logic:**
|
546 |
+
- **NMT Models** are preferred for their superior performance in general translation tasks and adaptability through fine-tuning.
|
547 |
+
- **Hybrid Systems** are selected when specific language nuances and domain-specific terminology require additional rule-based adjustments to achieve higher accuracy.
|
548 |
+
|
549 |
+
5. **Training the Model**
|
550 |
+
- **Fine-Tuning:** Adapt pre-trained NMT models on domain-specific translation pairs to ensure relevance in context (e.g., maintenance-related terminology).
|
551 |
+
- **Handling Dialects:** Incorporate regional dialects and colloquialisms to improve translation fidelity, ensuring that translations are contextually appropriate.
|
552 |
+
- **Optimization:** Use optimizers like Adam with learning rate scheduling to achieve efficient convergence without overfitting.
|
553 |
+
- **Data Augmentation:** Employ techniques like back-translation to augment the training dataset, enhancing model robustness and performance.
|
554 |
+
|
555 |
+
6. **Model Evaluation**
|
556 |
+
- **Metrics:** BLEU (Bilingual Evaluation Understudy) score, METEOR, and human evaluation for translation accuracy and fluency.
|
557 |
+
- **Validation:** Create a diverse validation set that includes various dialects, slang, and context-specific phrases to test model robustness.
|
558 |
+
- **Error Analysis:** Identify common translation errors to iteratively improve the model, focusing on problematic language pairs or specific terms.
|
559 |
+
- **User Feedback:** Incorporate feedback from actual users to assess translation quality and identify areas needing improvement.
|
560 |
+
|
561 |
+
7. **Deployment**
|
562 |
+
- **Integration into Flask API:**
|
563 |
+
- Deploy the trained translation model as a Flask endpoint (`/api/multilingual-translation`) using scalable frameworks (e.g., TensorFlow Serving, FastAPI).
|
564 |
+
- **Endpoint Functionality:**
|
565 |
+
- **Input:** User message with source and target language identifiers.
|
566 |
+
- **Output:** Translated message.
|
567 |
+
- **API Development:** Develop RESTful APIs that handle translation requests, ensuring low latency and high throughput to maintain real-time communication standards.
|
568 |
+
- **Response Structure:**
|
569 |
+
```json
|
570 |
+
{
|
571 |
+
"translated_message": "There is no water coming in the toilet."
|
572 |
+
}
|
573 |
+
```
|
574 |
+
- **Monitoring Tools:** Utilize monitoring tools to track translation service performance, latency, and error rates, ensuring timely detection and resolution of issues.
|
575 |
+
- **Retraining Schedule:** Schedule periodic updates and retraining sessions with new data to maintain translation accuracy and adapt to evolving language use patterns.
|
576 |
+
|
577 |
+
8. **Interacting with the Model**
|
578 |
+
- **API Requests:** External applications can interact with the Multilingual Translation model by sending POST requests to `/api/multilingual-translation` with messages to be translated.
|
579 |
+
- **Example Request:**
|
580 |
+
```json
|
581 |
+
{
|
582 |
+
"user_message": "toilet me paani nahi aa rha hain",
|
583 |
+
"source_language": "Hindi",
|
584 |
+
"target_language": "English"
|
585 |
+
}
|
586 |
+
```
|
587 |
+
|
588 |
+
### **Training Data Requirements**
|
589 |
+
|
590 |
+
- **Conversation Dataset:**
|
591 |
+
- **Features:** User messages, worker responses, language identifiers, annotated intents, extracted entities.
|
592 |
+
- **Example:**
|
593 |
+
```json
|
594 |
+
{
|
595 |
+
"user_message": "toilet me paani nahi aa rha hain",
|
596 |
+
"intent": "submit_grievance",
|
597 |
+
"entities": {
|
598 |
+
"grievance_type": "Water Supply",
|
599 |
+
"location": "Toilet"
|
600 |
+
},
|
601 |
+
"bot_response": "There is no water coming in the toilet.",
|
602 |
+
"detected_language": "Hindi",
|
603 |
+
"target_language": "English"
|
604 |
+
}
|
605 |
+
```
|
606 |
+
|
607 |
+
- **Translation Pairs:**
|
608 |
+
- **Features:** Source sentence, target sentence, language pair.
|
609 |
+
- **Example:**
|
610 |
+
```json
|
611 |
+
{
|
612 |
+
"source_sentence": "toilet me paani nahi aa rha hain",
|
613 |
+
"target_sentence": "There is no water coming in the toilet.",
|
614 |
+
"language_pair": "Hindi-English"
|
615 |
+
}
|
616 |
+
```
|
617 |
+
|
618 |
+
### **Sample Input and Output**
|
619 |
+
|
620 |
+
- **Sample Input:**
|
621 |
+
```json
|
622 |
+
{
|
623 |
+
"user_message": "toilet me paani nahi aa rha hain",
|
624 |
+
"target_language": "English"
|
625 |
+
}
|
626 |
+
```
|
627 |
+
|
628 |
+
- **Sample Output:**
|
629 |
+
```json
|
630 |
+
{
|
631 |
+
"translated_message": "There is no water coming in the toilet."
|
632 |
+
}
|
633 |
+
```
|
634 |
+
|
635 |
+
- **Sample Translation Scenario:**
|
636 |
+
|
637 |
+
- **Resident to Staff:**
|
638 |
+
- **Resident's Message:** "toilet me paani nahi aa rha hain"
|
639 |
+
- **Translated Message to Staff:** "There is no water coming in the toilet."
|
640 |
+
|
641 |
+
- **Staff's Response Back:**
|
642 |
+
- **Staff's Message:** "We will send a technician to fix the issue."
|
643 |
+
- **Translated Message to Resident:** "हम तकनीशियन को समस्या को ठीक करने के लिए भेजेंगे।"
|
644 |
+
|
645 |
+
### **Implementation Considerations**
|
646 |
+
- **Real-Time Translation:** Ensure that translations occur in real-time to maintain the flow of conversation without noticeable delays.
|
647 |
+
- **Context Preservation:** Maintain the context of the conversation to ensure translations are accurate and contextually appropriate.
|
648 |
+
- **User Control:** Allow users to enable or disable automatic translations based on their preferences.
|
649 |
+
- **Error Handling:** Implement robust error handling to manage translation failures gracefully, including notifying users and providing manual translation options.
|
650 |
+
- **Security and Privacy:** Ensure that all translated data is handled securely, complying with data privacy regulations, encrypting data in transit and at rest to protect sensitive information.
|
651 |
+
|
652 |
+
### **Benefits**
|
653 |
+
- **Enhanced Communication:** Bridges language barriers between residents and workers, ensuring clear and effective communication.
|
654 |
+
- **Improved Efficiency:** Reduces misunderstandings and clarifications, speeding up the grievance resolution process.
|
655 |
+
- **User Satisfaction:** Enhances user experience by providing support in the user's native language, fostering trust and reliability.
|
656 |
+
- **Scalability:** Supports a diverse user base with multiple language preferences, making the system adaptable to various linguistic demographics.
|
657 |
+
|
658 |
+
---
|
659 |
+
|
660 |
+
## 6. Worker Job Recommendation
|
661 |
+
|
662 |
+
### **Purpose**
|
663 |
+
The Worker Job Recommendation system aims to optimize the assignment of specific jobs to workers based on various factors to save time and enhance efficiency. By considering the urgency of requests, proximity of tasks within the same floor or hostel, similarity in job descriptions, job success rates, and additional relevant factors, the system ensures that workers are assigned tasks that best match their skills and current context, thereby improving overall operational efficiency.
|
664 |
+
|
665 |
+
### **Model Design Pipeline**
|
666 |
+
|
667 |
+
1. **Data Collection**
|
668 |
+
- **Job Requests Data:** Details of all incoming job requests, including type, description, urgency level, location (floor, hostel), and timestamps.
|
669 |
+
- **Worker Profiles:** Information about workers, such as department, current assignments, availability, past performance, and job success rates.
|
670 |
+
- **Historical Assignments:** Records of past job assignments, including job types, worker assignments, time taken, and outcomes.
|
671 |
+
- **Spatial Data:** Mapping of tasks and worker locations to understand proximity and optimize assignments based on geographic density.
|
672 |
+
|
673 |
+
2. **Data Preprocessing**
|
674 |
+
- **Cleaning:** Remove duplicates, handle missing values, and ensure the consistency of data across different datasets.
|
675 |
+
- **Feature Engineering:**
|
676 |
+
- Extract features such as job category, detailed descriptions, and urgency levels.
|
677 |
+
- Calculate workers' current workload and availability status.
|
678 |
+
- Incorporate location data to assess proximity.
|
679 |
+
- Analyze historical success rates to prioritize reliable workers.
|
680 |
+
- Map job types to relevant departments.
|
681 |
+
- **Encoding:** Convert categorical data (e.g., job types, hostel names) into numerical representations using One-Hot Encoding or Label Encoding to facilitate model training.
|
682 |
+
|
683 |
+
3. **Model Selection**
|
684 |
+
- **Collaborative Filtering:** Utilize recommendation algorithms like Matrix Factorization or K-Nearest Neighbors to predict worker-job compatibility based on historical assignment patterns.
|
685 |
+
- **Advantages:**
|
686 |
+
- Effective in capturing latent relationships between workers and job types.
|
687 |
+
- Scales well with large datasets.
|
688 |
+
- **Use Case Justification:** Suitable for leveraging historical data to recommend appropriate worker assignments.
|
689 |
+
|
690 |
+
- **Decision Trees/Random Forest:** Implement models to make assignment decisions based on importance of features such as urgency, proximity, and worker performance.
|
691 |
+
- **Advantages:**
|
692 |
+
- Handles both numerical and categorical data efficiently.
|
693 |
+
- Provides interpretability through feature importance.
|
694 |
+
- **Use Case Justification:** Ideal for scenarios where multiple factors influence assignment decisions and interpretability is important.
|
695 |
+
|
696 |
+
- **Deep Learning Models:** Use neural networks to capture complex interactions between features for improved recommendation accuracy.
|
697 |
+
- **Advantages:**
|
698 |
+
- Capable of modeling non-linear relationships between features.
|
699 |
+
- Can integrate various data types seamlessly.
|
700 |
+
- **Use Case Justification:** Beneficial when the complexity of interactions between features necessitates more robust modeling capabilities.
|
701 |
+
|
702 |
+
- **Comparison and Selection Logic:**
|
703 |
+
- **Collaborative Filtering** is chosen for its effectiveness in leveraging historical assignment data to recommend suitable workers.
|
704 |
+
- **Random Forest** is preferred when feature importance and interpretability are critical in understanding assignment decisions.
|
705 |
+
- **Deep Learning Models** are considered when the complexity of interactions between features necessitates more robust modeling capabilities.
|
706 |
+
|
707 |
+
4. **Training the Model**
|
708 |
+
- **Data Splitting:** Divide the dataset into training, validation, and testing sets to evaluate model performance effectively.
|
709 |
+
- **Model Training:** Train selected models using the training data, ensuring they learn the optimal patterns for job-worker assignments.
|
710 |
+
- **Hyperparameter Tuning:** Optimize model parameters using techniques like Grid Search or Random Search to enhance performance.
|
711 |
+
- **Validation:** Use the validation set to fine-tune models and prevent overfitting by adjusting model complexity as necessary.
|
712 |
+
|
713 |
+
5. **Model Evaluation**
|
714 |
+
- **Metrics:** Use evaluation metrics such as Precision, Recall, F1-Score, and Mean Absolute Error (MAE) to assess model performance.
|
715 |
+
- **Cross-Validation:** Apply k-fold cross-validation to ensure model robustness and generalizability across different data subsets.
|
716 |
+
- **Benchmarking:** Compare model performance against baseline assignment methods (e.g., manual assignment or rule-based systems) to quantify improvements.
|
717 |
+
|
718 |
+
6. **Deployment**
|
719 |
+
- **Integration into Flask API:**
|
720 |
+
- Deploy the trained recommendation model as a Flask endpoint (`/api/job-recommendation`) using scalable frameworks (e.g., TensorFlow Serving, FastAPI).
|
721 |
+
- **Endpoint Functionality:**
|
722 |
+
- **Input:** Job request details and available workers in JSON format.
|
723 |
+
- **Output:** Assigned worker details and assignment metadata.
|
724 |
+
- **API Development:** Create RESTful APIs that handle job assignment requests, ensuring real-time recommendations with minimal latency.
|
725 |
+
- **Response Structure:**
|
726 |
+
```json
|
727 |
+
{
|
728 |
+
"job_id": "J12346",
|
729 |
+
"assigned_worker_id": "W67890",
|
730 |
+
"assignment_timestamp": "2023-10-02T08:16:00Z",
|
731 |
+
"expected_resolution_time": "1 hour",
|
732 |
+
"location": {
|
733 |
+
"hostel_name": "Hostel A",
|
734 |
+
"floor_number": 2,
|
735 |
+
"room_number": "204"
|
736 |
+
}
|
737 |
+
}
|
738 |
+
```
|
739 |
+
- **Monitoring Tools:** Implement monitoring tools (e.g., Prometheus, Grafana) to track model performance and system health, triggering alerts for any deviations.
|
740 |
+
- **Retraining Schedule:** Establish periodic retraining intervals using new assignment data to keep the model updated and maintain recommendation accuracy.
|
741 |
+
|
742 |
+
7. **Interacting with the Model**
|
743 |
+
- **API Requests:** External applications can interact with the Job Recommendation model by sending POST requests to `/api/job-recommendation` with job and worker details.
|
744 |
+
- **Example Request:**
|
745 |
+
```json
|
746 |
+
{
|
747 |
+
"job_id": "J12346",
|
748 |
+
"type": "Electrical",
|
749 |
+
"description": "Power outage in room 204.",
|
750 |
+
"urgency_level": "Critical",
|
751 |
+
"submission_timestamp": "2023-10-02T08:15:00Z",
|
752 |
+
"location": {
|
753 |
+
"hostel_name": "Hostel A",
|
754 |
+
"floor_number": 2,
|
755 |
+
"room_number": "204"
|
756 |
+
},
|
757 |
+
"workers": [
|
758 |
+
{
|
759 |
+
"worker_id": "W67890",
|
760 |
+
"department": "Electrical",
|
761 |
+
"current_workload": 3,
|
762 |
+
"availability_status": "Available",
|
763 |
+
"job_success_rate": 0.95,
|
764 |
+
"current_location": {
|
765 |
+
"hostel_name": "Hostel A",
|
766 |
+
"floor_number": 2,
|
767 |
+
"room_number": "210"
|
768 |
+
}
|
769 |
+
},
|
770 |
+
{
|
771 |
+
"worker_id": "W67891",
|
772 |
+
"department": "Mechanical",
|
773 |
+
"current_workload": 2,
|
774 |
+
"availability_status": "Available",
|
775 |
+
"job_success_rate": 0.90,
|
776 |
+
"current_location": {
|
777 |
+
"hostel_name": "Hostel A",
|
778 |
+
"floor_number": 2,
|
779 |
+
"room_number": "215"
|
780 |
+
}
|
781 |
+
}
|
782 |
+
]
|
783 |
+
}
|
784 |
+
```
|
785 |
+
|
786 |
+
### **Training Data Requirements**
|
787 |
+
|
788 |
+
- **Job Requests Dataset:**
|
789 |
+
- **Features:** Job ID, type, description, urgency level, location (floor, hostel), submission timestamp.
|
790 |
+
- **Example:**
|
791 |
+
```json
|
792 |
+
{
|
793 |
+
"job_id": "J12345",
|
794 |
+
"type": "Electrical",
|
795 |
+
"description": "Fan not working in room 204.",
|
796 |
+
"urgency_level": "High",
|
797 |
+
"submission_timestamp": "2023-10-02T08:15:00Z",
|
798 |
+
"location": {
|
799 |
+
"hostel_name": "Hostel A",
|
800 |
+
"floor_number": 2,
|
801 |
+
"room_number": "204"
|
802 |
+
}
|
803 |
+
}
|
804 |
+
```
|
805 |
+
|
806 |
+
- **Worker Profiles Dataset:**
|
807 |
+
- **Features:** Worker ID, department, current workload, availability status, job success rates.
|
808 |
+
- **Example:**
|
809 |
+
```json
|
810 |
+
{
|
811 |
+
"worker_id": "W67890",
|
812 |
+
"department": "Electrical",
|
813 |
+
"current_workload": 3,
|
814 |
+
"availability_status": "Available",
|
815 |
+
"job_success_rate": 0.95
|
816 |
+
}
|
817 |
+
```
|
818 |
+
|
819 |
+
- **Historical Assignments Dataset:**
|
820 |
+
- **Features:** Job ID, worker ID, assignment timestamp, resolution time, outcome, location.
|
821 |
+
- **Example:**
|
822 |
+
```json
|
823 |
+
{
|
824 |
+
"job_id": "J12340",
|
825 |
+
"worker_id": "W67885",
|
826 |
+
"assignment_timestamp": "2023-09-25T09:00:00Z",
|
827 |
+
"resolution_time": "2 hours",
|
828 |
+
"outcome": "Resolved Successfully",
|
829 |
+
"location": {
|
830 |
+
"hostel_name": "Hostel A",
|
831 |
+
"floor_number": 1,
|
832 |
+
"room_number": "101"
|
833 |
+
}
|
834 |
+
}
|
835 |
+
```
|
836 |
+
|
837 |
+
- **Spatial Data Dataset:**
|
838 |
+
- **Features:** Worker locations, job locations, distance metrics.
|
839 |
+
- **Example:**
|
840 |
+
```json
|
841 |
+
{
|
842 |
+
"worker_id": "W67890",
|
843 |
+
"current_location": {
|
844 |
+
"hostel_name": "Hostel A",
|
845 |
+
"floor_number": 2,
|
846 |
+
"room_number": "210"
|
847 |
+
},
|
848 |
+
"available_distance_radius": 50
|
849 |
+
}
|
850 |
+
```
|
851 |
+
|
852 |
+
### **Sample Input and Output**
|
853 |
+
|
854 |
+
- **Sample Input:**
|
855 |
+
```json
|
856 |
+
{
|
857 |
+
"job_id": "J12346",
|
858 |
+
"type": "Electrical",
|
859 |
+
"description": "Power outage in room 204.",
|
860 |
+
"urgency_level": "Critical",
|
861 |
+
"submission_timestamp": "2023-10-02T08:15:00Z",
|
862 |
+
"location": {
|
863 |
+
"hostel_name": "Hostel A",
|
864 |
+
"floor_number": 2,
|
865 |
+
"room_number": "204"
|
866 |
+
},
|
867 |
+
"workers": [
|
868 |
+
{
|
869 |
+
"worker_id": "W67890",
|
870 |
+
"department": "Electrical",
|
871 |
+
"current_workload": 3,
|
872 |
+
"availability_status": "Available",
|
873 |
+
"job_success_rate": 0.95,
|
874 |
+
"current_location": {
|
875 |
+
"hostel_name": "Hostel A",
|
876 |
+
"floor_number": 2,
|
877 |
+
"room_number": "210"
|
878 |
+
}
|
879 |
+
},
|
880 |
+
{
|
881 |
+
"worker_id": "W67891",
|
882 |
+
"department": "Mechanical",
|
883 |
+
"current_workload": 2,
|
884 |
+
"availability_status": "Available",
|
885 |
+
"job_success_rate": 0.90,
|
886 |
+
"current_location": {
|
887 |
+
"hostel_name": "Hostel A",
|
888 |
+
"floor_number": 2,
|
889 |
+
"room_number": "215"
|
890 |
+
}
|
891 |
+
}
|
892 |
+
]
|
893 |
+
}
|
894 |
+
```
|
895 |
+
|
896 |
+
- **Sample Output:**
|
897 |
+
```json
|
898 |
+
{
|
899 |
+
"job_id": "J12346",
|
900 |
+
"assigned_worker_id": "W67890",
|
901 |
+
"assignment_timestamp": "2023-10-02T08:16:00Z",
|
902 |
+
"expected_resolution_time": "1 hour",
|
903 |
+
"location": {
|
904 |
+
"hostel_name": "Hostel A",
|
905 |
+
"floor_number": 2,
|
906 |
+
"room_number": "204"
|
907 |
+
}
|
908 |
+
}
|
909 |
+
```
|
910 |
+
|
911 |
+
### **Additional Recommendation Factors**
|
912 |
+
|
913 |
+
Beyond the factors provided, the following additional factors can enhance job recommendations:
|
914 |
+
|
915 |
+
5. **Current Traffic Load:** The number of jobs currently assigned to nearby workers.
|
916 |
+
6. **Department Specialization:** Specific expertise within general department categories (e.g., high-voltage electrical systems).
|
917 |
+
7. **Worker's Past Performance in Similar Jobs:** Higher priority to workers who have successfully resolved similar issues efficiently.
|
918 |
+
8. **Geographical Proximity:** Minimizing travel time by assigning jobs to the closest available worker.
|
919 |
+
9. **Time of Day:** Allocating jobs considering workers' shift timings and peak activity periods.
|
920 |
+
10. **Worker's Preferences:** Respecting workers' preferences for certain types of jobs or locations within their department.
|
921 |
+
|
922 |
+
---
|
923 |
+
|
924 |
+
# Conclusion
|
925 |
+
|
926 |
+
Implementing these AI/ML functionalities will significantly enhance the efficiency and effectiveness of the Hostel Grievance Redressal System. By leveraging advanced technologies like reinforcement learning, transformer-based models, and anomaly detection algorithms, and by integrating them within a Flask API framework, the system will provide a more responsive, empathetic, and proactive approach to managing resident grievances. Proper data collection, preprocessing, model training, and continuous monitoring are crucial to the success of these implementations. Following the detailed steps outlined above will ensure a robust and scalable integration of AI/ML capabilities into the existing system.
|
927 |
+
|
928 |
+
---
|
929 |
+
|
930 |
+
# License
|
931 |
+
|
932 |
+
This project is licensed under the [MIT License](LICENSE).
|
933 |
+
|
934 |
+
# Contact
|
935 |
+
|
936 |
+
For any questions or feedback, please contact [your-email@example.com](mailto:your-email@example.com).
|
docs/data_plan.md
ADDED
@@ -0,0 +1,313 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
# Dataset Plan for AI/ML Models
|
2 |
+
|
3 |
+
This document outlines the datasets required for implementing the AI/ML functionalities described in the ai_plan.md file. For each model, we'll provide the CSV structure and example records.
|
4 |
+
|
5 |
+
## 1. Intelligent Routing and Workflow Automation
|
6 |
+
|
7 |
+
### 1.1 Grievance Data (grievances.csv)
|
8 |
+
|
9 |
+
Fields:
|
10 |
+
- grievance_id (string)
|
11 |
+
- category (string)
|
12 |
+
- submission_timestamp (datetime)
|
13 |
+
- student_room_no (string)
|
14 |
+
- hostel_name (string)
|
15 |
+
- floor_number (integer)
|
16 |
+
|
17 |
+
Examples:
|
18 |
+
```csv
|
19 |
+
grievance_id,category,submission_timestamp,student_room_no,hostel_name,floor_number
|
20 |
+
G12345,plumber,2023-10-01T10:30:00Z,204,bh1,2
|
21 |
+
G12346,electricity,2023-10-02T08:15:00Z,101,bh2,1
|
22 |
+
G12347,internet,2023-10-03T14:20:00Z,305,bh3,3
|
23 |
+
G12348,water cooler,2023-10-04T09:45:00Z,102,ivh,1
|
24 |
+
G12349,sweeper,2023-10-05T11:00:00Z,201,gh,2
|
25 |
+
G12350,carpenter,2023-10-06T13:30:00Z,303,bh1,3
|
26 |
+
```
|
27 |
+
|
28 |
+
### 1.2 Staff Data (staff.csv)
|
29 |
+
|
30 |
+
Fields:
|
31 |
+
- staff_id (string)
|
32 |
+
- department (string)
|
33 |
+
- current_workload (integer)
|
34 |
+
- availability_status (string)
|
35 |
+
- past_resolution_rate (float)
|
36 |
+
|
37 |
+
Examples:
|
38 |
+
```csv
|
39 |
+
staff_id,department,current_workload,availability_status,past_resolution_rate
|
40 |
+
S67890,plumber,5,Available,0.95
|
41 |
+
S67891,electricity,3,Available,0.92
|
42 |
+
S67892,internet,4,Unavailable,0.88
|
43 |
+
S67893,water cooler,2,Available,0.97
|
44 |
+
S67894,sweeper,6,Available,0.91
|
45 |
+
S67895,carpenter,1,Available,0.94
|
46 |
+
```
|
47 |
+
|
48 |
+
### 1.3 Historical Assignments (historical_assignments.csv)
|
49 |
+
|
50 |
+
Fields:
|
51 |
+
- grievance_id (string)
|
52 |
+
- staff_id (string)
|
53 |
+
- assignment_timestamp (datetime)
|
54 |
+
- resolution_time (string)
|
55 |
+
- outcome (string)
|
56 |
+
- floor_number (integer)
|
57 |
+
|
58 |
+
Examples:
|
59 |
+
```csv
|
60 |
+
grievance_id,staff_id,assignment_timestamp,resolution_time,outcome,floor_number
|
61 |
+
G12340,S67890,2023-09-25T09:00:00Z,2 hours,Resolved Successfully,1
|
62 |
+
G12341,S67891,2023-09-26T10:30:00Z,1 hour,Resolved Successfully,2
|
63 |
+
G12342,S67892,2023-09-27T14:15:00Z,3 hours,Unresolved,3
|
64 |
+
G12343,S67893,2023-09-28T11:45:00Z,30 minutes,Resolved Successfully,1
|
65 |
+
G12344,S67894,2023-09-29T08:30:00Z,1 hour,Resolved Successfully,2
|
66 |
+
G12345,S67895,2023-09-30T13:00:00Z,2 hours,Pending,3
|
67 |
+
```
|
68 |
+
|
69 |
+
### 1.4 Floor Metrics (floor_metrics.csv)
|
70 |
+
|
71 |
+
Fields:
|
72 |
+
- hostel_name (string)
|
73 |
+
- floor_number (integer)
|
74 |
+
- date (date)
|
75 |
+
- number_of_requests (integer)
|
76 |
+
- total_delays (integer)
|
77 |
+
|
78 |
+
Examples:
|
79 |
+
```csv
|
80 |
+
hostel_name,floor_number,date,number_of_requests,total_delays
|
81 |
+
bh1,2,2023-10-01,20,2
|
82 |
+
bh2,1,2023-10-02,15,1
|
83 |
+
bh3,3,2023-10-03,18,3
|
84 |
+
ivh,1,2023-10-04,12,0
|
85 |
+
gh,2,2023-10-05,22,4
|
86 |
+
```
|
87 |
+
|
88 |
+
### 1.5 Availability Data (availability.csv)
|
89 |
+
|
90 |
+
Fields:
|
91 |
+
- id (string)
|
92 |
+
- type (string) # 'staff' or 'student'
|
93 |
+
- date (date)
|
94 |
+
- time_slot (string)
|
95 |
+
- availability_status (string)
|
96 |
+
|
97 |
+
Examples:
|
98 |
+
```csv
|
99 |
+
id,type,date,time_slot,availability_status
|
100 |
+
S67890,staff,2023-10-02,09:00-12:00,Available
|
101 |
+
S67891,staff,2023-10-02,14:00-17:00,Unavailable
|
102 |
+
STU123,student,2023-10-02,10:00-12:00,Available
|
103 |
+
STU124,student,2023-10-02,14:00-16:00,Unavailable
|
104 |
+
S67892,staff,2023-10-03,08:00-11:00,Available
|
105 |
+
STU125,student,2023-10-03,09:00-11:00,Available
|
106 |
+
```
|
107 |
+
|
108 |
+
## 2. Advanced Sentiment and Emotional Intelligence Analysis
|
109 |
+
|
110 |
+
### 2.1 Grievance Sentiment Data (grievance_sentiment.csv)
|
111 |
+
|
112 |
+
Fields:
|
113 |
+
- grievance_id (string)
|
114 |
+
- text (string)
|
115 |
+
- emotional_label (string)
|
116 |
+
|
117 |
+
Example:
|
118 |
+
```csv
|
119 |
+
grievance_id,text,emotional_label
|
120 |
+
G12347,"I am extremely frustrated with the constant power outages in my room.",Frustration
|
121 |
+
G12348,"Thank you for resolving my issue so quickly.",Satisfaction
|
122 |
+
```
|
123 |
+
|
124 |
+
## 3. Context-Aware Chatbots for Initial Grievance Handling
|
125 |
+
|
126 |
+
### 3.1 Conversation Dataset (conversations.csv)
|
127 |
+
|
128 |
+
Fields:
|
129 |
+
- conversation_id (string)
|
130 |
+
- user_message (string)
|
131 |
+
- intent (string)
|
132 |
+
- entities (string, JSON format)
|
133 |
+
- bot_response (string)
|
134 |
+
|
135 |
+
Example:
|
136 |
+
```csv
|
137 |
+
conversation_id,user_message,intent,entities,bot_response
|
138 |
+
C12345,"I want to report a broken heater in my room.",submit_grievance,"{'grievance_type': 'Broken Heater', 'room_number': '305'}","I'm sorry to hear that. Could you please provide your room number?"
|
139 |
+
```
|
140 |
+
|
141 |
+
### 3.2 FAQs Dataset (faqs.csv)
|
142 |
+
|
143 |
+
Fields:
|
144 |
+
- question_id (string)
|
145 |
+
- question (string)
|
146 |
+
- answer (string)
|
147 |
+
|
148 |
+
Example:
|
149 |
+
```csv
|
150 |
+
question_id,question,answer
|
151 |
+
Q12345,"How can I check the status of my grievance?","You can check the status by logging into your dashboard and navigating to the 'My Grievances' section."
|
152 |
+
```
|
153 |
+
|
154 |
+
## 4. Anomaly Detection in Grievance Patterns
|
155 |
+
|
156 |
+
### 4.1 Grievance Logs (grievance_logs.csv)
|
157 |
+
|
158 |
+
Fields:
|
159 |
+
- grievance_id (string)
|
160 |
+
- category (string)
|
161 |
+
- timestamp (datetime)
|
162 |
+
- description (string)
|
163 |
+
|
164 |
+
Example:
|
165 |
+
```csv
|
166 |
+
grievance_id,category,timestamp,description
|
167 |
+
G12350,Plumbing,2023-10-03T14:20:00Z,"Clogged drain in the kitchen area."
|
168 |
+
```
|
169 |
+
|
170 |
+
### 4.2 Anomaly Indicators (anomaly_indicators.csv)
|
171 |
+
|
172 |
+
Fields:
|
173 |
+
- date (date)
|
174 |
+
- category (string)
|
175 |
+
- grievance_count (integer)
|
176 |
+
- is_anomaly (boolean)
|
177 |
+
|
178 |
+
Example:
|
179 |
+
```csv
|
180 |
+
date,category,grievance_count,is_anomaly
|
181 |
+
2023-10-01,Electrical,50,false
|
182 |
+
2023-10-02,Electrical,150,true
|
183 |
+
```
|
184 |
+
|
185 |
+
## 5. Multilingual Translation in Chatroom
|
186 |
+
|
187 |
+
### 5.1 Translation Pairs (translation_pairs.csv)
|
188 |
+
|
189 |
+
Fields:
|
190 |
+
- pair_id (string)
|
191 |
+
- source_language (string)
|
192 |
+
- target_language (string)
|
193 |
+
- source_sentence (string)
|
194 |
+
- target_sentence (string)
|
195 |
+
|
196 |
+
Example:
|
197 |
+
```csv
|
198 |
+
pair_id,source_language,target_language,source_sentence,target_sentence
|
199 |
+
TP12345,Hindi,English,"toilet me paani nahi aa rha hain","There is no water coming in the toilet."
|
200 |
+
```
|
201 |
+
|
202 |
+
### 5.2 Language Preferences (language_preferences.csv)
|
203 |
+
|
204 |
+
Fields:
|
205 |
+
- user_id (string)
|
206 |
+
- preferred_language (string)
|
207 |
+
|
208 |
+
Example:
|
209 |
+
```csv
|
210 |
+
user_id,preferred_language
|
211 |
+
U12345,Hindi
|
212 |
+
W67890,English
|
213 |
+
```
|
214 |
+
|
215 |
+
## 6. Worker Job Recommendation
|
216 |
+
|
217 |
+
### 6.1 Job Requests (job_requests.csv)
|
218 |
+
|
219 |
+
Fields:
|
220 |
+
- job_id (string)
|
221 |
+
- type (string)
|
222 |
+
- description (string)
|
223 |
+
- urgency_level (string)
|
224 |
+
- submission_timestamp (datetime)
|
225 |
+
- hostel_name (string)
|
226 |
+
- floor_number (integer)
|
227 |
+
- room_number (string)
|
228 |
+
|
229 |
+
Example:
|
230 |
+
```csv
|
231 |
+
job_id,type,description,urgency_level,submission_timestamp,hostel_name,floor_number,room_number
|
232 |
+
J12345,Electrical,"Fan not working in room 204.",High,2023-10-02T08:15:00Z,Hostel A,2,204
|
233 |
+
```
|
234 |
+
|
235 |
+
### 6.2 Worker Profiles (worker_profiles.csv)
|
236 |
+
|
237 |
+
Fields:
|
238 |
+
- worker_id (string)
|
239 |
+
- department (string)
|
240 |
+
- current_workload (integer)
|
241 |
+
- availability_status (string)
|
242 |
+
- job_success_rate (float)
|
243 |
+
|
244 |
+
Example:
|
245 |
+
```csv
|
246 |
+
worker_id,department,current_workload,availability_status,job_success_rate
|
247 |
+
W67890,Electrical,3,Available,0.95
|
248 |
+
```
|
249 |
+
|
250 |
+
### 6.3 Historical Job Assignments (historical_job_assignments.csv)
|
251 |
+
|
252 |
+
Fields:
|
253 |
+
- job_id (string)
|
254 |
+
- worker_id (string)
|
255 |
+
- assignment_timestamp (datetime)
|
256 |
+
- resolution_time (string)
|
257 |
+
- outcome (string)
|
258 |
+
- hostel_name (string)
|
259 |
+
- floor_number (integer)
|
260 |
+
- room_number (string)
|
261 |
+
|
262 |
+
Example:
|
263 |
+
```csv
|
264 |
+
job_id,worker_id,assignment_timestamp,resolution_time,outcome,hostel_name,floor_number,room_number
|
265 |
+
J12340,W67885,2023-09-25T09:00:00Z,2 hours,Resolved Successfully,Hostel A,1,101
|
266 |
+
```
|
267 |
+
|
268 |
+
### 6.4 Worker Locations (worker_locations.csv)
|
269 |
+
|
270 |
+
Fields:
|
271 |
+
- worker_id (string)
|
272 |
+
- timestamp (datetime)
|
273 |
+
- hostel_name (string)
|
274 |
+
- floor_number (integer)
|
275 |
+
- room_number (string)
|
276 |
+
|
277 |
+
Example:
|
278 |
+
```csv
|
279 |
+
worker_id,timestamp,hostel_name,floor_number,room_number
|
280 |
+
W67890,2023-10-02T08:00:00Z,Hostel A,2,210
|
281 |
+
```
|
282 |
+
```
|
283 |
+
data/
|
284 |
+
│
|
285 |
+
├── intelligent_routing/
|
286 |
+
│ ├── grievances.csv
|
287 |
+
│ ├── staff.csv
|
288 |
+
│ ├── historical_assignments.csv
|
289 |
+
│ ├── floor_metrics.csv
|
290 |
+
│ └── availability.csv
|
291 |
+
│
|
292 |
+
├── sentiment_analysis/
|
293 |
+
│ └── grievance_sentiment.csv
|
294 |
+
│
|
295 |
+
├── chatbot/
|
296 |
+
│ ├── conversations.csv
|
297 |
+
│ └── faqs.csv
|
298 |
+
│
|
299 |
+
├── anomaly_detection/
|
300 |
+
│ ├── grievance_logs.csv
|
301 |
+
│ └── anomaly_indicators.csv
|
302 |
+
│
|
303 |
+
├── multilingual_translation/
|
304 |
+
│ ├── translation_pairs.csv
|
305 |
+
│ └── language_preferences.csv
|
306 |
+
│
|
307 |
+
└── job_recommendation/
|
308 |
+
├── job_requests.csv
|
309 |
+
├── worker_profiles.csv
|
310 |
+
├── historical_job_assignments.csv
|
311 |
+
└── worker_locations.csv
|
312 |
+
|
313 |
+
```
|
docs/plan.md
ADDED
@@ -0,0 +1,864 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
# Project Plan for Hostel Grievance Redressal System
|
2 |
+
|
3 |
+
## Table of Contents
|
4 |
+
|
5 |
+
1. [Web Pages Design](#1-web-pages-design)
|
6 |
+
- [High-Level Design](#high-level-design)
|
7 |
+
- [Low-Level Design](#low-level-design)
|
8 |
+
2. [Workflow and Event Flow](#2-workflow-and-event-flow)
|
9 |
+
3. [Directory Structure and File Division](#3-directory-structure-and-file-division)
|
10 |
+
4. [Backend and Frontend Separation](#4-backend-and-frontend-separation)
|
11 |
+
5. [Performance Dashboard for Students](#5-performance-dashboard-for-students)
|
12 |
+
|
13 |
+
---
|
14 |
+
|
15 |
+
## 1. Web Pages Design
|
16 |
+
|
17 |
+
### High-Level Design
|
18 |
+
|
19 |
+
The Hostel Grievance Redressal System consists of several web pages tailored for different user roles: **Residents (Students)** and **Administrators (Wardens)**. Each page is designed to provide specific functionalities to enhance user experience and ensure efficient grievance management.
|
20 |
+
|
21 |
+
#### Pages Overview
|
22 |
+
|
23 |
+
1. **Authentication Pages**
|
24 |
+
- **Login Page**
|
25 |
+
- **Signup Page**
|
26 |
+
|
27 |
+
2. **Resident Pages**
|
28 |
+
- **Student Dashboard**
|
29 |
+
- **Student Profile Information**
|
30 |
+
- **Submit Grievance**
|
31 |
+
- **View Submitted Grievances**
|
32 |
+
- **Grievance Details and Chatroom**
|
33 |
+
|
34 |
+
3. **Administrator Pages**
|
35 |
+
- **Warden Dashboard**
|
36 |
+
- **Manage Grievances**
|
37 |
+
- **Resolve Grievance**
|
38 |
+
- **Performance Dashboard**
|
39 |
+
|
40 |
+
4. **Common Components**
|
41 |
+
- **Navigation Bar**
|
42 |
+
- **Footer**
|
43 |
+
- **Notification System**
|
44 |
+
|
45 |
+
### Low-Level Design
|
46 |
+
|
47 |
+
#### 1. Authentication Pages
|
48 |
+
|
49 |
+
##### Login Page
|
50 |
+
- **Components:**
|
51 |
+
- **LoginForm**
|
52 |
+
- Email Input
|
53 |
+
- Password Input
|
54 |
+
- Submit Button
|
55 |
+
- **Forgot Password Link**
|
56 |
+
- **Signup Redirect Link**
|
57 |
+
- **Functionality:**
|
58 |
+
- User enters credentials and submits to authenticate.
|
59 |
+
- Validation for input fields.
|
60 |
+
- Error handling for incorrect credentials.
|
61 |
+
|
62 |
+
```markdown
|
63 |
+
````react:src/frontend/components/LoginPage.js
|
64 |
+
function LoginPage() {
|
65 |
+
return (
|
66 |
+
<div className="login-container">
|
67 |
+
<LoginForm />
|
68 |
+
<a href="/forgot-password">Forgot Password?</a>
|
69 |
+
<a href="/signup">Don't have an account? Sign Up</a>
|
70 |
+
</div>
|
71 |
+
);
|
72 |
+
}
|
73 |
+
```
|
74 |
+
````
|
75 |
+
|
76 |
+
##### Signup Page
|
77 |
+
- **Components:**
|
78 |
+
- **SignupForm**
|
79 |
+
- Name Input
|
80 |
+
- Email Input
|
81 |
+
- Password Input
|
82 |
+
- Confirm Password Input
|
83 |
+
- Submit Button
|
84 |
+
- **Functionality:**
|
85 |
+
- User registers by providing necessary details.
|
86 |
+
- Validation for input fields.
|
87 |
+
- Password strength indicator.
|
88 |
+
|
89 |
+
```markdown
|
90 |
+
````react:src/frontend/components/SignupPage.js
|
91 |
+
function SignupPage() {
|
92 |
+
return (
|
93 |
+
<div className="signup-container">
|
94 |
+
<SignupForm />
|
95 |
+
<a href="/login">Already have an account? Login</a>
|
96 |
+
</div>
|
97 |
+
);
|
98 |
+
}
|
99 |
+
```
|
100 |
+
````
|
101 |
+
|
102 |
+
#### 2. Resident Pages
|
103 |
+
|
104 |
+
##### Student Dashboard
|
105 |
+
- **Components:**
|
106 |
+
- **Sidebar Navigation**
|
107 |
+
- **Recent Grievances**
|
108 |
+
- **Statistics Overview**
|
109 |
+
- **Quick Submit Button**
|
110 |
+
- **Functionality:**
|
111 |
+
- Overview of submitted grievances.
|
112 |
+
- Quick access to submit new grievances.
|
113 |
+
- Visual statistics on grievance statuses.
|
114 |
+
|
115 |
+
```markdown
|
116 |
+
````react:src/frontend/pages/StudentDashboard.js
|
117 |
+
function StudentDashboard() {
|
118 |
+
return (
|
119 |
+
<div className="dashboard-container">
|
120 |
+
<Sidebar />
|
121 |
+
<div className="dashboard-content">
|
122 |
+
<RecentGrievances />
|
123 |
+
<StatisticsOverview />
|
124 |
+
<QuickSubmitButton />
|
125 |
+
</div>
|
126 |
+
</div>
|
127 |
+
);
|
128 |
+
}
|
129 |
+
```
|
130 |
+
````
|
131 |
+
|
132 |
+
##### Student Profile Information
|
133 |
+
- **Components:**
|
134 |
+
- **ProfileForm**
|
135 |
+
- Editable fields: Name, Email, Contact Number, Address
|
136 |
+
- Save Button
|
137 |
+
- **ProfilePictureUpload**
|
138 |
+
- **Functionality:**
|
139 |
+
- View and edit personal information.
|
140 |
+
- Update profile picture.
|
141 |
+
|
142 |
+
```markdown
|
143 |
+
````react:src/frontend/pages/StudentProfile.js
|
144 |
+
function StudentProfile() {
|
145 |
+
return (
|
146 |
+
<div className="profile-container">
|
147 |
+
<Sidebar />
|
148 |
+
<div className="profile-content">
|
149 |
+
<ProfileForm />
|
150 |
+
<ProfilePictureUpload />
|
151 |
+
</div>
|
152 |
+
</div>
|
153 |
+
);
|
154 |
+
}
|
155 |
+
```
|
156 |
+
````
|
157 |
+
|
158 |
+
##### Submit Grievance
|
159 |
+
- **Components:**
|
160 |
+
- **GrievanceForm**
|
161 |
+
- Title Input
|
162 |
+
- Description Textarea
|
163 |
+
- Category Dropdown
|
164 |
+
- Attachments Upload
|
165 |
+
- Voice-to-Text Input
|
166 |
+
- Submit Button
|
167 |
+
- **Functionality:**
|
168 |
+
- Allow residents to submit grievances with text or voice input.
|
169 |
+
- Attach relevant files if necessary.
|
170 |
+
- Categorize grievance for proper routing.
|
171 |
+
|
172 |
+
```markdown
|
173 |
+
````react:src/frontend/pages/SubmitGrievance.js
|
174 |
+
function SubmitGrievance() {
|
175 |
+
return (
|
176 |
+
<div className="submit-grievance-container">
|
177 |
+
<Sidebar />
|
178 |
+
<div className="grievance-form-container">
|
179 |
+
<GrievanceForm />
|
180 |
+
</div>
|
181 |
+
</div>
|
182 |
+
);
|
183 |
+
}
|
184 |
+
```
|
185 |
+
|
186 |
+
|
187 |
+
##### View Submitted Grievances
|
188 |
+
- **Components:**
|
189 |
+
- **GrievanceList**
|
190 |
+
- List Item (GrievanceTitle, Status, Submission Date)
|
191 |
+
- **Filter and Search Bar**
|
192 |
+
- **Functionality:**
|
193 |
+
- Display a list of grievances submitted by the student.
|
194 |
+
- Filter and search functionality for easy navigation.
|
195 |
+
|
196 |
+
```markdown
|
197 |
+
````react:src/frontend/pages/ViewGrievances.js
|
198 |
+
function ViewGrievances() {
|
199 |
+
return (
|
200 |
+
<div className="view-grievances-container">
|
201 |
+
<Sidebar />
|
202 |
+
<div className="grievances-list-container">
|
203 |
+
<FilterSearchBar />
|
204 |
+
<GrievanceList />
|
205 |
+
</div>
|
206 |
+
</div>
|
207 |
+
);
|
208 |
+
}
|
209 |
+
```
|
210 |
+
|
211 |
+
|
212 |
+
##### Grievance Details and Chatroom
|
213 |
+
- **Components:**
|
214 |
+
- **GrievanceDetails**
|
215 |
+
- Grievance Information (Title, Description, Status, Assigned Warden)
|
216 |
+
- **Chatroom**
|
217 |
+
- Message List
|
218 |
+
- Input Box
|
219 |
+
- Send Button
|
220 |
+
- **Functionality:**
|
221 |
+
- View detailed information about a specific grievance.
|
222 |
+
- Real-time chat with assigned warden for updates and communication.
|
223 |
+
|
224 |
+
```markdown
|
225 |
+
````react:src/frontend/pages/GrievanceDetails.js
|
226 |
+
function GrievanceDetails({ grievanceId }) {
|
227 |
+
return (
|
228 |
+
<div className="grievance-details-container">
|
229 |
+
<Sidebar />
|
230 |
+
<div className="details-and-chat">
|
231 |
+
<GrievanceDetails />
|
232 |
+
<Chatroom grievanceId={grievanceId} />
|
233 |
+
</div>
|
234 |
+
</div>
|
235 |
+
);
|
236 |
+
}
|
237 |
+
```
|
238 |
+
|
239 |
+
|
240 |
+
#### 3. Administrator Pages
|
241 |
+
|
242 |
+
##### Warden Dashboard
|
243 |
+
- **Components:**
|
244 |
+
- **Sidebar Navigation**
|
245 |
+
- **Grievances Overview**
|
246 |
+
- **Assigned Grievances**
|
247 |
+
- **Performance Metrics**
|
248 |
+
- **Functionality:**
|
249 |
+
- Overview of all grievances.
|
250 |
+
- Manage assignments and track resolution progress.
|
251 |
+
- View performance metrics of handled grievances.
|
252 |
+
|
253 |
+
```markdown
|
254 |
+
````react:src/frontend/pages/WardenDashboard.js
|
255 |
+
function WardenDashboard() {
|
256 |
+
return (
|
257 |
+
<div className="warden-dashboard-container">
|
258 |
+
<Sidebar />
|
259 |
+
<div className="warden-dashboard-content">
|
260 |
+
<GrievancesOverview />
|
261 |
+
<AssignedGrievances />
|
262 |
+
<PerformanceMetrics />
|
263 |
+
</div>
|
264 |
+
</div>
|
265 |
+
);
|
266 |
+
}
|
267 |
+
```
|
268 |
+
|
269 |
+
|
270 |
+
##### Manage Grievances
|
271 |
+
- **Components:**
|
272 |
+
- **GrievanceManagementList**
|
273 |
+
- Grievance Item (Title, Status, Assigned To, Actions)
|
274 |
+
- **Filter and Sort Options**
|
275 |
+
- **Functionality:**
|
276 |
+
- View and manage all grievances.
|
277 |
+
- Assign grievances to appropriate personnel.
|
278 |
+
- Update grievance statuses.
|
279 |
+
|
280 |
+
```markdown
|
281 |
+
````react:src/frontend/pages/ManageGrievances.js
|
282 |
+
function ManageGrievances() {
|
283 |
+
return (
|
284 |
+
<div className="manage-grievances-container">
|
285 |
+
<Sidebar />
|
286 |
+
<div className="management-content">
|
287 |
+
<FilterSortOptions />
|
288 |
+
<GrievanceManagementList />
|
289 |
+
</div>
|
290 |
+
</div>
|
291 |
+
);
|
292 |
+
}
|
293 |
+
```
|
294 |
+
|
295 |
+
|
296 |
+
##### Resolve Grievance
|
297 |
+
- **Components:**
|
298 |
+
- **ResolutionForm**
|
299 |
+
- Resolution Description
|
300 |
+
- Status Update Dropdown
|
301 |
+
- Attachments Upload
|
302 |
+
- Submit Resolution Button
|
303 |
+
- **Functionality:**
|
304 |
+
- Provide resolution details for a grievance.
|
305 |
+
- Update the status to "Completed" or other relevant states.
|
306 |
+
- Notify the resident upon resolution.
|
307 |
+
|
308 |
+
```markdown
|
309 |
+
````react:src/frontend/pages/ResolveGrievance.js
|
310 |
+
function ResolveGrievance({ grievanceId }) {
|
311 |
+
return (
|
312 |
+
<div className="resolve-grievance-container">
|
313 |
+
<Sidebar />
|
314 |
+
<div className="resolution-form-container">
|
315 |
+
<ResolutionForm grievanceId={grievanceId} />
|
316 |
+
</div>
|
317 |
+
</div>
|
318 |
+
);
|
319 |
+
}
|
320 |
+
```
|
321 |
+
|
322 |
+
|
323 |
+
#### 4. Common Components
|
324 |
+
|
325 |
+
##### Navigation Bar
|
326 |
+
- **Components:**
|
327 |
+
- **Logo**
|
328 |
+
- **Navigation Links**
|
329 |
+
- **User Profile Dropdown**
|
330 |
+
- **Notifications Icon**
|
331 |
+
- **Functionality:**
|
332 |
+
- Provide easy navigation across different pages.
|
333 |
+
- Access user profile and notifications.
|
334 |
+
|
335 |
+
```markdown
|
336 |
+
````react:src/frontend/components/NavigationBar.js
|
337 |
+
function NavigationBar() {
|
338 |
+
return (
|
339 |
+
<nav className="navigation-bar">
|
340 |
+
<Logo />
|
341 |
+
<NavigationLinks />
|
342 |
+
<UserProfileDropdown />
|
343 |
+
<NotificationsIcon />
|
344 |
+
</nav>
|
345 |
+
);
|
346 |
+
}
|
347 |
+
```
|
348 |
+
|
349 |
+
|
350 |
+
##### Footer
|
351 |
+
- **Components:**
|
352 |
+
- **Links**
|
353 |
+
- **Contact Information**
|
354 |
+
- **Social Media Icons**
|
355 |
+
- **Functionality:**
|
356 |
+
- Provide additional navigation and contact information.
|
357 |
+
- Enhance the overall aesthetics of the application.
|
358 |
+
|
359 |
+
```markdown
|
360 |
+
````react:src/frontend/components/Footer.js
|
361 |
+
function Footer() {
|
362 |
+
return (
|
363 |
+
<footer className="footer">
|
364 |
+
<Links />
|
365 |
+
<ContactInfo />
|
366 |
+
<SocialMediaIcons />
|
367 |
+
</footer>
|
368 |
+
);
|
369 |
+
}
|
370 |
+
```
|
371 |
+
|
372 |
+
|
373 |
+
##### Notification System
|
374 |
+
- **Components:**
|
375 |
+
- **NotificationList**
|
376 |
+
- Individual Notification Items
|
377 |
+
- **Real-time Notification Badge**
|
378 |
+
- **Functionality:**
|
379 |
+
- Display real-time notifications for updates on grievances.
|
380 |
+
- Alert users for new messages or status changes.
|
381 |
+
|
382 |
+
```markdown
|
383 |
+
````react:src/frontend/components/NotificationSystem.js
|
384 |
+
function NotificationSystem() {
|
385 |
+
return (
|
386 |
+
<div className="notification-system">
|
387 |
+
<NotificationBadge />
|
388 |
+
<NotificationList />
|
389 |
+
</div>
|
390 |
+
);
|
391 |
+
}
|
392 |
+
```
|
393 |
+
|
394 |
+
|
395 |
+
---
|
396 |
+
|
397 |
+
## 2. Workflow and Event Flow
|
398 |
+
|
399 |
+
### User Roles and Actions
|
400 |
+
|
401 |
+
#### Resident (Student) Workflow
|
402 |
+
|
403 |
+
1. **Registration and Authentication**
|
404 |
+
- **Events:**
|
405 |
+
- User navigates to Signup Page.
|
406 |
+
- Submits registration form.
|
407 |
+
- System validates and creates user account.
|
408 |
+
- User logs in via Login Page.
|
409 |
+
|
410 |
+
2. **Submitting a Grievance**
|
411 |
+
- **Events:**
|
412 |
+
- User accesses Submit Grievance Page.
|
413 |
+
- Fills out grievance form or uses voice-to-text feature.
|
414 |
+
- Submits grievance.
|
415 |
+
- System categorizes and routes grievance using AI-powered routing.
|
416 |
+
- A chatroom is created for real-time communication.
|
417 |
+
- User receives confirmation and grievance status updates.
|
418 |
+
|
419 |
+
3. **Tracking Grievances**
|
420 |
+
- **Events:**
|
421 |
+
- User views Student Dashboard.
|
422 |
+
- Navigates to View Grievances.
|
423 |
+
- Selects a grievance to view details and participate in chat.
|
424 |
+
|
425 |
+
4. **Profile Management**
|
426 |
+
- **Events:**
|
427 |
+
- User accesses Profile Information page.
|
428 |
+
- Updates personal details or profile picture.
|
429 |
+
- Saves changes, and system updates the database.
|
430 |
+
|
431 |
+
#### Administrator (Warden) Workflow
|
432 |
+
|
433 |
+
1. **Authentication**
|
434 |
+
- **Events:**
|
435 |
+
- Warden logs in via Login Page.
|
436 |
+
- Accesses Warden Dashboard upon successful authentication.
|
437 |
+
|
438 |
+
2. **Managing Grievances**
|
439 |
+
- **Events:**
|
440 |
+
- Warden views all grievances in Manage Grievances page.
|
441 |
+
- Assigns grievances to appropriate personnel.
|
442 |
+
- Updates grievance statuses as they progress.
|
443 |
+
- Resolves grievances by providing resolution details.
|
444 |
+
|
445 |
+
3. **Performance Monitoring**
|
446 |
+
- **Events:**
|
447 |
+
- Warden accesses Performance Dashboard.
|
448 |
+
- Views metrics on grievance handling efficiency, resolution times, and staff performance.
|
449 |
+
- Generates reports for administrative review.
|
450 |
+
|
451 |
+
4. **Real-time Communication**
|
452 |
+
- **Events:**
|
453 |
+
- Warden participates in chatrooms for assigned grievances.
|
454 |
+
- Sends and receives messages for updates and clarifications.
|
455 |
+
|
456 |
+
### AI/ML Functionalities Integration
|
457 |
+
|
458 |
+
1. **Automated Grievance Categorization**
|
459 |
+
- **Event Flow:**
|
460 |
+
- Upon grievance submission, text is processed by ML models.
|
461 |
+
- Category is automatically assigned.
|
462 |
+
- Grievance is routed based on the category.
|
463 |
+
|
464 |
+
2. **Sentiment Analysis for Prioritization**
|
465 |
+
- **Event Flow:**
|
466 |
+
- Grievance text is analyzed for sentiment.
|
467 |
+
- Negative sentiments trigger higher priority assignments.
|
468 |
+
- Dashboard highlights high-priority grievances.
|
469 |
+
|
470 |
+
3. **Predictive Resolution Time Estimation**
|
471 |
+
- **Event Flow:**
|
472 |
+
- System predicts resolution time based on historical data.
|
473 |
+
- Estimated time is displayed to the user and warden.
|
474 |
+
- Helps in managing expectations and resources.
|
475 |
+
|
476 |
+
4. **Anomaly Detection in Grievance Patterns**
|
477 |
+
- **Event Flow:**
|
478 |
+
- System continuously monitors grievance submissions.
|
479 |
+
- Detects unusual spikes or patterns.
|
480 |
+
- Alerts administrators to investigate potential systemic issues.
|
481 |
+
|
482 |
+
5. **Voice-to-Text Integration for Complaint Submission**
|
483 |
+
- **Event Flow:**
|
484 |
+
- User submits grievance via voice input.
|
485 |
+
- Voice data is transcribed to text using speech recognition.
|
486 |
+
- Transcribed text is processed for categorization and sentiment analysis.
|
487 |
+
|
488 |
+
6. **Proactive Grievance Prediction and Prevention**
|
489 |
+
- **Event Flow:**
|
490 |
+
- System analyzes trends to predict potential future grievances.
|
491 |
+
- Suggests preventive measures to administrators.
|
492 |
+
- Helps in mitigating issues before they escalate.
|
493 |
+
|
494 |
+
7. **Intelligent Routing and Workflow Automation**
|
495 |
+
- **Event Flow:**
|
496 |
+
- System assigns grievances to personnel based on AI-driven suggestions.
|
497 |
+
- Continuously learns and adapts routing based on outcomes.
|
498 |
+
- Ensures optimal workload distribution.
|
499 |
+
|
500 |
+
8. **Advanced Sentiment and Emotional Intelligence Analysis**
|
501 |
+
- **Event Flow:**
|
502 |
+
- Grievance submissions are analyzed for complex emotional states.
|
503 |
+
- Responses are tailored based on detected emotions.
|
504 |
+
- Enhances empathetic communication.
|
505 |
+
|
506 |
+
9. **Knowledge Graph Integration for Insight Generation**
|
507 |
+
- **Event Flow:**
|
508 |
+
- Grievances are integrated into a knowledge graph.
|
509 |
+
- Enables advanced querying and pattern detection.
|
510 |
+
- Provides actionable insights for improving the grievance resolution process.
|
511 |
+
|
512 |
+
---
|
513 |
+
|
514 |
+
## 3. Directory Structure and File Division
|
515 |
+
|
516 |
+
### Frontend Directory Structure
|
517 |
+
|
518 |
+
```markdown
|
519 |
+
````language:frontend
|
520 |
+
src/
|
521 |
+
├── assets/
|
522 |
+
│ ├── images/
|
523 |
+
│ │ └── *.png
|
524 |
+
│ └── styles/
|
525 |
+
│ └── tailwind.css
|
526 |
+
├── components/
|
527 |
+
│ ├── Authentication/
|
528 |
+
│ │ ├── LoginForm.js
|
529 |
+
│ │ └── SignupForm.js
|
530 |
+
│ ├── Common/
|
531 |
+
│ │ ├── NavigationBar.js
|
532 |
+
│ │ ├── Footer.js
|
533 |
+
│ │ └── NotificationSystem.js
|
534 |
+
│ ├── Dashboard/
|
535 |
+
│ │ ├── RecentGrievances.js
|
536 |
+
│ │ ├── StatisticsOverview.js
|
537 |
+
│ │ └── QuickSubmitButton.js
|
538 |
+
│ ├── Grievances/
|
539 |
+
│ │ ├── GrievanceForm.js
|
540 |
+
│ │ ├── GrievanceList.js
|
541 |
+
│ │ └── GrievanceDetails.js
|
542 |
+
│ ├── Profile/
|
543 |
+
│ │ ├── ProfileForm.js
|
544 |
+
│ │ └── ProfilePictureUpload.js
|
545 |
+
│ └── Chat/
|
546 |
+
│ └── Chatroom.js
|
547 |
+
├── pages/
|
548 |
+
│ ├── LoginPage.js
|
549 |
+
│ ├── SignupPage.js
|
550 |
+
│ ├── StudentDashboard.js
|
551 |
+
│ ├── StudentProfile.js
|
552 |
+
│ ├── SubmitGrievance.js
|
553 |
+
│ ├── ViewGrievances.js
|
554 |
+
│ ├── GrievanceDetails.js
|
555 |
+
│ ├── WardenDashboard.js
|
556 |
+
│ ├── ManageGrievances.js
|
557 |
+
│ ├── ResolveGrievance.js
|
558 |
+
│ └── PerformanceDashboard.js
|
559 |
+
├── services/
|
560 |
+
│ ├── api.js
|
561 |
+
│ ├── authService.js
|
562 |
+
│ ├── grievanceService.js
|
563 |
+
│ └── chatService.js
|
564 |
+
├── utils/
|
565 |
+
│ ├── validation.js
|
566 |
+
│ └── helpers.js
|
567 |
+
├── App.js
|
568 |
+
├── index.js
|
569 |
+
└── routes.js
|
570 |
+
```
|
571 |
+
|
572 |
+
|
573 |
+
### Backend Directory Structure
|
574 |
+
|
575 |
+
```markdown
|
576 |
+
````language:backend
|
577 |
+
src/
|
578 |
+
├── config/
|
579 |
+
│ ├── db.js
|
580 |
+
│ └── config.js
|
581 |
+
├── controllers/
|
582 |
+
│ ├── authController.js
|
583 |
+
│ ├── grievanceController.js
|
584 |
+
│ ├── userController.js
|
585 |
+
│ └── chatController.js
|
586 |
+
├── models/
|
587 |
+
│ ├── User.js
|
588 |
+
│ ├── Grievance.js
|
589 |
+
│ └── ChatMessage.js
|
590 |
+
├── routes/
|
591 |
+
│ ├── authRoutes.js
|
592 |
+
│ ├── grievanceRoutes.js
|
593 |
+
│ ├── userRoutes.js
|
594 |
+
│ └── chatRoutes.js
|
595 |
+
├── services/
|
596 |
+
│ ├── sentimentAnalysisService.js
|
597 |
+
│ ├── categorizationService.js
|
598 |
+
│ ├── routingService.js
|
599 |
+
│ └── knowledgeGraphService.js
|
600 |
+
├── middleware/
|
601 |
+
│ ├── authMiddleware.js
|
602 |
+
│ ├── errorHandler.js
|
603 |
+
│ └── validationMiddleware.js
|
604 |
+
├── utils/
|
605 |
+
│ ├── logger.js
|
606 |
+
│ └── helpers.js
|
607 |
+
├── app.js
|
608 |
+
└── server.js
|
609 |
+
```
|
610 |
+
|
611 |
+
|
612 |
+
### Explanation
|
613 |
+
|
614 |
+
- **Frontend (`src/frontend/`):**
|
615 |
+
- **assets/**: Static assets like images and styles.
|
616 |
+
- **components/**: Reusable React components categorized by functionality.
|
617 |
+
- **pages/**: Page-level components representing different routes.
|
618 |
+
- **services/**: API interaction logic.
|
619 |
+
- **utils/**: Utility functions and helpers.
|
620 |
+
- **App.js**: Root component.
|
621 |
+
- **index.js**: Entry point.
|
622 |
+
- **routes.js**: Application routing.
|
623 |
+
|
624 |
+
- **Backend (`src/backend/`):**
|
625 |
+
- **config/**: Configuration files for database and environment variables.
|
626 |
+
- **controllers/**: Business logic handling requests and responses.
|
627 |
+
- **models/**: Database models using ORM (e.g., Sequelize for PostgreSQL).
|
628 |
+
- **routes/**: API route definitions.
|
629 |
+
- **services/**: AI/ML and other service integrations.
|
630 |
+
- **middleware/**: Express middleware for authentication, error handling, etc.
|
631 |
+
- **utils/**: Utility functions and helpers.
|
632 |
+
- **app.js**: Express app setup.
|
633 |
+
- **server.js**: Server initialization.
|
634 |
+
|
635 |
+
---
|
636 |
+
|
637 |
+
## 4. Backend and Frontend Separation
|
638 |
+
|
639 |
+
### Frontend
|
640 |
+
|
641 |
+
- **Technology Stack:**
|
642 |
+
- **Framework**: React.js
|
643 |
+
- **Styling**: Tailwind CSS
|
644 |
+
- **State Management**: Redux or Context API
|
645 |
+
- **Real-time Communication**: Socket.io-client
|
646 |
+
|
647 |
+
- **Responsibilities:**
|
648 |
+
- User Interface and User Experience.
|
649 |
+
- Making API calls to the backend.
|
650 |
+
- Handling client-side routing.
|
651 |
+
- Managing user authentication state.
|
652 |
+
- Displaying real-time updates and notifications.
|
653 |
+
|
654 |
+
- **Key Components:**
|
655 |
+
- **Pages**: Represent different routes/views.
|
656 |
+
- **Components**: Reusable UI elements.
|
657 |
+
- **Services**: Handle API communications.
|
658 |
+
- **Utilities**: Helper functions and validation.
|
659 |
+
|
660 |
+
### Backend
|
661 |
+
|
662 |
+
- **Technology Stack:**
|
663 |
+
- **Runtime Environment**: Node.js
|
664 |
+
- **Framework**: Express.js
|
665 |
+
- **Database**: PostgreSQL
|
666 |
+
- **Real-time Communication**: Socket.io
|
667 |
+
- **AI/ML Integration**: Python scripts or external services
|
668 |
+
- **Authentication**: JWT (JSON Web Tokens)
|
669 |
+
|
670 |
+
- **Responsibilities:**
|
671 |
+
- API Endpoints for frontend communication.
|
672 |
+
- Business logic and data processing.
|
673 |
+
- Database interactions and ORM management.
|
674 |
+
- Authentication and authorization.
|
675 |
+
- AI/ML functionalities like sentiment analysis, categorization.
|
676 |
+
- Managing real-time chatrooms and notifications.
|
677 |
+
|
678 |
+
- **Key Components:**
|
679 |
+
- **Controllers**: Handle incoming requests, interact with services.
|
680 |
+
- **Models**: Define database schemas and ORM models.
|
681 |
+
- **Routes**: Define API endpoints.
|
682 |
+
- **Services**: Business logic and AI/ML integrations.
|
683 |
+
- **Middleware**: Authentication, validation, error handling.
|
684 |
+
|
685 |
+
### Communication Between Frontend and Backend
|
686 |
+
|
687 |
+
- **RESTful APIs**: For standard CRUD operations and data retrieval.
|
688 |
+
- **WebSockets (Socket.io)**: For real-time features like chatrooms and live notifications.
|
689 |
+
- **Authentication**: JWT tokens stored in HTTP-only cookies or local storage for secure communication.
|
690 |
+
|
691 |
+
---
|
692 |
+
|
693 |
+
## 5. Performance Dashboard for Students
|
694 |
+
|
695 |
+
### Overview
|
696 |
+
|
697 |
+
The Performance Dashboard provides insights into the performance of different students regarding their grievance handling. This feature is accessible to administrators to monitor and improve the efficiency of the grievance redressal process.
|
698 |
+
|
699 |
+
### Components
|
700 |
+
|
701 |
+
1. **Dashboard Overview**
|
702 |
+
- **Total Grievances Handled**: Number of grievances each student has submitted and their current status.
|
703 |
+
- **Average Resolution Time**: Time taken to resolve grievances per student.
|
704 |
+
- **Success Rate**: Percentage of grievances successfully resolved.
|
705 |
+
|
706 |
+
2. **Graphs and Charts**
|
707 |
+
- **Bar Chart**: Number of grievances submitted by each student.
|
708 |
+
- **Line Chart**: Resolution time trends over a period.
|
709 |
+
- **Pie Chart**: Distribution of grievance statuses (Resolved, Pending, In Progress).
|
710 |
+
|
711 |
+
3. **Filters and Search**
|
712 |
+
- **Date Range Picker**: Filter data based on specific time frames.
|
713 |
+
- **Student Selector**: Choose specific students to view detailed performance.
|
714 |
+
- **Grievance Category Filter**: Analyze performance across different categories.
|
715 |
+
|
716 |
+
4. **Detailed Tables**
|
717 |
+
- **Grievance List**: Detailed list of grievances with columns for Student Name, Grievance Title, Status, Submission Date, Resolution Date.
|
718 |
+
- **Export Options**: Export data in CSV or PDF formats for reporting.
|
719 |
+
|
720 |
+
### Functionality
|
721 |
+
|
722 |
+
- **Data Aggregation**: Fetch data from the backend to display aggregated statistics.
|
723 |
+
- **Real-time Updates**: Reflect real-time changes in grievance statuses.
|
724 |
+
- **Responsive Design**: Ensure the dashboard is accessible on various devices.
|
725 |
+
- **User Interactions**: Allow administrators to interact with charts and tables for deeper insights.
|
726 |
+
|
727 |
+
### Implementation
|
728 |
+
|
729 |
+
```markdown
|
730 |
+
react:src/frontend/pages/PerformanceDashboard.js
|
731 |
+
function PerformanceDashboard() {
|
732 |
+
const [data, setData] = useState({});
|
733 |
+
const [filters, setFilters] = useState({
|
734 |
+
dateRange: { start: null, end: null },
|
735 |
+
student: '',
|
736 |
+
category: ''
|
737 |
+
});
|
738 |
+
|
739 |
+
useEffect(() => {
|
740 |
+
// Fetch dashboard data based on filters
|
741 |
+
fetchDashboardData(filters).then(response => setData(response));
|
742 |
+
}, [filters]);
|
743 |
+
|
744 |
+
return (
|
745 |
+
<div className="performance-dashboard-container">
|
746 |
+
<Sidebar />
|
747 |
+
<div className="dashboard-content">
|
748 |
+
<FiltersComponent filters={filters} setFilters={setFilters} />
|
749 |
+
<Graphs />
|
750 |
+
<DetailedTables data={data} />
|
751 |
+
</div>
|
752 |
+
</div>
|
753 |
+
);
|
754 |
+
}
|
755 |
+
```
|
756 |
+
|
757 |
+
|
758 |
+
```markdown
|
759 |
+
javascript:src/frontend/services/dashboardService.js:fetchDashboardData
|
760 |
+
async function fetchDashboardData(filters) {
|
761 |
+
try {
|
762 |
+
const response = await axios.get('/api/dashboard', { params: filters });
|
763 |
+
return response.data;
|
764 |
+
} catch (error) {
|
765 |
+
console.error('Error fetching dashboard data:', error);
|
766 |
+
throw error;
|
767 |
+
}
|
768 |
+
}
|
769 |
+
```
|
770 |
+
|
771 |
+
|
772 |
+
```markdown
|
773 |
+
````javascript:src/backend/controllers/dashboardController.js:getDashboardData
|
774 |
+
async function getDashboardData(req, res) {
|
775 |
+
const { dateRange, student, category } = req.query;
|
776 |
+
try {
|
777 |
+
const data = await DashboardService.aggregatePerformanceData({ dateRange, student, category });
|
778 |
+
res.status(200).json(data);
|
779 |
+
} catch (error) {
|
780 |
+
res.status(500).json({ message: 'Failed to fetch dashboard data.' });
|
781 |
+
}
|
782 |
+
}
|
783 |
+
```
|
784 |
+
|
785 |
+
|
786 |
+
```markdown
|
787 |
+
javascript:src/backend/services/dashboardService.js:aggregatePerformanceData
|
788 |
+
async function aggregatePerformanceData(filters) {
|
789 |
+
const { dateRange, student, category } = filters;
|
790 |
+
// Build query based on filters
|
791 |
+
let query = { /* ... */ };
|
792 |
+
|
793 |
+
const grievances = await Grievance.findAll({ where: query });
|
794 |
+
|
795 |
+
// Aggregate data
|
796 |
+
const totalHandled = /* logic to calculate */;
|
797 |
+
const avgResolutionTime = /* logic to calculate */;
|
798 |
+
const successRate = /* logic to calculate */;
|
799 |
+
const perStudent = /* logic to calculate */;
|
800 |
+
|
801 |
+
return {
|
802 |
+
totalHandled,
|
803 |
+
avgResolutionTime,
|
804 |
+
successRate,
|
805 |
+
perStudent,
|
806 |
+
// Additional aggregated data
|
807 |
+
};
|
808 |
+
}
|
809 |
+
```
|
810 |
+
|
811 |
+
|
812 |
+
### Backend API Endpoint
|
813 |
+
|
814 |
+
```markdown
|
815 |
+
````language:backend
|
816 |
+
// src/backend/routes/dashboardRoutes.js
|
817 |
+
|
818 |
+
const express = require('express');
|
819 |
+
const router = express.Router();
|
820 |
+
const dashboardController = require('../controllers/dashboardController');
|
821 |
+
const authMiddleware = require('../middleware/authMiddleware');
|
822 |
+
|
823 |
+
router.get('/dashboard', authMiddleware.verifyAdmin, dashboardController.getDashboardData);
|
824 |
+
|
825 |
+
module.exports = router;
|
826 |
+
```
|
827 |
+
|
828 |
+
|
829 |
+
### Frontend API Integration
|
830 |
+
|
831 |
+
```markdown
|
832 |
+
````language:frontend
|
833 |
+
// src/frontend/services/dashboardService.js
|
834 |
+
|
835 |
+
import axios from 'axios';
|
836 |
+
|
837 |
+
export async function fetchDashboardData(filters) {
|
838 |
+
try {
|
839 |
+
const response = await axios.get('/api/dashboard', { params: filters });
|
840 |
+
return response.data;
|
841 |
+
} catch (error) {
|
842 |
+
console.error('Error fetching dashboard data:', error);
|
843 |
+
throw error;
|
844 |
+
}
|
845 |
+
}
|
846 |
+
```
|
847 |
+
|
848 |
+
|
849 |
+
### UI Implementation
|
850 |
+
|
851 |
+
- **Graphs and Charts**: Utilize charting libraries like **Chart.js** or **Recharts** to create interactive and responsive charts.
|
852 |
+
- **Filters Component**: Allows administrators to apply various filters to the data.
|
853 |
+
- **Detailed Tables**: Implement sortable and searchable tables using libraries like **React Table**.
|
854 |
+
|
855 |
+
### Security Considerations
|
856 |
+
|
857 |
+
- **Authentication and Authorization**: Ensure that only authorized administrators can access the Performance Dashboard.
|
858 |
+
- **Data Protection**: Secure sensitive performance data and ensure compliance with data protection regulations.
|
859 |
+
|
860 |
+
---
|
861 |
+
|
862 |
+
# Conclusion
|
863 |
+
|
864 |
+
This comprehensive project plan outlines the detailed structure and workflow for the Hostel Grievance Redressal System. By following this plan, the development team can ensure a well-organized, efficient, and feature-rich application that effectively addresses the grievances of hostel residents. The integration of AI/ML functionalities will further enhance the system's capability to manage and resolve issues promptly and intelligently.
|
models/intelligent_routing/generate_data.py
ADDED
@@ -0,0 +1,118 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
import random
|
2 |
+
import json
|
3 |
+
from datetime import datetime, timedelta
|
4 |
+
import logging
|
5 |
+
import os
|
6 |
+
|
7 |
+
logging.basicConfig(level=logging.INFO)
|
8 |
+
logger = logging.getLogger(__name__)
|
9 |
+
|
10 |
+
class IntelligentRoutingDataGenerator:
|
11 |
+
def __init__(self):
|
12 |
+
self.categories = ['electricity', 'internet', 'plumber', 'water_cooler', 'sweeper', 'carpenter']
|
13 |
+
self.availability_statuses = ['Available', 'Unavailable']
|
14 |
+
self.hostel_names = ['bh1', 'bh2', 'bh3', 'ivh', 'gh']
|
15 |
+
self.floor_numbers = [0, 1, 2, 3]
|
16 |
+
self.time_slots = [
|
17 |
+
"08:00-12:00", "12:00-16:00", "16:00-20:00"
|
18 |
+
]
|
19 |
+
|
20 |
+
def generate_staff_members(self, category):
|
21 |
+
"""Generate 2 staff members for a specific category"""
|
22 |
+
return [
|
23 |
+
{
|
24 |
+
"staff_id": f"S{random.randint(10000, 99999)}",
|
25 |
+
"department": category, # Ensure staff department matches grievance category
|
26 |
+
"current_workload": random.randint(0, 5),
|
27 |
+
"availability_status": random.choice(self.availability_statuses),
|
28 |
+
"past_resolution_rate": round(random.uniform(0.85, 0.99), 2)
|
29 |
+
}
|
30 |
+
for _ in range(2)
|
31 |
+
]
|
32 |
+
|
33 |
+
def generate_availability_data(self, staff_id, student_id):
|
34 |
+
return {
|
35 |
+
"staff_availability": [
|
36 |
+
{
|
37 |
+
"staff_id": staff_id,
|
38 |
+
"time_slot": random.choice(self.time_slots),
|
39 |
+
"availability_status": random.choice(self.availability_statuses)
|
40 |
+
}
|
41 |
+
],
|
42 |
+
"student_availability": [
|
43 |
+
{
|
44 |
+
"student_id": student_id,
|
45 |
+
"time_slot": random.choice(self.time_slots),
|
46 |
+
"availability_status": random.choice(self.availability_statuses)
|
47 |
+
}
|
48 |
+
]
|
49 |
+
}
|
50 |
+
|
51 |
+
def generate_sample(self, index):
|
52 |
+
grievance_id = f"G{67890 + index}"
|
53 |
+
student_id = f"STU{200 + index}"
|
54 |
+
|
55 |
+
# First select category, then generate matching staff
|
56 |
+
selected_category = random.choice(self.categories)
|
57 |
+
staff_members = self.generate_staff_members(selected_category)
|
58 |
+
|
59 |
+
# Generate base timestamp
|
60 |
+
base_time = datetime.utcnow()
|
61 |
+
submission_time = base_time - timedelta(minutes=random.randint(0, 60))
|
62 |
+
|
63 |
+
# Generate sample data
|
64 |
+
sample = {
|
65 |
+
"grievance_id": grievance_id,
|
66 |
+
"category": selected_category,
|
67 |
+
"submission_timestamp": submission_time.strftime("%Y-%m-%dT%H:%M:%SZ"),
|
68 |
+
"student_room_no": str(random.randint(100, 499)),
|
69 |
+
"hostel_name": random.choice(self.hostel_names),
|
70 |
+
"floor_number": random.choice(self.floor_numbers),
|
71 |
+
"current_staff_status": staff_members,
|
72 |
+
"floor_metrics": {
|
73 |
+
"number_of_requests": random.randint(0, 30),
|
74 |
+
"total_delays": random.randint(0, 5)
|
75 |
+
},
|
76 |
+
"availability_data": self.generate_availability_data(
|
77 |
+
staff_members[0]["staff_id"],
|
78 |
+
student_id
|
79 |
+
)
|
80 |
+
}
|
81 |
+
|
82 |
+
return sample
|
83 |
+
|
84 |
+
def generate_dataset(self, num_samples, output_path):
|
85 |
+
dataset = []
|
86 |
+
for i in range(num_samples):
|
87 |
+
sample = self.generate_sample(i)
|
88 |
+
dataset.append(sample)
|
89 |
+
|
90 |
+
# Create directory if it doesn't exist
|
91 |
+
os.makedirs(os.path.dirname(output_path), exist_ok=True)
|
92 |
+
|
93 |
+
# Save to JSON file
|
94 |
+
with open(output_path, 'w') as f:
|
95 |
+
json.dump(dataset, f, indent=2)
|
96 |
+
|
97 |
+
logger.info(f"Generated {len(dataset)} samples and saved to {output_path}")
|
98 |
+
return dataset
|
99 |
+
|
100 |
+
def main():
|
101 |
+
generator = IntelligentRoutingDataGenerator()
|
102 |
+
|
103 |
+
# Generate training data
|
104 |
+
train_samples = generator.generate_dataset(
|
105 |
+
40000,
|
106 |
+
'models/intelligent_routing/train_data/training_data.json'
|
107 |
+
)
|
108 |
+
|
109 |
+
# Generate test data
|
110 |
+
test_samples = generator.generate_dataset(
|
111 |
+
8000,
|
112 |
+
'models/intelligent_routing/test_data/test_data.json'
|
113 |
+
)
|
114 |
+
|
115 |
+
print(f"Generated {len(train_samples)} training samples and {len(test_samples)} test samples")
|
116 |
+
|
117 |
+
if __name__ == "__main__":
|
118 |
+
main()
|
models/intelligent_routing/model.py
ADDED
@@ -0,0 +1,253 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
import tensorflow as tf
|
2 |
+
import numpy as np
|
3 |
+
from datetime import datetime
|
4 |
+
import json
|
5 |
+
import logging
|
6 |
+
|
7 |
+
# Configure logging
|
8 |
+
logging.basicConfig(level=logging.INFO, format='%(asctime)s - %(levelname)s - %(message)s')
|
9 |
+
|
10 |
+
class IntelligentRoutingModel:
|
11 |
+
def __init__(self):
|
12 |
+
self.model = None
|
13 |
+
self.feature_columns = [
|
14 |
+
'category_encoded',
|
15 |
+
'floor_number',
|
16 |
+
'current_workload',
|
17 |
+
'past_resolution_rate',
|
18 |
+
'number_of_requests',
|
19 |
+
'total_delays'
|
20 |
+
]
|
21 |
+
|
22 |
+
# Category encoding
|
23 |
+
self.categories = ['electricity', 'internet', 'plumber', 'water_cooler', 'sweeper', 'carpenter']
|
24 |
+
self.category_encoding = {cat: i for i, cat in enumerate(self.categories)}
|
25 |
+
logging.info(f"Initialized IntelligentRoutingModel with {len(self.categories)} categories")
|
26 |
+
|
27 |
+
def preprocess_data(self, data):
|
28 |
+
"""Enhanced data preprocessing"""
|
29 |
+
features = []
|
30 |
+
labels = []
|
31 |
+
|
32 |
+
for sample in data:
|
33 |
+
# Encode category
|
34 |
+
category_encoded = [0] * len(self.categories)
|
35 |
+
category_idx = self.category_encoding[sample['category']]
|
36 |
+
category_encoded[category_idx] = 1
|
37 |
+
|
38 |
+
# Process each staff member
|
39 |
+
for staff in sample['current_staff_status']:
|
40 |
+
if staff['department'] == sample['category']:
|
41 |
+
# Normalize numerical features
|
42 |
+
normalized_workload = staff['current_workload'] / 5.0
|
43 |
+
|
44 |
+
# Calculate time-based features
|
45 |
+
submission_time = datetime.strptime(sample['submission_timestamp'], "%Y-%m-%dT%H:%M:%SZ")
|
46 |
+
hour_of_day = submission_time.hour / 24.0
|
47 |
+
|
48 |
+
# Calculate distance (simplified)
|
49 |
+
distance = abs(int(staff.get('current_floor', 0)) -
|
50 |
+
int(sample['floor_number'])) / 4.0
|
51 |
+
|
52 |
+
# Create enhanced feature vector
|
53 |
+
feature = np.array([
|
54 |
+
*category_encoded,
|
55 |
+
sample['floor_number'] / 4.0, # Normalized floor number
|
56 |
+
normalized_workload,
|
57 |
+
staff['past_resolution_rate'],
|
58 |
+
sample['floor_metrics']['number_of_requests'] / 30.0,
|
59 |
+
sample['floor_metrics']['total_delays'] / 5.0,
|
60 |
+
hour_of_day,
|
61 |
+
1.0 if staff['availability_status'] == 'Available' else 0.0,
|
62 |
+
distance # Normalized distance
|
63 |
+
])
|
64 |
+
|
65 |
+
features.append(feature)
|
66 |
+
|
67 |
+
# Enhanced label creation
|
68 |
+
is_good_match = (
|
69 |
+
staff['availability_status'] == 'Available' and
|
70 |
+
staff['current_workload'] < 4 and
|
71 |
+
staff['past_resolution_rate'] > 0.85 and
|
72 |
+
distance < 0.5 # Prefer closer staff
|
73 |
+
)
|
74 |
+
labels.append(1 if is_good_match else 0)
|
75 |
+
|
76 |
+
if not features:
|
77 |
+
raise ValueError("No valid features found in the dataset")
|
78 |
+
|
79 |
+
# Convert to numpy arrays
|
80 |
+
features = np.array(features)
|
81 |
+
labels = np.array(labels)
|
82 |
+
|
83 |
+
# Log shapes for debugging
|
84 |
+
logging.info(f"Preprocessed data shapes - Features: {features.shape}, Labels: {labels.shape}")
|
85 |
+
|
86 |
+
return features, labels
|
87 |
+
|
88 |
+
def build_model(self):
|
89 |
+
"""Build an improved neural network model"""
|
90 |
+
# Calculate input dimension based on features
|
91 |
+
input_dim = (
|
92 |
+
len(self.categories) + # One-hot encoded categories
|
93 |
+
8 # Additional features: floor_number, workload, resolution_rate,
|
94 |
+
# requests, delays, hour_of_day, availability, distance
|
95 |
+
)
|
96 |
+
|
97 |
+
logging.info(f"Building model with input dimension: {input_dim}")
|
98 |
+
|
99 |
+
model = tf.keras.Sequential([
|
100 |
+
# Input layer with regularization
|
101 |
+
tf.keras.layers.Dense(128, activation='relu', input_shape=(input_dim,),
|
102 |
+
kernel_regularizer=tf.keras.regularizers.l2(0.01)),
|
103 |
+
tf.keras.layers.BatchNormalization(),
|
104 |
+
tf.keras.layers.Dropout(0.3),
|
105 |
+
|
106 |
+
# Hidden layers with skip connections
|
107 |
+
tf.keras.layers.Dense(64, activation='relu',
|
108 |
+
kernel_regularizer=tf.keras.regularizers.l2(0.01)),
|
109 |
+
tf.keras.layers.BatchNormalization(),
|
110 |
+
tf.keras.layers.Dropout(0.2),
|
111 |
+
|
112 |
+
tf.keras.layers.Dense(32, activation='relu',
|
113 |
+
kernel_regularizer=tf.keras.regularizers.l2(0.01)),
|
114 |
+
tf.keras.layers.BatchNormalization(),
|
115 |
+
tf.keras.layers.Dropout(0.2),
|
116 |
+
|
117 |
+
# Output layer
|
118 |
+
tf.keras.layers.Dense(1, activation='sigmoid')
|
119 |
+
])
|
120 |
+
|
121 |
+
# Use a more sophisticated optimizer with learning rate scheduling
|
122 |
+
initial_learning_rate = 0.001
|
123 |
+
lr_schedule = tf.keras.optimizers.schedules.ExponentialDecay(
|
124 |
+
initial_learning_rate,
|
125 |
+
decay_steps=1000,
|
126 |
+
decay_rate=0.9,
|
127 |
+
staircase=True)
|
128 |
+
|
129 |
+
optimizer = tf.keras.optimizers.Adam(learning_rate=lr_schedule)
|
130 |
+
|
131 |
+
model.compile(
|
132 |
+
optimizer=optimizer,
|
133 |
+
loss='binary_crossentropy',
|
134 |
+
metrics=['accuracy',
|
135 |
+
tf.keras.metrics.Precision(),
|
136 |
+
tf.keras.metrics.Recall(),
|
137 |
+
tf.keras.metrics.AUC()]
|
138 |
+
)
|
139 |
+
|
140 |
+
# Print model summary
|
141 |
+
model.summary()
|
142 |
+
|
143 |
+
self.model = model
|
144 |
+
return model
|
145 |
+
|
146 |
+
def train(self, train_data_path, epochs=20, batch_size=32):
|
147 |
+
"""Enhanced training process"""
|
148 |
+
logging.info(f"Starting model training with {epochs} epochs")
|
149 |
+
|
150 |
+
# Load and preprocess data
|
151 |
+
with open(train_data_path) as f:
|
152 |
+
train_data = json.load(f)
|
153 |
+
|
154 |
+
X, y = self.preprocess_data(train_data)
|
155 |
+
|
156 |
+
# Create validation split
|
157 |
+
from sklearn.model_selection import train_test_split
|
158 |
+
X_train, X_val, y_train, y_val = train_test_split(
|
159 |
+
X, y, test_size=0.2, random_state=42, stratify=y
|
160 |
+
)
|
161 |
+
|
162 |
+
# Handle class imbalance
|
163 |
+
from sklearn.utils.class_weight import compute_class_weight
|
164 |
+
class_weights = compute_class_weight(
|
165 |
+
'balanced',
|
166 |
+
classes=np.unique(y_train),
|
167 |
+
y=y_train
|
168 |
+
)
|
169 |
+
class_weight_dict = {i: weight for i, weight in enumerate(class_weights)}
|
170 |
+
|
171 |
+
# Build model
|
172 |
+
self.build_model()
|
173 |
+
|
174 |
+
# Add callbacks
|
175 |
+
callbacks = [
|
176 |
+
tf.keras.callbacks.EarlyStopping(
|
177 |
+
monitor='val_loss',
|
178 |
+
patience=5,
|
179 |
+
restore_best_weights=True
|
180 |
+
),
|
181 |
+
tf.keras.callbacks.ReduceLROnPlateau(
|
182 |
+
monitor='val_loss',
|
183 |
+
factor=0.5,
|
184 |
+
patience=3,
|
185 |
+
min_lr=0.00001
|
186 |
+
)
|
187 |
+
]
|
188 |
+
|
189 |
+
# Train model
|
190 |
+
history = self.model.fit(
|
191 |
+
X_train, y_train,
|
192 |
+
epochs=epochs,
|
193 |
+
batch_size=batch_size,
|
194 |
+
validation_data=(X_val, y_val),
|
195 |
+
class_weight=class_weight_dict,
|
196 |
+
callbacks=callbacks,
|
197 |
+
verbose=1
|
198 |
+
)
|
199 |
+
|
200 |
+
return history
|
201 |
+
|
202 |
+
def predict(self, input_data):
|
203 |
+
"""Make predictions for input data"""
|
204 |
+
logging.info(f"Making prediction for grievance {input_data['grievance_id']}")
|
205 |
+
# Preprocess input
|
206 |
+
X = self.preprocess_data([input_data])
|
207 |
+
|
208 |
+
# Make prediction
|
209 |
+
prediction = self.model.predict(X)[0][0]
|
210 |
+
logging.info(f"Raw prediction: {prediction}")
|
211 |
+
|
212 |
+
# Find best matching staff
|
213 |
+
best_staff = None
|
214 |
+
highest_score = -1
|
215 |
+
|
216 |
+
for staff in input_data['current_staff_status']:
|
217 |
+
if staff['department'] == input_data['category']:
|
218 |
+
score = prediction * staff['past_resolution_rate'] * (1 / (staff['current_workload'] + 1))
|
219 |
+
logging.debug(f"Staff {staff['staff_id']} score: {score}")
|
220 |
+
if score > highest_score:
|
221 |
+
highest_score = score
|
222 |
+
best_staff = staff
|
223 |
+
|
224 |
+
if not best_staff:
|
225 |
+
logging.warning("No suitable staff found for the grievance")
|
226 |
+
return None
|
227 |
+
|
228 |
+
# Generate response
|
229 |
+
assignment_time = datetime.utcnow()
|
230 |
+
|
231 |
+
response = {
|
232 |
+
"grievance_id": input_data['grievance_id'],
|
233 |
+
"assigned_staff_id": best_staff['staff_id'],
|
234 |
+
"assignment_timestamp": assignment_time.strftime("%Y-%m-%dT%H:%M:%SZ"),
|
235 |
+
"expected_resolution_time": "1 hour",
|
236 |
+
"floor_number": input_data['floor_number'],
|
237 |
+
"hostel_name": input_data['hostel_name'],
|
238 |
+
"student_room_no": input_data['student_room_no']
|
239 |
+
}
|
240 |
+
logging.info(f"Generated response: {response}")
|
241 |
+
return response
|
242 |
+
|
243 |
+
def save_model(self, path):
|
244 |
+
"""Save the trained model"""
|
245 |
+
logging.info(f"Saving model to {path}")
|
246 |
+
self.model.save(path)
|
247 |
+
logging.info("Model saved successfully")
|
248 |
+
|
249 |
+
def load_model(self, path):
|
250 |
+
"""Load a trained model"""
|
251 |
+
logging.info(f"Loading model from {path}")
|
252 |
+
self.model = tf.keras.models.load_model(path)
|
253 |
+
logging.info("Model loaded successfully")
|
models/intelligent_routing/saved_model/model.keras
ADDED
@@ -0,0 +1,3 @@
|
|
|
|
|
|
|
|
|
1 |
+
version https://git-lfs.github.com/spec/v1
|
2 |
+
oid sha256:21096f35bb4c5aabc441e3e4d4d4804566ccd08c96ff922de0dfc444c1476941
|
3 |
+
size 210119
|
models/intelligent_routing/test_data/__init__.py
ADDED
File without changes
|
models/intelligent_routing/test_data/test_data.json
ADDED
The diff for this file is too large to render.
See raw diff
|
|
models/intelligent_routing/test_model.py
ADDED
@@ -0,0 +1,259 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
import json
|
2 |
+
import logging
|
3 |
+
import numpy as np
|
4 |
+
from sklearn.metrics import accuracy_score, precision_score, recall_score, f1_score, confusion_matrix
|
5 |
+
from model import IntelligentRoutingModel
|
6 |
+
import matplotlib.pyplot as plt
|
7 |
+
import seaborn as sns
|
8 |
+
from datetime import datetime
|
9 |
+
import os
|
10 |
+
|
11 |
+
logging.basicConfig(
|
12 |
+
level=logging.INFO,
|
13 |
+
format='%(asctime)s - %(levelname)s - %(message)s',
|
14 |
+
handlers=[
|
15 |
+
logging.FileHandler('testing.log'),
|
16 |
+
logging.StreamHandler()
|
17 |
+
]
|
18 |
+
)
|
19 |
+
|
20 |
+
logger = logging.getLogger(__name__)
|
21 |
+
|
22 |
+
class IntelligentRoutingTester:
|
23 |
+
def __init__(self, model_path, test_data_path):
|
24 |
+
self.model = IntelligentRoutingModel()
|
25 |
+
self.model.load_model(model_path)
|
26 |
+
self.test_data_path = test_data_path
|
27 |
+
|
28 |
+
# Create results directory
|
29 |
+
self.results_dir = 'models/intelligent_routing/test_results'
|
30 |
+
os.makedirs(self.results_dir, exist_ok=True)
|
31 |
+
|
32 |
+
def load_test_data(self):
|
33 |
+
"""Load test data from JSON file"""
|
34 |
+
try:
|
35 |
+
logger.info(f"Loading test data from {self.test_data_path}")
|
36 |
+
with open(self.test_data_path, 'r') as f:
|
37 |
+
data = json.load(f)
|
38 |
+
logger.info(f"Successfully loaded {len(data)} test samples")
|
39 |
+
return data
|
40 |
+
except Exception as e:
|
41 |
+
logger.error(f"Error loading test data: {str(e)}")
|
42 |
+
raise
|
43 |
+
|
44 |
+
def generate_test_cases(self):
|
45 |
+
"""Generate specific test cases to evaluate model robustness"""
|
46 |
+
test_cases = []
|
47 |
+
|
48 |
+
# Test case 1: Ideal scenario
|
49 |
+
test_cases.append({
|
50 |
+
"grievance_id": "G_TEST_1",
|
51 |
+
"category": "electricity",
|
52 |
+
"submission_timestamp": datetime.utcnow().strftime("%Y-%m-%dT%H:%M:%SZ"),
|
53 |
+
"floor_number": 1,
|
54 |
+
"hostel_name": "bh1",
|
55 |
+
"student_room_no": "101",
|
56 |
+
"current_staff_status": [
|
57 |
+
{
|
58 |
+
"staff_id": "S_TEST_1",
|
59 |
+
"department": "electricity",
|
60 |
+
"current_workload": 1,
|
61 |
+
"availability_status": "Available",
|
62 |
+
"past_resolution_rate": 0.95,
|
63 |
+
"current_floor": 1
|
64 |
+
}
|
65 |
+
],
|
66 |
+
"floor_metrics": {
|
67 |
+
"number_of_requests": 5,
|
68 |
+
"total_delays": 1
|
69 |
+
}
|
70 |
+
})
|
71 |
+
|
72 |
+
# Test case 2: High workload scenario
|
73 |
+
test_cases.append({
|
74 |
+
"grievance_id": "G_TEST_2",
|
75 |
+
"category": "plumber",
|
76 |
+
"submission_timestamp": datetime.utcnow().strftime("%Y-%m-%dT%H:%M:%SZ"),
|
77 |
+
"floor_number": 2,
|
78 |
+
"hostel_name": "bh2",
|
79 |
+
"student_room_no": "201",
|
80 |
+
"current_staff_status": [
|
81 |
+
{
|
82 |
+
"staff_id": "S_TEST_2",
|
83 |
+
"department": "plumber",
|
84 |
+
"current_workload": 4,
|
85 |
+
"availability_status": "Available",
|
86 |
+
"past_resolution_rate": 0.90,
|
87 |
+
"current_floor": 1
|
88 |
+
}
|
89 |
+
],
|
90 |
+
"floor_metrics": {
|
91 |
+
"number_of_requests": 15,
|
92 |
+
"total_delays": 3
|
93 |
+
}
|
94 |
+
})
|
95 |
+
|
96 |
+
# Test case 3: Multiple staff scenario
|
97 |
+
test_cases.append({
|
98 |
+
"grievance_id": "G_TEST_3",
|
99 |
+
"category": "carpenter",
|
100 |
+
"submission_timestamp": datetime.utcnow().strftime("%Y-%m-%dT%H:%M:%SZ"),
|
101 |
+
"floor_number": 3,
|
102 |
+
"hostel_name": "bh3",
|
103 |
+
"student_room_no": "301",
|
104 |
+
"current_staff_status": [
|
105 |
+
{
|
106 |
+
"staff_id": "S_TEST_3A",
|
107 |
+
"department": "carpenter",
|
108 |
+
"current_workload": 2,
|
109 |
+
"availability_status": "Available",
|
110 |
+
"past_resolution_rate": 0.88,
|
111 |
+
"current_floor": 3
|
112 |
+
},
|
113 |
+
{
|
114 |
+
"staff_id": "S_TEST_3B",
|
115 |
+
"department": "carpenter",
|
116 |
+
"current_workload": 1,
|
117 |
+
"availability_status": "Available",
|
118 |
+
"past_resolution_rate": 0.92,
|
119 |
+
"current_floor": 2
|
120 |
+
}
|
121 |
+
],
|
122 |
+
"floor_metrics": {
|
123 |
+
"number_of_requests": 8,
|
124 |
+
"total_delays": 2
|
125 |
+
}
|
126 |
+
})
|
127 |
+
|
128 |
+
return test_cases
|
129 |
+
|
130 |
+
def evaluate_model(self):
|
131 |
+
"""Evaluate model performance on test data"""
|
132 |
+
logger.info("Starting model evaluation")
|
133 |
+
|
134 |
+
# Load test data
|
135 |
+
test_data = self.load_test_data()
|
136 |
+
X_test, y_test = self.model.preprocess_data(test_data)
|
137 |
+
|
138 |
+
# Get predictions
|
139 |
+
logger.info("Making predictions on test data")
|
140 |
+
y_pred = self.model.model.predict(X_test)
|
141 |
+
y_pred_binary = (y_pred > 0.5).astype(int)
|
142 |
+
|
143 |
+
# Calculate metrics
|
144 |
+
metrics = {
|
145 |
+
'accuracy': accuracy_score(y_test, y_pred_binary),
|
146 |
+
'precision': precision_score(y_test, y_pred_binary),
|
147 |
+
'recall': recall_score(y_test, y_pred_binary),
|
148 |
+
'f1': f1_score(y_test, y_pred_binary)
|
149 |
+
}
|
150 |
+
|
151 |
+
# Generate confusion matrix
|
152 |
+
cm = confusion_matrix(y_test, y_pred_binary)
|
153 |
+
|
154 |
+
# Plot confusion matrix
|
155 |
+
self.plot_confusion_matrix(cm)
|
156 |
+
|
157 |
+
logger.info(f"Evaluation metrics: {metrics}")
|
158 |
+
return metrics, cm, y_test, y_pred
|
159 |
+
|
160 |
+
def plot_confusion_matrix(self, cm):
|
161 |
+
"""Plot and save confusion matrix"""
|
162 |
+
plt.figure(figsize=(8, 6))
|
163 |
+
sns.heatmap(cm, annot=True, fmt='d', cmap='Blues')
|
164 |
+
plt.title('Confusion Matrix')
|
165 |
+
plt.ylabel('True Label')
|
166 |
+
plt.xlabel('Predicted Label')
|
167 |
+
plt.savefig(f'{self.results_dir}/confusion_matrix.png')
|
168 |
+
plt.close()
|
169 |
+
|
170 |
+
def test_specific_cases(self):
|
171 |
+
"""Test model on specific test cases"""
|
172 |
+
test_cases = self.generate_test_cases()
|
173 |
+
results = []
|
174 |
+
|
175 |
+
for case in test_cases:
|
176 |
+
prediction = self.model.predict(case)
|
177 |
+
results.append({
|
178 |
+
'case': case['grievance_id'],
|
179 |
+
'prediction': prediction,
|
180 |
+
'analysis': self.analyze_prediction(case, prediction)
|
181 |
+
})
|
182 |
+
|
183 |
+
return results
|
184 |
+
|
185 |
+
def analyze_prediction(self, case, prediction):
|
186 |
+
"""Analyze the prediction for a specific case"""
|
187 |
+
if not prediction:
|
188 |
+
return "No suitable staff found"
|
189 |
+
|
190 |
+
analysis = {
|
191 |
+
'assigned_staff': prediction['assigned_staff_id'],
|
192 |
+
'response_time': (
|
193 |
+
datetime.strptime(prediction['assignment_timestamp'], "%Y-%m-%dT%H:%M:%SZ") -
|
194 |
+
datetime.strptime(case['submission_timestamp'], "%Y-%m-%dT%H:%M:%SZ")
|
195 |
+
).total_seconds(),
|
196 |
+
'same_floor_assignment':
|
197 |
+
any(staff['current_floor'] == case['floor_number']
|
198 |
+
for staff in case['current_staff_status']
|
199 |
+
if staff['staff_id'] == prediction['assigned_staff_id'])
|
200 |
+
}
|
201 |
+
|
202 |
+
return analysis
|
203 |
+
|
204 |
+
def run_full_test(self):
|
205 |
+
"""Run complete test suite and generate report"""
|
206 |
+
logger.info("Starting full model testing")
|
207 |
+
|
208 |
+
# Evaluate model
|
209 |
+
metrics, cm, y_test, y_pred = self.evaluate_model()
|
210 |
+
|
211 |
+
# Test specific cases
|
212 |
+
specific_case_results = self.test_specific_cases()
|
213 |
+
|
214 |
+
# Generate test report
|
215 |
+
report = {
|
216 |
+
'metrics': metrics,
|
217 |
+
'specific_case_results': specific_case_results,
|
218 |
+
'test_timestamp': datetime.utcnow().strftime("%Y-%m-%dT%H:%M:%SZ"),
|
219 |
+
'detailed_analysis': {
|
220 |
+
'false_positives': int(cm[0][1]),
|
221 |
+
'false_negatives': int(cm[1][0]),
|
222 |
+
'average_prediction_confidence': float(np.mean(y_pred))
|
223 |
+
}
|
224 |
+
}
|
225 |
+
|
226 |
+
# Save report
|
227 |
+
with open(f'{self.results_dir}/test_report.json', 'w') as f:
|
228 |
+
json.dump(report, f, indent=2)
|
229 |
+
|
230 |
+
logger.info("Testing completed. Results saved in test_results directory")
|
231 |
+
return report
|
232 |
+
|
233 |
+
def main():
|
234 |
+
try:
|
235 |
+
model_path = 'models/intelligent_routing/saved_model/model.keras'
|
236 |
+
test_data_path = 'models/intelligent_routing/test_data/test_data.json'
|
237 |
+
|
238 |
+
logger.info("Initializing tester")
|
239 |
+
tester = IntelligentRoutingTester(model_path, test_data_path)
|
240 |
+
|
241 |
+
logger.info("Running full test suite")
|
242 |
+
report = tester.run_full_test()
|
243 |
+
|
244 |
+
logger.info("\nTest Results Summary:")
|
245 |
+
logger.info(f"Accuracy: {report['metrics']['accuracy']:.4f}")
|
246 |
+
logger.info(f"Precision: {report['metrics']['precision']:.4f}")
|
247 |
+
logger.info(f"Recall: {report['metrics']['recall']:.4f}")
|
248 |
+
logger.info(f"F1 Score: {report['metrics']['f1']:.4f}")
|
249 |
+
logger.info("\nDetailed Analysis:")
|
250 |
+
logger.info(f"False Positives: {report['detailed_analysis']['false_positives']}")
|
251 |
+
logger.info(f"False Negatives: {report['detailed_analysis']['false_negatives']}")
|
252 |
+
logger.info(f"Avg Prediction Confidence: {report['detailed_analysis']['average_prediction_confidence']:.4f}")
|
253 |
+
|
254 |
+
except Exception as e:
|
255 |
+
logger.error(f"Error during testing: {str(e)}", exc_info=True)
|
256 |
+
raise
|
257 |
+
|
258 |
+
if __name__ == "__main__":
|
259 |
+
main()
|
models/intelligent_routing/train.py
ADDED
@@ -0,0 +1,45 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
from model import IntelligentRoutingModel
|
2 |
+
import os
|
3 |
+
import logging
|
4 |
+
|
5 |
+
# Configure logging
|
6 |
+
logging.basicConfig(
|
7 |
+
level=logging.INFO,
|
8 |
+
format='%(asctime)s - %(levelname)s - %(message)s',
|
9 |
+
handlers=[
|
10 |
+
logging.FileHandler('training.log'),
|
11 |
+
logging.StreamHandler()
|
12 |
+
]
|
13 |
+
)
|
14 |
+
|
15 |
+
logger = logging.getLogger(__name__)
|
16 |
+
|
17 |
+
def main():
|
18 |
+
try:
|
19 |
+
logger.info("Starting model training process")
|
20 |
+
|
21 |
+
# Create model instance
|
22 |
+
logger.info("Initializing IntelligentRoutingModel")
|
23 |
+
model = IntelligentRoutingModel()
|
24 |
+
|
25 |
+
# Train model
|
26 |
+
train_data_path = 'models/intelligent_routing/train_data/training_data.json'
|
27 |
+
logger.info(f"Training model with data from {train_data_path}")
|
28 |
+
history = model.train(train_data_path, epochs=10)
|
29 |
+
|
30 |
+
# Create directory if it doesn't exist
|
31 |
+
os.makedirs('models/intelligent_routing/saved_model', exist_ok=True)
|
32 |
+
|
33 |
+
# Save model with correct extension
|
34 |
+
model_path = 'models/intelligent_routing/saved_model/model.keras'
|
35 |
+
logger.info(f"Saving trained model to {model_path}")
|
36 |
+
model.save_model(model_path)
|
37 |
+
|
38 |
+
logger.info("Model training completed and saved successfully")
|
39 |
+
|
40 |
+
except Exception as e:
|
41 |
+
logger.error(f"Error during model training: {str(e)}", exc_info=True)
|
42 |
+
raise
|
43 |
+
|
44 |
+
if __name__ == "__main__":
|
45 |
+
main()
|
models/intelligent_routing/train_data/__init__.py
ADDED
File without changes
|
models/job_recommendation/generate_data.py
ADDED
@@ -0,0 +1,92 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
import random
|
2 |
+
import json
|
3 |
+
from datetime import datetime, timedelta
|
4 |
+
import os
|
5 |
+
import logging
|
6 |
+
|
7 |
+
logging.basicConfig(level=logging.INFO)
|
8 |
+
logger = logging.getLogger(__name__)
|
9 |
+
|
10 |
+
class JobRecommendationDataGenerator:
|
11 |
+
def __init__(self):
|
12 |
+
self.job_types = ['Electrical', 'Mechanical', 'Plumbing', 'Carpentry', 'Cleaning', 'IT']
|
13 |
+
self.urgency_levels = ['Critical', 'High', 'Medium', 'Low']
|
14 |
+
self.hostel_names = ['Hostel A', 'Hostel B', 'Hostel C', 'Hostel D']
|
15 |
+
self.availability_statuses = ['Available', 'Busy', 'On Leave']
|
16 |
+
|
17 |
+
def generate_location(self):
|
18 |
+
return {
|
19 |
+
"hostel_name": random.choice(self.hostel_names),
|
20 |
+
"floor_number": random.randint(0, 4),
|
21 |
+
"room_number": f"{random.randint(1, 4)}{random.randint(0, 9)}{random.randint(0, 9)}"
|
22 |
+
}
|
23 |
+
|
24 |
+
def generate_worker(self, department=None):
|
25 |
+
if department is None:
|
26 |
+
department = random.choice(self.job_types)
|
27 |
+
|
28 |
+
return {
|
29 |
+
"worker_id": f"W{random.randint(10000, 99999)}",
|
30 |
+
"department": department,
|
31 |
+
"current_workload": random.randint(0, 5),
|
32 |
+
"availability_status": random.choice(self.availability_statuses),
|
33 |
+
"job_success_rate": round(random.uniform(0.80, 0.99), 2),
|
34 |
+
"current_location": self.generate_location()
|
35 |
+
}
|
36 |
+
|
37 |
+
def generate_sample(self, index):
|
38 |
+
job_type = random.choice(self.job_types)
|
39 |
+
location = self.generate_location()
|
40 |
+
|
41 |
+
# Generate workers list with at least one matching department
|
42 |
+
workers = [self.generate_worker(job_type)] # Ensure one matching worker
|
43 |
+
workers.extend([self.generate_worker() for _ in range(random.randint(2, 4))])
|
44 |
+
|
45 |
+
sample = {
|
46 |
+
"job_id": f"J{60000 + index}",
|
47 |
+
"type": job_type,
|
48 |
+
"description": f"{job_type} issue in room {location['room_number']}.",
|
49 |
+
"urgency_level": random.choice(self.urgency_levels),
|
50 |
+
"submission_timestamp": (datetime.utcnow() - timedelta(minutes=random.randint(0, 60))).strftime("%Y-%m-%dT%H:%M:%SZ"),
|
51 |
+
"location": location,
|
52 |
+
"workers": workers
|
53 |
+
}
|
54 |
+
|
55 |
+
return sample
|
56 |
+
|
57 |
+
def generate_dataset(self, num_samples, output_path):
|
58 |
+
logger.info(f"Generating {num_samples} samples...")
|
59 |
+
dataset = []
|
60 |
+
for i in range(num_samples):
|
61 |
+
sample = self.generate_sample(i)
|
62 |
+
dataset.append(sample)
|
63 |
+
|
64 |
+
# Create directory if it doesn't exist
|
65 |
+
os.makedirs(os.path.dirname(output_path), exist_ok=True)
|
66 |
+
|
67 |
+
# Save to JSON file
|
68 |
+
with open(output_path, 'w') as f:
|
69 |
+
json.dump(dataset, f, indent=2)
|
70 |
+
|
71 |
+
logger.info(f"Generated {len(dataset)} samples and saved to {output_path}")
|
72 |
+
return dataset
|
73 |
+
|
74 |
+
def main():
|
75 |
+
generator = JobRecommendationDataGenerator()
|
76 |
+
|
77 |
+
# Generate training data
|
78 |
+
train_samples = generator.generate_dataset(
|
79 |
+
20000,
|
80 |
+
'models/job_recommendation/train_data/training_data.json'
|
81 |
+
)
|
82 |
+
|
83 |
+
# Generate test data
|
84 |
+
test_samples = generator.generate_dataset(
|
85 |
+
4000,
|
86 |
+
'models/job_recommendation/test_data/test_data.json'
|
87 |
+
)
|
88 |
+
|
89 |
+
logger.info(f"Generated {len(train_samples)} training samples and {len(test_samples)} test samples")
|
90 |
+
|
91 |
+
if __name__ == "__main__":
|
92 |
+
main()
|
models/job_recommendation/model.py
ADDED
@@ -0,0 +1,144 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
import tensorflow as tf
|
2 |
+
import numpy as np
|
3 |
+
from datetime import datetime
|
4 |
+
import json
|
5 |
+
import logging
|
6 |
+
|
7 |
+
logging.basicConfig(level=logging.INFO)
|
8 |
+
logger = logging.getLogger(__name__)
|
9 |
+
|
10 |
+
class JobRecommendationModel:
|
11 |
+
def __init__(self):
|
12 |
+
self.model = None
|
13 |
+
self.job_types = ['Electrical', 'Mechanical', 'Plumbing', 'Carpentry', 'Cleaning', 'IT']
|
14 |
+
self.urgency_levels = ['Critical', 'High', 'Medium', 'Low']
|
15 |
+
|
16 |
+
# Create encodings
|
17 |
+
self.job_type_encoding = {job: i for i, job in enumerate(self.job_types)}
|
18 |
+
self.urgency_encoding = {level: i for i, level in enumerate(self.urgency_levels)}
|
19 |
+
|
20 |
+
def preprocess_data(self, data):
|
21 |
+
"""Preprocess input data for model"""
|
22 |
+
features = []
|
23 |
+
labels = []
|
24 |
+
|
25 |
+
for sample in data:
|
26 |
+
# Encode job type
|
27 |
+
job_type_encoded = [0] * len(self.job_types)
|
28 |
+
job_type_idx = self.job_type_encoding[sample['type']]
|
29 |
+
job_type_encoded[job_type_idx] = 1
|
30 |
+
|
31 |
+
# Encode urgency level
|
32 |
+
urgency_encoded = [0] * len(self.urgency_levels)
|
33 |
+
urgency_idx = self.urgency_encoding[sample['urgency_level']]
|
34 |
+
urgency_encoded[urgency_idx] = 1
|
35 |
+
|
36 |
+
# Process each worker
|
37 |
+
for worker in sample['workers']:
|
38 |
+
if worker['department'] == sample['type']: # Only process matching department workers
|
39 |
+
# Create feature vector
|
40 |
+
feature = np.array([
|
41 |
+
*job_type_encoded,
|
42 |
+
*urgency_encoded,
|
43 |
+
worker['current_workload'],
|
44 |
+
worker['job_success_rate'],
|
45 |
+
1 if worker['availability_status'] == 'Available' else 0,
|
46 |
+
sample['location']['floor_number']
|
47 |
+
])
|
48 |
+
features.append(feature)
|
49 |
+
|
50 |
+
# Create label (1 if worker was assigned)
|
51 |
+
labels.append(1 if worker['availability_status'] == 'Available' and
|
52 |
+
worker['current_workload'] < 3 and
|
53 |
+
worker['job_success_rate'] > 0.85 else 0)
|
54 |
+
|
55 |
+
if not features:
|
56 |
+
raise ValueError("No valid features found in the dataset")
|
57 |
+
|
58 |
+
return np.array(features), np.array(labels)
|
59 |
+
|
60 |
+
def build_model(self):
|
61 |
+
"""Build the neural network model"""
|
62 |
+
input_dim = len(self.job_types) + len(self.urgency_levels) + 4 # job_type + urgency + workload + success_rate + availability + floor
|
63 |
+
|
64 |
+
model = tf.keras.Sequential([
|
65 |
+
tf.keras.layers.Dense(64, activation='relu', input_shape=(input_dim,)),
|
66 |
+
tf.keras.layers.BatchNormalization(),
|
67 |
+
tf.keras.layers.Dropout(0.3),
|
68 |
+
tf.keras.layers.Dense(32, activation='relu'),
|
69 |
+
tf.keras.layers.BatchNormalization(),
|
70 |
+
tf.keras.layers.Dropout(0.2),
|
71 |
+
tf.keras.layers.Dense(16, activation='relu'),
|
72 |
+
tf.keras.layers.Dense(1, activation='sigmoid')
|
73 |
+
])
|
74 |
+
|
75 |
+
model.compile(
|
76 |
+
optimizer='adam',
|
77 |
+
loss='binary_crossentropy',
|
78 |
+
metrics=['accuracy']
|
79 |
+
)
|
80 |
+
|
81 |
+
self.model = model
|
82 |
+
return model
|
83 |
+
|
84 |
+
def train(self, train_data_path, epochs=10, batch_size=32):
|
85 |
+
"""Train the model"""
|
86 |
+
logger.info(f"Starting model training with {epochs} epochs")
|
87 |
+
|
88 |
+
# Load training data
|
89 |
+
with open(train_data_path) as f:
|
90 |
+
train_data = json.load(f)
|
91 |
+
|
92 |
+
# Preprocess data
|
93 |
+
X, y = self.preprocess_data(train_data)
|
94 |
+
|
95 |
+
# Build and train model
|
96 |
+
self.build_model()
|
97 |
+
history = self.model.fit(
|
98 |
+
X, y,
|
99 |
+
epochs=epochs,
|
100 |
+
batch_size=batch_size,
|
101 |
+
validation_split=0.2,
|
102 |
+
verbose=1
|
103 |
+
)
|
104 |
+
|
105 |
+
return history
|
106 |
+
|
107 |
+
def predict(self, input_data):
|
108 |
+
"""Make predictions for input data"""
|
109 |
+
# Preprocess input
|
110 |
+
X, _ = self.preprocess_data([input_data])
|
111 |
+
|
112 |
+
# Make prediction
|
113 |
+
predictions = self.model.predict(X)
|
114 |
+
|
115 |
+
# Find best worker
|
116 |
+
best_worker = None
|
117 |
+
highest_score = -1
|
118 |
+
|
119 |
+
for i, worker in enumerate(input_data['workers']):
|
120 |
+
if worker['department'] == input_data['type']:
|
121 |
+
score = predictions[i][0] * worker['job_success_rate'] * (1 / (worker['current_workload'] + 1))
|
122 |
+
if score > highest_score:
|
123 |
+
highest_score = score
|
124 |
+
best_worker = worker
|
125 |
+
|
126 |
+
if not best_worker:
|
127 |
+
return None
|
128 |
+
|
129 |
+
# Generate response
|
130 |
+
return {
|
131 |
+
"job_id": input_data['job_id'],
|
132 |
+
"assigned_worker_id": best_worker['worker_id'],
|
133 |
+
"assignment_timestamp": datetime.utcnow().strftime("%Y-%m-%dT%H:%M:%SZ"),
|
134 |
+
"expected_resolution_time": "1 hour",
|
135 |
+
"location": input_data['location']
|
136 |
+
}
|
137 |
+
|
138 |
+
def save_model(self, path):
|
139 |
+
"""Save the trained model"""
|
140 |
+
self.model.save(path)
|
141 |
+
|
142 |
+
def load_model(self, path):
|
143 |
+
"""Load a trained model"""
|
144 |
+
self.model = tf.keras.models.load_model(path)
|
models/job_recommendation/saved_model/model.keras
ADDED
@@ -0,0 +1,3 @@
|
|
|
|
|
|
|
|
|
1 |
+
version https://git-lfs.github.com/spec/v1
|
2 |
+
oid sha256:950d3e03a2824a735893fb8789627df760f9d7ae6335a13b8c076af5e6292949
|
3 |
+
size 92508
|
models/job_recommendation/test.py
ADDED
@@ -0,0 +1,96 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
import json
|
2 |
+
import logging
|
3 |
+
import numpy as np
|
4 |
+
from sklearn.metrics import accuracy_score, precision_score, recall_score, f1_score, confusion_matrix
|
5 |
+
from model import JobRecommendationModel
|
6 |
+
import matplotlib.pyplot as plt
|
7 |
+
import seaborn as sns
|
8 |
+
from datetime import datetime
|
9 |
+
import os
|
10 |
+
|
11 |
+
# Configure logging
|
12 |
+
logging.basicConfig(
|
13 |
+
level=logging.INFO,
|
14 |
+
format='%(asctime)s - %(levelname)s - %(message)s',
|
15 |
+
handlers=[
|
16 |
+
logging.FileHandler('job_recommendation_testing.log'),
|
17 |
+
logging.StreamHandler()
|
18 |
+
]
|
19 |
+
)
|
20 |
+
|
21 |
+
logger = logging.getLogger(__name__)
|
22 |
+
|
23 |
+
class JobRecommendationTester:
|
24 |
+
def __init__(self, model_path, test_data_path):
|
25 |
+
self.model = JobRecommendationModel()
|
26 |
+
self.model.load_model(model_path)
|
27 |
+
self.test_data_path = test_data_path
|
28 |
+
|
29 |
+
# Create results directory
|
30 |
+
self.results_dir = 'models/job_recommendation/test_results'
|
31 |
+
os.makedirs(self.results_dir, exist_ok=True)
|
32 |
+
|
33 |
+
def load_test_data(self):
|
34 |
+
"""Load test data from JSON file"""
|
35 |
+
with open(self.test_data_path, 'r') as f:
|
36 |
+
return json.load(f)
|
37 |
+
|
38 |
+
def evaluate_model(self):
|
39 |
+
"""Evaluate model performance on test data"""
|
40 |
+
test_data = self.load_test_data()
|
41 |
+
X_test, y_test = self.model.preprocess_data(test_data)
|
42 |
+
|
43 |
+
# Get predictions
|
44 |
+
y_pred = self.model.model.predict(X_test)
|
45 |
+
y_pred_binary = (y_pred > 0.5).astype(int)
|
46 |
+
|
47 |
+
# Calculate metrics
|
48 |
+
metrics = {
|
49 |
+
'accuracy': accuracy_score(y_test, y_pred_binary),
|
50 |
+
'precision': precision_score(y_test, y_pred_binary),
|
51 |
+
'recall': recall_score(y_test, y_pred_binary),
|
52 |
+
'f1': f1_score(y_test, y_pred_binary)
|
53 |
+
}
|
54 |
+
|
55 |
+
cm = confusion_matrix(y_test, y_pred_binary)
|
56 |
+
|
57 |
+
return metrics, cm, y_test, y_pred
|
58 |
+
|
59 |
+
def run_full_test(self):
|
60 |
+
"""Run complete test suite"""
|
61 |
+
logger.info("Starting full model testing")
|
62 |
+
|
63 |
+
metrics, cm, y_test, y_pred = self.evaluate_model()
|
64 |
+
|
65 |
+
# Save results
|
66 |
+
report = {
|
67 |
+
'metrics': metrics,
|
68 |
+
'test_timestamp': datetime.utcnow().strftime("%Y-%m-%dT%H:%M:%SZ")
|
69 |
+
}
|
70 |
+
|
71 |
+
with open(f'{self.results_dir}/test_report.json', 'w') as f:
|
72 |
+
json.dump(report, f, indent=2)
|
73 |
+
|
74 |
+
logger.info("Testing completed. Results saved in test_results directory")
|
75 |
+
return report
|
76 |
+
|
77 |
+
def main():
|
78 |
+
try:
|
79 |
+
model_path = 'models/job_recommendation/saved_model/model.keras'
|
80 |
+
test_data_path = 'models/job_recommendation/test_data/test_data.json'
|
81 |
+
|
82 |
+
tester = JobRecommendationTester(model_path, test_data_path)
|
83 |
+
report = tester.run_full_test()
|
84 |
+
|
85 |
+
logger.info("\nTest Results Summary:")
|
86 |
+
logger.info(f"Accuracy: {report['metrics']['accuracy']:.4f}")
|
87 |
+
logger.info(f"Precision: {report['metrics']['precision']:.4f}")
|
88 |
+
logger.info(f"Recall: {report['metrics']['recall']:.4f}")
|
89 |
+
logger.info(f"F1 Score: {report['metrics']['f1']:.4f}")
|
90 |
+
|
91 |
+
except Exception as e:
|
92 |
+
logger.error(f"Error during testing: {str(e)}", exc_info=True)
|
93 |
+
raise
|
94 |
+
|
95 |
+
if __name__ == "__main__":
|
96 |
+
main()
|
models/job_recommendation/test_data/__init__.py
ADDED
File without changes
|
models/job_recommendation/test_data/test_data.json
ADDED
The diff for this file is too large to render.
See raw diff
|
|
models/job_recommendation/train.py
ADDED
@@ -0,0 +1,41 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
from model import JobRecommendationModel
|
2 |
+
import os
|
3 |
+
import logging
|
4 |
+
|
5 |
+
logging.basicConfig(
|
6 |
+
level=logging.INFO,
|
7 |
+
format='%(asctime)s - %(levelname)s - %(message)s',
|
8 |
+
handlers=[
|
9 |
+
logging.FileHandler('job_recommendation_training.log'),
|
10 |
+
logging.StreamHandler()
|
11 |
+
]
|
12 |
+
)
|
13 |
+
|
14 |
+
logger = logging.getLogger(__name__)
|
15 |
+
|
16 |
+
def main():
|
17 |
+
try:
|
18 |
+
logger.info("Starting job recommendation model training")
|
19 |
+
|
20 |
+
# Create model instance
|
21 |
+
model = JobRecommendationModel()
|
22 |
+
|
23 |
+
# Train model
|
24 |
+
train_data_path = 'models/job_recommendation/train_data/training_data.json'
|
25 |
+
history = model.train(train_data_path, epochs=10)
|
26 |
+
|
27 |
+
# Create directory if it doesn't exist
|
28 |
+
os.makedirs('models/job_recommendation/saved_model', exist_ok=True)
|
29 |
+
|
30 |
+
# Save model
|
31 |
+
model_path = 'models/job_recommendation/saved_model/model.keras'
|
32 |
+
model.save_model(model_path)
|
33 |
+
|
34 |
+
logger.info("Model training completed and saved successfully")
|
35 |
+
|
36 |
+
except Exception as e:
|
37 |
+
logger.error(f"Error during model training: {str(e)}", exc_info=True)
|
38 |
+
raise
|
39 |
+
|
40 |
+
if __name__ == "__main__":
|
41 |
+
main()
|
models/job_recommendation/train_data/__init__.py
ADDED
File without changes
|
models/multilingual_translation/model.py
ADDED
@@ -0,0 +1,184 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
import logging
|
2 |
+
from typing import Dict
|
3 |
+
from datetime import datetime
|
4 |
+
from deep_translator import GoogleTranslator
|
5 |
+
from langdetect import detect, DetectorFactory
|
6 |
+
import time
|
7 |
+
import re
|
8 |
+
|
9 |
+
# Set seed for consistent language detection
|
10 |
+
DetectorFactory.seed = 0
|
11 |
+
|
12 |
+
logger = logging.getLogger(__name__)
|
13 |
+
|
14 |
+
class MultilingualTranslationModel:
|
15 |
+
def __init__(self):
|
16 |
+
# Supported languages with codes
|
17 |
+
self.supported_languages = {
|
18 |
+
'en': 'English',
|
19 |
+
'hi': 'Hindi',
|
20 |
+
'bn': 'Bengali',
|
21 |
+
'te': 'Telugu',
|
22 |
+
'ta': 'Tamil',
|
23 |
+
'mr': 'Marathi',
|
24 |
+
'gu': 'Gujarati',
|
25 |
+
'kn': 'Kannada',
|
26 |
+
'ml': 'Malayalam',
|
27 |
+
'pa': 'Punjabi'
|
28 |
+
}
|
29 |
+
|
30 |
+
# Common Hinglish patterns and their English equivalents
|
31 |
+
self.hinglish_patterns = {
|
32 |
+
r'\b(nahi|nhi)\b': 'not',
|
33 |
+
r'\b(hai|he)\b': 'is',
|
34 |
+
r'\bpaani\b': 'water',
|
35 |
+
r'\bkharab\b': 'broken',
|
36 |
+
r'\bgaya\b': 'gone',
|
37 |
+
r'\braha\b': 'staying',
|
38 |
+
r'\bho\b': 'happening',
|
39 |
+
r'\bme\b': 'in',
|
40 |
+
r'\bka\b': 'of',
|
41 |
+
r'\bki\b': 'of'
|
42 |
+
}
|
43 |
+
|
44 |
+
def is_hinglish(self, text: str) -> bool:
|
45 |
+
"""Check if text is likely Hinglish"""
|
46 |
+
# Count Hinglish patterns
|
47 |
+
pattern_count = sum(1 for pattern in self.hinglish_patterns if re.search(pattern, text.lower()))
|
48 |
+
words = text.split()
|
49 |
+
|
50 |
+
# If more than 30% of words match Hinglish patterns, consider it Hinglish
|
51 |
+
return pattern_count / len(words) > 0.3 if words else False
|
52 |
+
|
53 |
+
def convert_hinglish_to_english(self, text: str) -> str:
|
54 |
+
"""Convert Hinglish text to proper English"""
|
55 |
+
try:
|
56 |
+
# First try direct translation
|
57 |
+
translator = GoogleTranslator(source='auto', target='en')
|
58 |
+
result = translator.translate(text)
|
59 |
+
|
60 |
+
# If translation failed or returned same text, try pattern-based conversion
|
61 |
+
if not result or result.lower() == text.lower():
|
62 |
+
# Convert to proper English using patterns
|
63 |
+
processed_text = text.lower()
|
64 |
+
for pattern, replacement in self.hinglish_patterns.items():
|
65 |
+
processed_text = re.sub(pattern, replacement, processed_text)
|
66 |
+
return processed_text
|
67 |
+
|
68 |
+
return result
|
69 |
+
|
70 |
+
except Exception as e:
|
71 |
+
logger.error(f"Hinglish conversion failed: {str(e)}")
|
72 |
+
return text
|
73 |
+
|
74 |
+
def detect_language(self, text: str, max_retries=3) -> str:
|
75 |
+
"""Detect the language of input text with retry logic"""
|
76 |
+
# Check for Hinglish first
|
77 |
+
if self.is_hinglish(text):
|
78 |
+
logger.info("Detected Hinglish text")
|
79 |
+
return 'hi'
|
80 |
+
|
81 |
+
for attempt in range(max_retries):
|
82 |
+
try:
|
83 |
+
detected_lang = detect(text)
|
84 |
+
logger.info(f"Detected language: {detected_lang}")
|
85 |
+
return detected_lang
|
86 |
+
|
87 |
+
except Exception as e:
|
88 |
+
logger.error(f"Language detection attempt {attempt + 1} failed: {str(e)}")
|
89 |
+
if attempt < max_retries - 1:
|
90 |
+
time.sleep(1)
|
91 |
+
|
92 |
+
return 'en' # Default to English
|
93 |
+
|
94 |
+
def translate(self, text: str, target_lang: str = 'en', max_retries=3) -> Dict:
|
95 |
+
"""Translate text to target language with retry logic"""
|
96 |
+
for attempt in range(max_retries):
|
97 |
+
try:
|
98 |
+
source_lang = self.detect_language(text)
|
99 |
+
logger.info(f"Source language detected: {source_lang}")
|
100 |
+
|
101 |
+
# Handle Hinglish text specially
|
102 |
+
if self.is_hinglish(text) and target_lang == 'en':
|
103 |
+
translated_text = self.convert_hinglish_to_english(text)
|
104 |
+
else:
|
105 |
+
# If already in target language, return original text
|
106 |
+
if source_lang == target_lang:
|
107 |
+
return {
|
108 |
+
'translated_text': text,
|
109 |
+
'source_language': source_lang,
|
110 |
+
'target_language': target_lang,
|
111 |
+
'confidence': 1.0,
|
112 |
+
'timestamp': datetime.utcnow().isoformat()
|
113 |
+
}
|
114 |
+
|
115 |
+
# Initialize translator
|
116 |
+
translator = GoogleTranslator(
|
117 |
+
source='auto',
|
118 |
+
target=target_lang
|
119 |
+
)
|
120 |
+
|
121 |
+
# Perform translation
|
122 |
+
translated_text = translator.translate(text)
|
123 |
+
|
124 |
+
logger.info(f"Translation result: {translated_text}")
|
125 |
+
|
126 |
+
return {
|
127 |
+
'translated_text': translated_text,
|
128 |
+
'source_language': source_lang,
|
129 |
+
'target_language': target_lang,
|
130 |
+
'confidence': 0.9,
|
131 |
+
'timestamp': datetime.utcnow().isoformat()
|
132 |
+
}
|
133 |
+
|
134 |
+
except Exception as e:
|
135 |
+
logger.error(f"Translation attempt {attempt + 1} failed: {str(e)}")
|
136 |
+
if attempt < max_retries - 1:
|
137 |
+
time.sleep(1)
|
138 |
+
continue
|
139 |
+
|
140 |
+
return {
|
141 |
+
'error': 'Translation failed after maximum retries',
|
142 |
+
'timestamp': datetime.utcnow().isoformat()
|
143 |
+
}
|
144 |
+
|
145 |
+
def process_message(self, message_data: Dict) -> Dict:
|
146 |
+
"""Process a chat message and return translation"""
|
147 |
+
try:
|
148 |
+
if not message_data.get('user_message'):
|
149 |
+
return {
|
150 |
+
'error': 'No message provided',
|
151 |
+
'timestamp': datetime.utcnow().isoformat()
|
152 |
+
}
|
153 |
+
|
154 |
+
target_lang = message_data.get('target_language', 'en').lower()
|
155 |
+
|
156 |
+
# Validate target language
|
157 |
+
if target_lang not in self.supported_languages:
|
158 |
+
return {
|
159 |
+
'error': f'Unsupported target language: {target_lang}',
|
160 |
+
'timestamp': datetime.utcnow().isoformat()
|
161 |
+
}
|
162 |
+
|
163 |
+
result = self.translate(
|
164 |
+
message_data['user_message'],
|
165 |
+
target_lang
|
166 |
+
)
|
167 |
+
|
168 |
+
return {
|
169 |
+
'original_message': message_data['user_message'],
|
170 |
+
'translated_message': result.get('translated_text', ''),
|
171 |
+
'source_language': result.get('source_language', ''),
|
172 |
+
'target_language': target_lang,
|
173 |
+
'language_name': self.supported_languages.get(target_lang, ''),
|
174 |
+
'confidence': result.get('confidence', 0.0),
|
175 |
+
'timestamp': result.get('timestamp', datetime.utcnow().isoformat()),
|
176 |
+
'error': result.get('error')
|
177 |
+
}
|
178 |
+
|
179 |
+
except Exception as e:
|
180 |
+
logger.error(f"Message processing error: {str(e)}")
|
181 |
+
return {
|
182 |
+
'error': str(e),
|
183 |
+
'timestamp': datetime.utcnow().isoformat()
|
184 |
+
}
|
models/multilingual_translation/test_data/__init__.py
ADDED
File without changes
|
models/multilingual_translation/test_data/test_data.json
ADDED
@@ -0,0 +1,156 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
{
|
2 |
+
"translation_tests": [
|
3 |
+
{
|
4 |
+
"user_message": "toilet me paani nahi aa rha hain",
|
5 |
+
"target_language": "en",
|
6 |
+
"expected_contains": ["toilet", "water", "not", "coming"]
|
7 |
+
},
|
8 |
+
{
|
9 |
+
"user_message": "AC ka temperature control kharab ho gaya hai",
|
10 |
+
"target_language": "en",
|
11 |
+
"expected_contains": ["AC", "temperature", "control", "broken"]
|
12 |
+
},
|
13 |
+
{
|
14 |
+
"user_message": "fan ki speed kam ho gayi hai",
|
15 |
+
"target_language": "en",
|
16 |
+
"expected_contains": ["fan", "speed", "reduced"]
|
17 |
+
},
|
18 |
+
{
|
19 |
+
"user_message": "The water heater is not working",
|
20 |
+
"target_language": "hi",
|
21 |
+
"expected_contains": ["पानी", "हीटर", "काम"]
|
22 |
+
},
|
23 |
+
{
|
24 |
+
"user_message": "Light bulb needs to be replaced",
|
25 |
+
"target_language": "hi",
|
26 |
+
"expected_contains": ["लाइट", "बल्ब", "बदलना"]
|
27 |
+
},
|
28 |
+
{
|
29 |
+
"user_message": "ਪੱਖਾ ਕੰਮ ਨਹੀਂ ਕਰ ਰਿਹਾ",
|
30 |
+
"target_language": "en",
|
31 |
+
"expected_contains": ["fan", "not", "working"]
|
32 |
+
},
|
33 |
+
{
|
34 |
+
"user_message": "The sink is clogged",
|
35 |
+
"target_language": "pa",
|
36 |
+
"expected_contains": ["ਸਿੰਕ", "ਬੰਦ"]
|
37 |
+
},
|
38 |
+
{
|
39 |
+
"user_message": "বাথরুমে জল নেই",
|
40 |
+
"target_language": "en",
|
41 |
+
"expected_contains": ["bathroom", "no", "water"]
|
42 |
+
},
|
43 |
+
{
|
44 |
+
"user_message": "Electricity is not working",
|
45 |
+
"target_language": "bn",
|
46 |
+
"expected_contains": ["বিদ্যুৎ", "কাজ"]
|
47 |
+
},
|
48 |
+
{
|
49 |
+
"user_message": "వాష్ బేసిన్ లో నీరు పోవడం లేదు",
|
50 |
+
"target_language": "en",
|
51 |
+
"expected_contains": ["washbasin", "water", "not", "draining"]
|
52 |
+
},
|
53 |
+
{
|
54 |
+
"user_message": "Door lock is broken",
|
55 |
+
"target_language": "te",
|
56 |
+
"expected_contains": ["తలుపు", "తాళం", "పగిలిపోయింది"]
|
57 |
+
},
|
58 |
+
{
|
59 |
+
"user_message": "குளியலறையில் தண்ணீர் கசிகிறது",
|
60 |
+
"target_language": "en",
|
61 |
+
"expected_contains": ["bathroom", "water", "leaking"]
|
62 |
+
},
|
63 |
+
{
|
64 |
+
"user_message": "Window is stuck",
|
65 |
+
"target_language": "ta",
|
66 |
+
"expected_contains": ["ஜன்னல்", "சிக்கி"]
|
67 |
+
},
|
68 |
+
{
|
69 |
+
"user_message": "room me light nahi chal rahi hai",
|
70 |
+
"target_language": "en",
|
71 |
+
"expected_contains": ["room", "light", "not", "working"]
|
72 |
+
},
|
73 |
+
{
|
74 |
+
"user_message": "bathroom ka tap leak ho raha hai",
|
75 |
+
"target_language": "en",
|
76 |
+
"expected_contains": ["bathroom", "tap", "leaking"]
|
77 |
+
},
|
78 |
+
{
|
79 |
+
"user_message": "AC remote not working",
|
80 |
+
"target_language": "hi",
|
81 |
+
"expected_contains": ["एसी", "रिमोट", "काम"]
|
82 |
+
},
|
83 |
+
{
|
84 |
+
"user_message": "ਬਾਥਰੂਮ ਦਾ ਸ਼ਾਵਰ ਖਰਾਬ ਹੈ",
|
85 |
+
"target_language": "en",
|
86 |
+
"expected_contains": ["bathroom", "shower", "broken"]
|
87 |
+
},
|
88 |
+
{
|
89 |
+
"user_message": "Geyser is not heating properly",
|
90 |
+
"target_language": "pa",
|
91 |
+
"expected_contains": ["ਗੀਜ਼ਰ", "ਗਰਮ"]
|
92 |
+
},
|
93 |
+
{
|
94 |
+
"user_message": "এসি থেকে পানি পড়ছে",
|
95 |
+
"target_language": "en",
|
96 |
+
"expected_contains": ["AC", "water", "dripping"]
|
97 |
+
},
|
98 |
+
{
|
99 |
+
"user_message": "Ceiling fan making noise",
|
100 |
+
"target_language": "bn",
|
101 |
+
"expected_contains": ["সিলিং", "ফ্যান", "আওয়াজ"]
|
102 |
+
},
|
103 |
+
{
|
104 |
+
"user_message": "కిటికీ తెరవడం లేదు",
|
105 |
+
"target_language": "en",
|
106 |
+
"expected_contains": ["window", "not", "opening"]
|
107 |
+
},
|
108 |
+
{
|
109 |
+
"user_message": "Bed frame is broken",
|
110 |
+
"target_language": "te",
|
111 |
+
"expected_contains": ["మంచం", "ఫ్రేమ్", "విరిగింది"]
|
112 |
+
},
|
113 |
+
{
|
114 |
+
"user_message": "மின்விசிறி வேகம் குறைந்துள்ளது",
|
115 |
+
"target_language": "en",
|
116 |
+
"expected_contains": ["fan", "speed", "reduced"]
|
117 |
+
},
|
118 |
+
{
|
119 |
+
"user_message": "TV not turning on",
|
120 |
+
"target_language": "ta",
|
121 |
+
"expected_contains": ["டிவி", "ஆன்", "ஆகவில்லை"]
|
122 |
+
},
|
123 |
+
{
|
124 |
+
"user_message": "balcony ka darwaza band ho gaya hai",
|
125 |
+
"target_language": "en",
|
126 |
+
"expected_contains": ["balcony", "door", "stuck"]
|
127 |
+
}
|
128 |
+
],
|
129 |
+
"language_detection_tests": [
|
130 |
+
{
|
131 |
+
"text": "This is English text",
|
132 |
+
"expected_language": "en"
|
133 |
+
},
|
134 |
+
{
|
135 |
+
"text": "यह हिंदी टेक्स्ट है",
|
136 |
+
"expected_language": "hi"
|
137 |
+
},
|
138 |
+
{
|
139 |
+
"text": "ਇਹ ਪੰਜਾਬੀ ਟੈਕਸਟ ਹੈ",
|
140 |
+
"expected_language": "pa"
|
141 |
+
},
|
142 |
+
{
|
143 |
+
"text": "এটি বাংলা টেক্সট",
|
144 |
+
"expected_language": "bn"
|
145 |
+
},
|
146 |
+
{
|
147 |
+
"text": "ఇది తెలుగు టెక్స్ట్",
|
148 |
+
"expected_language": "te"
|
149 |
+
},
|
150 |
+
{
|
151 |
+
"text": "இது தமிழ் உரை",
|
152 |
+
"expected_language": "ta"
|
153 |
+
}
|
154 |
+
]
|
155 |
+
}
|
156 |
+
|
models/multilingual_translation/test_model.py
ADDED
@@ -0,0 +1,160 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
import json
|
2 |
+
import logging
|
3 |
+
from datetime import datetime
|
4 |
+
import os
|
5 |
+
from model import MultilingualTranslationModel
|
6 |
+
import time
|
7 |
+
|
8 |
+
# Configure logging with UTF-8 encoding
|
9 |
+
logging.basicConfig(
|
10 |
+
level=logging.INFO,
|
11 |
+
format='%(asctime)s - %(levelname)s - %(message)s',
|
12 |
+
handlers=[
|
13 |
+
logging.FileHandler('translation_testing.log', encoding='utf-8'),
|
14 |
+
logging.StreamHandler()
|
15 |
+
]
|
16 |
+
)
|
17 |
+
|
18 |
+
logger = logging.getLogger(__name__)
|
19 |
+
|
20 |
+
class TranslationTester:
|
21 |
+
def __init__(self):
|
22 |
+
self.model = MultilingualTranslationModel()
|
23 |
+
self.results_dir = 'models/multilingual_translation/test_results'
|
24 |
+
os.makedirs(self.results_dir, exist_ok=True)
|
25 |
+
|
26 |
+
def load_test_data(self):
|
27 |
+
"""Load test data from JSON file"""
|
28 |
+
test_data_path = 'models/multilingual_translation/test_data/test_data.json'
|
29 |
+
try:
|
30 |
+
with open(test_data_path, 'r', encoding='utf-8') as f:
|
31 |
+
return json.load(f)
|
32 |
+
except Exception as e:
|
33 |
+
logger.error(f"Error loading test data: {str(e)}")
|
34 |
+
raise
|
35 |
+
|
36 |
+
def test_translations(self):
|
37 |
+
"""Test translation with sample messages"""
|
38 |
+
test_data = self.load_test_data()
|
39 |
+
test_cases = test_data['translation_tests']
|
40 |
+
|
41 |
+
results = []
|
42 |
+
for case in test_cases:
|
43 |
+
logger.info(f"\nTesting translation:")
|
44 |
+
logger.info(f"Original: {case['user_message']}")
|
45 |
+
logger.info(f"Target Language: {case['target_language']}")
|
46 |
+
|
47 |
+
result = self.model.process_message(case)
|
48 |
+
|
49 |
+
# Add test-specific fields
|
50 |
+
result['expected_contains'] = case['expected_contains']
|
51 |
+
|
52 |
+
# Check if translation contains expected words
|
53 |
+
translation = result.get('translated_message', '').lower()
|
54 |
+
contains_expected = all(
|
55 |
+
word.lower() in translation
|
56 |
+
for word in case['expected_contains']
|
57 |
+
) if not result.get('error') else False
|
58 |
+
|
59 |
+
result['translation_quality'] = 'Good' if contains_expected else 'Check needed'
|
60 |
+
|
61 |
+
# Log the result
|
62 |
+
logger.info(f"Translation: {result.get('translated_message', 'No translation')}")
|
63 |
+
logger.info(f"Quality: {result['translation_quality']}")
|
64 |
+
logger.info(f"Confidence: {result.get('confidence', 0.0):.2f}")
|
65 |
+
|
66 |
+
if result.get('error'):
|
67 |
+
logger.warning(f"Error: {result['error']}")
|
68 |
+
|
69 |
+
results.append(result)
|
70 |
+
time.sleep(1) # Avoid rate limiting
|
71 |
+
|
72 |
+
return results
|
73 |
+
|
74 |
+
def test_language_detection(self):
|
75 |
+
"""Test language detection"""
|
76 |
+
test_data = self.load_test_data()
|
77 |
+
test_cases = test_data['language_detection_tests']
|
78 |
+
|
79 |
+
results = []
|
80 |
+
for case in test_cases:
|
81 |
+
logger.info(f"\nTesting language detection:")
|
82 |
+
logger.info(f"Text: {case['text']}")
|
83 |
+
|
84 |
+
detected_lang = self.model.detect_language(case['text'])
|
85 |
+
|
86 |
+
result = {
|
87 |
+
'text': case['text'],
|
88 |
+
'detected_language': detected_lang,
|
89 |
+
'expected_language': case['expected_language'],
|
90 |
+
'is_correct': detected_lang == case['expected_language']
|
91 |
+
}
|
92 |
+
|
93 |
+
logger.info(f"Detected: {detected_lang}")
|
94 |
+
logger.info(f"Expected: {case['expected_language']}")
|
95 |
+
|
96 |
+
results.append(result)
|
97 |
+
time.sleep(1)
|
98 |
+
|
99 |
+
return results
|
100 |
+
|
101 |
+
def run_full_test(self):
|
102 |
+
"""Run complete test suite"""
|
103 |
+
logger.info("Starting translation testing")
|
104 |
+
|
105 |
+
try:
|
106 |
+
# Test translations
|
107 |
+
translation_results = self.test_translations()
|
108 |
+
|
109 |
+
# Test language detection
|
110 |
+
detection_results = self.test_language_detection()
|
111 |
+
|
112 |
+
# Prepare report
|
113 |
+
report = {
|
114 |
+
'test_timestamp': datetime.utcnow().isoformat(),
|
115 |
+
'translation_tests': {
|
116 |
+
'total': len(translation_results),
|
117 |
+
'successful': sum(1 for r in translation_results if not r.get('error')),
|
118 |
+
'good_quality': sum(1 for r in translation_results if r.get('translation_quality') == 'Good'),
|
119 |
+
'detailed_results': translation_results
|
120 |
+
},
|
121 |
+
'detection_tests': {
|
122 |
+
'total': len(detection_results),
|
123 |
+
'successful': sum(1 for r in detection_results if r['is_correct']),
|
124 |
+
'detailed_results': detection_results
|
125 |
+
}
|
126 |
+
}
|
127 |
+
|
128 |
+
# Save report
|
129 |
+
report_path = f'{self.results_dir}/test_report.json'
|
130 |
+
with open(report_path, 'w', encoding='utf-8') as f:
|
131 |
+
json.dump(report, f, indent=2, ensure_ascii=False)
|
132 |
+
|
133 |
+
logger.info(f"Testing completed. Results saved to {report_path}")
|
134 |
+
|
135 |
+
return report
|
136 |
+
|
137 |
+
except Exception as e:
|
138 |
+
logger.error(f"Error during testing: {str(e)}", exc_info=True)
|
139 |
+
raise
|
140 |
+
|
141 |
+
def main():
|
142 |
+
try:
|
143 |
+
tester = TranslationTester()
|
144 |
+
report = tester.run_full_test()
|
145 |
+
|
146 |
+
print("\nTest Results Summary:")
|
147 |
+
print("Translation Tests:")
|
148 |
+
print(f"Total: {report['translation_tests']['total']}")
|
149 |
+
print(f"Successful: {report['translation_tests']['successful']}")
|
150 |
+
print(f"Good Quality: {report['translation_tests']['good_quality']}")
|
151 |
+
print("\nLanguage Detection Tests:")
|
152 |
+
print(f"Total: {report['detection_tests']['total']}")
|
153 |
+
print(f"Successful: {report['detection_tests']['successful']}")
|
154 |
+
|
155 |
+
except Exception as e:
|
156 |
+
logger.error(f"Error in main: {str(e)}", exc_info=True)
|
157 |
+
raise
|
158 |
+
|
159 |
+
if __name__ == "__main__":
|
160 |
+
main()
|
models/multilingual_translation/train_data/__init__.py
ADDED
File without changes
|
models/multilingual_translation/train_data/training_data.json
ADDED
@@ -0,0 +1,7 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
{
|
2 |
+
"data": [],
|
3 |
+
"metadata": {
|
4 |
+
"version": "1.0",
|
5 |
+
"created_at": "2024-03-20"
|
6 |
+
}
|
7 |
+
}
|
models/sentiment_analysis/model.py
ADDED
@@ -0,0 +1,118 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
import requests
|
2 |
+
import logging
|
3 |
+
from typing import Dict
|
4 |
+
import os
|
5 |
+
from datetime import datetime
|
6 |
+
import time
|
7 |
+
|
8 |
+
logger = logging.getLogger(__name__)
|
9 |
+
|
10 |
+
class SentimentAnalysisModel:
|
11 |
+
def __init__(self):
|
12 |
+
# Hugging Face API configuration
|
13 |
+
self.api_url = "https://api-inference.huggingface.co/models/finiteautomata/bertweet-base-sentiment-analysis"
|
14 |
+
self.headers = {
|
15 |
+
"Authorization": f"Bearer {os.getenv('HUGGINGFACE_API_TOKEN')}",
|
16 |
+
"Content-Type": "application/json"
|
17 |
+
}
|
18 |
+
|
19 |
+
# Emotion mapping from the model's output to our categories
|
20 |
+
self.emotion_mapping = {
|
21 |
+
'POS': 'Satisfaction',
|
22 |
+
'NEU': 'Indifference',
|
23 |
+
'NEG': 'Frustration'
|
24 |
+
}
|
25 |
+
|
26 |
+
def predict(self, text: str, max_retries=3, retry_delay=5) -> Dict:
|
27 |
+
"""
|
28 |
+
Get sentiment prediction from Hugging Face API with retry logic
|
29 |
+
"""
|
30 |
+
for attempt in range(max_retries):
|
31 |
+
try:
|
32 |
+
response = requests.post(
|
33 |
+
self.api_url,
|
34 |
+
headers=self.headers,
|
35 |
+
json={"inputs": text}
|
36 |
+
)
|
37 |
+
|
38 |
+
if response.status_code == 503:
|
39 |
+
# Model is loading, wait and retry
|
40 |
+
wait_time = min(retry_delay * (attempt + 1), 20)
|
41 |
+
logger.info(f"Model is loading, waiting {wait_time} seconds before retry...")
|
42 |
+
time.sleep(wait_time)
|
43 |
+
continue
|
44 |
+
|
45 |
+
if response.status_code != 200:
|
46 |
+
logger.error(f"API request failed with status code: {response.status_code}")
|
47 |
+
logger.error(f"Response content: {response.text}")
|
48 |
+
continue
|
49 |
+
|
50 |
+
# Process response
|
51 |
+
result = response.json()
|
52 |
+
|
53 |
+
if isinstance(result, list) and len(result) > 0:
|
54 |
+
# Get the prediction with highest score
|
55 |
+
prediction = max(result[0], key=lambda x: x['score'])
|
56 |
+
|
57 |
+
# Map to our emotion categories
|
58 |
+
mapped_emotion = self.emotion_mapping.get(
|
59 |
+
prediction['label'],
|
60 |
+
'Indifference'
|
61 |
+
)
|
62 |
+
|
63 |
+
return {
|
64 |
+
'emotional_label': mapped_emotion,
|
65 |
+
'confidence': prediction['score'],
|
66 |
+
'timestamp': datetime.utcnow().isoformat()
|
67 |
+
}
|
68 |
+
|
69 |
+
except Exception as e:
|
70 |
+
logger.error(f"Attempt {attempt + 1} failed: {str(e)}")
|
71 |
+
if attempt < max_retries - 1:
|
72 |
+
time.sleep(retry_delay)
|
73 |
+
continue
|
74 |
+
|
75 |
+
# If all retries failed, return default response
|
76 |
+
return {
|
77 |
+
'emotional_label': 'Indifference',
|
78 |
+
'confidence': 0.0,
|
79 |
+
'timestamp': datetime.utcnow().isoformat(),
|
80 |
+
'error': "Failed after maximum retries"
|
81 |
+
}
|
82 |
+
|
83 |
+
def process_grievance(self, grievance_data: Dict) -> Dict:
|
84 |
+
"""
|
85 |
+
Process a grievance and return sentiment analysis
|
86 |
+
"""
|
87 |
+
try:
|
88 |
+
if not grievance_data.get('text'):
|
89 |
+
return {
|
90 |
+
'grievance_id': grievance_data.get('grievance_id', 'unknown'),
|
91 |
+
'emotional_label': 'Indifference',
|
92 |
+
'confidence': 0.0,
|
93 |
+
'analysis_timestamp': datetime.utcnow().isoformat(),
|
94 |
+
'error': 'No text provided'
|
95 |
+
}
|
96 |
+
|
97 |
+
# Add some context to help with sentiment analysis
|
98 |
+
context_text = f"In a hostel maintenance context: {grievance_data['text']}"
|
99 |
+
sentiment_result = self.predict(context_text)
|
100 |
+
|
101 |
+
return {
|
102 |
+
'grievance_id': grievance_data.get('grievance_id', 'unknown'),
|
103 |
+
'text': grievance_data['text'],
|
104 |
+
'emotional_label': sentiment_result['emotional_label'],
|
105 |
+
'confidence': sentiment_result['confidence'],
|
106 |
+
'analysis_timestamp': sentiment_result['timestamp'],
|
107 |
+
'error': sentiment_result.get('error')
|
108 |
+
}
|
109 |
+
|
110 |
+
except Exception as e:
|
111 |
+
logger.error(f"Error processing grievance: {str(e)}")
|
112 |
+
return {
|
113 |
+
'grievance_id': grievance_data.get('grievance_id', 'unknown'),
|
114 |
+
'emotional_label': 'Indifference',
|
115 |
+
'confidence': 0.0,
|
116 |
+
'analysis_timestamp': datetime.utcnow().isoformat(),
|
117 |
+
'error': str(e)
|
118 |
+
}
|
models/sentiment_analysis/test_data/__init__.py
ADDED
File without changes
|
models/sentiment_analysis/test_data/test_data.json
ADDED
@@ -0,0 +1,773 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
[
|
2 |
+
{
|
3 |
+
"grievance_id": "G12347",
|
4 |
+
"text": "I am extremely frustrated with the constant power outages in my room.",
|
5 |
+
"expected_emotion": "Frustration"
|
6 |
+
},
|
7 |
+
{
|
8 |
+
"grievance_id": "G12348",
|
9 |
+
"text": "Thank you for resolving my issue so quickly! Great service!",
|
10 |
+
"expected_emotion": "Satisfaction"
|
11 |
+
},
|
12 |
+
{
|
13 |
+
"grievance_id": "G12349",
|
14 |
+
"text": "Why hasn't the maintenance team fixed the leaking roof yet? This is unacceptable!",
|
15 |
+
"expected_emotion": "Frustration"
|
16 |
+
},
|
17 |
+
{
|
18 |
+
"grievance_id": "G12350",
|
19 |
+
"text": "The water pressure is slightly low today.",
|
20 |
+
"expected_emotion": "Indifference"
|
21 |
+
},
|
22 |
+
{
|
23 |
+
"grievance_id": "G12351",
|
24 |
+
"text": "The geyser in the toilet is not working properly.",
|
25 |
+
"expected_emotion": "Frustration"
|
26 |
+
},
|
27 |
+
{
|
28 |
+
"grievance_id": "G12352",
|
29 |
+
"text": "I am happy with the new cleaning schedule.",
|
30 |
+
"expected_emotion": "Satisfaction"
|
31 |
+
},
|
32 |
+
{
|
33 |
+
"grievance_id": "G12353",
|
34 |
+
"text": "The food quality in the mess has improved significantly.",
|
35 |
+
"expected_emotion": "Satisfaction"
|
36 |
+
},
|
37 |
+
{
|
38 |
+
"grievance_id": "G12354",
|
39 |
+
"text": "There is no AC in my room, and it's very uncomfortable.",
|
40 |
+
"expected_emotion": "Frustration"
|
41 |
+
},
|
42 |
+
{
|
43 |
+
"grievance_id": "G12355",
|
44 |
+
"text": "The heater is not available in the hostel, and it's freezing.",
|
45 |
+
"expected_emotion": "Frustration"
|
46 |
+
},
|
47 |
+
{
|
48 |
+
"grievance_id": "G12356",
|
49 |
+
"text": "The new warden is very approachable and helpful.",
|
50 |
+
"expected_emotion": "Satisfaction"
|
51 |
+
},
|
52 |
+
{
|
53 |
+
"grievance_id": "G12357",
|
54 |
+
"text": "The internet speed is too slow for my online classes.",
|
55 |
+
"expected_emotion": "Frustration"
|
56 |
+
},
|
57 |
+
{
|
58 |
+
"grievance_id": "G12358",
|
59 |
+
"text": "The library hours have been extended, which is great!",
|
60 |
+
"expected_emotion": "Satisfaction"
|
61 |
+
},
|
62 |
+
{
|
63 |
+
"grievance_id": "G12359",
|
64 |
+
"text": "The water cooler is not dispensing cold water.",
|
65 |
+
"expected_emotion": "Frustration"
|
66 |
+
},
|
67 |
+
{
|
68 |
+
"grievance_id": "G12360",
|
69 |
+
"text": "The maintenance team fixed the broken window quickly.",
|
70 |
+
"expected_emotion": "Satisfaction"
|
71 |
+
},
|
72 |
+
{
|
73 |
+
"grievance_id": "G12361",
|
74 |
+
"text": "The noise from the construction is unbearable.",
|
75 |
+
"expected_emotion": "Frustration"
|
76 |
+
},
|
77 |
+
{
|
78 |
+
"grievance_id": "G12362",
|
79 |
+
"text": "The new gym equipment is fantastic!",
|
80 |
+
"expected_emotion": "Satisfaction"
|
81 |
+
},
|
82 |
+
{
|
83 |
+
"grievance_id": "G12363",
|
84 |
+
"text": "The laundry service is often delayed.",
|
85 |
+
"expected_emotion": "Frustration"
|
86 |
+
},
|
87 |
+
{
|
88 |
+
"grievance_id": "G12364",
|
89 |
+
"text": "The hostel garden is well-maintained and beautiful.",
|
90 |
+
"expected_emotion": "Satisfaction"
|
91 |
+
},
|
92 |
+
{
|
93 |
+
"grievance_id": "G12365",
|
94 |
+
"text": "The security staff is very vigilant and polite.",
|
95 |
+
"expected_emotion": "Satisfaction"
|
96 |
+
},
|
97 |
+
{
|
98 |
+
"grievance_id": "G12366",
|
99 |
+
"text": "The room cleaning service is inconsistent.",
|
100 |
+
"expected_emotion": "Frustration"
|
101 |
+
},
|
102 |
+
{
|
103 |
+
"grievance_id": "G12367",
|
104 |
+
"text": "The study room is too crowded during exam times.",
|
105 |
+
"expected_emotion": "Frustration"
|
106 |
+
},
|
107 |
+
{
|
108 |
+
"grievance_id": "G12368",
|
109 |
+
"text": "The hostel management is very responsive to our needs.",
|
110 |
+
"expected_emotion": "Satisfaction"
|
111 |
+
},
|
112 |
+
{
|
113 |
+
"grievance_id": "G12369",
|
114 |
+
"text": "The fire alarm went off without any reason.",
|
115 |
+
"expected_emotion": "Frustration"
|
116 |
+
},
|
117 |
+
{
|
118 |
+
"grievance_id": "G12370",
|
119 |
+
"text": "The new recreational area is a great addition.",
|
120 |
+
"expected_emotion": "Satisfaction"
|
121 |
+
},
|
122 |
+
{
|
123 |
+
"grievance_id": "G12371",
|
124 |
+
"text": "The water supply is often interrupted.",
|
125 |
+
"expected_emotion": "Frustration"
|
126 |
+
},
|
127 |
+
{
|
128 |
+
"grievance_id": "G12372",
|
129 |
+
"text": "The hostel events are well-organized and fun.",
|
130 |
+
"expected_emotion": "Satisfaction"
|
131 |
+
},
|
132 |
+
{
|
133 |
+
"grievance_id": "G12373",
|
134 |
+
"text": "The room furniture is old and needs replacement.",
|
135 |
+
"expected_emotion": "Frustration"
|
136 |
+
},
|
137 |
+
{
|
138 |
+
"grievance_id": "G12374",
|
139 |
+
"text": "The hostel staff is very courteous and helpful.",
|
140 |
+
"expected_emotion": "Satisfaction"
|
141 |
+
},
|
142 |
+
{
|
143 |
+
"grievance_id": "G12375",
|
144 |
+
"text": "The parking area is too small for all residents.",
|
145 |
+
"expected_emotion": "Frustration"
|
146 |
+
},
|
147 |
+
{
|
148 |
+
"grievance_id": "G12376",
|
149 |
+
"text": "The hostel is very clean and well-maintained.",
|
150 |
+
"expected_emotion": "Satisfaction"
|
151 |
+
},
|
152 |
+
{
|
153 |
+
"grievance_id": "G12377",
|
154 |
+
"text": "The room keys are often misplaced by the staff.",
|
155 |
+
"expected_emotion": "Frustration"
|
156 |
+
},
|
157 |
+
{
|
158 |
+
"grievance_id": "G12378",
|
159 |
+
"text": "The hostel location is very convenient for commuting.",
|
160 |
+
"expected_emotion": "Satisfaction"
|
161 |
+
},
|
162 |
+
{
|
163 |
+
"grievance_id": "G12379",
|
164 |
+
"text": "The hostel rules are too strict and inflexible.",
|
165 |
+
"expected_emotion": "Frustration"
|
166 |
+
},
|
167 |
+
{
|
168 |
+
"grievance_id": "G12380",
|
169 |
+
"text": "The hostel provides a very safe environment.",
|
170 |
+
"expected_emotion": "Satisfaction"
|
171 |
+
},
|
172 |
+
{
|
173 |
+
"grievance_id": "G12381",
|
174 |
+
"text": "The room walls are too thin, and noise is a problem.",
|
175 |
+
"expected_emotion": "Frustration"
|
176 |
+
},
|
177 |
+
{
|
178 |
+
"grievance_id": "G12382",
|
179 |
+
"text": "The hostel has a very friendly community.",
|
180 |
+
"expected_emotion": "Satisfaction"
|
181 |
+
},
|
182 |
+
{
|
183 |
+
"grievance_id": "G12383",
|
184 |
+
"text": "The hostel Wi-Fi is often down during peak hours.",
|
185 |
+
"expected_emotion": "Frustration"
|
186 |
+
},
|
187 |
+
{
|
188 |
+
"grievance_id": "G12384",
|
189 |
+
"text": "The hostel provides excellent study facilities.",
|
190 |
+
"expected_emotion": "Satisfaction"
|
191 |
+
},
|
192 |
+
{
|
193 |
+
"grievance_id": "G12385",
|
194 |
+
"text": "The hostel's emergency response is very slow.",
|
195 |
+
"expected_emotion": "Frustration"
|
196 |
+
},
|
197 |
+
{
|
198 |
+
"grievance_id": "G12386",
|
199 |
+
"text": "The hostel has a great view of the city.",
|
200 |
+
"expected_emotion": "Satisfaction"
|
201 |
+
},
|
202 |
+
{
|
203 |
+
"grievance_id": "G12387",
|
204 |
+
"text": "The hostel's maintenance requests take too long to process.",
|
205 |
+
"expected_emotion": "Frustration"
|
206 |
+
},
|
207 |
+
{
|
208 |
+
"grievance_id": "G12388",
|
209 |
+
"text": "The hostel's cultural events are very enriching.",
|
210 |
+
"expected_emotion": "Satisfaction"
|
211 |
+
},
|
212 |
+
{
|
213 |
+
"grievance_id": "G12389",
|
214 |
+
"text": "The hostel's dining area is too small for all residents.",
|
215 |
+
"expected_emotion": "Frustration"
|
216 |
+
},
|
217 |
+
{
|
218 |
+
"grievance_id": "G12390",
|
219 |
+
"text": "The hostel's sports facilities are top-notch.",
|
220 |
+
"expected_emotion": "Satisfaction"
|
221 |
+
},
|
222 |
+
{
|
223 |
+
"grievance_id": "G12391",
|
224 |
+
"text": "The hostel's laundry machines are often out of order.",
|
225 |
+
"expected_emotion": "Frustration"
|
226 |
+
},
|
227 |
+
{
|
228 |
+
"grievance_id": "G12392",
|
229 |
+
"text": "The hostel's location is very peaceful and quiet.",
|
230 |
+
"expected_emotion": "Satisfaction"
|
231 |
+
},
|
232 |
+
{
|
233 |
+
"grievance_id": "G12393",
|
234 |
+
"text": "The hostel's fire drills are not conducted regularly.",
|
235 |
+
"expected_emotion": "Frustration"
|
236 |
+
},
|
237 |
+
{
|
238 |
+
"grievance_id": "G12394",
|
239 |
+
"text": "The hostel's common areas are very well-decorated.",
|
240 |
+
"expected_emotion": "Satisfaction"
|
241 |
+
},
|
242 |
+
{
|
243 |
+
"grievance_id": "G12395",
|
244 |
+
"text": "The hostel's check-in process is very cumbersome.",
|
245 |
+
"expected_emotion": "Frustration"
|
246 |
+
},
|
247 |
+
{
|
248 |
+
"grievance_id": "G12396",
|
249 |
+
"text": "The hostel's staff is very efficient and friendly.",
|
250 |
+
"expected_emotion": "Satisfaction"
|
251 |
+
},
|
252 |
+
{
|
253 |
+
"grievance_id": "G12397",
|
254 |
+
"text": "The hostel's maintenance team is not responsive.",
|
255 |
+
"expected_emotion": "Frustration"
|
256 |
+
},
|
257 |
+
{
|
258 |
+
"grievance_id": "G12398",
|
259 |
+
"text": "The hostel's environment is very conducive to studying.",
|
260 |
+
"expected_emotion": "Satisfaction"
|
261 |
+
},
|
262 |
+
{
|
263 |
+
"grievance_id": "G12399",
|
264 |
+
"text": "The hostel's food menu lacks variety.",
|
265 |
+
"expected_emotion": "Frustration"
|
266 |
+
},
|
267 |
+
{
|
268 |
+
"grievance_id": "G12400",
|
269 |
+
"text": "The hostel's management is very proactive.",
|
270 |
+
"expected_emotion": "Satisfaction"
|
271 |
+
},
|
272 |
+
{
|
273 |
+
"grievance_id": "G12401",
|
274 |
+
"text": "The hostel's water supply is often contaminated.",
|
275 |
+
"expected_emotion": "Frustration"
|
276 |
+
},
|
277 |
+
{
|
278 |
+
"grievance_id": "G12402",
|
279 |
+
"text": "The hostel's cultural diversity is very enriching.",
|
280 |
+
"expected_emotion": "Satisfaction"
|
281 |
+
},
|
282 |
+
{
|
283 |
+
"grievance_id": "G12403",
|
284 |
+
"text": "The hostel's room allocation process is very slow.",
|
285 |
+
"expected_emotion": "Frustration"
|
286 |
+
},
|
287 |
+
{
|
288 |
+
"grievance_id": "G12404",
|
289 |
+
"text": "The hostel's community events are very engaging.",
|
290 |
+
"expected_emotion": "Satisfaction"
|
291 |
+
},
|
292 |
+
{
|
293 |
+
"grievance_id": "G12405",
|
294 |
+
"text": "The hostel's maintenance requests are often ignored.",
|
295 |
+
"expected_emotion": "Frustration"
|
296 |
+
},
|
297 |
+
{
|
298 |
+
"grievance_id": "G12406",
|
299 |
+
"text": "The hostel's location is very convenient for shopping.",
|
300 |
+
"expected_emotion": "Satisfaction"
|
301 |
+
},
|
302 |
+
{
|
303 |
+
"grievance_id": "G12407",
|
304 |
+
"text": "The hostel's room cleaning is not thorough.",
|
305 |
+
"expected_emotion": "Frustration"
|
306 |
+
},
|
307 |
+
{
|
308 |
+
"grievance_id": "G12408",
|
309 |
+
"text": "The hostel's staff is very attentive to our needs.",
|
310 |
+
"expected_emotion": "Satisfaction"
|
311 |
+
},
|
312 |
+
{
|
313 |
+
"grievance_id": "G12409",
|
314 |
+
"text": "The hostel's Wi-Fi is often unreliable.",
|
315 |
+
"expected_emotion": "Frustration"
|
316 |
+
},
|
317 |
+
{
|
318 |
+
"grievance_id": "G12410",
|
319 |
+
"text": "The hostel's facilities are very modern and up-to-date.",
|
320 |
+
"expected_emotion": "Satisfaction"
|
321 |
+
},
|
322 |
+
{
|
323 |
+
"grievance_id": "G12411",
|
324 |
+
"text": "The hostel's maintenance team is very slow to respond.",
|
325 |
+
"expected_emotion": "Frustration"
|
326 |
+
},
|
327 |
+
{
|
328 |
+
"grievance_id": "G12412",
|
329 |
+
"text": "The hostel's environment is very welcoming.",
|
330 |
+
"expected_emotion": "Satisfaction"
|
331 |
+
},
|
332 |
+
{
|
333 |
+
"grievance_id": "G12413",
|
334 |
+
"text": "The hostel's dining area is often overcrowded.",
|
335 |
+
"expected_emotion": "Frustration"
|
336 |
+
},
|
337 |
+
{
|
338 |
+
"grievance_id": "G12414",
|
339 |
+
"text": "The hostel's recreational facilities are excellent.",
|
340 |
+
"expected_emotion": "Satisfaction"
|
341 |
+
},
|
342 |
+
{
|
343 |
+
"grievance_id": "G12415",
|
344 |
+
"text": "The hostel's laundry service is often delayed.",
|
345 |
+
"expected_emotion": "Frustration"
|
346 |
+
},
|
347 |
+
{
|
348 |
+
"grievance_id": "G12416",
|
349 |
+
"text": "The hostel's location is very scenic.",
|
350 |
+
"expected_emotion": "Satisfaction"
|
351 |
+
},
|
352 |
+
{
|
353 |
+
"grievance_id": "G12417",
|
354 |
+
"text": "The hostel's fire safety measures are inadequate.",
|
355 |
+
"expected_emotion": "Frustration"
|
356 |
+
},
|
357 |
+
{
|
358 |
+
"grievance_id": "G12418",
|
359 |
+
"text": "The hostel's common areas are very spacious.",
|
360 |
+
"expected_emotion": "Satisfaction"
|
361 |
+
},
|
362 |
+
{
|
363 |
+
"grievance_id": "G12419",
|
364 |
+
"text": "The hostel's check-out process is very tedious.",
|
365 |
+
"expected_emotion": "Frustration"
|
366 |
+
},
|
367 |
+
{
|
368 |
+
"grievance_id": "G12420",
|
369 |
+
"text": "The hostel's staff is very professional.",
|
370 |
+
"expected_emotion": "Satisfaction"
|
371 |
+
},
|
372 |
+
{
|
373 |
+
"grievance_id": "G12421",
|
374 |
+
"text": "The hostel's maintenance requests are often mishandled.",
|
375 |
+
"expected_emotion": "Frustration"
|
376 |
+
},
|
377 |
+
{
|
378 |
+
"grievance_id": "G12422",
|
379 |
+
"text": "The hostel's environment is very conducive to relaxation.",
|
380 |
+
"expected_emotion": "Satisfaction"
|
381 |
+
},
|
382 |
+
{
|
383 |
+
"grievance_id": "G12423",
|
384 |
+
"text": "The hostel's food quality is inconsistent.",
|
385 |
+
"expected_emotion": "Frustration"
|
386 |
+
},
|
387 |
+
{
|
388 |
+
"grievance_id": "G12424",
|
389 |
+
"text": "The hostel's management is very supportive.",
|
390 |
+
"expected_emotion": "Satisfaction"
|
391 |
+
},
|
392 |
+
{
|
393 |
+
"grievance_id": "G12425",
|
394 |
+
"text": "The hostel's water supply is often interrupted.",
|
395 |
+
"expected_emotion": "Frustration"
|
396 |
+
},
|
397 |
+
{
|
398 |
+
"grievance_id": "G12426",
|
399 |
+
"text": "The hostel's cultural events are very inclusive.",
|
400 |
+
"expected_emotion": "Satisfaction"
|
401 |
+
},
|
402 |
+
{
|
403 |
+
"grievance_id": "G12427",
|
404 |
+
"text": "The hostel's room allocation is often delayed.",
|
405 |
+
"expected_emotion": "Frustration"
|
406 |
+
},
|
407 |
+
{
|
408 |
+
"grievance_id": "G12428",
|
409 |
+
"text": "The hostel's community is very vibrant.",
|
410 |
+
"expected_emotion": "Satisfaction"
|
411 |
+
},
|
412 |
+
{
|
413 |
+
"grievance_id": "G12429",
|
414 |
+
"text": "The hostel's maintenance team is not efficient.",
|
415 |
+
"expected_emotion": "Frustration"
|
416 |
+
},
|
417 |
+
{
|
418 |
+
"grievance_id": "G12430",
|
419 |
+
"text": "The hostel's location is very convenient for public transport.",
|
420 |
+
"expected_emotion": "Satisfaction"
|
421 |
+
},
|
422 |
+
{
|
423 |
+
"grievance_id": "G12431",
|
424 |
+
"text": "The hostel's room cleaning is not up to standard.",
|
425 |
+
"expected_emotion": "Frustration"
|
426 |
+
},
|
427 |
+
{
|
428 |
+
"grievance_id": "G12432",
|
429 |
+
"text": "The hostel's staff is very accommodating.",
|
430 |
+
"expected_emotion": "Satisfaction"
|
431 |
+
},
|
432 |
+
{
|
433 |
+
"grievance_id": "G12433",
|
434 |
+
"text": "The hostel's Wi-Fi is often down.",
|
435 |
+
"expected_emotion": "Frustration"
|
436 |
+
},
|
437 |
+
{
|
438 |
+
"grievance_id": "G12434",
|
439 |
+
"text": "The hostel's facilities are very well-maintained.",
|
440 |
+
"expected_emotion": "Satisfaction"
|
441 |
+
},
|
442 |
+
{
|
443 |
+
"grievance_id": "G12435",
|
444 |
+
"text": "The hostel's maintenance team is very slow.",
|
445 |
+
"expected_emotion": "Frustration"
|
446 |
+
},
|
447 |
+
{
|
448 |
+
"grievance_id": "G12436",
|
449 |
+
"text": "The hostel's environment is very peaceful.",
|
450 |
+
"expected_emotion": "Satisfaction"
|
451 |
+
},
|
452 |
+
{
|
453 |
+
"grievance_id": "G12437",
|
454 |
+
"text": "The hostel's dining area is too small.",
|
455 |
+
"expected_emotion": "Frustration"
|
456 |
+
},
|
457 |
+
{
|
458 |
+
"grievance_id": "G12438",
|
459 |
+
"text": "The hostel's recreational facilities are very good.",
|
460 |
+
"expected_emotion": "Satisfaction"
|
461 |
+
},
|
462 |
+
{
|
463 |
+
"grievance_id": "G12439",
|
464 |
+
"text": "The hostel's laundry service is often late.",
|
465 |
+
"expected_emotion": "Frustration"
|
466 |
+
},
|
467 |
+
{
|
468 |
+
"grievance_id": "G12440",
|
469 |
+
"text": "The hostel's location is very beautiful.",
|
470 |
+
"expected_emotion": "Satisfaction"
|
471 |
+
},
|
472 |
+
{
|
473 |
+
"grievance_id": "G12441",
|
474 |
+
"text": "The hostel's fire safety is not adequate.",
|
475 |
+
"expected_emotion": "Frustration"
|
476 |
+
},
|
477 |
+
{
|
478 |
+
"grievance_id": "G12442",
|
479 |
+
"text": "The hostel's common areas are very nice.",
|
480 |
+
"expected_emotion": "Satisfaction"
|
481 |
+
},
|
482 |
+
{
|
483 |
+
"grievance_id": "G12443",
|
484 |
+
"text": "The hostel's check-out process is very slow.",
|
485 |
+
"expected_emotion": "Frustration"
|
486 |
+
},
|
487 |
+
{
|
488 |
+
"grievance_id": "G12444",
|
489 |
+
"text": "The hostel's staff is very helpful.",
|
490 |
+
"expected_emotion": "Satisfaction"
|
491 |
+
},
|
492 |
+
{
|
493 |
+
"grievance_id": "G12445",
|
494 |
+
"text": "The hostel's maintenance requests are often ignored.",
|
495 |
+
"expected_emotion": "Frustration"
|
496 |
+
},
|
497 |
+
{
|
498 |
+
"grievance_id": "G12446",
|
499 |
+
"text": "The hostel's environment is very relaxing.",
|
500 |
+
"expected_emotion": "Satisfaction"
|
501 |
+
},
|
502 |
+
{
|
503 |
+
"grievance_id": "G12447",
|
504 |
+
"text": "The hostel's food is not good.",
|
505 |
+
"expected_emotion": "Frustration"
|
506 |
+
},
|
507 |
+
{
|
508 |
+
"grievance_id": "G12448",
|
509 |
+
"text": "The hostel's management is very good.",
|
510 |
+
"expected_emotion": "Satisfaction"
|
511 |
+
},
|
512 |
+
{
|
513 |
+
"grievance_id": "G12449",
|
514 |
+
"text": "The hostel's water supply is not reliable.",
|
515 |
+
"expected_emotion": "Frustration"
|
516 |
+
},
|
517 |
+
{
|
518 |
+
"grievance_id": "G12450",
|
519 |
+
"text": "The hostel's cultural events are very good.",
|
520 |
+
"expected_emotion": "Satisfaction"
|
521 |
+
},
|
522 |
+
{
|
523 |
+
"grievance_id": "G12451",
|
524 |
+
"text": "The hostel's room allocation is not fast.",
|
525 |
+
"expected_emotion": "Frustration"
|
526 |
+
},
|
527 |
+
{
|
528 |
+
"grievance_id": "G12452",
|
529 |
+
"text": "The hostel's community is very good.",
|
530 |
+
"expected_emotion": "Satisfaction"
|
531 |
+
},
|
532 |
+
{
|
533 |
+
"grievance_id": "G12453",
|
534 |
+
"text": "The hostel's maintenance team is not fast.",
|
535 |
+
"expected_emotion": "Frustration"
|
536 |
+
},
|
537 |
+
{
|
538 |
+
"grievance_id": "G12454",
|
539 |
+
"text": "The hostel's location is very good.",
|
540 |
+
"expected_emotion": "Satisfaction"
|
541 |
+
},
|
542 |
+
{
|
543 |
+
"grievance_id": "G12455",
|
544 |
+
"text": "The hostel's room cleaning is not good.",
|
545 |
+
"expected_emotion": "Frustration"
|
546 |
+
},
|
547 |
+
{
|
548 |
+
"grievance_id": "G12456",
|
549 |
+
"text": "The hostel's staff is very good.",
|
550 |
+
"expected_emotion": "Satisfaction"
|
551 |
+
},
|
552 |
+
{
|
553 |
+
"grievance_id": "G12457",
|
554 |
+
"text": "The hostel's Wi-Fi is not good.",
|
555 |
+
"expected_emotion": "Frustration"
|
556 |
+
},
|
557 |
+
{
|
558 |
+
"grievance_id": "G12458",
|
559 |
+
"text": "The hostel's facilities are very good.",
|
560 |
+
"expected_emotion": "Satisfaction"
|
561 |
+
},
|
562 |
+
{
|
563 |
+
"grievance_id": "G12459",
|
564 |
+
"text": "The hostel's maintenance team is not good.",
|
565 |
+
"expected_emotion": "Frustration"
|
566 |
+
},
|
567 |
+
{
|
568 |
+
"grievance_id": "G12460",
|
569 |
+
"text": "The hostel's environment is very good.",
|
570 |
+
"expected_emotion": "Satisfaction"
|
571 |
+
},
|
572 |
+
{
|
573 |
+
"grievance_id": "G12461",
|
574 |
+
"text": "The hostel's dining area is not good.",
|
575 |
+
"expected_emotion": "Frustration"
|
576 |
+
},
|
577 |
+
{
|
578 |
+
"grievance_id": "G12462",
|
579 |
+
"text": "The hostel's recreational facilities are very good.",
|
580 |
+
"expected_emotion": "Satisfaction"
|
581 |
+
},
|
582 |
+
{
|
583 |
+
"grievance_id": "G12463",
|
584 |
+
"text": "The hostel's laundry service is not good.",
|
585 |
+
"expected_emotion": "Frustration"
|
586 |
+
},
|
587 |
+
{
|
588 |
+
"grievance_id": "G12464",
|
589 |
+
"text": "The hostel's location is very good.",
|
590 |
+
"expected_emotion": "Satisfaction"
|
591 |
+
},
|
592 |
+
{
|
593 |
+
"grievance_id": "G12465",
|
594 |
+
"text": "The hostel's fire safety is not good.",
|
595 |
+
"expected_emotion": "Frustration"
|
596 |
+
},
|
597 |
+
{
|
598 |
+
"grievance_id": "G12466",
|
599 |
+
"text": "The hostel's common areas are very good.",
|
600 |
+
"expected_emotion": "Satisfaction"
|
601 |
+
},
|
602 |
+
{
|
603 |
+
"grievance_id": "G12467",
|
604 |
+
"text": "The hostel's check-out process is not good.",
|
605 |
+
"expected_emotion": "Frustration"
|
606 |
+
},
|
607 |
+
{
|
608 |
+
"grievance_id": "G12468",
|
609 |
+
"text": "The hostel's staff is very good.",
|
610 |
+
"expected_emotion": "Satisfaction"
|
611 |
+
},
|
612 |
+
{
|
613 |
+
"grievance_id": "G12469",
|
614 |
+
"text": "The hostel's maintenance requests are not good.",
|
615 |
+
"expected_emotion": "Frustration"
|
616 |
+
},
|
617 |
+
{
|
618 |
+
"grievance_id": "G12470",
|
619 |
+
"text": "The hostel's environment is very good.",
|
620 |
+
"expected_emotion": "Satisfaction"
|
621 |
+
},
|
622 |
+
{
|
623 |
+
"grievance_id": "G12471",
|
624 |
+
"text": "The hostel's food is not good.",
|
625 |
+
"expected_emotion": "Frustration"
|
626 |
+
},
|
627 |
+
{
|
628 |
+
"grievance_id": "G12472",
|
629 |
+
"text": "The hostel's management is very good.",
|
630 |
+
"expected_emotion": "Satisfaction"
|
631 |
+
},
|
632 |
+
{
|
633 |
+
"grievance_id": "G12473",
|
634 |
+
"text": "The hostel's water supply is not good.",
|
635 |
+
"expected_emotion": "Frustration"
|
636 |
+
},
|
637 |
+
{
|
638 |
+
"grievance_id": "G12474",
|
639 |
+
"text": "The hostel's cultural events are very good.",
|
640 |
+
"expected_emotion": "Satisfaction"
|
641 |
+
},
|
642 |
+
{
|
643 |
+
"grievance_id": "G12475",
|
644 |
+
"text": "The hostel's room allocation is not good.",
|
645 |
+
"expected_emotion": "Frustration"
|
646 |
+
},
|
647 |
+
{
|
648 |
+
"grievance_id": "G12476",
|
649 |
+
"text": "The hostel's community is very good.",
|
650 |
+
"expected_emotion": "Satisfaction"
|
651 |
+
},
|
652 |
+
{
|
653 |
+
"grievance_id": "G12477",
|
654 |
+
"text": "The hostel's maintenance team is not good.",
|
655 |
+
"expected_emotion": "Frustration"
|
656 |
+
},
|
657 |
+
{
|
658 |
+
"grievance_id": "G12478",
|
659 |
+
"text": "The hostel's location is very good.",
|
660 |
+
"expected_emotion": "Satisfaction"
|
661 |
+
},
|
662 |
+
{
|
663 |
+
"grievance_id": "G12479",
|
664 |
+
"text": "The hostel's room cleaning is not good.",
|
665 |
+
"expected_emotion": "Frustration"
|
666 |
+
},
|
667 |
+
{
|
668 |
+
"grievance_id": "G12480",
|
669 |
+
"text": "The hostel's staff is very good.",
|
670 |
+
"expected_emotion": "Satisfaction"
|
671 |
+
},
|
672 |
+
{
|
673 |
+
"grievance_id": "G12481",
|
674 |
+
"text": "The hostel's Wi-Fi is not good.",
|
675 |
+
"expected_emotion": "Frustration"
|
676 |
+
},
|
677 |
+
{
|
678 |
+
"grievance_id": "G12482",
|
679 |
+
"text": "The hostel's facilities are very good.",
|
680 |
+
"expected_emotion": "Satisfaction"
|
681 |
+
},
|
682 |
+
{
|
683 |
+
"grievance_id": "G12483",
|
684 |
+
"text": "The hostel's maintenance team is not good.",
|
685 |
+
"expected_emotion": "Frustration"
|
686 |
+
},
|
687 |
+
{
|
688 |
+
"grievance_id": "G12484",
|
689 |
+
"text": "The hostel's environment is very good.",
|
690 |
+
"expected_emotion": "Satisfaction"
|
691 |
+
},
|
692 |
+
{
|
693 |
+
"grievance_id": "G12485",
|
694 |
+
"text": "The hostel's dining area is not good.",
|
695 |
+
"expected_emotion": "Frustration"
|
696 |
+
},
|
697 |
+
{
|
698 |
+
"grievance_id": "G12486",
|
699 |
+
"text": "The hostel's recreational facilities are very good.",
|
700 |
+
"expected_emotion": "Satisfaction"
|
701 |
+
},
|
702 |
+
{
|
703 |
+
"grievance_id": "G12487",
|
704 |
+
"text": "The hostel's laundry service is not good.",
|
705 |
+
"expected_emotion": "Frustration"
|
706 |
+
},
|
707 |
+
{
|
708 |
+
"grievance_id": "G12488",
|
709 |
+
"text": "The hostel's location is very good.",
|
710 |
+
"expected_emotion": "Satisfaction"
|
711 |
+
},
|
712 |
+
{
|
713 |
+
"grievance_id": "G12489",
|
714 |
+
"text": "The hostel's fire safety is not good.",
|
715 |
+
"expected_emotion": "Frustration"
|
716 |
+
},
|
717 |
+
{
|
718 |
+
"grievance_id": "G12490",
|
719 |
+
"text": "The hostel's common areas are very good.",
|
720 |
+
"expected_emotion": "Satisfaction"
|
721 |
+
},
|
722 |
+
{
|
723 |
+
"grievance_id": "G12491",
|
724 |
+
"text": "The hostel's check-out process is not good.",
|
725 |
+
"expected_emotion": "Frustration"
|
726 |
+
},
|
727 |
+
{
|
728 |
+
"grievance_id": "G12492",
|
729 |
+
"text": "The hostel's staff is very good.",
|
730 |
+
"expected_emotion": "Satisfaction"
|
731 |
+
},
|
732 |
+
{
|
733 |
+
"grievance_id": "G12493",
|
734 |
+
"text": "The hostel's maintenance requests are not good.",
|
735 |
+
"expected_emotion": "Frustration"
|
736 |
+
},
|
737 |
+
{
|
738 |
+
"grievance_id": "G12494",
|
739 |
+
"text": "The hostel's environment is very good.",
|
740 |
+
"expected_emotion": "Satisfaction"
|
741 |
+
},
|
742 |
+
{
|
743 |
+
"grievance_id": "G12495",
|
744 |
+
"text": "The hostel's food is not good.",
|
745 |
+
"expected_emotion": "Frustration"
|
746 |
+
},
|
747 |
+
{
|
748 |
+
"grievance_id": "G12496",
|
749 |
+
"text": "The hostel's management is very good.",
|
750 |
+
"expected_emotion": "Satisfaction"
|
751 |
+
},
|
752 |
+
{
|
753 |
+
"grievance_id": "G12497",
|
754 |
+
"text": "The hostel's water supply is not good.",
|
755 |
+
"expected_emotion": "Frustration"
|
756 |
+
},
|
757 |
+
{
|
758 |
+
"grievance_id": "G12498",
|
759 |
+
"text": "The hostel's cultural events are very good.",
|
760 |
+
"expected_emotion": "Satisfaction"
|
761 |
+
},
|
762 |
+
{
|
763 |
+
"grievance_id": "G12499",
|
764 |
+
"text": "The hostel's room allocation is not good.",
|
765 |
+
"expected_emotion": "Frustration"
|
766 |
+
},
|
767 |
+
{
|
768 |
+
"grievance_id": "G12500",
|
769 |
+
"text": "The hostel's community is very good.",
|
770 |
+
"expected_emotion": "Satisfaction"
|
771 |
+
}
|
772 |
+
]
|
773 |
+
|
models/sentiment_analysis/test_model.py
ADDED
@@ -0,0 +1,125 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
import json
|
2 |
+
import logging
|
3 |
+
from datetime import datetime
|
4 |
+
import os
|
5 |
+
from model import SentimentAnalysisModel
|
6 |
+
import time
|
7 |
+
|
8 |
+
# Configure logging
|
9 |
+
logging.basicConfig(
|
10 |
+
level=logging.INFO,
|
11 |
+
format='%(asctime)s - %(levelname)s - %(message)s',
|
12 |
+
handlers=[
|
13 |
+
logging.FileHandler('sentiment_analysis_testing.log'),
|
14 |
+
logging.StreamHandler()
|
15 |
+
]
|
16 |
+
)
|
17 |
+
|
18 |
+
logger = logging.getLogger(__name__)
|
19 |
+
|
20 |
+
class SentimentAnalysisTester:
|
21 |
+
def __init__(self):
|
22 |
+
self.model = SentimentAnalysisModel()
|
23 |
+
self.results_dir = 'models/sentiment_analysis/test_results'
|
24 |
+
self.test_data_path = 'models/sentiment_analysis/test_data/test_data.json'
|
25 |
+
os.makedirs(self.results_dir, exist_ok=True)
|
26 |
+
|
27 |
+
def load_test_cases(self):
|
28 |
+
"""Load test cases from JSON file"""
|
29 |
+
try:
|
30 |
+
with open(self.test_data_path, 'r') as f:
|
31 |
+
test_cases = json.load(f)
|
32 |
+
logger.info(f"Successfully loaded {len(test_cases)} test cases")
|
33 |
+
return test_cases
|
34 |
+
except Exception as e:
|
35 |
+
logger.error(f"Error loading test cases: {str(e)}", exc_info=True)
|
36 |
+
raise
|
37 |
+
|
38 |
+
def test_sample_grievances(self):
|
39 |
+
"""Test model with sample grievances"""
|
40 |
+
test_cases = self.load_test_cases()
|
41 |
+
results = []
|
42 |
+
|
43 |
+
for case in test_cases:
|
44 |
+
logger.info(f"\nTesting grievance {case['grievance_id']}")
|
45 |
+
logger.info(f"Text: {case['text']}")
|
46 |
+
|
47 |
+
result = self.model.process_grievance({
|
48 |
+
'grievance_id': case['grievance_id'],
|
49 |
+
'text': case['text']
|
50 |
+
})
|
51 |
+
|
52 |
+
# Add test-specific fields
|
53 |
+
result['expected_emotion'] = case['expected_emotion']
|
54 |
+
result['matches_expected'] = (
|
55 |
+
result.get('emotional_label') == case['expected_emotion']
|
56 |
+
)
|
57 |
+
|
58 |
+
# Log the result
|
59 |
+
logger.info(
|
60 |
+
f"Result: Expected={case['expected_emotion']}, "
|
61 |
+
f"Got={result.get('emotional_label', 'Unknown')}, "
|
62 |
+
f"Confidence={result.get('confidence', 0.0):.2f}"
|
63 |
+
)
|
64 |
+
|
65 |
+
if result.get('error'):
|
66 |
+
logger.warning(f"Error in result: {result['error']}")
|
67 |
+
|
68 |
+
results.append(result)
|
69 |
+
|
70 |
+
# Add a small delay between requests to avoid rate limiting
|
71 |
+
time.sleep(1)
|
72 |
+
|
73 |
+
return results
|
74 |
+
|
75 |
+
def run_full_test(self):
|
76 |
+
"""Run complete test suite"""
|
77 |
+
logger.info("Starting sentiment analysis testing")
|
78 |
+
|
79 |
+
try:
|
80 |
+
# Test sample grievances
|
81 |
+
results = self.test_sample_grievances()
|
82 |
+
|
83 |
+
# Calculate accuracy
|
84 |
+
correct = sum(1 for r in results if r.get('matches_expected', False))
|
85 |
+
accuracy = correct / len(results) if results else 0
|
86 |
+
|
87 |
+
# Prepare report
|
88 |
+
report = {
|
89 |
+
'test_timestamp': datetime.utcnow().isoformat(),
|
90 |
+
'accuracy': accuracy,
|
91 |
+
'total_tests': len(results),
|
92 |
+
'correct_predictions': correct,
|
93 |
+
'detailed_results': results
|
94 |
+
}
|
95 |
+
|
96 |
+
# Save report
|
97 |
+
report_path = f'{self.results_dir}/test_report.json'
|
98 |
+
with open(report_path, 'w') as f:
|
99 |
+
json.dump(report, f, indent=2)
|
100 |
+
|
101 |
+
logger.info(f"Testing completed. Results saved to {report_path}")
|
102 |
+
logger.info(f"Accuracy: {accuracy:.2%}")
|
103 |
+
|
104 |
+
return report
|
105 |
+
|
106 |
+
except Exception as e:
|
107 |
+
logger.error(f"Error during testing: {str(e)}", exc_info=True)
|
108 |
+
raise
|
109 |
+
|
110 |
+
def main():
|
111 |
+
try:
|
112 |
+
tester = SentimentAnalysisTester()
|
113 |
+
report = tester.run_full_test()
|
114 |
+
|
115 |
+
print("\nTest Results Summary:")
|
116 |
+
print(f"Accuracy: {report['accuracy']:.2%}")
|
117 |
+
print(f"Total Tests: {report['total_tests']}")
|
118 |
+
print(f"Correct Predictions: {report['correct_predictions']}")
|
119 |
+
|
120 |
+
except Exception as e:
|
121 |
+
logger.error(f"Error in main: {str(e)}", exc_info=True)
|
122 |
+
raise
|
123 |
+
|
124 |
+
if __name__ == "__main__":
|
125 |
+
main()
|
models/sentiment_analysis/train_data/__init__.py
ADDED
File without changes
|
models/sentiment_analysis/train_data/training_data.json
ADDED
@@ -0,0 +1,7 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
{
|
2 |
+
"data": [],
|
3 |
+
"metadata": {
|
4 |
+
"version": "1.0",
|
5 |
+
"created_at": "2024-03-20"
|
6 |
+
}
|
7 |
+
}
|
requirements.txt
ADDED
@@ -0,0 +1,37 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
# Web Framework
|
2 |
+
flask
|
3 |
+
flask-cors
|
4 |
+
gunicorn
|
5 |
+
uvicorn
|
6 |
+
|
7 |
+
# ML & Data Science
|
8 |
+
tensorflow
|
9 |
+
torch
|
10 |
+
transformers
|
11 |
+
scikit-learn
|
12 |
+
pandas
|
13 |
+
numpy
|
14 |
+
matplotlib
|
15 |
+
seaborn
|
16 |
+
|
17 |
+
# Translation
|
18 |
+
deep-translator
|
19 |
+
langdetect
|
20 |
+
|
21 |
+
# Authentication & API
|
22 |
+
python-jose
|
23 |
+
python-multipart
|
24 |
+
pydantic
|
25 |
+
|
26 |
+
# Testing
|
27 |
+
pytest
|
28 |
+
requests
|
29 |
+
|
30 |
+
# Environment & Utils
|
31 |
+
python-dotenv
|
32 |
+
|
33 |
+
# Additional from file_context_0
|
34 |
+
gradio
|
35 |
+
protobuf
|
36 |
+
sentencepiece
|
37 |
+
streamlit
|
routes.py
ADDED
@@ -0,0 +1,21 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
from models.multilingual_translation.model import MultilingualTranslationModel
|
2 |
+
from models.sentiment_analysis.model import SentimentAnalysisModel
|
3 |
+
from models.intelligent_routing.model import IntelligentRoutingModel
|
4 |
+
from models.job_recommendation.model import JobRecommendationModel
|
5 |
+
import logging
|
6 |
+
from datetime import datetime
|
7 |
+
|
8 |
+
logger = logging.getLogger(__name__)
|
9 |
+
|
10 |
+
# Initialize models
|
11 |
+
translation_model = MultilingualTranslationModel()
|
12 |
+
sentiment_model = SentimentAnalysisModel()
|
13 |
+
routing_model = IntelligentRoutingModel()
|
14 |
+
job_model = JobRecommendationModel()
|
15 |
+
|
16 |
+
# Load models
|
17 |
+
try:
|
18 |
+
routing_model.load_model('models/intelligent_routing/saved_model/model.keras')
|
19 |
+
job_model.load_model('models/job_recommendation/saved_model/model.keras')
|
20 |
+
except Exception as e:
|
21 |
+
logger.error(f"Error loading models: {str(e)}")
|
space.yml
ADDED
@@ -0,0 +1,7 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
title: Hostel Management System
|
2 |
+
emoji: 🏨
|
3 |
+
colorFrom: blue
|
4 |
+
colorTo: green
|
5 |
+
sdk: streamlit
|
6 |
+
app_file: app.py
|
7 |
+
pinned: false
|
test_endpoints.py
ADDED
@@ -0,0 +1,437 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
import requests
|
2 |
+
import json
|
3 |
+
import logging
|
4 |
+
from datetime import datetime
|
5 |
+
import time
|
6 |
+
import os
|
7 |
+
import sys
|
8 |
+
|
9 |
+
# Configure logging
|
10 |
+
logging.basicConfig(
|
11 |
+
level=logging.INFO,
|
12 |
+
format='%(asctime)s - %(levelname)s - %(message)s',
|
13 |
+
handlers=[
|
14 |
+
logging.FileHandler('endpoint_testing.log', encoding='utf-8'),
|
15 |
+
logging.StreamHandler()
|
16 |
+
]
|
17 |
+
)
|
18 |
+
|
19 |
+
logger = logging.getLogger(__name__)
|
20 |
+
|
21 |
+
class EndpointTester:
|
22 |
+
def __init__(self, base_url='https://huggingface.co/spaces/ArchCoder/Hostel-Management-and-Greivance-Redressal-System'):
|
23 |
+
self.base_url = base_url
|
24 |
+
self.results_dir = 'test_results1'
|
25 |
+
# Create results directory if it doesn't exist
|
26 |
+
os.makedirs(self.results_dir, exist_ok=True)
|
27 |
+
|
28 |
+
def test_translation_endpoint(self):
|
29 |
+
"""Test the translation endpoint"""
|
30 |
+
endpoint = f'{self.base_url}/translate'
|
31 |
+
test_cases = [
|
32 |
+
{
|
33 |
+
"user_message": "toilet me paani nahi aa rha hain",
|
34 |
+
"target_language": "en"
|
35 |
+
},
|
36 |
+
{
|
37 |
+
"user_message": "AC not working properly",
|
38 |
+
"target_language": "hi"
|
39 |
+
},
|
40 |
+
{
|
41 |
+
"user_message": "ਪੱਖਾ ਕੰਮ ਨਹੀਂ ਕਰ ਰਿਹਾ",
|
42 |
+
"target_language": "en"
|
43 |
+
}
|
44 |
+
]
|
45 |
+
|
46 |
+
results = []
|
47 |
+
for case in test_cases:
|
48 |
+
logger.info(f"\nTesting translation endpoint:")
|
49 |
+
logger.info(f"Input: {case}")
|
50 |
+
|
51 |
+
try:
|
52 |
+
response = requests.post(endpoint, json=case)
|
53 |
+
result = response.json()
|
54 |
+
|
55 |
+
logger.info(f"Status Code: {response.status_code}")
|
56 |
+
logger.info(f"Response: {result}")
|
57 |
+
|
58 |
+
results.append({
|
59 |
+
'test_case': case,
|
60 |
+
'status_code': response.status_code,
|
61 |
+
'response': result
|
62 |
+
})
|
63 |
+
|
64 |
+
except Exception as e:
|
65 |
+
logger.error(f"Error testing translation: {str(e)}")
|
66 |
+
|
67 |
+
time.sleep(1) # Rate limiting
|
68 |
+
|
69 |
+
return results
|
70 |
+
|
71 |
+
def test_sentiment_analysis_endpoint(self):
|
72 |
+
"""Test the sentiment analysis endpoint"""
|
73 |
+
endpoint = f'{self.base_url}/analyze-sentiment'
|
74 |
+
test_cases = [
|
75 |
+
{
|
76 |
+
"grievance_id": "G12347",
|
77 |
+
"text": "I am extremely frustrated with the constant power outages in my room."
|
78 |
+
},
|
79 |
+
{
|
80 |
+
"grievance_id": "G12348",
|
81 |
+
"text": "Thank you for quickly fixing the water issue."
|
82 |
+
},
|
83 |
+
{
|
84 |
+
"grievance_id": "G12349",
|
85 |
+
"text": "The AC has been making strange noises all night."
|
86 |
+
}
|
87 |
+
]
|
88 |
+
|
89 |
+
results = []
|
90 |
+
for case in test_cases:
|
91 |
+
logger.info(f"\nTesting sentiment analysis endpoint:")
|
92 |
+
logger.info(f"Input: {case}")
|
93 |
+
|
94 |
+
try:
|
95 |
+
response = requests.post(endpoint, json=case)
|
96 |
+
result = response.json()
|
97 |
+
|
98 |
+
logger.info(f"Status Code: {response.status_code}")
|
99 |
+
logger.info(f"Response: {result}")
|
100 |
+
|
101 |
+
results.append({
|
102 |
+
'test_case': case,
|
103 |
+
'status_code': response.status_code,
|
104 |
+
'response': result
|
105 |
+
})
|
106 |
+
|
107 |
+
except Exception as e:
|
108 |
+
logger.error(f"Error testing sentiment analysis: {str(e)}")
|
109 |
+
|
110 |
+
time.sleep(1)
|
111 |
+
|
112 |
+
return results
|
113 |
+
|
114 |
+
def test_routing_endpoint(self):
|
115 |
+
"""Test the grievance routing endpoint"""
|
116 |
+
endpoint = f'{self.base_url}/route-grievance'
|
117 |
+
test_cases = [
|
118 |
+
{
|
119 |
+
"grievance_id": "G67890",
|
120 |
+
"category": "water_cooler",
|
121 |
+
"submission_timestamp": "2024-10-28T04:22:13Z",
|
122 |
+
"student_room_no": "148",
|
123 |
+
"hostel_name": "bh2",
|
124 |
+
"floor_number": 3,
|
125 |
+
"current_staff_status": [
|
126 |
+
{
|
127 |
+
"staff_id": "S84148",
|
128 |
+
"department": "water_cooler",
|
129 |
+
"current_workload": 0,
|
130 |
+
"availability_status": "Unavailable",
|
131 |
+
"past_resolution_rate": 0.98
|
132 |
+
},
|
133 |
+
{
|
134 |
+
"staff_id": "S57369",
|
135 |
+
"department": "water_cooler",
|
136 |
+
"current_workload": 0,
|
137 |
+
"availability_status": "Available",
|
138 |
+
"past_resolution_rate": 0.96
|
139 |
+
}
|
140 |
+
],
|
141 |
+
"floor_metrics": {
|
142 |
+
"number_of_requests": 0,
|
143 |
+
"total_delays": 4
|
144 |
+
},
|
145 |
+
"availability_data": {
|
146 |
+
"staff_availability": [
|
147 |
+
{
|
148 |
+
"staff_id": "S84148",
|
149 |
+
"time_slot": "08:00-12:00",
|
150 |
+
"availability_status": "Available"
|
151 |
+
}
|
152 |
+
],
|
153 |
+
"student_availability": [
|
154 |
+
{
|
155 |
+
"student_id": "STU200",
|
156 |
+
"time_slot": "16:00-20:00",
|
157 |
+
"availability_status": "Available"
|
158 |
+
}
|
159 |
+
]
|
160 |
+
}
|
161 |
+
},
|
162 |
+
{
|
163 |
+
"grievance_id": "G67891",
|
164 |
+
"category": "carpenter",
|
165 |
+
"submission_timestamp": "2024-10-28T04:18:13Z",
|
166 |
+
"student_room_no": "213",
|
167 |
+
"hostel_name": "bh1",
|
168 |
+
"floor_number": 2,
|
169 |
+
"current_staff_status": [
|
170 |
+
{
|
171 |
+
"staff_id": "S52775",
|
172 |
+
"department": "carpenter",
|
173 |
+
"current_workload": 5,
|
174 |
+
"availability_status": "Unavailable",
|
175 |
+
"past_resolution_rate": 0.98
|
176 |
+
},
|
177 |
+
{
|
178 |
+
"staff_id": "S24943",
|
179 |
+
"department": "carpenter",
|
180 |
+
"current_workload": 3,
|
181 |
+
"availability_status": "Unavailable",
|
182 |
+
"past_resolution_rate": 0.85
|
183 |
+
}
|
184 |
+
],
|
185 |
+
"floor_metrics": {
|
186 |
+
"number_of_requests": 29,
|
187 |
+
"total_delays": 4
|
188 |
+
},
|
189 |
+
"availability_data": {
|
190 |
+
"staff_availability": [
|
191 |
+
{
|
192 |
+
"staff_id": "S52775",
|
193 |
+
"time_slot": "12:00-16:00",
|
194 |
+
"availability_status": "Unavailable"
|
195 |
+
}
|
196 |
+
],
|
197 |
+
"student_availability": [
|
198 |
+
{
|
199 |
+
"student_id": "STU201",
|
200 |
+
"time_slot": "08:00-12:00",
|
201 |
+
"availability_status": "Available"
|
202 |
+
}
|
203 |
+
]
|
204 |
+
}
|
205 |
+
},
|
206 |
+
{
|
207 |
+
"grievance_id": "G67892",
|
208 |
+
"category": "electricity",
|
209 |
+
"submission_timestamp": "2024-10-28T04:00:13Z",
|
210 |
+
"student_room_no": "275",
|
211 |
+
"hostel_name": "bh3",
|
212 |
+
"floor_number": 2,
|
213 |
+
"current_staff_status": [
|
214 |
+
{
|
215 |
+
"staff_id": "S33368",
|
216 |
+
"department": "electricity",
|
217 |
+
"current_workload": 1,
|
218 |
+
"availability_status": "Available",
|
219 |
+
"past_resolution_rate": 0.95
|
220 |
+
},
|
221 |
+
{
|
222 |
+
"staff_id": "S20522",
|
223 |
+
"department": "electricity",
|
224 |
+
"current_workload": 5,
|
225 |
+
"availability_status": "Available",
|
226 |
+
"past_resolution_rate": 0.87
|
227 |
+
}
|
228 |
+
],
|
229 |
+
"floor_metrics": {
|
230 |
+
"number_of_requests": 2,
|
231 |
+
"total_delays": 3
|
232 |
+
},
|
233 |
+
"availability_data": {
|
234 |
+
"staff_availability": [
|
235 |
+
{
|
236 |
+
"staff_id": "S33368",
|
237 |
+
"time_slot": "12:00-16:00",
|
238 |
+
"availability_status": "Unavailable"
|
239 |
+
}
|
240 |
+
],
|
241 |
+
"student_availability": [
|
242 |
+
{
|
243 |
+
"student_id": "STU202",
|
244 |
+
"time_slot": "08:00-12:00",
|
245 |
+
"availability_status": "Unavailable"
|
246 |
+
}
|
247 |
+
]
|
248 |
+
}
|
249 |
+
}
|
250 |
+
]
|
251 |
+
|
252 |
+
results = []
|
253 |
+
for case in test_cases:
|
254 |
+
logger.info(f"\nTesting routing endpoint:")
|
255 |
+
logger.info(f"Input: {case}")
|
256 |
+
|
257 |
+
try:
|
258 |
+
response = requests.post(endpoint, json=case)
|
259 |
+
result = response.json()
|
260 |
+
|
261 |
+
logger.info(f"Status Code: {response.status_code}")
|
262 |
+
logger.info(f"Response: {result}")
|
263 |
+
|
264 |
+
results.append({
|
265 |
+
'test_case': case,
|
266 |
+
'status_code': response.status_code,
|
267 |
+
'response': result
|
268 |
+
})
|
269 |
+
|
270 |
+
except Exception as e:
|
271 |
+
logger.error(f"Error testing routing: {str(e)}")
|
272 |
+
|
273 |
+
time.sleep(1)
|
274 |
+
|
275 |
+
return results
|
276 |
+
|
277 |
+
def test_job_recommendation_endpoint(self):
|
278 |
+
"""Test the job recommendation endpoint"""
|
279 |
+
endpoint = f'{self.base_url}/recommend-job'
|
280 |
+
test_cases = [
|
281 |
+
{
|
282 |
+
"job_id": "J60000",
|
283 |
+
"type": "IT",
|
284 |
+
"description": "IT issue in room 358.",
|
285 |
+
"urgency_level": "Low",
|
286 |
+
"location": {
|
287 |
+
"hostel_name": "Hostel B",
|
288 |
+
"floor_number": 3,
|
289 |
+
"room_number": "358"
|
290 |
+
},
|
291 |
+
"workers": [
|
292 |
+
{
|
293 |
+
"worker_id": "W97053",
|
294 |
+
"department": "IT",
|
295 |
+
"current_workload": 3,
|
296 |
+
"availability_status": "Available",
|
297 |
+
"job_success_rate": 0.95,
|
298 |
+
"current_location": {
|
299 |
+
"hostel_name": "Hostel A",
|
300 |
+
"floor_number": 3,
|
301 |
+
"room_number": "468"
|
302 |
+
}
|
303 |
+
},
|
304 |
+
{
|
305 |
+
"worker_id": "W97054",
|
306 |
+
"department": "IT",
|
307 |
+
"current_workload": 1,
|
308 |
+
"availability_status": "Available",
|
309 |
+
"job_success_rate": 0.92,
|
310 |
+
"current_location": {
|
311 |
+
"hostel_name": "Hostel B",
|
312 |
+
"floor_number": 3,
|
313 |
+
"room_number": "360"
|
314 |
+
}
|
315 |
+
}
|
316 |
+
]
|
317 |
+
}
|
318 |
+
]
|
319 |
+
|
320 |
+
results = []
|
321 |
+
for case in test_cases:
|
322 |
+
logger.info(f"\nTesting job recommendation endpoint:")
|
323 |
+
logger.info(f"Input: {case}")
|
324 |
+
|
325 |
+
try:
|
326 |
+
response = requests.post(endpoint, json=case)
|
327 |
+
result = response.json()
|
328 |
+
|
329 |
+
logger.info(f"Status Code: {response.status_code}")
|
330 |
+
logger.info(f"Response: {result}")
|
331 |
+
|
332 |
+
results.append({
|
333 |
+
'test_case': case,
|
334 |
+
'status_code': response.status_code,
|
335 |
+
'response': result
|
336 |
+
})
|
337 |
+
|
338 |
+
except Exception as e:
|
339 |
+
logger.error(f"Error testing job recommendation: {str(e)}")
|
340 |
+
|
341 |
+
time.sleep(1)
|
342 |
+
|
343 |
+
return results
|
344 |
+
|
345 |
+
def test_health_endpoint(self):
|
346 |
+
"""Test the health check endpoint"""
|
347 |
+
endpoint = f'{self.base_url}/health'
|
348 |
+
|
349 |
+
try:
|
350 |
+
response = requests.get(endpoint)
|
351 |
+
result = response.json()
|
352 |
+
|
353 |
+
logger.info("\nTesting health endpoint:")
|
354 |
+
logger.info(f"Status Code: {response.status_code}")
|
355 |
+
logger.info(f"Response: {result}")
|
356 |
+
|
357 |
+
return {
|
358 |
+
'status_code': response.status_code,
|
359 |
+
'response': result
|
360 |
+
}
|
361 |
+
|
362 |
+
except Exception as e:
|
363 |
+
logger.error(f"Error testing health endpoint: {str(e)}")
|
364 |
+
return None
|
365 |
+
|
366 |
+
def run_all_tests(self):
|
367 |
+
"""Run all endpoint tests"""
|
368 |
+
try:
|
369 |
+
# Test health endpoint first
|
370 |
+
health_result = self.test_health_endpoint()
|
371 |
+
if not health_result or health_result['status_code'] != 200:
|
372 |
+
logger.error("Health check failed. Skipping other tests.")
|
373 |
+
return
|
374 |
+
|
375 |
+
# Run all tests
|
376 |
+
results = {
|
377 |
+
'timestamp': datetime.utcnow().isoformat(),
|
378 |
+
'health_check': health_result,
|
379 |
+
'translation_tests': self.test_translation_endpoint(),
|
380 |
+
'sentiment_analysis_tests': self.test_sentiment_analysis_endpoint(),
|
381 |
+
'routing_tests': self.test_routing_endpoint(),
|
382 |
+
'job_recommendation_tests': self.test_job_recommendation_endpoint()
|
383 |
+
}
|
384 |
+
|
385 |
+
# Save results
|
386 |
+
try:
|
387 |
+
results_file = os.path.join(self.results_dir, 'endpoint_test_results.json')
|
388 |
+
with open(results_file, 'w', encoding='utf-8') as f:
|
389 |
+
json.dump(results, f, indent=2, ensure_ascii=False)
|
390 |
+
logger.info(f"Test results saved to {results_file}")
|
391 |
+
except Exception as e:
|
392 |
+
logger.error(f"Error saving results: {str(e)}")
|
393 |
+
# Continue execution even if saving fails
|
394 |
+
|
395 |
+
logger.info("All tests completed successfully")
|
396 |
+
return results
|
397 |
+
|
398 |
+
except Exception as e:
|
399 |
+
logger.error(f"Error running tests: {str(e)}")
|
400 |
+
return {
|
401 |
+
'timestamp': datetime.utcnow().isoformat(),
|
402 |
+
'error': str(e),
|
403 |
+
'completed_tests': []
|
404 |
+
}
|
405 |
+
|
406 |
+
def main():
|
407 |
+
try:
|
408 |
+
tester = EndpointTester()
|
409 |
+
results = tester.run_all_tests()
|
410 |
+
|
411 |
+
if not results:
|
412 |
+
logger.error("No test results available")
|
413 |
+
return
|
414 |
+
|
415 |
+
# Print summary
|
416 |
+
print("\nTest Results Summary:")
|
417 |
+
for test_type, test_results in results.items():
|
418 |
+
if test_type in ['timestamp', 'error']:
|
419 |
+
continue
|
420 |
+
|
421 |
+
print(f"\n{test_type.replace('_', ' ').title()}:")
|
422 |
+
if isinstance(test_results, list):
|
423 |
+
success = sum(1 for r in test_results if r['status_code'] == 200)
|
424 |
+
total = len(test_results)
|
425 |
+
print(f"Total: {total}")
|
426 |
+
print(f"Successful: {success}")
|
427 |
+
print(f"Failed: {total - success}")
|
428 |
+
else:
|
429 |
+
status = test_results.get('status_code') == 200 if test_results else False
|
430 |
+
print(f"Status: {'Success' if status else 'Failed'}")
|
431 |
+
|
432 |
+
except Exception as e:
|
433 |
+
logger.error(f"Error in main: {str(e)}")
|
434 |
+
raise
|
435 |
+
|
436 |
+
if __name__ == "__main__":
|
437 |
+
main()
|
test_results1/endpoint_test_results.json
ADDED
@@ -0,0 +1,157 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
{
|
2 |
+
"timestamp": "2024-10-28T18:28:04.957085",
|
3 |
+
"health_check": {
|
4 |
+
"status_code": 200,
|
5 |
+
"response": {
|
6 |
+
"services": {
|
7 |
+
"intelligent_routing": "up",
|
8 |
+
"job_recommendation": "up",
|
9 |
+
"sentiment_analysis": "up",
|
10 |
+
"translation": "up"
|
11 |
+
},
|
12 |
+
"status": "healthy",
|
13 |
+
"timestamp": "2024-10-28T18:28:01.846113"
|
14 |
+
}
|
15 |
+
},
|
16 |
+
"translation_tests": [
|
17 |
+
{
|
18 |
+
"test_case": {
|
19 |
+
"user_message": "toilet me paani nahi aa rha hain",
|
20 |
+
"target_language": "en"
|
21 |
+
},
|
22 |
+
"status_code": 200,
|
23 |
+
"response": {
|
24 |
+
"confidence": 0.9,
|
25 |
+
"error": null,
|
26 |
+
"language_name": "English",
|
27 |
+
"original_message": "toilet me paani nahi aa rha hain",
|
28 |
+
"source_language": "hi",
|
29 |
+
"target_language": "en",
|
30 |
+
"timestamp": "2024-10-28T18:28:02.381673",
|
31 |
+
"translated_message": "There is no water coming in the toilet"
|
32 |
+
}
|
33 |
+
},
|
34 |
+
{
|
35 |
+
"test_case": {
|
36 |
+
"user_message": "AC not working properly",
|
37 |
+
"target_language": "hi"
|
38 |
+
},
|
39 |
+
"status_code": 200,
|
40 |
+
"response": {
|
41 |
+
"confidence": 0.9,
|
42 |
+
"error": null,
|
43 |
+
"language_name": "Hindi",
|
44 |
+
"original_message": "AC not working properly",
|
45 |
+
"source_language": "af",
|
46 |
+
"target_language": "hi",
|
47 |
+
"timestamp": "2024-10-28T18:28:09.334685",
|
48 |
+
"translated_message": "एसी ठीक से काम नहीं कर रहा है"
|
49 |
+
}
|
50 |
+
},
|
51 |
+
{
|
52 |
+
"test_case": {
|
53 |
+
"user_message": "ਪੱਖਾ ਕੰਮ ਨਹੀਂ ਕਰ ਰਿਹਾ",
|
54 |
+
"target_language": "en"
|
55 |
+
},
|
56 |
+
"status_code": 200,
|
57 |
+
"response": {
|
58 |
+
"confidence": 0.9,
|
59 |
+
"error": null,
|
60 |
+
"language_name": "English",
|
61 |
+
"original_message": "ਪੱਖਾ ਕੰਮ ਨਹੀਂ ਕਰ ਰਿਹਾ",
|
62 |
+
"source_language": "pa",
|
63 |
+
"target_language": "en",
|
64 |
+
"timestamp": "2024-10-28T18:28:10.832359",
|
65 |
+
"translated_message": "The fan is not working"
|
66 |
+
}
|
67 |
+
}
|
68 |
+
],
|
69 |
+
"sentiment_analysis_tests": [
|
70 |
+
{
|
71 |
+
"test_case": {
|
72 |
+
"grievance_id": "G12347",
|
73 |
+
"text": "I am extremely frustrated with the constant power outages in my room."
|
74 |
+
},
|
75 |
+
"status_code": 200,
|
76 |
+
"response": {
|
77 |
+
"confidence": 0.98044353723526,
|
78 |
+
"emotional_label": "Frustration",
|
79 |
+
"grievance_id": "G12347",
|
80 |
+
"timestamp": "2024-10-28T18:28:12.376193"
|
81 |
+
}
|
82 |
+
},
|
83 |
+
{
|
84 |
+
"test_case": {
|
85 |
+
"grievance_id": "G12348",
|
86 |
+
"text": "Thank you for quickly fixing the water issue."
|
87 |
+
},
|
88 |
+
"status_code": 200,
|
89 |
+
"response": {
|
90 |
+
"confidence": 0.938926100730896,
|
91 |
+
"emotional_label": "Satisfaction",
|
92 |
+
"grievance_id": "G12348",
|
93 |
+
"timestamp": "2024-10-28T18:28:13.784609"
|
94 |
+
}
|
95 |
+
},
|
96 |
+
{
|
97 |
+
"test_case": {
|
98 |
+
"grievance_id": "G12349",
|
99 |
+
"text": "The AC has been making strange noises all night."
|
100 |
+
},
|
101 |
+
"status_code": 200,
|
102 |
+
"response": {
|
103 |
+
"confidence": 0.8782024383544922,
|
104 |
+
"emotional_label": "Frustration",
|
105 |
+
"grievance_id": "G12349",
|
106 |
+
"timestamp": "2024-10-28T18:28:15.172750"
|
107 |
+
}
|
108 |
+
}
|
109 |
+
],
|
110 |
+
"routing_tests": [],
|
111 |
+
"job_recommendation_tests": [
|
112 |
+
{
|
113 |
+
"test_case": {
|
114 |
+
"job_id": "J60000",
|
115 |
+
"type": "IT",
|
116 |
+
"description": "IT issue in room 358.",
|
117 |
+
"urgency_level": "Low",
|
118 |
+
"location": {
|
119 |
+
"hostel_name": "Hostel B",
|
120 |
+
"floor_number": 3,
|
121 |
+
"room_number": "358"
|
122 |
+
},
|
123 |
+
"workers": [
|
124 |
+
{
|
125 |
+
"worker_id": "W97053",
|
126 |
+
"department": "IT",
|
127 |
+
"current_workload": 3,
|
128 |
+
"availability_status": "Available",
|
129 |
+
"job_success_rate": 0.95,
|
130 |
+
"current_location": {
|
131 |
+
"hostel_name": "Hostel A",
|
132 |
+
"floor_number": 3,
|
133 |
+
"room_number": "468"
|
134 |
+
}
|
135 |
+
},
|
136 |
+
{
|
137 |
+
"worker_id": "W97054",
|
138 |
+
"department": "IT",
|
139 |
+
"current_workload": 1,
|
140 |
+
"availability_status": "Available",
|
141 |
+
"job_success_rate": 0.92,
|
142 |
+
"current_location": {
|
143 |
+
"hostel_name": "Hostel B",
|
144 |
+
"floor_number": 3,
|
145 |
+
"room_number": "360"
|
146 |
+
}
|
147 |
+
}
|
148 |
+
]
|
149 |
+
},
|
150 |
+
"status_code": 500,
|
151 |
+
"response": {
|
152 |
+
"details": "hour must be in 0..23",
|
153 |
+
"error": "Internal server error"
|
154 |
+
}
|
155 |
+
}
|
156 |
+
]
|
157 |
+
}
|
utils/__init__.py
ADDED
@@ -0,0 +1,2 @@
|
|
|
|
|
|
|
1 |
+
from .logger import setup_logger, get_logger
|
2 |
+
|
utils/dir_str_creater.py
ADDED
@@ -0,0 +1,35 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
import os
|
2 |
+
|
3 |
+
def print_directory_structure(startpath, exclude_dirs=None, indent=''):
|
4 |
+
if exclude_dirs is None:
|
5 |
+
exclude_dirs = ['myenv', '__pycache__']
|
6 |
+
|
7 |
+
# Get list of items in directory
|
8 |
+
try:
|
9 |
+
items = os.listdir(startpath)
|
10 |
+
except PermissionError:
|
11 |
+
return
|
12 |
+
|
13 |
+
# Sort items to show directories first, then files
|
14 |
+
items.sort(key=lambda x: (not os.path.isdir(os.path.join(startpath, x)), x))
|
15 |
+
|
16 |
+
for item in items:
|
17 |
+
path = os.path.join(startpath, item)
|
18 |
+
|
19 |
+
# Skip excluded directories
|
20 |
+
if os.path.isdir(path) and item in exclude_dirs:
|
21 |
+
continue
|
22 |
+
|
23 |
+
if os.path.isdir(path):
|
24 |
+
print(f'{indent}📁 {item}')
|
25 |
+
print_directory_structure(path, exclude_dirs, indent + ' ')
|
26 |
+
else:
|
27 |
+
print(f'{indent}📄 {item}')
|
28 |
+
|
29 |
+
if __name__ == '__main__':
|
30 |
+
# You can modify the start path and excluded directories here
|
31 |
+
start_path = '.' # Current directory
|
32 |
+
excluded_directories = ['myenv', 'node_modules', '__pycache__', '.git'] # Added .git
|
33 |
+
|
34 |
+
print('Directory Structure:')
|
35 |
+
print_directory_structure(start_path, excluded_directories)
|
utils/logger.py
ADDED
@@ -0,0 +1,30 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
import logging
|
2 |
+
import sys
|
3 |
+
from logging.handlers import RotatingFileHandler
|
4 |
+
|
5 |
+
def setup_logger(log_level, log_format):
|
6 |
+
"""Configure application logging"""
|
7 |
+
# Create logger
|
8 |
+
logger = logging.getLogger()
|
9 |
+
logger.setLevel(log_level)
|
10 |
+
|
11 |
+
# Create console handler with formatting
|
12 |
+
console_handler = logging.StreamHandler(sys.stdout)
|
13 |
+
console_handler.setFormatter(logging.Formatter(log_format))
|
14 |
+
logger.addHandler(console_handler)
|
15 |
+
|
16 |
+
# Create file handler with formatting
|
17 |
+
file_handler = RotatingFileHandler(
|
18 |
+
'app.log',
|
19 |
+
maxBytes=10000000, # 10MB
|
20 |
+
backupCount=5
|
21 |
+
)
|
22 |
+
file_handler.setFormatter(logging.Formatter(log_format))
|
23 |
+
logger.addHandler(file_handler)
|
24 |
+
|
25 |
+
return logger
|
26 |
+
|
27 |
+
def get_logger(name):
|
28 |
+
"""Get logger instance for a specific module"""
|
29 |
+
return logging.getLogger(name)
|
30 |
+
|