Spaces:
Sleeping
Sleeping
File size: 5,026 Bytes
8268d5c 2008a9e 8268d5c 6241033 8268d5c 1207d3b 8268d5c 1207d3b 8268d5c 1207d3b 8268d5c 1207d3b 8268d5c 1207d3b 8268d5c 1207d3b 8268d5c 1207d3b 8268d5c 1207d3b 8268d5c 2008a9e 8268d5c 2008a9e 6241033 2008a9e 8268d5c 2008a9e 8268d5c 2008a9e 6241033 2008a9e 8268d5c 6241033 2008a9e 8268d5c 2008a9e 8268d5c | 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 147 148 149 150 | 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() |