Skip to content
 
 

Repository files navigation

FlavorMatrix — Board Game Recommender

A Flask + React app that suggests board games using classical IR and LLM-powered query enhancement, with transparent explanations of why each game was recommended.

Features

  • TF-IDF cosine similarity — baseline keyword retrieval
  • Truncated SVD (LSA) — latent semantic retrieval that captures themes beyond exact keywords
  • AI query rewriting — an LLM rewrites your query based on the latent dimensions it activates, surfacing games you might not have thought to search for
  • AI summary — after both searches run, the LLM writes a unified narrative: which themes fired, top picks from each search, and one overall recommendation
  • Free-text queries — e.g. strategic medieval war game with no dice
  • Seed-title recommendations — pick a game and get semantically similar games
  • Combined input — seed game + clarifying details (e.g. similar to Catan, but shorter and card-based)
  • Latent dimension explainability — every result shows which SVD themes drove the match

Stack

Layer Tech
Backend Flask, Flask-SQLAlchemy
Frontend React + TypeScript + Vite
IR / ML scikit-learn (TfidfVectorizer, TruncatedSVD)
LLM Spark API (infosci_spark_client)
Data SQLite (data/database.sqlite)

How It Works

  1. User provides a seed game, a text query, or both.
  2. The backend projects the input into TF-IDF and SVD spaces and returns the top-K games by cosine similarity (standard results).
  3. If SPARK_API_KEY is set, the top activated SVD dimensions are fed to the LLM, which rewrites the query to focus on the most semantically relevant vocabulary. The rewritten query runs through the same retrieval pipeline (AI-enhanced results).
  4. A second LLM call synthesises both result sets into a plain-English summary with bullet-pointed top picks and an overall recommendation.

Project Structure

FlavorMatrix/
├── src/
│   ├── app.py
│   ├── routes.py
│   ├── models.py
│   └── services/
│       ├── index_store.py
│       ├── ir.py
│       └── query_rewriter.py   # rewrite_query + generate_summary
├── scripts/
│   └── build_indices.py
├── frontend/
│   └── src/
│       ├── App.tsx             # SummaryPanel + two-column results
│       ├── App.css
│       ├── Landing.tsx
│       └── types.ts
├── data/
│   ├── database.sqlite         # not tracked in git (too large)
│   └── artifacts/              # generated by build_indices.py
├── requirements.txt
└── README.md

Setup

1. Python dependencies

python3 -m venv venv
source venv/bin/activate
pip install -r requirements.txt

2. Build retrieval artifacts

python3 scripts/build_indices.py

Generates under data/artifacts/: tfidf_matrix.npz, tfidf_vectorizer.pkl, svd_model.pkl, svd_embeddings.npy, games.json, game_ids.json, svd_top_terms.json

3. Frontend

cd frontend
npm install
npm run build
cd ..

4. Run

python3 src/app.py

Open http://localhost:5001.

5. Enable LLM features (optional)

Set SPARK_API_KEY in your environment before starting the server. Without it the app runs standard IR only and the AI summary and rewritten query are skipped.

export SPARK_API_KEY=your_key_here
python3 src/app.py

API

Endpoint Method Description
/api/config GET Returns {"use_llm": bool}
/api/games/search?q= GET Autocomplete game title search
/api/recommendations GET Standard IR results (q, seed, method, k)
/api/rag GET Standard + AI-enhanced results + LLM summary
/api/latent-dimensions GET Corpus-wide SVD dimension stats
/api/games/dimensions?id= GET Top SVD dimensions for a specific game
/api/metrics GET Cached evaluation metrics + feedback score
/api/feedback POST Record thumbs-up/down on a result

/api/rag response shape

{
  "original_label": "Similar to Catan + details",
  "original_dims": [...],
  "original_results": [...],
  "rewritten_query": "resource trading card game fast settlement building",
  "rewritten_dims": [...],
  "rag_results": [...],
  "llm_summary": "Your search activated themes of resource trading...",
  "error": null
}

Data Filters

Games included in the index:

  • type = 'boardgame'
  • users_rated > 50

Combined text field: description + boardgamecategory + boardgamemechanic (HTML-unescaped, whitespace-normalised).

NPM Scripts (from repo root)

npm run build         # builds frontend
npm run start         # starts Flask server
npm run prepare-data  # runs build_indices.py

Notes

  • data/database.sqlite is git-ignored (exceeds GitHub's file size limit). Rebuild artifacts from a local copy of the database before deploying.
  • The AI summary makes two sequential LLM calls per query (rewrite + summary). Expect ~2–4 s added latency when SPARK_API_KEY is set.

About

Board game recommender project, final for CS 4300

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages