Bnava13 commited on
Commit
8268d5c
ยท
verified ยท
1 Parent(s): 9e12919

Create app.py

Browse files
Files changed (1) hide show
  1. app.py +169 -0
app.py ADDED
@@ -0,0 +1,169 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import pandas as pd
2
+ import difflib
3
+ from sklearn.feature_extraction.text import TfidfVectorizer
4
+ from sklearn.metrics.pairwise import cosine_similarity
5
+ import gradio as gr
6
+ import numpy as np
7
+
8
+ # Load the data - when deploying, adjust the path to where your dataset will be stored
9
+ def load_data():
10
+ try:
11
+ # For Hugging Face Spaces deployment, you might need to adjust this path
12
+ data = pd.read_csv('games_march2025_cleaned.csv', nrows=88899, on_bad_lines='skip', engine='python')
13
+ return data
14
+ except Exception as e:
15
+ print(f"Error loading data: {e}")
16
+ return None
17
+
18
+ # Prepare the feature vectors for similarity calculation
19
+ def prepare_features(data):
20
+ selected_features = ['genres', 'price', 'average_playtime_2weeks', 'tags']
21
+
22
+ for feature in selected_features:
23
+ data[feature] = data[feature].fillna('')
24
+
25
+ combined_features = (
26
+ data['genres'] + ' ' +
27
+ data['price'].astype(str) + ' ' +
28
+ data['average_playtime_2weeks'].astype(str) + ' ' +
29
+ data['tags'].astype(str)
30
+ )
31
+
32
+ vectorizer = TfidfVectorizer()
33
+ feature_vectors = vectorizer.fit_transform(combined_features)
34
+
35
+ return feature_vectors
36
+
37
+ # Function to get game recommendations
38
+ def get_recommendations(game_name, data, feature_vectors):
39
+ list_of_all_titles = data['name'].tolist()
40
+ find_close_match = difflib.get_close_matches(game_name, list_of_all_titles)
41
+
42
+ if not find_close_match:
43
+ return "No match found for the game name. Please try another title."
44
+
45
+ closest_match = find_close_match[0]
46
+ index_of_the_game = data.loc[data['name'] == closest_match].index[0]
47
+
48
+ game_similarity = cosine_similarity(feature_vectors)
49
+ similarity_scores = list(enumerate(game_similarity[index_of_the_game]))
50
+ sorted_similar_games = sorted(similarity_scores, key=lambda x: x[1], reverse=True)
51
+
52
+ result_html = ""
53
+
54
+ for i, (index, score) in enumerate(sorted_similar_games[1:10], 1):
55
+ name = data.loc[index, 'name']
56
+ about = data.loc[index, 'short_description'] or "No description available"
57
+ image_url = data.loc[index, 'header_image'] or ""
58
+
59
+ platforms = []
60
+ if data.loc[index, 'windows'] == 1:
61
+ platforms.append("Windows")
62
+ if data.loc[index, 'mac'] == 1:
63
+ platforms.append("Mac")
64
+ if data.loc[index, 'linux'] == 1:
65
+ platforms.append("Linux")
66
+ platforms_str = ", ".join(platforms) or "Unknown"
67
+
68
+ price = data.loc[index, 'price']
69
+ pos = data.loc[index, 'positive']
70
+ neg = data.loc[index, 'negative']
71
+ total_reviews = pos + neg
72
+ pos_ratio = f"{(pos / total_reviews * 100):.1f}%" if total_reviews > 0 else "N/A"
73
+
74
+ result_html += f"""
75
+ <div style="display:flex; align-items:flex-start; margin-bottom:20px;">
76
+ <img src="{image_url}" style="width:150px; height:auto; margin-right:15px; border-radius:8px;">
77
+ <div>
78
+ <h3>{i}. {name} <small>(Similarity: {score:.2f})</small></h3>
79
+ <p><b>Platforms:</b> {platforms_str}</p>
80
+ <p><b>Price:</b> ${price}</p>
81
+ <p><b>Positive Reviews:</b> {pos_ratio}</p>
82
+ <p>{about}</p>
83
+ </div>
84
+ </div>
85
+ <hr>
86
+ """
87
+
88
+ return result_html
89
+
90
+ # Gradio interface function
91
+ def recommend_games(game_name, max_age, max_price, min_pos_neg_ratio):
92
+ data = load_data()
93
+ if data is None:
94
+ return "Failed to load data. Please check the data file."
95
+
96
+ # Fill NA values to avoid division errors
97
+ data['positive'] = data['positive'].fillna(0)
98
+ data['negative'] = data['negative'].fillna(0)
99
+
100
+ # Calculate the positive-to-negative ratio (avoid division by zero)
101
+ data['pos_neg_ratio'] = data.apply(
102
+ lambda row: (row['positive'] / row['negative']) if row['negative'] > 0 else row['positive'],
103
+ axis=1
104
+ )
105
+
106
+ # Apply filters
107
+ data = data[
108
+ (data['required_age'] <= max_age) &
109
+ (data['price'] <= max_price) &
110
+ (data['pos_neg_ratio'] >= min_pos_neg_ratio)
111
+ ].reset_index(drop=True)
112
+
113
+ if data.empty:
114
+ return "No games found matching your filter criteria."
115
+
116
+ feature_vectors = prepare_features(data)
117
+ recommendations_html = get_recommendations(game_name, data, feature_vectors)
118
+
119
+ return recommendations_html
120
+
121
+
122
+
123
+ # Format the output for Gradio
124
+ result_texts = []
125
+ result_images = []
126
+
127
+ for result, image_url in recommendations:
128
+ result_texts.append(result)
129
+ if image_url and str(image_url) != 'nan':
130
+ result_images.append(image_url)
131
+ else:
132
+ # Use a placeholder image if no image URL is available
133
+ result_images.append(None)
134
+
135
+ # Create a gallery of results
136
+ results_html = ""
137
+ for i, (text, img) in enumerate(zip(result_texts, result_images)):
138
+ results_html += text
139
+
140
+ return results_html, result_images
141
+
142
+ # Create the Gradio interface
143
+ with gr.Blocks(title="Steam Game Recommender") as demo:
144
+ gr.Markdown("# ๐ŸŽฎ Steam Game Recommender")
145
+ gr.Markdown("Enter a game you like and adjust filters to get the best matches.")
146
+
147
+ with gr.Row():
148
+ input_text = gr.Textbox(label="๐ŸŽฏ Favorite Game")
149
+
150
+ with gr.Row():
151
+ max_age_slider = gr.Slider(0, 21, value=17, label="Max Age Rating (Avoid Adult Games)")
152
+ max_price_slider = gr.Slider(0.0, 100.0, value=60.0, step=0.5, label="Maximum Price ($)")
153
+ min_pos_neg_slider = gr.Slider(0.0, 10.0, value=2.0, step=0.1, label="Min Positive:Negative Ratio")
154
+
155
+ with gr.Row():
156
+ submit_btn = gr.Button("๐Ÿ” Get Recommendations")
157
+
158
+ with gr.Row():
159
+ output_text = gr.Markdown(label="๐Ÿง  Recommendations")
160
+
161
+ submit_btn.click(
162
+ fn=recommend_games,
163
+ inputs=[input_text, max_age_slider, max_price_slider, min_pos_neg_slider],
164
+ outputs=output_text
165
+ )
166
+
167
+ # Launch the app
168
+ if __name__ == "__main__":
169
+ demo.launch()