File size: 4,054 Bytes
1f24680
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
# ==============================
# Explainable Recommendation System
# Group 15 Project
# ==============================

import os
import json
import numpy as np
from fastapi import FastAPI
from pydantic import BaseModel
from sklearn.metrics.pairwise import cosine_similarity
from openai import OpenAI

# ------------------------------
# Initialize OpenAI client
# ------------------------------
client = OpenAI(api_key=os.getenv("OPENAI_API_KEY"))

# ------------------------------
# Small Local Dataset
# ------------------------------
dataset = [
    {
        "id": 1,
        "title": "Introduction to Machine Learning",
        "description": "Learn supervised and unsupervised learning, regression, and classification.",
        "tags": ["machine learning", "ai", "beginner"]
    },
    {
        "id": 2,
        "title": "Deep Learning with Neural Networks",
        "description": "Advanced deep learning concepts including CNNs and RNNs.",
        "tags": ["deep learning", "neural networks", "ai"]
    },
    {
        "id": 3,
        "title": "Data Science with Python",
        "description": "Data analysis, visualization, and machine learning using Python.",
        "tags": ["python", "data science"]
    },
    {
        "id": 4,
        "title": "Natural Language Processing",
        "description": "Text processing, embeddings, and transformer models.",
        "tags": ["nlp", "transformers", "ai"]
    }
]

# ------------------------------
# Generate Embedding
# ------------------------------
def get_embedding(text: str):
    response = client.embeddings.create(
        model="text-embedding-3-small",
        input=text
    )
    return np.array(response.data[0].embedding)

# ------------------------------
# Precompute Dataset Embeddings
# ------------------------------
for item in dataset:
    combined_text = (
        item["title"] + " " +
        item["description"] + " " +
        " ".join(item["tags"])
    )
    item["embedding"] = get_embedding(combined_text)

# ------------------------------
# Recommendation Function
# ------------------------------
def recommend(user_query: str, top_k: int = 2):
    query_embedding = get_embedding(user_query)

    similarities = []
    for item in dataset:
        score = cosine_similarity(
            [query_embedding],
            [item["embedding"]]
        )[0][0]
        similarities.append((item, score))

    similarities.sort(key=lambda x: x[1], reverse=True)
    return similarities[:top_k]

# ------------------------------
# LLM Explanation Function
# ------------------------------
def generate_explanation(user_query, recommended_items):

    items_text = "\n".join([
        f"- {item['title']}: {item['description']}"
        for item, score in recommended_items
    ])

    prompt = f"""
User interest: {user_query}

Recommended items:
{items_text}

Explain clearly why these recommendations match the user's interest.
Make it personalized and easy to understand.
"""

    response = client.chat.completions.create(
        model="gpt-4o-mini",
        messages=[{"role": "user", "content": prompt}]
    )

    return response.choices[0].message.content

# ------------------------------
# FastAPI App
# ------------------------------
app = FastAPI(title="Explainable Recommendation System")

class QueryRequest(BaseModel):
    user_query: str

@app.post("/recommend")
def get_recommendation(request: QueryRequest):

    recommended = recommend(request.user_query)
    explanation = generate_explanation(request.user_query, recommended)

    return {
        "query": request.user_query,
        "recommendations": [
            {
                "title": item["title"],
                "description": item["description"],
                "score": float(score)
            }
            for item, score in recommended
        ],
        "explanation": explanation
    }

# ------------------------------
# Root Endpoint
# ------------------------------
@app.get("/")
def home():
    return {"message": "Explainable Recommendation System is running 🚀"}