Supply Chain AI

AI Supply Chain Optimization

Yapay zeka ile tedarik zinciri optimizasyonu. Demand forecasting, inventory management, route optimization, predictive maintenance ve supplier risk assessment.

🚚AI Supply Chain Kullanım Alanları

AI-powered supply chain, envanter maliyetlerini %25-35 azaltır, teslimat sürelerini %20-30 kısaltır ve stok tükenme oranını %40 düşürür.

Demand Planning

• Talep tahmini (forecasting)
• Sezonallik analizi
• Promotion impact
• New product demand

Inventory Management

• Optimal stock levels
• Reorder point calculation
• Safety stock optimization
• Dead stock prediction

Logistics

• Route optimization
• Fleet management
• Warehouse optimization
• Last-mile delivery

Demand Forecasting (LSTM)

# Deep Learning ile talep tahmini
import pandas as pd
import numpy as np
from tensorflow.keras.models import Sequential
from tensorflow.keras.layers import LSTM, Dense, Dropout
from sklearn.preprocessing import MinMaxScaler

# Veri yükleme (geçmiş satış verileri)
df = pd.read_csv('sales_history.csv')  # Columns: date, product_id, quantity_sold

# Feature engineering
df['day_of_week'] = pd.to_datetime(df['date']).dt.dayofweek
df['month'] = pd.to_datetime(df['date']).dt.month
df['is_weekend'] = df['day_of_week'].isin([5, 6]).astype(int)
df['is_promotion'] = df['promotion'].fillna(0)

# Normalizasyon
scaler = MinMaxScaler()
features = ['quantity_sold', 'day_of_week', 'month', 'is_weekend', 'is_promotion']
scaled_data = scaler.fit_transform(df[features])

# Sequence oluşturma (son 30 gün → gelecek 7 gün)
def create_sequences(data, seq_length=30, pred_length=7):
    X, y = [], []
    for i in range(len(data) - seq_length - pred_length):
        X.append(data[i:i+seq_length])
        y.append(data[i+seq_length:i+seq_length+pred_length, 0])  # Sadece quantity
    return np.array(X), np.array(y)

X, y = create_sequences(scaled_data)

# Train/test split
split = int(0.8 * len(X))
X_train, X_test = X[:split], X[split:]
y_train, y_test = y[:split], y[split:]

# LSTM modeli
model = Sequential([
    LSTM(128, return_sequences=True, input_shape=(30, len(features))),
    Dropout(0.2),
    LSTM(64, return_sequences=False),
    Dropout(0.2),
    Dense(32, activation='relu'),
    Dense(7)  # 7 günlük tahmin
])

model.compile(optimizer='adam', loss='mse', metrics=['mae'])

# Eğitim
history = model.fit(
    X_train, y_train,
    epochs=50,
    batch_size=32,
    validation_split=0.2,
    verbose=1
)

# Tahmin
predictions = model.predict(X_test)

# Denormalize
predictions_original = scaler.inverse_transform(
    np.concatenate([predictions, np.zeros((len(predictions), len(features)-1))], axis=1)
)[:, 0]

# Doğruluk
from sklearn.metrics import mean_absolute_percentage_error
mape = mean_absolute_percentage_error(y_test, predictions)
print(f"MAPE: {mape:.2%}")  # Örnek: 8.5%

# Gelecek 7 gün tahmini
last_sequence = scaled_data[-30:]
next_7_days = model.predict(last_sequence.reshape(1, 30, len(features)))

print(f"\nGelecek 7 gün tahmin:")
for i, qty in enumerate(next_7_days[0], 1):
    print(f"Gün {i}: {qty:.0f} adet")

Inventory Optimization

# EOQ (Economic Order Quantity) + AI optimization
import numpy as np
from scipy.optimize import minimize

class InventoryOptimizer:
    def __init__(self, product_id):
        self.product_id = product_id
        self.demand_forecast = self.get_demand_forecast()  # AI tahmini
        self.holding_cost = 50  # TL/birim/yıl
        self.ordering_cost = 500  # TL/sipariş
        self.lead_time = 7  # gün
        self.service_level = 0.95  # %95 stok bulunurluk

    def calculate_eoq(self):
        """Economic Order Quantity (klasik formül)"""
        annual_demand = sum(self.demand_forecast) * 52  # Haftalık → Yıllık
        eoq = np.sqrt((2 * annual_demand * self.ordering_cost) / self.holding_cost)
        return eoq

    def calculate_reorder_point(self):
        """Yeniden sipariş noktası"""
        # Lead time boyunca talep
        daily_demand = np.mean(self.demand_forecast) / 7
        lead_time_demand = daily_demand * self.lead_time

        # Safety stock (güvenlik stoğu)
        demand_std = np.std(self.demand_forecast) / np.sqrt(7)
        z_score = 1.65  # %95 service level için
        safety_stock = z_score * demand_std * np.sqrt(self.lead_time)

        reorder_point = lead_time_demand + safety_stock
        return reorder_point, safety_stock

    def calculate_total_cost(self, order_quantity):
        """Toplam maliyet (holding + ordering)"""
        annual_demand = sum(self.demand_forecast) * 52

        # Ordering cost
        num_orders = annual_demand / order_quantity
        ordering_cost = num_orders * self.ordering_cost

        # Holding cost
        avg_inventory = order_quantity / 2
        holding_cost = avg_inventory * self.holding_cost

        return ordering_cost + holding_cost

    def optimize(self):
        """AI-enhanced optimization"""
        # Klasik EOQ
        eoq = self.calculate_eoq()

        # AI adjustment (sezonallik, trend için)
        demand_volatility = np.std(self.demand_forecast) / np.mean(self.demand_forecast)

        if demand_volatility > 0.5:  # Yüksek volatilite
            # Daha küçük, daha sık siparişler
            adjusted_eoq = eoq * 0.8
        elif demand_volatility < 0.2:  # Düşük volatilite
            # Daha büyük, daha az sıklıkta
            adjusted_eoq = eoq * 1.2
        else:
            adjusted_eoq = eoq

        reorder_point, safety_stock = self.calculate_reorder_point()

        return {
            'optimal_order_quantity': round(adjusted_eoq),
            'reorder_point': round(reorder_point),
            'safety_stock': round(safety_stock),
            'total_annual_cost': self.calculate_total_cost(adjusted_eoq),
            'order_frequency': round(365 / (sum(self.demand_forecast) * 52 / adjusted_eoq))  # gün
        }

# Kullanım
optimizer = InventoryOptimizer(product_id='LAPTOP-001')
result = optimizer.optimize()

print(f"Optimal Sipariş Miktarı: {result['optimal_order_quantity']} adet")
print(f"Yeniden Sipariş Noktası: {result['reorder_point']} adet")
print(f"Güvenlik Stoğu: {result['safety_stock']} adet")
print(f"Sipariş Sıklığı: Her {result['order_frequency']} günde bir")
print(f"Yıllık Toplam Maliyet: {result['total_annual_cost']:,.0f} TL")

# Multi-echelon inventory (çok kademeli)
# Warehouse → Distribution Centers → Stores
# Her kademe için optimal stok seviyeleri

Route Optimization (VRP)

# Vehicle Routing Problem (VRP) çözümü
from ortools.constraint_solver import routing_enums_pb2
from ortools.constraint_solver import pywrapcp

def solve_vrp(delivery_locations, vehicle_capacity=100):
    """
    Optimal teslimat rotası (Google OR-Tools)
    """
    # Distance matrix (koordinatlardan hesapla)
    def create_distance_matrix(locations):
        distances = []
        for from_loc in locations:
            row = []
            for to_loc in locations:
                # Haversine distance
                dist = calculate_distance(from_loc, to_loc)
                row.append(int(dist * 1000))  # km → meter
            distances.append(row)
        return distances

    distance_matrix = create_distance_matrix(delivery_locations)

    # VRP model
    manager = pywrapcp.RoutingIndexManager(
        len(distance_matrix),
        num_vehicles=3,  # 3 araç
        depot=0  # Depo konumu (index 0)
    )

    routing = pywrapcp.RoutingModel(manager)

    # Distance callback
    def distance_callback(from_index, to_index):
        from_node = manager.IndexToNode(from_index)
        to_node = manager.IndexToNode(to_index)
        return distance_matrix[from_node][to_node]

    transit_callback_index = routing.RegisterTransitCallback(distance_callback)
    routing.SetArcCostEvaluatorOfAllVehicles(transit_callback_index)

    # Capacity constraint (her araç max 100 paket)
    demands = [0] + [delivery['package_count'] for delivery in delivery_locations[1:]]

    def demand_callback(from_index):
        from_node = manager.IndexToNode(from_index)
        return demands[from_node]

    demand_callback_index = routing.RegisterUnaryTransitCallback(demand_callback)

    routing.AddDimensionWithVehicleCapacity(
        demand_callback_index,
        0,  # null capacity slack
        [vehicle_capacity] * 3,  # vehicle maximum capacities
        True,  # start cumul to zero
        'Capacity'
    )

    # Search parameters
    search_parameters = pywrapcp.DefaultRoutingSearchParameters()
    search_parameters.first_solution_strategy = (
        routing_enums_pb2.FirstSolutionStrategy.PATH_CHEAPEST_ARC
    )
    search_parameters.local_search_metaheuristic = (
        routing_enums_pb2.LocalSearchMetaheuristic.GUIDED_LOCAL_SEARCH
    )
    search_parameters.time_limit.seconds = 30

    # Solve
    solution = routing.SolveWithParameters(search_parameters)

    if solution:
        routes = []
        total_distance = 0

        for vehicle_id in range(3):
            index = routing.Start(vehicle_id)
            route = []
            route_distance = 0

            while not routing.IsEnd(index):
                node = manager.IndexToNode(index)
                route.append(delivery_locations[node])

                previous_index = index
                index = solution.Value(routing.NextVar(index))
                route_distance += routing.GetArcCostForVehicle(
                    previous_index, index, vehicle_id
                )

            routes.append({
                'vehicle': vehicle_id,
                'route': route,
                'distance_km': route_distance / 1000,
                'num_stops': len(route)
            })

            total_distance += route_distance

        return {
            'routes': routes,
            'total_distance_km': total_distance / 1000,
            'total_time_hours': (total_distance / 1000) / 40  # Ortalama 40 km/h
        }

# Örnek kullanım
deliveries = [
    {'lat': 41.0082, 'lon': 28.9784, 'package_count': 0},  # Depo
    {'lat': 41.0150, 'lon': 28.9850, 'package_count': 5},
    {'lat': 41.0200, 'lon': 29.0000, 'package_count': 8},
    # ... 50+ teslimat noktası
]

result = solve_vrp(deliveries)

for route in result['routes']:
    print(f"\nAraç {route['vehicle']}:")
    print(f"  Durak sayısı: {route['num_stops']}")
    print(f"  Mesafe: {route['distance_km']:.1f} km")
    print(f"  Rota: {' → '.join([str(i) for i in route['route'][:5]])}...")

print(f"\nToplam Mesafe: {result['total_distance_km']:.1f} km")
print(f"Tahmini Süre: {result['total_time_hours']:.1f} saat")

Predictive Maintenance

# Araç/makine arıza tahmini
import pandas as pd
from sklearn.ensemble import RandomForestClassifier

# IoT sensor verileri
df = pd.DataFrame({
    'vehicle_id': [...],
    'mileage': [...],  # Kilometre
    'engine_temp': [...],  # Motor sıcaklığı
    'oil_pressure': [...],  # Yağ basıncı
    'vibration': [...],  # Titreşim
    'brake_wear': [...],  # Fren aşınması
    'last_maintenance_days': [...],  # Son bakımdan beri geçen gün
    'failure': [...]  # 1: Arıza oldu, 0: Normal (target)
})

# Feature engineering
df['maintenance_overdue'] = (df['last_maintenance_days'] > 90).astype(int)
df['high_temp'] = (df['engine_temp'] > 95).astype(int)

features = ['mileage', 'engine_temp', 'oil_pressure', 'vibration',
            'brake_wear', 'last_maintenance_days', 'maintenance_overdue', 'high_temp']

X = df[features]
y = df['failure']

# Model
model = RandomForestClassifier(n_estimators=100, random_state=42)
model.fit(X_train, y_train)

# Tahmin
y_pred_proba = model.predict_proba(X_test)[:, 1]

# Risk skorlarına göre bakım planla
df_test['failure_risk'] = y_pred_proba

high_risk = df_test[df_test['failure_risk'] > 0.7].sort_values('failure_risk', ascending=False)

print("Yüksek Riskli Araçlar (acil bakım gerekli):")
print(high_risk[['vehicle_id', 'failure_risk', 'last_maintenance_days']])

# Bakım scheduling (öncelik bazlı)
def schedule_maintenance(vehicles, mechanic_capacity=5):
    """Optimal bakım takvimi"""
    scheduled = []

    for day in range(1, 31):  # 30 günlük plan
        # En yüksek riskli araçları seç
        today_schedule = vehicles.nlargest(mechanic_capacity, 'failure_risk')

        for _, vehicle in today_schedule.iterrows():
            scheduled.append({
                'vehicle_id': vehicle['vehicle_id'],
                'scheduled_day': day,
                'risk': vehicle['failure_risk'],
                'estimated_cost': 2000  # TL
            })

        # Schedule edilenleri listeden çıkar
        vehicles = vehicles[~vehicles['vehicle_id'].isin(today_schedule['vehicle_id'])]

        if len(vehicles) == 0:
            break

    return scheduled

maintenance_plan = schedule_maintenance(high_risk)
print(f"\n{len(maintenance_plan)} araç için 30 günlük bakım planı oluşturuldu")

Supplier Risk Assessment

# Tedarikçi risk puanlaması
class SupplierRiskModel:
    def __init__(self):
        self.weights = {
            'financial_health': 0.25,
            'delivery_performance': 0.20,
            'quality_score': 0.20,
            'geographic_risk': 0.15,
            'dependency': 0.10,
            'certification': 0.10
        }

    def calculate_risk_score(self, supplier_data):
        """0-100 risk skoru (0 = en güvenli, 100 = çok riskli)"""

        # 1. Financial health (mali sağlık)
        financial_risk = self._assess_financial(supplier_data)

        # 2. Delivery performance (teslimat performansı)
        delivery_risk = 100 - supplier_data['on_time_delivery_rate']

        # 3. Quality score (kalite)
        quality_risk = supplier_data['defect_rate'] * 100

        # 4. Geographic risk (coğrafi risk - doğal afet, politik)
        geo_risk = self._assess_geographic_risk(supplier_data['country'])

        # 5. Dependency (bağımlılık - tek tedarikçi riski)
        dependency_risk = 100 if supplier_data['is_sole_source'] else 20

        # 6. Certification (sertifika - ISO vb.)
        cert_risk = 0 if supplier_data['has_iso_certification'] else 50

        # Weighted risk score
        total_risk = (
            financial_risk * self.weights['financial_health'] +
            delivery_risk * self.weights['delivery_performance'] +
            quality_risk * self.weights['quality_score'] +
            geo_risk * self.weights['geographic_risk'] +
            dependency_risk * self.weights['dependency'] +
            cert_risk * self.weights['certification']
        )

        return round(total_risk, 2)

    def _assess_financial(self, supplier_data):
        # Z-score (Altman) - iflas riski
        z_score = supplier_data.get('altman_z_score', 2.5)

        if z_score > 3:
            return 10  # Düşük risk
        elif z_score > 1.8:
            return 50  # Orta risk
        else:
            return 90  # Yüksek risk (iflas riski)

    def _assess_geographic_risk(self, country):
        # Political stability index, natural disaster risk
        high_risk_countries = ['Country A', 'Country B']
        medium_risk = ['Country C', 'Country D']

        if country in high_risk_countries:
            return 80
        elif country in medium_risk:
            return 50
        else:
            return 20

    def recommend_mitigation(self, risk_score):
        """Risk azaltma önerileri"""
        if risk_score > 70:
            return [
                "Alternatif tedarikçi bul (URGENT)",
                "Güvenlik stoğunu 2x artır",
                "Aylık performans review",
                "Escrow anlaşması yap"
            ]
        elif risk_score > 40:
            return [
                "İkinci tedarikçi ekle (dual sourcing)",
                "Sözleşmeyi yeniden müzakere et",
                "Üç aylık audit yap"
            ]
        else:
            return ["Mevcut ilişkiye devam et", "Yıllık audit"]

# Kullanım
model = SupplierRiskModel()

supplier = {
    'name': 'ABC Electronics',
    'country': 'China',
    'altman_z_score': 1.5,  # Düşük (risk)
    'on_time_delivery_rate': 92,  # %92
    'defect_rate': 0.03,  # %3
    'is_sole_source': True,  # Tek tedarikçi
    'has_iso_certification': True
}

risk_score = model.calculate_risk_score(supplier)
actions = model.recommend_mitigation(risk_score)

print(f"Supplier: {supplier['name']}")
print(f"Risk Score: {risk_score}/100")
print(f"\nÖnerilen Aksiyonlar:")
for action in actions:
    print(f"  - {action}")

İş Etkileri ve ROI

Supply Chain AI ROI

-30%
Inventory Cost
-25%
Logistics Cost
+40%
Forecast Accuracy

Örnek ROI: Perakende Zinciri

Envanter maliyeti (önce): 80M TL
AI optimization sonrası: 56M TL (%30 azalma)
Lojistik maliyeti (önce): 40M TL
Route optimization sonrası: 30M TL (%25 azalma)
Toplam tasarruf: 34M TL/yıl
AI sistem maliyeti: 1.2M TL (kurulum + 1. yıl)
ROI: 2,733% (ilk yıl)

AI Supply Chain Çözümünüzü Kuralım

Demand forecasting, inventory optimization, route planning ile tedarik zinciri maliyetlerinizi %30'a kadar azaltın.

Demo İste