{
  "nbformat": 4,
  "nbformat_minor": 0,
  "metadata": {
    "colab": {
      "provenance": []
    },
    "kernelspec": {
      "name": "python3",
      "display_name": "Python 3"
    },
    "language_info": {
      "name": "python"
    }
  },
  "cells": [
    {
      "cell_type": "code",
      "execution_count": 2,
      "metadata": {
        "colab": {
          "base_uri": "https://localhost:8080/"
        },
        "id": "ZvIJ1L1rZ4GJ",
        "outputId": "b6211cc8-ca01-49ec-d5e1-3a02fd83f708"
      },
      "outputs": [
        {
          "output_type": "stream",
          "name": "stdout",
          "text": [
            "--- Predicting Rings as Continuous ---\n",
            "Mean Squared Error (Rings - Regression): 4.891232447128576\n",
            "R² Score (Rings - Regression): 0.5481628137889265\n"
          ]
        },
        {
          "output_type": "stream",
          "name": "stderr",
          "text": [
            "/usr/local/lib/python3.11/dist-packages/sklearn/base.py:1389: DataConversionWarning: A column-vector y was passed when a 1d array was expected. Please change the shape of y to (n_samples,), for example using ravel().\n",
            "  return fit_method(estimator, *args, **kwargs)\n"
          ]
        },
        {
          "output_type": "stream",
          "name": "stdout",
          "text": [
            "--- Predicting Rings as Classification ---\n",
            "Accuracy (Rings - Classification): 0.5717703349282297\n",
            "--- Predicting Age ---\n",
            "Mean Squared Error (Age): 4.891232447128576\n",
            "R² Score (Age): 0.5481628137889265\n"
          ]
        }
      ],
      "source": [
        "import pandas as pd\n",
        "from sklearn.linear_model import LinearRegression\n",
        "from sklearn.model_selection import train_test_split\n",
        "from sklearn.metrics import mean_squared_error, r2_score\n",
        "from sklearn.preprocessing import KBinsDiscretizer\n",
        "from sklearn.ensemble import RandomForestClassifier\n",
        "\n",
        "# Column names as per UCI description\n",
        "column_names = ['Sex', 'Length', 'Diameter', 'Height',\n",
        "                'WholeWeight', 'ShuckedWeight', 'VisceraWeight',\n",
        "                'ShellWeight', 'Rings']\n",
        "\n",
        "# Load dataset directly from UCI\n",
        "url = 'https://archive.ics.uci.edu/ml/machine-learning-databases/abalone/abalone.data'\n",
        "df = pd.read_csv(url, names=column_names)\n",
        "\n",
        "# One-hot encode the 'Sex' column\n",
        "df = pd.get_dummies(df, columns=['Sex'], drop_first=True)\n",
        "\n",
        "# Features and target\n",
        "X = df.drop('Rings', axis=1)\n",
        "y = df['Rings']\n",
        "\n",
        "# ---- PART (a) ----\n",
        "\n",
        "# Approach 1: Predict Rings as a Continuous Value (Regression)\n",
        "\n",
        "# Train-test split\n",
        "X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2, random_state=42)\n",
        "\n",
        "# Linear Regression for continuous rings prediction\n",
        "model_regression = LinearRegression()\n",
        "model_regression.fit(X_train, y_train)\n",
        "y_pred_regression = model_regression.predict(X_test)\n",
        "\n",
        "# Evaluation for Rings (Regression)\n",
        "print('--- Predicting Rings as Continuous ---')\n",
        "print('Mean Squared Error (Rings - Regression):', mean_squared_error(y_test, y_pred_regression))\n",
        "print('R² Score (Rings - Regression):', r2_score(y_test, y_pred_regression))\n",
        "\n",
        "# Approach 2: Predict Rings as a Classification Problem (Binned)\n",
        "\n",
        "# Bin the Rings values into categories\n",
        "kbins = KBinsDiscretizer(n_bins=10, encode='ordinal', strategy='uniform')\n",
        "y_binned = kbins.fit_transform(y.values.reshape(-1, 1)).astype(int)\n",
        "\n",
        "# Train-test split for classification\n",
        "X_train_class, X_test_class, y_train_class, y_test_class = train_test_split(X, y_binned, test_size=0.2, random_state=42)\n",
        "\n",
        "# Random Forest Classifier for classification\n",
        "model_classifier = RandomForestClassifier(random_state=42)\n",
        "model_classifier.fit(X_train_class, y_train_class)\n",
        "y_pred_class = model_classifier.predict(X_test_class)\n",
        "\n",
        "# Evaluation for Rings (Classification)\n",
        "from sklearn.metrics import accuracy_score\n",
        "print('--- Predicting Rings as Classification ---')\n",
        "print('Accuracy (Rings - Classification):', accuracy_score(y_test_class, y_pred_class))\n",
        "\n",
        "# ---- PART (b) ----\n",
        "\n",
        "# Predict Age (Age = Rings + 1.5)\n",
        "df['Age'] = df['Rings'] + 1.5\n",
        "\n",
        "# Define new target for Age prediction\n",
        "y_age = df['Age']\n",
        "\n",
        "# Train-test split for Age prediction\n",
        "X_train_age, X_test_age, y_train_age, y_test_age = train_test_split(X, y_age, test_size=0.2, random_state=42)\n",
        "\n",
        "# Linear Regression for Age prediction\n",
        "model_age = LinearRegression()\n",
        "model_age.fit(X_train_age, y_train_age)\n",
        "y_pred_age = model_age.predict(X_test_age)\n",
        "\n",
        "# Evaluation for Age\n",
        "print('--- Predicting Age ---')\n",
        "print('Mean Squared Error (Age):', mean_squared_error(y_test_age, y_pred_age))\n",
        "print('R² Score (Age):', r2_score(y_test_age, y_pred_age))\n"
      ]
    }
  ]
}