Spaces:
Sleeping
Sleeping
| import os | |
| import pandas as pd | |
| import streamlit as st | |
| from sklearn.compose import ColumnTransformer | |
| from sklearn.linear_model import LinearRegression | |
| from sklearn.metrics import mean_squared_error, r2_score | |
| from sklearn.model_selection import train_test_split | |
| from sklearn.pipeline import Pipeline | |
| from sklearn.preprocessing import OneHotEncoder, StandardScaler | |
| # ------------------------------------------------- | |
| # SAYFA AYARLARI | |
| # ------------------------------------------------- | |
| st.set_page_config( | |
| page_title="Araç Fiyat Tahmin Sistemi", | |
| page_icon="🚗", | |
| layout="centered" | |
| ) | |
| # ------------------------------------------------- | |
| # DOSYA YOLU | |
| # app.py: /app/src/app.py | |
| # cars.xlsx: /app/cars.xlsx | |
| # ------------------------------------------------- | |
| BASE_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__))) | |
| DATA_PATH = os.path.join(BASE_DIR, "cars.xlsx") | |
| # ------------------------------------------------- | |
| # VERİYİ YÜKLE | |
| # ------------------------------------------------- | |
| def load_data(): | |
| data = pd.read_excel(DATA_PATH) | |
| required_columns = [ | |
| "Price", "Make", "Model", "Trim", "Mileage", | |
| "Type", "Cylinder", "Liter", "Doors", | |
| "Cruise", "Sound", "Leather" | |
| ] | |
| missing_columns = [ | |
| column for column in required_columns | |
| if column not in data.columns | |
| ] | |
| if missing_columns: | |
| raise ValueError( | |
| f"cars.xlsx içinde şu sütunlar eksik: {', '.join(missing_columns)}" | |
| ) | |
| data = data.dropna() | |
| return data | |
| # ------------------------------------------------- | |
| # MODELİ EĞİT | |
| # ------------------------------------------------- | |
| def train_model(data): | |
| x = data.drop("Price", axis=1) | |
| y = data["Price"] | |
| x_train, x_test, y_train, y_test = train_test_split( | |
| x, | |
| y, | |
| test_size=0.20, | |
| random_state=42 | |
| ) | |
| preprocessor = ColumnTransformer( | |
| transformers=[ | |
| ( | |
| "numeric", | |
| StandardScaler(), | |
| ["Mileage", "Cylinder", "Liter", "Doors"] | |
| ), | |
| ( | |
| "categorical", | |
| OneHotEncoder(handle_unknown="ignore"), | |
| ["Make", "Model", "Trim", "Type"] | |
| ) | |
| ], | |
| remainder="passthrough" | |
| ) | |
| pipeline = Pipeline( | |
| steps=[ | |
| ("preprocessor", preprocessor), | |
| ("regressor", LinearRegression()) | |
| ] | |
| ) | |
| pipeline.fit(x_train, y_train) | |
| predictions = pipeline.predict(x_test) | |
| rmse = mean_squared_error(y_test, predictions) ** 0.5 | |
| r2 = r2_score(y_test, predictions) | |
| return pipeline, rmse, r2 | |
| # ------------------------------------------------- | |
| # FİYAT TAHMİNİ | |
| # ------------------------------------------------- | |
| def predict_price( | |
| make, | |
| car_model, | |
| trim, | |
| mileage, | |
| car_type, | |
| cylinder, | |
| liter, | |
| doors, | |
| cruise, | |
| sound, | |
| leather | |
| ): | |
| input_data = pd.DataFrame([{ | |
| "Make": make, | |
| "Model": car_model, | |
| "Trim": trim, | |
| "Mileage": mileage, | |
| "Type": car_type, | |
| "Cylinder": cylinder, | |
| "Liter": liter, | |
| "Doors": doors, | |
| "Cruise": cruise, | |
| "Sound": sound, | |
| "Leather": leather | |
| }]) | |
| price = pipeline.predict(input_data)[0] | |
| return float(price) | |
| # ------------------------------------------------- | |
| # VERİ VE MODELİ BAŞLAT | |
| # ------------------------------------------------- | |
| try: | |
| df = load_data() | |
| pipeline, rmse, r2 = train_model(df) | |
| except FileNotFoundError: | |
| st.error("cars.xlsx dosyası ana klasörde bulunamadı.") | |
| st.info("Dosya yapısı şu şekilde olmalı: ana klasörde cars.xlsx, src içinde app.py.") | |
| st.stop() | |
| except Exception as error: | |
| st.error(f"Uygulama başlatılırken hata oluştu: {error}") | |
| st.stop() | |
| # ------------------------------------------------- | |
| # TASARIM | |
| # ------------------------------------------------- | |
| st.markdown(""" | |
| <style> | |
| .main-title { | |
| text-align: center; | |
| font-size: 40px; | |
| font-weight: 800; | |
| margin-bottom: 5px; | |
| } | |
| .sub-title { | |
| text-align: center; | |
| font-size: 17px; | |
| color: #6b7280; | |
| margin-bottom: 25px; | |
| } | |
| .result-card { | |
| padding: 24px; | |
| border-radius: 16px; | |
| text-align: center; | |
| font-size: 28px; | |
| font-weight: 800; | |
| background: #ecfdf5; | |
| border: 1px solid #86efac; | |
| color: #166534 !important; | |
| margin-top: 15px; | |
| margin-bottom: 20px; | |
| } | |
| } | |
| </style> | |
| """, unsafe_allow_html=True) | |
| st.markdown( | |
| "<div class='main-title'>🚗 Araç Fiyat Tahmin Sistemi</div>", | |
| unsafe_allow_html=True | |
| ) | |
| st.markdown( | |
| "<div class='sub-title'>Araç bilgilerini girin, model tahmini satış fiyatını hesaplasın.</div>", | |
| unsafe_allow_html=True | |
| ) | |
| st.divider() | |
| # ------------------------------------------------- | |
| # FORM | |
| # ------------------------------------------------- | |
| left_column, right_column = st.columns(2) | |
| with left_column: | |
| make = st.selectbox( | |
| "Marka", | |
| sorted(df["Make"].unique()) | |
| ) | |
| available_models = sorted( | |
| df[df["Make"] == make]["Model"].unique() | |
| ) | |
| car_model = st.selectbox( | |
| "Model", | |
| available_models | |
| ) | |
| available_trims = sorted( | |
| df[ | |
| (df["Make"] == make) & | |
| (df["Model"] == car_model) | |
| ]["Trim"].unique() | |
| ) | |
| trim = st.selectbox( | |
| "Donanım Paketi", | |
| available_trims | |
| ) | |
| mileage = st.number_input( | |
| "Kilometre", | |
| min_value=0, | |
| max_value=500000, | |
| value=30000, | |
| step=1000 | |
| ) | |
| car_type = st.selectbox( | |
| "Araç Tipi", | |
| sorted(df["Type"].unique()) | |
| ) | |
| with right_column: | |
| cylinder = st.selectbox( | |
| "Silindir Sayısı", | |
| sorted(df["Cylinder"].unique()) | |
| ) | |
| liter = st.selectbox( | |
| "Motor Hacmi", | |
| sorted(df["Liter"].unique()) | |
| ) | |
| doors = st.selectbox( | |
| "Kapı Sayısı", | |
| sorted(df["Doors"].unique()) | |
| ) | |
| cruise = st.radio( | |
| "Hız Sabitleyici", | |
| options=[0, 1], | |
| horizontal=True, | |
| format_func=lambda value: "Var" if value == 1 else "Yok" | |
| ) | |
| sound = st.radio( | |
| "Premium Ses Sistemi", | |
| options=[0, 1], | |
| horizontal=True, | |
| format_func=lambda value: "Var" if value == 1 else "Yok" | |
| ) | |
| leather = st.radio( | |
| "Deri Koltuk", | |
| options=[0, 1], | |
| horizontal=True, | |
| format_func=lambda value: "Var" if value == 1 else "Yok" | |
| ) | |
| st.divider() | |
| # ------------------------------------------------- | |
| # TAHMİN | |
| # ------------------------------------------------- | |
| if st.button("Tahmini Fiyatı Hesapla", use_container_width=True): | |
| predicted_price = predict_price( | |
| make=make, | |
| car_model=car_model, | |
| trim=trim, | |
| mileage=mileage, | |
| car_type=car_type, | |
| cylinder=cylinder, | |
| liter=liter, | |
| doors=doors, | |
| cruise=cruise, | |
| sound=sound, | |
| leather=leather | |
| ) | |
| st.markdown( | |
| f"<div class='result-card'>Tahmini Araç Fiyatı: ${predicted_price:,.2f}</div>", | |
| unsafe_allow_html=True | |
| ) | |
| metric_1, metric_2 = st.columns(2) | |
| with metric_1: | |
| st.metric( | |
| "R² Başarı Skoru", | |
| f"{r2:.2f}" | |
| ) | |
| with metric_2: | |
| st.metric( | |
| "RMSE Hata Skoru", | |
| f"${rmse:,.0f}" | |
| ) | |
| st.subheader("Girilen Araç Bilgileri") | |
| result_table = pd.DataFrame([{ | |
| "Marka": make, | |
| "Model": car_model, | |
| "Donanım": trim, | |
| "Kilometre": mileage, | |
| "Araç Tipi": car_type, | |
| "Silindir": cylinder, | |
| "Motor Hacmi": liter, | |
| "Kapı Sayısı": doors, | |
| "Hız Sabitleyici": "Var" if cruise == 1 else "Yok", | |
| "Premium Ses": "Var" if sound == 1 else "Yok", | |
| "Deri Koltuk": "Var" if leather == 1 else "Yok", | |
| "Tahmini Fiyat": f"${predicted_price:,.2f}" | |
| }]) | |
| st.dataframe( | |
| result_table, | |
| use_container_width=True, | |
| hide_index=True | |
| ) | |
| st.divider() | |
| st.caption( | |
| "Bu uygulama eğitim amaçlı bir makine öğrenmesi fiyat tahmin projesidir. " | |
| "Tahminler gerçek piyasa fiyatını garanti etmez." | |
| ) |