{
 "cells": [
  {
   "cell_type": "code",
   "execution_count": 1,
   "id": "73b01c17",
   "metadata": {},
   "outputs": [],
   "source": [
    "from sklearn.preprocessing import StandardScaler\n",
    "from sklearn.datasets import load_breast_cancer\n",
    "from easynn.feedforward import FFNN, Layer, Regularization, LeakyReLU, MSELoss, Linear\n",
    "from easynn.schedulers import AdamScheduler\n",
    "import numpy as np"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 2,
   "id": "b53c542f",
   "metadata": {},
   "outputs": [],
   "source": [
    "data = load_breast_cancer()\n",
    "\n",
    "\n",
    "feature_names = [n for n in data.feature_names if \"radius\" in n or \"area\" in n]\n",
    "\n",
    "X = data.data[:, [data.feature_names.tolist().index(n) for n in feature_names]]\n",
    "X = StandardScaler().fit_transform(X)\n",
    "y = data.data[\n",
    "    :,\n",
    "    [\n",
    "        data.feature_names.tolist().index(n)\n",
    "        for n in data.feature_names\n",
    "        if n not in feature_names\n",
    "    ],\n",
    "]\n",
    "y = StandardScaler().fit_transform(y)\n",
    "feature_dim = X.shape[1]\n",
    "target_dim = y.shape[1]\n",
    "\n",
    "\n",
    "def get_regression_model(\n",
    "    n_hidden_layers: int,\n",
    "    n_neurons: int,\n",
    "    activation: type = LeakyReLU,\n",
    "    regularization_strength: float = 1e-3,\n",
    ") -> list[Layer]:\n",
    "    layers = []\n",
    "    layers.append(Layer(feature_dim, n_neurons, activation_function=activation()))\n",
    "    for _ in range(n_hidden_layers - 1):\n",
    "        layers.append(Layer(n_neurons, n_neurons, activation_function=activation()))\n",
    "    layers.append(Layer(n_neurons, target_dim, activation_function=Linear()))\n",
    "    for layer in layers:\n",
    "        layer.regularization = Regularization(regularization_strength, \"l2\")\n",
    "    return layers\n",
    "\n",
    "\n",
    "def get_model():\n",
    "    return FFNN(\n",
    "        get_regression_model(\n",
    "            n_hidden_layers=2,\n",
    "            n_neurons=32,\n",
    "            activation=LeakyReLU,\n",
    "            regularization_strength=1e-3,\n",
    "        ),\n",
    "        AdamScheduler(epochs=10000, learning_rate=1e-2),\n",
    "        MSELoss(),\n",
    "    )"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 3,
   "id": "faa68894",
   "metadata": {},
   "outputs": [],
   "source": [
    "crossvalidation_groups = 5\n",
    "group_length = X.shape[0] // crossvalidation_groups\n",
    "predictions = np.zeros_like(y)\n",
    "for g in range(crossvalidation_groups + 1):  # One final smaller group to catch the rest\n",
    "    indices = [\n",
    "        i\n",
    "        for i in range(X.shape[0])\n",
    "        if i < g * group_length or i > (g + 1) * group_length\n",
    "    ]\n",
    "    prediction_indices = [i for i in range(X.shape[0]) if i not in indices]\n",
    "    X_train = X[indices]\n",
    "    X_pred = X[prediction_indices]\n",
    "    y_train = y[indices]\n",
    "\n",
    "    model = get_model()\n",
    "    model.fit(X_train, y_train)\n",
    "    predictions[prediction_indices] = model.predict(X_pred)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 4,
   "id": "2adacb9c",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "array([[-1.66264192e-03, -2.10728169e-03, -8.91893024e-03, ...,\n",
       "        -7.92692008e-03, -9.60004239e-03, -8.11141572e-03],\n",
       "       [-1.66264235e-03, -2.10728108e-03, -8.91893066e-03, ...,\n",
       "        -7.92692057e-03, -9.60004241e-03, -8.11141547e-03],\n",
       "       [-1.66264225e-03, -2.10728127e-03, -8.91893096e-03, ...,\n",
       "        -7.92692035e-03, -9.60004219e-03, -8.11141554e-03],\n",
       "       ...,\n",
       "       [-3.60719147e-04, -2.98012242e-04,  2.82998606e-04, ...,\n",
       "        -6.55977181e-05, -2.86525840e-05, -1.67033211e-05],\n",
       "       [-3.60718156e-04, -2.98012138e-04,  2.82997361e-04, ...,\n",
       "        -6.55992365e-05, -2.86528173e-05, -1.67018688e-05],\n",
       "       [-3.60719175e-04, -2.98012516e-04,  2.82998898e-04, ...,\n",
       "        -6.55989362e-05, -2.86521880e-05, -1.67059487e-05]],\n",
       "      shape=(569, 24))"
      ]
     },
     "execution_count": 4,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "predictions"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 5,
   "id": "690b4c57",
   "metadata": {},
   "outputs": [],
   "source": [
    "import pandas as pd"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 8,
   "id": "460e364e",
   "metadata": {},
   "outputs": [],
   "source": [
    "combined_data = np.zeros_like(data.data)\n",
    "combined_data[:, :6] = X\n",
    "combined_data[:, 6:] = predictions\n",
    "\n",
    "combined_df = pd.DataFrame(\n",
    "    combined_data,\n",
    "    columns=[\n",
    "        *feature_names,\n",
    "        *[n for n in data.feature_names if n not in feature_names],\n",
    "    ],\n",
    ")\n",
    "combined_df[\"target\"] = data.target\n",
    "combined_df.to_csv(\"breast_cancer_regression_results.csv\", index=False)\n",
    "\n",
    "original_df = pd.DataFrame(data.data, columns=data.feature_names)\n",
    "original_df[\"target\"] = data.target\n",
    "original_df.to_csv(\"breast_cancer_original_data.csv\", index=False)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "11b2a0ad",
   "metadata": {},
   "outputs": [],
   "source": []
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "project2",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.13.7"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 5
}
