{ "cells": [ { "cell_type": "code", "execution_count": 8, "metadata": { "colab": { "base_uri": "https://localhost:8080/" }, "id": "akUhAEHqKY1B", "outputId": "413748d1-857a-4b05-baf3-24168ddcfbf2" }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "Predicted churn risk: 0.17 ± 0.11\n", "Predicted churn risk: 0.24 ± 0.11\n", "Predicted churn risk: 0.06 ± 0.11\n", "New customer churn risk: 0.30 ± 0.14\n", "R-squared score: 0.80\n", "Mean Squared Error: 0.00\n" ] } ], "source": [ "# Probabilistic Linear Regression Example\n", "import numpy as np\n", "import pandas as pd\n", "from sklearn.model_selection import train_test_split\n", "from sklearn.linear_model import BayesianRidge\n", "\n", "# Example dataset (continuous target: churn probability score)\n", "# Features: age, monthly_spend, tenure_months\n", "data = {\n", " 'age': [25, 32, 47, 51, 62, 23, 38, 44, 29, 55],\n", " 'monthly_spend': [50, 60, 120, 110, 150, 40, 75, 95, 52, 130],\n", " 'tenure_months': [12, 24, 36, 48, 60, 6, 18, 30, 20, 50],\n", " # Target: churn risk score (continuous between 0 and 1)\n", " 'churn_risk': [0.1, 0.2, 0.8, 0.7, 0.9, 0.05, 0.3, 0.6, 0.15, 0.85]\n", "}\n", "\n", "df = pd.DataFrame(data)\n", "\n", "# Features (X) and target (y)\n", "X = df[['age', 'monthly_spend', 'tenure_months']]\n", "y = df['churn_risk']\n", "\n", "# Split into train/test sets\n", "X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.3, random_state=42)\n", "\n", "# Initialize and train Bayesian Ridge Regression\n", "model = BayesianRidge()\n", "model.fit(X_train, y_train)\n", "\n", "# Predictions with uncertainty\n", "y_mean, y_std = model.predict(X_test, return_std=True)\n", "\n", "# Convert y_std to numpy array for consistent indexing\n", "y_std_np = y_std.to_numpy()\n", "\n", "# Show results\n", "for i in range(len(y_mean)):\n", " print(f\"Predicted churn risk: {y_mean[i]:.2f} ± {y_std_np[i]:.2f}\")\n", "\n", "# Example: predict churn risk for a new customer\n", "# Convert new_customer to a DataFrame with feature names to avoid UserWarning\n", "new_customer_data = pd.DataFrame([[30, 70, 12]], columns=X.columns) # age=30, spend=70, tenure=12\n", "pred_mean, pred_std = model.predict(new_customer_data, return_std=True)\n", "print(f\"New customer churn risk: {pred_mean[0]:.2f} ± {pred_std[0]:.2f}\")\n", "\n", "from sklearn.metrics import r2_score, mean_squared_error\n", "\n", "# Calculate R-squared score\n", "r2 = r2_score(y_test, y_mean)\n", "print(f\"R-squared score: {r2:.2f}\")\n", "\n", "# Calculate Mean Squared Error\n", "mse = mean_squared_error(y_test, y_mean)\n", "print(f\"Mean Squared Error: {mse:.2f}\")" ] }, { "cell_type": "code", "execution_count": 9, "metadata": {}, "outputs": [], "source": [ "from huggingface_hub import notebook_login\n", "\n", "notebook_login()" ] }, { "cell_type": "code", "execution_count": 10, "metadata": { "colab": { "base_uri": "https://localhost:8080/" }, "id": "e58541b3", "outputId": "0fd73a98-4d75-428d-dc50-66c07c6466bf" }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "Model saved locally: /content/ML_LinearRegression_ChurnPredictor.joblib\n" ] }, { "data": { "application/vnd.jupyter.widget-view+json": { "model_id": "554925fb0d7f410a83a935a1b59314e4", "version_major": 2, "version_minor": 0 }, "text/plain": [ "Processing Files (0 / 0) : | | 0.00B / 0.00B " ] }, "metadata": {}, "output_type": "display_data" }, { "data": { "application/vnd.jupyter.widget-view+json": { "model_id": "e00ef06fe8964cb3af0f1137d3fd0caf", "version_major": 2, "version_minor": 0 }, "text/plain": [ "New Data Upload : | | 0.00B / 0.00B " ] }, "metadata": {}, "output_type": "display_data" }, { "data": { "application/vnd.jupyter.widget-view+json": { "model_id": "cc01ef1c10114eb7a1b59315bc17f82c", "version_major": 2, "version_minor": 0 }, "text/plain": [ " ...ion_ChurnPredictor.joblib: 100%|##########| 1.34kB / 1.34kB " ] }, "metadata": {}, "output_type": "display_data" }, { "name": "stdout", "output_type": "stream", "text": [ "Uploaded model to https://huggingface.co/looh2/model\n" ] } ], "source": [ "import joblib\n", "from pathlib import Path\n", "from huggingface_hub import HfApi\n", "\n", "# Define local model path and target Hugging Face repo\n", "repo_id = \"looh2/model\"\n", "model_path = Path(\"ML_LinearRegression_ChurnPredictor.joblib\")\n", "\n", "# Save the trained model locally\n", "joblib.dump(model, model_path)\n", "print(f\"Model saved locally: {model_path.resolve()}\")\n", "\n", "# Create repo if needed, then upload model artifact\n", "api = HfApi()\n", "api.create_repo(repo_id=repo_id, repo_type=\"model\", exist_ok=True)\n", "api.upload_file(\n", " path_or_fileobj=str(model_path),\n", " path_in_repo=model_path.name,\n", " repo_id=repo_id,\n", " repo_type=\"model\",\n", ")\n", "\n", "print(f\"Uploaded model to https://huggingface.co/{repo_id}\")" ] }, { "cell_type": "code", "execution_count": 11, "metadata": { "id": "gLXNHe9sLLpG" }, "outputs": [], "source": [ "import joblib\n", "from fastapi import FastAPI\n", "from pydantic import BaseModel\n", "import pandas as pd\n", "import uvicorn\n", "from contextlib import asynccontextmanager\n", "\n", "# Define the filename for the saved model\n", "model_filename = 'model_linear_regression.joblib'\n", "\n", "# Store the model globally\n", "model = None\n", "\n", "# Define a request body schema\n", "class CustomerData(BaseModel):\n", " age: int\n", " monthly_spend: int\n", " tenure_months: int\n", "\n", "# Lifespan context manager to load and unload the model\n", "@asynccontextmanager\n", "async def lifespan(app: FastAPI):\n", " global model\n", " try:\n", " model = joblib.load(model_filename)\n", " print(f\"Model '{model_filename}' loaded successfully.\")\n", " except FileNotFoundError:\n", " print(f\"Error: Model file '{model_filename}' not found. Please ensure the model is saved.\")\n", " model = None # Ensure model is None if loading fails\n", " yield\n", " # Clean up resources if necessary on shutdown\n", " print(\"Application shutting down. Model will be unloaded.\")\n", "\n", "# Initialize FastAPI app with lifespan\n", "app = FastAPI(lifespan=lifespan)\n", "\n", "@app.get(\"/\", summary=\"Root endpoint\")\n", "async def root():\n", " return {\"message\": \"Welcome to the Bayesian Ridge Regression Model API. Use /predict to get predictions.\"}\n", "\n", "@app.post(\"/predict\", summary=\"Predict churn risk with uncertainty\")\n", "async def predict_churn_risk(customer: CustomerData):\n", " if model is None:\n", " return {\"error\": \"Model not loaded. Please ensure the model file exists and the application restarted.\", \"status\": 500}\n", "\n", " # Convert input data to DataFrame matching training features\n", " new_customer_data = pd.DataFrame([[customer.age, customer.monthly_spend, customer.tenure_months]],\n", " columns=['age', 'monthly_spend', 'tenure_months'])\n", "\n", " # Make prediction with uncertainty\n", " pred_mean, pred_std = model.predict(new_customer_data, return_std=True)\n", "\n", " return {\n", " \"predicted_churn_risk_mean\": float(pred_mean[0]),\n", " \"predicted_churn_risk_std\": float(pred_std[0]),\n", " \"message\": \"Prediction successful\"\n", " }\n", "\n", "# To run this in Colab, you would typically save it as a .py file and run it\n", "# However, for demonstration, you can run uvicorn directly:\n", "# if __name__ == '__main__':\n", "# uvicorn.run(app, host=\"0.0.0.0\", port=8000)\n", "\n", "# Note: Running FastAPI directly inside a Colab cell might require specific setups\n", "# to expose the port and handle blocking execution. This code is best run in a\n", "# dedicated Python environment." ] } ], "metadata": { "colab": { "provenance": [] }, "kernelspec": { "display_name": "Python 3 (ipykernel)", "language": "python", "name": "python3" } }, "nbformat": 4, "nbformat_minor": 0 }