{"cells":[{"metadata":{"_uuid":"8f2839f25d086af736a60e9eeb907d3b93b6e0e5","_cell_guid":"b1076dfc-b9ad-4769-8c92-a6c4dae69d19","trusted":true},"cell_type":"code","source":"import numpy as np\nimport pandas as pd\n\nimport matplotlib.pyplot as plt\nimport seaborn as sns","execution_count":null,"outputs":[]},{"metadata":{"_uuid":"d629ff2d2480ee46fbb7e2d37f6b5fab8052498a","_cell_guid":"79c7e3d0-c299-4dcb-8224-4455121ee9b0","trusted":true},"cell_type":"code","source":"df_train = pd.read_csv('../input/osic-pulmonary-fibrosis-progression/train.csv')\ndf_test = pd.read_csv('../input/osic-pulmonary-fibrosis-progression/test.csv')\nsub = pd.read_csv('../input/osic-pulmonary-fibrosis-progression/sample_submission.csv')\n\nprint('Train shape: ', df_train.shape)\nprint('Number of unique customers in train: {}'.format(df_train['Patient'].nunique()))\nprint('Test shape:', df_test.shape)","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"# Format data to meet submission requirement\n## Train","execution_count":null},{"metadata":{"trusted":true},"cell_type":"code","source":"df_base = df_train.drop_duplicates(subset='Patient', keep='first')\ndf_base = df_base[['Patient', 'Weeks', 'FVC', \n                   'Percent', 'Age']].rename(columns={'Weeks': 'base_week',\n                                                      'Percent': 'base_percent',\n                                                      'Age': 'base_age',\n                                                      'FVC': 'base_FVC'})\ndf_base.head(3)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"# Remove the first visit (base visit)\ndf_train['visit'] = 1\ndf_train['visit'] = df_train[['Patient', 'visit']].groupby('Patient').cumsum()\ndf_train = df_train.loc[df_train['visit'] > 1, :]","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"# Merge with base info\ndf_train = pd.merge(df_train,\n                    df_base,\n                    on='Patient',\n                    how='left')\nprint(df_train.shape)\ndf_train.head(3)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"df_train['weeks_passed'] = df_train['Weeks'] - df_train['base_week']\ndf_train = pd.get_dummies(df_train, columns=['Sex', 'SmokingStatus'])","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"df_train.head()","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"## Submission","execution_count":null},{"metadata":{"trusted":true},"cell_type":"code","source":"sub['Patient'] = sub['Patient_Week'].apply(lambda x: x.split('_')[0])\nsub['Weeks'] = sub['Patient_Week'].apply(lambda x: x.split('_')[1]).astype(int)\nsub.head()","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"df_test = df_test.rename(columns={'Weeks': 'base_week', \n                                  'Percent': 'base_percent',\n                                  'Age': 'base_age',\n                                  'FVC': 'base_FVC'})\ndf_test = pd.merge(sub,\n                   df_test,\n                   on='Patient',\n                   how='right')\ndf_test = pd.get_dummies(df_test, columns=['Sex', 'SmokingStatus'])\ndf_test['weeks_passed'] = df_test['Weeks'] - df_test['base_week']\ndf_test.head()","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"missing_columns = np.setdiff1d(df_train.drop(['Patient', 'FVC', 'Percent', 'Age', 'visit'], axis = 1).columns, df_test.columns)\nif len(missing_columns) > 0:\n    print('/!\\ Missing columns in test: ', missing_columns)\n    for col in missing_columns:\n        df_test[col] = 0","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"# Baseline","execution_count":null},{"metadata":{"trusted":true},"cell_type":"code","source":"def OSIC_metric(y_true, y_pred, y_pred_std):\n    delta = np.clip(abs(y_true - y_pred), 0, 1000)\n    std_clipped = np.clip(y_pred_std, 70, np.inf)\n    return np.mean(-(np.sqrt(2)*delta/std_clipped) - np.log(np.sqrt(2)*std_clipped))","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"from sklearn.model_selection import GroupKFold\nfrom sklearn.metrics import mean_squared_error\nfrom sklearn.linear_model import BayesianRidge\n\nclass Model():\n    def __init__(self, model=BayesianRidge(), n_splits=5):\n        self.regressor = model\n        self.n_splits = n_splits\n        self.gkf = GroupKFold(n_splits=n_splits)\n        self.train_cols = ['Weeks', 'base_week', 'base_FVC', \n                           'base_percent', 'base_age', 'weeks_passed', 'Sex_Female',\n                           'Sex_Male', 'SmokingStatus_Currently smokes', \n                           'SmokingStatus_Ex-smoker', 'SmokingStatus_Never smoked']\n    \n    def fit(self, X, y):\n        self.regressor.fit(X, y)\n            \n    def predict(self, X):\n        pred = self.regressor.predict(X, return_std=True)        \n        return pred\n    \n    def fit_predict_cv(self, df, df_test=pd.DataFrame()):\n        \n        scores = np.zeros((self.n_splits, ))\n        oof = np.zeros((len(df), ))\n        oof_std = np.zeros_like(oof)\n        \n        if len(df_test) > 0:\n            pred_sub = np.zeros((len(df_test), self.n_splits))\n            pred_sub_std = np.zeros_like(pred_sub)\n        \n        target = 'FVC'\n        \n        for i, (train_idx, val_idx) in enumerate(self.gkf.split(df, groups=df['Patient'])):\n            X_train = df.loc[train_idx, self.train_cols]\n            y_train = df.loc[train_idx, target]\n            X_val = df.loc[val_idx, self.train_cols]\n            y_val = df.loc[val_idx, target]\n            \n            self.fit(X_train, y_train)\n            \n            pred_train, pred_train_std = self.predict(X_train)\n            pred_val, pred_val_std = self.predict(X_val)\n            \n            if len(df_test) > 0:\n                pred_sub[:, i], pred_sub_std[:, i] = self.predict(df_test[self.train_cols])\n            \n            oof[val_idx] = pred_val\n            oof_std[val_idx] = pred_val_std\n            print('Train score: {0:.2f} | Test score: {1:.2f}'.format(OSIC_metric(y_train, pred_train, pred_train_std),\n                                                                    OSIC_metric(y_val, pred_val, pred_val_std)))\n        print('OOF score: {0:.4f}'.format(OSIC_metric(df[target], oof, oof_std)))\n        res = dict()\n        res['oof'] = oof\n        res['oof_std'] = oof_std\n        \n        if len(df_test) > 0:\n            res['pred_sub'] = pred_sub.mean(axis=1)\n            res['pred_sub_std'] = pred_sub_std.mean(axis=1)\n        \n        return res","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"fvc_model = Model()","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"res = fvc_model.fit_predict_cv(df_train, df_test)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"plt.figure(figsize=(15, 4))\nplt.subplot(1, 2, 1)\nsns.distplot(df_train['FVC'], label='Ground Truth')\nsns.distplot(res['oof'], label='OOF')\nplt.title('FVC Distributions')\nplt.subplot(1, 2, 2)\nsns.distplot(res['oof_std'])\nplt.title('OOF Confidence Distribution')\nplt.tight_layout()\nplt.show()","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"# Submission","execution_count":null},{"metadata":{"trusted":true},"cell_type":"code","source":"df_test['FVC'] = res['pred_sub']\ndf_test['Confidence'] = res['pred_sub_std']\n\nsubmission = sub[['Patient_Week']]\nsubmission = pd.merge(submission,\n                      df_test[['Patient_Week', 'FVC', 'Confidence']],\n                      on='Patient_Week',\n                      how='left')\nsubmission.head()","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"submission.to_csv('submission.csv', index=False)","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}