File size: 5,004 Bytes
111fffd
 
86624d4
 
47b2831
 
86624d4
2b50b7d
47b2831
d37e92f
2b50b7d
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
 
 
 
 
 
 
 
 
47b2831
d99d2fc
47b2831
 
0995083
dbeda2b
 
0afde79
 
 
d99d2fc
0afde79
dbeda2b
56eaf29
0995083
56eaf29
47b2831
243bf9f
47b2831
243bf9f
1ac06e8
ee10bed
47b2831
dbeda2b
 
56eaf29
111fffd
0995083
aa642f2
ee10bed
56eaf29
 
d99d2fc
56eaf29
 
dbeda2b
56eaf29
 
dbeda2b
56eaf29
47b2831
ee10bed
d99d2fc
243bf9f
d37e92f
abaa7f5
47b2831
d37e92f
2b50b7d
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
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):
    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."
    
    # 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()