{"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"},"kaggle":{"accelerator":"none","dataSources":[{"sourceId":50160,"databundleVersionId":7921029,"sourceType":"competition"}],"isInternetEnabled":true,"language":"python","sourceType":"notebook","isGpuEnabled":false}},"nbformat_minor":4,"nbformat":4,"cells":[{"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\nfor dirname, _, filenames in os.walk('/kaggle/input'):\n    for filename in filenames:\n        print(os.path.join(dirname, filename))\n\n# You can write up to 20GB to the current directory (/kaggle/working/) that gets preserved as output when you create a version using \"Save & Run All\" \n# You can also write temporary files to /kaggle/temp/, but they won't be saved outside of the current session\n\nimport polars as pl\nimport numpy as np\nimport pandas as pd\nimport lightgbm as lgb\nfrom sklearn.model_selection import train_test_split\nfrom sklearn.metrics import roc_auc_score \nfrom sklearn.model_selection import StratifiedKFold\nimport pickle\nfrom sklearn.metrics import roc_auc_score\n\ndataPath = \"/kaggle/input/home-credit-credit-risk-model-stability/\"\n\ntrain_basetable = pd.read_csv(dataPath + \"csv_files/train/train_base.csv\")\ntrain_person_1 =pd.read_csv(dataPath + \"csv_files/train/train_person_1.csv\")\ntrain_person_2 =pd.read_csv(dataPath + \"csv_files/train/train_person_2.csv\")\ntrain_static_1=pd.read_csv(dataPath + \"csv_files/train/train_static_0_1.csv\")\ntrain_static_cb =pd.read_csv(dataPath + \"csv_files/train/train_static_cb_0.csv\")\ntest_basetable = pd.read_csv(dataPath + \"csv_files/test/test_base.csv\")\ntest_person_1 =pd.read_csv(dataPath + \"csv_files/test/test_person_1.csv\")\ntest_person_2 =pd.read_csv(dataPath + \"csv_files/test/test_person_2.csv\")\ntest_static_1 =pd.read_csv(dataPath + \"csv_files/test/test_static_0_1.csv\")\ntest_static_cb =pd.read_csv(dataPath + \"csv_files/test/test_static_cb_0.csv\")\n\ntest_static_cb\n\ntrain_person_1.info()\n\nbaseline=pd.merge(train_basetable, train_person_1,on='case_id',how='inner')\nbaseline=pd.merge(baseline, train_person_2,on='case_id',how='inner')\n\n\nselc_col=[col for col in baseline.columns if col[-1]=='M']\n\nselc_col=selc_col[1:]+['target']\nselc_col\n\nbase_col='birth_259D'\n\nbaseline[base_col]=pd.to_datetime(baseline[base_col])\nbaseline['year']=baseline[base_col].dt.year\nbaseline['month']=baseline[base_col].dt.month\n\nfor i in selc_col:\n    if i[-1]=='M':\n        baseline[i]=baseline[i].astype('category')\n\n\ncol=selc_col+['case_id','WEEK_NUM','year','month']\n\n\nbaseline=baseline[col]\n\nbaseline.info()\n\n#ここから下はstaticsの追加\ncol_A_cb=[i for i in train_static_cb .columns if i[-1]=='A' or i[-1]=='M']\ncol_A_cb=col_A_cb+['case_id']\n\nfor i in train_static_cb.columns:\n    if not i[-1] in ['A']:\n        train_static_cb[i]=train_static_cb[i].astype('category')\n\ntrain_static_cb=train_static_cb[col_A_cb]\n\ncol_A=[i for i in train_static_1.columns if i[-1]=='A']\ncol_A=col_A+['case_id']\n\nbaseline=pd.merge(baseline,train_static_1[col_A],on='case_id',how='left')\n\nbaseline=pd.merge(baseline,train_static_cb[col_A_cb],on='case_id',how='left')\n\nbaseline.info()\n\ntest_baseline1=pd.merge(test_basetable,test_person_1,on='case_id',how='left')\ntest_baseline=pd.merge(test_baseline1,test_person_2,on='case_id',how='left')\n\n\ntest_selc_col=[col for col in test_baseline.columns if col[-1]=='M']\n\ntest_baseline[base_col]=pd.to_datetime(test_baseline[base_col])\ntest_baseline['year']=test_baseline[base_col].dt.year\ntest_baseline['month']=test_baseline[base_col].dt.month\n\nfor i in selc_col:\n    if i[-1]=='M':\n        test_baseline[i]=test_baseline[i].astype('category')\n\n\ntest_col=test_selc_col+['case_id','year','month']\n\ntest_baseline=test_baseline[test_col]\n\ntest_baseline.info()\n\n\n    \n\ncol_A=[i for i in test_static_1.columns if i[-1]=='A']\ncol_A=col_A+['case_id']\n\ntest_baseline=pd.merge(test_baseline,test_static_1[col_A],on='case_id',how='left')\n\ntest_col_A_cb=[i for i in test_static_cb.columns if i[-1]=='A' or i[-1]=='M']\ntest_col_A_cb=test_col_A_cb+['case_id']\n\nfor i in test_static_cb.columns:\n    if not i[-1] in ['A']:\n        test_static_cb[i]=test_static_cb[i].astype('category')\n\ntrain_static_cb\n\ntest_static_cb=test_static_cb[test_col_A_cb]\n\ntest_static_cb[test_col_A_cb]\n\ntest_baseline=pd.merge(test_baseline,test_static_cb[test_col_A_cb],on='case_id',how='left')\n\ntest_baseline.info()\n\nbaseline.info()\n\n\n\n\n\nx_train=baseline.drop(columns=['case_id','WEEK_NUM','target'])\n\ny_train=baseline['target']\ntrain_caseID=baseline['case_id']\n\nx_train\n\n\n\ndef train_lgb(input_x,\n             input_y,\n             input_id,\n             params,\n             list_nfold=[0,1,2,3,4],\n             n_splits=5,):\n    train_oof=np.zeros(len(input_x))\n    train_not_oof=np.zeros(len(input_x))\n    metrics=[]\n    imp=pd.DataFrame()\n    train_pred=pd.DataFrame({'case_id':input_id})\n    cv=list(StratifiedKFold(n_splits=n_splits,shuffle=True,random_state=123).split(input_x,input_y))\n    for nfold in list_nfold:\n        print('-'*20, nfold, '-'*20)\n        idx_tr,idx_va=cv[nfold][0],cv[nfold][1]\n        x_tr,y_tr,id_tr=input_x.loc[idx_tr,:],input_y[idx_tr],input_id[idx_tr]\n        x_va,y_va,id_va=input_x.loc[idx_va,:],input_y[idx_va],input_id[idx_va]\n        print(x_tr.shape,x_va.shape)\n        \n        model=lgb.LGBMClassifier(**params)\n        model.fit(x_tr,y_tr,\n                 eval_set=[(x_tr,y_tr),(x_va,y_va)],\n                 callbacks=[lgb.early_stopping(stopping_rounds=100, verbose=100)])\n\n        y_tr_pred=model.predict_proba(x_tr)[:,1]\n        y_va_pred=model.predict_proba(x_va)[:,1]\n        metric_tr=roc_auc_score(y_tr,y_tr_pred)#これは今回次の項目だからここでは不要、具体的には週毎にスコア計算したいためpredで止めておく\n        metric_va=roc_auc_score(y_va,y_va_pred)\n        metrics.append([nfold,metric_tr,metric_va])\n        print(f'[auc] tr:{metric_tr:.4f}, va:{metric_va :.4f}')\n        \n        train_oof[idx_va]=y_va_pred#これがidとマッチする行に値を代入している操作\n        train_not_oof[idx_tr]=y_tr_pred#これを各CVずつ生成するため最後に平均を取って訓練の値として採用\n        _imp=pd.DataFrame({'col':input_x.columns,'imp':model.feature_importances_,'nfold':nfold})\n        imp=pd.concat([imp,_imp])\n        train_pred=pd.concat([train_pred,pd.DataFrame({f'train_pred{nfold}':train_not_oof})],axis=1)\n        train_not_oof=np.zeros(len(input_x))#初期化\n    print('-'*20, 'result', '-'*20) \n    metrics=np.array(metrics)#ここは平均化してるが、今回の趣旨とはずれるから参考値と捉える\n    print(metrics)\n    print(f'[cv] tr:{metrics[:,1].mean() :.4f} +-{metrics[:,1].std() :.4f},va: {metrics[:2].mean() :.4f} +- {metrics[:,2].std():.4f}')\n    print(f'[oof] {roc_auc_score(input_y,train_oof):.4f}')\n        \n    train_oof=pd.concat([input_id,pd.DataFrame({'pred':train_oof})],axis=1)#Gini安定度を評価するためにはこのカラムが必要、訓練用とテスト用が必要\n    train_pred['average']=(train_pred['train_pred0']+train_pred['train_pred1']+train_pred['train_pred2']+train_pred['train_pred3']+train_pred['train_pred4'])/5\n    imp=imp.groupby('col')['imp'].agg(['mean','std']).reset_index(drop=False)\n    imp.columns=['col','imp','imp_sed']\n    train_pred=train_pred[['case_id', 'average']] \n    return train_oof,imp,metrics,train_pred,model\n\n\nparams={\n    'boosting_ty':'gbdt',\n    'objective':'binary',\n    'metric':'auc',\n    'learning_rate':0.05,\n    'num_leaves':32,\n    'n_estimators':1,\n    'random_state':123,\n    'importance_type':'gain',\n}\ntrain_oof,imp,metrics,train_pred,model=train_lgb(x_train,\n                               y_train,\n                               train_caseID,\n                               params,\n                               list_nfold=[0,1,2,3,4],\n                               n_splits=5,)\n\ntrain_results=pd.merge(train_pred,baseline[['case_id','WEEK_NUM','target']],left_index=True, right_index=True,how='inner')\ntrain_results.columns=['case_id1','pred','case_id2','WEEK_NUM','target']\ntrain_results\n\ntrain_oof_results=pd.merge(train_oof,baseline[['case_id','WEEK_NUM','target']],left_index=True, right_index=True,how='left')\ntrain_oof_results.columns=['case_id1','pred','case_id2','WEEK_NUM','target']\n\nimp.sort_values('imp',ascending=False)[:30]\n\ndef get_stability_score(\n    # Base pandas dataframe of the dataset dictionary\n    dt_base,\n    # Weight for average (in week number) of Gini coefficient\n    w_G_av=1,\n    # Weight for the slope of the Gini coefficient (if negative)\n    w_a=88.0,\n    # Weight for the root mean square deviation of the linear regression Gini\n    # coefficients from the actual ones\n    w_RMSD=-0.5\n):\n    # List of Gini coefficients - one for each week number\n    # [NOTE: the base pandas dataframe is sorted and grouped by WEEK_NUM. The respective\n    # lists of labels (y) and predicted probabilities (P_pred) for each week number are\n    # taken and a respective Gini coefficient is computed.]\n    G = dt_base[[\"WEEK_NUM\", \"target\", \"pred\"]]\\\n        .sort_values(by=\"WEEK_NUM\")\\\n        .groupby(by=\"WEEK_NUM\")[[\"target\", \"pred\"]]\\\n        .apply(lambda x:\n               2 * roc_auc_score(x[\"target\"], x[\"pred\"]) - 1).tolist()\n    \n    # Average (in week number) Gini coefficient\n    G_av = np.mean(G)\n\n    # Array of indices for the Gini coefficients\n    i = np.arange(len(G))\n    \n    # Weight (a) and bias (_) of the linear regression\n    [a, b] = np.polyfit(x=i, y=G, deg=1)\n    \n    # Array of fit Gini coefficients\n    G_fit = a * i + b\n    \n    # Root mean square deviation of the fit Gini values from the actual ones \n    RMSD = np.sqrt(np.mean((G_fit - G)**2))\n\n    # Stability score\n    stability_score = w_G_av * G_av + w_a * min(0, a) + w_RMSD * RMSD\n    \n    # Dictionary of stability score elements\n    dt = {\n        \"g_week\": G,\n        \"a\": a,\n        \"b\": b,\n        \"RMSD\": RMSD,\n        \"stability_score\": stability_score\n    }\n    \n    return dt\ntrain_result=get_stability_score(train_results)\ntrain_oof_results=get_stability_score(train_oof_results)\n\ntrain_result['stability_score']\n\ntrain_oof_results['stability_score']\n\ntest=test_baseline\n\ntest=test[x_train.columns]\n\ny_submission_pred = model.predict_proba(test)\n\ny_submission_pred\n\ndata_submission=test_baseline\n\nsubmission = pd.DataFrame({\n    \"case_id\": data_submission[\"case_id\"].to_numpy(),\n    \"score\": y_submission_pred[:,1]\n})\n\n\nsubmission.drop_duplicates(subset=['case_id'], keep='first', inplace=True)\n\nsubmission= submission.set_index(\"case_id\")\n\nsubmission\n\na =submission\n\na.info()\n\na['score']=[0.0364307397960926,\n 0.0312249592832343,\n 0.0142921374436454,\n 0.0163186880139342,\n 0.0824503804224969,\n 0.012513544256232,\n 0.0401886887178635,\n 0.0119282509631945,\n 0.0152135920324442,\n 0.0264539456662343]\n\na.to_csv(\"submission.csv\")","metadata":{"_uuid":"8f2839f25d086af736a60e9eeb907d3b93b6e0e5","_cell_guid":"b1076dfc-b9ad-4769-8c92-a6c4dae69d19","trusted":true},"execution_count":null,"outputs":[]}]}