{"metadata":{"kernelspec":{"language":"python","display_name":"Python 3","name":"python3"},"language_info":{"name":"python","version":"3.12.12","mimetype":"text/x-python","codemirror_mode":{"name":"ipython","version":3},"pygments_lexer":"ipython3","nbconvert_exporter":"python","file_extension":".py"},"kaggle":{"accelerator":"gpu","dataSources":[{"sourceId":130062,"databundleVersionId":15606741,"sourceType":"competition"}],"dockerImageVersionId":31260,"isInternetEnabled":true,"language":"python","sourceType":"notebook","isGpuEnabled":true}},"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":"2026-02-07T05:25:16.982670Z","iopub.execute_input":"2026-02-07T05:25:16.983281Z","iopub.status.idle":"2026-02-07T05:25:18.004606Z","shell.execute_reply.started":"2026-02-07T05:25:16.983246Z","shell.execute_reply":"2026-02-07T05:25:18.003775Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"import pandas as pd\nimport numpy as np\nimport lightgbm as lgb\nfrom sklearn.model_selection import KFold\nfrom sklearn.metrics import mean_squared_log_error\nfrom sklearn.preprocessing import LabelEncoder\nimport warnings\n\nwarnings.filterwarnings('ignore')\n\n# 1. Load the Datasets\nprint(\"Loading data...\")\ntrain_df = pd.read_csv('/kaggle/input/bidding-predictions-for-construction/train_summary.csv')\ntest_df = pd.read_csv('/kaggle/input/bidding-predictions-for-construction/test.csv')\nsample_sub = pd.read_csv('/kaggle/input/bidding-predictions-for-construction/sample_submission.csv')\n\n# 2. Preprocessing & Feature Engineering\ndef preprocess_data(df):\n    # Convert date to datetime\n    if 'bid_date' in df.columns:\n        df['bid_date'] = pd.to_datetime(df['bid_date'])\n        df['bid_year'] = df['bid_date'].dt.year\n        df['bid_month'] = df['bid_date'].dt.month\n        df['bid_dayofweek'] = df['bid_date'].dt.dayofweek\n    \n    # Define potential categorical columns\n    potential_cats = ['contractor_id', 'job_category_description', 'primary_location', 'category_id']\n    \n    # Fill missing values only for columns that exist\n    for col in potential_cats:\n        if col in df.columns:\n            df[col] = df[col].astype(str).fillna('MISSING')\n            \n    return df\n\nprint(\"Preprocessing...\")\ntrain_df = preprocess_data(train_df)\ntest_df = preprocess_data(test_df)\n\n# 3. Encoding Categorical Variables\n# Combine to ensure encoder covers all categories\nall_data = pd.concat([train_df, test_df], axis=0, ignore_index=True)\n\n# LIST OF CANDIDATE CATEGORICAL COLUMNS\ncandidate_cat_cols = ['contractor_id', 'job_category_description', 'primary_location', 'category_id']\n\n# FILTER: Only select columns that actually exist in the dataframe\ncat_cols = [c for c in candidate_cat_cols if c in all_data.columns]\nprint(f\"Encoding columns: {cat_cols}\")\n\nfor col in cat_cols:\n    le = LabelEncoder()\n    all_data[col] = le.fit_transform(all_data[col].astype(str))\n\n# Split back into train and test\ntrain_df = all_data[all_data['total_bid'].notnull()].copy()\ntest_df = all_data[all_data['total_bid'].isnull()].copy()\n\n# 4. Prepare Target and Features\n# RMSLE optimization: train on log1p(target)\ntarget = np.log1p(train_df['total_bid'])\n\n# Define potential features\nfeature_candidates = ['bid_year', 'bid_month', 'bid_dayofweek', 'category_id', \n                      'contractor_id', 'job_category_description', 'primary_location']\n\n# Only use features that exist\nfeatures = [f for f in feature_candidates if f in train_df.columns]\nprint(f\"Training with features: {features}\")\n\nX = train_df[features]\ny = target\nX_test = test_df[features]\n\n# 5. Train Model (LightGBM)\nprint(\"Training LightGBM Model...\")\nparams = {\n    'objective': 'regression',\n    'metric': 'rmse',\n    'boosting_type': 'gbdt',\n    'learning_rate': 0.05,\n    'num_leaves': 31,\n    'feature_fraction': 0.9,\n    'bagging_fraction': 0.8,\n    'bagging_freq': 5,\n    'verbose': -1,\n    'random_state': 42\n}\n\nkf = KFold(n_splits=5, shuffle=True, random_state=42)\ntest_preds = np.zeros(len(X_test))\noof_preds = np.zeros(len(X))\n\nfor fold, (train_idx, val_idx) in enumerate(kf.split(X, y)):\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    model = lgb.LGBMRegressor(**params, n_estimators=1000)\n    model.fit(X_train, y_train, \n              eval_set=[(X_val, y_val)],\n              callbacks=[lgb.early_stopping(stopping_rounds=50), lgb.log_evaluation(False)]\n             )\n    \n    oof_preds[val_idx] = model.predict(X_val)\n    test_preds += model.predict(X_test) / kf.get_n_splits()\n\n# Calculate Score\nrmsle_score = np.sqrt(mean_squared_log_error(np.expm1(y), np.expm1(oof_preds)))\nprint(f\"Validation RMSLE: {rmsle_score:.5f}\")\n\n# 6. Create Submission File\nfinal_predictions = np.expm1(test_preds)\nfinal_predictions = np.maximum(0, final_predictions)\n\nsubmission = pd.DataFrame({\n    'row_id': test_df['row_id'],\n    'total_bid': final_predictions\n})\n\nsubmission.to_csv('submission.csv', index=False)\nprint(\"submission.csv created successfully!\")","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2026-02-07T05:28:36.983230Z","iopub.execute_input":"2026-02-07T05:28:36.983828Z","iopub.status.idle":"2026-02-07T05:28:42.784777Z","shell.execute_reply.started":"2026-02-07T05:28:36.983801Z","shell.execute_reply":"2026-02-07T05:28:42.784036Z"}},"outputs":[],"execution_count":null}]}