Makine öğrenmesi kullanarak balığın fiziksel özelliklerinden ağırlığını tahmin eden web uygulaması.
Yukarıdaki görsel: Flask web arayüzü - kullanıcıdan balık özelliklerini alan form
Bu projede balık ağırlığını tahmin etmek için:
1️⃣ Backward Elimination ile özellik seçimi yapıldı
2️⃣ OLS (Ordinary Least Squares) Regresyon modeli kuruldu
3️⃣ Model .pkl formatında kaydedildi
4️⃣ Flask tabanlı bir web arayüzü ile kullanıcıdan veri alınıp gerçek zamanlı tahmin yapılması sağlandı
Veri bilimi sürecinin tüm aşamaları .ipynb dosyasında açıklamalı olarak gösterilmiştir.
Kullandığım veri setinde şu öznitelikler bulunuyordu:
- Length1 → Dikey uzunluk (cm)
- Length2 → Çapraz uzunluk (cm)
- Length3 → En uzun çapraz uzunluk (cm)
- Height → Yükseklik (cm)
- Width → Genişlik (cm)
- Species → Balık türü (Bream, Pike, Perch, Roach, Smelt, Whitefish, Parkki)
- Weight → Hedef değişken (ağırlık - gram)
Yukarıdaki görsel: df.info() çıktısı - veri setinin yapısı, kolonlar ve veri tipleri
Bu özniteliklerin hepsi anlamlı olduğu için veri setinden çıkarılacak "gereksiz" bir kolon yoktu. Ayrıca öznitelik sayısı 7 olup ödev gereği belirlenen maksimum 10 sınırının içerisindedir.
.isnull().sum() ile veri incelendi:
Yukarıdaki görsel: Eksik veri kontrolü - tüm kolonlarda 0 eksik veri
Sonuç: Hiçbir eksik veri bulunmadığı için doldurma (imputation) işlemi yapılmasına gerek olmadı. Eksik veri olsaydı ortalama/medyan ile doldurmayı tercih ederdik.
Species (Balık Türü) gibi değişkenler nominal (sırasız) kategoriktir.
Label Encoding kullanılsaydı:
- Bream = 1, Pike = 2 gibi değerler atanacak
- Model bu sayıları sıralı sanıp yanlış ilişki kuracaktı
✔ Bu nedenle One-Hot Encoding en doğru yöntemdir:
- Kategoriler ayrı sütunlarda 0/1 şeklinde gösterilir
- "Dummy Variable Trap" oluşmaması için
drop_first=Truekullanıldı
Yukarıdaki görsel: df_encoded.head() çıktısı - Species kolonu one-hot encoding ile dönüştürüldü
Kullanılan Yöntem: StandardScaler
Gerekçe:
- Length1, Length2, Length3, Height, Width gibi özellikler farklı ölçeklerdedir (cm cinsinden)
- Ölçekleme yapılmazsa, büyük değerlere sahip özellikler (örn: Length3) model üzerinde daha fazla etkili olabilir
- StandardScaler kullanarak tüm özellikler ortalaması 0, standart sapması 1 olacak şekilde normalize edilir
- Bu işlem modelin daha iyi performans göstermesini sağlar
Not: Scaler sadece eğitim verisiyle fit edilir, test verisi sadece transform edilir (data leakage önlemek için)
Modelin istatistiksel anlamlılığını ölçmek için:
- Tüm özelliklerle OLS modeli kuruldu
- p-value değerleri kontrol edildi
- p > 0.05 olan kolonlar tek tek elenerek model sadeleştirildi
Süreç:
- Her iterasyonda en yüksek p-value'ya sahip özellik bulunur
- Eğer p-value > 0.05 ise, o özellik çıkarılır
- Tüm özelliklerin p-value'su < 0.05 olana kadar işlem devam eder
Sonuç:
Yukarıdaki görsel: Backward Elimination süreci - hangi özelliklerin çıkarıldığı gösteriliyor
Seçilen Özellikler:
- ✔ Length2 (Çapraz Uzunluk) - En önemli özellik
- ✔ Species_Parkki
- ✔ Species_Pike
- ✔ Species_Smelt
Elenen Özellikler:
- ❌ Width (p-value: 0.798)
- ❌ Species_Roach (p-value: 0.571)
- ❌ Species_Whitefish (p-value: 0.705)
- ❌ Species_Perch (p-value: 0.533)
- ❌ Length3 (p-value: 0.343)
- ❌ Height (p-value: 0.667)
- ❌ Length1 (p-value: 0.158)
Eğitim/Test ayrımı yapıldıktan sonra OLS (Ordinary Least Squares) Regresyon modeli eğitildi.
Yukarıdaki görsel: OLS Regression Results - model katsayıları, p-value'lar ve istatistikler
Model İstatistikleri:
- R² (R-squared): 0.926 (%92.6)
- Adj. R-squared: 0.924
- F-statistic: 382.5
- Prob (F-statistic): 5.33e-68 (çok yüksek anlamlılık)
- No. Observations: 127 (eğitim seti)
Katsayılar (Coefficients):
- const: 386.79 (sabit terim)
- Length2: 419.16 (en yüksek katsayı - en önemli özellik)
- Species_Parkki: 18.22 (p-value: 0.046)
- Species_Pike: -113.46 (p-value: 0.000)
- Species_Smelt: 62.75 (p-value: 0.000)
Yukarıdaki görsel: Test seti üzerinde hesaplanan performans metrikleri
Test Seti Sonuçları:
- R² Score: 0.9477 (%94.77) → Model veriyi %95 oranında açıklamaktadır
- MAE (Mean Absolute Error): 65.43 gram → Ortalama tahmin hatası
- MSE (Mean Squared Error): 7432.55
- RMSE (Root Mean Squared Error): 86.21 gram → Karekök ortalama karesel hata
- R² skorunun 0.95 olması modelin balık ağırlığındaki değişimin %95'ini açıkladığını gösterir → çok iyi bir sonuç
- MAE ≈ 65 gram, ortalama tahmin hatasını ifade eder
- Balıkların ağırlıkları 200-1500 gram bandında değiştiği düşünülürse, 65 gramlık ortalama hata başarılı bir sonuçtur
- Length2 özelliği en önemli tahmin edici değişkendir (katsayı: 419.16)
Model .pkl dosyasına kaydedildi:
fish_model.pkl- Eğitilmiş OLS regresyon modeliscaler.pkl- StandardScaler nesnesifeature_names.json- Tüm özellik isimleribe_cols.json- Backward Elimination sonrası seçilen özellikler
Yukarıdaki görsel: Flask web arayüzü - kullanıcıdan balık özelliklerini alan form
Form Alanları:
- Balık Türü: Dropdown menüden seçim (Bream, Pike, Perch, Roach, Smelt, Whitefish, Parkki)
- Uzunluk 1: Dikey uzunluk (cm)
- Uzunluk 2: Çapraz uzunluk (cm)
- Uzunluk 3: En uzun çapraz uzunluk (cm)
- Yükseklik: Balığın yüksekliği (cm)
- Genişlik: Balığın genişliği (cm)
Yukarıdaki görsel: Balık türü seçim dropdown menüsü
- ✅ Türkçe kullanıcı arayüzü
- ✅ Gerçek zamanlı form validasyonu
- ✅ Her alan için açıklayıcı hint yazıları
- ✅ Placeholder örnekleri
- ✅ Görsel geri bildirim (geçerli/geçersiz alanlar)
- ✅ Form değerleri korunur (submit sonrası sıfırlanmaz)
Yukarıdaki görsel: Form doldurulduktan sonra gösterilen tahmin sonucu
Örnek Tahmin:
- Girdi: Smelt türü, Length1=23.4, Length2=25.3, Length3=30, Height=11.56, Width=4.08
- Tahmin Edilen Ağırlık: 526.48 gram
- Python 3.7 veya üzeri
- pip (Python paket yöneticisi)
git clone https://github.com/kosebaris1/MLP_Flask.git cd Fish_Weight_Predictor### Adım 2: Sanal Ortam Oluşturun (Önerilen)
python -m venv venv venv\Scripts\activate
python3 -m venv venv source venv/bin/activate### Adım 3: Gerekli Paketleri Yükleyin
pip install flask pandas numpy scikit-learn statsmodels### Adım 4: Uygulamayı Başlatın
python app.pyUygulama http://localhost:5000 adresinde çalışacaktır.