{"metadata":{"kernelspec":{"language":"python","display_name":"Python 3","name":"python3"},"language_info":{"name":"python","version":"3.10.12","mimetype":"text/x-python","codemirror_mode":{"name":"ipython","version":3},"pygments_lexer":"ipython3","nbconvert_exporter":"python","file_extension":".py"},"kaggle":{"accelerator":"none","dataSources":[{"sourceId":10038,"databundleVersionId":180088,"sourceType":"competition"}],"dockerImageVersionId":30839,"isInternetEnabled":true,"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":"2025-02-03T21:48:20.995247Z","iopub.execute_input":"2025-02-03T21:48:20.995696Z","iopub.status.idle":"2025-02-03T21:48:21.853413Z","shell.execute_reply.started":"2025-02-03T21:48:20.995660Z","shell.execute_reply":"2025-02-03T21:48:21.852417Z"}},"outputs":[],"execution_count":null},{"cell_type":"markdown","source":"Code to extract data from fields with Json format","metadata":{}},{"cell_type":"code","source":"import json\nfrom pandas import json_normalize\ndef load_df(csv_path='../input/train_v2.csv', nrows=None):\n    JSON_COLUMNS = ['device', 'geoNetwork', 'totals', 'trafficSource']\n    \n    df = pd.read_csv(csv_path, \n                     converters={column: json.loads for column in JSON_COLUMNS}, \n                     dtype={'fullVisitorId': 'str'}, # Important!!\n                     nrows=nrows)\n    \n    for column in JSON_COLUMNS:\n        column_as_df = json_normalize(df[column])\n        column_as_df.columns = [f\"{column}.{subcolumn}\" for subcolumn in column_as_df.columns]\n        df = df.drop(column, axis=1).merge(column_as_df, right_index=True, left_index=True)\n    print(f\"Loaded {os.path.basename(csv_path)}. Shape: {df.shape}\")\n    return df","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-02-03T21:48:21.855010Z","iopub.execute_input":"2025-02-03T21:48:21.855666Z","iopub.status.idle":"2025-02-03T21:48:21.862950Z","shell.execute_reply.started":"2025-02-03T21:48:21.855618Z","shell.execute_reply":"2025-02-03T21:48:21.861667Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"import pandas as pd\ndf=load_df('/kaggle/input/ga-customer-revenue-prediction/train.csv')\ndf['totals.transactionRevenue']=df['totals.transactionRevenue'].fillna(0).astype('int')\ndf_test=load_df('/kaggle/input/ga-customer-revenue-prediction/test_v2.csv')","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-02-03T21:48:21.865152Z","iopub.execute_input":"2025-02-03T21:48:21.865570Z","iopub.status.idle":"2025-02-03T21:53:09.040616Z","shell.execute_reply.started":"2025-02-03T21:48:21.865528Z","shell.execute_reply":"2025-02-03T21:53:09.039327Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"total_visitor_rev=df.groupby(\"fullVisitorId\")[\"totals.transactionRevenue\"].sum().reset_index()\n\ncount_vis=len(total_visitor_rev[total_visitor_rev['totals.transactionRevenue']>0])\n              \nprint(\"Number of unique visitor with some revenue\",count_vis)\nprint(\"Number of unique visitor with some revenue\",len(total_visitor_rev))\nprint( ' % of visitor generating revenue',count_vis/len(total_visitor_rev))","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-02-03T21:53:09.042883Z","iopub.execute_input":"2025-02-03T21:53:09.043244Z","iopub.status.idle":"2025-02-03T21:53:10.868196Z","shell.execute_reply.started":"2025-02-03T21:53:09.043213Z","shell.execute_reply":"2025-02-03T21:53:10.866956Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"df.date=pd.to_datetime(df.date, format=\"%Y%m%d\")\ndf['trans_month']=df.date.dt.month","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-02-03T21:53:10.869528Z","iopub.execute_input":"2025-02-03T21:53:10.869905Z","iopub.status.idle":"2025-02-03T21:53:10.925569Z","shell.execute_reply.started":"2025-02-03T21:53:10.869875Z","shell.execute_reply":"2025-02-03T21:53:10.924501Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"df['month_year'] = df['date'].dt.strftime('%b-%Y')\ndf['transact']=np.where(df['totals.transactionRevenue']>0,1,0)","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-02-03T21:53:10.926636Z","iopub.execute_input":"2025-02-03T21:53:10.926935Z","iopub.status.idle":"2025-02-03T21:53:15.207483Z","shell.execute_reply.started":"2025-02-03T21:53:10.926908Z","shell.execute_reply":"2025-02-03T21:53:15.206283Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"first_purchase = df[df['transact'] == 1].groupby('fullVisitorId')['sessionId'].min().reset_index()\nfirst_purchase['is_first_purchase']=1","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-02-03T21:53:15.208617Z","iopub.execute_input":"2025-02-03T21:53:15.208922Z","iopub.status.idle":"2025-02-03T21:53:15.878894Z","shell.execute_reply.started":"2025-02-03T21:53:15.208895Z","shell.execute_reply":"2025-02-03T21:53:15.877850Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"\ndf = df.merge(first_purchase, on=['fullVisitorId','sessionId'], how='left')\ndf.groupby(df.month_year)[\"totals.transactionRevenue\"].sum().reset_index()\n\ndf_mt=df.groupby('month_year').agg({\n    'totals.transactionRevenue': 'sum',         # Sum values\n    'transact': 'sum',         # Sum counts,\n    'is_first_purchase':'sum',\n    'fullVisitorId':  pd.Series.nunique    # Unique count of user_id\n}).reset_index()\n\n","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-02-03T21:53:15.881675Z","iopub.execute_input":"2025-02-03T21:53:15.881995Z","iopub.status.idle":"2025-02-03T21:53:23.038884Z","shell.execute_reply.started":"2025-02-03T21:53:15.881968Z","shell.execute_reply":"2025-02-03T21:53:23.037377Z"}},"outputs":[],"execution_count":null},{"cell_type":"markdown","source":"Analysing what percentage of transaction are first transaction - understanding user behavior is important ","metadata":{}},{"cell_type":"code","source":"df_mt['%first_trans']=df_mt['is_first_purchase']/df_mt['transact']","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-02-03T21:53:23.041030Z","iopub.execute_input":"2025-02-03T21:53:23.041355Z","iopub.status.idle":"2025-02-03T21:53:23.047263Z","shell.execute_reply.started":"2025-02-03T21:53:23.041325Z","shell.execute_reply":"2025-02-03T21:53:23.045975Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"df_mt['month_year_dt'] = pd.to_datetime(df_mt['month_year'], format='%b-%Y')\n\n# Sort by month & year\ndf_mt = df_mt.sort_values(by='month_year_dt')\n\n# Drop the datetime column if not needed\ndf_mt = df_mt.drop(columns=['month_year_dt'])\n\n# Reset index\ndf_mt = df_mt.reset_index(drop=True)","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-02-03T21:53:23.048719Z","iopub.execute_input":"2025-02-03T21:53:23.049112Z","iopub.status.idle":"2025-02-03T21:53:23.073415Z","shell.execute_reply.started":"2025-02-03T21:53:23.049068Z","shell.execute_reply":"2025-02-03T21:53:23.072205Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"df_mt","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-02-03T21:53:23.074620Z","iopub.execute_input":"2025-02-03T21:53:23.075006Z","iopub.status.idle":"2025-02-03T21:53:23.118225Z","shell.execute_reply.started":"2025-02-03T21:53:23.074969Z","shell.execute_reply":"2025-02-03T21:53:23.116762Z"}},"outputs":[],"execution_count":null},{"cell_type":"markdown","source":"Anlaysing revenue by month & count of visitors driving the revenue","metadata":{}},{"cell_type":"code","source":"\nimport plotly.graph_objects as go\n\n# Create the figure\nfig = go.Figure()\n\n# Add Transaction Revenue (Primary Y-axis)\nfig.add_trace(go.Bar(\n    x=df_mt['month_year'],\n    y=df_mt['totals.transactionRevenue'],\n    name=\"Total Revenue\",\n    marker_color='blue',\n    yaxis='y1'  # Primary Y-axis\n))\n\n# Add Number of Transactions (Secondary Y-axis)\nfig.add_trace(go.Scatter(\n    x=df_mt['month_year'],\n    y=df_mt['transact'],\n    name=\"Total Transactions\",\n    mode='lines+markers',\n    marker=dict(color='red', size=8),\n    yaxis='y2'  # Secondary Y-axis\n))\n\n# Add Unique Visitors (Secondary Y-axis)\nfig.add_trace(go.Scatter(\n    x=df_mt['month_year'],\n    y=df_mt['fullVisitorId'],\n    name=\"Unique Visitors\",\n    mode='lines+markers',\n    marker=dict(color='green', size=8),\n    yaxis='y2'\n))\n\n# Add New Users (Secondary Y-axis)\nfig.add_trace(go.Scatter(\n    x=df_mt['month_year'],\n    y=df_mt['is_first_purchase'],\n    name=\"New Users\",\n    mode='lines+markers',\n    marker=dict(color='purple', size=8),\n    yaxis='y2'\n))\n\n# Layout adjustments\nfig.update_layout(\n    title=\"Monthly Comparison of Revenue, Transactions, and Visitors\",\n    xaxis=dict(title=\"Month-Year\"),\n    \n    yaxis=dict(\n        title=\"Total Transaction Revenue\",\n        titlefont=dict(color=\"blue\"),\n        tickfont=dict(color=\"blue\"),\n        side=\"left\"\n    ),\n\n    yaxis2=dict(\n        title=\"Transactions / Visitors\",\n        titlefont=dict(color=\"red\"),\n        tickfont=dict(color=\"red\"),\n        overlaying=\"y\",\n        side=\"right\"\n    ),\n    \n    legend=dict(x=0.1, y=1.1),\n    template=\"plotly_white\"\n)\n\n# Show the figure\nfig.show()\n","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-02-03T21:53:23.119489Z","iopub.execute_input":"2025-02-03T21:53:23.119882Z","iopub.status.idle":"2025-02-03T21:53:25.213190Z","shell.execute_reply.started":"2025-02-03T21:53:23.119835Z","shell.execute_reply":"2025-02-03T21:53:25.212101Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"","metadata":{"trusted":true},"outputs":[],"execution_count":null},{"cell_type":"markdown","source":"Though we observe significatly new visitor in Nov that doesn't neccessarily imply Higher revenue , will analyse if there was something specific in Aug/Dec/April for higher revenues","metadata":{}},{"cell_type":"code","source":"import plotly.express as px\ndf_grouped = df.groupby(['month_year', 'trafficSource.campaign'])['totals.transactionRevenue'].sum().reset_index()\n\n\n\n# Create stacked bar chart\nfig = px.bar(df_grouped, \n             x='month_year', \n             y='totals.transactionRevenue', \n             color='trafficSource.campaign', \n             title='Monthly Revenue Split by Campaign',\n             labels={'revenue': 'Total Revenue', 'month_year': 'Month-Year'},\n             barmode='stack')  # Stack bars by campaign\n\n# Show the plot\nfig.show()\n","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-02-03T21:57:24.734587Z","iopub.execute_input":"2025-02-03T21:57:24.734926Z","iopub.status.idle":"2025-02-03T21:57:25.119872Z","shell.execute_reply.started":"2025-02-03T21:57:24.734901Z","shell.execute_reply":"2025-02-03T21:57:25.118807Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"df_grouped = df.groupby(['month_year', 'trafficSource.campaign'])['totals.transactionRevenue'].sum().reset_index()\ndf_grouped.columns=['month_year','trafficSource.campaign','revenue_by_campaign']\ndf_total = df.groupby(['month_year'])['totals.transactionRevenue'].sum().reset_index()\ndf_ana=pd.merge(df_grouped,df_total,on=['month_year'])\ndf_ana['%contri']=df_ana['revenue_by_campaign']/df_ana['totals.transactionRevenue']*100\ndf_ana[df_ana['trafficSource.campaign']!='(not set)']\ndf_ana['month_year'] = pd.to_datetime(df_ana['month_year'], format='%b-%Y')\ndf_ana = df_ana.sort_values(by='month_year')\n\n# Filter out '(not set)' campaign\ndf_filtered = df_ana[df_ana['trafficSource.campaign'] != '(not set)']\n\n# Create a stacked bar chart for % contribution\nfig = px.bar(df_filtered, \n             x='month_year', \n             y='%contri', \n             color='trafficSource.campaign', \n             title='% Contribution in Monthly Revenue Split by Campaign',\n             labels={'%contri': '% Contribution', 'month_year': 'Month-Year'},\n             barmode='stack')\n\n# Add a secondary y-axis for total transaction revenue\nfig.add_trace(go.Scatter(\n    x=df_filtered['month_year'],\n    y=df_filtered['totals.transactionRevenue'],\n    name=\"Total Revenue\",\n    mode='lines+markers',\n    marker=dict(color='red', size=8),\n    yaxis='y2'  # Secondary Y-axis\n))\n\n# Update layout for better readability\nfig.update_layout(\n    xaxis=dict(title='Month-Year', tickformat='%b-%Y'),\n    yaxis=dict(title='% Contribution', side='left'),\n    yaxis2=dict(title='Total Revenue', overlaying='y', side='right', showgrid=False),\n    legend=dict(title='Campaign', orientation='h', yanchor='bottom', y=-0.3),\n    margin=dict(l=50, r=50, t=50, b=50),\n    height=600\n)\n\n# Show plot\nfig.show()","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-02-03T21:57:27.654658Z","iopub.execute_input":"2025-02-03T21:57:27.655135Z","iopub.status.idle":"2025-02-03T21:57:28.306717Z","shell.execute_reply.started":"2025-02-03T21:57:27.655095Z","shell.execute_reply":"2025-02-03T21:57:28.305615Z"}},"outputs":[],"execution_count":null},{"cell_type":"markdown","source":"#We can clearly see the Camapigns have different impact in revenue .. One thing to note is a campaign might attain its highest impact after 4-5 month .. as we observe it twice for AW in Dec-2016 & June -2017","metadata":{}},{"cell_type":"markdown","source":"Understanding & analysing different Catgeorical Columns\n","metadata":{}},{"cell_type":"code","source":"import plotly.express as px\ncols=['channelGrouping',  'device.browser',\n       'device.operatingSystem', 'device.deviceCategory',\n       'geoNetwork.continent', 'geoNetwork.subContinent', 'geoNetwork.country',\n       'geoNetwork.region', 'geoNetwork.metro', 'geoNetwork.city',\n       'geoNetwork.networkDomain', 'totals.hits', 'totals.pageviews',\n       'totals.bounces', 'totals.newVisits', 'trafficSource.campaign',\n       'trafficSource.source', 'trafficSource.medium', 'trafficSource.keyword',\n       'trafficSource.isTrueDirect', 'trafficSource.referralPath']\nfor i in cols:\n    df_t=df.groupby(i)['fullVisitorId'].count().reset_index()\n    \n    fig = px.bar(df_t, \n             x=i, \n             y='fullVisitorId', \n             title=\"Number of Records per \"+i,\n             labels={ 'fullVisitorId': 'Number of Records'},\n             color='fullVisitorId', \n             color_continuous_scale='Viridis')\n\n    \n    fig.show()","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-02-03T21:57:31.451687Z","iopub.execute_input":"2025-02-03T21:57:31.452085Z","iopub.status.idle":"2025-02-03T21:57:36.885291Z","shell.execute_reply.started":"2025-02-03T21:57:31.452054Z","shell.execute_reply":"2025-02-03T21:57:36.883982Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"one_hot_encoder=['channelGrouping','device.browser','device.operatingSystem', 'device.deviceCategory', 'geoNetwork.continent','trafficSource.medium', 'trafficSource.adwordsClickInfo.slot']\ndrop_col=['geoNetwork.subContinent', 'geoNetwork.country','visitStartTime',\n       'geoNetwork.region', 'geoNetwork.metro', 'geoNetwork.city','trafficSource.referralPath',\n       'geoNetwork.networkDomain','trafficSource.campaign','trafficSource.source', 'trafficSource.keyword',\n         'trafficSource.adwordsClickInfo.page','sessionId','visitId','socialEngagementType',\n       'device.browserVersion', 'device.browserSize','customDimensions','hits', 'totals.timeOnSite',\n       'totals.sessionQualityDim', 'totals.transactions',\n       'totals.totalTransactionRevenue',\n       'device.operatingSystemVersion', 'device.mobileDeviceBranding',\n       'device.mobileDeviceModel', 'device.mobileInputSelector',\n       'device.mobileDeviceInfo', 'device.mobileDeviceMarketingName',\n       'device.flashVersion', 'device.language', 'device.screenColors',\n       'device.screenResolution', 'geoNetwork.cityId', 'geoNetwork.latitude',\n       'geoNetwork.longitude', 'geoNetwork.networkLocation', 'totals.visits',\n       'trafficSource.adwordsClickInfo.criteriaParameters',\n       'trafficSource.adwordsClickInfo.gclId', 'trafficSource.adwordsClickInfo.adNetworkType', 'trafficSource.adContent', 'trafficSource.campaignCode']\nconst_cols = [c for c in df.columns if df[c].nunique(dropna=False)==1 ]","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-02-03T21:58:29.672747Z","iopub.execute_input":"2025-02-03T21:58:29.673118Z","iopub.status.idle":"2025-02-03T21:58:36.818393Z","shell.execute_reply.started":"2025-02-03T21:58:29.673087Z","shell.execute_reply":"2025-02-03T21:58:36.817225Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"const_cols = [col for col in const_cols if col != 'tag']\n\ndrop_col=drop_col+const_cols\n\nfrom sklearn.preprocessing import LabelEncoder\ndef transform_df(df):\n    \n    df.date=pd.to_datetime(df.date, format=\"%Y%m%d\")\n    df['trans_month']=df.date.dt.month\n    df['device.browser']=df['device.browser'].str.replace('Safari (in-app)','Safari')\n    df['device.browser']=df['device.browser'].str.replace('Apple-iPhone7C2','Safari')\n    df['device.browser']=df['device.browser'].apply(lambda x: x if x in ['Chrome', 'Safari', 'Firefox', 'Internet Explorer'] else 'other')\n    df['device.operatingSystem']=df['device.operatingSystem'].apply(lambda x: x if x in ['Windows','Macintosh','Android','iOS','Linux','Chrome OS'] else 'other') \n    df[['totals.hits','device.isMobile', 'totals.pageviews','totals.bounces', 'totals.newVisits','trafficSource.isTrueDirect']]=df[['totals.hits','device.isMobile', 'totals.pageviews','totals.bounces', 'totals.newVisits','trafficSource.isTrueDirect']].fillna(0).astype('int')\n    df['trafficSource.adwordsClickInfo.isVideoAd']=df['trafficSource.adwordsClickInfo.isVideoAd'].fillna(True).astype('int')\n    df['bounce_rate'] = df['totals.bounces'] / df['totals.hits']  \n    df['pages_per_session'] = df['totals.pageviews'] / df['visitNumber']\n    df['engagement_score'] = df['totals.hits'] + df['totals.pageviews']\n    df['is_campaign']=np.where(df['trafficSource.campaign']== '(not set)',0,1)\n    drop_col_existing = [col for col in drop_col if col in df.columns]\n    \n    df=df.drop(drop_col_existing,axis=1)\n    #df=pd.get_dummies(df, columns=one_hot_encoder)\n\n    for col in one_hot_encoder:\n        df[col] = LabelEncoder().fit_transform(df[col])\n   \n    return df","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-02-03T21:59:27.031702Z","iopub.execute_input":"2025-02-03T21:59:27.032076Z","iopub.status.idle":"2025-02-03T21:59:27.181337Z","shell.execute_reply.started":"2025-02-03T21:59:27.032045Z","shell.execute_reply":"2025-02-03T21:59:27.180046Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"df_test['tag']='test'\ndf['tag']='train'\n","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-02-03T21:59:30.454541Z","iopub.execute_input":"2025-02-03T21:59:30.454887Z","iopub.status.idle":"2025-02-03T21:59:30.468198Z","shell.execute_reply.started":"2025-02-03T21:59:30.454862Z","shell.execute_reply":"2025-02-03T21:59:30.467011Z"}},"outputs":[],"execution_count":null},{"cell_type":"markdown","source":"Transforming the whole dataset in one go by concatenating & identifying train & test based on tags .. In case of real time evaluations one needs to create pipelines and achieve the same .. for Purpose of Kaggle & evaluations I have taken a simplistic technique","metadata":{}},{"cell_type":"code","source":"df_base=pd.concat([df,df_test])\ndf_base=transform_df(df_base)","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-02-03T21:59:32.804761Z","iopub.execute_input":"2025-02-03T21:59:32.805120Z","iopub.status.idle":"2025-02-03T21:59:46.048759Z","shell.execute_reply.started":"2025-02-03T21:59:32.805093Z","shell.execute_reply":"2025-02-03T21:59:46.047295Z"}},"outputs":[],"execution_count":null},{"cell_type":"markdown","source":" Since the test dataset corresponds to different time period , doing a temporal split based on date would be ideal while training the models so evaluation is inline with the final output","metadata":{}},{"cell_type":"code","source":"df_base[df_base['tag']=='train']['date']\ndf_base2 = df_base[df_base['tag']=='train'].sort_values(by='date')\n\nsplit_index = int(len(df_base2) * 0.8)  # Get index for 80% split\n\n# ✅ Step 3: Get the Split Date\nsplit_date = df_base2.iloc[split_index]['date']\nprint(f\"📅 Split Date for 80:20 Split: {split_date}\")","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-02-03T21:59:46.050141Z","iopub.execute_input":"2025-02-03T21:59:46.050445Z","iopub.status.idle":"2025-02-03T21:59:46.822160Z","shell.execute_reply.started":"2025-02-03T21:59:46.050421Z","shell.execute_reply":"2025-02-03T21:59:46.821051Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"X_train=df_base[(df_base['tag']=='train') & (df_base.date<'2017-05-11')].drop(['date','tag','totals.transactionRevenue','fullVisitorId', 'month_year'],axis=1)\ny_train=np.log1p(df_base[(df_base['tag']=='train') & (df_base.date<'2017-05-11')]['totals.transactionRevenue'].astype(float))\nX_val=df_base[(df_base['tag']=='train') & (df_base.date>='2017-05-11')].drop(['date','tag','totals.transactionRevenue','fullVisitorId', 'month_year'],axis=1)\ny_val=np.log1p(df_base[(df_base['tag']=='train') & (df_base.date>='2017-05-11')]['totals.transactionRevenue'].astype(float))\nX_test=df_base[(df_base['tag']=='test')].drop(['date','tag','totals.transactionRevenue','fullVisitorId', 'month_year'],axis=1)","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-02-03T21:59:46.824060Z","iopub.execute_input":"2025-02-03T21:59:46.824377Z","iopub.status.idle":"2025-02-03T21:59:48.047170Z","shell.execute_reply.started":"2025-02-03T21:59:46.824349Z","shell.execute_reply":"2025-02-03T21:59:48.046151Z"}},"outputs":[],"execution_count":null},{"cell_type":"markdown","source":"Inetgrating Optuna for Hyper Parameter Tuning for Xgboost & Lightbm to find Optimal Model","metadata":{}},{"cell_type":"code","source":"import optuna\nimport xgboost as xgb\nimport lightgbm as lgb\nfrom sklearn.metrics import mean_squared_error\nimport numpy as np\nimport warnings\nimport logging\nimport optuna\n\n# Suppress warnings\nwarnings.simplefilter(\"ignore\")  # Ignores all warnings\n\n# Reduce Optuna logging verbosity\noptuna.logging.set_verbosity(optuna.logging.WARNING)\n\n# Reduce LightGBM logs\nlogging.getLogger(\"lightgbm\").setLevel(logging.WARNING)\nlogging.getLogger(\"xgboost\").setLevel(logging.WARNING)\n\n# Function to optimize XGBoost\ndef objective_xgb(trial):\n    params = {\n        \"objective\": \"reg:squarederror\",\n        \"n_estimators\": trial.suggest_int(\"n_estimators\", 100, 500),\n        \"max_depth\": trial.suggest_int(\"max_depth\", 3, 10),\n        \"learning_rate\": trial.suggest_float(\"learning_rate\", 0.01, 0.3, log=True),\n        \"subsample\": trial.suggest_float(\"subsample\", 0.5, 1.0),\n        \"colsample_bytree\": trial.suggest_float(\"colsample_bytree\", 0.5, 1.0),\n        \"min_child_weight\": trial.suggest_int(\"min_child_weight\", 1, 10),\n        \"gamma\": trial.suggest_float(\"gamma\", 0, 5),\n        \"reg_alpha\": trial.suggest_float(\"reg_alpha\", 0, 1),\n        \"reg_lambda\": trial.suggest_float(\"reg_lambda\", 0, 1),\n        \"random_state\": 42\n    }\n    \n    model = xgb.XGBRegressor(**params)\n    model.fit(X_train, y_train, eval_set=[(X_val, y_val)], early_stopping_rounds=50, verbose=False)\n\n    val_pred = model.predict(X_val)\n    train_pred = model.predict(X_train)\n    \n    rmse_val = np.sqrt(mean_squared_error(y_val, val_pred))\n    rmse_train = np.sqrt(mean_squared_error(y_train, train_pred))\n\n    return rmse_val + 0.1 * rmse_train  # Prioritizing validation RMSE, but considering training too\n\n# Function to optimize LightGBM\ndef objective_lgb(trial):\n    params = {\n        \"n_estimators\": trial.suggest_int(\"n_estimators\", 100, 500),\n        \"learning_rate\": trial.suggest_float(\"learning_rate\", 0.01, 0.3, log=True),\n        \"num_leaves\": trial.suggest_int(\"num_leaves\", 20, 300),\n        \"min_child_samples\": trial.suggest_int(\"min_child_samples\", 5, 50),\n        \"colsample_bytree\": trial.suggest_float(\"colsample_bytree\", 0.5, 1.0),\n        \"subsample\": trial.suggest_float(\"subsample\", 0.5, 1.0),\n        \"min_split_gain\": trial.suggest_float(\"min_split_gain\", 0, 0.5),\n        \"reg_alpha\": trial.suggest_float(\"reg_alpha\", 0, 1),\n        \"reg_lambda\": trial.suggest_float(\"reg_lambda\", 0, 1),\n        \"random_state\": 422\n    }\n\n    model = lgb.LGBMRegressor(**params)\n    \n    # Early stopping via callbacks\n    model.fit(\n        X_train, y_train,\n        eval_set=[(X_val, y_val)],\n        eval_metric=\"rmse\",\n        callbacks=[lgb.early_stopping(50, verbose=False)]\n    )\n\n    val_pred = model.predict(X_val)\n    train_pred = model.predict(X_train)\n\n    rmse_val = np.sqrt(mean_squared_error(y_val, val_pred))\n    rmse_train = np.sqrt(mean_squared_error(y_train, train_pred))\n\n    return rmse_val + 0.1 * rmse_train  # Balancing validation and train RMSE\n\n# Running Optuna for XGBoost\nstudy_xgb = optuna.create_study(direction=\"minimize\")\nstudy_xgb.optimize(objective_xgb, n_trials=20)  # Adjust trials as needed\nbest_xgb_params = study_xgb.best_params\n\n# Running Optuna for LightGBM\nstudy_lgb = optuna.create_study(direction=\"minimize\")\nstudy_lgb.optimize(objective_lgb, n_trials=20)\nbest_lgb_params = study_lgb.best_params\n\n# Train models with best parameters\nxgb_model = xgb.XGBRegressor(**best_xgb_params)\nxgb_model.fit(X_train, y_train)\n\nlgb_model = lgb.LGBMRegressor(**best_lgb_params)\nlgb_model.fit(X_train, y_train)\n\n# Predictions\nxgb_pred_train = xgb_model.predict(X_train)\nxgb_pred_val = xgb_model.predict(X_val)\nxgb_pred_test = xgb_model.predict(X_test)\n\nlgb_pred_train = lgb_model.predict(X_train)\nlgb_pred_val = lgb_model.predict(X_val)\nlgb_pred_test = lgb_model.predict(X_test)\n\n# RMSE\nxgb_rmse_train = np.sqrt(mean_squared_error(y_train, xgb_pred_train))\nxgb_rmse_val = np.sqrt(mean_squared_error(y_val, xgb_pred_val))\nlgb_rmse_train = np.sqrt(mean_squared_error(y_train, lgb_pred_train))\nlgb_rmse_val = np.sqrt(mean_squared_error(y_val, lgb_pred_val))\n\nprint(f\"XGBoost RMSE - Train: {xgb_rmse_train:.4f}, Validation: {xgb_rmse_val:.4f}\")\nprint(f\"LightGBM RMSE - Train: {lgb_rmse_train:.4f}, Validation: {lgb_rmse_val:.4f}\")\n\n","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-02-03T21:59:55.579176Z","iopub.execute_input":"2025-02-03T21:59:55.579593Z","iopub.status.idle":"2025-02-03T22:10:47.735109Z","shell.execute_reply.started":"2025-02-03T21:59:55.579556Z","shell.execute_reply":"2025-02-03T22:10:47.733829Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"# import xgboost as xgb\n# import lightgbm as lgb\n\n# from sklearn.metrics import mean_absolute_error, mean_squared_error\n\n# xgb_model = xgb.XGBRegressor(objective='reg:squarederror', n_estimators=100, random_state=42)\n# xgb_model.fit(X_train, y_train)\n\n# lgb_model = lgb.LGBMRegressor(n_estimators=100, min_data_in_leaf=10, min_split_gain=0.1, random_state=422)\n# lgb_model.fit(X_train, y_train)\n# xgb_pred_train = xgb_model.predict(X_train)\n# lgb_pred_train = lgb_model.predict(X_train)\n\n# xgb_pred_val = xgb_model.predict(X_val)\n# lgb_pred_val = lgb_model.predict(X_val)\n\n# xgb_pred_test = xgb_model.predict(X_test)\n# lgb_pred_test = lgb_model.predict(X_test)\n\n# def evaluate_model_log_rmse(y_true, y_pred, model_name):\n#     # Apply log transformation (log1p to handle zero values)\n#     # log_y_true = np.log1p(y_true)\n#     # log_y_pred = np.log1p(y_pred)\n#     # log_y_true=np.nan_to_num(log_y_true, nan=0)\n#     # log_y_pred=np.nan_to_num(log_y_pred, nan=0)\n\n#     # Compute RMSE\n#     rmse = np.sqrt(mean_squared_error(y_true, y_pred))\n#     print(f\"{model_name} - Log RMSE: {rmse:.4f}\")\n\n# # Evaluate models using log-transformed RMSE\n# evaluate_model_log_rmse(y_val, xgb_pred_val, \"XGBoost\")\n# evaluate_model_log_rmse(y_val, lgb_pred_val, \"LightGBM\")\n# evaluate_model_log_rmse(y_train, xgb_pred_train, \"XGBoost\")\n# evaluate_model_log_rmse(y_train, lgb_pred_train, \"LightGBM\")","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-02-03T21:53:25.384261Z","iopub.status.idle":"2025-02-03T21:53:25.384739Z","shell.execute_reply":"2025-02-03T21:53:25.384537Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"df_sub=pd.merge(df_base[(df_base['tag']=='test')]['fullVisitorId'],pd.DataFrame(lgb_pred_test),left_index=True, right_index=True)\ndf_sub.columns=['fullVisitorId','PredictedLogRevenue']\ndf_sub[\"PredictedLogRevenue\"] = np.expm1(df_sub[\"PredictedLogRevenue\"])  \ndf_sub['PredictedLogRevenue']= df_sub['PredictedLogRevenue']#.astype(float).round(1)\ndf_sub['PredictedLogRevenue'].value_counts()\ndf_sub=df_sub.groupby(\"fullVisitorId\")[\"PredictedLogRevenue\"].sum().reset_index()\ndf_sub['PredictedLogRevenue']=np.log1p(df_sub['PredictedLogRevenue'])\ndf_sub.to_csv(\"submission.csv\",index=False)","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-02-03T22:10:47.736814Z","iopub.execute_input":"2025-02-03T22:10:47.737788Z","iopub.status.idle":"2025-02-03T22:10:49.504328Z","shell.execute_reply.started":"2025-02-03T22:10:47.737750Z","shell.execute_reply":"2025-02-03T22:10:49.502894Z"}},"outputs":[],"execution_count":null}]}