{"metadata":{"kernelspec":{"language":"python","display_name":"Python 3","name":"python3"},"language_info":{"name":"python","version":"3.10.14","mimetype":"text/x-python","codemirror_mode":{"name":"ipython","version":3},"pygments_lexer":"ipython3","nbconvert_exporter":"python","file_extension":".py"},"kaggle":{"accelerator":"nvidiaTeslaT4","dataSources":[{"sourceId":81933,"databundleVersionId":9643020,"sourceType":"competition"},{"sourceId":7453542,"sourceType":"datasetVersion","datasetId":921302}],"dockerImageVersionId":30786,"isInternetEnabled":false,"language":"python","sourceType":"notebook","isGpuEnabled":true}},"nbformat_minor":4,"nbformat":4,"cells":[{"cell_type":"markdown","source":"# Team information: DS102_Teams2\n\n* Hien-My Nguyen\n* Khanh-Linh Nguyen Phan\n* Tuan-Kiet Tran\n* Thanh-Linh Le Ho\n* Van-Truong Vo\n","metadata":{}},{"cell_type":"markdown","source":"## 1. Visualization and understand data","metadata":{}},{"cell_type":"code","source":"# Standard Libraries\nimport os\nimport re\nimport warnings\nfrom concurrent.futures import ThreadPoolExecutor\n\n# Data Handling and Processing\nimport numpy as np\nimport pandas as pd\nimport polars as pl  # Faster alternative to Pandas for large data\nfrom sklearn.model_selection import StratifiedKFold\nfrom sklearn.preprocessing import StandardScaler, MinMaxScaler, RobustScaler\nfrom sklearn.impute import SimpleImputer, KNNImputer\nfrom sklearn.pipeline import Pipeline\n\n# Machine Learning and Deep Learning Libraries\nfrom sklearn.base import clone\nfrom sklearn.metrics import cohen_kappa_score\nfrom lightgbm import LGBMRegressor\nfrom xgboost import XGBRegressor\nfrom catboost import CatBoostRegressor\nfrom sklearn.ensemble import VotingRegressor, RandomForestRegressor, GradientBoostingRegressor\n\n\n# For TabNet\n# from sklearn.base import BaseEstimator, RegressorMixin\n# from sklearn.impute import SimpleImputer\n# from sklearn.model_selection import train_test_split\n# from pytorch_tabnet.callbacks import Callback\n# import os\n# import torch\n# from pytorch_tabnet.callbacks import Callback\n# from pytorch_tabnet.tab_model import TabNetRegressor\n\n# Optimization\nfrom scipy.optimize import minimize\n\n# Visualization\nimport matplotlib.pyplot as plt\nimport seaborn as sns\nfrom matplotlib.ticker import MaxNLocator, FormatStrFormatter, PercentFormatter\nfrom tqdm import tqdm\nfrom colorama import Fore, Style\nfrom IPython.display import clear_output\nfrom keras.models import Model\nfrom keras.layers import Input, Dense\nfrom keras.optimizers import Adam\nimport torch\nimport torch.nn as nn\nimport torch.optim as optim\n\n\n\n# Display settings\nwarnings.filterwarnings('ignore')\npd.options.display.max_columns = None\n\n# Define Severity Labels\nseverity_levels = ['None', 'Mild', 'Moderate', 'Severe']\n\n# Define an Enum data type for seasonal data columns\nseason_enum = pl.Enum(['Spring', 'Summer', 'Fall', 'Winter'])\n\n# Load and Preprocess Training Dataset\ntrain_data = (\n    pl.read_csv('/kaggle/input/child-mind-institute-problematic-internet-use/train.csv')\n    .with_columns(pl.col('^.*Season$').cast(season_enum))  # Cast season-related columns to season_enum\n)\n\n# Load and Preprocess Test Dataset\ntest_data = (\n    pl.read_csv('/kaggle/input/child-mind-institute-problematic-internet-use/test.csv')\n    .with_columns(pl.col('^.*Season$').cast(season_enum))  # Cast season-related columns to season_enum\n)\n\n# Display a sample of loaded data for quick verification\nprint(\"Sample of Training Data:\")\nprint(train_data.head())\nprint(\"\\nSample of Test Data:\")\nprint(test_data.head())\n","metadata":{"_uuid":"8f2839f25d086af736a60e9eeb907d3b93b6e0e5","_cell_guid":"b1076dfc-b9ad-4769-8c92-a6c4dae69d19","execution":{"iopub.status.busy":"2024-12-21T03:30:52.394604Z","iopub.execute_input":"2024-12-21T03:30:52.395439Z","iopub.status.idle":"2024-12-21T03:31:10.514465Z","shell.execute_reply.started":"2024-12-21T03:30:52.395402Z","shell.execute_reply":"2024-12-21T03:31:10.513604Z"},"trusted":true},"outputs":[],"execution_count":null},{"cell_type":"markdown","source":"### 1.1. Check missing and null data","metadata":{}},{"cell_type":"code","source":"import matplotlib.pyplot as plt\nimport numpy as np\nfrom matplotlib.ticker import PercentFormatter\n\n# Step 1: Filter out rows with missing 'sii' values for supervised learning\nfiltered_data = train_data.filter(pl.col('sii').is_not_null())\n\n# Step 2: Calculate missing values per feature\nmissing_values = (\n    filtered_data\n    .null_count()\n    .transpose(include_header=True, header_name='feature', column_names=['missing_count'])\n    .sort('missing_count', descending=True)\n    .with_columns((pl.col('missing_count') / len(filtered_data)).alias('missing_ratio'))\n)\n\n# Step 3: Plot missing value ratios for features\nplt.figure(figsize=(6, 15))\nplt.title(f\"Missing values across {len(filtered_data)} samples with valid 'sii' targets\")\n\n# Plot bars for missing and available values\nplt.barh(np.arange(len(missing_values)), missing_values.get_column('missing_ratio'), color='coral', label='missing')\nplt.barh(np.arange(len(missing_values)), \n         1 - missing_values.get_column('missing_ratio'),\n         left=missing_values.get_column('missing_ratio'),\n         color='darkseagreen', label='available')\n\n# Customize plot appearance\nplt.yticks(np.arange(len(missing_values)), missing_values.get_column('feature'))\nplt.gca().xaxis.set_major_formatter(PercentFormatter(xmax=1, decimals=0))\nplt.xlim(0, 1)\nplt.legend()\nplt.show()\n\n# Step 4: Check if 'PCIAT-PCIAT_Total' missing values align with 'sii' missing values\npciat_sii_match_ratio = train_data.select((pl.col('PCIAT-PCIAT_Total').is_null() == pl.col('sii').is_null())).to_series().mean()\nprint(f\"Percentage of consistent missing values between 'PCIAT-PCIAT_Total' and 'sii': {pciat_sii_match_ratio * 100:.2f}%\")\n\n# Step 5: Group by 'sii' to find min, max, and count of 'PCIAT-PCIAT_Total' within each 'sii' level\npciat_summary_by_sii = (\n    train_data\n    .select(pl.col('PCIAT-PCIAT_Total'))\n    .group_by(train_data.get_column('sii'))\n    .agg([\n        pl.col('PCIAT-PCIAT_Total').min().alias('PCIAT_Total_min'),\n        pl.col('PCIAT-PCIAT_Total').max().alias('PCIAT_Total_max'),\n        pl.col('PCIAT-PCIAT_Total').len().alias('count')\n    ])\n    .sort('sii')\n)\n\nprint(\"Summary of 'PCIAT-PCIAT_Total' by 'sii' levels:\")\nprint(pciat_summary_by_sii)\n","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2024-12-21T03:31:10.516098Z","iopub.execute_input":"2024-12-21T03:31:10.516667Z","iopub.status.idle":"2024-12-21T03:31:11.511530Z","shell.execute_reply.started":"2024-12-21T03:31:10.516637Z","shell.execute_reply":"2024-12-21T03:31:11.510717Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"# Checking Class Imbalance in the Target Variable\nprint(\"Note: This dataset is imbalanced, with a significant number of samples in class 0 and very few in class 3.\")\n\n# Identifying Columns Present in Training Data but Missing in Test Data\nmissing_in_test = [col for col in train_data.columns if col not in test_data.columns]\nprint(\"Columns present in training data but missing in test data:\")\nprint(missing_in_test)\n","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2024-12-21T03:31:11.512419Z","iopub.execute_input":"2024-12-21T03:31:11.512669Z","iopub.status.idle":"2024-12-21T03:31:11.518011Z","shell.execute_reply.started":"2024-12-21T03:31:11.512645Z","shell.execute_reply":"2024-12-21T03:31:11.517179Z"}},"outputs":[],"execution_count":null},{"cell_type":"markdown","source":"### 1.2. Visualize tabular data","metadata":{}},{"cell_type":"code","source":"import matplotlib.pyplot as plt\nimport numpy as np\nfrom matplotlib.ticker import PercentFormatter, MaxNLocator\n\n# Plot Enrollment Season Distribution (using a bar chart for clearer comparison)\nenroll_season_counts = train_data.get_column('Basic_Demos-Enroll_Season').value_counts()\nplt.figure()\nplt.bar(enroll_season_counts.get_column('Basic_Demos-Enroll_Season'), enroll_season_counts.get_column('count'), color='skyblue')\nplt.title('Participant Enrollment by Season')\nplt.xlabel('Season')\nplt.ylabel('Number of Participants')\nplt.show()\n\n# Plot Sex Distribution of Participants (using a bar chart for clarity)\nsex_counts = train_data.get_column('Basic_Demos-Sex').value_counts()\nplt.figure()\nplt.bar(['Boys', 'Girls'], sex_counts.get_column('count'), color=['cornflowerblue', 'lightpink'])\nplt.title('Distribution of Participants by Sex')\nplt.xlabel('Sex')\nplt.ylabel('Number of Participants')\nplt.show()\n\n# Plot Age Distribution by Sex (using histograms for better age grouping)\nfig, age_axes = plt.subplots(2, 1, sharex=True)\nfor gender in range(2):  # 0 for boys, 1 for girls\n    ax = age_axes[gender]\n    age_counts = train_data.filter(pl.col('Basic_Demos-Sex') == gender).get_column('Basic_Demos-Age').value_counts()\n    ax.bar(age_counts.get_column('Basic_Demos-Age'),\n           age_counts.get_column('count'),\n           color=['cornflowerblue', 'lightpink'][gender],\n           label=['Boys', 'Girls'][gender])\n    ax.xaxis.set_major_locator(MaxNLocator(integer=True))\n    ax.set_ylabel('Participants')\n    ax.legend()\nfig.suptitle('Age Distribution of Participants by Sex')\nage_axes[1].set_xlabel('Age (years)')\nplt.show()\n\n# Plot Severity Impairment Index (sii) Distribution by Sex (using a stacked bar chart for normalized percentages)\nfig, sii_axes = plt.subplots(2, 1, sharex=True, sharey=True)\nfor gender in range(2):  # 0 for boys, 1 for girls\n    ax = sii_axes[gender]\n    sii_counts = train_data.filter(pl.col('Basic_Demos-Sex') == gender).get_column('sii').value_counts()\n    ax.bar(sii_counts.get_column('sii'),\n           sii_counts.get_column('count') / sii_counts.get_column('count').sum(),\n           color=['cornflowerblue', 'lightpink'][gender],\n           label=['Boys', 'Girls'][gender])\n    ax.set_xticks(np.arange(4), severity_levels)  # severity_levels corresponds to ['None', 'Mild', 'Moderate', 'Severe']\n    ax.yaxis.set_major_formatter(PercentFormatter(xmax=1, decimals=0))\n    ax.set_ylabel('Percentage')\n    ax.legend()\nfig.suptitle('Severity Impairment Index (sii) Distribution by Sex')\nsii_axes[1].set_xlabel('Severity Level (sii)')\nplt.show()\n","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2024-12-21T03:31:11.519999Z","iopub.execute_input":"2024-12-21T03:31:11.520807Z","iopub.status.idle":"2024-12-21T03:31:12.568379Z","shell.execute_reply.started":"2024-12-21T03:31:11.520776Z","shell.execute_reply":"2024-12-21T03:31:12.567512Z"}},"outputs":[],"execution_count":null},{"cell_type":"markdown","source":"### 1.3. Understand actigraphy data","metadata":{}},{"cell_type":"code","source":"import numpy as np\nimport matplotlib.pyplot as plt\nfrom matplotlib.ticker import MaxNLocator\n\n# Load the initial actigraphy data for verification\nactigraphy_sample = pl.read_parquet('/kaggle/input/child-mind-institute-problematic-internet-use/series_train.parquet/id=0417c91e/part-0.parquet')\nprint(actigraphy_sample)\n\n# Define the function to analyze and visualize actigraphy data\ndef analyze_actigraphy(participant_id, one_week_only=False, minimal_features=False):\n    # Load the specific participant's actigraphy data\n    actigraphy_data = pl.read_parquet(f'/kaggle/input/child-mind-institute-problematic-internet-use/series_train.parquet/id={participant_id}/part-0.parquet')\n    \n    # Calculate the \"day\" based on relative PCIAT test date and time of day\n    days_since_test = actigraphy_data.get_column('relative_date_PCIAT') + actigraphy_data.get_column('time_of_day') / 86400e9\n    \n    # Retrieve age and sex information for participant\n    participant_info = train_data.filter(pl.col('id') == participant_id)\n    age = participant_info.get_column('Basic_Demos-Age').item()\n    sex = 'boy' if participant_info.get_column('Basic_Demos-Sex').item() == 0 else 'girl'\n    \n    # Add computed features: time differences and acceleration norm\n    actigraphy_data = (\n        actigraphy_data\n        .with_columns(\n            (days_since_test.diff() * 86400).alias('time_diff_seconds'),\n            (np.sqrt(np.square(pl.col('X')) + np.square(pl.col('Y')) + np.square(pl.col('Z')))).alias('accel_norm')\n        )\n    )\n    \n    # Apply data mask based on whether only one week of data is desired\n    if one_week_only:\n        start_day = np.ceil(days_since_test.min())\n        mask = (start_day <= days_since_test.to_numpy()) & (days_since_test.to_numpy() <= start_day + 7)\n        mask &= ~actigraphy_data.get_column('non-wear_flag').cast(bool).to_numpy()\n    else:\n        mask = np.ones(len(days_since_test), dtype=bool)  # Use all data if one_week_only is False\n\n    # Select features to plot based on the minimal_features flag\n    if minimal_features:\n        feature_list = [\n            ('enmo', 'forestgreen'),\n            ('light', 'gold'),\n        ]\n    else:\n        feature_list = [\n            ('X', 'mediumslateblue'),\n            ('Y', 'deepskyblue'),\n            ('Z', 'dodgerblue'),\n            ('enmo', 'forestgreen'),\n            ('anglez', 'lightblue'),\n            ('light', 'gold'),\n            ('non-wear_flag', 'darkorange')\n        ]\n\n    # Plot each selected feature over time\n    fig, axes = plt.subplots(len(feature_list), 1, sharex=True, figsize=(12, len(feature_list) * 1.2))\n    for ax, (feature, color) in zip(axes, feature_list):\n        ax.set_facecolor('#f5f5f5')\n        ax.scatter(days_since_test.to_numpy()[mask],\n                   actigraphy_data.get_column(feature).to_numpy()[mask],\n                   color=color, label=feature, s=1)\n        ax.legend(loc='upper left', facecolor='#f5f5f5', framealpha=0.9)\n        if feature == 'time_diff_seconds':\n            ax.set_ylim(-0.5, 20.5)\n    \n    # Set titles and labels\n    fig.suptitle(f'Participant ID={participant_id}, Sex={sex}, Age={age}')\n    axes[-1].set_xlabel('Days since PCIAT Test')\n    axes[-1].xaxis.set_major_locator(MaxNLocator(integer=True))\n    plt.tight_layout()\n    plt.show()\n\n# Test the function with participant ID and settings\nanalyze_actigraphy('0417c91e', one_week_only=False, minimal_features=True)\n\n# Set seed and define number of splits for cross-validation (if needed later)\nimport random\ndef seed_everything(seed):\n    \"\"\"Set the random seed for reproducibility.\n\n    Args:\n        seed (int): Seed value.\n    \"\"\"\n    random.seed(seed)\n    os.environ['PYTHONHASHSEED'] = str(seed)\n    np.random.seed(seed)\n    torch.manual_seed(seed)\n    torch.cuda.manual_seed(seed)\n    torch.backends.cudnn.deterministic = True\n    torch.backends.cudnn.benchmark = False\n\n# Set the random seed\nseed_everything(2024)\n\nSEED = 42\nn_splits = 5\n","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2024-12-21T03:31:12.569842Z","iopub.execute_input":"2024-12-21T03:31:12.570087Z","iopub.status.idle":"2024-12-21T03:31:13.231556Z","shell.execute_reply.started":"2024-12-21T03:31:12.570064Z","shell.execute_reply":"2024-12-21T03:31:13.230667Z"}},"outputs":[],"execution_count":null},{"cell_type":"markdown","source":"## 2. Test with method 1","metadata":{}},{"cell_type":"markdown","source":"### 2.1. Preprocessing","metadata":{}},{"cell_type":"code","source":"# Load data\ntrain = pd.read_csv('/kaggle/input/child-mind-institute-problematic-internet-use/train.csv')\ntest = pd.read_csv('/kaggle/input/child-mind-institute-problematic-internet-use/test.csv')\nsample = pd.read_csv('/kaggle/input/child-mind-institute-problematic-internet-use/sample_submission.csv')\n\ndef process_file(filename, dirname):\n    df = pd.read_parquet(os.path.join(dirname, filename, 'part-0.parquet'))\n    df.drop('step', axis=1, inplace=True)\n    return df.describe().values.reshape(-1), filename.split('=')[1]\n\ndef load_time_series(dirname) -> pd.DataFrame:\n    ids = os.listdir(dirname)\n    \n    with ThreadPoolExecutor() as executor:\n        results = list(tqdm(executor.map(lambda fname: process_file(fname, dirname), ids), total=len(ids)))\n    \n    stats, indexes = zip(*results)\n    \n    df = pd.DataFrame(stats, columns=[f\"stat_{i}\" for i in range(len(stats[0]))])\n    df['id'] = indexes\n    return df\n\n","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2024-12-21T03:31:13.232830Z","iopub.execute_input":"2024-12-21T03:31:13.233775Z","iopub.status.idle":"2024-12-21T03:31:13.286387Z","shell.execute_reply.started":"2024-12-21T03:31:13.233733Z","shell.execute_reply":"2024-12-21T03:31:13.285562Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"# Merge and Drop Columns\n        \ntrain_ts = load_time_series(\"/kaggle/input/child-mind-institute-problematic-internet-use/series_train.parquet\")\ntest_ts = load_time_series(\"/kaggle/input/child-mind-institute-problematic-internet-use/series_test.parquet\")\n\ntime_series_cols = train_ts.columns.tolist()\ntime_series_cols.remove(\"id\")\n\ntrain = pd.merge(train, train_ts, how=\"left\", on='id')\ntest = pd.merge(test, test_ts, how=\"left\", on='id')\n\ntrain = train.drop('id', axis=1)\ntest = test.drop('id', axis=1)   ","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2024-12-21T03:31:13.287493Z","iopub.execute_input":"2024-12-21T03:31:13.287764Z","iopub.status.idle":"2024-12-21T03:32:25.455125Z","shell.execute_reply.started":"2024-12-21T03:31:13.287739Z","shell.execute_reply":"2024-12-21T03:32:25.454194Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"# Select Relevant Features and Handle Missing Values\nfeaturesCols = ['Basic_Demos-Enroll_Season', 'Basic_Demos-Age', 'Basic_Demos-Sex',\n                'CGAS-Season', 'CGAS-CGAS_Score', 'Physical-Season', 'Physical-BMI',\n                'Physical-Height', 'Physical-Weight', 'Physical-Waist_Circumference',\n                'Physical-Diastolic_BP', 'Physical-HeartRate', 'Physical-Systolic_BP',\n                'Fitness_Endurance-Season', 'Fitness_Endurance-Max_Stage',\n                'Fitness_Endurance-Time_Mins', 'Fitness_Endurance-Time_Sec',\n                'FGC-Season', 'FGC-FGC_CU', 'FGC-FGC_CU_Zone', 'FGC-FGC_GSND',\n                'FGC-FGC_GSND_Zone', 'FGC-FGC_GSD', 'FGC-FGC_GSD_Zone', 'FGC-FGC_PU',\n                'FGC-FGC_PU_Zone', 'FGC-FGC_SRL', 'FGC-FGC_SRL_Zone', 'FGC-FGC_SRR',\n                'FGC-FGC_SRR_Zone', 'FGC-FGC_TL', 'FGC-FGC_TL_Zone', 'BIA-Season',\n                'BIA-BIA_Activity_Level_num', 'BIA-BIA_BMC', 'BIA-BIA_BMI',\n                'BIA-BIA_BMR', 'BIA-BIA_DEE', 'BIA-BIA_ECW', 'BIA-BIA_FFM',\n                'BIA-BIA_FFMI', 'BIA-BIA_FMI', 'BIA-BIA_Fat', 'BIA-BIA_Frame_num',\n                'BIA-BIA_ICW', 'BIA-BIA_LDM', 'BIA-BIA_LST', 'BIA-BIA_SMM',\n                'BIA-BIA_TBW', 'PAQ_A-Season', 'PAQ_A-PAQ_A_Total', 'PAQ_C-Season',\n                'PAQ_C-PAQ_C_Total', 'SDS-Season', 'SDS-SDS_Total_Raw',\n                'SDS-SDS_Total_T', 'PreInt_EduHx-Season',\n                'PreInt_EduHx-computerinternet_hoursday', 'sii']\n\nfeaturesCols += time_series_cols\n\ntrain = train[featuresCols]\ntrain = train.dropna(subset='sii')\n\ncat_c = ['Basic_Demos-Enroll_Season', 'CGAS-Season', 'Physical-Season', \n          'Fitness_Endurance-Season', 'FGC-Season', 'BIA-Season', \n          'PAQ_A-Season', 'PAQ_C-Season', 'SDS-Season', 'PreInt_EduHx-Season']\n\ndef update(df):\n    global cat_c\n    for c in cat_c: \n        df[c] = df[c].fillna('Missing')\n        df[c] = df[c].astype('category')\n    return df\n        \ntrain = update(train)\ntest = update(test)","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2024-12-21T03:32:25.456190Z","iopub.execute_input":"2024-12-21T03:32:25.456459Z","iopub.status.idle":"2024-12-21T03:32:25.491268Z","shell.execute_reply.started":"2024-12-21T03:32:25.456432Z","shell.execute_reply":"2024-12-21T03:32:25.490650Z"}},"outputs":[],"execution_count":null},{"cell_type":"markdown","source":"### 2.2. Feature Extraction ","metadata":{}},{"cell_type":"code","source":"# Feature Extraction \n\ndef create_mapping(column, dataset):\n    unique_values = dataset[column].unique()\n    return {value: idx for idx, value in enumerate(unique_values)}\n\nfor col in cat_c:\n    mapping = create_mapping(col, train)\n    mappingTe = create_mapping(col, test)\n    \n    train[col] = train[col].replace(mapping).astype(int)\n    test[col] = test[col].replace(mappingTe).astype(int)\n","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2024-12-21T03:32:25.492227Z","iopub.execute_input":"2024-12-21T03:32:25.492480Z","iopub.status.idle":"2024-12-21T03:32:25.532235Z","shell.execute_reply.started":"2024-12-21T03:32:25.492456Z","shell.execute_reply":"2024-12-21T03:32:25.531459Z"}},"outputs":[],"execution_count":null},{"cell_type":"markdown","source":"### 2.3. Training model","metadata":{}},{"cell_type":"code","source":"\ndef quadratic_weighted_kappa(y_true, y_pred):\n    return cohen_kappa_score(y_true, y_pred, weights='quadratic')\n\ndef threshold_Rounder(oof_non_rounded, thresholds):\n    return np.where(oof_non_rounded < thresholds[0], 0,\n                    np.where(oof_non_rounded < thresholds[1], 1,\n                             np.where(oof_non_rounded < thresholds[2], 2, 3)))\n\ndef evaluate_predictions(thresholds, y_true, oof_non_rounded):\n    rounded_p = threshold_Rounder(oof_non_rounded, thresholds)\n    return -quadratic_weighted_kappa(y_true, rounded_p)\n\n","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2024-12-21T03:32:25.534262Z","iopub.execute_input":"2024-12-21T03:32:25.534485Z","iopub.status.idle":"2024-12-21T03:32:25.539236Z","shell.execute_reply.started":"2024-12-21T03:32:25.534462Z","shell.execute_reply":"2024-12-21T03:32:25.538351Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"def TrainML(model_class, test_data):\n    X = train.drop(['sii'], axis=1)\n    y = train['sii']\n\n    SKF = StratifiedKFold(n_splits=n_splits, shuffle=True, random_state=SEED)\n    \n    train_S = []\n    test_S = []\n    \n    oof_non_rounded = np.zeros(len(y), dtype=float) \n    oof_rounded = np.zeros(len(y), dtype=int) \n    test_preds = np.zeros((len(test_data), n_splits))\n\n    for fold, (train_idx, test_idx) in enumerate(tqdm(SKF.split(X, y), desc=\"Training Folds\", total=n_splits)):\n        X_train, X_val = X.iloc[train_idx], X.iloc[test_idx]\n        y_train, y_val = y.iloc[train_idx], y.iloc[test_idx]\n\n        model = clone(model_class)\n        model.fit(X_train, y_train)\n\n        y_train_pred = model.predict(X_train)\n        y_val_pred = model.predict(X_val)\n\n        oof_non_rounded[test_idx] = y_val_pred\n        y_val_pred_rounded = y_val_pred.round(0).astype(int)\n        oof_rounded[test_idx] = y_val_pred_rounded\n\n        train_kappa = quadratic_weighted_kappa(y_train, y_train_pred.round(0).astype(int))\n        val_kappa = quadratic_weighted_kappa(y_val, y_val_pred_rounded)\n\n        train_S.append(train_kappa)\n        test_S.append(val_kappa)\n        \n        test_preds[:, fold] = model.predict(test_data)\n        \n        clear_output(wait=True)\n\n    KappaOPtimizer = minimize(evaluate_predictions,\n                              x0=[0.5, 1.5, 2.5], args=(y, oof_non_rounded), \n                              method='Nelder-Mead')\n    assert KappaOPtimizer.success, \"Optimization did not converge.\"\n    \n    oof_tuned = threshold_Rounder(oof_non_rounded, KappaOPtimizer.x)\n    tKappa = quadratic_weighted_kappa(y, oof_tuned)\n\n    tpm = test_preds.mean(axis=1)\n    tpTuned = threshold_Rounder(tpm, KappaOPtimizer.x)\n    \n    submission = pd.DataFrame({\n        'id': sample['id'],\n        'sii': tpTuned\n    })\n\n    return submission","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2024-12-21T03:32:25.540206Z","iopub.execute_input":"2024-12-21T03:32:25.540436Z","iopub.status.idle":"2024-12-21T03:32:25.549235Z","shell.execute_reply.started":"2024-12-21T03:32:25.540410Z","shell.execute_reply":"2024-12-21T03:32:25.548492Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"Params = {\n    'learning_rate': 0.046,\n    'max_depth': 12,\n    'num_leaves': 478,\n    'min_data_in_leaf': 13,\n    'feature_fraction': 0.893,\n    'bagging_fraction': 0.784,\n    'bagging_freq': 4,\n    'lambda_l1': 10,  \n    'lambda_l2': 0.01  \n}\n\n\n\nXGB_Params = {\n    'learning_rate': 0.05,\n    'max_depth': 6,\n    'n_estimators': 200,\n    'subsample': 0.8,\n    'colsample_bytree': 0.8,\n    'reg_alpha': 1, \n    'reg_lambda': 5,  \n    'random_state': SEED\n}\n\n\nCatBoost_Params = {\n    'learning_rate': 0.05,\n    'depth': 6,\n    'iterations': 200,\n    'random_seed': SEED,\n    'cat_features': cat_c,\n    'verbose': 0,\n    'l2_leaf_reg': 10  \n}\n\n\nfrom collections import Counter\n\n# Tính toán trọng số lớp\nclass_counts = Counter(train['sii'])  # Số lượng mẫu trong từng lớp\ntotal_samples = len(train)\nclass_weights = {cls: total_samples / count for cls, count in class_counts.items()}\n\n# Áp dụng trọng số vào tham số LightGBM\nParams_with_weights = {\n    **Params,\n    'class_weight': class_weights\n}\n\n# Khởi tạo mô hình LightGBM với trọng số lớp\nLight = LGBMRegressor(**Params_with_weights, random_state=SEED, verbose=-1, n_estimators=300)\n# XGB_Model = XGBRegressor(**XGB_Params)\n# CatBoost_Model = CatBoostRegressor(**CatBoost_Params)\n\n\n\n# voting_model = VotingRegressor(estimators=[\n#     ('lightgbm', Light),\n#     ('xgboost', XGB_Model),\n#     ('catboost', CatBoost_Model)\n# ])\n\n# Train the ensemble model\nSubmission1 = TrainML(Light, test)\n\nSubmission1","metadata":{"trusted":true},"outputs":[],"execution_count":null},{"cell_type":"markdown","source":"# Submission","metadata":{}},{"cell_type":"code","source":"# sub1 = Submission1\n# sub2 = Submission2\n# sub3 = Submission3\n\n# sub1 = sub1.sort_values(by='id').reset_index(drop=True)\n# sub2 = sub2.sort_values(by='id').reset_index(drop=True)\n# sub3 = sub3.sort_values(by='id').reset_index(drop=True)\n\n# combined = pd.DataFrame({\n#     'id': sub1['id'],\n#     'sii_1': sub1['sii'],\n#     'sii_2': sub2['sii'],\n#     'sii_3': sub3['sii']\n# })\n\n# def majority_vote(row):\n#     return row.mode()[0] if len(row.mode()) == 1 else row.mean().round().astype(int)\n\n# combined['final_sii'] = combined[['sii_1', 'sii_2', 'sii_3']].apply(majority_vote, axis=1)\n\n# final_submission = combined[['id', 'final_sii']].rename(columns={'final_sii': 'sii'})\n# final_submission.to_csv('submission.csv', index=False)","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2024-12-21T03:32:25.567177Z","iopub.status.idle":"2024-12-21T03:32:25.567526Z","shell.execute_reply.started":"2024-12-21T03:32:25.567358Z","shell.execute_reply":"2024-12-21T03:32:25.567375Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2024-12-21T03:32:25.568933Z","iopub.status.idle":"2024-12-21T03:32:25.569315Z","shell.execute_reply.started":"2024-12-21T03:32:25.569085Z","shell.execute_reply":"2024-12-21T03:32:25.569100Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"Submission1.to_csv('submission.csv', index=False)","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2024-12-21T03:32:25.570731Z","iopub.status.idle":"2024-12-21T03:32:25.571029Z","shell.execute_reply.started":"2024-12-21T03:32:25.570889Z","shell.execute_reply":"2024-12-21T03:32:25.570903Z"}},"outputs":[],"execution_count":null}]}