A’dan Z’ye Makine Öğrenmesi Rehberi

Bölüm 0: Giriş — Yapay Zeka ve Makine Öğrenmesi Ekosistemine Mühendislik Yaklaşımı

Günümüz yazılım dünyasında makine öğrenmesi (ML), akademinin sınırlarını aşıp doğrudan üretim sistemlerinin (production) merkezine yerleşti. Bir Yapay Zeka Mühendisi için ML; yalnızca hazır kütüphaneleri çağırıp .fit() ve .predict() çalıştırmaktan ibaret değildir. Asıl mühendislik disiplini; iş problemini doğru ML problemine dönüştürmek, veri boru hatlarını (data pipelines) sürdürülebilir kurmak, doğru matematiksel mimariyi seçmek ve modelin üretim ortamındaki başarımını (latency, throughput, drift) yönetebilmektir.

Bu blog serisinde, oyuncak (toy) veri setleri üzerinden ezberlenmiş kodları değil; endüstri standartlarında kullanılan algoritmik yaklaşımları, matematiksel sezgileri ve kodlama pratiklerini uçtan uca ele alacağız.

 
1. Problemi Doğru Tanımlamak: ML Problem Tipleri

Bir projeye başlarken ilk soru şudur: “Elimizdeki veri ve hedef değişkenin yapısı nedir?” Yanıt, bizi doğru problem tipine götürür:

  • Sürekli Değişken Tahmini (Regresyon – Supervised Learning): Hedef değişkenin (y) sürekli sayısal değerler aldığı durumlar. Finansal fiyat tahminleri, ev/araç değerleme, talep tahmini (demand forecasting) gibi senaryolar bu gruba girer.

  • Kategorik Sınıflandırma (Sınıflandırma – Supervised Learning): Verinin önceden tanımlanmış sınıflara (y : {0, 1} veya çoklu sınıf) atanması. Kredi risk analizi, müşteri terk (churn) tahmini, medikal teşhis ve görüntü sınıflandırma bu dikeyin temelidir.

  • Örüntü ve Grup Keşfi (Kümeleme – Unsupervised Learning): Etiketsiz (y değişkeni olmayan) veride gizli yapıları ve grupları bulma süreci. Müşteri segmentasyonu, anomali tespiti (anomaly detection) ve pazar sepeti analizinde kritik rol oynar.

  • Metin ve Dil İşleme (NLP): Yapısal olmayan metin verisinden anlamsal özellik çıkarımı. Duygu analizi (sentiment analysis), döküman sınıflandırma, spam tespiti ve modern LLM (Large Language Model) tabanlı uygulamaların altyapısı.

  • Kişiselleştirme ve Öneri Sistemleri (Recommendation Systems): Kullanıcı-öğe (user-item) etkileşim matrisleri üzerinden kişiselleştirilmiş içerik/ürün sunma. E-ticaret ve medya platformlarının ana gelir motorudur.

2. Repo Yapısı ve Mimari Düzen

Proje mimarisinin derli toplu ve modüler olması, kodun yeniden kullanılabilirliği (reusability) ve MLOps süreçlerine aktarımı açısından hayati önem taşır. Bu seri boyunca kullanacağımız kod parçalarına ve notebook’lara resmi GitHub depomuz üzerinden erişebilirsiniz:

🔗 GitHub Deposu: Rasittekin18 / 4-Machine_Learning

Repo mimarisi, her bir algoritmik konseptin bağımsız olarak test edilebileceği, veri setleriyle modüler bağlandığı bir yapıda kurgulanmıştır

3. Çalışma Ortamının Kurulumu ve Bağımlılıklar

Geliştirme ortamında tutarlılık sağlamak adına standart veri bilimi ve ML stack’i kullanılmaktadır. Ortamı hazırlamak için terminalinizde şu adımları izleyebilirsiniz:

Sanal Ortam Oluşturma (Virtual Environment)

 
Bash
# Sanal ortam oluşturma
python -m venv ml_env

# Aktif etme (Linux/macOS)
source ml_env/bin/activate

# Aktif etme (Windows)
ml_env\Scripts\activate
Temel Kütüphanelerin Kurulumu

Projedeki analizler, vektörel hesaplamalar, görselleştirme ve modelleme adımları için temel bağımlılıklar:

 
Bash
pip install numpy pandas matplotlib seaborn scipy scikit-learn nltk
  • NumPy & Pandas: Vektörel matris işlemleri ve veri manipülasyonu.

  • Matplotlib & Seaborn: Keşifçi Veri Analizi (EDA) ve model değerlendirme grafiklerinin oluşturulması.

  • Scikit-Learn: Sınıflandırma, regresyon, kümeleme ve boyut indirgeme algoritmalarının endüstri standardı kütüphanesi.

  • NLTK: Doğal Dil İşleme adımlarındaki metin temizleme ve tokenization işlemleri.

Giriş altyapımızı tamamladığımıza göre, doğrudan Bölüm 1: Regresyon Mimarileri ve Sürekli Değişken Tahmini ile teorik ve pratik kodlamaya geçebiliriz.

 
Bölüm 1: Regresyon Mimarileri ve Sürekli Değişken Tahmini

Gözetimli öğrenmenin (Supervised Learning) temel taşlarından biri olan regresyon, sürekli sayısal değerleri (y E {R}) en az hata ile tahmin etme sanatıdır. Gelin, farklı regresyon mimarilerini adım adım inceleyelim.

1.1. Lineer Tahmin Modelleri

Lineer modeller, bağımsız değişkenlerimiz (X) ile hedefimiz (y) arasında doğrusal bir bağ kurar.

1. Basit Lineer Regresyon (Simple Linear Regression)

Tek bir bağımsız değişken (x) kullanarak hedef değişkeni (y) tahmin etmek istediğimizde temel formülümüz şudur:

 
 

y = β0 + β1x

  • β0(Bias / Intercept): Çizginin y eksenini kestiği başlangıç noktası.

  • β1 (Slope / Coeff): Doğrunun eğimi.

 Optimizasyonun Kalbi: Cost Function Modelimiz, gerçek değerler (y) ile tahmin ettiği değerler (ŷ) arasındaki farkı (residual) ölçmek için Mean Squared Error (MSE) fonksiyonunu kullanır:

 
 

MSE = 1
n
i=1 n (yi − ŷi)2

Temel amaç: MSE değerini en küçükleyecek (min(MSE) optimum β₀ ve β₁ katsayılarını bulmaktır.

Python Uygulaması (Deneyim – Maaş İlişkisi):

Çalışanların deneyim sürelerine göre maaşlarını tahmin ettiğimiz ilk senaryoda, Scikit-Learn’ün matris beklentisine uygun olarak verimizi .reshape(-1, 1) ile boyutlandırıp modelimizi eğitiyoruz:

 
 
Python
import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
from sklearn.linear_model import LinearRegression

# Veri yükleme ve boyutlandırma
df = pd.read_csv("linear_regression_dataset.csv", sep=";")
x = df.deneyim.values.reshape(-1, 1)
y = df.maas.values.reshape(-1, 1)

# Modelin fit edilmesi
linear_reg = LinearRegression()
linear_reg.fit(x, y)

# Parametrelerimizin incelenmesi
b0 = linear_reg.intercept_  # Bias (1663.89)
b1 = linear_reg.coef_       # Eğim (1138.34)

# Örnek Tahmin: 11 Yıllık Deneyim
print("11 Yıllık Deneyim Maaş Tahmini:", linear_reg.predict([[11]]))  # ~14.185 TL
2. Çoklu Lineer Regresyon (Multiple Linear Regression)

Gerçek hayatta maaşı sadece deneyim belirlemez; yaş, eğitim veya pozisyon gibi ek etkenler de devreye girer. İşte burada Çoklu Regresyon devreye girer:

                                                                     y = β₀ + β₁x₁ + β₂x₂ + … + βₙxₙ

 

 
Python
# Deneyim ve Yaş değişkenlerini bağımsız değişken olarak seçiyoruz
x = df.iloc[:, [0, 2]].values  # Deneyim ve Yaş
y = df.maas.values.reshape(-1, 1)

multiple_linear_regression = LinearRegression()
multiple_linear_regression.fit(x, y)

print("b0 (Bias):", multiple_linear_regression.intercept_)
print("b1, b2 (Katsayılar):", multiple_linear_regression.coef_)
3. Polinom Regresyon (Polynomial Regression)

Peki ya veri doğrusal bir çizgiye uymayacak kadar kavisliyse? Örneğin araba fiyatı arttıkça maksimum hızın doyuma ulaşması gibi… Bu durumda değişkenlerimizin derecesini artırarak çizgi yerine eğriler çizeriz:

                                                                              y = β₀ + β₁x + β₂x² + … + βₙxⁿ

 
 

PolynomialFeatures kullanarak veriyi önce yüksek dereceli terimlere dönüştürüyor, ardından yine lineer modele veriyoruz:

 
Python
from sklearn.preprocessing import PolynomialFeatures

# 2. Dereceden Polinom Öznitelik Dönüştürücü
polynomial_regression = PolynomialFeatures(degree=2)
x_polynomial = polynomial_regression.fit_transform(x)

# Polinom Özelliklerle Model Eğitimi
linear_regression2 = LinearRegression()
linear_regression2.fit(x_polynomial, y)

# Tahmin ve Görselleştirme
y_head2 = linear_regression2.predict(x_polynomial)
plt.scatter(x, y, color="blue")
plt.plot(x, y_head2, color="green", label="Polynomial Fit")
plt.legend()
plt.show()

 Mühendislik Uyarısı: Polinom derecesini (degree) çok yüksek seçerseniz modeliniz veriyi ezberlemeye başlar ve Overfitting (Aşırı Öğrenme) tuzağına düşersiniz.

1.2. Ağaç Tabanlı Regresyon Mimarileri

Veride sürekli matematiksel denklemler aramak yerine, veriyi mantıksal süzgeçlerden geçirip alt gruplara bölerek tahmin yapan yapılardır.

1. Karar Ağacı Regresyonu (Decision Tree – CART)

Karar ağaçları, veriyi Information Entropy / Variance Reduction kriterlerine dayanarak dallara (split) ayırır. Ağacın en ucundaki yaprak düğümlere (leaf node) düşen veri noktalarının ortalamasını alarak tahminini söyler.

  • Basamaklı Tahmin Eğrisi: Karar ağaçları düz bir çizgi çizmez; belirli aralıklardaki veriler için aynı ortalama değeri ürettiği için basamaklı (step-like) bir grafik oluşturur.

 
Python
from sklearn.tree import DecisionTreeRegressor

tree_reg = DecisionTreeRegressor()
tree_reg.fit(x, y)

# Basamaklı yapıyı net görebilmek için hassas aralık oluşturuyoruz
x_ = np.arange(min(x), max(x), 0.01).reshape(-1, 1)
y_head = tree_reg.predict(x_)

plt.scatter(x, y, color="red")
plt.plot(x_, y_head, color="green")
plt.xlabel("Tribün Level")
plt.ylabel("Ücret")
plt.show()
2. Random Forest Regresyonu (Ensemble Learning)

Tek bir karar ağacı kolayca ezber yapabilir (yüksek varyans). Bu zayıflığı aşmak için Ensemble Learning (Topluluk Öğrenmesi) felsefesini kullanırız.

Random Forest, veri kümesinden rastgele alt kümeler seçerek (Bagging/Bootstrap) onlarca karar ağacı eğitir. Tahmin yaparken tüm ağaçların görüşünü alır ve ortalamasını hesaplar.

 
Python
from sklearn.ensemble import RandomForestRegressor

# 100 Karar Ağacından Oluşan Güçlü Bir Orman
rf = RandomForestRegressor(n_estimators=100, random_state=42)
rf.fit(x, y)

print("Tahmin:", rf.predict([[7.8]]))

⚙️ Best Practice: random_state=42 parametresi rastgele işlemleri sabitleyerek kodunuzun her çalışmasında aynı sonuçları üretmesini (reproducibility) sağlar.

1.3. Model Başarısını Ölçmek ( Score)

Peki kurduğumuz model gerçekten başarılı mı? Bir regresyon modelinin veriyi temsil gücünü ölçmek için Determinasyon Katsayısı ( Score) kullanırız:

 

R2 = 1 − ∑(yi − ŷi)2 ∑(yi − ȳ)2

  • R²  = 1.0: Kusursuz tahmin

  • R²  = 0.0: Model, verilerin basitçe ortalamasını almaktan daha iyi bir performans gösteremiyor.

 
 
Python
from sklearn.metrics import r2_score

# Random Forest R2 Skoru
y_pred_rf = rf.predict(x)
print("Random Forest R2 Score:", r2_score(y, y_pred_rf))  # ~0.979

# Linear Regression R2 Skoru
y_pred_lr = linear_reg.predict(x)
print("Linear Regression R2 Score:", r2_score(y, y_pred_lr)) # ~0.977
Algoritma Karşılaştırma & Mühendislik Kararları
Algoritma Ne Zaman Kullanmalı? Avantajı Dezavantajı / Riskleri
Linear Regression Değişkenler arası doğrusal ilişki varsa. Hızlı, hafif ve tamamen açıklanabilir (interpretable). Karmaşık/eğrisel ilişkileri kaçırır.
Polynomial Regression Veride açık bir kavis/eğri görülüyorsa. Doğrusal olmayan kalıpları çözer. Derece yükseldikçe hızla Overfitting'e kayar.
Decision Tree Karmaşık ve ölçeklenmemiş verilerde. Veri ölçekleme gerektirmez, hızlıdır. Basamaklı tahmin yapar, aşırı dallanırsa ezberler.
Random Forest Yüksek doğruluk ve genelleme istendiğinde. Varyansı düşürür, ezberlemeye karşı dirençlidir. Bellek yükü fazla ve eğitim süresi daha uzundur.
Bölüm 2: Sınıflandırma Algoritmaları ve Karar Sınırları
2.1. Olasılıksal ve Mesafe Tabanlı Sınıflandırıcılar

Regresyonda sürekli değerleri (y E R) tahmin etmeye çalışıyorduk. Sınıflandırmada (Classification) ise amacımız veriyi belirli kesikli sınıflara (örneğin y E {0, 1}) atamaktır.

Sınıflandırma mimarilerine, Derin Öğrenme (Deep Learning) dünyasındaki yapay sinir hücrelerinin (Neuron) de temelini oluşturan Lojistik Regresyon (Logistic Regression) ile başlıyoruz.

1. Lojistik Regresyon Mantığı ve Matematiksel Sezgi

Lojistik Regresyon, adı “regresyon” olmasına rağmen temelde binary (ikili) sınıflandırma yapan olasılıksal bir algoritmadır.

Örneğin bir medikal görüntüleme verisinde hücre özelliklerine bakarak kitleye İyi Huylu (0) veya Kötü Huylu (1) teşhisi koymak klasik bir lojistik regresyon problemidir.

a. Lineer Kombinasyondan Olasılığa

Model ilk olarak girdileri katsayılar (weights) ve sapma (bias) ile çarparak doğrusal bir denkletim elde eder:

                                                            z = wᵀx + b = w₁x₁ + w₂x₂ + … + wₙxₙ + b

Ancak z değeri −∞ ile +∞ arasında her değeri alabilir. Bize ise [0, 1] aralığında bir olasılık değeri gereklidir.

b. Sigmoid Aktivasyon Fonksiyonu

Elde edilen z değerini [0, 1] aralığına sıkıştırmak için Sigmoid (Lojistik) fonksiyonu kullanılır:

 

 

σ(z) = 1 1 + e−z

Olasılık (y_head) = Sigmoid(z)

  • z = +4 ⇒ Sigmoid(4) ≈ 0.98 (%98 olasılıkla Sınıf 1)
  • z = -2 ⇒ Sigmoid(-2) ≈ 0.11 (%10 olasılıkla Sınıf 1 → Sınıf 0)

Neden Sigmoid Kullanıyoruz?

  1. Çıktıyı doğrudan olasılık olarak yorumlamamızı sağlar.
  2. Pürüzsüzdür ve türevi alınabilir (differentiable). Bu özellik, parametreleri Gradient Descent ile güncellerken hayati önem taşır.

c. Karar Eşiği (Decision Threshold)

Gelen olasılık değerini sınıfa dönüştürmek için varsayılan olarak 0.5 karar eşiği kullanılır:

ŷ = { 1, eğer σ(z) ≥ 0.5 | 0, eğer σ(z) < 0.5 }


2. İleri Yayılım (Forward Propagation) ve Kayıp Fonksiyonu (Log Loss)

Eğitim sürecinde girdi verisinden maliyet (cost) hesabına kadar yapılan işlemlere İleri Yayılım (Forward Propagation) denir.

Binary Cross-Entropy (Log Loss)

Modelin tahmin hatasını ölçmek için MSE yerine Lojistik Regresyona özel Log Loss kullanılır:

Loss(ŷ, y) = −&Big( y log(ŷ) + (1 − y) log(1 − ŷ) &Big)
  • Gerçek y = 1 iken tahmin ŷ → 1 ise Hata → 0
  • Gerçek y = 1 iken tahmin ŷ → 0 ise Hata → ∞ (ağır cezalandırılır)

Tüm veri seti (m adet örnek) üzerindeki toplam maliyet ise Cost Function (J) olarak adlandırılır:

J(w, b) = mi=1 Loss(ŷ(i), y(i)) / m

3. Geri Yayılım (Backward Propagation) ve Gradient Descent Optimizasyonu

Maliyeti (J) en küçüklemek için katsayıları (w) ve sapmayı (b) güncellememiz gerekir. Bunun için Gradient Descent (Gradyan İnişi) algoritması ile cost fonksiyonunun parametrelere göre türevi (eğimi) alınır:

∂J / ∂w = (1 / m) X (ŷ − y)T

∂J / ∂b = (1 / m) ∑ (ŷ(i) − y(i))

Güncelleme kuralı:

w := w − α (∂J / ∂w)
b := b − α (∂J / ∂b)

(Buradaki α Learning Rate / Öğrenme Oranı'dır. Çok küçük seçilirse öğrenme çok yavaşlar; çok büyük seçilirse optimum nokta atlanabilir.)


4. Python İle A'dan Z'ye Sıfırdan (From Scratch) Uygulama

Meme Kanseri Teşhis Veri Seti (data.csv) üzerinde sıfırdan bir Lojistik Regresyon motoru inşa edelim.

a. Veri Ön İşleme ve Normalizasyon

Sınıflandırma algoritmalarında farklı ölçekteki özniteliklerin birbirini baskılamaması için Min-Max Normalization uygulanması zorunludur:

Python
import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
from sklearn.model_selection import train_test_split

# Veri setini oku ve gereksiz sütunları temizle
data = pd.read_csv("data.csv")
data.drop(["Unnamed: 32", "id"], axis=1, inplace=True)

# Hedef değişkeni binary yapıya dönüştür (M: Malignant=1, B: Benign=0)
data.diagnosis = [1 if each == "M" else 0 for each in data.diagnosis]

# Bağımsız ve Bağımlı değişkenlerin ayrılması
y = data.diagnosis.values
x_data = data.drop(["diagnosis"], axis=1)

# Normalizasyon: (x - min) / (max - min)
x = (x_data - x_data.min()) / (x_data.max() - x_data.min())
x = x.values

# Train-Test Split (%80 Train, %20 Test)
x_train, x_test, y_train, y_test = train_test_split(x, y, test_size=0.2, random_state=42)

# Matris boyutlarını algoritmik yapıya uyarlama (Feature x Sample)
x_train = x_train.T
x_test = x_test.T
y_train = y_train.T
y_test = y_test.T
b. Ağırlık Başlatma, Forward/Backward & Predict Fonksiyonları
 
 
Python
# 1. Parametre İlklendirme
def initialize_weights_and_bias(dimension):
    w = np.full((dimension, 1), 0.01)
    b = 0.0
    return w, b

# 2. Sigmoid Fonksiyonu
def sigmoid(z):
    return 1 / (1 + np.exp(-z))

# 3. İleri ve Geri Yayılım
def forward_backward_propagation(w, b, x_train, y_train):
    m = x_train.shape[1]
    
    # Forward
    z = np.dot(w.T, x_train) + b
    y_head = sigmoid(z)
    loss = -y_train * np.log(y_head) - (1 - y_train) * np.log(1 - y_head)
    cost = (np.sum(loss)) / m
    
    # Backward
    derivative_weight = (np.dot(x_train, ((y_head - y_train).T))) / m
    derivative_bias = np.sum(y_head - y_train) / m
    
    gradients = {"derivative_weight": derivative_weight, "derivative_bias": derivative_bias}
    return cost, gradients

# 4. Parametre Güncelleme (Gradient Descent)
def update(w, b, x_train, y_train, learning_rate, number_of_iteration):
    cost_list = []
    for i in range(number_of_iteration):
        cost, gradients = forward_backward_propagation(w, b, x_train, y_train)
        cost_list.append(cost)
        
        # Güncelleme
        w = w - learning_rate * gradients["derivative_weight"]
        b = b - learning_rate * gradients["derivative_bias"]
        
    parameters = {"weight": w, "bias": b}
    return parameters, gradients, cost_list

# 5. Tahmin Metodu
def predict(w, b, x_test):
    z = sigmoid(np.dot(w.T, x_test) + b)
    y_prediction = np.zeros((1, x_test.shape[1]))
    
    for i in range(z.shape[1]):
        if z[0, i] <= 0.5:
            y_prediction[0, i] = 0
        else:
            y_prediction[0, i] = 1
    return y_prediction
c. Sıfırdan Modelin Çalıştırılması
 
 
Python
def logistic_regression(x_train, y_train, x_test, y_test, learning_rate, num_iterations):
    dimension = x_train.shape[0]
    w, b = initialize_weights_and_bias(dimension)
    
    parameters, gradients, cost_list = update(w, b, x_train, y_train, learning_rate, num_iterations)
    
    y_prediction_test = predict(parameters["weight"], parameters["bias"], x_test)
    print("Test Accuracy (From Scratch): {:.2f} %".format(100 - np.mean(np.abs(y_prediction_test - y_test)) * 100))

logistic_regression(x_train, y_train, x_test, y_test, learning_rate=1, num_iterations=300)

# Çıktı: Test Accuracy (From Scratch): 96.49 %
5. Scikit-Learn İle Endüstriyel (Production) Uygulama

Sıfırdan yazdığımız bu matematiksel altyapıyı üretim ortamlarında Scikit-Learn kütüphanesi kullanarak tek satırda gerçekleştirebiliriz[cite: 14]:

 
Python
from sklearn.linear_model import LogisticRegression

# Model Tanımlama ve Eğitme
lr = LogisticRegression()
lr.fit(x_train.T, y_train.T)

# Performans Testi
acc = lr.score(x_test.T, y_test.T)
print("Test Accuracy (Scikit-Learn): {:.2f} %".format(acc * 100))

# Çıktı: Test Accuracy (Scikit-Learn): 98.25 %
 Notlar & Mühendislik Detayları
  1. Feature Scaling Zorunluluğu: Lojistik Regresyonda öznitelikler normalize edilmezse yüksek sayısal aralığa sahip öznitelik türevlerin büyüklüğüne domine eder ve Gradient Descent salınım yaparak (oscillation) konverje olamaz[cite: 14].

  2. Karar Eşiği İnce Ayarı (Threshold Tuning): Tıpta yanlış negatifi (Kanser hastasına sağlıklı demek) engellemek için karar eşiği varsayılan 0.5 yerine 0.20.3 gibi daha hassas seviyelere çekilebilir.

  3. Derin Öğrenmeye Geçiş: Lojistik Regresyon, aktivasyon fonksiyonuna sahip en basit tek katmanlı yapay sinir hücresidir (Neuron)[cite: 14]. Bu mimarinin ardışık dizilmesiyle Çok Katmanlı Algılayıcılar (MLP) ve Derin Öğrenme ağları oluşur[cite: 14].

 
2. K-En Yakın Komşu (K-Nearest Neighbors – KNN)

KNN, parametrik olmayan ve “öğrenme” safhası yerine verileri bellekte tutan Lazy Learning (Tembel Öğrenme) mimarisidir.

  • Çalışma Mantığı: Yeni bir test noktası geldiğinde, ona en yakın K adet komşusuna bakılır (genelde Öklid mesafesi kullanılır). Çoğunluk oyu (majority voting) hangi sınıftaysa, yeni veri o sınıfa atanır.

  • Feature Scaling Şartı: Mesafe hesabı yaptığı için özniteliklerin 0 ile 1 arasında normalleştirilmesi (Normalization) şarttır.

 
Python
from sklearn.neighbors import KNeighborsClassifier

# En uygun K değerini hiperparametre aramasıyla bulma
score_list = []
for k in range(1, 15):
    knn = KNeighborsClassifier(n_neighbors=k)
    knn.fit(x_train, y_train)
    score_list.append(knn.score(x_test, y_test))

# En yüksek doğruluk veren k=7 için model
knn = KNeighborsClassifier(n_neighbors=7)
knn.fit(x_train, y_train)
print("KNN (k=7) Accuracy: {:.2f} %".format(knn.score(x_test, y_test) * 100))
3. Naive Bayes Sınıflandırıcısı

Naive Bayes, Bayes Teoremi‘ne dayanan olasılıksal bir algoritmadır.

  • Sınıf Bağımsızlığı Varsayımı (“Naive”): Bütün özniteliklerin birbirinden bağımsız olduğunu varsayar. Bu varsayım gerçek hayatta her zaman tutmasa da algoritma metin sınıflandırma ve spam tespitinde inanılmaz hızlı ve başarılı çalışır.

 
Bayes Teoremi
P(A|B) =
P(B|A) · P(A)
P(B)
Python
from sklearn.naive_bayes import GaussianNB

nb = GaussianNB()
nb.fit(x_train, y_train)
print("Naive Bayes Accuracy: {:.2f} %".format(nb.score(x_test, y_test) * 100))
2.2. Karmaşık Karar Sınırları ve Ağaç Modelleri
1. Destek Vektör Makineleri (Support Vector Machines – SVM)

SVM, iki sınıfı birbirinden en ideal şekilde ayıracak Optimal Hiper Düzlemi (Decision Boundary) çizer.

  • Maximum Margin Classifier: Sınıf sınırlarına en yakın veri noktalarına Destek Vektörleri (Support Vectors) denir. SVM, bu destek vektörleri arasındaki marjin mesafesini maksimize eder.

  • Kernel Trick (Çekirdek Numarası): Veri doğrusal ayrılamıyorsa (non-linear), veriyi daha yüksek boyutlu bir uzaya taşıyarak doğrusal olarak ayrılabilir hale getirir (RBF, Polynomial Kernel).

 
Python
from sklearn.svm import SVC

svm = SVC(random_state=1)
svm.fit(x_train, y_train)
print("SVM Accuracy: {:.2f} %".format(svm.score(x_test, y_test) * 100))
2. Karar Ağacı Sınıflandırması (Decision Tree Classification)

Karar ağaçları, veriyi soru-cevap mantığıyla (if-else yapısı) küçük alt kümelere böler.

  • Bölünme Kriteri (Gini / Entropy): Bölünmenin ne kadar saf (pure) olduğunu ölçmek için Gini Impurity veya Information Entropy kullanılır. Amaç, dallanma sonunda en saf (homojen) yaprak düğümlere (leaf node) ulaşmaktır.

 
Python
from sklearn.tree import DecisionTreeClassifier

dt = DecisionTreeClassifier()
dt.fit(x_train, y_train)
print("Decision Tree Accuracy: {:.2f} %".format(dt.score(x_test, y_test) * 100))
3. Random Forest Sınıflandırması (Ensemble Learning)

Yalnızca tek bir Karar Ağacı kullanmak aşırı öğrenmeye (Overfitting) yol açabilir. Random Forest, yüzlerce ağacın oy birliğiyle karar verdiği bir Topluluk Öğrenmesi (Ensemble Learning) yaklaşımıdır.

 
Python
from sklearn.ensemble import RandomForestClassifier

# 100 adet karar ağacı ile oylama yapan rastgele orman mimarisi
rf = RandomForestClassifier(n_estimators=100, random_state=1)
rf.fit(x_train, y_train)
print("Random Forest Accuracy: {:.2f} %".format(rf.score(x_test, y_test) * 100))
2.3. Model Değerlendirme ve Performans Analizi (Evaluation)

Bir sınıflandırma modelinde yalnızca Accuracy (Doğruluk) metriğine bakmak ölümcül bir mühendislik hatasıdır!

⚠️ Dengesiz Veri (Imbalanced Data) Tuzağı: 1.000.000 veride 990.000 Kedi ve 10.000 Köpek olsun. Hiçbir şey öğrenmeyip “Her şey Kedidir” diyen tembel bir model %99 Accuracy elde eder; fakat Köpekleri tahmin etme başarısı %0’dır! Bu durumu tespit etmek için Confusion Matrix (Karmaşıklık Matrisi) kullanılır.

Confusion Matrix (Karmaşıklık Matrisi) Yapısı

 
Tahmin: 0 (İyi) Tahmin: 1 (Kötü)
Gerçek: 0 (İyi) TN FP
Gerçek: 1 (Kötü) FN TP
  • True Positive (TP): Kötü huyluya kötü denmiş (Doğru Teşhis)
  • True Negative (TN): Sağlıklıya sağlıklı denmiş (Doğru Teşhis)
  • False Positive (FP - Tip I Hata): Sağlıklı birine yanlışlıkla "kansersin" denmiş
  • False Negative (FN - Tip II Hata): Kanseri gözden kaçırıp "sağlıklısın" denmiş (Tıpta en tehlikeli hata!)
Python
import seaborn as sns
import matplotlib.pyplot as plt
from sklearn.metrics import confusion_matrix

# Tahminleri alma ve Matris Oluşturma
y_pred = rf.predict(x_test)
cm = confusion_matrix(y_test, y_pred)

# Heatmap (Isı Haritası) ile Görselleştirme
plt.figure(figsize=(5, 5))
sns.heatmap(cm, annot=True, fmt=".0f", cmap="Blues", linecolor="red", linewidths=0.5)
plt.xlabel("Tahmin Edilen (y_pred)")
plt.ylabel("Gerçek Değer (y_true)")
plt.title("Random Forest Confusion Matrix")
plt.show()
Bölüm 2 Özet & Algoritma Kıyaslama Tablosu
Algoritma Öne Çıkan Özelliği Ölçekleme Şartı mı? En İyi Kullanım Alanı
Logistic Regression Olasılıksal çıktı üretir, hızlıdır. Evet (Normalizasyon) İkili sınıflandırma, Derin Öğrenme temelleri.
KNN Mesafe tabanlı, basittir. Evet (Zorunlu) Küçük/Orta ölçekli pürüzsüz veriler.
SVM Marjin maksimizasyonu yapar. Evet Yüksek boyutlu ve doğrusal ayrılamayan veriler.
Naive Bayes Hızlı olasılık hesabı yapar. Hayır Metin Sınıflandırma, Spam tespiti.
Decision Tree Görselleştirilebilir, if-else yapısındadır. Hayır Açıklanabilirlik istenen tabular veriler.
Random Forest Yüksek doğruluk, overfitting'e dirençlidir. Hayır Karmaşık tabular veriler ve yarışma projeleri.
Bölüm 3: Gözetimsiz Öğrenme (Unsupervised Learning) ve Kümeleme Algoritmaları

Makine öğrenmesi serimizde şu ana kadar hedef değişkenimizin y belli olduğu Gözetimli Öğrenme (Supervised Learning) yöntemlerini —Regresyon ve Sınıflandırma— detaylıca ele aldık. Ancak gerçek hayattaki verilerin büyük bir kısmında herhangi bir etiket (label) bulunmaz.

İşte bu noktada Gözetimsiz Öğrenme (Unsupervised Learning) devreye girer. Amacımız, etiketsiz verideki gizli desenleri, grupları ve ilişkileri keşfetmektir. Bu bölümde gözetimsiz öğrenmenin en popüler iki kümeleme (clustering) mimarisi olan K-Means ve Hiyerarşik Kümeleme (Hierarchical Clustering) yöntemlerini matematiksel sezgisi, SciPy/Scikit-Learn uygulamaları ve görselleştirmeleriyle inceleyeceğiz.

3.1. K-Means Kümeleme Mimarisi

K-Means, veriyi önceden belirlenmiş K adet kümeye bölmeyi hedefleyen, hızlı ve efektif bir kümeleme algoritmasıdır.

1. Algoritmanın Çalışma Mantığı

K-Means adımları şu döngü etrafında şekillenir:

  1. Centroid (Ağırlık Merkezi) Atama: Veri uzayında rastgele K adet merkez (centroid) noktası seçilir.

  2. Kümeye Atama: Her bir veri noktası, kendisine en yakın olan centroid’e atanır (genellikle Öklid mesafesi kullanılır).

  3. Merkez Güncelleme: Oluşan yeni kümelerdeki noktaların ortalaması alınarak centroid’lerin konumları yeniden hesaplanır.

  4. Iterasyon: Centroid’lerin konumları değişmeyene (model konverje olana) kadar 2. ve 3. adımlar tekrarlanır.

2. Optimum K Sayısının Seçimi: Dirsek Metodu (Elbow Method)

“Verimizi kaç kümeye ayırmalıyız?” sorusu gözetimsiz öğrenmenin ana zorluğudur. Bu problemi çözmek için WCSS (Within-Cluster Sum of Squares / Inertia) metriğinden yararlanılır.

WCSS, küme içindeki varyansı ölçer. Küme sayısı K artırıldıkça WCSS düşer; K örnek sayısına eşitlendiğinde WCSS 0 olur. Ancak amaç 0 yapmak değil, kompaktlık ile küme sayısı arasındaki en ideal dengeyi bulmaktır.

💡 Dirsek Noktası (Elbow Point): K değerine karşı WCSS grafiği çizildiğinde, düşüş hızının aniden yavaşladığı ve grafiğin büküldüğü “dirsek” noktası optimum K değerini gösterir.

3. Python Uygulaması (K-Means)

Sentetik bir veri seti oluşturup K-Means algoritmasını ve Dirsek Yöntemini uygulayalım:

 
Python
import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
from sklearn.cluster import KMeans

# 1. 3 farklı gruptan oluşan sentetik veri seti üretimi
x1 = np.random.normal(25, 5, 1000)
y1 = np.random.normal(25, 5, 1000)

x2 = np.random.normal(55, 5, 1000)
y2 = np.random.normal(60, 5, 1000)

x3 = np.random.normal(55, 5, 1000)
y3 = np.random.normal(15, 5, 1000)

x = np.concatenate((x1, x2, x3), axis=0)
y = np.concatenate((y1, y2, y3), axis=0)
data = pd.DataFrame({"x": x, "y": y})

# 2. Dirsek Metodu (Elbow Method) ile optimum K seçimi
wcss = []
for k in range(1, 15):
    kmeans = KMeans(n_clusters=k)
    kmeans.fit(data)
    wcss.append(kmeans.inertia_)  # Inertia = WCSS

# WCSS Grafiği
plt.plot(range(1, 15), wcss)
plt.xlabel("number of k (cluster) value")
plt.ylabel("wcss")
plt.show()  # Dirsek noktası K=3 olarak görülür

# 3. K=3 ile Model Eğitimi ve Tahmin
kmeans2 = KMeans(n_clusters=3)
clusters = kmeans2.fit_predict(data)
data["label"] = clusters

# 4. Kümelerin ve Centroid'lerin Görselleştirilmesi
plt.scatter(data.x[data.label == 0], data.y[data.label == 0], color="red")
plt.scatter(data.x[data.label == 1], data.y[data.label == 1], color="green")
plt.scatter(data.x[data.label == 2], data.y[data.label == 2], color="blue")
# Centroid noktalarını sarı renk ile işaretliyoruz
plt.scatter(kmeans2.cluster_centers_[:, 0], kmeans2.cluster_centers_[:, 1], color="yellow")
plt.show()
3.2. Hiyerarşik Kümeleme (Hierarchical Clustering)

Hiyerarşik Kümeleme, verileri bir ağaç yapısı şeklinde üst üste veya alt alta gruplayan yaklaşımdır. En yaygın kullanılan türü Birleştirici (Agglomerative) yaklaşımdır.

1. Birleştirici (Agglomerative) Yaklaşım
  • Tümevarım Mantığı: Her veri noktası başlangıçta tek başına bir küme kabul edilir.

  • Adım adım birbirine en yakın iki küme birleştirilerek yukarı doğru ilerlenir ve en sonunda tüm noktalar tek bir dev kümede toplanır.

  • Mesafe Bağlantı Kriterleri (Linkage Methods): Kümeler arası uzaklık ölçülürken Ward (küme içi varyansı minimize eder), Complete (en uzak noktalar arası) veya Average (ortalama uzaklık) gibi metodlar kullanılır.

2. Dendrogram Analizi

Hiyerarşik kümelemenin tüm adımlarını ve kümelerin birleşme mesafelerini gösteren ağaç grafiğine Dendrogram denir.

Dendrogram üzerinde yatay bir kesim çizgisi (eşik değeri – threshold) çekilerek veri setinin kaç kümeye ayrılacağına görsel olarak karar verilebilir.

3. Python Uygulaması (Dendrogram & Agglomerative Clustering)

SciPy ve Scikit-Learn kullanarak Hiyerarşik Kümeleme uygulayalım:

 
Python
from scipy.cluster.hierarchy import linkage, dendrogram
from sklearn.cluster import AgglomerativeClustering

# 1. Dendrogram Çizimi (SciPy)
merg = linkage(data, method="ward")  # Ward metodu varyansı minimize eder
dendrogram(merg, leaf_rotation=90)
plt.xlabel("data points")
plt.ylabel("euclidean distance")
plt.show()

# 2. Agglomerative Clustering Modeli (Scikit-Learn)
hiyerartical_cluster = AgglomerativeClustering(n_clusters=3, metric="euclidean", linkage="ward")
cluster = hiyerartical_cluster.fit_predict(data)
data["label"] = cluster

# 3. Kümelerin Görselleştirilmesi
plt.scatter(data.x[data.label == 0], data.y[data.label == 0], color="red")
plt.scatter(data.x[data.label == 1], data.y[data.label == 1], color="green")
plt.scatter(data.x[data.label == 2], data.y[data.label == 2], color="blue")
plt.show()
K-Means vs. Hiyerarşik Kümeleme Karşılaştırması
 
Özellik K-Means Kümeleme Hiyerarşik Kümeleme (Agglomerative)
Küme Sayısı (K) Önceden tanımlanmalıdır (K belirlemek şarttır). Dendrogram üzerinden sonradan kesim yapılabilir.
Hız ve Ölçeklenebilirlik Çok hızlıdır, büyük veri setlerine uygundur. Hesaplama karmaşıklığı yüksektir, büyük veride yavaştır.
Çıktı Yapısı Düzlemsel kümeleme (Flat clustering) yapar. Ağaç yapılı (Dendrogram) hiyerarşik ilişki sunar.
Hassasiyet İlk seçilen centroid'lere (initialization) duyarlıdır. Deterministiktir, her çalışmada aynı hiyerarşiyi üretir.
Bölüm 4: Doğal Dil İşleme (NLP) Esasları ve Metin Sınıflandırma
 
Makine öğrenmesi modelleri sayısal vektörlerle çalışır. Ancak gerçek hayattaki verilerin büyük bir kısmı —müşteri yorumları, e-postalar, sosyal medya gönderileri, haber metinleri— yapısal olmayan metin (unstructured text) formatındadır.

Doğal Dil İşleme (Natural Language Processing – NLP), insan dilini bilgisayarların anlayabileceği ve işleyebileceği matematiksel formata dönüştürme disiplinidir. Siri gibi sesli asistanlardan döküman özetlemeye, duygu analizinden (sentiment analysis) metin sınıflandırmaya kadar pek çok alanın temelini oluşturur.

Bu bölümde, ham metin verisini bir ML modeline hazırlama süreçlerini (Text Preprocessing), Bag of Words (Kelime Çantası) yöntemiyle vektörleştirmeyi ve Twitter Cinsiyet Sınıflandırması vaka çalışmasını inceleyeceğiz.

4.1. Metin Ön İşleme (Text Preprocessing) Pipeline

Ham metin verisi gürültücüdür (noktalama işaretleri, özel karakterler, büyük/küçük harf karmaşası, etkisiz kelimeler). Başarılı bir NLP modelinin %80’i doğru bir temizleme boru hattından (preprocessing pipeline) geçer.

Metin temizleme adımlarını sırasıyla uygulayalım:

  1. Özel Karakter Temizliği (Regex): Harf dışındaki tüm rakam ve noktalama işaretlerinin (:), /, @ vb.) temizlenmesi.

  2. Küçük Harfe Çevirme (Lowercasing): Best ile best kelimelerinin farklı algılanmasını önlemek için standart küçük harf dönüşümü.

  3. Tokenization (Kelimelerine Ayırma): Cümlenin bağımsız kelime birimlerine (token) bölünmesi.

  4. Stopwords Eliminasyonu (Etkisiz Kelimeler): Dilin yapısında sık geçen ancak anlamsal ayırt ediciliği olmayan (the, and, is, for vb.) kelimelerin ayıklanması.

  5. Lemmatization (Kök Bulma): Kelimelerin eklerini atarak sözlük köklerine (loved —> love, gigs –> gig) indirgenmesi.

Tek Bir Metin Üzerinde Ön İşleme Örneği:
 
Python
import re
import nltk
from nltk.corpus import stopwords
import nltk as nlp

# Gerekli NLTK paketlerinin indirilmesi
nltk.download('punkt')
nltk.download('stopwords')
nltk.download('wordnet')

description = "Ricky Wilson The Best FRONTMAN/Kaiser Chiefs The Best BAND Xxxx Thank you Kaiser Chiefs for an incredible year of gigs and memories to cherish always:)"

# 1. Regex ile sadece harfleri alma
description = re.sub("[^a-zA-Z]", " ", description)

# 2. Küçük harfe dönüştürme
description = description.lower()

# 3. Tokenization (Kelimelerine ayırma)
description = nltk.word_tokenize(description)

# 4. Stopwords (Gereksiz kelimeler) çıkarma
description = [word for word in description if not word in set(stopwords.words("english"))]

# 5. Lemmatization (Köklerine ayırma)
lemma = nlp.WordNetLemmatizer()
description = [lemma.lemmatize(word) for word in description]

# Tekrar cümle haline getirme
description = " ".join(description)
# Çıktı: 'ricky wilson best frontman kaiser chief best band xxxx thank kaiser chief incredible year gig memory cherish always xxxxxxx'
4.2. Vektörleştirme: Bag of Words (BoW) Yöntemi

Metinler temizlendikten sonra sayılara dönüştürülmelidir. Bag of Words (Kelime Çantası), en temel ve etkili öznitelik çıkarma (feature extraction) yöntemlerinden biridir.

  • Çalışma Prensibi: Bütün dökümanlarda geçen benzersiz (unique) kelimelerden bir kelime hazinesi (vocabulary) oluşturulur.

  • Her bir metin/cümle bir satır, vocabulary’deki her kelime bir sütun (feature) olur.

  • İlgili kelime cümlede geçiyorsa frekansı (veya varlığına göre 1/0) matrise yazılır. Bu yüksek boyutlu ve bol sıfırlı yapıya Sparse Matrix (Seyrek Matris) denir.

 
Python
from sklearn.feature_extraction.text import CountVectorizer

# En sık kullanılan 10.000 kelimeyi öznitelik olarak belirleme
max_features = 10000
count_vectorizer = CountVectorizer(max_features=max_features, stop_words="english")

# Metin listesini seyrek matrise dönüştürme
sparce_matrix = count_vectorizer.fit_transform(description_list).toarray()
4.3. Vaka Çalışması: Twitter Cinsiyet Sınıflandırma Model

Twitter kullanıcılarının profil açıklamalarından (description) cinsiyetlerini (female = 1, male = 0) tahmin eden uçtan uca bir NLP modeli oluşturalım[cite: 23].

 

1. Veri Hazırlığı ve Ön İşleme Döngüsü

Python
import pandas as pd

# Veri setini yükleme
data = pd.read_csv("gender_classifier.csv", encoding="latin1")
data = pd.concat([data.gender, data.description], axis=1)
data.dropna(axis=0, inplace=True)

# Etiket kodlama: Female -> 1, Male -> 0
data.gender = [1 if each == "female" else 0 for each in data.gender]

# Bütün veri seti için temizlik döngüsü
description_list = []
for description in data.description:
    description = re.sub("[^a-zA-Z]", " ", description)
    description = description.lower()
    description = nltk.word_tokenize(description)
    lemma = nlp.WordNetLemmatizer()
    description = [lemma.lemmatize(word) for word in description]
    description = " ".join(description)
    description_list.append(description)
2. Modelleme ve Doğruluk Testi

Sayısal vektörlere dönüştürdüğümüz veriyi Naive Bayes sınıflandırıcısı ile eğitelim[cite: 23]:

 
Python
from sklearn.model_selection import train_test_split
from sklearn.naive_bayes import GaussianNB

# X: Bag of Words Matrisi, Y: Cinsiyet Etiketleri
x = sparce_matrix
y = data.iloc[:, 0].values

# Train-Test Ayrımı (%90 Train, %10 Test)
x_train, x_test, y_train, y_test = train_test_split(x, y, test_size=0.1, random_state=42)

# Naive Bayes Modeli
nb = GaussianNB()
nb.fit(x_train, y_train)

# Tahmin ve Accuracy
print("Test Accuracy: {:.2f} %".format(nb.score(x_test, y_test) * 100))
# Çıktı: Test Accuracy: 55.82 %
💡 AI Engineer Değerlendirmesi: Model Başarısı Neden %55.82 Kaldı?

Metin sınıflandırma modelimizde elde ettiğimiz %55.82 doğruluk oranı, rastgele tahmin yapmaya (%50) oldukça yakındır[cite: 23]. Bir Yapay Zeka Mühendisi olarak bu sonucu şöyle analiz etmeliyiz[cite: 23]:

  1. GaussianNB vs. Seyrek Matris Uyumsuzluğu: GaussianNB, sürekli ve normal dağılan veriler için tasarlanmıştır[cite: 23]. Seyrek (0/1 ağırlıklı) metin matrislerinde MultinomialNB veya BernoulliNB kullanmak doğruluk oranını doğrudan %70-80 seviyesine çıkarır[cite: 23].

  2. Kelime Frekansı Eksikliği (TF-IDF İhtiyacı): Sadece kelime saymak (CountVectorizer) yerine, nadir geçen ama anlamsal değeri yüksek kelimeleri öne çıkaran TF-IDF (Term Frequency-Inverse Document Frequency) vektörleştirmesi tercih edilmelidir.

  3. Twitter Bios Karmaşıklığı: İnsanların profil biyografileri oldukça kısa, imlasız ve jargondur[cite: 23]. Bu tür verilerde bağlamı yakalamak için Word Embeddings (Word2Vec, GloVe) veya Transformer tabanlı modeller (BERT) daha üstün performans gösterir.

 
Bölüm 5: Boyut İndirgeme ve Temel Bileşen Analizi (PCA)

Makine öğrenmesi projelerinde veri setimizin öznitelik (feature) sayısı arttıkça modelin eğitilmesi zorlaşır, işlem maliyeti artar ve yüksek boyutlu uzayda verinin yapısını anlamak/görselleştirmek neredeyse imkansız hale gelir. Bu durum zeka literatüründe “Boyut Laneti” (Curse of Dimensionality) olarak adlandırılır.

Temel Bileşen Analizi (Principal Component Analysis – PCA), gözetimsiz (unsupervised) bir boyut indirgeme tekniğidir. Temel amacı; verideki bilgi kaybını (varyansı) minimize ederek çok boyutlu bir veri setini daha az sayıda bileşene (component) dönüştürmektir.

Bu bölümde, PCA’in matematiksel mantığını, varyans maksimizasyonunu, Scikit-Learn ile 4 boyutlu Iris veri setini 2 boyuta düşürmeyi ve görselleştirmeyi inceleyeceğiz.

5.1. PCA Nedir ve Nasıl Çalışır?

PCA, veriyi birbirine dik (orthogonal) yeni eksenlere atar. Bu yeni eksenlere Temel Bileşenler (Principal Components) adı verilir.

  • Varyans Maksimizasyonu: PCA yaparken ana hedef verideki dağılımı (varyansı) en iyi temsil eden doğruları bulmaktır. İlk bileşen (P1), verideki en yüksek varyansı temsil eden eksendir. İkinci bileşen (P2) ise P1‘e dik olan ve kalan varyansın en büyük kısmını açıklayan eksendir.

  • Feature Scaling (Normalizasyon) Şartı: Eğer özniteliklerden biri 0-1 aralığında, diğeri 1.000.000 seviyesinde ise yüksek değerli olan öznitelik varyans hesabını domine eder. Bu nedenle PCA öncesi veriyi ölçeklendirmek (Scaling/Whiten) şarttır.

💡 Neden Boyut İndirgeriz?

  1. Yüksek boyutlu verileri 2D veya 3D düzlemde görselleştirmek için.

  2. Eğitimi hızlandırmak ve bellek/işlemci yükünü hafifletmek için.

  3. Öznitelikler arası yüksek korelasyonu (Multicollinearity) ortadan kaldırmak için.

5.2. Scikit-Learn ile 4D -> 2D İndirgeme Vaka Çalışması (Iris Veri Seti)

4 farklı ölçüm özelliğine (sepal length, sepal width, petal length, petal width) sahip olan Iris çiçeği veri setini 2 temel bileşene (P1 ve P2) dönüştürelim.

1. Veriyi Yükleme ve Hazırlama
 
Python
import pandas as pd
from sklearn.datasets import load_iris

# Iris veri setinin yüklenmesi
iris = load_iris()
data = iris.data
feature_names = iris.feature_names
y = iris.target

df = pd.DataFrame(data, columns=feature_names)
df["sinif"] = y
x = data

# df.head() -> 4 adet sayısal öznitelik ve 1 adet sınıf sütunu içerir
2. PCA Modelinin Uygulanması

Scikit-Learn’ün PCA sınıfını kullanarak 4 boyutlu matrisi 2 bileşene düşürelim. whiten=True parametresi ile otomatik normalizasyon sağlıyoruz:

 
Python
from sklearn.decomposition import PCA

# 2 bileşenli PCA modeli oluşturma
pca = PCA(n_components=2, whiten=True)

# Modeli eğitme ve veriyi dönüştürme (Fit & Transform)
pca.fit(x)
x_pca = pca.transform(x)

# Bileşenleri DataFrame'e ekleme
df["p1"] = x_pca[:, 0]
df["p2"] = x_pca[:, 1]
5.3. AÇıklanan Varyans Oranı (Explained Variance Ratio) ve Görselleştirme

Boyut indirgeme yaparken verideki bilginin ne kadarını koruyabildiğimizi Explained Variance Ratio metriği ile ölçeriz.

 
Python
# Her bir bileşenin açıkladığı varyans oranı
print("Variance Ratio:", pca.explained_variance_ratio_)
# Çıktı: [0.92461872, 0.05306648] -> P1 %92.4'ünü, P2 %5.3'ünü açıklar.

# Toplam Korunan Bilgi / Varyans Oranı
print("Total Explained Variance:", sum(pca.explained_variance_ratio_))
# Çıktı: 0.9776852063187979 (%97.77 bilgi korunmuştur).

Mühendislik Yorumu: Verimizin boyutunu %50 azalttık (4 boyuttan 2 boyuta düşürdük) ancak orijinal verideki bilginin %97.77’sini korumayı başardık! Sadece %2.23’lük küçük bir bilgi kaybı yaşandı.

2D Düzlemde Görselleştirme

Orijinalde 4D olduğu için grafik çizdiremediğimiz veriyi, elde ettiğimiz P1 ve P2 bileşenleriyle 2D düzlemde görselleştirelim:

 
Python
import matplotlib.pyplot as plt

color = ["red", "green", "blue"]  # 3 sınıf için 3 farklı renk

for each in range(3):
    plt.scatter(df.p1[df.sinif == each], df.p2[df.sinif == each], color=color[each], label=iris.target_names[each])

plt.legend()
plt.xlabel("p1")
plt.ylabel("p2")
plt.title("Iris Dataset PCA (4D -> 2D)")
plt.show()

Görselleştirme sonucunda; 2 boyuta indirgenmiş olmasına rağmen çiçeğe ait sınıfların (Setosa, Versicolor, Virginica) belirgin sınırlarla birbirinden ayrılabildiği net şekilde görülmektedir.

 
PCA Kullanımında Dikkat Edilmesi Gerekenler
Parametre / Konu Açıklama / Mühendislik Notu
Öznitelik Ölçekleme (Scaling) PCA yapmadan önce öznitelikler mutlaka standartlaştırılmalı / normalize edilmelidir.
Açıklanan Varyans Eşiği Endüstride genellikle toplam varyansın en az %90 - %95'ini koruyan bileşen sayısı (N) seçilir.
Anlaşılabilirlik (Interpretability) PCA sonrası elde edilen P1, P2 terimleri orijinal özniteliklerin kombinasyonu olduğu için anlamlandırmak zordur.
Bölüm 6: Model Seçimi, Çapraz Doğrulama ve Hiperparametre Optimizasyonu

Makine öğrenmesi modellerini eğitip yüksek başarım skorları elde etmek harika görünse de şu soru her zaman akılda kalır: “Modelimiz gerçekten öğrendi mi, yoksa veriyi ezberledi mi (Overfitting)?”

 

Bir modeli yalnızca tek bir rastgele train/test bölünmesiyle değerlendirmek yanıltıcı olabilir. Model bir veri kümesinde %89 doğruluk sağlarken başka bir test setinde %60 doğruluk veriyorsa ciddi bir tutarsızlık ve aşırı öğrenme (overfitting) problemiyle karşı karşıyayız demektir.

Bu bölümde; modellerimizin güvenilirliğini ölçen K-Fold Cross Validation (Çapraz Doğrulama) yöntemini ve model parametrelerini en üst seviyeye çıkaran Grid Search CV (Izgara Araması) tekniğini Scikit-Learn uygulamalarıyla detaylandıracağız.

6.1. K-Fold Cross Validation (K-Katlı Çapraz Doğrulama)

K-Fold Cross Validation, modelin genelleştirme yeteneğini ve varyansını doğru değerlendirmek için veriyi $K$ adet eşit parçaya (fold) bölen bir doğrulama tekniğidir.

1. Çalışma Mantığı

Veri seti K parçaya bölündüğünde işlem adım adım şöyle işler:

  1. K-1 adet parça Train (Eğitim) verisi olarak seçilir.

  2. Kalan 1 parça ise Validation (Doğrulama) verisi olarak ayrılır ve model test edilir.

  3. Bu süreç K defa tekrarlanır; her adımda farklı bir parça validation kümesi olur.

  4. En sonunda K adet doğruluk skoru elde edilir. Bu skorların ortalaması (mean) modelin gerçek performansını, standart sapması (std) ise modelin ne kadar kararlı olduğunu gösterir.

2. Python ile K-Fold Cross Validation (KNN Örneği)

Iris veri setimizi Min-Max normalizasyonundan geçirip K-Nearest Neighbors (KNN) modeli üzerinde K=10 katlı çapraz doğrulama uygulayalım:

 
Python
import numpy as np
import pandas as pd
from sklearn.datasets import load_iris
from sklearn.model_selection import train_test_split, cross_val_score
from sklearn.neighbors import KNeighborsClassifier

# 1. Veri Hazırlığı ve Normalizasyon
iris = load_iris()
x = iris.data
y = iris.target

# Normalizasyon (KNN mesafe tabanlı olduğu için şarttır)
x = (x - np.min(x)) / (np.max(x) - np.min(x))

# Train-Test Split (%70 Train, %30 Test)
x_train, x_test, y_train, y_test = train_test_split(x, y, test_size=0.3, random_state=42)

# 2. KNN Modelinin Tanımlanması (k=3)
knn = KNeighborsClassifier(n_neighbors=3)

# 3. K-Fold Cross Validation (cv=10)
# Train verimizi 10 parçaya bölüp çapraz doğrulama yapıyoruz
accuracies = cross_val_score(estimator=knn, X=x_train, y=y_train, cv=10)

print("10 Fold Accuracy Değerleri:\n", accuracies)
print("Ortalama Accuracy (Average Accuracy): {:.2f} %".format(np.mean(accuracies) * 100))
print("Standart Sapma (Standard Deviation): {:.4f}".format(np.std(accuracies)))

# Çıktı: Average Accuracy: 97.09 %, Std: 0.0445
# Standart sapmanın küçük olması modelin kararlı (stable) çalıştığını gösterir!

Eğitim setinde doğrulamayı başarıyla tamamladıktan sonra modelimizi nihai olarak test verimizde deneriz:

 
Python
knn.fit(x_train, y_train)
print("Test Accuracy: {:.2f} %".format(knn.score(x_test, y_test) * 100))

# Çıktı: Test Accuracy: 95.56 %
6.2. Hiperparametre Optimizasyonu: Grid Search CV

Bir makine öğrenmesi algoritmasının eğitilebilmesi için dışarıdan bizim tanımladığımız parametrelere Hiperparametre (Hyperparameter) denir (örneğin KNN’deki komşu sayısı n_neighbors veya Lojistik Regresyondaki C ve penalty terimleri).

Deneme-yanılma yapmadan en optimum hiperparametre kombinasyonlarını bulmak için Grid Search CV (Izgara Araması Çapraz Doğrulama) kullanılır.

1. KNN İle Optimum Komşu Sayısını (K) Bulma

KNN için 1‘den 50‘ye kadar olan komşu sayılarını 10-Fold Cross Validation ile tarayalım:

 
Python
from sklearn.model_selection import GridSearchCV

# Aranacak hiperparametre aralığı
grid = {"n_neighbors": np.arange(1, 50)}
knn = KNeighborsClassifier()

# Grid Search CV Modeli
knn_cv = GridSearchCV(knn, grid, cv=10)
knn_cv.fit(x, y)

print("En Optimum K Değeri (Tuned K):", knn_cv.best_params_)
print("En İyi Accuracy Skor (Best Score): {:.2f} %".format(knn_cv.best_score_ * 100))

# Çıktı: Tuned K: {'n_neighbors': 13}, Best Score: 98.00 %
2. Lojistik Regresyon İle Karmaşık Parametre Arama

Lojistik Regresyon algoritmasında aşırı öğrenmeyi engelleyen Düzenlileştirme (Regularization – C) ve Kayıp Cezası (Penalty: L1/L2) parametrelerini optimize edelim:

  • C Parametresi: Düzenlileştirme gücünü temsil eder. Çok büyük C değerleri aşırı öğrenmeye (overfitting), çok küçük C değerleri yetersiz öğrenmeye (underfitting) yol açabilir.

  • Penalty (L1 vs. L2): L1 (Lasso) lüzumsuz öznitelik katsayılarını sıfırlayarak öznitelik seçimi yapar; L2 (Ridge) ise katsayıları küçülterek varyansı düşürür.

 
 
Python
from sklearn.linear_model import LogisticRegression

# Iris veri setinden ikili sınıflandırma alanı seçimi (ilk 2 sınıf)
x_binary = x[:100, :]
y_binary = y[:100]

x_train, x_test, y_train, y_test = train_test_split(x_binary, y_binary, test_size=0.3, random_state=42)

# Hiperparametre Izgarası
grid = {
    "C": np.logspace(-3, 3, 7),  # 0.001'den 1000'e kadar değerler
    "penalty": ["l1", "l2"]      # L1 (Lasso) ve L2 (Ridge)
}

# Logistic Regression Modeli
logreg = LogisticRegression(solver='liblinear', max_iter=1000)
logreg_cv = GridSearchCV(logreg, grid, cv=10)
logreg_cv.fit(x_train, y_train)

print("Tuned Hyperparameters:", logreg_cv.best_params_)
print("Best Validation Accuracy: {:.2f} %".format(logreg_cv.best_score_ * 100))

# Elde edilen optimum parametrelerle testi gerçekleştirme
best_logreg = LogisticRegression(C=1.0, penalty="l1", solver="liblinear", max_iter=1000)
best_logreg.fit(x_train, y_train)
print("Test Set Accuracy: {:.2f} %".format(best_logreg.score(x_test, y_test) * 100))

# Çıktı: Best Parameters: {'C': 1.0, 'penalty': 'l1'}, Test Set Accuracy: 100 %
Bias-Variance Trade-off (Yanlılık ve Varyans Dengesi)

Makine öğrenmesinde nihai amacımız Bias (Yanlılık) ile Variance (Varyans) arasında kusursuz bir denge kurmaktır.

 
Makine Öğrenmesi Notları

Bias - Variance Dengesi ve Model Genelleştirme

  • Eğilim / Bias Yüksek Bias (Underfitting)

    Model verideki karmaşık ilişkiyi yakalayamayacak kadar basittir. Hem eğitim (train) hem de test skorları oldukça düşüktür.

  • Varyans / Variance Yüksek Variance (Overfitting)

    Model eğitim verisini ezberlemiştir. Eğitim skoru çok yüksek (%99) iken test kümesindeki skoru belirgin şekilde düşüktür.

  • İdeal Durum Optimum Model

    K-Fold Cross Validation ve Grid Search CV teknikleri ile hiperparametreleri tune edilmiş, varyansı düşürülmüş ve genelleştirme (generalization) yeteneği en üst düzeye çıkarılmış modeldir.

Özet & Best Practice Tavsiyeleri
Yöntem / Metrik Kullanım Amacı Mühendislik İpucu
K-Fold CV Overfitting riskini ölçmek ve kararlılığı test etmek. K değeri endüstri standardı olarak genellikle 5 veya 10 seçilir.
Grid Search CV Algoritmanın en iyi parametrelerini bulmak. Arama uzayı büyükse işlem süresini kısaltmak için RandomizedSearchCV de tercih edilebilir.
Data Leakage Önleme Doğru ölçekleme ve değerlendirme. Grid Search CV işlemleri sadece Train veri seti üzerinde yapılmalı, Test veri seti en sona saklanmalıdır.
Bölüm 7: Öneri Sistemleri (Recommendation Systems) ve Ürün Öneri Motoru Mimarisi

Günümüzde Netflix, Amazon, Spotify veya YouTube gibi dev dijital platformların başarısının arkasındaki en büyük güçlerden biri Öneri Sistemleri (Recommendation Systems) mimarileridir.

Öneri sistemleri, kullanıcıların geçmişteki davranışlarını (izleme, beğenme, satın alma, puanlama) analiz ederek onların gelecekte hangi içerik veya ürünü tercih edebileceğini tahmin eden algoritmik yapılardır.

Bu bölümde; İşbirlikçi Filtreleme (Collaborative Filtering) yaklaşımlarını, User-Based ve Item-Based sistemlerin farklarını ve Python / Pandas kullanarak MovieLens veri seti üzerinde adım adım bir Item-Based Öneri Motoru geliştirmeyi inceleyeceğiz.

7.1. İşbirlikçi Filtreleme (Collaborative Filtering) Yöntemleri

İşbirlikçi Filtreleme, bir kullanıcının geçmiş deneyimlerini diğer kullanıcıların deneyimleriyle harmanlayarak kişiselleştirilmiş öneriler sunar.

Bu yaklaşım temelde iki ana kategoriye ayrılır:

1. Kullanıcı Tabanlı Filtreleme (User-Based Collaborative Filtering)
  • Mantık: “Bana benzeyen kullanıcılar neleri izledi/aldı?”

     

  • Çalışma Şekli: Kullanıcılar (satırlar) ve Öğeler (sütunlar) içeren bir etkileşim matrisi oluşturulur. Kullanıcılar arasındaki benzerlik skorları (Örn: Cosine Similarity, Pearson Correlation) hesaplanır. Benzer zevklere sahip kullanıcıların izlediği ama hedef kullanıcının henüz izlemediği içerikler önerilir.

  • Dezavantajları ve Mühendislik Zorlukları:

    1. Yüksek İşlem Maliyeti: Dünya üzerinde yüz milyonlarca kullanıcı bulunur. Her kullanıcıyı diğer milyonlarca kullanıcıyla kıyaslamak devasa bir işlem gücü (computational power) gerektirir.

    2. Dinamik Kullanıcı Davranışları: İnsanların zevkleri ve alışkanlıkları zamanla değişebilir. Bu durum önerilerin zamanla doğruluğunu kaybetmesine yol açar.

2. Öğe Tabanlı Filtreleme (Item-Based Collaborative Filtering)
  • Mantık: “Bu filmi/ürünü beğenen kullanıcılar başka hangi filmleri/ürünleri beğendi?”

     

  • Çalışma Şekli: Kullanıcılar yerine ürünler/içerikler birbiriyle kıyaslanır. İki filmin puanlama kalıpları birbirine benziyorsa bu iki film “benzer” kabul edilir.

  • Mühendislik Avantajları:

    1. Sabit Öğe Yapısı: İçeriklerin/ürünlerin kimliği ve doğası insan davranışı gibi sürekli değişmez.

    2. Düşük İşlem Yükü: Sistemlerdeki toplam ürün/film sayısı genelde kullanıcı sayısından çok daha azdır. Bu yüzden sütunlar arası benzerlik hesaplamak mantıksal ve sistemsel açıdan çok daha verimlidir.

7.2. Python ile Item-Based Öneri Motoru Uygulaması

MovieLens film ve puanlama (rating) veri setlerini birleştirerek, belirli bir filmi (Bad Boys (1995)) izleyen bir kullanıcıya en benzer diğer filmleri öneren bir algoritma kurgulayalım.

1. Veri Setinin Yüklenmesi ve Birleştirilmesi
 
Python
import pandas as pd

# Film ve Puanlama veri setlerinin okunması
movie = pd.read_csv("movie.csv")  # movieId, title, genres
rating = pd.read_csv("rating.csv")  # userId, movieId, rating, timestamp

# Yalnızca ihtiyacımız olan sütunların seçilmesi
movie = movie.loc[:, ["movieId", "title"]]
rating = rating.loc[:, ["userId", "movieId", "rating"]]

# Veri setlerinin movieId üzerinden birleştirilmesi (Merge)
data = pd.merge(movie, rating)
print("Veri Seti Şekli (Orijinal):", data.shape)  # Yaklaşık 20 Milyon satır

# İşlem bellek sınırlarını aşmamak için ilk 1.000.000 örneği alıyoruz
data = data.iloc[:1000000, :]
2. Kullanıcı-Öğe Matrisinin (Pivot Table) Oluşturulması

Öneri sistemimizin kalbi olan matris düzeninde satırlar kullanıcıları (userId), sütunlar filmleri (title) ve hücreler verilen puanları (rating) temsil eder:

Python
# User-Item Matrisi
pivot_table = data.pivot_table(index=["userId"], columns=["title"], values="rating")
pivot_table.head()
3. Benzerlik Skorlarının Hesaplanması ve Öneri Üretimi

Eğer bir kullanıcı “Bad Boys (1995)” filmini izlediyse, bu filme benzer puanlama kalıbına sahip diğer filmleri corrwith() fonksiyonu (Korelasyon Analizi) ile tespit edelim:

 
Python
# İzlenen filmin kullanıcı puanlama vektörü
movie_watched = pivot_table["Bad Boys (1995)"]

# Hedef film ile diğer tüm filmler arasındaki korelasyon hesabı
similarity_with_other_movies = pivot_table.corrwith(movie_watched)

# Benzerlik skorlarına göre yüksekten düşüğe sıralama
similarity_with_other_movies = similarity_with_other_movies.sort_values(ascending=False)

# En yüksek benzerliğe sahip ilk filmler
print(similarity_with_other_movies.head(5))

Örnek Çıktı ve Öneri Sonucu:

 
Output / Console
title
Bad Boys (1995)                        1.000000
Headless Body in Topless Bar (1995)    0.723747
Last Summer in the Hamptons (1995)     0.607554
Two Bits (1995)                        0.507008
Shadows (Cienie) (1988)                 0.494186

Mühendislik Yorumu: “Bad Boys (1995)” filmini izleyen bir kullanıcıya sistemimiz otomatik olarak en yüksek korelasyona (0.72) sahip olan “Headless Body in Topless Bar (1995)” filmini önermelidir[cite: 26].

⚙️ Production Ortamında Öneri Sistemleri & Best Practice’ler
  1. Oy Sayısı Filtreleme (Popularity Threshold): Yalnızca 1 kişinin 5 puan verdiği marjinal filmler yüksek korelasyon gösterip önerileri domine edebilir[cite: 26]. Bu yüzden korelasyon hesabına geçmeden önce minimum oy sınırı (örneğin en az 100 oy almış filmler) koymak kritik önem taşır[cite: 26].

  2. Cold Start Problemi: Sisteme yeni giren bir kullanıcının veya yeni eklenen bir ürünün geçmiş verisi olmadığı için tavsiye üretilemez. Bu durum popüler içerikler gösterilerek veya İçerik Tabanlı (Content-Based) yöntemlerle çözülür.

  3. Hibrit Yaklaşımlar (Hybrid Recommender Systems): Gerçek hayat sistemlerinde (Netflix/Amazon) en iyi sonuçlar Collaborative Filtering ve Content-Based yöntemlerin birleşimiyle elde edilir.

 
Sonuç ve Gelecek Adımlar

Giriş modülünden başlayıp Gözetimli Öğrenme (Regresyon & Sınıflandırma), Gözetimsiz Öğrenme (Kümeleme & Boyut İndirgeme), Doğal Dil İşleme (NLP), Model Seçimi / Optimizasyon ve Tavsiye Sistemleri başlıklarını kapsayan Uygulamalı Makine Öğrenmesi Mühendisliği Rehberi serimizin sonuna geldik.

Bu serinin temel amacı; makine öğrenmesi algoritmalarını yalnızca teorik veya matematiksel birer denklem olarak bırakmayıp, gerçek dünya problemlerine uygulayabilecek mühendislik sezgisini ve kod pratiklerini kazandırmaktı.

 Neler Başardık?
  • Modelleme Disiplini: Farklı problem tiplerinde (sürekli değer tahmini, sınıflandırma veya kümeleme) hangi algoritmanın hangi senaryoda tercih edilmesi gerektiğini senaryolarla ele aldık.

  • Veri Hazırlığı Pipeline’ları: Ham metinlerden özellik çıkarma (Bag of Words), boyut küçültme (PCA) ve ölçekleme (Normalization) gibi veriyi profile hazırlama adımlarını işledik.

  • Model Güvenilirliği: Yalnızca eğitim başarısına odaklanmak yerine K-Fold Cross Validation ve Grid Search CV ile modellerimizin genelleştirme yeteneğini ve karar mekanizmasını optimize ettik.

 Proje Kodları ve Jupyter Notebook Kaynakları

Söz konusu teorik ve pratik anlatımların tamamına, veri setlerine ve hazırlanan tüm Jupyter Notebook (.ipynb) dosyalarına projemizin resmi GitHub deposu üzerinden ulaşabilirsiniz.

Kendi yerel ortamınızda notebook’ları çalıştırmak, kodlar üzerinde denemeler yapmak ve katkıda bulunmak için repoyu çatallayabilir (fork) veya yıldızlayabilirsiniz (star):

 GitHub Deposu: github.com/Rasittekin18/4-Machine_Learning

 

Yorum bırakın

E-posta adresiniz yayınlanmayacak. Gerekli alanlar * ile işaretlenmişlerdir