yusufenes commited on
Commit
ea59388
·
verified ·
1 Parent(s): 8184093

Upload 8 files

Browse files
app.py ADDED
@@ -0,0 +1,240 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import streamlit as st
2
+ import joblib
3
+ import pandas as pd
4
+ import numpy as np
5
+ from preprocess_pipeline import SingleInstancePreprocessor
6
+ from get_real_home_listing import get_home_listings
7
+ from home_listing_display import display_home_listings
8
+
9
+ model = joblib.load('random_forest.joblib')
10
+ preprocessor = SingleInstancePreprocessor()
11
+
12
+
13
+ temp = {}
14
+ st.set_page_config(
15
+ page_title="🏠 Ev Fiyatı Tahmin ve Öneri aracı",
16
+ page_icon="🏠",
17
+ layout="wide",
18
+ initial_sidebar_state="expanded",
19
+ )
20
+
21
+ st.markdown("""
22
+ <style>
23
+ :root {
24
+ --primary: #2A3950;
25
+ --secondary: #00C0A3;
26
+ --background: #1A1A1A;
27
+ --surface: #2D2D2D;
28
+ --text-primary: #FFFFFF;
29
+ }
30
+
31
+ body {
32
+ font-family: 'Arial', sans-serif;
33
+ background-color: var(--background);
34
+ color: var(--text-primary);
35
+ }
36
+
37
+ .stApp {
38
+ background: var(--background);
39
+ color: var(--text-primary);
40
+ font-family: 'Inter', sans-serif;
41
+ }
42
+
43
+ .header-container {
44
+ background: var(--surface);
45
+ padding: 3rem;
46
+ border-radius: 15px;
47
+ margin-bottom: 2.5rem;
48
+ box-shadow: 0 6px 25px rgba(0,0,0,0.3);
49
+ text-align: center;
50
+ }
51
+
52
+ .input-card {
53
+ background: var(--surface);
54
+ border-radius: 12px;
55
+ padding: 2rem;
56
+ margin: 1.2rem 0;
57
+ border: 1px solid rgba(255,255,255,0.1);
58
+ transition: all 0.3s ease;
59
+ }
60
+
61
+ .input-card:hover {
62
+ transform: translateY(-5px);
63
+ box-shadow: 0 8px 20px rgba(0,0,0,0.4);
64
+ }
65
+
66
+ .stSelectbox, .stNumberInput, .stTextInput {
67
+ background: var(--primary) !important;
68
+ border-radius: 10px !important;
69
+ border: none !important;
70
+ color: var(--text-primary) !important;
71
+ padding: 0.75rem !important;
72
+ }
73
+
74
+ .stButton>button {
75
+ background: var(--secondary) !important;
76
+ color: var(--text-primary) !important;
77
+ border: none;
78
+ padding: 16px 36px;
79
+ border-radius: 10px;
80
+ font-weight: 600;
81
+ transition: all 0.3s;
82
+ box-shadow: 0 5px 15px rgba(0,192,163,0.4);
83
+ }
84
+
85
+ .stButton>button:hover {
86
+ opacity: 0.9;
87
+ transform: translateY(-2px);
88
+ box-shadow: 0 6px 20px rgba(0,192,163,0.5);
89
+ }
90
+
91
+ .prediction-card {
92
+ background: linear-gradient(135deg, var(--primary) 0%, #1B2838 100%);
93
+ border-radius: 15px;
94
+ padding: 2.5rem;
95
+ text-align: center;
96
+ margin: 2.5rem 0;
97
+ border: 1px solid rgba(255,255,255,0.15);
98
+ box-shadow: 0 8px 25px rgba(0,0,0,0.3);
99
+ }
100
+
101
+ .section-title {
102
+ font-size: 1.4rem;
103
+ font-weight: 700;
104
+ color: var(--secondary);
105
+ margin: 1.8rem 0;
106
+ display: flex;
107
+ align-items: center;
108
+ gap: 1rem;
109
+ text-transform: uppercase;
110
+ letter-spacing: 1px;
111
+ }
112
+
113
+ .footer {
114
+ text-align: center;
115
+ padding: 2rem;
116
+ color: rgba(255,255,255,0.7);
117
+ font-size: 0.95rem;
118
+ margin-top: 3.5rem;
119
+ border-top: 1px solid rgba(255,255,255,0.1);
120
+ }
121
+
122
+ /* Ek olarak, mobil uyumluluk için medya sorguları ekleyebilirsiniz */
123
+ @media (max-width: 768px) {
124
+ .header-container {
125
+ padding: 2rem;
126
+ margin-bottom: 2rem;
127
+ }
128
+ .section-title {
129
+ font-size: 1.2rem;
130
+ margin: 1.5rem 0;
131
+ }
132
+ }
133
+ </style>
134
+ """, unsafe_allow_html=True)
135
+
136
+ with st.container():
137
+ st.markdown("""
138
+ <div class="header-container">
139
+ <h1 style="margin:0;font-size:2.5rem">🏠 Ev Tahmin</h1>
140
+ <p style="color:rgba(255,255,255,0.8);margin-top:0.5rem">Ev Fiyatı Tahmin Ve Öneri Aracı</p>
141
+ </div>
142
+ """, unsafe_allow_html=True)
143
+
144
+ with st.container():
145
+ col1, col2 = st.columns([1, 1.2])
146
+
147
+ with col1:
148
+ st.markdown('<div class="section-title">📍 Lokasyon Bilgileri</div>', unsafe_allow_html=True)
149
+ st.markdown('<div style="color:rgba(255,255,255,0.8);margin-bottom:1rem">Ev fiyatı tahmini yapmak için lütfen aşağıdaki bilgileri doldurun.</div>', unsafe_allow_html=True)
150
+
151
+ with st.container():
152
+ st.markdown('<div class="input-card">', unsafe_allow_html=True)
153
+ il_listesi = list(preprocessor.location_map.keys())
154
+ selected_il = st.selectbox('İl', options=il_listesi)
155
+ ilceler = list(preprocessor.location_map.get(selected_il, {}).keys())
156
+ selected_ilce = st.selectbox('İlçe', options=ilceler)
157
+ mahalleler = preprocessor.location_map.get(selected_il, {}).get(selected_ilce, [])
158
+ selected_mahalle = st.selectbox('Mahalle', options=mahalleler)
159
+ st.markdown('</div>', unsafe_allow_html=True)
160
+
161
+ st.markdown('<div class="section-title">📐 Temel Özellikler</div>', unsafe_allow_html=True)
162
+ with st.container():
163
+ st.markdown('<div class="input-card">', unsafe_allow_html=True)
164
+ tipi = st.selectbox('Konut Tipi', options=['Daire', 'Residence', 'Villa', 'Müstakil Ev', 'Yazlık'])
165
+ brut_metrekare = st.number_input('Brüt Metrekare (m²)', min_value=30, max_value=500, value=100)
166
+ binanin_yasi = st.number_input('Bina Yaşı', min_value=0, max_value=100, value=5)
167
+ st.markdown('</div>', unsafe_allow_html=True)
168
+
169
+ with col2:
170
+ st.markdown('<div class="section-title">📊 Detaylı Özellikler</div>', unsafe_allow_html=True)
171
+ with st.container():
172
+ st.markdown('<div class="input-card">', unsafe_allow_html=True)
173
+ cols = st.columns(2)
174
+ with cols[0]:
175
+ oda_sayisi = st.selectbox('Oda', options=['1+1', '2+1', '3+1', '4+1', '5+1'])
176
+ banyo_sayisi = st.number_input('Banyo', min_value=1, max_value=5, value=1)
177
+ isitma_tipi = st.selectbox('Isıtma Tipi', options=['Doğalgaz', 'Merkezi Sistem', 'Elektrikli', 'Soba'])
178
+ with cols[1]:
179
+ bulundugu_kat = 3 # Ortalama veya tipik bir değer
180
+ binanin_kat_sayisi = 10 # Ortalama veya tipik bir değer
181
+ esya_durumu = st.selectbox('Eşya Durumu', options=['Eşyalı', 'Eşyasız'])
182
+ st.markdown('</div>', unsafe_allow_html=True)
183
+
184
+ st.markdown('<div class="section-title">⚙️ Diğer Ayarlar</div>', unsafe_allow_html=True)
185
+ with st.container():
186
+ st.markdown('<div class="input-card">', unsafe_allow_html=True)
187
+ cols = st.columns(2)
188
+ with cols[0]:
189
+ site_icerisinde = st.selectbox('Site İçinde', options=['Evet', 'Hayır'])
190
+ with cols[1]:
191
+ kullanim_durumu = st.selectbox('Kullanım Durumu', options=['Konut', 'İş Yeri', 'Diğer'])
192
+ st.markdown('</div>', unsafe_allow_html=True)
193
+
194
+ if st.button('💵 Tahmin Yap', use_container_width=True):
195
+ input_data = {
196
+ 'Oda Sayısı': oda_sayisi,
197
+ 'Bulunduğu Kat': bulundugu_kat,
198
+ 'Isıtma Tipi': isitma_tipi,
199
+ 'Eşya Durumu': esya_durumu,
200
+ 'Site İçerisinde': site_icerisinde,
201
+ 'Tipi': tipi,
202
+ 'Brüt Metrekare': brut_metrekare,
203
+ 'Binanın Yaşı': binanin_yasi,
204
+ 'Binanın Kat Sayısı': binanin_kat_sayisi,
205
+ 'Kullanım Durumu': kullanim_durumu,
206
+ 'Banyo Sayısı': banyo_sayisi,
207
+ 'İl': selected_il,
208
+ 'İlçe': selected_ilce,
209
+ 'Mahalle': selected_mahalle
210
+ }
211
+
212
+
213
+ with st.spinner('AI analiz yapıyor...'):
214
+ input_array = preprocessor.transform(input_data)
215
+
216
+ tahmin = model.predict(input_array)
217
+
218
+ st.markdown(f'''
219
+ <div class="prediction-card">
220
+ <h3 style="margin:0 0 1rem 0;color:rgba(255,255,255,0.9)">TAHMİN EDİLEN DEĞER</h3>
221
+ <div style="font-size:2.8rem;font-weight:700;color:var(--secondary);margin:1rem 0">{tahmin[0]:,.0f} TL</div>
222
+ <p style="color:rgba(255,255,255,0.7);margin:0">*Gerçek değerler piyasa koşullarına göre değişiklik gösterebilir</p>
223
+ </div>
224
+ ''', unsafe_allow_html=True)
225
+
226
+ predicted_price = tahmin[0]
227
+ with st.spinner("Seçim ile benzer özelliğe sahip ilanlar getiriliyor..."):
228
+ home_listings = get_home_listings(selected_il, predicted_price)
229
+ display_home_listings(home_listings)
230
+
231
+ st.markdown('''
232
+ <div class="footer">
233
+ <div> @yusufenes || Konut Fiyatı Tahmin ve Konut Öneri Sistemi || Tüm veriler İnternet Üzerinden Alınmıştır Ticari Kullanım Hakkı Yoktur.</div>
234
+ <div style="margin-top:0.5rem;font-size:0.8rem">
235
+ <span style="opacity:0.7">Geliştirici: Yusuf Enes</span> •
236
+ <span style="opacity:0.7">🧑‍💻 <a href="https://github.com/yusuffenes">Github</a> </span>
237
+ </div>
238
+ </div>
239
+ ''', unsafe_allow_html=True)
240
+
display_listings.py ADDED
@@ -0,0 +1,8 @@
 
 
 
 
 
 
 
 
 
1
+ def display_listings(listings):
2
+ for i in range(0, len(listings), 2):
3
+ listing1 = listings[i]
4
+ print(f"Listing 1: {listing1['title']}, {listing1['url']}")
5
+ if i + 1 < len(listings):
6
+ listing2 = listings[i + 1]
7
+ print(f"Listing 2: {listing2['title']}, {listing2['url']}")
8
+ print("-" * 50)
get_real_home_listing.py ADDED
@@ -0,0 +1,117 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ from selenium import webdriver
2
+ from selenium.webdriver.chrome.service import Service
3
+ from selenium.webdriver.chrome.options import Options
4
+ from selenium.webdriver.common.by import By
5
+ from selenium.webdriver.support.ui import WebDriverWait
6
+ from selenium.webdriver.support import expected_conditions as EC
7
+ from selenium.common.exceptions import NoSuchElementException
8
+ import json
9
+ import pandas as pd
10
+ import requests
11
+ from bs4 import BeautifulSoup
12
+
13
+ def format_price(price):
14
+ # Remove dots and convert to integer
15
+ price = str(price)[0:-2]
16
+ clean_price = price.replace('.', '')
17
+ return int(clean_price)
18
+
19
+
20
+ def get_home_listings(selected_il, price_value):
21
+ # Set up Chrome options
22
+ chrome_options = Options()
23
+ chrome_options.add_argument('--headless') # Run Chrome in headless mode
24
+ chrome_options.add_argument('--start-maximized')
25
+
26
+ # Initialize the Chrome driver
27
+ driver = webdriver.Chrome(options=chrome_options)
28
+
29
+ # Navigate to the website
30
+ driver.get('https://www.emlakjet.com/')
31
+
32
+ # Wait for the element to be present and then send input data
33
+ search_input = WebDriverWait(driver, 10).until(
34
+ EC.presence_of_element_located((By.XPATH, '//*[@id="headlessui-tabs-panel-:r9:"]/div/div[2]/div/div/div/input'))
35
+ )
36
+ search_input.send_keys(f'{selected_il}')
37
+ # Click the dropdown to open the price range options
38
+ dropdown_button = driver.find_element(By.XPATH, '//*[@id="headlessui-listbox-button-:rh:"]')
39
+ dropdown_button.click()
40
+
41
+ # Calculate lower and upper bounds
42
+ # Remove periods from the price string before calculation
43
+ price_value = format_price(price_value)
44
+ lower_bound = price_value - 500000
45
+ upper_bound = price_value + 500000
46
+
47
+ # Locate the first input element and set it to the lower bound
48
+ first_input = WebDriverWait(driver, 10).until(
49
+ EC.presence_of_element_located((By.XPATH, '//*[@id="headlessui-listbox-options-:ri:"]/ul[1]/div[1]/div/div[1]/input'))
50
+ )
51
+ first_input.clear()
52
+ first_input.send_keys(str(lower_bound))
53
+
54
+ # Locate the second input element and set it to the upper bound
55
+ second_input = WebDriverWait(driver, 10).until(
56
+ EC.presence_of_element_located((By.XPATH, '//*[@id="headlessui-listbox-options-:ri:"]/ul[2]/div[1]/div/div[1]/input'))
57
+ )
58
+ second_input.clear()
59
+ second_input.send_keys(str(upper_bound))
60
+
61
+ # Click the "Find" button to perform the search
62
+ find_button = WebDriverWait(driver, 10).until(
63
+ EC.element_to_be_clickable((By.XPATH, '//*[@id="headlessui-tabs-panel-:r9:"]/div/div[5]/div/button'))
64
+ )
65
+ find_button.click()
66
+
67
+ i = 1
68
+ data = []
69
+
70
+ while i<=10:
71
+ WebDriverWait(driver,10).until(EC.presence_of_element_located((By.XPATH, f'//*[@id="content-wrapper"]/div[1]/div[4]/div[2]/div[3]/div[{""+str(i)+""}]/div/a')))
72
+ link = driver.find_element(By.XPATH, f'//*[@id="content-wrapper"]/div[1]/div[4]/div[2]/div[3]/div[{""+str(i)+""}]/div/a')
73
+ driver.get(link.get_attribute('href'))
74
+ detail_url = driver.current_url
75
+ # Wait for the features list to load
76
+ WebDriverWait(driver, 3).until(
77
+ EC.presence_of_element_located((By.ID, "ilan-hakkinda"))
78
+ )
79
+
80
+ try:
81
+ ul = driver.find_element(By.XPATH, '//*[@id="ilan-hakkinda"]/div/div/ul')
82
+ list_items = ul.find_elements(By.TAG_NAME, 'li')
83
+
84
+ details = {}
85
+ for item in list_items:
86
+ try:
87
+ key = item.find_element(By.CLASS_NAME, 'styles_key__VqMhC').text
88
+ value = item.find_element(By.CLASS_NAME, 'styles_value__3QmL3').text
89
+ details[key] = value
90
+ except NoSuchElementException:
91
+ continue
92
+
93
+ # Extract the title
94
+ title = driver.find_element(By.XPATH, '//*[@id="content-wrapper"]/div[2]/div[1]/div/h1').text
95
+ resim_url = driver.find_element(By.XPATH, '//*[@id="content-wrapper"]/div[2]/div[2]/div[2]/img').get_attribute('src')
96
+ fiyat = driver.find_element(By.XPATH, '//*[@id="genel-bakis"]/div[1]/div[1]/div[1]/div/span').text
97
+ fiyat = int(fiyat.replace('.','').replace('TL',''))
98
+ # Add the URL and title to the details
99
+ details['url'] = detail_url
100
+ details['title'] = title
101
+ details['resim_url'] = resim_url
102
+ details['price'] = fiyat
103
+
104
+
105
+
106
+ data.append(details)
107
+
108
+ except NoSuchElementException as e:
109
+ print(f"Element not found: {e}")
110
+ except Exception as e:
111
+ print(f"An error occurred: {e}")
112
+
113
+ driver.execute_script("window.history.go(-1)")
114
+ i += 1
115
+
116
+ driver.quit()
117
+ return data
home_listing_display.py ADDED
@@ -0,0 +1,61 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import streamlit as st
2
+
3
+ def display_home_listings(listings):
4
+ st.markdown("""
5
+ <style>
6
+ .listing-card {
7
+ background: #2D2D2D;
8
+ border-radius: 10px;
9
+ padding: 1rem;
10
+ margin: 1rem 0;
11
+ border: 1px solid rgba(255,255,255,0.1);
12
+ transition: transform 0.2s;
13
+ }
14
+ .listing-card:hover {
15
+ transform: translateY(-2px);
16
+ box-shadow: 0 4px 15px rgba(0,0,0,0.2);
17
+ }
18
+ .price-tag {
19
+ color: #00C0A3;
20
+ font-size: 1.4rem;
21
+ font-weight: bold;
22
+ margin: 0.5rem 0;
23
+ }
24
+ .property-info {
25
+ color: rgba(255,255,255,0.8);
26
+ font-size: 0.9rem;
27
+ margin: 0.3rem 0;
28
+ }
29
+ .listing-link {
30
+ display: inline-block;
31
+ background: #2A3950;
32
+ color: white;
33
+ padding: 0.5rem 1rem;
34
+ border-radius: 5px;
35
+ text-decoration: none;
36
+ margin-top: 0.5rem;
37
+ transition: background 0.2s;
38
+ }
39
+ .listing-link:hover {
40
+ background: #374863;
41
+ }
42
+ </style>
43
+ """, unsafe_allow_html=True)
44
+
45
+ st.markdown("### 🏠 Benzer Fiyatlı İlanlar", unsafe_allow_html=True)
46
+
47
+ col1, col2 = st.columns(2)
48
+
49
+ for idx, listing in enumerate(listings):
50
+ with col1 if idx % 2 == 0 else col2:
51
+ st.markdown(f"""
52
+ <div class="listing-card">
53
+ <img src="{listing['resim_url']}" style="width: 100%; height: 200px; object-fit: cover; object-position: center; border-radius: 5px; margin-bottom: 0.5rem;">
54
+ <div style="font-size:1.2rem; font-weight:bold">{listing['title']}</div>
55
+ <div class="price-tag">{listing['price']:,} TL</div>
56
+ <div class="property-info">📏 {listing['Brüt Metrekare']}</div>
57
+ <div class="property-info">🏘️ {listing.get('Oda Sayısı', 'Belirtilmemiş')}</div>
58
+ <div class="property-info">♨️ {listing.get('Isıtma Tipi', 'Belirtilmemiş')}</div>
59
+ <a href="{listing['url']}" target="_blank" class="listing-link">İlanı Görüntüle →</a>
60
+ </div>
61
+ """, unsafe_allow_html=True)
location_map.json ADDED
The diff for this file is too large to render. See raw diff
 
preprocess_pipeline.py ADDED
@@ -0,0 +1,164 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import numpy as np
2
+ import re
3
+ import json
4
+ import pandas as pd
5
+
6
+ class SingleInstancePreprocessor:
7
+ def __init__(self, location_map_path='location_map.json'):
8
+ self.isitma_mapping = {
9
+ "Doğalgaz": 5,
10
+ "Merkezi Sistem": 6,
11
+ "Elektrikli": 3,
12
+ "Soba": 1,
13
+ "Isıtma Yok": 0,
14
+ "Other": 4,
15
+ "Klimalı": 3,
16
+ "Doğalgaz Sobalı": 4,
17
+ "Merkezi (Pay Ölçer)": 6,
18
+ "Merkezi Doğalgaz": 6,
19
+ "Güneş Enerjisi": 9,
20
+ "Yerden Isıtma": 7,
21
+ "Merkezi Kömür": 8,
22
+ "Şömine": 2,
23
+ "Jeotermal": 10,
24
+ "Kat Kaloriferi": 11,
25
+ "Isı Pompası": 12
26
+ }
27
+ self.esya_mapping = {
28
+ "Eşyalı": 1,
29
+ "Eşyasız": 0,
30
+ "Belirtilmemiş": 2,
31
+ "Boşluk": 2
32
+ }
33
+ self.tipi_mapping = {
34
+ "Daire": 3,
35
+ "Residence": 5,
36
+ "Villa": 8,
37
+ "Müstakil Ev": 6,
38
+ "Yazlık": 4,
39
+ "Bina": 3,
40
+ "Köy Evi": 1,
41
+ "Çiftlik Evi": 2,
42
+ "Devremülk": 5,
43
+ "Yalı Dairesi": 7,
44
+ "Köşk": 9,
45
+ "Prefabrik": 1,
46
+ "Yalı": 12,
47
+ "Dağ Evi": 4,
48
+ "Kooperatif": 3
49
+ }
50
+ self.kullanim_mapping = {
51
+ "Konut": 0,
52
+ "İş Yeri": 1,
53
+ "Diğer": 2,
54
+ "Boş": 3,
55
+ "Boşluk2": 3
56
+ }
57
+ self.yatirim_mapping = {
58
+ 'Yatırıma Uygun':'10',
59
+ 'Yatırıma Uygun Değil':'0',
60
+ 'Bilinmiyor':'1',
61
+ 'Belirtilmemiş':'1'
62
+ }
63
+
64
+ self.oturma_mapping = {
65
+ 'Kendisi' : 0,
66
+ 'Kiracı': 1,
67
+ }
68
+
69
+ try:
70
+ with open(location_map_path, 'r', encoding='utf-8') as f:
71
+ self.location_map = json.load(f)
72
+ except FileNotFoundError:
73
+ print(f"Hata: {location_map_path} dosyası bulunamadı.")
74
+ self.location_map = {}
75
+
76
+ def transform(self, input_data):
77
+ """
78
+ Tek bir örnek için girdi verilerini dönüştürür.
79
+ """
80
+ input_series = pd.Series(input_data)
81
+
82
+ oda = input_series.get("Oda Sayısı")
83
+ if isinstance(oda, str):
84
+ oda = oda.strip()
85
+ if "Stüdyo" in oda:
86
+ oda_val = 0.0
87
+ elif "+" in oda:
88
+ try:
89
+ parts = oda.split("+")
90
+ oda_val = float(parts[0]) + float(parts[1])
91
+ except Exception:
92
+ oda_val = float(oda.replace("Oda", "").strip())
93
+ else:
94
+ oda_val = float(oda.replace("Oda", "").strip())
95
+ else:
96
+ oda_val = float(oda)
97
+
98
+ kat = input_series.get("Bulunduğu Kat")
99
+ if isinstance(kat, str):
100
+ kat_val = int(re.sub(r'\D', '', kat))
101
+ else:
102
+ kat_val = int(kat)
103
+
104
+ isitma = input_series.get("Isıtma Tipi")
105
+ isitma_val = self.isitma_mapping.get(isitma, 4)
106
+
107
+ esya = input_series.get("Eşya Durumu")
108
+ esya_val = self.esya_mapping.get(esya, 2)
109
+
110
+ site = input_series.get("Site İçerisinde", "Hayır")
111
+ site_val = 1 if site == "Evet" else 0
112
+
113
+ tipi = input_series.get("Tipi")
114
+ tipi_val = self.tipi_mapping.get(tipi, 3)
115
+
116
+ metrekare = input_series.get("Brüt Metrekare")
117
+ if isinstance(metrekare, str):
118
+ metrekare_val = float(re.sub(r'[^0-9]', '', metrekare))
119
+ else:
120
+ metrekare_val = float(metrekare)
121
+
122
+ yas = input_series.get("Binanın Yaşı")
123
+ if isinstance(yas, str):
124
+ yas_val = int(re.sub(r'\D', '', yas))
125
+ else:
126
+ yas_val = int(yas)
127
+
128
+ bina_kat = input_series.get("Binanın Kat Sayısı")
129
+ bina_kat_val = int(bina_kat)
130
+
131
+ kullanim = input_series.get("Kullanım Durumu")
132
+ kullanim_val = self.kullanim_mapping.get(kullanim, 0)
133
+
134
+ yatirim = input_series.get("Yatırıma Uygunluk")
135
+ yatirim_val = self.yatirim_mapping.get(yatirim, 1)
136
+
137
+ banyo = input_series.get("Banyo Sayısı")
138
+ banyo_val = int(banyo)
139
+
140
+ il = input_series.get("İl")
141
+ ilce = input_series.get("İlçe")
142
+ mahalle = input_series.get("Mahalle")
143
+
144
+ il_val = 0
145
+ ilce_val = 0
146
+ mahalle_val = 0
147
+
148
+ if il in self.location_map:
149
+ il_val = list(self.location_map.keys()).index(il)
150
+ if ilce in self.location_map[il]:
151
+ ilce_val = list(self.location_map[il].keys()).index(ilce)
152
+ if mahalle in self.location_map[il][ilce]:
153
+ mahalle_val = self.location_map[il][ilce].index(mahalle)
154
+
155
+ oturma_durumu = input_series.get('oturma_durumu')
156
+ oturma_val = self.oturma_mapping.get(oturma_durumu,0)
157
+
158
+
159
+ features = [oda_val, kat_val, isitma_val, esya_val, site_val, tipi_val,
160
+ metrekare_val, yas_val, bina_kat_val, kullanim_val, yatirim_val, banyo_val,
161
+ il_val, ilce_val, mahalle_val,oturma_val]
162
+
163
+ X = np.array(features).reshape(1, -1)
164
+ return X
random_forest.joblib ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ version https://git-lfs.github.com/spec/v1
2
+ oid sha256:b2c594e9fea936e8b651e8b7098dd8174af415960507933fb9f19ad1a51f5dc0
3
+ size 833520225
requirements.txt ADDED
Binary file (5.75 kB). View file