flaskbot / ai_chatbot.py
markobinario's picture
Update ai_chatbot.py
d1aea16 verified
raw
history blame
6.52 kB
import requests
import json
from sentence_transformers import SentenceTransformer
import numpy as np
from sklearn.metrics.pairwise import cosine_similarity
from recommender import CourseRecommender
class Chatbot:
def __init__(self):
self.qa_pairs = []
self.question_embeddings = []
self.model = SentenceTransformer('all-MiniLM-L6-v2')
self.database_url = "https://database-46m3.onrender.com"
self.recommender = CourseRecommender()
self.load_qa_data()
def load_qa_data(self):
"""Load Q&A pairs from the faqs table in the database"""
try:
# Connect to the faqs table endpoint
faqs_url = f"{self.database_url}/faqs"
response = requests.get(faqs_url)
if response.status_code == 200:
data = response.json()
# Assuming the database returns a list of FAQ objects
if isinstance(data, list):
self.qa_pairs = data
else:
# If it's a single object, wrap it in a list
self.qa_pairs = [data]
# Generate embeddings for all questions
questions = [item.get('question', '') for item in self.qa_pairs]
self.question_embeddings = self.model.encode(questions)
print(f"Loaded {len(self.qa_pairs)} FAQ pairs from database")
else:
print(f"Failed to load data from faqs table. Status code: {response.status_code}")
self._load_fallback_data()
except Exception as e:
print(f"Error loading FAQ data: {str(e)}")
self._load_fallback_data()
def _load_fallback_data(self):
"""Load fallback data if database is unavailable"""
self.qa_pairs = [
{"question": "What is artificial intelligence?", "answer": "Artificial Intelligence (AI) is a branch of computer science that aims to create machines capable of intelligent behavior."},
{"question": "How does machine learning work?", "answer": "Machine learning is a subset of AI that enables computers to learn and improve from experience without being explicitly programmed."},
{"question": "What is deep learning?", "answer": "Deep learning is a subset of machine learning that uses neural networks with multiple layers to model and understand complex patterns in data."},
{"question": "What is natural language processing?", "answer": "Natural Language Processing (NLP) is a field of AI that focuses on the interaction between computers and humans through natural language."},
{"question": "What is a neural network?", "answer": "A neural network is a computing system inspired by biological neural networks that constitute animal brains. It consists of interconnected nodes (neurons) that process information."}
]
questions = [item['question'] for item in self.qa_pairs]
self.question_embeddings = self.model.encode(questions)
print("Loaded fallback Q&A data")
def find_best_match(self, user_input, threshold=0.7):
"""Find the best matching question using semantic similarity"""
if not self.qa_pairs:
return None, 0
# Encode the user input
user_embedding = self.model.encode([user_input])
# Calculate cosine similarity with all questions
similarities = cosine_similarity(user_embedding, self.question_embeddings)[0]
# Find the best match
best_match_idx = np.argmax(similarities)
best_similarity = similarities[best_match_idx]
if best_similarity >= threshold:
return self.qa_pairs[best_match_idx], best_similarity
else:
return None, best_similarity
def get_response(self, user_input):
"""Get response for user input"""
if not user_input.strip():
return "Please enter a message."
best_match, similarity = self.find_best_match(user_input)
if best_match:
return {
'answer': best_match.get('answer', 'No answer found'),
'confidence': float(similarity),
'matched_question': best_match.get('question', ''),
'status': 'success'
}
else:
return {
'answer': "I'm sorry, I couldn't find a relevant answer to your question. Could you please rephrase it or ask something else?",
'confidence': float(similarity),
'matched_question': '',
'status': 'no_match'
}
def get_qa_count(self):
"""Get the number of loaded Q&A pairs"""
return len(self.qa_pairs)
def get_course_recommendations(self, stanine, gwa, strand, hobbies):
"""Get course recommendations using the recommender system"""
try:
# Validate inputs
stanine = int(stanine) if isinstance(stanine, str) else stanine
gwa = float(gwa) if isinstance(gwa, str) else gwa
if not (1 <= stanine <= 9):
return "❌ Stanine score must be between 1 and 9"
if not (75 <= gwa <= 100):
return "❌ GWA must be between 75 and 100"
if not strand:
return "❌ Please select a strand"
if not hobbies or not str(hobbies).strip():
return "❌ Please enter your hobbies/interests"
# Get recommendations
recommendations = self.recommender.recommend_courses(
stanine=stanine,
gwa=gwa,
strand=strand,
hobbies=str(hobbies)
)
if not recommendations:
return "No recommendations available at the moment."
# Format response (without confidence scores)
response = f"## 🎯 Course Recommendations for You\n\n"
response += f"**Profile:** Stanine {stanine}, GWA {gwa}, {strand} Strand\n"
response += f"**Interests:** {hobbies}\n\n"
for i, rec in enumerate(recommendations, 1):
response += f"### {i}. {rec['code']} - {rec['name']}\n\n"
return response
except Exception as e:
return f"❌ Error getting recommendations: {str(e)}"