Bnava13's picture
Update app.py
1207d3b verified
Raw
History Blame Contribute Delete
5.03 kB
import pandas as pd
import difflib
from sklearn.feature_extraction.text import TfidfVectorizer
from sklearn.metrics.pairwise import cosine_similarity
import gradio as gr
import numpy as np
# Load the data
def load_data():
try:
data = pd.read_csv('games_march2025_cleaned.csv', nrows=20000, on_bad_lines='skip', engine='python')
return data
except Exception as e:
print(f"Error loading data: {e}")
return None
# Prepare the feature vectors for similarity calculation
def prepare_features(data):
selected_features = ['genres', 'price', 'average_playtime_2weeks', 'tags']
for feature in selected_features:
data[feature] = data[feature].fillna('')
combined_features = (
data['genres'] + ' ' +
data['price'].astype(str) + ' ' +
data['average_playtime_2weeks'].astype(str) + ' ' +
data['tags'].astype(str)
)
vectorizer = TfidfVectorizer()
feature_vectors = vectorizer.fit_transform(combined_features)
return feature_vectors
# Function to get game recommendations
def get_recommendations(game_name, data, feature_vectors):
titles = data['name'].tolist()
close_matches = difflib.get_close_matches(game_name, titles)
if not close_matches:
print(f"Couldn't find a close match for: '{game_name}'")
return "No match found. Try typing a more complete or accurate title."
match = close_matches[0]
print(f"Using closest match: {match}")
game_idx = data[data['name'] == match].index[0]
similarity = cosine_similarity(feature_vectors)
scores = list(enumerate(similarity[game_idx]))
similar_games = sorted(scores, key=lambda x: x[1], reverse=True)
html = ""
for i, (idx, score) in enumerate(similar_games[1:10], 1): # skip the first one (it's the same game)
game = data.loc[idx]
name = game['name']
desc = game['short_description'] or "No description provided."
if len(desc) > 180:
desc = desc[:180] + "..."
img = game.get('header_image', '') or ""
# Detect supported platforms
platforms = []
if game.get('windows') == 1:
platforms.append('Windows')
if game.get('mac') == 1:
platforms.append('Mac')
if game.get('linux') == 1:
platforms.append('Linux')
platforms_str = ", ".join(platforms) if platforms else "Unknown"
price = game['price']
meta_score = game.get('metacritic_score')
meta_display = int(meta_score) if pd.notnull(meta_score) else "N/A"
pos = game.get('positive', 0)
neg = game.get('negative', 0)
total = pos + neg
pos_pct = f"{(pos / total * 100):.1f}%" if total > 0 else "N/A"
# Build the card HTML
html += f'''
<div style="display:flex; margin-bottom:16px;">
<img src="{img}" width="130" style="margin-right:12px; border-radius:4px;">
<div>
<h4>{i}. {name}</h4>
<p><b>Platforms:</b> {platforms_str}</p>
<p><b>Price:</b> ${price}</p>
<p><b>Metacritic:</b> {meta_display}</p>
<p><b>Positive Reviews:</b> {pos_pct}</p>
<p>{desc}</p>
</div>
</div>
<hr>
'''
return html
# Gradio interface function
def recommend_games(game_name, max_age, max_price, min_metacritic):
data = load_data()
if data is None:
return "Failed to load data."
# Apply filters BEFORE feature preparation
data = data[
(data['required_age'] <= max_age) &
(data['price'] <= max_price) &
((data['metacritic_score'].fillna(0) >= min_metacritic) | data['metacritic_score'].isna())
].reset_index(drop=True)
if data.empty:
return "No games found."
feature_vectors = prepare_features(data)
recommendations_html = get_recommendations(game_name, data, feature_vectors)
return recommendations_html
# Create the Gradio interface
with gr.Blocks(title="Steam Game Recommender") as demo:
gr.Markdown("Steam Game Recommender")
gr.Markdown("Enter a game you like and customize filters to get similar suggestions.")
with gr.Row():
input_text = gr.Textbox(label="Input Steam Game")
with gr.Row():
max_age_slider = gr.Slider(0, 21, value=17, label="Max Age Rating (Avoid Adult Games)")
max_price_slider = gr.Slider(0.0, 100.0, value=60.0, step=0.5, label="Maximum Price ($)")
min_metacritic_slider = gr.Slider(0, 100, value=50, step=1, label="Minimum Metacritic Score")
with gr.Row():
submit_btn = gr.Button("Get Recommendations")
with gr.Row():
output_text = gr.Markdown(label="Recommendations")
submit_btn.click(
fn=recommend_games,
inputs=[input_text, max_age_slider, max_price_slider, min_metacritic_slider],
outputs=output_text
)
# Launch the app
if __name__ == "__main__":
demo.launch()