sarizeybek commited on
Commit
40e40b3
·
verified ·
1 Parent(s): a263131

Upload 2 files

Browse files
Files changed (2) hide show
  1. app.py +467 -0
  2. requirements.txt +9 -0
app.py ADDED
@@ -0,0 +1,467 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import streamlit as st
2
+ import pandas as pd
3
+ import numpy as np
4
+ import streamlit.components.v1 as components
5
+ import matplotlib.pyplot as plt
6
+ import seaborn as sns
7
+ from sklearn.preprocessing import PowerTransformer
8
+ from sklearn.model_selection import train_test_split
9
+ from sklearn.linear_model import LinearRegression
10
+ from sklearn.tree import DecisionTreeRegressor, plot_tree
11
+ from sklearn.ensemble import RandomForestRegressor
12
+ from sklearn.metrics import mean_squared_error, mean_absolute_error, r2_score
13
+ import folium
14
+ from folium.plugins import HeatMap, MarkerCluster
15
+ import tempfile
16
+ import os
17
+
18
+ def folium_static(fig, height=500):
19
+ """Render folium map by saving to HTML."""
20
+ temp = tempfile.NamedTemporaryFile(delete=False, suffix='.html')
21
+ temp_path = temp.name
22
+ temp.close()
23
+ fig.save(temp_path)
24
+ with open(temp_path, 'r', encoding='utf-8') as f:
25
+ html_data = f.read()
26
+ os.unlink(temp_path)
27
+ components.html(html_data, height=height)
28
+
29
+
30
+ st.set_page_config(page_title="Airbnb Fiyat Tahmini", page_icon="🏠", layout="wide")
31
+
32
+ st.markdown("""
33
+ <style>
34
+ .main-header {
35
+ font-size: 2.5rem;
36
+ color: #FF5A5F; /* Airbnb color */
37
+ text-align: center;
38
+ margin-bottom: 1rem;
39
+ }
40
+ .section-header {
41
+ font-size: 1.8rem;
42
+ color: #484848;
43
+ margin-top: 1.5rem;
44
+ margin-bottom: 1rem;
45
+ }
46
+ .subsection-header {
47
+ font-size: 1.3rem;
48
+ color: #767676;
49
+ margin-top: 1rem;
50
+ }
51
+ .description {
52
+ font-size: 1rem;
53
+ color: #484848;
54
+ }
55
+ .info-box {
56
+ background-color: #f8f9fa;
57
+ padding: 15px;
58
+ border-radius: 5px;
59
+ border-left: 5px solid #FF5A5F;
60
+ }
61
+ </style>
62
+ """, unsafe_allow_html=True)
63
+
64
+ st.sidebar.title("Navigasyon")
65
+ pages = ["Ana Sayfa", "Veri İnceleme", "Ön İşleme Sonuçları", "Model Sonuçları", "Harita Görselleştirme"]
66
+ selected_page = st.sidebar.radio("", pages)
67
+
68
+ @st.cache_data
69
+ def load_data():
70
+ try:
71
+ df = pd.read_csv("AB_NYC_2019.csv")
72
+ return df
73
+ except:
74
+ st.error("Lütfen AB_NYC_2019.csv dosyasını yükleyin veya doğru konumda olduğundan emin olun.")
75
+ return None
76
+
77
+ df = load_data()
78
+
79
+ if df is None:
80
+ st.warning("Devam etmek için veri dosyasını yükleyin.")
81
+ uploaded_file = st.file_uploader("AB_NYC_2019.csv dosyasını yükleyin", type="csv")
82
+ if uploaded_file is not None:
83
+ df = pd.read_csv(uploaded_file)
84
+ st.success("Veri başarıyla yüklendi!")
85
+
86
+ def preprocess_data(df):
87
+
88
+ processed_df = df.copy()
89
+
90
+ processed_df.drop(columns=["id", "name", "host_id", "host_name", "last_review"], inplace=True)
91
+
92
+ power_transformer = PowerTransformer(method='yeo-johnson')
93
+ reviews_temp = processed_df["reviews_per_month"].fillna(0)
94
+ processed_df["reviews_per_month"] = power_transformer.fit_transform(reviews_temp.values.reshape(-1, 1))
95
+
96
+ processed_df["reviews_per_month_original"] = power_transformer.inverse_transform(
97
+ processed_df["reviews_per_month"].values.reshape(-1, 1)
98
+ ).flatten()
99
+
100
+ processed_df = pd.get_dummies(processed_df, columns=["neighbourhood_group", "room_type"], drop_first=True)
101
+
102
+ processed_df["neighbourhood_encoded"] = processed_df.groupby("neighbourhood")["price"].transform("mean")
103
+ processed_df.drop(columns=["neighbourhood"], inplace=True)
104
+
105
+ processed_df = processed_df[processed_df["price"] > 0]
106
+
107
+ processed_df["log_price"] = np.log1p(processed_df["price"])
108
+ processed_df["minimum_nights_log"] = np.log1p(processed_df["minimum_nights"])
109
+ processed_df["review_score"] = processed_df["reviews_per_month"] * processed_df["number_of_reviews"]
110
+
111
+ X = processed_df.drop(columns=["price"])
112
+ if "reviews_per_month_original" in X.columns:
113
+ X = X.drop(columns=["reviews_per_month_original"])
114
+ y = processed_df["price"]
115
+
116
+ return X, y, processed_df
117
+
118
+ if df is not None:
119
+
120
+ if selected_page == "Ana Sayfa":
121
+ st.markdown("<h1 class='main-header'>New York Airbnb Fiyat Tahmini</h1>", unsafe_allow_html=True)
122
+
123
+ col1, col2, col3 = st.columns([1, 3, 1])
124
+ with col2:
125
+ st.image("https://a0.muscache.com/im/pictures/fe7217ff-0b24-438d-8833-1dd45a298a6b.jpg", use_column_width=True)
126
+
127
+ st.markdown("<div class='info-box'>", unsafe_allow_html=True)
128
+ st.markdown("""
129
+ Bu veri seti ile New York City'deki Airbnb ilanlarının fiyatlarını tahmin etmeye çalışacağız.
130
+ Amacımız, bir evi kiralamak isteyen birinin fiyatının ne olacağını öngörmek.
131
+ Bunun için Regresyon, Karar Ağacı ve Random Forest modelleri uygulayacağız.
132
+ """)
133
+ st.markdown("</div>", unsafe_allow_html=True)
134
+
135
+ st.markdown("<h2 class='section-header'>Veri Seti Genel Bakış</h2>", unsafe_allow_html=True)
136
+ st.dataframe(df.head())
137
+
138
+ st.markdown("<h2 class='section-header'>Veri Seti Sütunları</h2>", unsafe_allow_html=True)
139
+ st.markdown("""
140
+ - **id**: Airbnb ilanının benzersiz kimlik numarası
141
+ - **name**: İlanın adı veya açıklaması
142
+ - **host_id**: İlan sahibinin benzersiz kimlik numarası
143
+ - **host_name**: İlan sahibinin adı
144
+ - **neighbourhood_group**: İlanın bulunduğu büyük bölge (örneğin Manhattan, Brooklyn)
145
+ - **neighbourhood**: İlanın bulunduğu mahalle
146
+ - **latitude**: İlanın enlem (latitude) koordinatı
147
+ - **longitude**: İlanın boylam (longitude) koordinatı
148
+ - **room_type**: Konaklama türü (Örneğin: "Private room", "Entire home/apt", "Shared room")
149
+ - **price**: Gecelik konaklama ücreti (USD cinsinden)
150
+ - **minimum_nights**: Konaklama için belirlenen minimum gece sayısı
151
+ - **number_of_reviews**: İlanın aldığı toplam inceleme sayısı
152
+ - **last_review**: İlanın son inceleme tarihi
153
+ - **reviews_per_month**: Aylık ortalama inceleme sayısı
154
+ - **calculated_host_listings_count**: Aynı ev sahibinin toplam ilan sayısı
155
+ - **availability_365**: Yıl boyunca müsait olduğu gün sayısı (365 gün üzerinden)
156
+ """)
157
+
158
+
159
+ elif selected_page == "Veri İnceleme":
160
+ st.markdown("<h1 class='main-header'>Veri İnceleme</h1>", unsafe_allow_html=True)
161
+
162
+ st.markdown("<h2 class='section-header'>Aylık Yorum Sayısı Analizi</h2>", unsafe_allow_html=True)
163
+
164
+ col1, col2 = st.columns(2)
165
+ with col1:
166
+ st.metric("Ortalama", f"{df['reviews_per_month'].mean():.2f}")
167
+ with col2:
168
+ st.metric("Medyan", f"{df['reviews_per_month'].median():.2f}")
169
+
170
+ st.markdown("<div class='info-box'>", unsafe_allow_html=True)
171
+ st.markdown("""
172
+ Çarpık bir dağılım var. Çünkü ortalama > medyan olduğundan dağılım sağa çarpık.
173
+ Bu da birçok ilan çok az yorum alırken, az sayıda ilan aşırı fazla yorum aldığını gösteriyor.
174
+ """)
175
+ st.markdown("</div>", unsafe_allow_html=True)
176
+
177
+ fig, ax = plt.subplots(figsize=(10, 5))
178
+ sns.histplot(df["reviews_per_month"].dropna(), bins=50, kde=True, ax=ax)
179
+ ax.axvline(df["reviews_per_month"].dropna().mean(), color='red', linestyle='dashed', linewidth=2, label="ortalama")
180
+ ax.axvline(df["reviews_per_month"].dropna().median(), color='blue', linestyle='dashed', linewidth=2, label="median")
181
+ ax.set_title("Aylık Yorum Sayısı Dağılımı")
182
+ ax.legend()
183
+
184
+ st.pyplot(fig)
185
+
186
+ st.markdown("""
187
+ Daha fazla yorum sayısına sahip ilanlar ortalamayı yukarı çekiyor.
188
+ Burada çarpıklığı azaltmam gerekiyor. Dağılımı dengeli hale getirelim.
189
+ """)
190
+
191
+ st.markdown("<h2 class='section-header'>Eksik Değer Analizi</h2>", unsafe_allow_html=True)
192
+
193
+ missing_vals = df.isnull().sum()
194
+ missing_cols = missing_vals[missing_vals > 0]
195
+
196
+ if len(missing_cols) > 0:
197
+ st.write("Eksik değer içeren sütunlar:")
198
+ st.write(missing_cols)
199
+ else:
200
+ st.success("Veri setinde eksik değer bulunmuyor.")
201
+
202
+
203
+ elif selected_page == "Ön İşleme Sonuçları":
204
+ st.markdown("<h1 class='main-header'>Ön İşleme Sonuçları</h1>", unsafe_allow_html=True)
205
+
206
+
207
+ st.markdown("<h2 class='section-header'>Yeo-Johnson Dönüşümü Sonuçları</h2>", unsafe_allow_html=True)
208
+
209
+ processed_df = df.copy()
210
+
211
+ try:
212
+ power_transformer = PowerTransformer(method='yeo-johnson')
213
+ reviews_temp = processed_df["reviews_per_month"].fillna(0)
214
+ reviews_transformed = power_transformer.fit_transform(reviews_temp.values.reshape(-1, 1))
215
+ reviews_original = power_transformer.inverse_transform(reviews_transformed)
216
+
217
+
218
+ fig, axes = plt.subplots(1, 2, figsize=(16, 5))
219
+
220
+
221
+ sns.histplot(reviews_temp, bins=50, kde=True, ax=axes[0], color='skyblue')
222
+ axes[0].axvline(reviews_temp.mean(), color='red', linestyle='dashed', linewidth=2, label="ortalama")
223
+ axes[0].axvline(reviews_temp.median(), color='blue', linestyle='dashed', linewidth=2, label="median")
224
+ axes[0].set_title("Orijinal Veride Aylık Yorum Dağılımı")
225
+ axes[0].legend()
226
+
227
+
228
+ sns.histplot(reviews_transformed, bins=50, kde=True, ax=axes[1], color='lightgreen')
229
+ axes[1].axvline(reviews_transformed.mean(), color='red', linestyle='dashed', linewidth=2, label="ortalama")
230
+ axes[1].axvline(np.median(reviews_transformed), color='blue', linestyle='dashed', linewidth=2, label="median")
231
+ axes[1].set_title("Yeo-Johnson Dönüşüm Sonrası Dağılım")
232
+ axes[1].legend()
233
+
234
+ plt.tight_layout()
235
+ st.pyplot(fig)
236
+
237
+
238
+ fig, ax = plt.subplots(1, 2, figsize=(12, 6))
239
+
240
+
241
+ sns.boxplot(x=reviews_transformed.flatten(), ax=ax[0])
242
+ ax[0].set_title("Aylık Yorum Sayısı Dağılımı (Boxplot)")
243
+
244
+
245
+ sns.histplot(reviews_transformed.flatten(), bins=30, kde=True, ax=ax[1])
246
+ ax[1].set_title("Aylık Yorum Sayısı Histogramı")
247
+
248
+ st.pyplot(fig)
249
+
250
+ st.markdown("<div class='info-box'>", unsafe_allow_html=True)
251
+ st.markdown("""
252
+ ✓ Çünkü veri uç değerler içeriyor ve çarpık bir dağılım gösteriyor.
253
+ ✓ Çoğu ilan çok az yorum alırken, birkaç ilan çok fazla yorum alıyor.
254
+ ✓ mean() kullanırsak, az yorum alan ilanlar için yanlış tahmin yapabiliriz.
255
+ """)
256
+ st.markdown("</div>", unsafe_allow_html=True)
257
+ except Exception as e:
258
+ st.error(f"Dönüşüm sırasında hata oluştu: {e}")
259
+
260
+
261
+ st.markdown("<h2 class='section-header'>Eksik Değer Doldurma Stratejisi</h2>", unsafe_allow_html=True)
262
+
263
+ st.markdown("""
264
+ Eksik değerleri şu stratejiye göre doldurdum:
265
+
266
+ 1. Önce reviews_per_month sütununu float tipine çevirdim.
267
+ 2. Aynı mahalle ve oda tipindeki medyan değerleri kullanarak eksik değerleri doldurdum.
268
+ 3. Hala eksik değer varsa, mahalle bazında medyan değerleri kullandım.
269
+ 4. Son olarak, kalan eksik değerleri 0 ile doldurdum.
270
+ """)
271
+
272
+
273
+ st.markdown("<h2 class='section-header'>Kategorik Değişken Dönüşümü ve Özellik Mühendisliği</h2>", unsafe_allow_html=True)
274
+
275
+ st.markdown("""
276
+ 1. neighbourhood_group ve room_type kategorik değişkenlerini one-hot encoding ile sayısal değerlere dönüştürdüm.
277
+ 2. neighbourhood değişkenini, her mahalle için ortalama fiyatı hesaplayarak kodladım.
278
+ 3. Sıfır fiyatlı ilanları veri setinden çıkardım.
279
+ 4. Logaritmik dönüşümler uygulayarak log_price ve minimum_nights_log değişkenlerini oluşturdum.
280
+ 5. reviews_per_month ve number_of_reviews değişkenlerini birleştirerek review_score adlı yeni bir özellik oluşturdum.
281
+ """)
282
+
283
+
284
+ elif selected_page == "Model Sonuçları":
285
+ st.markdown("<h1 class='main-header'>Model Sonuçları</h1>", unsafe_allow_html=True)
286
+
287
+
288
+ if st.checkbox("Modelleri Göster", value=True):
289
+ with st.spinner("Modeller hazırlanıyor..."):
290
+
291
+ X, y, processed_df = preprocess_data(df)
292
+ X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2, random_state=42)
293
+
294
+
295
+ st.markdown("<h2 class='section-header'>Doğrusal Regresyon Sonuçları</h2>", unsafe_allow_html=True)
296
+
297
+ lr_model = LinearRegression()
298
+ lr_model.fit(X_train, y_train)
299
+ lr_pred = lr_model.predict(X_test)
300
+
301
+ lr_mae = mean_absolute_error(y_test, lr_pred)
302
+ lr_mse = mean_squared_error(y_test, lr_pred)
303
+ lr_rmse = np.sqrt(lr_mse)
304
+
305
+ col1, col2, col3 = st.columns(3)
306
+ col1.metric("MAE", f"${lr_mae:.2f}")
307
+ col2.metric("RMSE", f"${lr_rmse:.2f}")
308
+ col3.metric("MSE", f"${lr_mse:.2f}")
309
+
310
+ fig, ax = plt.subplots(figsize=(8, 6))
311
+ sns.scatterplot(x=y_test, y=lr_pred, alpha=0.5, ax=ax)
312
+ ax.plot([y_test.min(), y_test.max()], [y_test.min(), y_test.max()], color="red", linestyle="--")
313
+ ax.set_xlabel("Gerçek Değerler (Fiyat)")
314
+ ax.set_ylabel("Tahmin Edilen Değerler (Fiyat)")
315
+ ax.set_title("Gerçek vs. Tahmin Edilen Fiyatlar")
316
+
317
+
318
+
319
+ st.pyplot(fig)
320
+
321
+
322
+ st.markdown("<h2 class='section-header'>Karar Ağacı Sonuçları</h2>", unsafe_allow_html=True)
323
+
324
+ dt_model = DecisionTreeRegressor(max_depth=4, random_state=42)
325
+ dt_model.fit(X_train, y_train)
326
+ dt_pred = dt_model.predict(X_test)
327
+
328
+ dt_mae = mean_absolute_error(y_test, dt_pred)
329
+ dt_mse = mean_squared_error(y_test, dt_pred)
330
+ dt_r2 = r2_score(y_test, dt_pred)
331
+
332
+ col1, col2, col3 = st.columns(3)
333
+ col1.metric("MAE", f"${dt_mae:.2f}")
334
+ col2.metric("MSE", f"${dt_mse:.2f}")
335
+ col3.metric("R²", f"{dt_r2:.4f}")
336
+
337
+ fig, ax = plt.subplots(figsize=(8, 6))
338
+ sns.scatterplot(x=y_test, y=dt_pred, alpha=0.5, ax=ax)
339
+ ax.plot([y_test.min(), y_test.max()], [y_test.min(), y_test.max()], color="brown", linestyle="--")
340
+ ax.set_xlabel("Gerçek Değerler (Fiyat)")
341
+ ax.set_ylabel("Tahmin Edilen Değerler (Fiyat)")
342
+ ax.set_title("Gerçek vs. Tahmin Edilen Fiyatlar")
343
+
344
+
345
+
346
+ st.pyplot(fig)
347
+
348
+ if st.checkbox("Karar Ağacını Görselleştir"):
349
+ fig, ax = plt.subplots(figsize=(20, 10))
350
+ plot_tree(dt_model, feature_names=X.columns, filled=True, rounded=True, ax=ax)
351
+ ax.set_title("Decision Tree")
352
+ st.pyplot(fig)
353
+
354
+
355
+ st.markdown("<h2 class='section-header'>Random Forest Sonuçları</h2>", unsafe_allow_html=True)
356
+
357
+ rf_model = RandomForestRegressor(n_estimators=100, random_state=42)
358
+ rf_model.fit(X_train, y_train)
359
+ rf_pred = rf_model.predict(X_test)
360
+
361
+ rf_mae = mean_absolute_error(y_test, rf_pred)
362
+ rf_mse = mean_squared_error(y_test, rf_pred)
363
+ rf_r2 = r2_score(y_test, rf_pred)
364
+
365
+ col1, col2, col3 = st.columns(3)
366
+ col1.metric("MAE", f"${rf_mae:.2f}")
367
+ col2.metric("MSE", f"${rf_mse:.2f}")
368
+ col3.metric("R²", f"{rf_r2:.4f}")
369
+
370
+ fig, ax = plt.subplots(figsize=(8, 6))
371
+ sns.scatterplot(x=y_test, y=rf_pred, alpha=0.5, ax=ax)
372
+ ax.plot([y_test.min(), y_test.max()], [y_test.min(), y_test.max()], color="red", linestyle="--")
373
+ ax.set_xlabel("Gerçek Değerler (Fiyat)")
374
+ ax.set_ylabel("Tahmin Edilen Değerler (Fiyat)")
375
+ ax.set_title("Gerçek vs. Tahmin Edilen Fiyatlar")
376
+
377
+
378
+
379
+ st.pyplot(fig)
380
+
381
+ st.markdown("<h2 class='section-header'>Model Karşılaştırması</h2>", unsafe_allow_html=True)
382
+
383
+ comparison_df = pd.DataFrame({
384
+ 'Model': ['Doğrusal Regresyon', 'Karar Ağacı', 'Random Forest'],
385
+ 'MAE': [lr_mae, dt_mae, rf_mae],
386
+ 'MSE': [lr_mse, dt_mse, rf_mse],
387
+ 'R²': [r2_score(y_test, lr_pred), dt_r2, rf_r2]
388
+ })
389
+
390
+ comparison_df = comparison_df.set_index('Model')
391
+ st.dataframe(comparison_df.style.highlight_min(subset=['MAE', 'MSE']).highlight_max(subset=['R²']))
392
+
393
+ st.markdown("<div class='info-box'>", unsafe_allow_html=True)
394
+ st.markdown("""
395
+ Random Forest modeli en iyi performansı göstermiştir.
396
+ R² değeri 1'e yakın olduğu için modelin açıklama gücü yüksektir.
397
+ """)
398
+ st.markdown("</div>", unsafe_allow_html=True)
399
+
400
+
401
+ elif selected_page == "Harita Görselleştirme":
402
+ st.markdown("<h1 class='main-header'>Harita Görselleştirme</h1>", unsafe_allow_html=True)
403
+
404
+ try:
405
+
406
+ st.markdown("<h2 class='section-header'>Semtlere Göre Konum Dağılımı</h2>", unsafe_allow_html=True)
407
+
408
+ fig, ax = plt.subplots(figsize=(10, 6))
409
+ sns.scatterplot(x=df.longitude, y=df.latitude, hue=df.neighbourhood_group, ax=ax)
410
+ ax.set_title('Neighbourhood Group Location')
411
+ st.pyplot(fig)
412
+
413
+
414
+ st.markdown("<h2 class='section-header'>Oda Tiplerine Göre Konum Dağılımı</h2>", unsafe_allow_html=True)
415
+
416
+ fig, ax = plt.subplots(figsize=(10, 6))
417
+ sns.scatterplot(x=df.longitude, y=df.latitude, hue=df.room_type, ax=ax)
418
+ ax.set_title('Room type location per Neighbourhood Group')
419
+ st.pyplot(fig)
420
+
421
+
422
+ st.markdown("<h2 class='section-header'>İlan Yoğunluğu Haritası</h2>", unsafe_allow_html=True)
423
+
424
+ if st.button("Yoğunluk Haritasını Göster"):
425
+
426
+ m = folium.Map(location=[40.76586, -73.98436], tiles='cartodbpositron', zoom_start=11)
427
+
428
+
429
+ sample_df = df.sample(min(5000, len(df)))
430
+
431
+
432
+ HeatMap(data=sample_df[['latitude', 'longitude']].values.tolist(), radius=10).add_to(m)
433
+
434
+
435
+ folium_static(m, height=600)
436
+
437
+
438
+ st.markdown("<h2 class='section-header'>İlan Kümeleme Haritası</h2>", unsafe_allow_html=True)
439
+
440
+ if st.button("Kümeleme Haritasını Göster"):
441
+
442
+ m = folium.Map(location=[40.76586, -73.98436], tiles='cartodbpositron', zoom_start=11)
443
+
444
+ sample_df = df.sample(min(1000, len(df)))
445
+
446
+
447
+ sample_df["All"] = 'Room type: ' + sample_df['room_type'].astype(str) + ', ' + \
448
+ 'Availability (365 days): ' + sample_df["availability_365"].astype(str) + ', ' + \
449
+ 'Price: $' + sample_df["price"].astype(str)
450
+
451
+
452
+ marker_cluster = MarkerCluster().add_to(m)
453
+
454
+
455
+ for idx, row in sample_df.iterrows():
456
+ folium.Marker(
457
+ location=[row['latitude'], row['longitude']],
458
+ popup=row['All']
459
+ ).add_to(marker_cluster)
460
+
461
+ folium_static(m, height=600)
462
+ except Exception as e:
463
+ st.error(f"Harita oluşturulurken bir hata oluştu: {e}")
464
+
465
+ if __name__ == "__main__":
466
+
467
+ pass
requirements.txt ADDED
@@ -0,0 +1,9 @@
 
 
 
 
 
 
 
 
 
 
1
+ streamlit>=1.25.0
2
+ pandas>=1.3.0
3
+ numpy>=1.21.0
4
+ matplotlib>=3.4.0
5
+ seaborn>=0.11.0
6
+ scikit-learn>=1.0.0
7
+ folium>=0.12.0
8
+ streamlit-folium>=0.11.0
9
+ plotly>=5.3.0