{"cells":[{"metadata":{"_uuid":"8f2839f25d086af736a60e9eeb907d3b93b6e0e5","_cell_guid":"b1076dfc-b9ad-4769-8c92-a6c4dae69d19","trusted":true},"cell_type":"code","source":"import os, sys\nimport numpy as np\nimport pandas as pd\nimport torch\nimport torch.nn as nn\nfrom torch.utils.data import Dataset, DataLoader\nimport torch.nn.functional as F\nfrom sklearn import preprocessing","execution_count":null,"outputs":[]},{"metadata":{"_uuid":"d629ff2d2480ee46fbb7e2d37f6b5fab8052498a","_cell_guid":"79c7e3d0-c299-4dcb-8224-4455121ee9b0","trusted":true},"cell_type":"code","source":"DATA_DIR = \"/kaggle/input/osic-pulmonary-fibrosis-progression/\"\nMODEL_DIR = \"/kaggle/input/osicqrmodel/\"\nQUANTILES = [0.2, 0.5, 0.8]\n# columns to be scaled using min-max scaling\nSCALE_COLUMNS = ['Weeks', 'FVC', 'Age']\nSCALE_COLUMNS = ['Weeks_Passed', 'Base_FVC', 'Base_Percent', 'Base_Age']\nSEX_COLUMNS = ['Male', 'Female']\nSMOKING_STATUS_COLUMNS = ['Currently smokes', 'Ex-smoker', 'Never smoked']\n\n# create the FV (feature vector) using the scaled columns + other columns\nFV = SEX_COLUMNS + SMOKING_STATUS_COLUMNS + SCALE_COLUMNS\nDEVICE = torch.device('cuda') if torch.cuda.is_available() else torch.device('cpu')","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"# initialize the sklearn's min-max scaler\nMIN_MAX_SCALER = preprocessing.MinMaxScaler()","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"train_df = pd.read_csv(os.path.join(DATA_DIR, \"train.csv\"))\ntest_df = pd.read_csv(os.path.join(DATA_DIR, \"test.csv\"))\nsub_df = pd.read_csv(os.path.join(DATA_DIR, \"sample_submission.csv\"))\n# remove the duplicates from the train_df\ntrain_df.drop_duplicates(keep=False, inplace=True, subset=['Patient', 'Weeks'])","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"# extract the Patient and weeks from the Patient_Week column\nsub_df['Patient'] = sub_df['Patient_Week'].apply(lambda x: x.split('_')[0])\nsub_df['Weeks'] = sub_df['Patient_Week'].apply(lambda x: int(x.split('_')[-1]))\nsub_df.head()","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"# merge the sub_df with the test_df\nsub_df = sub_df.drop('FVC', axis=1).merge(test_df.drop('Weeks', axis=1), on='Patient')\nsub_df.head()","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"train_df['FROM'] = 'train'\ntest_df['FROM'] = 'val'\nsub_df['FROM'] = 'test'","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"combined_df = train_df.append([test_df, sub_df])","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"# initialize base_week column\ncombined_df['Base_Week'] = combined_df['Weeks']\n# make the weeks from sub_df to be np.nan so that when we calculate the base_week it comes from the test_df\ncombined_df.loc[combined_df['FROM'] == 'test', 'Base_Week'] = np.nan\n# now calculate the min for each patient group and set it to the Base_Week column\ncombined_df['Base_Week'] = combined_df.groupby('Patient')['Base_Week'].transform('min')","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"# get the base_df (where the Base_Week == the min_week we calculated) so that we can get the base_fvc, base_age and base_percentage\nbase_df = combined_df[combined_df['Weeks'] == combined_df['Base_Week']]","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"base_df.rename(columns={\n    'FVC': 'Base_FVC',\n    'Percent': 'Base_Percent',\n    'Age': 'Base_Age'\n}, inplace=True)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"combined_df = combined_df.merge(base_df[['Patient', 'Base_FVC', 'Base_Percent', 'Base_Age']], on='Patient', how='left')","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"combined_df['Weeks_Passed'] = combined_df['Weeks'] - combined_df['Base_Week']","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"combined_df.head()","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"MIN_MAX_SCALER.fit(combined_df[combined_df['FROM'] == 'train'][['Weeks_Passed', 'FVC', 'Percent', 'Age']])","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"combined_df.tail()","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"combined_df[['Weeks_Passed', 'Base_FVC', 'Base_Percent', 'Base_Age']] = MIN_MAX_SCALER.transform(combined_df[['Weeks_Passed', 'Base_FVC', 'Base_Percent', 'Base_Age']])","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"# convert categoricals into dummies\ncombined_df['Sex'] = pd.Categorical(combined_df['Sex'], categories=SEX_COLUMNS)\ncombined_df['SmokingStatus'] = pd.Categorical(combined_df['SmokingStatus'], categories=SMOKING_STATUS_COLUMNS)\ncombined_df = combined_df.join(pd.get_dummies(combined_df['Sex']))\ncombined_df = combined_df.join(pd.get_dummies(combined_df['SmokingStatus']))","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"combined_df.drop_duplicates(inplace=True)\ncombined_df.reset_index(drop=True)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"class PulmonaryDataset(Dataset):\n    def __init__(self, df, FV, test=False):\n        self.df = df\n        self.test = test\n        self.FV = FV\n\n    def __getitem__(self, idx):\n        return {\n            'features': torch.tensor(self.df[self.FV].iloc[idx].values),\n            'target': torch.tensor(self.df['FVC'].iloc[idx])\n        }\n\n    def __len__(self):\n        return len(self.df)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"class PulmonaryModel(nn.Module):\n    def __init__(self, in_features=9, out_quantiles=3):\n        super(PulmonaryModel, self).__init__()\n        self.fc1 = nn.Linear(in_features, 256)\n        self.fc2 = nn.Linear(256, 512)\n        self.fc3 = nn.Linear(512, 256)\n        self.fc4 = nn.Linear(256, out_quantiles)\n    \n    def forward(self, x):\n        x = F.relu(self.fc1(x))\n        x = F.relu(self.fc2(x))\n        x = F.relu(self.fc3(x))\n        x = self.fc4(x)\n        return x","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"new_test_df = combined_df[combined_df['FROM'] == 'test'].reset_index(drop=True)\ntest_dataset = PulmonaryDataset(new_test_df, FV)\n\ntest_data_loader = DataLoader(\n    test_dataset,\n    batch_size=10,\n    drop_last=False,\n    num_workers=2\n)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"models = []\nfor fold in range(5):\n    model = PulmonaryModel(len(FV))\n    checkpoint = torch.load(os.path.join(MODEL_DIR, f\"model_fold_{fold}.pt\"))\n    model.load_state_dict(checkpoint['model_state_dict'])\n    model.to(DEVICE)\n    models.append(model)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"avg_preds = np.zeros((len(test_dataset), len(QUANTILES)))\nwith torch.no_grad():\n    for model in models:\n        preds = []\n        for j, test_data in enumerate(test_data_loader):\n            features = test_data['features']\n            targets = test_data['target']\n\n            features = features.to(DEVICE).float()\n            targets = targets.to(DEVICE).float()\n\n            out = model(features)\n            preds.append(out)\n        preds = torch.cat(preds, dim=0).cpu().numpy()\n        avg_preds += preds\n    avg_preds /= len(models)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"avg_preds","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"new_test_df['FVC'] = avg_preds[:, 1]\nnew_test_df['Confidence'] = np.abs(avg_preds[:, 2] - avg_preds[:, 0])","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"new_test_df.head(25)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"new_test_df[['Patient_Week', 'FVC', 'Confidence']].to_csv('submission.csv', index=False)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"","execution_count":null,"outputs":[]}],"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}