{"cells":[{"metadata":{"_uuid":"8f2839f25d086af736a60e9eeb907d3b93b6e0e5","_cell_guid":"b1076dfc-b9ad-4769-8c92-a6c4dae69d19","trusted":true},"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\nimport pydicom\nimport matplotlib.pyplot as plt\n%matplotlib inline\n","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"import random\n","execution_count":null,"outputs":[]},{"metadata":{"_uuid":"d629ff2d2480ee46fbb7e2d37f6b5fab8052498a","_cell_guid":"79c7e3d0-c299-4dcb-8224-4455121ee9b0","trusted":true},"cell_type":"code","source":"train_df = pd.read_csv('../input/osic-pulmonary-fibrosis-progression/train.csv')\ntest_df = pd.read_csv('../input/osic-pulmonary-fibrosis-progression/test.csv')\nsub = pd.read_csv('../input/osic-pulmonary-fibrosis-progression/sample_submission.csv')\ntrain_df.head()","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"print('Shape of Training data: ', train_df.shape)\nprint('Shape of Test data: ', test_df.shape)\n\nprint(f\"The total patient ids are {train_df['Patient'].count()}\")\nprint(f\"Number of unique ids are {train_df['Patient'].value_counts().shape[0]} \")","execution_count":null,"outputs":[]},{"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=sub.drop([\"FVC\",\"Patient_Week\",\"Confidence\"],axis=1)\nsubmission=sub[[\"Patient\",\"Weeks\"]].merge(test_df,on=[\"Patient\",\"Weeks\"],how=\"left\")\nfor col in [\"Age\",\"Sex\",\"SmokingStatus\"]:\n    submission[col]=submission.groupby(\"Patient\")[col].apply(lambda x : x.ffill())\n    submission[col]=submission.groupby(\"Patient\")[col].apply(lambda x : x.bfill())\nsubmission.head()#.isnull().sum(),submission.shape","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"# Remove duplicated records--*not deduplication, remove test patients\n\nprint(train_df.shape)\ntrain_df=train_df.drop_duplicates(keep=False, subset=['Patient','Weeks'])\nprint(train_df.shape)\ntrain_df=train_df[train_df[\"Patient\"].isin(list(submission[\"Patient\"].unique()))==False]\nprint(train_df.shape)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"# Feat eng1\ntrain_df.reset_index(drop=True,inplace=True)\ntrain_df=train_df.sort_values(\"Weeks\")\ntrain_df[\"c_first_week\"]=train_df.groupby(\"Patient\")[\"Weeks\"].transform(\"min\")\ntrain_df.loc[train_df[\"c_first_week\"]==train_df[\"Weeks\"],\"c_first_FVC\"]=train_df[\"FVC\"]\ntrain_df[\"c_first_FVC\"]=train_df.groupby(\"Patient\")[\"c_first_FVC\"].apply(lambda x: x.ffill())\ntrain_df.loc[train_df[\"c_first_week\"]==train_df[\"Weeks\"],\"c_first_PCT\"]=train_df[\"Percent\"]\ntrain_df[\"c_first_PCT\"]=train_df.groupby(\"Patient\")[\"c_first_PCT\"].apply(lambda x: x.ffill())\ntrain_df[\"c_week_since_week\"]=train_df[\"Weeks\"]-train_df[\"c_first_week\"]\ntrain_df.head()","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"# train_df.isnull().sum()","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"# Feat eng1\nsubmission.reset_index(drop=True,inplace=True)\nsubmission.loc[submission[\"FVC\"].notnull(),\"c_first_week\"]=submission[\"Weeks\"]\nsubmission.loc[submission[\"FVC\"].notnull(),\"c_first_FVC\"]=submission[\"FVC\"]\nsubmission.loc[submission[\"Percent\"].notnull(),\"c_first_PCT\"]=submission[\"Percent\"]\n\nsubmission[\"c_first_FVC\"]=submission.groupby(\"Patient\")[\"c_first_FVC\"].apply(lambda x: x.ffill())\nsubmission[\"c_first_FVC\"]=submission.groupby(\"Patient\")[\"c_first_FVC\"].apply(lambda x: x.bfill())\n\nsubmission[\"c_first_PCT\"]=submission.groupby(\"Patient\")[\"c_first_PCT\"].apply(lambda x: x.ffill())\nsubmission[\"c_first_PCT\"]=submission.groupby(\"Patient\")[\"c_first_PCT\"].apply(lambda x: x.bfill())\n\nsubmission[\"c_first_week\"]=submission.groupby(\"Patient\")[\"c_first_week\"].apply(lambda x: x.ffill())\nsubmission[\"c_first_week\"]=submission.groupby(\"Patient\")[\"c_first_week\"].apply(lambda x: x.bfill())\n\nsubmission[\"c_week_since_week\"]=submission[\"Weeks\"]-submission[\"c_first_week\"]\nsubmission","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"# Feat eng 2\n# Categorical- OHE\ncatcols=[\"SmokingStatus\",\"Sex\"]\nuval_dicts={}\nfor col in catcols:\n    uvals=train_df[col].unique()\n    for val in uvals:\n#         print(col,val)\n        train_df.loc[train_df[col]==val,\"ohe_\"+val]=1\n        train_df.loc[train_df[col]!=val,\"ohe_\"+val]=0\n        \n        submission.loc[submission[col]==val,\"ohe_\"+val]=1\n        submission.loc[submission[col]!=val,\"ohe_\"+val]=0\n    uval_dicts[col]=uvals\n\n    \n    \nfrom sklearn import preprocessing\n# Numerical normalzie\n\nnumcols=['Weeks','Age','c_first_week', 'c_first_FVC', 'c_week_since_week', 'c_first_PCT']\nfor col in numcols:\n    le=preprocessing.StandardScaler()\n    le.fit(np.array(train_df[col].tolist()+submission[col].tolist()).reshape(-1,1))\n    train_df[\"n_\"+col]=le.transform(train_df[col].values.reshape(-1,1)).flatten()\n    submission[\"n_\"+col]=le.transform(submission[col].values.reshape(-1,1)).flatten()\n    \ntrain_df.head()\n\n\nsubmission.head()","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"submission.columns","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"train_df.columns","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"numerical_features=[ 'n_Weeks', 'n_Age', 'n_c_first_week', 'n_c_first_FVC',\n       'n_c_week_since_week', 'n_c_first_PCT',]\nbinary_features=['ohe_Never smoked', 'ohe_Ex-smoker', 'ohe_Currently smokes',\n       'ohe_Female', 'ohe_Male']\ntarget=\"FVC\"","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"# https://www.kaggle.com/andypenrose/osic-multiple-quantile-regression-starter/comments\nimport tensorflow as tf\nimport tensorflow.keras.backend as K\nimport tensorflow.keras.layers as L\nimport tensorflow.keras.models as M\nC1, C2 = tf.constant(70, dtype='float32'), tf.constant(1000, dtype=\"float32\")\n#=============================#\ndef score(y_true, y_pred):\n    tf.dtypes.cast(y_true, tf.float32)\n    tf.dtypes.cast(y_pred, tf.float32)\n    sigma = y_pred[:, 2] - y_pred[:, 0]\n    fvc_pred = y_pred[:, 1]\n    \n    #sigma_clip = sigma + C1\n    sigma_clip = tf.maximum(sigma, C1)\n    delta = tf.abs(y_true[:, 0] - fvc_pred)\n    delta = tf.minimum(delta, C2)\n    sq2 = tf.sqrt( tf.dtypes.cast(2, dtype=tf.float32) )\n    metric = (delta / sigma_clip)*sq2 + tf.math.log(sigma_clip* sq2)\n    return K.mean(metric)\n#============================#\ndef qloss(y_true, y_pred):\n    # Pinball loss for multiple quantiles\n    qs = [0.2, 0.50, 0.8]\n    q = tf.constant(np.array([qs]), dtype=tf.float32)\n    e = y_true - y_pred\n    v = tf.maximum(q*e, (q-1)*e)\n    return K.mean(v)\n#=============================#\ndef mloss(_lambda):\n    def loss(y_true, y_pred):\n        return _lambda * qloss(y_true, y_pred) + (1 - _lambda)*score(y_true, y_pred)\n    return loss\n#=================\n\n    \n    ","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"def make_model(num_inputs,num_blocks,units,dropout):\n    input_ = L.Input((num_inputs,), name=\"Patient\")\n    for _ in range(num_blocks):\n        if _==0:\n            x=L.Dense(units,activation=\"relu\")(input_)\n        else:\n            x=L.Dense(units,activation=\"relu\")(x)\n        x=L.BatchNormalization()(x)\n        x=L.Dropout(dropout)(x)\n    \n    p1 = L.Dense(3, activation=\"linear\", name=\"p1\")(x)\n    p2 = L.Dense(3, activation=\"relu\", name=\"p2\")(x)\n    preds = L.Lambda(lambda x: x[0] + tf.cumsum(x[1], axis=1), \n                     name=\"preds\")([p1, p2])\n    \n    model = M.Model(input_, preds, name=\"CNN\")\n    model.compile(loss=mloss(1), optimizer=\"adam\", metrics=[score])\n    return model","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"# net = make_model(11,num_blocks=1,units=300,dropout=0.2)\n# print(net.summary())\n# print(net.count_params())","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"def seed_everything(seed=2020):\n    random.seed(seed)\n    os.environ['PYTHONHASHSEED'] = str(seed)\n    np.random.seed(seed)\n    tf.random.set_seed(seed)\n    \nseed_everything(2020)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"X=train_df[numerical_features+binary_features].values\ny=train_df[target].astype(np.float32).values\n\nX_test=submission[numerical_features+binary_features].values\nX.shape,y.shape,X_test.shape","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"model_checkpoint=tf.keras.callbacks.ModelCheckpoint(\"./bestmodel.chkpt\",save_best_only=True,save_weights_only=True,\\\n                                                   mode=\"min\",monitor=\"val_score\")\nlr=tf.keras.callbacks.ReduceLROnPlateau(monitor='val_loss', factor=0.8, patience=30, verbose=0, mode='min',\n    min_delta=0.0001, cooldown=0, min_lr=0,)\nes=tf.keras.callbacks.EarlyStopping(\n    monitor='val_score', min_delta=0, patience=20, verbose=0, mode='min', restore_best_weights=True\n)\nCALLBACKS=[lr]","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"from sklearn import model_selection\nfrom tqdm import tqdm\nimport numpy as np\n\nNFOLDS=5\nBATCH_SIZE=100\nEPOCHS=300\nkf=model_selection.KFold(n_splits=NFOLDS, random_state=2020)\ndfs=[]\nvalidation=np.zeros((X.shape[0],3))\ntest_predictions=[]\nval_scores=[]\n\n\nfor i,(train_index,val_index) in enumerate(kf.split(X)):\n    print(\"Fold\")\n    print(i,len(train_index),len(val_index))\n    X_train=X[train_index]\n    y_train=y[train_index]\n    X_val=X[val_index]\n    y_val=y[val_index]\n    \n    model=make_model(X.shape[1],num_blocks=2,units=300,dropout=0.2)\n    history=model.fit(X_train,y_train,\\\n              validation_data=(X_val,y_val),\\\n              batch_size=BATCH_SIZE,epochs=EPOCHS,verbose=0,\\\n                     callbacks=CALLBACKS)\n    \n    y_pred=model.predict(X_val)\n    val_score=score(y_val.reshape(-1,1),y_pred).numpy()\n    print(f\"Fold {i} Val score {val_score}\")\n    val_scores.append(val_score)\n    \n    \n    test_predictions.append(model.predict(X_test))\n    \n    histdf=pd.DataFrame(history.history)\n    histdf[\"epoch\"]=history.epoch\n    dfs.append(histdf)\n    \n    validation[val_index,:]=y_pred\n#     break\n    \n    \n    \n\nprint(f\"mean OOF validation score: {np.mean(val_scores)} \")\nprint(f\"min OOF validation score: {np.min(val_scores)} \")\nprint(f\"max OOF validation score: {np.max(val_scores)} \")\n\n\nfindf=pd.DataFrame()\n\nfor col in dfs[0].columns:\n    vals=np.zeros((EPOCHS,))\n    for df in dfs:\n        vals+=df[col].values\n    findf[col]=vals/len(dfs)\nfindf[\"val_score\"].plot()\nplt.show()\nfindf[\"val_loss\"].plot()\nplt.show()","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"print(findf[\"val_score\"].tail())\nfindf[\"val_score\"].plot()","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"preds=np.zeros((X_test.shape[0],3))\nfor p in test_predictions:\n    preds += p / NFOLDS\nprint(preds.shape)\npreds[:3]","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"sub=submission[[\"Patient\",\"Weeks\"]]\nsub[\"FVC_median\"]=preds[:,1]\nsub[\"Confidence\"]=preds[:,2]-preds[:,0]","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"sub.isnull().sum()","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"sub.describe().T","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"sub[\"Patient_Week\"]=sub.apply(lambda x: x[\"Patient\"]+\"_\"+str(x[\"Weeks\"]),axis=1)\nsub","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"sub.rename(columns={\"FVC_median\":\"FVC\"})[[\"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":{"trusted":true},"cell_type":"code","source":"","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"![image.png](attachment:image.png)","attachments":{"image.png":{"image/png":"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"}}},{"metadata":{"trusted":true},"cell_type":"code","source":"def calculate_score(y_true, y_pred):\n    \n    sigma = y_pred[:, 2] - y_pred[:, 0]\n    fvc_pred = y_pred[:, 1]\n    print(sigma)\n    sigma_clip = sigma#np.clip(sigma,a_min=None,a_max= None)\n    print(pd.Series(sigma_clip).value_counts())\n    delta = np.abs(y_true - fvc_pred)\n    print(delta)\n#     delta = np.clip(delta,a_min=1000, a_max= None)\n    print(pd.Series(delta).value_counts())\n    sq2 = np.sqrt( 2)\n    print(sq2)\n    metric = (delta / sigma_clip)*sq2+np.log(sigma_clip* sq2) \n    print(metric)\n    print(sigma_clip* sq2)\n    print(np.log(sigma_clip* sq2))\n    return - np.nanmean(metric)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"# calculate_score(y,validation)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"","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}