{"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":"gpu","dataSources":[{"sourceId":81933,"databundleVersionId":9643020,"sourceType":"competition"},{"sourceId":199751981,"sourceType":"kernelVersion"},{"sourceId":199914274,"sourceType":"kernelVersion"},{"sourceId":200055690,"sourceType":"kernelVersion"},{"sourceId":200365807,"sourceType":"kernelVersion"},{"sourceId":200413587,"sourceType":"kernelVersion"}],"dockerImageVersionId":30787,"isInternetEnabled":false,"language":"python","sourceType":"notebook","isGpuEnabled":true}},"nbformat_minor":4,"nbformat":4,"cells":[{"cell_type":"code","source":"import numpy as np\nimport pandas as pd\nimport os\nimport re\nfrom sklearn.base import clone\nfrom sklearn.metrics import cohen_kappa_score\nfrom sklearn.model_selection import StratifiedKFold\nfrom scipy.optimize import minimize\nfrom concurrent.futures import ThreadPoolExecutor\nfrom tqdm import tqdm\nfrom colorama import Fore, Style\nfrom IPython.display import clear_output\nimport warnings\nfrom lightgbm import LGBMRegressor\nfrom xgboost import XGBRegressor\nfrom catboost import CatBoostRegressor\nfrom sklearn.ensemble import VotingRegressor","metadata":{"execution":{"iopub.status.busy":"2024-10-11T13:26:36.124210Z","iopub.execute_input":"2024-10-11T13:26:36.124580Z","iopub.status.idle":"2024-10-11T13:26:40.613076Z","shell.execute_reply.started":"2024-10-11T13:26:36.124542Z","shell.execute_reply":"2024-10-11T13:26:40.612054Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"warnings.filterwarnings('ignore')\npd.options.display.max_columns = None","metadata":{"execution":{"iopub.status.busy":"2024-10-11T13:26:40.614961Z","iopub.execute_input":"2024-10-11T13:26:40.615882Z","iopub.status.idle":"2024-10-11T13:26:40.620231Z","shell.execute_reply.started":"2024-10-11T13:26:40.615836Z","shell.execute_reply":"2024-10-11T13:26:40.619314Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"# Configuration and Setup","metadata":{}},{"cell_type":"code","source":"SEED = 42\nn_splits = 5","metadata":{"execution":{"iopub.status.busy":"2024-10-11T13:26:40.621332Z","iopub.execute_input":"2024-10-11T13:26:40.621605Z","iopub.status.idle":"2024-10-11T13:26:40.630579Z","shell.execute_reply.started":"2024-10-11T13:26:40.621575Z","shell.execute_reply":"2024-10-11T13:26:40.629821Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"#  Data Loading","metadata":{}},{"cell_type":"code","source":"train = 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')","metadata":{"execution":{"iopub.status.busy":"2024-10-11T13:26:40.632670Z","iopub.execute_input":"2024-10-11T13:26:40.632980Z","iopub.status.idle":"2024-10-11T13:26:40.710360Z","shell.execute_reply.started":"2024-10-11T13:26:40.632948Z","shell.execute_reply":"2024-10-11T13:26:40.709607Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"# Data Processing Functions","metadata":{}},{"cell_type":"code","source":"def 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    \n    return df","metadata":{"execution":{"iopub.status.busy":"2024-10-11T13:26:40.711438Z","iopub.execute_input":"2024-10-11T13:26:40.711726Z","iopub.status.idle":"2024-10-11T13:26:40.719541Z","shell.execute_reply.started":"2024-10-11T13:26:40.711695Z","shell.execute_reply":"2024-10-11T13:26:40.718611Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"train_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\")","metadata":{"execution":{"iopub.status.busy":"2024-10-11T13:26:40.720659Z","iopub.execute_input":"2024-10-11T13:26:40.720955Z","iopub.status.idle":"2024-10-11T13:28:00.679731Z","shell.execute_reply.started":"2024-10-11T13:26:40.720914Z","shell.execute_reply":"2024-10-11T13:28:00.678815Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"time_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)   \n","metadata":{"execution":{"iopub.status.busy":"2024-10-11T13:28:00.680870Z","iopub.execute_input":"2024-10-11T13:28:00.681176Z","iopub.status.idle":"2024-10-11T13:28:00.712090Z","shell.execute_reply.started":"2024-10-11T13:28:00.681142Z","shell.execute_reply":"2024-10-11T13:28:00.711339Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"# Feature Selection","metadata":{}},{"cell_type":"code","source":"featuresCols = ['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')","metadata":{"execution":{"iopub.status.busy":"2024-10-11T13:28:00.713126Z","iopub.execute_input":"2024-10-11T13:28:00.713408Z","iopub.status.idle":"2024-10-11T13:28:00.725286Z","shell.execute_reply.started":"2024-10-11T13:28:00.713377Z","shell.execute_reply":"2024-10-11T13:28:00.724346Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"# Categorical Features Handling","metadata":{}},{"cell_type":"code","source":"\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)\n","metadata":{"execution":{"iopub.status.busy":"2024-10-11T13:28:00.726499Z","iopub.execute_input":"2024-10-11T13:28:00.726812Z","iopub.status.idle":"2024-10-11T13:28:00.757711Z","shell.execute_reply.started":"2024-10-11T13:28:00.726780Z","shell.execute_reply":"2024-10-11T13:28:00.757071Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"# Model Training Function","metadata":{}},{"cell_type":"code","source":"def 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\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\n","metadata":{"execution":{"iopub.status.busy":"2024-10-11T13:28:00.761085Z","iopub.execute_input":"2024-10-11T13:28:00.761442Z","iopub.status.idle":"2024-10-11T13:28:00.808739Z","shell.execute_reply.started":"2024-10-11T13:28:00.761407Z","shell.execute_reply":"2024-10-11T13:28:00.807941Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"def GetTopWeightedFeatures(model_class, train, n_splits=5, top_n=10):\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    # Thêm mảng để lưu feature importance của mỗi fold\n    feature_importances = np.zeros(X.shape[1])\n\n    for fold, (train_idx, test_idx) in enumerate(tqdm(SKF.split(X, y), desc=\"Calculating Feature Importance\", 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        # Clone và huấn luyện mô hình VotingRegressor\n        model = clone(model_class)\n        model.fit(X_train, y_train)\n\n        # Tính trung bình feature importance từ các mô hình thành phần\n        fold_importances = np.zeros(X.shape[1])\n        for estimator in model.estimators_:\n            if hasattr(estimator, 'feature_importances_'):\n                fold_importances += estimator.feature_importances_ / len(model.estimators_)\n\n        # Cộng dồn importance cho mỗi fold\n        feature_importances += fold_importances / n_splits\n\n    # Hiển thị tầm quan trọng của từng feature sau khi tính trung bình qua tất cả các fold\n    feature_importance_df = pd.DataFrame({\n        'feature': X.columns,\n        'importance': feature_importances\n    }).sort_values(by='importance', ascending=False)\n\n    print(\"Feature Importance:\\n\", feature_importance_df)\n\n    # Lấy top N features dựa trên tầm quan trọng\n    top_features = feature_importance_df.head(top_n)['feature'].values\n\n    # Gắn trọng số cho các cột top N\n    for col in top_features:\n        index = feature_importance_df[feature_importance_df['feature'] == col].index[0]\n        X[col] = X[col] * feature_importances[index]\n\n    # Trả về DataFrame đã gắn trọng số cho các cột top N\n    return X[top_features], feature_importance_df, top_features\n","metadata":{"execution":{"iopub.status.busy":"2024-10-11T13:28:00.810069Z","iopub.execute_input":"2024-10-11T13:28:00.810343Z","iopub.status.idle":"2024-10-11T13:28:00.820279Z","shell.execute_reply.started":"2024-10-11T13:28:00.810313Z","shell.execute_reply":"2024-10-11T13:28:00.819440Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# Model parameters for LightGBM\nParams = {\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,  # Increased from 6.59\n    'lambda_l2': 0.01,  # Increased from 2.68e-06\n    'device': 'gpu'\n\n}\n\n\n# XGBoost parameters\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,  # Increased from 0.1\n    'reg_lambda': 5,  # Increased from 1\n    'random_state': SEED,\n    'tree_method': 'gpu_hist',\n\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,  # Increase this value\n    'task_type': 'GPU'\n\n}\n\n# Create model instances\nLight = LGBMRegressor(**Params, random_state=SEED, verbose=-1, n_estimators=200)\nXGB_Model = XGBRegressor(**XGB_Params)\nCatBoost_Model = CatBoostRegressor(**CatBoost_Params)\n\n# Combine models using Voting Regressor\nvoting_model = VotingRegressor(estimators=[\n    ('lightgbm', Light),\n    ('xgboost', XGB_Model),\n    ('catboost', CatBoost_Model)\n])","metadata":{"execution":{"iopub.status.busy":"2024-10-11T13:28:00.821394Z","iopub.execute_input":"2024-10-11T13:28:00.821689Z","iopub.status.idle":"2024-10-11T13:28:00.837035Z","shell.execute_reply.started":"2024-10-11T13:28:00.821651Z","shell.execute_reply":"2024-10-11T13:28:00.836107Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"train_new = GetTopWeightedFeatures(voting_model, train)\n","metadata":{"execution":{"iopub.status.busy":"2024-10-11T13:28:55.741157Z","iopub.execute_input":"2024-10-11T13:28:55.741867Z","iopub.status.idle":"2024-10-11T13:30:03.415350Z","shell.execute_reply.started":"2024-10-11T13:28:55.741824Z","shell.execute_reply":"2024-10-11T13:30:03.414070Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"train[train_new[2]] = train_new[0]","metadata":{"execution":{"iopub.status.busy":"2024-10-11T13:30:47.306802Z","iopub.execute_input":"2024-10-11T13:30:47.307673Z","iopub.status.idle":"2024-10-11T13:30:47.315163Z","shell.execute_reply.started":"2024-10-11T13:30:47.307624Z","shell.execute_reply":"2024-10-11T13:30:47.314289Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"type(train)","metadata":{"execution":{"iopub.status.busy":"2024-10-11T13:30:53.016230Z","iopub.execute_input":"2024-10-11T13:30:53.017086Z","iopub.status.idle":"2024-10-11T13:30:53.022621Z","shell.execute_reply.started":"2024-10-11T13:30:53.017045Z","shell.execute_reply":"2024-10-11T13:30:53.021719Z"},"trusted":true},"execution_count":null,"outputs":[]},{"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        print(f\"Fold {fold+1} - Train QWK: {train_kappa:.4f}, Validation QWK: {val_kappa:.4f}\")\n        clear_output(wait=True)\n\n    print(f\"Mean Train QWK --> {np.mean(train_S):.4f}\")\n    print(f\"Mean Validation QWK ---> {np.mean(test_S):.4f}\")\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    print(f\"----> || Optimized QWK SCORE :: {Fore.CYAN}{Style.BRIGHT} {tKappa:.3f}{Style.RESET_ALL}\")\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":{"execution":{"iopub.status.busy":"2024-10-11T13:32:35.833104Z","iopub.execute_input":"2024-10-11T13:32:35.833820Z","iopub.status.idle":"2024-10-11T13:32:35.851013Z","shell.execute_reply.started":"2024-10-11T13:32:35.833779Z","shell.execute_reply":"2024-10-11T13:32:35.849800Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"# Hyperperameter Tuning","metadata":{}},{"cell_type":"markdown","source":"# Saving the Submission","metadata":{}},{"cell_type":"code","source":"\n# Train the ensemble model\nSubmission = TrainML(voting_model, test)\n\n# Save submission\nSubmission.to_csv('submission.csv', index=False)\nprint(Submission['sii'].value_counts())\n","metadata":{"execution":{"iopub.status.busy":"2024-10-11T13:32:56.948378Z","iopub.execute_input":"2024-10-11T13:32:56.949058Z","iopub.status.idle":"2024-10-11T13:33:29.114182Z","shell.execute_reply.started":"2024-10-11T13:32:56.949018Z","shell.execute_reply":"2024-10-11T13:33:29.113053Z"},"trusted":true},"execution_count":null,"outputs":[]}]}