boardgamereco / app.py
marcogallen's picture
Created dict for results
9884400
raw
history blame
5.4 kB
import pandas as pd
import numpy as np
from dotenv import load_dotenv
#from keras.src.backend.jax.random import categorical
from langchain_community.document_loaders import TextLoader #Transforms raw text into data langchain can work on
from langchain_text_splitters import CharacterTextSplitter # Breaks the text into chunks
from langchain_openai import OpenAIEmbeddings #Convert chunks into document embeddings
from langchain_chroma import Chroma # Import into vector database Chroma is one type of vector database opensource
import gradio as gr
load_dotenv()
#Chroma persistance store
# import chromadb
# client = chromadb.PersistentClient()
board_games = pd.read_csv('board_games_data_clean.csv')
raw_documents = TextLoader("tagged_descriptions.txt").load()
text_splitter = CharacterTextSplitter(chunk_size=0, chunk_overlap=0, separator="\n")
documents = text_splitter.split_documents(raw_documents)
db_boardgames = Chroma.from_documents(documents, embedding=OpenAIEmbeddings())
def retrive_semantic_recomendations(
query: str,
min_players: str = None,
max_players: str = None,
game_type: str = None,
initial_top_k: int = 50,
final_top_k: int = 16
) -> pd.DataFrame:
recs = db_boardgames.similarity_search(query, k=initial_top_k)
#print(len(recs))
game_list = [int(rec.page_content.strip('"').split()[0]) for rec in recs]
game_recs = board_games[board_games["id"].isin(game_list)]
#print(len(game_recs))
if min_players!= "All":
game_recs = game_recs[game_recs["min_players"] == min_players][:final_top_k]
else:
game_recs = game_recs.head(final_top_k)
if max_players!= "All":
game_recs = game_recs[game_recs["max_players"] == max_players][:final_top_k]
else:
game_recs = game_recs.head(final_top_k)
if game_type != "All":
game_recs = game_recs[game_recs["type"] == game_type][:final_top_k]
else:
game_recs = game_recs.head(final_top_k)
return game_recs
def recommend_games(
query: str,
min_players: str = None,
max_players: str = None,
game_type: str = None,
):
recommendations = retrive_semantic_recomendations(query, min_players, max_players, game_type)
results = []
for _, row in recommendations.iterrows():
description = row["description"]
truncated_desc_split = description.split()
truncated_description = " ".join(truncated_desc_split[:30]) + "..."
designers_split = row["designers_list"].split("|")
if len(designers_split) == 2:
designers_str = f"{designers_split[0]} {designers_split[1]}"
elif len(designers_split) > 2:
designers_str = f"{','.join(designers_split[:-1])} and {designers_split[-1]}"
else:
designers_str = row["designers_list"]
#caption = f"{row['name']} by {designers_str} for {row['players']} players. Type: {row['type']} Rating: {row['rating']}\n {truncated_description}"
# caption = {
# "name":row['name'],
# "designers":designers_str,
# "players":row['players'],
# "type": row['type'],
# "rating":row['rating'],
# "small_description": truncated_description,
# "description": description,
# "thumbnail":row["thumbnail_url"]
# }
caption = f"{row['name']}|{designers_str}|{row['players']}|{row['type']}|{row['rating']}|{truncated_description}|{description}"
results.append((row["thumbnail_url"],caption)) #"cover-not-found.jpg"
# results.append(caption) #"cover-not-found.jpg"
#print(len(results))
return results
# min_players = ["All"] + sorted(board_games["min_players"].unique())
# max_players = ["All"] + sorted(board_games["max_players"].unique())
game_types = ["All"] + sorted(board_games["type"].unique())
with gr.Blocks(theme = gr.themes.Glass()) as demo:
gr.Markdown("# Semantic Boardgame recommender")
with gr.Row():
user_query = gr.TextArea(label="Please enter a description of a game:",
placeholder="e.g., A game about empire building set in space")
with gr.Row():
with gr.Column(scale=1, min_width=300):
min_players_dropdown = gr.Dropdown(choices=["All","1","2","3","4","5","6","7","8"], label="Select min number of players", value="All")
max_players_dropdown = gr.Dropdown(choices=["All","1","2","3","4","5","6","7","8","9","10"], label="Select max number of players", value="All")
#min_players_dropdown = gr.Dropdown(choices=min_players, label="Select min number of players", value="All")
#max_players_dropdown = gr.Dropdown(choices=max_players, label="Select max number of players", value="All")
with gr.Column(scale=2, min_width=300):
type_dropdown = gr.Dropdown(choices=game_types, label="Select a type of game", value="All")
with gr.Row():
submit_button = gr.Button("Find recommendations")
with gr.Row():
gr.Markdown("## Recommendations")
with gr.Row():
output = gr.Gallery(label="Recommendations", columns=8, rows=2)
submit_button.click(fn=recommend_games, inputs=[user_query, min_players_dropdown, max_players_dropdown,type_dropdown], outputs=output)
if __name__ == "__main__":
demo.launch()