{"cells":[{"metadata":{},"cell_type":"markdown","source":"<!-- <img src=\"https://i.imgur.com/oiG2jZl.png\"> -->\n<center><h1>🧭Indoor Location and Navigation🧭</h1></center>\n\n# 1. Introduction\n> 📌**Goal**: Predicting the indoor position of smartphones📱 based on a *real-time* sensor🎯.\n\n> We'll also learn how to use the **GitHub Repository** available through this competition and call the custom functions **without** copy-pasting them into the notebook.\n\n### Libraries📚"},{"metadata":{"trusted":true},"cell_type":"code","source":"# CPU libraries\nimport os\nimport json\nimport glob\nimport cv2\nimport numpy as np\nimport pandas as pd\nimport seaborn as sns\nimport matplotlib\nimport matplotlib.pyplot as plt\nimport plotly.graph_objs as go\n\nfrom PIL import Image, ImageOps\nfrom skimage import io\nfrom skimage.color import rgba2rgb, rgb2xyz\nfrom tqdm import tqdm\nfrom dataclasses import dataclass\nfrom math import floor, ceil\n\nmycolors = [\"#797D62\", \"#9B9B7A\", \"#D9AE94\", \"#FFCB69\", \"#D08C60\", \"#997B66\"]","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"# Get path to all TRAIN & TEST files\ntrain_paths = glob.glob('../input/indoor-location-navigation/train/*/*/*')\ntest_paths = glob.glob('../input/indoor-location-navigation/test/*')\nsites = glob.glob('../input/indoor-location-navigation/metadata/*')\n\nprint(\"No. Files in Train: {:,}\".format(len(train_paths)), \"\\n\" +\n      \"No. Files in Test: {:,}\".format(len(test_paths)), \"\\n\" +\n      \"Total Sites (metadata): {:,}\".format(len(sites)))","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"# How 1 path looks\nbase = '../input/indoor-location-navigation'\npath = f'{base}/train/5cd56b5ae2acfd2d33b58549/5F/5d06134c4a19c000086c4324.txt'\n\nwith open(path) as p:\n    lines = p.readlines()\n\nprint(\"No. Lines in 1 example: {:,}\". format(len(lines)), \"\\n\" +\n      \"Example (5 lines): \", lines[0:10])","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"# 2. How to use a GitHub repo on Kaggle?🔗\n\n> 📌**Goal**: This competition has a [GitHub repo](https://github.com/location-competition/indoor-location-competition-20) available. We can use the `read_data_file` function in the `io_f` file to read in the information ( no additional struggle on our side + no copy-paste and cluttered code :) ).\n\n#### *🙏🏻Special thanks to [Laura](https://www.kaggle.com/allunia) for teaching me this awesome trick.🙏🏻*\n\n**Steps**:\n* 🦶🏻 - download the repo from [this link](https://github.com/location-competition/indoor-location-competition-20)\n* 🦶🏻 - copy the package to the Kaggle environment (`!cp -r path/* ./`)\n* 🦶🏻 - import it and use it as you please"},{"metadata":{"trusted":true},"cell_type":"code","source":"!cp -r ../input/indoor-locationnavigation-2021/indoor-location-competition-20-master/indoor-location-competition-20-master/* ./","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"# Import custom function from the repository\nfrom io_f import read_data_file\n\n# Read in 1 random example\nsample_file = read_data_file(path)\n\n# You can access the information for each variable:\nprint(\"~~~ Example ~~~\")\nprint(\"acce: {}\".format(sample_file.acce.shape), \"\\n\" +\n      \"acacce_uncalice: {}\".format(sample_file.acce_uncali.shape), \"\\n\" +\n      \"ahrs: {}\".format(sample_file.ahrs.shape), \"\\n\" +\n      \"gyro: {}\".format(sample_file.gyro.shape), \"\\n\" +\n      \"gyro_uncali: {}\".format(sample_file.gyro_uncali.shape), \"\\n\" +\n      \"ibeacon: {}\".format(sample_file.ibeacon.shape), \"\\n\" +\n      \"magn: {}\".format(sample_file.magn.shape), \"\\n\" +\n      \"magn_uncali: {}\".format(sample_file.magn_uncali.shape), \"\\n\" +\n      \"waypoint: {}\".format(sample_file.waypoint.shape), \"\\n\" +\n      \"wifi: {}\".format(sample_file.wifi.shape))","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"# pull out all the buildings actually used in the test set, given current method we don't need the other ones\nssubm = pd.read_csv('../input/indoor-location-navigation/sample_submission.csv')\n\n# only 24 of the total buildings are used in the test set, \n# this allows us to greatly reduce the intial size of the dataset\nssubm_df = ssubm[\"site_path_timestamp\"].apply(lambda x: pd.Series(x.split(\"_\")))\nssubm_df.head()","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"# How 1 path looks\nbase = '../input/indoor-location-navigation/train/'\n# used_buildings = sorted(ssubm_df[0].value_counts().index.tolist())\nused_buildings = [\"5a0546857ecc773753327266\"]\n\nwifi_cols = [\"Time\", \"ssid\", \"bssid\", \"RSSI\", \"last seen timestamp\"]\ndf = pd.DataFrame(columns=wifi_cols)\n\nfor building in used_buildings:\n    print(building)\n    folders = sorted(glob.glob(os.path.join(base + building + '/*')))\n    # Read in 1 random example\n    for folder in folders:\n        paths = glob.glob(os.path.join(folder, \"*.txt\"))\n        for path in paths:\n            temp = read_data_file(path)\n            # Stack the DataFrames on top of each other\n            if temp.wifi.size != 0:\n                df_wifi = pd.DataFrame(data=temp.wifi, columns=wifi_cols)\n                min_result = 10e9\n                for j in range(df_wifi.shape[0]):\n                    for i in range(len(temp.waypoint)):\n                        min_t = abs(int(df_wifi.loc[j, 'Time']) - int(temp.waypoint[i][0]))\n                        if min_result > min_t:\n                            min_result = min_t\n                            min_index = i\n                            \n                    df_wifi.loc[j, 'pointTime'] = int(temp.waypoint[min_index][0])\n                    df_wifi.loc[j, 'x'] = int(temp.waypoint[min_index][1])\n                    df_wifi.loc[j, 'y'] = int(temp.waypoint[min_index][2])\n                    df = df.append(df_wifi)\n\ndf.head()","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"df.head()","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"# 4. Baseline Model\n\n> 📌**Note**: Preprocessed data is from [this dataset](https://www.kaggle.com/devinanzelmo/indoor-navigation-and-location-wifi-features) by [Devin Anzelmo](https://www.kaggle.com/devinanzelmo)."},{"metadata":{},"cell_type":"markdown","source":"### RAPIDS function"},{"metadata":{"trusted":true},"cell_type":"code","source":"from cupy import sqrt as sqrt_g\nfrom cupy import power as power_g\nfrom cupy import abs as abs_g","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"def mean_position_error_gpu(x_pred, y_pred, f_pred, x_true, y_true, f_true, p=15):\n    '''Same, but Faster ;)\n    Using RAPIDS here for our XGBoost model later.'''\n    \n    N = len(x_true)\n    formula = sqrt_g( power_g(x_pred - x_true, 2) + power_g(y_pred - y_true, 2) )\n    formula = formula + p * abs_g(f_pred - f_true)\n    formula = formula.sum() / N\n    return formula","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"def mean_position_error(x_pred, y_pred, f_pred, x_true, y_true, f_true, p=15):\n    '''Custom function to evaluate Mean Position Error.\n    x: x coordinate of the waypoint position; dtype list()\n    y: y coordinate of the waypoint position; dtype list()\n    f: exact floor or the building; dtype list()\n    p: floor penalty, set to 15 (always)'''\n    \n    N = len(x_true)\n    #1\n    formula = sqrt( power(x_pred - x_true, 2) + power(y_pred - y_true, 2) )\n    #2\n    formula = formula + p * absolute(f_pred - f_true)\n    #3\n    formula = formula.sum() / N\n    \n    return formula","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"def make_submission(predictions, sample_subm, name=\"base.csv\"):\n    '''Receives a list of predictions in dataframe format.'''\n    final_submission = pd.concat(predictions).reset_index(drop=True)\n    final_submission.index = sample_subm.index\n    final_submission.to_csv(name)\n    print(\"Submission ready.\")","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"## I. Light GBM"},{"metadata":{"trusted":true},"cell_type":"code","source":"# Import Libraries\nimport lightgbm as lgb\n\n# ~~~~\n# Data\n# ~~~~\nbase_dir = \"../input/indoor-navigation-and-location-wifi-features/wifi_features\"\ntrain_dir = \"/train/*_train.csv\"\ntest_dir = \"/test/*_test.csv\"\n\n\n# Paths for train & test files\ntrain_paths = sorted(glob.glob(base_dir + train_dir))\ntest_paths = sorted(glob.glob(base_dir + test_dir))\nsample_subm = pd.read_csv('../input/indoor-location-navigation/sample_submission.csv',\n                          index_col=0)\n\nprint(\"Len Train Files: {}\".format(len(train_paths)), \"\\n\" +\n      \"Len Test Files: {}\".format(len(test_paths)))","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"# Initialize new experiment (LGBM)\nrun = wandb.init(project=\"indoor-location-kaggle\", name=\"lgbm_train\")\n\nwandb.log({'Len Train Files' : len(train_paths),\n           'Len Test Files' : len(test_paths)})","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"> Schema of the \"Training loop\" (inspired by [Jiwei Liu's work](https://www.kaggle.com/jiweiliu)):\n<img src=\"https://i.imgur.com/UQmdRcz.png\" width=750>\n\n#### Code Below"},{"metadata":{"trusted":true,"_kg_hide-input":true,"_kg_hide-output":false},"cell_type":"code","source":"def train_lgbm(train_perc=0.75, version=1, n_estimators=150, num_leaves=127):\n    '''\n    Training loop\n    '''\n\n    f = open(f\"lgbm_logs_{version}.txt\", \"w+\")\n    lgbm_predictions = []\n    \n    # Log in W&B\n    wandb.log({'n_estimators': n_estimators, 'num_leaves': num_leaves})\n    \n    k = 1\n    for train_path, test_path in zip(train_paths, test_paths):\n\n\n        # --- Read in data ---\n        train_df = pd.read_csv(train_path, index_col=0)\n        train_df = train_df.sample(frac=1, random_state=10)\n\n        # Erase last column (which is \"site_path_timestamp\")\n        test_df = pd.read_csv(test_path, index_col=0).iloc[:, :-1]\n\n        # Sample out training and validation data\n        ### we need to be careful to choose same information for ALL 3 models\n        ### 1 for x, 1 for y and 1 for floor\n\n        train_size = int(len(train_df) * train_perc)\n\n\n        # --- Data Validation ---\n        # Train features + targets\n        X_train = train_df.iloc[:train_size, :-4]\n        y_train_x = train_df.iloc[:train_size, -4]\n        y_train_y = train_df.iloc[:train_size, -3]\n        y_train_f = train_df.iloc[:train_size, -2]\n\n        # Valid features + targets\n        X_valid = train_df.iloc[train_size:, :-4]\n        y_valid_x = train_df.iloc[train_size:, -4]\n        y_valid_y = train_df.iloc[train_size:, -3]\n        y_valid_f = train_df.iloc[train_size:, -2]\n\n\n        # --- Model Training ---\n        lgbm_x = lgb.LGBMRegressor(n_estimators=n_estimators, num_leaves=num_leaves)\n        lgbm_x.fit(X_train, y_train_x)\n\n        lgbm_y = lgb.LGBMRegressor(n_estimators=n_estimators, num_leaves=num_leaves)\n        lgbm_y.fit(X_train, y_train_y)\n\n        lgbm_f = lgb.LGBMClassifier(n_estimators=n_estimators, num_leaves=num_leaves)\n        lgbm_f.fit(X_train, y_train_f)\n\n\n        # --- Model Validation Predictions ---\n        preds_x = lgbm_x.predict(X_valid)\n        preds_y = lgbm_y.predict(X_valid)\n        preds_f = lgbm_f.predict(X_valid).astype(int)\n        \n        mpe = mean_position_error(preds_x, preds_y, preds_f,\n                                  y_valid_x, y_valid_y, y_valid_f)\n        print(\"{} | MPE: {}\".format(k, mpe))\n        # Save logs\n        with open(f\"lgbm_logs_{version}.txt\", 'a+') as f:\n            print(\"{} | MPE: {}\".format(k, mpe), file=f)\n        \n        # Log MPE of this experiment\n        wandb.log({'MPE' : mpe, 'step' : k})\n        \n        k+=1\n\n\n        # --- Model Test Predictions ---\n        test_preds_x = lgbm_x.predict(test_df)\n        test_preds_y = lgbm_y.predict(test_df)\n        test_preds_f = lgbm_f.predict(test_df).astype(int)\n\n        all_test_preds = pd.DataFrame({'floor' : test_preds_f,\n                                       'x' : test_preds_x, \n                                       'y' : test_preds_y})\n        lgbm_predictions.append(all_test_preds)\n    \n    \n    return lgbm_predictions","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"train_df = pd.read_csv(train_paths[0], index_col=0)\n# train_size = int(len(train_df) * 0.7)\ntrain_df.iloc[:train_size, :]","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"### Training"},{"metadata":{"trusted":true},"cell_type":"code","source":"# Uncomment line below to train your own model\n# lgbm_predictions = train_lgbm(train_perc = 0.75, version=1)\n\n# # Logs from my training:\nprint(open('../input/indoor-locationnavigation-2021/lgbm_logs_1.txt', \"r\").read())","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"> ❗**Attention**: *5th* dataframe had a BIG error (jumped from ~4 on average to 18). This case HAS to be taken into consideration, as the models seems to be underfitting. The *10th, 13th, 21st* have big MPE as well.\n\n### Submission LGBM"},{"metadata":{"trusted":true},"cell_type":"code","source":"# Uncomment line below to make your own submission\n# make_submission(lgbm_predictions, sample_subm, name=\"lgbm_base.csv\")\n\n# My submission:\nlgbm_predictions = pd.read_csv(\"../input/indoor-locationnavigation-2021/lgbm_base.csv\")\nlgbm_predictions.to_csv(\"lgbm_base.csv\", index=False)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"# ~ END of EXPERIMENT ~\nwandb.finish()\n# ~~~~~~~~~~~~~~~~~~~~~","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"## II. XGBoost - Faster with RAPIDS\n\n> 📌**Note**: I will use a combination of **RAPIDS** libraries on GPU and XGBoost as one of my base models. More information on this open source suite of libraries [here](https://rapids.ai/)."},{"metadata":{"_kg_hide-input":false,"trusted":true},"cell_type":"code","source":"# Libraries\nimport cudf\nimport cupy\nimport cuml\nimport xgboost\n\n# Adjust floor function\n### As the Multiclass XGBoost takes only labels between [0, n)\n### But we have negative floor values\ndef adjust_floor(df, col_name):\n    '''Adjusts the floor to be >= 0.\n    Also returns the number fo classes (also used to complete classification).'''\n    num_classes = df[col_name].nunique()\n    smallest = df[col_name].unique().min()\n    df[col_name] = df[col_name] - smallest\n    \n    return df[col_name], num_classes, smallest","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"# Initialize new experiment (XGB)\nrun = wandb.init(project=\"indoor-location-kaggle\", name=\"xgb_train\")\n\nwandb.log({'Len Train Files' : len(train_paths),\n           'Len Test Files' : len(test_paths)})","execution_count":null,"outputs":[]},{"metadata":{"_kg_hide-input":true,"trusted":true},"cell_type":"code","source":"def train_xgb(train_perc=0.75, version=1):\n    '''\n    Training loop\n    '''\n\n    f = open(f\"xgb_logs_{version}.txt\", \"w+\")\n    xgb_predictions = []\n    \n    \n    k = 1\n    for train_path, test_path in zip(train_paths, test_paths):\n\n\n        # --- Read in data ---\n        train_df = cudf.read_csv(train_path, index_col=0)\n        train_df = train_df.sample(frac=1, random_state=10)\n        train_df[\"f\"], num_classes, smallest = adjust_floor(train_df, 'f')\n\n        # Erase last column (which is \"site_path_timestamp\")\n        test_df = cudf.read_csv(test_path, index_col=0).iloc[:, :-1]\n\n        # Sample out training and validation data\n        ### we need to be careful to choose same information for ALL 3 models\n        ### 1 for x, 1 for y and 1 for floor\n\n        train_size = int(len(train_df) * train_perc)\n\n\n        # --- Data Validation ---\n        # Train features + targets\n        X_train = train_df.iloc[:train_size, :-4]\n        y_train_x = train_df.iloc[:train_size, -4]\n        y_train_y = train_df.iloc[:train_size, -3]\n        y_train_f = train_df.iloc[:train_size, -2]\n\n        # Valid features + targets\n        X_valid = train_df.iloc[train_size:, :-4]\n        y_valid_x = cupy.asanyarray(train_df.iloc[train_size:, -4])\n        y_valid_y = cupy.asanyarray(train_df.iloc[train_size:, -3])\n        y_valid_f = cupy.asanyarray(train_df.iloc[train_size:, -2])\n        \n        \n        # --- Parameters ---\n        regr_params = {'max_depth' : 4, 'max_leaves' : 2**4, \n                       'tree_method' : 'gpu_hist', 'objective' : 'reg:squarederror',\n                       'grow_policy' : 'lossguide', 'colsample_bynode': 0.8}\n        classif_params = {'max_depth' : 4, 'max_leaves' : 2**4,\n                          'tree_method' : 'gpu_hist', 'objective' : 'multi:softmax',\n                          'num_class' : num_classes, 'grow_policy' : 'lossguide',\n                          'colsample_bynode': 0.8, 'verbosity' : 0}\n        \n        # Log once to W&B\n        if k == 1:\n            wandb.log(regr_params)\n            wandb.log(classif_params)\n\n\n        # --- Model Training ---\n        trainMatrix_x = xgboost.DMatrix(data=X_train, label=y_train_x)\n        xgboost_x = xgboost.train(params=regr_params, dtrain=trainMatrix_x)\n\n        trainMatrix_y = xgboost.DMatrix(data=X_train, label=y_train_y)\n        xgboost_y = xgboost.train(params=regr_params, dtrain=trainMatrix_y)\n\n        trainMatrix_f = xgboost.DMatrix(data=X_train, label=y_train_f)\n        xgboost_f = xgboost.train(params=classif_params, dtrain=trainMatrix_f)\n\n\n        # --- Model Validation Predictions ---\n        preds_x = cupy.asanyarray(xgboost_x.predict(xgboost.DMatrix(X_valid)))\n        preds_y = cupy.asanyarray(xgboost_y.predict(xgboost.DMatrix(X_valid)))\n        preds_f = cupy.asanyarray(xgboost_f.predict(xgboost.DMatrix(X_valid)).astype(int))\n\n        mpe = mean_position_error_gpu(preds_x, preds_y, preds_f,\n                                      y_valid_x, y_valid_y, y_valid_f)\n        print(\"{} | MPE: {}\".format(k, mpe))\n        # Save logs\n        with open(f\"xgb_logs_{version}.txt\", 'a+') as f:\n            print(\"{} | MPE: {}\".format(k, mpe), file=f)\n        \n        # Log MPE of this experiment\n        wandb.log({'MPE' : mpe, 'step' : k})\n        \n        k+=1\n\n\n        # --- Model Test Predictions ---\n        test_preds_x = xgboost_x.predict(xgboost.DMatrix(test_df))\n        test_preds_y = xgboost_y.predict(xgboost.DMatrix(test_df))\n        test_preds_f = xgboost_f.predict(xgboost.DMatrix(test_df)).astype(int) + smallest\n\n        all_test_preds = pd.DataFrame({'floor' : test_preds_f,\n                                       'x' : test_preds_x, \n                                       'y' : test_preds_y})\n        xgb_predictions.append(all_test_preds)\n    \n    \n    return xgb_predictions","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"### Training"},{"metadata":{"_kg_hide-input":false,"trusted":true},"cell_type":"code","source":"# Uncomment line below to train your own model\n# xgb_predictions = train_xgb(train_perc=0.75, version=1)\n\n# Logs from my training:\nprint(open('../input/indoor-locationnavigation-2021/xgb_logs_1.txt', \"r\").read())","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"### Submission"},{"metadata":{"trusted":true},"cell_type":"code","source":"# Uncomment line below to make your own submission\n# make_submission(xgb_predictions, sample_subm, name=\"xgb_base.csv\")\n\n# My submission:\nxgb_predictions = pd.read_csv(\"../input/indoor-locationnavigation-2021/xgb_base.csv\")\nxgb_predictions.to_csv(\"xgb_base.csv\", index=False)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"# ~ END of EXPERIMENT ~\nwandb.finish()\n# ~~~~~~~~~~~~~~~~~~~~~","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"# 5. Save W&B Submissions and Logs\n\n> We can save the predictions and logs to W&B."},{"metadata":{"trusted":true},"cell_type":"code","source":"# Submissions\n### we can save the predictions in W&B\nrun = wandb.init(project='indoor-location-kaggle', name='submissions')\nartifact = wandb.Artifact(name='submissions', \n                          type='dataset')\n\nartifact.add_file(\"../input/indoor-locationnavigation-2021/lgbm_base.csv\")\nartifact.add_file(\"../input/indoor-locationnavigation-2021/xgb_base.csv\")\n\nwandb.log_artifact(artifact)\nwandb.finish()","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"# Logs\n### we can save the predictions in W&B\nrun = wandb.init(project='indoor-location-kaggle', name='training_logs')\nartifact = wandb.Artifact(name='training_logs', \n                          type='dataset')\n\nartifact.add_file(\"../input/indoor-locationnavigation-2021/lgbm_logs_1.txt\")\nartifact.add_file(\"../input/indoor-locationnavigation-2021/xgb_logs_1.txt\")\n\nwandb.log_artifact(artifact)\nwandb.finish()","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"> The Artifact section of the project:\n<img src=\"https://i.imgur.com/KqzJuFL.png\">\n\n# Blending Stirring Cooking 🥙\n\n> First let's compare the 2 model's predictions. (needs more work)"},{"metadata":{"_kg_hide-input":true,"trusted":true},"cell_type":"code","source":"# # Read in data\n# lgb_preds = pd.read_csv(\"../input/indoor-locationnavigation-2021/lgbm_base.csv\")\n# xgb_preds = pd.read_csv(\"../input/indoor-locationnavigation-2021/xgb_base.csv\")\n\n# sample_submission = pd.read_csv(\"../input/indoor-location-navigation/sample_submission.csv\")\n\n# # Sample Submission\n# sample_submission[\"x\"] = lgb_preds[\"x\"] * 0.9 + xgb_preds[\"x\"] * 0.1\n# sample_submission[\"y\"] = lgb_preds[\"y\"] * 0.9 + xgb_preds[\"y\"] * 0.1\n\n# sample_submission.to_csv(\"blend1.csv\", index=False)","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"<img src=\"https://i.imgur.com/cUQXtS7.png\">\n\n# Specs on how I prepped & trained ⌨️🎨\n### (on my local machine)\n* Z8 G4 Workstation 🖥\n* 2 CPUs & 96GB Memory 💾\n* NVIDIA Quadro RTX 8000 🎮\n* RAPIDS version 0.17 🏃🏾‍♀️"}],"metadata":{"kernelspec":{"language":"python","display_name":"Python 3","name":"python3"},"language_info":{"pygments_lexer":"ipython3","nbconvert_exporter":"python","version":"3.6.4","file_extension":".py","codemirror_mode":{"name":"ipython","version":3},"name":"python","mimetype":"text/x-python"}},"nbformat":4,"nbformat_minor":4}