{"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":"none","dataSources":[{"sourceId":81933,"databundleVersionId":9643020,"sourceType":"competition"}],"dockerImageVersionId":30786,"isInternetEnabled":false,"language":"python","sourceType":"notebook","isGpuEnabled":false}},"nbformat_minor":4,"nbformat":4,"cells":[{"cell_type":"code","source":"# This Python 3 environment comes with many helpful analytics libraries installed\n# It is defined by the kaggle/python Docker image: https://github.com/kaggle/docker-python\n# For example, here's several helpful packages to load\n\nimport numpy as np # linear algebra\nimport pandas as pd # data processing, CSV file I/O (e.g. pd.read_csv)\n\n# Input data files are available in the read-only \"../input/\" directory\n# For example, running this (by clicking run or pressing Shift+Enter) will list all files under the input directory\n\nimport os\nfor dirname, _, filenames in os.walk('/kaggle/input'):\n    for filename in filenames:\n        print(os.path.join(dirname, filename))\n\n# You can write up to 20GB to the current directory (/kaggle/working/) that gets preserved as output when you create a version using \"Save & Run All\" \n# You can also write temporary files to /kaggle/temp/, but they won't be saved outside of the current session","metadata":{"_uuid":"8f2839f25d086af736a60e9eeb907d3b93b6e0e5","_cell_guid":"b1076dfc-b9ad-4769-8c92-a6c4dae69d19","trusted":true,"execution":{"iopub.status.busy":"2024-12-01T23:35:57.266948Z","iopub.execute_input":"2024-12-01T23:35:57.268297Z","iopub.status.idle":"2024-12-01T23:36:01.621674Z","shell.execute_reply.started":"2024-12-01T23:35:57.268251Z","shell.execute_reply":"2024-12-01T23:36:01.620628Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"import pandas as pd\nimport numpy as np\nfrom sklearn.preprocessing import LabelEncoder, StandardScaler, PowerTransformer\nfrom sklearn.model_selection import StratifiedKFold, cross_val_score\nfrom sklearn.metrics import accuracy_score, f1_score\nimport lightgbm as lgb\nimport xgboost as xgb\nfrom catboost import CatBoostClassifier\nimport optuna\nfrom sklearn.ensemble import VotingClassifier\nimport pickle\nimport warnings\nfrom tqdm import tqdm\nimport os\nwarnings.filterwarnings('ignore')\n\ndef create_interaction_features(df):\n    \"\"\"Tạo các feature tương tác\"\"\"\n    if 'Physical-BMI' in df.columns and 'Physical-Weight' in df.columns:\n        df['BMI_Weight_Ratio'] = df['Physical-BMI'] / (df['Physical-Weight'] + 1e-3)\n    \n    if 'BIA-BIA_BMR' in df.columns and 'Physical-Weight' in df.columns:\n        df['BMR_Weight_Ratio'] = df['BIA-BIA_BMR'] / (df['Physical-Weight'] + 1e-3)\n    \n    if 'Physical-HeartRate' in df.columns and 'BIA-BIA_Activity_Level_num' in df.columns:\n        df['Heart_Activity_Interaction'] = df['Physical-HeartRate'] * df['BIA-BIA_Activity_Level_num']\n    \n    return df\n\ndef add_statistical_features(df):\n    \"\"\"Thêm các feature thống kê\"\"\"\n    numeric_cols = df.select_dtypes(include=['float64', 'int64']).columns\n    \n    for col in numeric_cols:\n        if col not in ['id', 'sii']:\n            df[f'{col}_squared'] = df[col] ** 2\n            df[f'{col}_cubed'] = df[col] ** 3\n            \n    return df\n\ndef preprocess_data(df, scaler=None, is_train=True):\n    # Chọn features quan trọng với thêm nhiều features hơn\n    selected_features = [\n        'Basic_Demos-Age', 'Basic_Demos-Sex', 'Physical-BMI',\n        'Physical-Height', 'Physical-Weight', 'Physical-HeartRate',\n        'BIA-BIA_Activity_Level_num', 'BIA-BIA_BMR', 'BIA-BIA_Fat',\n        'SDS-SDS_Total_Raw', 'PreInt_EduHx-computerinternet_hoursday',\n        'Basic_Demos-Race', 'Basic_Demos-Ethnicity',\n        'Physical-SBP', 'Physical-DBP',\n        'BIA-BIA_TBW', 'BIA-BIA_FFM',\n        'SDS-SDS_Somatic', 'SDS-SDS_Positive', 'SDS-SDS_Negative'\n    ]\n    \n    available_features = [col for col in selected_features if col in df.columns]\n    \n    if 'sii' in df.columns:\n        df = df[['id'] + available_features + ['sii']]\n    else:\n        df = df[['id'] + available_features]\n    \n    # Xử lý categorical features\n    cat_features = ['Basic_Demos-Sex', 'Basic_Demos-Race', 'Basic_Demos-Ethnicity']\n    for col in cat_features:\n        if col in df.columns:\n            le = LabelEncoder()\n            df[col] = le.fit_transform(df[col].astype(str))\n    \n    # Xử lý missing values với nhiều phương pháp\n    numeric_cols = [col for col in df.columns if col not in ['id', 'sii'] and df[col].dtype in ['int64', 'float64']]\n    \n    # Tạo features cho missing values\n    missing_features = []\n    for col in numeric_cols:\n        if df[col].isnull().sum() > 0:\n            missing_col = f'{col}_missing'\n            df[missing_col] = df[col].isnull().astype(int)\n            missing_features.append(missing_col)\n            df[col] = df[col].fillna(df[col].median())\n    \n    # Áp dụng Power Transform và scaling\n    if is_train:\n        scaler = PowerTransformer(method='yeo-johnson')\n        df[numeric_cols] = scaler.fit_transform(df[numeric_cols])\n    else:\n        if scaler is not None:\n            df[numeric_cols] = scaler.transform(df[numeric_cols])\n    \n    # Thêm features tương tác và thống kê\n    df = create_interaction_features(df)\n    df = add_statistical_features(df)\n    \n    return df, scaler, missing_features\n\ndef objective(trial, X, y):\n    \"\"\"Hàm tối ưu hyperparameters với Optuna\"\"\"\n    params = {\n        'objective': 'multiclass',\n        'num_class': 4,\n        'metric': 'multi_logloss',\n        'learning_rate': trial.suggest_float('learning_rate', 0.001, 0.1, log=True),\n        'num_leaves': trial.suggest_int('num_leaves', 20, 100),\n        'max_depth': trial.suggest_int('max_depth', 3, 12),\n        'feature_fraction': trial.suggest_float('feature_fraction', 0.5, 1.0),\n        'bagging_fraction': trial.suggest_float('bagging_fraction', 0.5, 1.0),\n        'bagging_freq': trial.suggest_int('bagging_freq', 1, 10),\n        'min_child_samples': trial.suggest_int('min_child_samples', 10, 100),\n        'lambda_l1': trial.suggest_float('lambda_l1', 1e-8, 10.0, log=True),\n        'lambda_l2': trial.suggest_float('lambda_l2', 1e-8, 10.0, log=True)\n    }\n    \n    # Cross validation score\n    cv = StratifiedKFold(n_splits=5, shuffle=True, random_state=42)\n    scores = cross_val_score(\n        lgb.LGBMClassifier(**params),\n        X, y,\n        cv=cv,\n        scoring='accuracy',\n        n_jobs=-1\n    )\n    \n    return scores.mean()\n\ndef train_and_predict():\n    # Đọc dữ liệu\n    print(\"\\nLoading and preprocessing data...\")\n    train_df = pd.read_csv('/kaggle/input/child-mind-institute-problematic-internet-use/train.csv')\n    test_df = pd.read_csv('/kaggle/input/child-mind-institute-problematic-internet-use/test.csv')\n    \n    train_df = train_df.dropna(subset=['sii'])\n    \n    # Tiền xử lý dữ liệu\n    train_df, scaler, missing_features = preprocess_data(train_df, is_train=True)\n    test_df, _, _ = preprocess_data(test_df, scaler=scaler, is_train=False)\n    \n    feature_cols = [col for col in train_df.columns if col not in ['id', 'sii']]\n    X = train_df[feature_cols]\n    y = train_df['sii'].astype(int)\n    X_test = test_df[feature_cols]\n    \n    # Tối ưu hyperparameters\n    print(\"\\nOptimizing hyperparameters...\")\n    study = optuna.create_study(direction='maximize')\n    study.optimize(lambda trial: objective(trial, X, y), n_trials=50)\n    best_params = study.best_params\n    \n    print(f\"\\nBest parameters found: {best_params}\")\n    \n    # Training với ensemble của nhiều mô hình\n    n_folds = 5\n    kf = StratifiedKFold(n_splits=n_folds, shuffle=True, random_state=42)\n    \n    lgb_models = []\n    xgb_models = []\n    cat_models = []\n    \n    print(\"\\nTraining models...\")\n    for fold, (train_idx, val_idx) in enumerate(kf.split(X, y), 1):\n        print(f\"\\nTraining fold {fold}/{n_folds}\")\n        \n        X_train, X_val = X.iloc[train_idx], X.iloc[val_idx]\n        y_train, y_val = y.iloc[train_idx], y.iloc[val_idx]\n        \n        # LightGBM\n        lgb_params = {\n            **best_params,\n            'random_state': 42,\n            'n_estimators': 1000,\n            'verbose': -1\n        }\n        lgb_model = lgb.LGBMClassifier(**lgb_params)\n        lgb_model.fit(\n            X_train, y_train,\n            eval_set=[(X_val, y_val)],\n            callbacks=[lgb.early_stopping(50, verbose=False)]\n        )\n        lgb_models.append(lgb_model)\n        \n        # XGBoost\n        xgb_model = xgb.XGBClassifier(\n            objective='multi:softprob',\n            num_class=4,\n            learning_rate=best_params['learning_rate'],\n            max_depth=best_params['max_depth'],\n            n_estimators=1000,\n            verbosity=0\n        )\n        xgb_model.fit(\n            X_train, y_train,\n            eval_set=[(X_val, y_val)],\n            early_stopping_rounds=50,\n            verbose=False\n        )\n        xgb_models.append(xgb_model)\n        \n        # CatBoost\n        cat_model = CatBoostClassifier(\n            iterations=1000,\n            learning_rate=best_params['learning_rate'],\n            depth=best_params['max_depth'],\n            cat_features=[col for col in X_train.columns if 'cat' in col],\n            verbose=0\n        )\n        cat_model.fit(X_train, y_train)\n        cat_models.append(cat_model)\n    \n    # Gộp các mô hình bằng VotingClassifier\n    voting_clf = VotingClassifier(estimators=[\n        ('lgb', lgb_models[-1]),\n        ('xgb', xgb_models[-1]),\n        ('cat', cat_models[-1])\n    ], voting='soft')\n    \n    voting_clf.fit(X, y)\n    \n    print(\"\\nMaking predictions...\")\n    y_pred = voting_clf.predict(X_test)\n    \n    # Lưu mô hình và dự đoán\n    if not os.path.exists('models'):\n        os.mkdir('models')\n    \n    pickle.dump(voting_clf, open('models/voting_model.pkl', 'wb'))\n    pd.DataFrame({'id': test_df['id'], 'sii': y_pred}).to_csv('submission.csv', index=False)\n    print(\"\\nSubmission saved.\")\n\n# Bắt đầu huấn luyện và dự đoán\ntrain_and_predict()\n","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2024-12-01T23:37:12.177508Z","iopub.execute_input":"2024-12-01T23:37:12.178044Z","iopub.status.idle":"2024-12-01T23:42:42.133058Z","shell.execute_reply.started":"2024-12-01T23:37:12.178008Z","shell.execute_reply":"2024-12-01T23:42:42.131801Z"}},"outputs":[],"execution_count":null}]}