{"metadata":{"kernelspec":{"language":"python","display_name":"Python 3","name":"python3"},"language_info":{"name":"python","version":"3.12.13","mimetype":"text/x-python","codemirror_mode":{"name":"ipython","version":3},"pygments_lexer":"ipython3","nbconvert_exporter":"python","file_extension":".py"},"kaggle":{"accelerator":"none","dataSources":[],"dockerImageVersionId":28755,"isInternetEnabled":false,"language":"python","sourceType":"notebook","isGpuEnabled":false}},"nbformat_minor":4,"nbformat":4,"cells":[{"cell_type":"markdown","source":"# Avito Demand Prediction\n\n## Goal\n\nThe objective of this competition is to predict the probability that an advertisement will lead to a successful deal.\n\nTarget Variable:\n- deal_probability\n\nEvaluation Metric:\n- RMSE","metadata":{}},{"cell_type":"code","source":"import warnings\n\nimport numpy as np\nimport pandas as pd\n\nimport matplotlib.pyplot as plt\nimport seaborn as sns\n\nwarnings.filterwarnings(\"ignore\")","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2026-08-06T14:42:19.796767Z","iopub.execute_input":"2026-08-06T14:42:19.797114Z","iopub.status.idle":"2026-08-06T14:42:25.49163Z","shell.execute_reply.started":"2026-08-06T14:42:19.797081Z","shell.execute_reply":"2026-08-06T14:42:25.490573Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"DATA_PATH  = \"/kaggle/input/competitions/avito-demand-prediction\"\n\ntrain = pd.read_csv(DATA_PATH + \"/train.csv\", parse_dates=[\"activation_date\"])\n\ntest = pd.read_csv(DATA_PATH + \"/test.csv\" , parse_dates =[\"activation_date\"])","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2026-08-06T14:42:25.493506Z","iopub.execute_input":"2026-08-06T14:42:25.49413Z","iopub.status.idle":"2026-08-06T14:43:03.835338Z","shell.execute_reply.started":"2026-08-06T14:42:25.494095Z","shell.execute_reply":"2026-08-06T14:43:03.834405Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"train.head()","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2026-08-06T14:43:03.836639Z","iopub.execute_input":"2026-08-06T14:43:03.836959Z","iopub.status.idle":"2026-08-06T14:43:03.866958Z","shell.execute_reply.started":"2026-08-06T14:43:03.836923Z","shell.execute_reply":"2026-08-06T14:43:03.86595Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"train.shape","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2026-08-06T14:43:03.869561Z","iopub.execute_input":"2026-08-06T14:43:03.869897Z","iopub.status.idle":"2026-08-06T14:43:03.877388Z","shell.execute_reply.started":"2026-08-06T14:43:03.86987Z","shell.execute_reply":"2026-08-06T14:43:03.876354Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"train.info()","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2026-08-06T14:43:03.878643Z","iopub.execute_input":"2026-08-06T14:43:03.878916Z","iopub.status.idle":"2026-08-06T14:43:05.030189Z","shell.execute_reply.started":"2026-08-06T14:43:03.87889Z","shell.execute_reply":"2026-08-06T14:43:05.029047Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"train.describe()","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2026-08-06T14:43:05.031509Z","iopub.execute_input":"2026-08-06T14:43:05.032139Z","iopub.status.idle":"2026-08-06T14:43:05.357917Z","shell.execute_reply.started":"2026-08-06T14:43:05.032105Z","shell.execute_reply":"2026-08-06T14:43:05.356902Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"train[\"deal_probability\"].describe()","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2026-08-06T14:43:05.359049Z","iopub.execute_input":"2026-08-06T14:43:05.359427Z","iopub.status.idle":"2026-08-06T14:43:05.421689Z","shell.execute_reply.started":"2026-08-06T14:43:05.359397Z","shell.execute_reply":"2026-08-06T14:43:05.42069Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"# Calculate Memory Usage\nmemory_gb = train.memory_usage(deep=True).sum() / 1024**2\nprint(f\"{memory_gb:.2f} MB\")","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2026-08-06T14:43:05.42276Z","iopub.execute_input":"2026-08-06T14:43:05.423971Z","iopub.status.idle":"2026-08-06T14:43:10.018678Z","shell.execute_reply.started":"2026-08-06T14:43:05.423936Z","shell.execute_reply":"2026-08-06T14:43:10.017516Z"}},"outputs":[],"execution_count":null},{"cell_type":"markdown","source":"# Exploratory Data Analysis (EDA)\n\nIn this section, we will explore the dataset to understand:\n\n- Dataset structure\n- Target distribution\n- Missing values\n- Feature types\n- Numerical feature distributions\n- Categorical feature distributions\n- Initial observations","metadata":{}},{"cell_type":"code","source":"print(train.shape)\n\nmissing = train.isnull().sum().sort_values(ascending = False)\nmissing = missing[missing > 0]\nmissing","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2026-08-06T14:43:10.019918Z","iopub.execute_input":"2026-08-06T14:43:10.020269Z","iopub.status.idle":"2026-08-06T14:43:11.140404Z","shell.execute_reply.started":"2026-08-06T14:43:10.020229Z","shell.execute_reply":"2026-08-06T14:43:11.139482Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"missing_percent = (missing / len(train)) * 100\nmissing_percent","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2026-08-06T14:43:11.143181Z","iopub.execute_input":"2026-08-06T14:43:11.143477Z","iopub.status.idle":"2026-08-06T14:43:11.151581Z","shell.execute_reply.started":"2026-08-06T14:43:11.143452Z","shell.execute_reply":"2026-08-06T14:43:11.150524Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"missing_df = pd.DataFrame({\n    \"Missing Count\": missing,\n    \"Missing Percentage\": missing_percent\n})\n\nmissing_df","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2026-08-06T14:43:11.152625Z","iopub.execute_input":"2026-08-06T14:43:11.152951Z","iopub.status.idle":"2026-08-06T14:43:11.175803Z","shell.execute_reply.started":"2026-08-06T14:43:11.152923Z","shell.execute_reply":"2026-08-06T14:43:11.17488Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"plt.figure(figsize=(10, 5))\n\nsns.barplot(x = missing_df.index,y = missing_df[\"Missing Percentage\"])\n\nplt.xticks(rotation=45)\n\nplt.title(\"Missing Values Percentage\")\n\nplt.show()","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2026-08-06T14:43:11.177031Z","iopub.execute_input":"2026-08-06T14:43:11.1774Z","iopub.status.idle":"2026-08-06T14:43:11.447084Z","shell.execute_reply.started":"2026-08-06T14:43:11.177362Z","shell.execute_reply":"2026-08-06T14:43:11.446077Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"train.duplicated().sum()","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2026-08-06T14:43:11.448548Z","iopub.execute_input":"2026-08-06T14:43:11.448977Z","iopub.status.idle":"2026-08-06T14:43:15.875624Z","shell.execute_reply.started":"2026-08-06T14:43:11.448932Z","shell.execute_reply":"2026-08-06T14:43:15.874693Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"train[\"deal_probability\"].describe()","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2026-08-06T14:43:15.876911Z","iopub.execute_input":"2026-08-06T14:43:15.877248Z","iopub.status.idle":"2026-08-06T14:43:15.938829Z","shell.execute_reply.started":"2026-08-06T14:43:15.877208Z","shell.execute_reply":"2026-08-06T14:43:15.937897Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"plt.figure(figsize=(8,5))\n\nsns.histplot(\n    train[\"deal_probability\"],\n    bins=30,\n    kde=True\n)\n\nplt.title(\"Distribution of Deal Probability\")\n\nplt.show()","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2026-08-06T14:43:15.940372Z","iopub.execute_input":"2026-08-06T14:43:15.94081Z","iopub.status.idle":"2026-08-06T14:43:23.260896Z","shell.execute_reply.started":"2026-08-06T14:43:15.940766Z","shell.execute_reply":"2026-08-06T14:43:23.259892Z"}},"outputs":[],"execution_count":null},{"cell_type":"markdown","source":"## Observation\n\nThe target distribution is highly skewed toward zero.\n\nA large number of advertisements have a deal probability of 0.\n\nThe target is not normally distributed.","metadata":{}},{"cell_type":"code","source":"train.dtypes.value_counts()","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2026-08-06T14:43:23.262253Z","iopub.execute_input":"2026-08-06T14:43:23.262639Z","iopub.status.idle":"2026-08-06T14:43:23.27244Z","shell.execute_reply.started":"2026-08-06T14:43:23.262578Z","shell.execute_reply":"2026-08-06T14:43:23.27113Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"categorical_cols = train.select_dtypes(include = [\"object\"]).columns\nnumerical_cols = train.select_dtypes(include = [\"int64\",\"float64\"]).columns\ndatetime_cols = train.select_dtypes(include = [\"datetime\"]).columns","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2026-08-06T14:43:23.273813Z","iopub.execute_input":"2026-08-06T14:43:23.274165Z","iopub.status.idle":"2026-08-06T14:43:23.673606Z","shell.execute_reply.started":"2026-08-06T14:43:23.274124Z","shell.execute_reply":"2026-08-06T14:43:23.672537Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"print(\"Categorical Features :\", len(categorical_cols))\nprint(\"Numerical Features :\", len(numerical_cols))\nprint(\"Datetime Features :\", len(datetime_cols))","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2026-08-06T14:43:23.675262Z","iopub.execute_input":"2026-08-06T14:43:23.675727Z","iopub.status.idle":"2026-08-06T14:43:23.682247Z","shell.execute_reply.started":"2026-08-06T14:43:23.675683Z","shell.execute_reply":"2026-08-06T14:43:23.681093Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"categorical_cols","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2026-08-06T14:43:23.684175Z","iopub.execute_input":"2026-08-06T14:43:23.684616Z","iopub.status.idle":"2026-08-06T14:43:23.70641Z","shell.execute_reply.started":"2026-08-06T14:43:23.684539Z","shell.execute_reply":"2026-08-06T14:43:23.705225Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"print(datetime_cols)\nnumerical_cols\n","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2026-08-06T14:43:23.707941Z","iopub.execute_input":"2026-08-06T14:43:23.710134Z","iopub.status.idle":"2026-08-06T14:43:23.738407Z","shell.execute_reply.started":"2026-08-06T14:43:23.709925Z","shell.execute_reply":"2026-08-06T14:43:23.737296Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"numerical_cols = numerical_cols.drop(\"deal_probability\")","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2026-08-06T14:43:23.739744Z","iopub.execute_input":"2026-08-06T14:43:23.740177Z","iopub.status.idle":"2026-08-06T14:43:23.764549Z","shell.execute_reply.started":"2026-08-06T14:43:23.740129Z","shell.execute_reply":"2026-08-06T14:43:23.763419Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"numerical_df = train[numerical_cols]\nnumerical_df ","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2026-08-06T14:43:23.766282Z","iopub.execute_input":"2026-08-06T14:43:23.766792Z","iopub.status.idle":"2026-08-06T14:43:23.811642Z","shell.execute_reply.started":"2026-08-06T14:43:23.766746Z","shell.execute_reply":"2026-08-06T14:43:23.810038Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"    fig, ax = plt.subplots(1, 2, figsize=(14, 4))\n\n    sns.histplot(numerical_df.price, kde=True, ax=ax[0])\n    ax[0].set_title(\"price Distribution\")\n\n    sns.boxplot(x=numerical_df.price, ax=ax[1])\n    ax[1].set_title(\"price Boxplot\")\n\n    plt.show()","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2026-08-06T14:41:26.139285Z","iopub.execute_input":"2026-08-06T14:41:26.139797Z","execution_failed":"2026-08-06T14:41:44.182Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"train[\"price\"].sort_values(ascending = False).head(10)","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2026-08-06T14:43:23.813139Z","iopub.execute_input":"2026-08-06T14:43:23.813669Z","iopub.status.idle":"2026-08-06T14:43:24.174687Z","shell.execute_reply.started":"2026-08-06T14:43:23.813545Z","shell.execute_reply":"2026-08-06T14:43:24.173652Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"train[\"price\"].describe(percentiles=[0.90,0.95,0.99,0.999])","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2026-08-06T14:43:29.607014Z","iopub.execute_input":"2026-08-06T14:43:29.607365Z","iopub.status.idle":"2026-08-06T14:43:29.68125Z","shell.execute_reply.started":"2026-08-06T14:43:29.607335Z","shell.execute_reply":"2026-08-06T14:43:29.680337Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"train.nlargest(10,\"price\")[[\"price\", \"category_name\", \"title\"]]","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2026-08-06T14:43:30.185715Z","iopub.execute_input":"2026-08-06T14:43:30.186039Z","iopub.status.idle":"2026-08-06T14:43:30.667126Z","shell.execute_reply.started":"2026-08-06T14:43:30.186013Z","shell.execute_reply":"2026-08-06T14:43:30.666121Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"_, ax = plt.subplots(1, 2, figsize = (14,4))\nsns.histplot(np.log1p(train[\"price\"]) ,bins = 50 ,kde = True, ax=ax[0])\nsns.boxplot(np.log1p(train[\"price\"]) , ax=ax[1])\nplt.show()","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2026-08-06T14:43:30.668908Z","iopub.execute_input":"2026-08-06T14:43:30.669332Z","iopub.status.idle":"2026-08-06T14:43:41.150848Z","shell.execute_reply.started":"2026-08-06T14:43:30.669287Z","shell.execute_reply":"2026-08-06T14:43:41.149948Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"def categorical_summary(df, col):\n    \n    print(\"=\" * 50)\n    print(f\"Feature: {col}\")\n    print(\"=\" * 50)\n\n    print(\"Unique Values:\", df[col].nunique())\n\n    print()\n\n    summary = pd.DataFrame({\n        \"Count\": df[col].value_counts(),\n        \"Percentage\": df[col].value_counts(normalize=True) * 100\n    })\n\n    display(summary.head(10))","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2026-08-06T14:43:41.152563Z","iopub.execute_input":"2026-08-06T14:43:41.152987Z","iopub.status.idle":"2026-08-06T14:43:41.159438Z","shell.execute_reply.started":"2026-08-06T14:43:41.152954Z","shell.execute_reply":"2026-08-06T14:43:41.158523Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"for col in categorical_cols:\n    categorical_summary(train, col)","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2026-08-06T14:43:41.16058Z","iopub.execute_input":"2026-08-06T14:43:41.160979Z","iopub.status.idle":"2026-08-06T14:44:01.982231Z","shell.execute_reply.started":"2026-08-06T14:43:41.160941Z","shell.execute_reply":"2026-08-06T14:44:01.98105Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"plt.figure(figsize=(10,5))\n\nsns.countplot(\n    data=train,\n    y=\"parent_category_name\",\n    order=train[\"parent_category_name\"].value_counts().index\n)\n\nplt.title(\"Parent Categories\")\n\nplt.show()","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2026-08-06T14:44:01.984473Z","iopub.execute_input":"2026-08-06T14:44:01.98496Z","iopub.status.idle":"2026-08-06T14:44:04.271958Z","shell.execute_reply.started":"2026-08-06T14:44:01.984924Z","shell.execute_reply":"2026-08-06T14:44:04.271006Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"plt.figure(figsize = (10,5))\n\nsns.countplot(data = train,\n             x = \"user_type\",\n             order = train[\"user_type\"].value_counts().index\n             )\nplt.show()","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2026-08-06T14:44:04.273173Z","iopub.execute_input":"2026-08-06T14:44:04.273776Z","iopub.status.idle":"2026-08-06T14:44:06.449099Z","shell.execute_reply.started":"2026-08-06T14:44:04.273744Z","shell.execute_reply":"2026-08-06T14:44:06.448073Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"user_type_target = (\n    train\n    .groupby(\"user_type\")[\"deal_probability\"]\n    .mean()\n    .sort_values(ascending=False)\n)\n\nuser_type_target","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2026-08-06T14:44:06.450309Z","iopub.execute_input":"2026-08-06T14:44:06.450663Z","iopub.status.idle":"2026-08-06T14:44:06.56423Z","shell.execute_reply.started":"2026-08-06T14:44:06.450621Z","shell.execute_reply":"2026-08-06T14:44:06.563426Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"sns.barplot(x = user_type_target.index,\n           y = user_type_target.values)\n\nplt.ylabel(\"Average Deal Probability\")\nplt.title(\"User Type vs Deal Probability\")\n\nplt.show()","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2026-08-06T14:44:09.318091Z","iopub.execute_input":"2026-08-06T14:44:09.318433Z","iopub.status.idle":"2026-08-06T14:44:09.487149Z","shell.execute_reply.started":"2026-08-06T14:44:09.318405Z","shell.execute_reply":"2026-08-06T14:44:09.486207Z"}},"outputs":[],"execution_count":null},{"cell_type":"markdown","source":"- **Private** users have the highest average deal probability (~0.15).\n- **Company** accounts have a lower average deal probability (~0.12).\n- **Shop** accounts have the lowest average deal probability (~0.06).\n\n**Insight:**\nThe type of seller appears to influence the likelihood of a successful deal. Therefore, `user_type` is likely to be an important predictive feature.\n","metadata":{}},{"cell_type":"code","source":"parent_target = (\n    train\n    .groupby(\"parent_category_name\")[\"deal_probability\"]\n    .mean()\n    .sort_values(ascending=False)\n)\n\nparent_target\n","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2026-08-06T14:44:10.327032Z","iopub.execute_input":"2026-08-06T14:44:10.327405Z","iopub.status.idle":"2026-08-06T14:44:10.461209Z","shell.execute_reply.started":"2026-08-06T14:44:10.327373Z","shell.execute_reply":"2026-08-06T14:44:10.459991Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"plt.figure(figsize=(10,5))\n\nsns.barplot(\n    x=parent_target.values,\n    y=parent_target.index\n)\n\nplt.xlabel(\"Average Deal Probability\")\nplt.title(\"Parent Category vs Deal Probability\")\n\nplt.show()","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2026-08-06T14:44:10.797912Z","iopub.execute_input":"2026-08-06T14:44:10.798333Z","iopub.status.idle":"2026-08-06T14:44:11.018956Z","shell.execute_reply.started":"2026-08-06T14:44:10.798288Z","shell.execute_reply":"2026-08-06T14:44:11.017714Z"}},"outputs":[],"execution_count":null},{"cell_type":"markdown","source":"- **Services** have the highest average deal probability (~0.40).\n- **Transport** and **Animals** also have relatively high probabilities.\n- **Personal Items** have the lowest average deal probability (~0.08).\n\n**Insight:**\nThe product category has a strong relationship with the target variable. Different categories exhibit different selling behaviors, making `parent_category_name` an informative feature.\n","metadata":{}},{"cell_type":"code","source":"category_name_target = (train.groupby(\"category_name\")[\"deal_probability\"]\n                        .mean()\n                        .sort_values(ascending=False)\n                        .head(10)\n                       )\ncategory_name_target","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2026-08-06T14:44:15.087736Z","iopub.execute_input":"2026-08-06T14:44:15.088189Z","iopub.status.idle":"2026-08-06T14:44:15.263652Z","shell.execute_reply.started":"2026-08-06T14:44:15.088137Z","shell.execute_reply":"2026-08-06T14:44:15.262672Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"plt.figure(figsize=(10,5))\n\nsns.barplot(\n    x=category_name_target.values,\n    y=category_name_target.index\n)\n\nplt.xlabel(\"Average Deal Probability\")\nplt.title(\"category_name vs Deal Probability\")\n\nplt.show()","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2026-08-06T14:44:15.563829Z","iopub.execute_input":"2026-08-06T14:44:15.564183Z","iopub.status.idle":"2026-08-06T14:44:15.779172Z","shell.execute_reply.started":"2026-08-06T14:44:15.564151Z","shell.execute_reply":"2026-08-06T14:44:15.778291Z"}},"outputs":[],"execution_count":null},{"cell_type":"markdown","source":"- Service-related advertisements achieve the highest average deal probability.\n- Vehicle and pet-related categories also perform well.\n- Average deal probability varies considerably across categories.\n\n**Insight:**\nFine-grained categories contain valuable information and should be retained during feature engineering.","metadata":{}},{"cell_type":"code","source":"train[\"activation_date\"].head()","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2026-08-06T14:44:20.149854Z","iopub.execute_input":"2026-08-06T14:44:20.15022Z","iopub.status.idle":"2026-08-06T14:44:20.158472Z","shell.execute_reply.started":"2026-08-06T14:44:20.150189Z","shell.execute_reply":"2026-08-06T14:44:20.157455Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"train[\"day_name\"] = train[\"activation_date\"].dt.day_name()\ntest[\"day_name\"] = test[\"activation_date\"].dt.day_name()","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2026-08-06T14:44:20.630562Z","iopub.execute_input":"2026-08-06T14:44:20.630955Z","iopub.status.idle":"2026-08-06T14:44:21.130637Z","shell.execute_reply.started":"2026-08-06T14:44:20.630923Z","shell.execute_reply":"2026-08-06T14:44:21.129679Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"train[\"day\"] = train[\"activation_date\"].dt.day\ntrain[\"month\"] = train[\"activation_date\"].dt.month\ntrain[\"weakday\"] = train[\"activation_date\"].dt.weekday\n\ntest[\"day\"] = test[\"activation_date\"].dt.day\ntest[\"month\"] = test[\"activation_date\"].dt.month\ntest[\"weakday\"] = test[\"activation_date\"].dt.weekday","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2026-08-06T14:44:21.132062Z","iopub.execute_input":"2026-08-06T14:44:21.132371Z","iopub.status.idle":"2026-08-06T14:44:21.309973Z","shell.execute_reply.started":"2026-08-06T14:44:21.132342Z","shell.execute_reply":"2026-08-06T14:44:21.308921Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"train[\"day_name\"].value_counts()","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2026-08-06T14:44:21.648843Z","iopub.execute_input":"2026-08-06T14:44:21.649233Z","iopub.status.idle":"2026-08-06T14:44:21.819511Z","shell.execute_reply.started":"2026-08-06T14:44:21.6492Z","shell.execute_reply":"2026-08-06T14:44:21.818522Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"plt.figure(figsize=(10,5))\n\nsns.countplot(\n    data=train,\n    x=\"day_name\",\n    order=[\n        \"Monday\",\n        \"Tuesday\",\n        \"Wednesday\",\n        \"Thursday\",\n        \"Friday\",\n        \"Saturday\",\n        \"Sunday\"\n    ]\n)\n\nplt.title(\"Advertisements by Day of Week\")\n\nplt.show()\n","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2026-08-06T14:44:22.137699Z","iopub.execute_input":"2026-08-06T14:44:22.138055Z","iopub.status.idle":"2026-08-06T14:44:24.471959Z","shell.execute_reply.started":"2026-08-06T14:44:22.138023Z","shell.execute_reply":"2026-08-06T14:44:24.470731Z"}},"outputs":[],"execution_count":null},{"cell_type":"markdown","source":"#### Observations\n\n- Advertisements are distributed across all days of the week.\n- Monday and Sunday have the highest number of published advertisements.\n- Friday and Saturday have slightly fewer advertisements.\n- No significant imbalance is observed across weekdays.","metadata":{}},{"cell_type":"code","source":"day_target = (\n    train\n    .groupby(\"day_name\")[\"deal_probability\"]\n    .mean()\n    .reindex([\n        \"Monday\",\n        \"Tuesday\",\n        \"Wednesday\",\n        \"Thursday\",\n        \"Friday\",\n        \"Saturday\",\n        \"Sunday\"\n    ])\n)\n\nday_target","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2026-08-06T14:44:24.474282Z","iopub.execute_input":"2026-08-06T14:44:24.47473Z","iopub.status.idle":"2026-08-06T14:44:24.591287Z","shell.execute_reply.started":"2026-08-06T14:44:24.474698Z","shell.execute_reply":"2026-08-06T14:44:24.59047Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"plt.figure(figsize=(10,5))\n\nsns.barplot(x = day_target.index,\n           y = day_target.values)\n\nplt.ylabel(\"Average Deal Probability\")\nplt.title(\"Day of Week vs Deal Probability\")\n\nplt.show()","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2026-08-06T14:44:26.768961Z","iopub.execute_input":"2026-08-06T14:44:26.769331Z","iopub.status.idle":"2026-08-06T14:44:26.965466Z","shell.execute_reply.started":"2026-08-06T14:44:26.769297Z","shell.execute_reply":"2026-08-06T14:44:26.964522Z"}},"outputs":[],"execution_count":null},{"cell_type":"markdown","source":"#### Observations\n\n- The average deal probability is very similar across all weekdays.\n- Friday and Saturday have slightly higher average deal probabilities.\n- The overall difference between weekdays is very small.\n\n**Insight**\n\nThe day of the week has only a weak relationship with the target variable.","metadata":{}},{"cell_type":"code","source":"train[\"month\"].value_counts().sort_index()","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2026-08-06T14:44:27.422312Z","iopub.execute_input":"2026-08-06T14:44:27.422704Z","iopub.status.idle":"2026-08-06T14:44:27.441284Z","shell.execute_reply.started":"2026-08-06T14:44:27.42267Z","shell.execute_reply":"2026-08-06T14:44:27.440422Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"train[[\"title\",\"description\"]].isnull().sum()\n","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2026-08-06T14:44:27.75105Z","iopub.execute_input":"2026-08-06T14:44:27.751448Z","iopub.status.idle":"2026-08-06T14:44:28.136082Z","shell.execute_reply.started":"2026-08-06T14:44:27.751404Z","shell.execute_reply":"2026-08-06T14:44:28.135178Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"train[\"title_length\"] = train[\"title\"].str.len()\ntrain[\"title_length\"].describe()","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2026-08-06T14:44:30.355699Z","iopub.execute_input":"2026-08-06T14:44:30.356049Z","iopub.status.idle":"2026-08-06T14:44:30.890737Z","shell.execute_reply.started":"2026-08-06T14:44:30.356019Z","shell.execute_reply":"2026-08-06T14:44:30.889679Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"test[\"title_length\"] = test[\"title\"].str.len()","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2026-08-06T14:44:30.892475Z","iopub.execute_input":"2026-08-06T14:44:30.893174Z","iopub.status.idle":"2026-08-06T14:44:31.068442Z","shell.execute_reply.started":"2026-08-06T14:44:30.893141Z","shell.execute_reply":"2026-08-06T14:44:31.067656Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"sns.histplot(train[\"title_length\"],\n            bins = 40,\n            kde = True)\n\nplt.title(\"Title length distribution\")\nplt.show()","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2026-08-06T14:44:31.069425Z","iopub.execute_input":"2026-08-06T14:44:31.069743Z","iopub.status.idle":"2026-08-06T14:44:37.972147Z","shell.execute_reply.started":"2026-08-06T14:44:31.069705Z","shell.execute_reply":"2026-08-06T14:44:37.971144Z"}},"outputs":[],"execution_count":null},{"cell_type":"markdown","source":"### Title Length\n\n#### Observations\n\n- Most advertisement titles are relatively short.\n- The majority of titles contain between 10 and 30 characters.\n\n**Insight**\n\nTitle length may contain useful information, but most sellers prefer concise titles.","metadata":{}},{"cell_type":"code","source":"train[\"description_length\"] = train[\"description\"].fillna(\"\").str.len()","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2026-08-06T14:44:37.974162Z","iopub.execute_input":"2026-08-06T14:44:37.974487Z","iopub.status.idle":"2026-08-06T14:44:38.95645Z","shell.execute_reply.started":"2026-08-06T14:44:37.974458Z","shell.execute_reply":"2026-08-06T14:44:38.95552Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"train[\"description_length\"].describe()","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2026-08-06T14:44:38.957701Z","iopub.execute_input":"2026-08-06T14:44:38.958082Z","iopub.status.idle":"2026-08-06T14:44:39.011659Z","shell.execute_reply.started":"2026-08-06T14:44:38.95804Z","shell.execute_reply":"2026-08-06T14:44:39.010737Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"test[\"description_length\"] = test[\"description\"].fillna(\"\").str.len()\n","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2026-08-06T14:44:39.012926Z","iopub.execute_input":"2026-08-06T14:44:39.013888Z","iopub.status.idle":"2026-08-06T14:44:39.403796Z","shell.execute_reply.started":"2026-08-06T14:44:39.013845Z","shell.execute_reply":"2026-08-06T14:44:39.402825Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"sns.histplot(train[\"description_length\"] , bins = 50, kde = True)\n\nplt.title(\"Description Length Distribution\")\n\nplt.show()","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2026-08-06T14:44:39.40503Z","iopub.execute_input":"2026-08-06T14:44:39.405381Z","iopub.status.idle":"2026-08-06T14:44:46.301889Z","shell.execute_reply.started":"2026-08-06T14:44:39.40534Z","shell.execute_reply":"2026-08-06T14:44:46.300675Z"}},"outputs":[],"execution_count":null},{"cell_type":"markdown","source":"### Description Length\n\n#### Observations\n\n- Description length is highly right-skewed.\n- Most advertisements contain relatively short descriptions.\n- A small number of advertisements contain very long descriptions.\n\n**Insight**\n\nDescription length varies considerably across advertisements and may provide useful predictive information.","metadata":{}},{"cell_type":"code","source":"result = (\n    train.groupby(pd.cut(train[\"description_length\"], bins=10))\n    .agg(\n        deal_probability=(\"deal_probability\", \"mean\"),\n        count_ads=(\"deal_probability\", \"size\")\n    )\n    .reset_index()\n)\n\nresult[\"Bin\"] = [f\"Bin{i}\" for i in range(1, len(result)+1)]\n\nresult = result[[\"Bin\", \"description_length\", \"deal_probability\", \"count_ads\"]]\n\nprint(result)","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2026-08-06T14:44:51.050624Z","iopub.execute_input":"2026-08-06T14:44:51.051032Z","iopub.status.idle":"2026-08-06T14:44:51.1607Z","shell.execute_reply.started":"2026-08-06T14:44:51.050984Z","shell.execute_reply":"2026-08-06T14:44:51.159632Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"plt.figure(figsize=(10,5))\nsns.barplot(data=result, x=\"Bin\", y=\"deal_probability\")\n\nplt.xlabel(\"Description Length Bins\")\nplt.ylabel(\"Mean Deal Probability\")\nplt.title(\"Average Deal Probability by Description Length\")\nplt.show()","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2026-08-06T14:44:51.758514Z","iopub.execute_input":"2026-08-06T14:44:51.758945Z","iopub.status.idle":"2026-08-06T14:44:51.983711Z","shell.execute_reply.started":"2026-08-06T14:44:51.758914Z","shell.execute_reply":"2026-08-06T14:44:51.982452Z"}},"outputs":[],"execution_count":null},{"cell_type":"markdown","source":"### Description Length vs Deal Probability\n\n#### Observations\n\n- Advertisements with medium-length descriptions achieve the highest average deal probability.\n- Extremely long descriptions do not improve the likelihood of a successful deal.\n- Very long descriptions are also relatively rare.\n\n**Insight**\n\nThe relationship between description length and deal probability is not linear. Description length should be considered as a predictive feature, but longer descriptions do not necessarily lead to higher sales probability.","metadata":{}},{"cell_type":"markdown","source":"","metadata":{}},{"cell_type":"markdown","source":"# Exploratory Data Analysis (EDA) Summary\n\n## Missing Values\n- `param_3` contains a high percentage of missing values (~57%).\n- `param_2` also contains substantial missing values (~43%).\n- `description` and `price` contain a moderate number of missing values.\n\n## Target Variable\n- The target distribution is highly skewed toward zero.\n- More than half of the advertisements have a deal probability of zero.\n\n## Numerical Features\n- `price` is heavily right-skewed.\n- Extreme outliers exist in the price column.\n- Log transformation provides a better representation of the price distribution.\n\n## Categorical Features\n- `user_type`, `parent_category_name`, and `category_name` show noticeable differences in average deal probability.\n- Category-related features are expected to be highly informative.\n\n## Date Features\n- Advertisement counts are relatively balanced across weekdays.\n- Weekday has only a weak relationship with deal probability.\n- `month` has almost no variation and is unlikely to be useful.\n\n## Text Features\n- Most titles are short.\n- Description length is highly skewed.\n- Medium-length descriptions tend to achieve the highest average deal probability.","metadata":{}},{"cell_type":"code","source":"train.info()","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2026-08-06T14:45:00.436464Z","iopub.execute_input":"2026-08-06T14:45:00.437202Z","iopub.status.idle":"2026-08-06T14:45:01.68769Z","shell.execute_reply.started":"2026-08-06T14:45:00.437164Z","shell.execute_reply":"2026-08-06T14:45:01.6868Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"test.info()","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2026-08-06T14:45:01.689406Z","iopub.execute_input":"2026-08-06T14:45:01.689739Z","iopub.status.idle":"2026-08-06T14:45:02.118097Z","shell.execute_reply.started":"2026-08-06T14:45:01.6897Z","shell.execute_reply":"2026-08-06T14:45:02.117158Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"print(categorical_cols)","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2026-08-06T14:45:02.119292Z","iopub.execute_input":"2026-08-06T14:45:02.120375Z","iopub.status.idle":"2026-08-06T14:45:02.125476Z","shell.execute_reply.started":"2026-08-06T14:45:02.120332Z","shell.execute_reply":"2026-08-06T14:45:02.124531Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"train.drop(columns=[\"day_name\", \"month\"], inplace=True)\n\ntest.drop(columns=[\"day_name\", \"month\"], inplace=True)\n\n\n\ntrain[\"description\"] = train[\"description\"].fillna(\"\")\ntest[\"description\"] = test[\"description\"].fillna(\"\")\n\n\ntrain[\"title\"] = train[\"title\"].fillna(\"\")\ntest[\"title\"] = test[\"title\"].fillna(\"\")\n\n\n\ntrain[\"has_image\"] = train[\"image\"].notna().astype(\"int8\")\ntest[\"has_image\"] = test[\"image\"].notna().astype(\"int8\")\n","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2026-08-06T14:45:06.78529Z","iopub.execute_input":"2026-08-06T14:45:06.785686Z","iopub.status.idle":"2026-08-06T14:45:08.091468Z","shell.execute_reply.started":"2026-08-06T14:45:06.78565Z","shell.execute_reply":"2026-08-06T14:45:08.090504Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"for col in categorical_cols:\n    train[col] = train[col].astype(\"category\")\n    test[col] = test[col].astype(\"category\")","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2026-08-06T14:45:08.093097Z","iopub.execute_input":"2026-08-06T14:45:08.093903Z","iopub.status.idle":"2026-08-06T14:45:43.357902Z","shell.execute_reply.started":"2026-08-06T14:45:08.093866Z","shell.execute_reply":"2026-08-06T14:45:43.356746Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"train.info()","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2026-08-06T14:45:52.359372Z","iopub.execute_input":"2026-08-06T14:45:52.359851Z","iopub.status.idle":"2026-08-06T14:45:57.278414Z","shell.execute_reply.started":"2026-08-06T14:45:52.359814Z","shell.execute_reply":"2026-08-06T14:45:57.277187Z"}},"outputs":[],"execution_count":null},{"cell_type":"markdown","source":"## Handling Missing Values","metadata":{}},{"cell_type":"code","source":"for col in [\"param_1\", \"param_2\", \"param_3\"]:\n    train[col] = train[col].cat.add_categories(\"missing\").fillna(\"missing\")\n    test[col] = test[col].cat.add_categories(\"missing\").fillna(\"missing\")\n\ntrain[\"price\"] = train[\"price\"].fillna(train[\"price\"].median())\ntest[\"price\"] = test[\"price\"].fillna(train[\"price\"].median())\n\ntrain[\"image_top_1\"] = train[\"image_top_1\"].fillna(-1)\ntest[\"image_top_1\"] = test[\"image_top_1\"].fillna(-1)","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2026-08-06T14:46:04.627181Z","iopub.execute_input":"2026-08-06T14:46:04.627577Z","iopub.status.idle":"2026-08-06T14:46:04.753449Z","shell.execute_reply.started":"2026-08-06T14:46:04.627544Z","shell.execute_reply":"2026-08-06T14:46:04.752472Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"train.isnull().sum().sort_values(ascending=False).head(10)","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2026-08-06T14:46:04.994703Z","iopub.execute_input":"2026-08-06T14:46:04.995405Z","iopub.status.idle":"2026-08-06T14:46:05.042732Z","shell.execute_reply.started":"2026-08-06T14:46:04.995369Z","shell.execute_reply":"2026-08-06T14:46:05.041764Z"}},"outputs":[],"execution_count":null},{"cell_type":"markdown","source":"#### Observations\n\n- `param_1`, `param_2`, and `param_3` missing values are replaced with a `missing` category, since the absence of a parameter is itself informative.\n- `price` missing values are filled with the median price to avoid distortion from outliers.\n- `image_top_1` missing values are filled with -1 to represent ads without an image classification.\n\n**Insight**\n\nMissing values in this dataset are not random. They mostly correspond to ads that lack certain parameters or an image, so filling them with a placeholder preserves that signal instead of discarding it.","metadata":{}},{"cell_type":"markdown","source":"## Removing Unnecessary Features","metadata":{}},{"cell_type":"code","source":"drop_cols = [\"item_id\", \"image\"]\n\ntrain.drop(columns=drop_cols, inplace=True)\ntest.drop(columns=drop_cols, inplace=True)","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2026-08-06T14:46:10.342515Z","iopub.execute_input":"2026-08-06T14:46:10.342937Z","iopub.status.idle":"2026-08-06T14:46:10.547093Z","shell.execute_reply.started":"2026-08-06T14:46:10.342904Z","shell.execute_reply":"2026-08-06T14:46:10.546206Z"}},"outputs":[],"execution_count":null},{"cell_type":"markdown","source":"#### Observations\n\n- `item_id` is a unique identifier and carries no predictive value.\n- `image` is a raw image path and is already summarized by `has_image`.\n\n**Insight**\n\nDropping identifier and raw path columns reduces noise without losing information, since the useful signal from these columns has already been captured in engineered features.","metadata":{}},{"cell_type":"code","source":"train.info()","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2026-08-06T14:46:12.017622Z","iopub.execute_input":"2026-08-06T14:46:12.018524Z","iopub.status.idle":"2026-08-06T14:46:12.071559Z","shell.execute_reply.started":"2026-08-06T14:46:12.018485Z","shell.execute_reply":"2026-08-06T14:46:12.070437Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"test.info()","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2026-08-06T14:46:16.37977Z","iopub.execute_input":"2026-08-06T14:46:16.380767Z","iopub.status.idle":"2026-08-06T14:46:17.356704Z","shell.execute_reply.started":"2026-08-06T14:46:16.380697Z","shell.execute_reply":"2026-08-06T14:46:17.355413Z"}},"outputs":[],"execution_count":null},{"cell_type":"markdown","source":"# Feature Engineering","metadata":{}},{"cell_type":"markdown","source":"## price_log","metadata":{}},{"cell_type":"code","source":"train[\"price_log\"] = np.log1p(train[\"price\"])\ntest[\"price_log\"] = np.log1p(test[\"price\"])","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2026-08-06T14:46:17.526347Z","iopub.execute_input":"2026-08-06T14:46:17.526713Z","iopub.status.idle":"2026-08-06T14:46:17.575093Z","shell.execute_reply.started":"2026-08-06T14:46:17.526672Z","shell.execute_reply":"2026-08-06T14:46:17.574186Z"}},"outputs":[],"execution_count":null},{"cell_type":"markdown","source":"## has_description","metadata":{}},{"cell_type":"code","source":"train[\"has_description\"] = (train[\"description\"].str.len() > 0).astype(\"int8\")\ntest[\"has_description\"] = (test[\"description\"].str.len() > 0).astype(\"int8\")","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2026-08-06T14:46:21.04957Z","iopub.execute_input":"2026-08-06T14:46:21.049968Z","iopub.status.idle":"2026-08-06T14:46:22.435354Z","shell.execute_reply.started":"2026-08-06T14:46:21.049933Z","shell.execute_reply":"2026-08-06T14:46:22.4344Z"}},"outputs":[],"execution_count":null},{"cell_type":"markdown","source":"## title_words and description_words","metadata":{}},{"cell_type":"code","source":"train[\"title_words\"] = train[\"title\"].str.split().str.len()\n    test[\"title_words\"] = test[\"title\"].str.split().str.len()\n    \n    train[\"description_words\"] = train[\"description\"].str.split().str.len().fillna(0)\ntest[\"description_words\"] = test[\"description\"].str.split().str.len().fillna(0)","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2026-08-06T14:46:22.436928Z","iopub.execute_input":"2026-08-06T14:46:22.437298Z","iopub.status.idle":"2026-08-06T14:46:48.96731Z","shell.execute_reply.started":"2026-08-06T14:46:22.437246Z","shell.execute_reply":"2026-08-06T14:46:48.966456Z"}},"outputs":[],"execution_count":null},{"cell_type":"markdown","source":"## weekday","metadata":{}},{"cell_type":"code","source":"train.rename(columns={\"weakday\": \"weekday\"}, inplace=True)\ntest.rename(columns={\"weakday\": \"weekday\"}, inplace=True)","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2026-08-06T14:47:02.354484Z","iopub.execute_input":"2026-08-06T14:47:02.354906Z","iopub.status.idle":"2026-08-06T14:47:02.361935Z","shell.execute_reply.started":"2026-08-06T14:47:02.35487Z","shell.execute_reply":"2026-08-06T14:47:02.360628Z"}},"outputs":[],"execution_count":null},{"cell_type":"markdown","source":"## price_per_category","metadata":{}},{"cell_type":"code","source":"category_avg_price = train.groupby(\"category_name\")[\"price\"].mean()\n\ntrain[\"price_per_category\"] = train[\"category_name\"].map(category_avg_price)\ntest[\"price_per_category\"] = test[\"category_name\"].map(category_avg_price)","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2026-08-06T14:47:04.859904Z","iopub.execute_input":"2026-08-06T14:47:04.860945Z","iopub.status.idle":"2026-08-06T14:47:04.891715Z","shell.execute_reply.started":"2026-08-06T14:47:04.860893Z","shell.execute_reply":"2026-08-06T14:47:04.890654Z"}},"outputs":[],"execution_count":null},{"cell_type":"markdown","source":"## user_total_ads","metadata":{}},{"cell_type":"code","source":"user_ads_count = train[\"user_id\"].value_counts()\n\ntrain[\"user_total_ads\"] = train[\"user_id\"].map(user_ads_count)\ntest[\"user_total_ads\"] = test[\"user_id\"].map(user_ads_count).fillna(1)","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2026-08-06T14:47:05.706393Z","iopub.execute_input":"2026-08-06T14:47:05.706788Z","iopub.status.idle":"2026-08-06T14:47:06.288387Z","shell.execute_reply.started":"2026-08-06T14:47:05.706755Z","shell.execute_reply":"2026-08-06T14:47:06.28756Z"}},"outputs":[],"execution_count":null},{"cell_type":"markdown","source":"## region_avg_price","metadata":{}},{"cell_type":"code","source":"region_avg_price = train.groupby(\"region\")[\"price\"].mean()\n\ntrain[\"region_avg_price\"] = train[\"region\"].map(region_avg_price)\ntest[\"region_avg_price\"] = test[\"region\"].map(region_avg_price)","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2026-08-06T14:47:08.413074Z","iopub.execute_input":"2026-08-06T14:47:08.413436Z","iopub.status.idle":"2026-08-06T14:47:08.439274Z","shell.execute_reply.started":"2026-08-06T14:47:08.413404Z","shell.execute_reply":"2026-08-06T14:47:08.438363Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"train.head()","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2026-08-06T14:47:08.851861Z","iopub.execute_input":"2026-08-06T14:47:08.85221Z","iopub.status.idle":"2026-08-06T14:47:09.976919Z","shell.execute_reply.started":"2026-08-06T14:47:08.85218Z","shell.execute_reply":"2026-08-06T14:47:09.975782Z"}},"outputs":[],"execution_count":null},{"cell_type":"markdown","source":"#### Observations\n\n- `price_log` reduces the effect of extreme outliers in price and produces a more usable distribution for modeling.\n- `has_description` captures whether an ad includes any description at all, separate from its length.\n- `title_words` and `description_words` measure text richness in a way that is less sensitive to character-level noise than raw length.\n- `price_per_category` and `region_avg_price` encode the average price context for each category and region, so the model can see whether a listing is priced above or below its peers.\n- `user_total_ads` reflects how active a seller is, since sellers with many ads may behave differently from occasional sellers.\n\n**Insight**\n\nThese features move beyond what the raw columns provide and give the model context: how a price compares to similar ads, how active a user is, and how much information an ad's text carries. This kind of relative and aggregated information is usually where meaningful gains come from in tabular models.","metadata":{}},{"cell_type":"markdown","source":"# Baseline Model","metadata":{}},{"cell_type":"markdown","source":"We start with a CatBoost baseline using the current feature set, without heavy tuning, to establish a reference RMSE score before improving further.","metadata":{}},{"cell_type":"code","source":"from sklearn.model_selection import train_test_split\nfrom sklearn.metrics import mean_squared_error\nfrom catboost import CatBoostRegressor","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2026-08-06T14:47:12.37535Z","iopub.execute_input":"2026-08-06T14:47:12.375724Z","iopub.status.idle":"2026-08-06T14:47:12.677113Z","shell.execute_reply.started":"2026-08-06T14:47:12.375693Z","shell.execute_reply":"2026-08-06T14:47:12.675542Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"drop_features = [\"user_id\", \"title\", \"description\", \"activation_date\", \"deal_probability\"]\n\nfeatures = [col for col in train.columns if col not in drop_features]\n\ncat_features = train[features].select_dtypes(include=[\"category\"]).columns.tolist()\n\nX = train[features]\ny = train[\"deal_probability\"]\n\nX_train, X_valid, y_train, y_valid = train_test_split(\n    X, y, test_size=0.2, random_state=42\n)","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2026-08-06T14:47:14.040532Z","iopub.execute_input":"2026-08-06T14:47:14.041524Z","iopub.status.idle":"2026-08-06T14:47:14.725444Z","shell.execute_reply.started":"2026-08-06T14:47:14.041483Z","shell.execute_reply":"2026-08-06T14:47:14.724161Z"}},"outputs":[],"execution_count":null},{"cell_type":"markdown","source":"# Remove price_per_category, region_avg_price from cat_features","metadata":{}},{"cell_type":"code","source":"print(cat_features)","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2026-08-06T14:50:26.59854Z","iopub.execute_input":"2026-08-06T14:50:26.599481Z","iopub.status.idle":"2026-08-06T14:50:26.604221Z","shell.execute_reply.started":"2026-08-06T14:50:26.599444Z","shell.execute_reply":"2026-08-06T14:50:26.60311Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"print(X_train[['cat_features.remove(\"price_per_category\")\ncat_features.remove(\"region_avg_price\")', 'region_avg_price']].dtypes)","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2026-08-06T14:51:01.534074Z","iopub.execute_input":"2026-08-06T14:51:01.534432Z","iopub.status.idle":"2026-08-06T14:51:01.543169Z","shell.execute_reply.started":"2026-08-06T14:51:01.534403Z","shell.execute_reply":"2026-08-06T14:51:01.542201Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"print(X_train['price_per_category'].cat.categories[:5])\nprint(type(X_train['price_per_category'].cat.categories[0]))","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2026-08-06T14:52:04.151335Z","iopub.execute_input":"2026-08-06T14:52:04.153735Z","iopub.status.idle":"2026-08-06T14:52:04.171682Z","shell.execute_reply.started":"2026-08-06T14:52:04.15367Z","shell.execute_reply":"2026-08-06T14:52:04.170482Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"print(X_train['region_avg_price'].cat.categories[:5])\nprint(type(X_train['region_avg_price'].cat.categories[0]))","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2026-08-06T14:52:47.656106Z","iopub.execute_input":"2026-08-06T14:52:47.656527Z","iopub.status.idle":"2026-08-06T14:52:47.664159Z","shell.execute_reply.started":"2026-08-06T14:52:47.656492Z","shell.execute_reply":"2026-08-06T14:52:47.663127Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"train[\"price_per_category\"] = train[\"price_per_category\"].astype(float)\ntest[\"price_per_category\"] = test[\"price_per_category\"].astype(float)\n\ntrain[\"region_avg_price\"] = train[\"region_avg_price\"].astype(float)\ntest[\"region_avg_price\"] = test[\"region_avg_price\"].astype(float)\n\n\nif \"price_per_category\" in cat_features:\n    cat_features.remove(\"price_per_category\")\n\nif \"region_avg_price\" in cat_features:\n    cat_features.remove(\"region_avg_price\")","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2026-08-06T15:48:08.060983Z","iopub.execute_input":"2026-08-06T15:48:08.061428Z","iopub.status.idle":"2026-08-06T15:48:08.179016Z","shell.execute_reply.started":"2026-08-06T15:48:08.061394Z","shell.execute_reply":"2026-08-06T15:48:08.177992Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"type(cat_features)","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2026-08-06T15:01:03.996222Z","iopub.execute_input":"2026-08-06T15:01:03.996693Z","iopub.status.idle":"2026-08-06T15:01:04.005147Z","shell.execute_reply.started":"2026-08-06T15:01:03.996656Z","shell.execute_reply":"2026-08-06T15:01:04.003988Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"cat_features","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2026-08-06T15:01:49.620428Z","iopub.execute_input":"2026-08-06T15:01:49.62142Z","iopub.status.idle":"2026-08-06T15:01:49.629191Z","shell.execute_reply.started":"2026-08-06T15:01:49.621372Z","shell.execute_reply":"2026-08-06T15:01:49.628075Z"}},"outputs":[],"execution_count":null},{"cell_type":"markdown","source":"","metadata":{}},{"cell_type":"code","source":"# convert to foat\nX_train[\"price_per_category\"] = X_train[\"price_per_category\"].astype(float)\nX_valid[\"price_per_category\"] = X_valid[\"price_per_category\"].astype(float)\n\nX_train[\"region_avg_price\"] = X_train[\"region_avg_price\"].astype(float)\nX_valid[\"region_avg_price\"] = X_valid[\"region_avg_price\"].astype(float)","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2026-08-06T15:02:58.922535Z","iopub.execute_input":"2026-08-06T15:02:58.92345Z","iopub.status.idle":"2026-08-06T15:02:58.941289Z","shell.execute_reply.started":"2026-08-06T15:02:58.923411Z","shell.execute_reply":"2026-08-06T15:02:58.94019Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"model = CatBoostRegressor(\n    iterations=1000,\n    learning_rate=0.05,\n    depth=8,\n    loss_function=\"RMSE\",\n    eval_metric=\"RMSE\",\n    random_seed=42,\n    verbose=100\n)\n\nmodel.fit(\n    X_train, y_train,\n    eval_set=(X_valid, y_valid),\n    cat_features=cat_features,\n    early_stopping_rounds=50\n)","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2026-08-06T15:02:59.947463Z","iopub.execute_input":"2026-08-06T15:02:59.948566Z","iopub.status.idle":"2026-08-06T15:28:36.633632Z","shell.execute_reply.started":"2026-08-06T15:02:59.948525Z","shell.execute_reply":"2026-08-06T15:28:36.632473Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"preds = model.predict(X_valid)\npreds = np.clip(preds, 0, 1)\n\nmse = mean_squared_error(y_valid, preds)\nrmse = np.sqrt(mse)\n\nprint(f\"Validation RMSE: {rmse:.5f}\")","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2026-08-06T15:32:27.910326Z","iopub.execute_input":"2026-08-06T15:32:27.910779Z","iopub.status.idle":"2026-08-06T15:32:31.376473Z","shell.execute_reply.started":"2026-08-06T15:32:27.910743Z","shell.execute_reply":"2026-08-06T15:32:31.375551Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"importance = pd.DataFrame({\n    \"Feature\": features,\n    \"Importance\": model.get_feature_importance()\n}).sort_values(\"Importance\", ascending=False)\n\nplt.figure(figsize=(10,8))\nsns.barplot(data=importance.head(15), x=\"Importance\", y=\"Feature\")\nplt.title(\"Top 15 Feature Importances\")\nplt.show()","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2026-08-06T15:32:34.996563Z","iopub.execute_input":"2026-08-06T15:32:34.99695Z","iopub.status.idle":"2026-08-06T15:32:35.469093Z","shell.execute_reply.started":"2026-08-06T15:32:34.99692Z","shell.execute_reply":"2026-08-06T15:32:35.467898Z"}},"outputs":[],"execution_count":null},{"cell_type":"markdown","source":"#### Observations\n\n- The baseline CatBoost model provides a first reference RMSE without any hyperparameter tuning.\n- Predictions are clipped to the [0, 1] range, since `deal_probability` cannot fall outside these bounds.\n- Feature importance gives an early signal of which engineered features are actually useful to the model.\n\n**Insight**\n\nThis baseline is not meant to be the final model. Its purpose is to confirm that the pipeline works end to end and to establish a score that any future improvement, such as text embeddings, image features, or tuning, can be measured against.","metadata":{}},{"cell_type":"code","source":"from sklearn.metrics import mean_squared_error, mean_absolute_error, r2_score\nimport pandas as pd\n\npreds = model.predict(X_valid)\n\nmse = mean_squared_error(y_valid, preds)\nrmse = np.sqrt(mse)\nmae = mean_absolute_error(y_valid, preds)\nr2 = r2_score(y_valid, preds)\n\nresults = pd.DataFrame({\n    \"Metric\": [\"RMSE\", \"MAE\", \"R2 Score\"],\n    \"Value\": [rmse, mae, r2]\n})\n\nresults.style.background_gradient(cmap=\"Blues\").set_properties(subset = ['Metric'],\n                                                              **{\n                                                                  \"background-color\":\"#00B5FDFF\",\n                                                                  \"font-weight\": \"bold\",\n                                                                  \"color\":\"black\"\n                                                              }) .hide(axis=\"index\")","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2026-08-06T15:46:31.826255Z","iopub.execute_input":"2026-08-06T15:46:31.826685Z","iopub.status.idle":"2026-08-06T15:46:35.604966Z","shell.execute_reply.started":"2026-08-06T15:46:31.826653Z","shell.execute_reply":"2026-08-06T15:46:35.603926Z"}},"outputs":[],"execution_count":null},{"cell_type":"markdown","source":"![image.png](attachment:9095fd6d-f19c-4c09-ad29-9291171aeb81.png)","metadata":{},"attachments":{"9095fd6d-f19c-4c09-ad29-9291171aeb81.png":{"image/png":"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"}}}]}