MLOPs_Car_Price_Predict / src /streamlit_app.py
jalesummak's picture
Update src/streamlit_app.py
d65f138 verified
Raw
History Blame Contribute Delete
8.24 kB
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
# -------------------------------------------------
@st.cache_data
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
# -------------------------------------------------
@st.cache_resource
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."
)