File size: 5,214 Bytes
111fffd
 
86624d4
 
47b2831
 
86624d4
47b2831
 
d37e92f
47b2831
dbeda2b
d37e92f
 
 
47b2831
6cfc78d
47b2831
 
56eaf29
47b2831
 
 
 
 
 
 
 
56eaf29
47b2831
d4cf16c
47b2831
 
d4cf16c
47b2831
 
 
 
 
 
6a655a9
47b2831
 
d4cf16c
47b2831
 
d37e92f
47b2831
 
 
243bf9f
 
 
dbeda2b
 
47b2831
243bf9f
 
 
47b2831
243bf9f
6a655a9
243bf9f
47b2831
243bf9f
6a655a9
243bf9f
 
dbeda2b
243bf9f
 
 
 
 
 
dbeda2b
243bf9f
 
 
 
dbeda2b
243bf9f
 
dbeda2b
243bf9f
 
 
 
 
 
 
 
 
dbeda2b
47b2831
dbeda2b
47b2831
 
 
dbeda2b
 
56eaf29
 
 
dbeda2b
56eaf29
dbeda2b
56eaf29
 
 
47b2831
243bf9f
47b2831
243bf9f
1ac06e8
18879d7
ee10bed
47b2831
dbeda2b
 
56eaf29
111fffd
dbeda2b
aa642f2
ee10bed
56eaf29
 
dbeda2b
56eaf29
 
dbeda2b
56eaf29
 
dbeda2b
56eaf29
47b2831
ee10bed
dbeda2b
243bf9f
d37e92f
abaa7f5
dbeda2b
47b2831
d37e92f
 
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
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 - when deploying, adjust the path to where your dataset will be stored
def load_data():
    try:
        # For Hugging Face Spaces deployment, you might need to adjust this path
        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):
    list_of_all_titles = data['name'].tolist()
    find_close_match = difflib.get_close_matches(game_name, list_of_all_titles)
    
    if not find_close_match:
        return "No match found for the game name. Please try another title."
    
    closest_match = find_close_match[0]
    index_of_the_game = data.loc[data['name'] == closest_match].index[0]
    
    game_similarity = cosine_similarity(feature_vectors)
    similarity_scores = list(enumerate(game_similarity[index_of_the_game]))
    sorted_similar_games = sorted(similarity_scores, key=lambda x: x[1], reverse=True)

    result_html = ""

    for i, game in enumerate(sorted_similar_games[1:10], 1):
        index = game[0]
        name = data.loc[index, 'name']
        about = data.loc[index, 'short_description'] or "No description available"
        image_url = data.loc[index, 'header_image'] or ""

        platforms = []
        if data.loc[index, 'windows'] == 1:
            platforms.append("Windows")
        if data.loc[index, 'mac'] == 1:
            platforms.append("Mac")
        if data.loc[index, 'linux'] == 1:
            platforms.append("Linux")
        platforms_str = ", ".join(platforms) or "Unknown"

        metacritic = data.loc[index, 'metacritic_score']
        price = data.loc[index, 'price']
        pos = data.loc[index, 'positive']
        neg = data.loc[index, 'negative']
        total_reviews = pos + neg
        pos_ratio = f"{(pos / total_reviews * 100):.1f}%" if total_reviews > 0 else "N/A"

        # Combine into HTML
        result_html += f"""
        <div style="display:flex; align-items:flex-start; margin-bottom:20px;">
            <img src="{image_url}" style="width:150px; height:auto; margin-right:15px; border-radius:8px;">
            <div>
                <h3>{i}. {name}</h3>
                <p><b>Platforms:</b> {platforms_str}</p>
                <p><b>Price:</b> ${price}</p>
                <p><b>Metacritic Score:</b> {metacritic if pd.notnull(metacritic) else "N/A"}</p>
                <p><b>Positive Reviews:</b> {pos_ratio}</p>
                <p>{about}</p>
            </div>
        </div>
        <hr>
        """

    return result_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. Please check the data file."
    
    # 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 matching your filter criteria."

    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="Favorite 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()