from fastapi import FastAPI, Request, Form from fastapi.responses import HTMLResponse from fastapi.staticfiles import StaticFiles import numpy as np import pandas as pd from sklearn.preprocessing import StandardScaler from sklearn.model_selection import train_test_split from sklearn.impute import SimpleImputer from collections import Counter import uvicorn # Manual Logistic Regression class LogisticRegressionManual: def __init__(self, learning_rate=0.01, n_iterations=1000, regularization='l2', lambda_reg=0.01): self.learning_rate = learning_rate self.n_iterations = n_iterations self.regularization = regularization self.lambda_reg = lambda_reg self.weights = None self.bias = None def sigmoid(self, z): return 1 / (1 + np.exp(-np.clip(z, -500, 500))) def fit(self, X, y): m, n = X.shape self.weights = np.zeros(n) self.bias = 0 y = np.array(y) for _ in range(self.n_iterations): z = np.dot(X, self.weights) + self.bias y_pred = self.sigmoid(z) dw = (1/m) * np.dot(X.T, (y_pred - y)) db = (1/m) * np.sum(y_pred - y) if self.regularization == 'l2': dw += (self.lambda_reg / m) * self.weights self.weights -= self.learning_rate * dw self.bias -= self.learning_rate * db def predict_proba(self, X): z = np.dot(X, self.weights) + self.bias return self.sigmoid(z) def train_model(): data = pd.read_csv('diabetes.csv') zero_features = ['Glucose', 'BloodPressure', 'SkinThickness', 'Insulin', 'BMI'] data[zero_features] = data[zero_features].replace(0, np.nan) imputer = SimpleImputer(strategy='median') data[zero_features] = imputer.fit_transform(data[zero_features]) numerical_cols = ['Pregnancies', 'Glucose', 'BloodPressure', 'SkinThickness', 'Insulin', 'BMI', 'DiabetesPedigreeFunction', 'Age'] for col in numerical_cols: Q1 = data[col].quantile(0.25) Q3 = data[col].quantile(0.75) IQR = Q3 - Q1 data = data[(data[col] >= Q1 - 1.5 * IQR) & (data[col] <= Q3 + 1.5 * IQR)] X = data[numerical_cols] y = data['Outcome'] X_train, _, y_train, _ = train_test_split(X, y, test_size=0.2, random_state=42, stratify=y) scaler = StandardScaler() X_train_scaled = scaler.fit_transform(X_train) class_counts = Counter(y_train) majority = max(class_counts, key=class_counts.get) minority = min(class_counts, key=class_counts.get) minority_idx = np.where(y_train.values == minority)[0] n_needed = class_counts[majority] - class_counts[minority] if n_needed > 0: np.random.seed(42) extra_idx = np.random.choice(minority_idx, size=n_needed, replace=True) X_balanced = np.vstack([X_train_scaled, X_train_scaled[extra_idx]]) y_balanced = np.concatenate([y_train.values, y_train.values[extra_idx]]) else: X_balanced, y_balanced = X_train_scaled, y_train.values model = LogisticRegressionManual(learning_rate=0.1, n_iterations=1000, lambda_reg=0.01) model.fit(X_balanced, y_balanced) return model, scaler model, scaler = train_model() app = FastAPI() INDEX_HTML = ''' تشخيص مرض السكري

إدخال البيانات الصحية

أدخل المؤشرات الصحية للحصول على تقييم احتمالية الإصابة بالسكري

🤰
🩸
mg/dL
الطبيعي: 70-100 | ما قبل السكري: 100-125
💓
mm Hg
📏
mm
💉
mu U/ml
⚖️
kg/m²
الطبيعي: 18.5-25 | زيادة الوزن: 25-30
👨‍👩‍👧
التاريخ العائلي للسكري (0.0 - 2.5)
🎂
سنة
''' RESULT_HTML = ''' نتيجة التشخيص
{icon}

{prediction}

{probability}
احتمالية الإصابة
{risk_level}
مستوى الخطورة
مؤشر الخطورة {probability}
📋 {rec_title}
    {recommendations}

⚠️ هذا النظام للأغراض التعليمية فقط ولا يغني عن استشارة الطبيب

''' @app.get("/", response_class=HTMLResponse) async def home(): return INDEX_HTML @app.post("/predict", response_class=HTMLResponse) async def predict( pregnancies: float = Form(...), glucose: float = Form(...), blood_pressure: float = Form(...), skin_thickness: float = Form(...), insulin: float = Form(...), bmi: float = Form(...), dpf: float = Form(...), age: float = Form(...) ): features = np.array([[pregnancies, glucose, blood_pressure, skin_thickness, insulin, bmi, dpf, age]]) features_scaled = scaler.transform(features) probability = model.predict_proba(features_scaled)[0] is_diabetic = probability >= 0.5 if probability > 0.7: risk_level, risk_class = "عالي", "risk-high" progress_class = "bg-danger" elif probability > 0.4: risk_level, risk_class = "متوسط", "risk-medium" progress_class = "bg-warning" else: risk_level, risk_class = "منخفض", "risk-low" progress_class = "bg-success" if is_diabetic: recommendations = """
  • استشر طبيبك في أقرب وقت ممكن للتأكد من التشخيص
  • قم بإجراء فحص HbA1c (السكر التراكمي)
  • راقب مستوى السكر في الدم بانتظام
  • اتبع نظام غذائي صحي قليل السكريات
  • مارس الرياضة بانتظام (30 دقيقة يومياً)
  • """ rec_title = "التوصيات الطبية" rec_title_class = "text-danger" else: recommendations = """
  • حافظ على نمط حياة صحي ووزن مثالي
  • مارس الرياضة بانتظام (150 دقيقة أسبوعياً)
  • تناول غذاء متوازن غني بالألياف
  • قلل من السكريات والمشروبات الغازية
  • أجرِ فحص دوري للسكر كل سنة
  • """ rec_title = "نصائح للوقاية" rec_title_class = "text-success" return RESULT_HTML.format( header_class="result-positive" if is_diabetic else "result-negative", icon_class="icon-positive" if is_diabetic else "icon-negative", icon="⚠️" if is_diabetic else "✓", prediction="مصاب بالسكري" if is_diabetic else "غير مصاب بالسكري", text_class="text-positive" if is_diabetic else "text-negative", probability=f"{probability*100:.1f}%", risk_level=risk_level, risk_class=risk_class, progress_class=progress_class, recommendations=recommendations, rec_title=rec_title, rec_title_class=rec_title_class ) if __name__ == "__main__": uvicorn.run(app, host="0.0.0.0", port=7860)