{
 "nbformat": 4,
 "nbformat_minor": 5,
 "metadata": {
  "colab": {
   "provenance": [],
   "toc_visible": true
  },
  "kernelspec": {
   "display_name": "Python 3",
   "name": "python3"
  },
  "language_info": {
   "name": "python"
  }
 },
 "cells": [
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": "# 🚀 Predictive Maintenance with Quantum ML (Qiskit) – Full Edition\n## MES + PLC + OEE + CMMS + Klasik vs Quantum + (Opsiyonel) IBM Quantum Runtime\n\n**Colab eğitim notebook’u**  \n**Hedef kitle:** QML öğrencileri ve endüstriyel IoT-AI meraklıları  \n**Senaryo:** Motor / pompa / kompresör arıza tahmini + bakım kararı + OEE etkisi + iş emri simülasyonu\n\n### Bu notebook’ta neler var?\n1. Predictive Maintenance nedir? (görsel + şema)\n2. PLC + MES sentetik veri + OEE hesaplama\n3. Feature engineering, ölçekleme\n4. Klasik baseline (Random Forest + RBF-SVM) + Feature Importance + Confusion Matrix\n5. Quantum Kernel + QSVC (simülatör)\n6. Opsiyonel IBM Quantum Runtime (gerçek QPU)\n7. Karşılaştırma grafikleri + ROC\n8. Bakım karar katmanı + CMMS iş emri simülasyonu\n9. Öğrenci alıştırmaları\n\n> Her aşamada **neden** ve **niçin** açıklanmıştır.\n"
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": "# 1. Predictive Maintenance Nedir?\n\n## 1.1 Tanım\n**Predictive Maintenance (PdM)**, ekipmanın mevcut durumunu (titreşim, sıcaklık, akım, basınç vb.) sürekli izleyerek **arıza oluşmadan önce** ne zaman ve neden arızalanacağını tahmin eden bakım stratejisidir.\n\nAmaçlar:\n- Plansız duruşları azaltmak\n- Yedek parça ve işçilik maliyetini optimize etmek\n- **OEE** (Overall Equipment Effectiveness) değerini yükseltmek\n- Güvenliği artırmak\n\n## 1.2 Bakım Stratejileri\n\n| Strateji | Ne zaman müdahale? | Avantaj | Dezavantaj |\n|----------|---------------------|---------|------------|\n| Reactive | Arıza olduktan sonra | Düşük planlama maliyeti | Yüksek plansız duruş |\n| Preventive | Takvim / saat bazlı | Planlanabilir | Gereksiz parça değişimi |\n| **Predictive** | Koşul + veri modeli | Doğru zamanda müdahale | Sensör + model yatırımı |\n| Prescriptive | Tahmin + önerilen aksiyon | En yüksek optimizasyon | Daha karmaşık AI katmanı |\n\n## 1.3 Değer Zinciri\n```\nSensörler → Edge/Gateway → Feature Store → Model (Klasik + Quantum)\n                                              ↓\n                                    Risk skoru + Bakım kararı\n                                              ↓\n                                    CMMS İş Emri + OEE etkisi\n```\n"
  },
  {
   "cell_type": "code",
   "metadata": {},
   "source": "# Görsel: Bakım stratejileri – maliyet vs karmaşıklık\nimport matplotlib.pyplot as plt\nimport numpy as np\n\nstrategies = [\"Reactive\", \"Preventive\", \"Predictive\", \"Prescriptive\"]\ncost = [9, 6, 3.5, 2.5]\ncomplexity = [1, 3, 6, 8]\nx = np.arange(len(strategies))\nwidth = 0.35\n\nfig, ax = plt.subplots(figsize=(9, 4.2))\nax.bar(x - width/2, cost, width, label=\"Plansız duruş maliyeti (göreli)\", color=\"#E74C3C\")\nax.bar(x + width/2, complexity, width, label=\"Uygulama karmaşıklığı\", color=\"#3498DB\")\nax.set_ylabel(\"Göreli skor\")\nax.set_title(\"Bakım Stratejileri: Maliyet vs Karmaşıklık\", fontweight=\"bold\")\nax.set_xticks(x)\nax.set_xticklabels(strategies)\nax.legend()\nax.set_ylim(0, 11)\nax.grid(axis=\"y\", alpha=0.3)\nplt.tight_layout()\nplt.show()\nprint(\"Yorum: Predictive, plansız duruş maliyetini düşürür; orta-yüksek karmaşıklık ister.\")",
   "outputs": [],
   "execution_count": null
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": "# 2. Ortam Kurulumu\n\n**Neden?** Colab her oturumda temiz başlar. Qiskit, scikit-learn ve görselleştirme paketleri gerekir.\n\n**IBM Quantum (opsiyonel):** Token’ınız varsa gerçek QPU deneyebilirsiniz. Yoksa sadece simülatör kullanılır.\n"
  },
  {
   "cell_type": "code",
   "metadata": {},
   "source": "%pip install -q \"qiskit>=1.0\" qiskit-machine-learning qiskit-aer qiskit-ibm-runtime \\\n               matplotlib seaborn pandas numpy scikit-learn\n\nimport numpy as np\nimport pandas as pd\nimport matplotlib.pyplot as plt\nimport seaborn as sns\nfrom datetime import datetime, timedelta\nimport warnings\nwarnings.filterwarnings(\"ignore\")\n\nfrom sklearn.model_selection import train_test_split\nfrom sklearn.preprocessing import MinMaxScaler, StandardScaler\nfrom sklearn.metrics import (accuracy_score, classification_report, confusion_matrix,\n                             ConfusionMatrixDisplay, roc_curve, auc)\nfrom sklearn.ensemble import RandomForestClassifier\nfrom sklearn.svm import SVC\n\nfrom qiskit.circuit.library import ZZFeatureMap\nfrom qiskit_machine_learning.kernels import FidelityQuantumKernel\nfrom qiskit_machine_learning.algorithms import QSVC\nfrom qiskit_aer import AerSimulator\n\ntry:\n    from IPython.display import display\nexcept ImportError:\n    display = print\n\nplt.rcParams.update({\"figure.figsize\": (9, 4.5), \"axes.grid\": True, \"grid.alpha\": 0.3, \"font.size\": 11})\nsns.set_palette(\"colorblind\")\nprint(\"Kurulum tamam:\", datetime.now().strftime(\"%Y-%m-%d %H:%M\"))",
   "outputs": [],
   "execution_count": null
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": "# 3. PLC / Sensor + MES Simülasyonu + OEE\n\n**Neden OEE?**  \nOEE = Availability × Performance × Quality.  \nArıza tahmini sadece “bozulacak mı?” değil, “üretim ne kadar etkilenecek?” sorusuna da cevap vermelidir.\n\nBu bölümde:\n- Sensör telemetrisi üretilir\n- MES bağlamı eklenir\n- Basit OEE skoru hesaplanır / simüle edilir\n"
  },
  {
   "cell_type": "code",
   "metadata": {},
   "source": "np.random.seed(42)\nn_samples = 900\nmachines = [\"MTR-01\", \"PMP-02\", \"CMP-03\"]\n\nrows = []\nstart = datetime(2026, 3, 1)\nfor i in range(n_samples):\n    ts = start + timedelta(hours=i)\n    mid = np.random.choice(machines)\n    vib = np.random.normal(2.0, 0.6)\n    temp = np.random.normal(55, 6)\n    curr = np.random.normal(12.5, 1.2)\n    press = np.random.normal(6.0, 0.5)\n    rpm = np.random.normal(1450, 40)\n    fail = 0\n    if np.random.rand() < 0.17:\n        vib = np.random.normal(7.8, 1.6)\n        temp = np.random.normal(84, 9)\n        curr = np.random.normal(17.0, 2.0)\n        press = np.random.normal(3.8, 0.9)\n        rpm = np.random.normal(1320, 55)\n        fail = 1\n    # Basit OEE bileşenleri\n    availability = np.clip(np.random.normal(0.92 if fail == 0 else 0.65, 0.05), 0.4, 0.99)\n    performance = np.clip(np.random.normal(0.88 if fail == 0 else 0.70, 0.06), 0.4, 0.99)\n    quality = np.clip(np.random.normal(0.97 if fail == 0 else 0.85, 0.03), 0.5, 1.0)\n    oee = round(float(availability * performance * quality), 3)\n\n    rows.append({\n        \"ts\": ts, \"machine_id\": mid,\n        \"vibration_mms\": max(0.1, round(vib, 3)),\n        \"temp_c\": round(temp, 2), \"current_a\": round(curr, 2),\n        \"pressure_bar\": round(press, 2), \"rpm\": round(rpm, 1),\n        \"motor_run\": 1, \"emergency_stop\": 0,\n        \"availability\": round(float(availability), 3),\n        \"performance\": round(float(performance), 3),\n        \"quality\": round(float(quality), 3),\n        \"oee\": oee,\n        \"failure_soon\": fail\n    })\n\nplc_df = pd.DataFrame(rows)\n\n# MES bağlamı\nnp.random.seed(43)\nmes_rows = []\nfor i, row in plc_df.iterrows():\n    mes_rows.append({\n        \"ts\": row[\"ts\"], \"machine_id\": row[\"machine_id\"],\n        \"work_order\": f\"WO-{1000 + i // 12}\",\n        \"machine_state\": np.random.choice([\"RUN\", \"IDLE\", \"DOWN\"], p=[0.74, 0.18, 0.08]),\n        \"production_count\": np.random.randint(40, 220),\n        \"alarm_code\": np.random.choice([0, 101, 205, 310], p=[0.84, 0.08, 0.05, 0.03])\n    })\nmes_df = pd.DataFrame(mes_rows)\nfactory_df = pd.merge(plc_df, mes_df, on=[\"ts\", \"machine_id\"], how=\"inner\")\n\nprint(\"Birleşik fabrika verisi (PLC + MES + OEE):\")\ndisplay(factory_df.head(6))\nprint(f\"\\nŞekil: {factory_df.shape} | Arıza oranı: {factory_df.failure_soon.mean():.1%}\")\nprint(f\"Ortalama OEE (normal): {factory_df.loc[factory_df.failure_soon==0, 'oee'].mean():.3f}\")\nprint(f\"Ortalama OEE (arıza yakın): {factory_df.loc[factory_df.failure_soon==1, 'oee'].mean():.3f}\")",
   "outputs": [],
   "execution_count": null
  },
  {
   "cell_type": "code",
   "metadata": {},
   "source": "# Görsel: OEE vs Arıza + sensör dağılımları\nfig, axes = plt.subplots(1, 3, figsize=(13, 4))\n\n# OEE boxplot\nfactory_df.boxplot(column=\"oee\", by=\"failure_soon\", ax=axes[0])\naxes[0].set_title(\"OEE dağılımı (failure_soon)\")\naxes[0].set_xlabel(\"failure_soon\")\naxes[0].get_figure().suptitle(\"\")\n\nfor ax, col, title in zip(axes[1:], [\"vibration_mms\", \"temp_c\"], [\"Titreşim\", \"Sıcaklık\"]):\n    for label, color in [(0, \"#2ecc71\"), (1, \"#e74c3c\")]:\n        ax.hist(factory_df[factory_df.failure_soon==label][col], bins=22, alpha=0.55, label=f\"fail={label}\", color=color)\n    ax.set_title(title)\n    ax.legend()\n\nplt.suptitle(\"OEE ve Kritik Sensörler – Normal vs Arıza Yakın\", fontweight=\"bold\", y=1.02)\nplt.tight_layout()\nplt.show()",
   "outputs": [],
   "execution_count": null
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": "# 4. Feature Seçimi, Bölme ve Ölçekleme\n\n**Neden bu özellikler?** Titreşim, sıcaklık, akım, basınç, RPM ve OEE arıza riskini en iyi yansıtan değişkenlerdir.  \n**Neden MinMax (Quantum) + Standard (Klasik)?** Quantum feature map açı aralığına duyarlıdır; klasik modeller farklı ölçeklemeye daha toleranslıdır.\n"
  },
  {
   "cell_type": "code",
   "metadata": {},
   "source": "FEATURE_COLS = [\"vibration_mms\", \"temp_c\", \"current_a\", \"pressure_bar\", \"rpm\", \"oee\"]\nTARGET = \"failure_soon\"\n\nX = factory_df[FEATURE_COLS].values.astype(float)\ny = factory_df[TARGET].values.astype(int)\n\nX_train, X_test, y_train, y_test = train_test_split(\n    X, y, test_size=0.25, random_state=42, stratify=y\n)\n\nscaler_q = MinMaxScaler()\nX_train_q = scaler_q.fit_transform(X_train)\nX_test_q  = scaler_q.transform(X_test)\n\nscaler_c = StandardScaler()\nX_train_c = scaler_c.fit_transform(X_train)\nX_test_c  = scaler_c.transform(X_test)\n\nprint(f\"Train: {len(y_train)} | Test: {len(y_test)}\")\nprint(f\"Özellikler: {FEATURE_COLS}\")",
   "outputs": [],
   "execution_count": null
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": "# 5. Klasik Baseline + Feature Importance + Confusion Matrix\n\n**Neden baseline?** Quantum’un katma değerini ölçmek için klasik performansın bilinmesi gerekir.\n"
  },
  {
   "cell_type": "code",
   "metadata": {},
   "source": "rf = RandomForestClassifier(n_estimators=180, max_depth=9, random_state=42, n_jobs=-1)\nrf.fit(X_train_c, y_train)\n\nsvc_c = SVC(kernel=\"rbf\", C=1.0, gamma=\"scale\", probability=True, random_state=42)\nsvc_c.fit(X_train_c, y_train)\n\ny_pred_rf = rf.predict(X_test_c)\ny_pred_svc = svc_c.predict(X_test_c)\nacc_rf = accuracy_score(y_test, y_pred_rf)\nacc_svc = accuracy_score(y_test, y_pred_svc)\n\nprint(f\"Random Forest accuracy : {acc_rf:.3f}\")\nprint(f\"RBF-SVM accuracy      : {acc_svc:.3f}\")\nprint(\"\\nRF Classification Report:\")\nprint(classification_report(y_test, y_pred_rf, digits=3))",
   "outputs": [],
   "execution_count": null
  },
  {
   "cell_type": "code",
   "metadata": {},
   "source": "# Feature Importance + Confusion Matrix\nfig, axes = plt.subplots(1, 2, figsize=(12, 4.5))\n\nimp = pd.Series(rf.feature_importances_, index=FEATURE_COLS).sort_values(ascending=True)\nimp.plot.barh(ax=axes[0], color=\"#3498DB\", edgecolor=\"k\")\naxes[0].set_title(\"Random Forest – Feature Importance\")\naxes[0].set_xlabel(\"Önem skoru\")\n\ncm = confusion_matrix(y_test, y_pred_rf)\ndisp = ConfusionMatrixDisplay(confusion_matrix=cm, display_labels=[\"Normal\", \"Arıza Yakın\"])\ndisp.plot(ax=axes[1], cmap=\"Blues\", colorbar=False)\naxes[1].set_title(\"Random Forest – Confusion Matrix\")\n\nplt.tight_layout()\nplt.show()",
   "outputs": [],
   "execution_count": null
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": "# 6. Quantum Kernel + QSVC (Simülatör)\n\n**Neden ZZFeatureMap + FidelityQuantumKernel?**  \nVeriyi Hilbert uzayına non-lineer gömer ve state fidelity’yi kernel olarak kullanır.  \n**Neden küçük subset?** Kernel matrisi O(n²) circuit ister; eğitim için 100/40 yeterlidir.\n"
  },
  {
   "cell_type": "code",
   "metadata": {},
   "source": "N_TRAIN_Q = 100\nN_TEST_Q  = 40\n\nXtr_q = X_train_q[:N_TRAIN_Q]\nytr_q = y_train[:N_TRAIN_Q]\nXte_q = X_test_q[:N_TEST_Q]\nyte_q = y_test[:N_TEST_Q]\n\nfeature_map = ZZFeatureMap(feature_dimension=Xtr_q.shape[1], reps=2)\nquantum_kernel = FidelityQuantumKernel(feature_map=feature_map)\n\nqsvc = QSVC(quantum_kernel=quantum_kernel)\nprint(\"QSVC (simülatör) eğitiliyor... 1–3 dk sürebilir.\")\nqsvc.fit(Xtr_q, ytr_q)\n\ny_pred_q = qsvc.predict(Xte_q)\nacc_q = accuracy_score(yte_q, y_pred_q)\nprint(f\"\\nQuantum QSVC accuracy: {acc_q:.3f}\")\nprint(classification_report(yte_q, y_pred_q, digits=3))",
   "outputs": [],
   "execution_count": null
  },
  {
   "cell_type": "code",
   "metadata": {},
   "source": "# Quantum Confusion Matrix\nfig, ax = plt.subplots(figsize=(5, 4))\ncm_q = confusion_matrix(yte_q, y_pred_q)\ndisp_q = ConfusionMatrixDisplay(confusion_matrix=cm_q, display_labels=[\"Normal\", \"Arıza Yakın\"])\ndisp_q.plot(ax=ax, cmap=\"Greens\", colorbar=False)\nax.set_title(\"Quantum QSVC – Confusion Matrix\")\nplt.tight_layout()\nplt.show()",
   "outputs": [],
   "execution_count": null
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": "# 7. (Opsiyonel) IBM Quantum Runtime – Gerçek QPU\n\n**Neden opsiyonel?**  \nGerçek donanım kuyruk + kredi gerektirir. Token’ınız yoksa bu bölümü atlayın; simülatör sonuçları yeterlidir.\n\n**Nasıl kullanılır?**  \n1. [IBM Quantum](https://quantum.ibm.com/) hesabı açın  \n2. API token alın  \n3. Aşağıdaki `IBM_TOKEN` değişkenine yapıştırın  \n4. `USE_REAL_QPU = True` yapın  \n\n> Uyarı: Gerçek QPU’da çok küçük subset (ör. 30 train / 15 test) kullanın.\n"
  },
  {
   "cell_type": "code",
   "metadata": {},
   "source": "# === IBM Quantum Runtime (opsiyonel) ===\nUSE_REAL_QPU = False          # True yaparsanız gerçek QPU dener\nIBM_TOKEN = \"\"                # Buraya IBM Quantum API token'ınızı yazın\n\nacc_qpu = None\nif USE_REAL_QPU and IBM_TOKEN.strip():\n    try:\n        from qiskit_ibm_runtime import QiskitRuntimeService, Session, Sampler\n        from qiskit.transpiler.preset_passmanagers import generate_preset_pass_manager\n\n        service = QiskitRuntimeService(channel=\"ibm_quantum\", token=IBM_TOKEN)\n        backend = service.least_busy(operational=True, simulator=False)\n        print(f\"Seçilen backend: {backend.name}\")\n\n        # Çok küçük subset (QPU limiti)\n        Xtr_qpu = X_train_q[:30]\n        ytr_qpu = y_train[:30]\n        Xte_qpu = X_test_q[:15]\n        yte_qpu = y_test[:15]\n\n        fm_qpu = ZZFeatureMap(feature_dimension=Xtr_qpu.shape[1], reps=1)\n        # Not: Gerçek QPU için daha gelişmiş Session + Sampler entegrasyonu gerekir.\n        # Bu örnek iskelet olarak bırakılmıştır; tam production kodu için\n        # Qiskit Runtime QSVC örneklerine bakınız.\n        print(\"Gerçek QPU entegrasyonu için Qiskit Runtime QSVC örneklerini kullanın.\")\n        print(\"Şimdilik simülatör sonucu ile devam ediyoruz.\")\n    except Exception as e:\n        print(\"IBM Quantum bağlantı hatası:\", e)\n        print(\"Simülatör sonucu kullanılacak.\")\nelse:\n    print(\"Gerçek QPU kapalı (USE_REAL_QPU=False veya token yok). Simülatör kullanılıyor.\")",
   "outputs": [],
   "execution_count": null
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": "# 8. Model Karşılaştırma + ROC\n"
  },
  {
   "cell_type": "code",
   "metadata": {},
   "source": "# Accuracy karşılaştırma\nMAX_TEST = 40\nXte_c_s = X_test_c[:MAX_TEST]\nyte_c_s = y_test[:MAX_TEST]\nacc_rf_s = accuracy_score(yte_c_s, rf.predict(Xte_c_s))\nacc_svc_s = accuracy_score(yte_c_s, svc_c.predict(Xte_c_s))\n\nlabels = [\"Random Forest\", \"RBF-SVM\", \"Quantum QSVC\"]\nscores = [acc_rf_s, acc_svc_s, acc_q]\ncolors = [\"#4C72B0\", \"#DD8452\", \"#55A868\"]\n\nfig, axes = plt.subplots(1, 2, figsize=(12, 4.5))\n\nbars = axes[0].bar(labels, scores, color=colors, edgecolor=\"k\", width=0.55)\naxes[0].set_ylim(0, 1.05)\naxes[0].set_ylabel(\"Test accuracy\")\naxes[0].set_title(\"Klasik vs Quantum Accuracy\")\nfor b, s in zip(bars, scores):\n    axes[0].text(b.get_x() + b.get_width()/2, s + 0.02, f\"{s:.3f}\", ha=\"center\", fontweight=\"bold\")\n\n# ROC (RF + SVM)\nproba_rf = rf.predict_proba(X_test_c)[:, 1]\nproba_svc = svc_c.predict_proba(X_test_c)[:, 1]\nfpr_rf, tpr_rf, _ = roc_curve(y_test, proba_rf)\nfpr_svc, tpr_svc, _ = roc_curve(y_test, proba_svc)\naxes[1].plot(fpr_rf, tpr_rf, label=f\"RF (AUC={auc(fpr_rf, tpr_rf):.3f})\")\naxes[1].plot(fpr_svc, tpr_svc, label=f\"SVM (AUC={auc(fpr_svc, tpr_svc):.3f})\")\naxes[1].plot([0, 1], [0, 1], \"k--\", alpha=0.4)\naxes[1].set_xlabel(\"False Positive Rate\")\naxes[1].set_ylabel(\"True Positive Rate\")\naxes[1].set_title(\"ROC Eğrileri (Klasik)\")\naxes[1].legend()\n\nplt.tight_layout()\nplt.show()",
   "outputs": [],
   "execution_count": null
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": "# 9. Bakım Karar Katmanı + CMMS İş Emri Simülasyonu\n\n**Neden karar katmanı?** Model 0/1 üretir; operasyon “ne yapayım?” ister.  \n**Neden CMMS simülasyonu?** Tahmin → iş emri zincirini somutlaştırmak için.\n\n| Risk | Aksiyon |\n|------|---------|\n| LOW | Normal operasyon |\n| MEDIUM | 48 saat içinde planlı bakım |\n| HIGH | Acil inceleme + iş emri oluştur |\n"
  },
  {
   "cell_type": "code",
   "metadata": {},
   "source": "def maintenance_decision(sample_features, machine_id=\"UNKNOWN\"):\n    x_q = scaler_q.transform(sample_features.reshape(1, -1))\n    x_c = scaler_c.transform(sample_features.reshape(1, -1))\n    pred = int(qsvc.predict(x_q)[0])\n    proba = float(rf.predict_proba(x_c)[0, 1])\n\n    if proba >= 0.65 or pred == 1:\n        level, action = \"HIGH\", \"Acil inceleme / planlı duruş\"\n        create_wo = True\n    elif proba >= 0.40:\n        level, action = \"MEDIUM\", \"48 saat içinde bakım penceresi\"\n        create_wo = False\n    else:\n        level, action = \"LOW\", \"Normal operasyon\"\n        create_wo = False\n\n    wo = None\n    if create_wo:\n        wo = {\n            \"wo_id\": f\"CMMS-{np.random.randint(5000, 9999)}\",\n            \"machine_id\": machine_id,\n            \"priority\": \"P1-URGENT\",\n            \"description\": \"Predictive alert: yüksek arıza riski – titreşim/sıcaklık anomali\",\n            \"suggested_action\": action,\n            \"created_at\": datetime.now().isoformat(timespec=\"seconds\")\n        }\n    return {\"pred\": pred, \"proba\": proba, \"level\": level, \"action\": action, \"work_order\": wo}\n\nprint(\"=== Canlı karar + CMMS iş emri örnekleri ===\\n\")\nfor idx in factory_df.tail(6).index:\n    row = factory_df.loc[idx]\n    feats = row[FEATURE_COLS].values.astype(float)\n    dec = maintenance_decision(feats, machine_id=row[\"machine_id\"])\n    print(f\"{row['machine_id']} | vib={row['vibration_mms']:.1f} temp={row['temp_c']:.0f} OEE={row['oee']:.2f}\")\n    print(f\"  true={row['failure_soon']} | pred={dec['pred']} proba={dec['proba']:.2f} | {dec['level']}: {dec['action']}\")\n    if dec[\"work_order\"]:\n        print(f\"  → İş Emri oluşturuldu: {dec['work_order']}\")\n    print()",
   "outputs": [],
   "execution_count": null
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": "# 10. Üretim Entegrasyon Şeması\n\n```\nPLC (S7 / ControlLogix) ──OPC-UA/MQTT──▶ Edge Gateway\n                                              │\nMES (SAP ME / Opcenter) ──────────────────────┤\n                                              ▼\n                                    Feature Service + OEE\n                                              │\n                    ┌─────────────────────────┴─────────────────────────┐\n                    ▼                                                   ▼\n           Classical (RF / SVM)                              Quantum Kernel (QSVC)\n                    │                                                   │\n                    └─────────────────────────┬─────────────────────────┘\n                                              ▼\n                                    Risk Score + Karar Motoru\n                                              │\n                                              ▼\n                                    CMMS İş Emri + Bakım Planlama\n                                              │\n                                              ▼\n                                    OEE iyileştirme takibi\n```\n"
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": "# 11. Öğrenci Alıştırmaları\n\n1. `failure` oranını değiştirip sınıf dengesinin QSVC’ye etkisini ölçün.  \n2. Feature setinden `oee` veya `rpm` çıkarıp accuracy değişimini kaydedin.  \n3. `ZZFeatureMap` yerine `PauliFeatureMap` deneyin.  \n4. `reps=1` / `reps=3` ile derinlik ↔ doğruluk trade-off’unu tartışın.  \n5. Sadece bir makine (`MTR-01`) için model eğitin.  \n6. `USE_REAL_QPU=True` yapıp kendi IBM token’ınızla gerçek backend deneyin.  \n7. False Negative maliyeti yüksekse threshold’u düşürün; precision-recall inceleyin.  \n8. CMMS iş emri simülasyonuna “tahmini duruş süresi” ve “maliyet” alanları ekleyin.\n\n---\n\n# 12. Özet\n\nBu notebook’ta:\n- Predictive Maintenance kavramını görsellerle öğrendiniz\n- PLC + MES + **OEE** verisi ürettiniz\n- Klasik baseline + **Feature Importance** + **Confusion Matrix** + **ROC** yaptınız\n- Quantum Kernel + QSVC eğittiniz\n- Opsiyonel IBM Quantum Runtime iskeleti eklediniz\n- Bakım kararı + **CMMS iş emri** simülasyonu kurdunuz\n\n### Kaynaklar\n- Qiskit Machine Learning – Quantum Kernel / QSVC  \n- Qiskit IBM Runtime  \n- ISO 13374, ISA-95, OEE (Availability × Performance × Quality)\n\n---\n**QML Full Edition – Predictive Maintenance (MES + PLC + OEE + CMMS + Quantum)**\n"
  }
 ]
}