{"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_minor":4,"nbformat":4,"cells":[{"cell_type":"markdown","source":"\n\n\nV6 : Instead of using all train data (4M 721 K row), we can exclude rows that have a distance greater than 2, they are most likely to have a negative contact ( + 0.99 recall), the new train data have 660 K row, now we can add more features like the difference between player 1 and 2, product and multiple clusters ...\n\nV8 : Handling missing values for The Ground","metadata":{}},{"cell_type":"code","source":"import os\nimport torch\n\nclass Config:\n    AUTHOR = \"colum2131\"\n\n    NAME = \"NFLC-\" + \"Exp001-simple-xgb-baseline\"\n\n    COMPETITION = \"nfl-player-contact-detection\"\n\n    seed = 42\n    num_fold = 5\n    \n    xgb_params = {\n        'objective': 'binary:logistic',\n        'eval_metric': 'auc',\n        'learning_rate':0.03,\n        'tree_method':'hist' if not torch.cuda.is_available() else 'gpu_hist'\n    }","metadata":{"_uuid":"8f2839f25d086af736a60e9eeb907d3b93b6e0e5","_cell_guid":"b1076dfc-b9ad-4769-8c92-a6c4dae69d19","execution":{"iopub.status.busy":"2022-12-30T16:49:52.344484Z","iopub.execute_input":"2022-12-30T16:49:52.344920Z","iopub.status.idle":"2022-12-30T16:49:54.142074Z","shell.execute_reply.started":"2022-12-30T16:49:52.344827Z","shell.execute_reply":"2022-12-30T16:49:54.140824Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"import os\nimport gc\nimport subprocess\n\nimport numpy as np\nimport pandas as pd\nimport matplotlib.pyplot as plt\nimport matplotlib.patches as patches\nfrom IPython.display import Video, display\n\nfrom scipy.optimize import minimize\nimport cv2\nfrom glob import glob\nfrom tqdm import tqdm\n\nfrom sklearn.model_selection import GroupKFold\nfrom sklearn.metrics import (\n    roc_auc_score,\n    matthews_corrcoef,\n)\n\nimport xgboost as xgb\n\nimport torch\n\nif torch.cuda.is_available():\n    import cupy \n    import cudf\n    from cuml import ForestInference","metadata":{"execution":{"iopub.status.busy":"2022-12-30T16:49:54.147848Z","iopub.execute_input":"2022-12-30T16:49:54.149057Z","iopub.status.idle":"2022-12-30T16:49:57.982289Z","shell.execute_reply.started":"2022-12-30T16:49:54.148989Z","shell.execute_reply":"2022-12-30T16:49:57.981333Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"def setup(cfg):\n    cfg.device = torch.device('cuda' if torch.cuda.is_available() else 'cpu')\n    \n    # set dirs\n    cfg.INPUT = f'../input/{cfg.COMPETITION}'\n    cfg.EXP = cfg.NAME\n    cfg.OUTPUT_EXP = cfg.NAME\n    cfg.SUBMISSION = './'\n    cfg.DATASET = '../input/'\n\n    cfg.EXP_MODEL = os.path.join(cfg.EXP, 'model')\n    cfg.EXP_FIG = os.path.join(cfg.EXP, 'fig')\n    cfg.EXP_PREDS = os.path.join(cfg.EXP, 'preds')\n\n    # make dirs\n    for d in [cfg.EXP_MODEL, cfg.EXP_FIG, cfg.EXP_PREDS]:\n        os.makedirs(d, exist_ok=True)\n        \n    return cfg","metadata":{"execution":{"iopub.status.busy":"2022-12-30T16:49:57.983926Z","iopub.execute_input":"2022-12-30T16:49:57.984294Z","iopub.status.idle":"2022-12-30T16:49:57.994500Z","shell.execute_reply.started":"2022-12-30T16:49:57.984259Z","shell.execute_reply":"2022-12-30T16:49:57.991638Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# ==============================\n# function\n# ==============================\n# ref: https://www.kaggle.com/code/robikscube/nfl-player-contact-detection-getting-started\ndef add_contact_id(df):\n    # Create contact ids\n    df[\"contact_id\"] = (\n        df[\"game_play\"]\n        + \"_\"\n        + df[\"step\"].astype(\"str\")\n        + \"_\"\n        + df[\"nfl_player_id_1\"].astype(\"str\")\n        + \"_\"\n        + df[\"nfl_player_id_2\"].astype(\"str\")\n    )\n    return df\n\ndef expand_contact_id(df):\n    \"\"\"\n    Splits out contact_id into seperate columns.\n    \"\"\"\n    df[\"game_play\"] = df[\"contact_id\"].str[:12]\n    df[\"step\"] = df[\"contact_id\"].str.split(\"_\").str[-3].astype(\"int\")\n    df[\"nfl_player_id_1\"] = df[\"contact_id\"].str.split(\"_\").str[-2]\n    df[\"nfl_player_id_2\"] = df[\"contact_id\"].str.split(\"_\").str[-1]\n    return df\n\n# cross validation\ndef get_groupkfold(train, target_col, group_col, n_splits):\n    kf = GroupKFold(n_splits=n_splits)\n    generator = kf.split(train, train[target_col], train[group_col])\n    fold_series = []\n    for fold, (idx_train, idx_valid) in enumerate(generator):\n        fold_series.append(pd.Series(fold, index=idx_valid))\n    fold_series = pd.concat(fold_series).sort_index()\n    return fold_series\n\n# xgboost code\ndef fit_xgboost(cfg, X, y, params, add_suffix=''):\n    \"\"\"\n    xgb_params = {\n        'objective': 'binary:logistic',\n        'eval_metric': 'auc',\n        'learning_rate':0.01,\n        'tree_method':'gpu_hist'\n    }\n    \"\"\"\n    oof_pred = np.zeros(len(y), dtype=np.float32)\n    for fold in sorted(cfg.folds.unique()):\n        if fold == -1: continue\n        idx_train = (cfg.folds!=fold)\n        idx_valid = (cfg.folds==fold)\n        x_train, y_train = X[idx_train], y[idx_train]\n        x_valid, y_valid = X[idx_valid], y[idx_valid]\n        display(pd.Series(y_valid).value_counts())\n\n        xgb_train = xgb.DMatrix(x_train, label=y_train)\n        xgb_valid = xgb.DMatrix(x_valid, label=y_valid)\n        evals = [(xgb_train,'train'),(xgb_valid,'eval')]\n\n        model = xgb.train(\n            params,\n            xgb_train,\n            num_boost_round=10_000,\n            early_stopping_rounds=100,\n            evals=evals,\n            verbose_eval=100,\n        )\n\n        model_path = os.path.join(cfg.EXP_MODEL, f'xgb_fold{fold}{add_suffix}.model')\n        model.save_model(model_path)\n        if not torch.cuda.is_available():\n            model = xgb.Booster().load_model(model_path)\n        else:\n            model = ForestInference.load(model_path, output_class=True, model_type='xgboost')\n        pred_i = model.predict_proba(x_valid)[:, 1]\n        oof_pred[x_valid.index] = pred_i\n        score = round(roc_auc_score(y_valid, pred_i), 5)\n        print(f'Performance of the prediction: {score}\\n')\n        del model; gc.collect()\n\n    np.save(os.path.join(cfg.EXP_PREDS, f'oof_pred{add_suffix}'), oof_pred)\n    score = round(roc_auc_score(y, oof_pred), 5)\n    print(f'All Performance of the prediction: {score}')\n    return oof_pred\n\ndef pred_xgboost(X, data_dir, add_suffix=''):\n    models = glob(os.path.join(data_dir, f'xgb_fold*{add_suffix}.model'))\n    if not torch.cuda.is_available():\n         models = [xgb.Booster().load_model(model_path) for model in models]\n    else:\n        models = [ForestInference.load(model, output_class=True, model_type='xgboost') for model in models]\n    preds = np.array([model.predict_proba(X)[:, 1] for model in models])\n    preds = np.mean(preds, axis=0)\n    return preds","metadata":{"execution":{"iopub.status.busy":"2022-12-30T16:49:57.997897Z","iopub.execute_input":"2022-12-30T16:49:57.998162Z","iopub.status.idle":"2022-12-30T16:49:58.018451Z","shell.execute_reply.started":"2022-12-30T16:49:57.998138Z","shell.execute_reply":"2022-12-30T16:49:58.017423Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# ==============================\n# read data\n# ==============================\ncfg = setup(Config)\n\nif not torch.cuda.is_available():\n    tr_tracking = pd.read_csv(os.path.join(cfg.INPUT, 'train_player_tracking.csv'), parse_dates=[\"datetime\"])\n    te_tracking = pd.read_csv(os.path.join(cfg.INPUT, 'test_player_tracking.csv'), parse_dates=[\"datetime\"])\n    # tr_helmets = pd.read_csv(os.path.join(cfg.INPUT, 'train_baseline_helmets.csv'))\n    # te_helmets = pd.read_csv(os.path.join(cfg.INPUT, 'test_baseline_helmets.csv'))\n    # tr_video_metadata = pd.read_csv(os.path.join(cfg.INPUT, 'train_video_metadata.csv'))\n    # te_video_metadata = pd.read_csv(os.path.join(cfg.INPUT, 'test_video_metadata.csv'))\n    sub = pd.read_csv(os.path.join(cfg.INPUT, 'sample_submission.csv'))\n\n    train = pd.read_csv(os.path.join(cfg.INPUT, 'train_labels.csv'), parse_dates=[\"datetime\"])\n    test = expand_contact_id(sub)\n    \nelse:\n    tr_tracking = cudf.read_csv(os.path.join(cfg.INPUT, 'train_player_tracking.csv'), parse_dates=[\"datetime\"])\n    te_tracking = cudf.read_csv(os.path.join(cfg.INPUT, 'test_player_tracking.csv'), parse_dates=[\"datetime\"])\n    # tr_helmets = cudf.read_csv(os.path.join(cfg.INPUT, 'train_baseline_helmets.csv'))\n    # te_helmets = cudf.read_csv(os.path.join(cfg.INPUT, 'test_baseline_helmets.csv'))\n    # tr_video_metadata = cudf.read_csv(os.path.join(cfg.INPUT, 'train_video_metadata.csv'))\n    # te_video_metadata = cudf.read_csv(os.path.join(cfg.INPUT, 'test_video_metadata.csv'))\n    sub = pd.read_csv(os.path.join(cfg.INPUT, 'sample_submission.csv'))\n\n    train = cudf.read_csv(os.path.join(cfg.INPUT, 'train_labels.csv'), parse_dates=[\"datetime\"])\n    test = cudf.DataFrame(expand_contact_id(sub))","metadata":{"execution":{"iopub.status.busy":"2022-12-30T16:49:58.020237Z","iopub.execute_input":"2022-12-30T16:49:58.020574Z","iopub.status.idle":"2022-12-30T16:50:09.617563Z","shell.execute_reply.started":"2022-12-30T16:49:58.020542Z","shell.execute_reply":"2022-12-30T16:50:09.616495Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"The following code is used to create the features.  \nBasically, the numerical features contained in player_tracking.csv are merged into player_id_1 and player_id_2 respectively.","metadata":{}},{"cell_type":"code","source":"# ==============================\n# feature engineering\n# ==============================\ndef create_features(df, tr_tracking, merge_col=\"step\", use_cols=[\"x_position\", \"y_position\"]):\n    output_cols = []\n    df_combo = (\n        df.astype({\"nfl_player_id_1\": \"str\"})\n        .merge(\n            tr_tracking.astype({\"nfl_player_id\": \"str\"})[\n                [\"game_play\", merge_col, \"nfl_player_id\",] + use_cols\n            ],\n            left_on=[\"game_play\", merge_col, \"nfl_player_id_1\"],\n            right_on=[\"game_play\", merge_col, \"nfl_player_id\"],\n            how=\"left\",\n        )\n        .rename(columns={c: c+\"_1\" for c in use_cols})\n        .drop(\"nfl_player_id\", axis=1)\n        .merge(\n            tr_tracking.astype({\"nfl_player_id\": \"str\"})[\n                [\"game_play\", merge_col, \"nfl_player_id\"] + use_cols\n            ],\n            left_on=[\"game_play\", merge_col, \"nfl_player_id_2\"],\n            right_on=[\"game_play\", merge_col, \"nfl_player_id\"],\n            how=\"left\",\n        )\n        .drop(\"nfl_player_id\", axis=1)\n        .rename(columns={c: c+\"_2\" for c in use_cols})\n        .sort_values([\"game_play\", merge_col, \"nfl_player_id_1\", \"nfl_player_id_2\"])\n        .reset_index(drop=True)\n    )\n    output_cols += [c+\"_1\" for c in use_cols]\n    output_cols += [c+\"_2\" for c in use_cols]\n    \n    if (\"x_position\" in use_cols) & (\"y_position\" in use_cols):\n        index = df_combo['x_position_2'].notnull()\n        if torch.cuda.is_available():\n            index = index.to_array()\n        distance_arr = np.full(len(index), np.nan)\n        tmp_distance_arr = np.sqrt(\n            np.square(df_combo.loc[index, \"x_position_1\"] - df_combo.loc[index, \"x_position_2\"])\n            + np.square(df_combo.loc[index, \"y_position_1\"]- df_combo.loc[index, \"y_position_2\"])\n        )\n        if torch.cuda.is_available():\n            tmp_distance_arr = tmp_distance_arr.to_array()\n        distance_arr[index] = tmp_distance_arr\n        df_combo['distance'] = distance_arr\n        output_cols += [\"distance\"]\n        \n    df_combo['G_flug'] = (df_combo['nfl_player_id_2']==\"G\")\n    output_cols += [\"G_flug\"]\n    return df_combo, output_cols\n\n\nuse_cols = [\n    'x_position', 'y_position', 'speed', 'distance',\n    'direction', 'orientation', 'acceleration', 'sa'\n]\ntrain, feature_cols = create_features(train, tr_tracking, use_cols=use_cols)\ntest, feature_cols = create_features(test, te_tracking, use_cols=use_cols)\nif torch.cuda.is_available():\n    train = train.to_pandas()\n    test = test.to_pandas()\n\ndisplay(train)","metadata":{"execution":{"iopub.status.busy":"2022-12-30T16:50:09.619211Z","iopub.execute_input":"2022-12-30T16:50:09.619790Z","iopub.status.idle":"2022-12-30T16:50:17.293531Z","shell.execute_reply.started":"2022-12-30T16:50:09.619738Z","shell.execute_reply":"2022-12-30T16:50:17.292316Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"# Exclude distance > 2\nif the distance between two players is greater than 2 then the probability of contact is so low, we will consider it = 0, training data will be reduced from 4.7 M rows to 660 K","metadata":{}},{"cell_type":"code","source":"DISTANCE_THRESH = 2\n\ntrain_y = train['contact'].values\noof_pred = np.zeros(len(train))\ncond_dis_train = (train['distance']<=DISTANCE_THRESH) | (train['distance'].isna())\ncond_dis_test = (test['distance']<=DISTANCE_THRESH) | (test['distance'].isna())\n\ntrain = train[cond_dis_train]\ntrain.reset_index(inplace = True, drop = True)\n\nprint('number of train data : ',len(train))\n\n_ = gc.collect()","metadata":{"execution":{"iopub.status.busy":"2022-12-30T16:50:17.295124Z","iopub.execute_input":"2022-12-30T16:50:17.296172Z","iopub.status.idle":"2022-12-30T16:50:17.737627Z","shell.execute_reply.started":"2022-12-30T16:50:17.296129Z","shell.execute_reply":"2022-12-30T16:50:17.736709Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"# Helmet track Features","metadata":{}},{"cell_type":"code","source":"CLUSTERS = [10, 50, 100, 500]\n\ndef add_step_pct(df, cluster):\n    df['step_pct'] = cluster * (df['step']-min(df['step']))/(max(df['step'])-min(df['step']))\n    df['step_pct'] = df['step_pct'].apply(np.ceil).astype(np.int32)\n    return df\n\nfor cluster in CLUSTERS:\n    train = train.groupby('game_play').apply(lambda x:add_step_pct(x,cluster))\n    test = test.groupby('game_play').apply(lambda x:add_step_pct(x,cluster))\n\n    for helmet_view in ['Sideline', 'Endzone']:\n        helmet_train = pd.read_csv('/kaggle/input/nfl-player-contact-detection/train_baseline_helmets.csv')\n        helmet_train.loc[helmet_train['view']=='Endzone2','view'] = 'Endzone'\n        helmet_test = pd.read_csv('/kaggle/input/nfl-player-contact-detection/test_baseline_helmets.csv')\n        helmet_test.loc[helmet_test['view']=='Endzone2','view'] = 'Endzone'\n\n        helmet_train.rename(columns = {'frame': 'step'}, inplace = True)\n        helmet_train = helmet_train.groupby('game_play').apply(lambda x:add_step_pct(x,cluster))\n        helmet_test.rename(columns = {'frame': 'step'}, inplace = True)\n        helmet_test = helmet_test.groupby('game_play').apply(lambda x:add_step_pct(x,cluster))\n        helmet_train = helmet_train[helmet_train['view']==helmet_view]\n        helmet_test = helmet_test[helmet_test['view']==helmet_view]\n\n        helmet_train['helmet_id'] = helmet_train['game_play'] + '_' + helmet_train['nfl_player_id'].astype(str) + '_' + helmet_train['step_pct'].astype(str)\n        helmet_test['helmet_id'] = helmet_test['game_play'] + '_' + helmet_test['nfl_player_id'].astype(str) + '_' + helmet_test['step_pct'].astype(str)\n\n        helmet_train = helmet_train[['helmet_id', 'left', 'width', 'top', 'height']].groupby('helmet_id').mean().reset_index()\n        helmet_test = helmet_test[['helmet_id', 'left', 'width', 'top', 'height']].groupby('helmet_id').mean().reset_index()\n        for player_ind in [1, 2]:\n            train['helmet_id'] = train['game_play'] + '_' + train['nfl_player_id_'+str(player_ind)].astype(str) + \\\n                                    '_' + train['step_pct'].astype(str)\n            test['helmet_id'] = test['game_play'] + '_' + test['nfl_player_id_'+str(player_ind)].astype(str) + \\\n                                    '_' + test['step_pct'].astype(str)\n\n            train = train.merge(helmet_train, how = 'left')\n            test = test.merge(helmet_test, how = 'left')\n\n            train.rename(columns = {i:i+'_'+helmet_view+'_'+str(cluster)+'_'+str(player_ind) for i in ['left', 'width', 'top', 'height']}, inplace = True)\n            test.rename(columns = {i:i+'_'+helmet_view+'_'+str(cluster)+'_'+str(player_ind) for i in ['left', 'width', 'top', 'height']}, inplace = True)\n\n            del train['helmet_id'], test['helmet_id']\n            gc.collect()\n\n            feature_cols += [i+'_'+helmet_view+'_'+str(cluster)+'_'+str(player_ind) for i in ['left', 'width', 'top', 'height']]\n        del helmet_train, helmet_test\n        gc.collect()","metadata":{"execution":{"iopub.status.busy":"2022-12-30T16:50:17.739897Z","iopub.execute_input":"2022-12-30T16:50:17.740511Z","iopub.status.idle":"2022-12-30T16:52:43.893689Z","shell.execute_reply.started":"2022-12-30T16:50:17.740473Z","shell.execute_reply":"2022-12-30T16:52:43.892692Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"# Fill missing values for the ground","metadata":{}},{"cell_type":"code","source":"for cluster in CLUSTERS:\n    for helmet_view in ['Sideline', 'Endzone']:\n        train.loc[train['G_flug']==True,'left_'+helmet_view+'_'+str(cluster)+'_2'] = train.loc[train['G_flug']==True,'left_'+helmet_view+'_'+str(cluster)+'_1']\n        train.loc[train['G_flug']==True,'top_'+helmet_view+'_'+str(cluster)+'_2'] = train.loc[train['G_flug']==True,'top_'+helmet_view+'_'+str(cluster)+'_1']\n        train.loc[train['G_flug']==True,'width_'+helmet_view+'_'+str(cluster)+'_2'] = 0\n        train.loc[train['G_flug']==True,'height_'+helmet_view+'_'+str(cluster)+'_2'] = 0\n        \n        test.loc[test['G_flug']==True,'left_'+helmet_view+'_'+str(cluster)+'_2'] = test.loc[test['G_flug']==True,'left_'+helmet_view+'_'+str(cluster)+'_1']\n        test.loc[test['G_flug']==True,'top_'+helmet_view+'_'+str(cluster)+'_2'] = test.loc[test['G_flug']==True,'top_'+helmet_view+'_'+str(cluster)+'_1']\n        test.loc[test['G_flug']==True,'width_'+helmet_view+'_'+str(cluster)+'_2'] = 0\n        test.loc[test['G_flug']==True,'height_'+helmet_view+'_'+str(cluster)+'_2'] = 0","metadata":{"execution":{"iopub.status.busy":"2022-12-30T16:52:43.895219Z","iopub.execute_input":"2022-12-30T16:52:43.895562Z","iopub.status.idle":"2022-12-30T16:52:43.901031Z","shell.execute_reply.started":"2022-12-30T16:52:43.895529Z","shell.execute_reply":"2022-12-30T16:52:43.899906Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"# Diffrence & Product features","metadata":{}},{"cell_type":"code","source":"cols = [i[:-2] for i in train.columns if i[-2:]=='_1' and i!='nfl_player_id_1']\ntrain[[i+'_diff' for i in cols]] = np.abs(train[[i+'_1' for i in cols]].values - train[[i+'_2' for i in cols]].values)\ntest[[i+'_diff' for i in cols]] = np.abs(test[[i+'_1' for i in cols]].values - test[[i+'_2' for i in cols]].values)\nfeature_cols += [i+'_diff' for i in cols]\n\ncols = ['x_position', 'y_position', 'speed', 'distance', 'direction', 'orientation', 'acceleration', 'sa']\ntrain[[i+'_prod' for i in cols]] = train[[i+'_1' for i in cols]].values * train[[i+'_2' for i in cols]].values\ntest[[i+'_prod' for i in cols]] = test[[i+'_1' for i in cols]].values * test[[i+'_2' for i in cols]].values\nfeature_cols += [i+'_prod' for i in cols]\n\nprint('number of features : ',len(feature_cols))\nprint('number of train data : ',len(train))","metadata":{"execution":{"iopub.status.busy":"2022-12-30T16:52:43.904500Z","iopub.execute_input":"2022-12-30T16:52:43.904986Z","iopub.status.idle":"2022-12-30T16:52:45.187355Z","shell.execute_reply.started":"2022-12-30T16:52:43.904950Z","shell.execute_reply":"2022-12-30T16:52:45.186378Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"# Train & Infer XGBoost model","metadata":{}},{"cell_type":"code","source":"# ==============================\n# training & inference\n# ==============================\n\ncfg.folds = get_groupkfold(train, 'contact', 'game_play', cfg.num_fold)\ncfg.folds.to_csv(os.path.join(cfg.EXP_PREDS, 'folds.csv'), index=False)\n\noof_pred[np.where(cond_dis_train)] = fit_xgboost(cfg, train[feature_cols], train['contact'], \n                                              cfg.xgb_params, add_suffix=\"_xgb_1st\")\nnp.save('oof_pred.npy',oof_pred)\nsub_pred = pred_xgboost(test.loc[cond_dis_test, feature_cols], cfg.EXP_MODEL, add_suffix=\"_xgb_1st\")","metadata":{"execution":{"iopub.status.busy":"2022-12-30T16:52:45.188964Z","iopub.execute_input":"2022-12-30T16:52:45.189625Z","iopub.status.idle":"2022-12-30T16:55:11.125540Z","shell.execute_reply.started":"2022-12-30T16:52:45.189579Z","shell.execute_reply":"2022-12-30T16:55:11.124470Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"# Submission","metadata":{}},{"cell_type":"code","source":"# ==============================\n# optimize\n# ==============================\ndef func(x_list):\n    score = matthews_corrcoef(train_y, oof_pred>x_list[0])\n    return -score\n\nx0 = [0.5]\nresult = minimize(func, x0,  method=\"nelder-mead\")\ncfg.threshold = result.x[0]\nprint(\"score:\", round(matthews_corrcoef(train_y, oof_pred>cfg.threshold), 5))\nprint(\"threshold\", round(cfg.threshold, 5))\ndel train\ngc.collect()\n\ntest = add_contact_id(test)\ntest['contact'] = 0\ntest.loc[cond_dis_test, 'contact'] = (sub_pred > cfg.threshold).astype(int)\ntest[['contact_id', 'contact']].to_csv('submission.csv', index=False)\ndisplay(test[['contact_id', 'contact']].head())","metadata":{"execution":{"iopub.status.busy":"2022-12-30T16:55:11.127358Z","iopub.execute_input":"2022-12-30T16:55:11.127798Z","iopub.status.idle":"2022-12-30T16:55:53.489871Z","shell.execute_reply.started":"2022-12-30T16:55:11.127745Z","shell.execute_reply":"2022-12-30T16:55:53.488804Z"},"trusted":true},"execution_count":null,"outputs":[]}]}