{"cells":[{"metadata":{},"cell_type":"markdown","source":"# Script para generar la solución del Primer Benchmark de la Competencia\n\n## Si no presentaste aún tu primera solución, tenes la oportunidad de hacerlo en pocos Clicks!\n\n**Hola! **  \n  \nEste Script es un Ejemplo de Procesamiento de los Datos, Modelado y Generación de una Solución.\n\nAgregamos una pequeña explicación de lo que se hace en cada paso para ayudar a los que están comenzando ahora\n"},{"metadata":{},"cell_type":"markdown","source":"### Importamos las librerías que vamos a utilizar"},{"metadata":{"_uuid":"d629ff2d2480ee46fbb7e2d37f6b5fab8052498a","_cell_guid":"79c7e3d0-c299-4dcb-8224-4455121ee9b0","trusted":true},"cell_type":"code","source":"import pandas as pd\nfrom lightgbm import LGBMClassifier\nfrom sklearn.metrics import roc_auc_score\nfrom sklearn.model_selection import KFold\nimport re","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"### Lectura de las Bases\n\nObservamos los datos que tenemos disponibles en https://www.kaggle.com/c/interbank20/data\n\nVamos a trabajar ahora con todas las bases disponibles"},{"metadata":{"trusted":true},"cell_type":"code","source":"rcc_train = pd.read_csv(\"/kaggle/input/interbank20/rcc_train.csv\")\nse_train = pd.read_csv(\"/kaggle/input/interbank20/se_train.csv\", index_col=\"key_value\")\ncenso_train = pd.read_csv(\"/kaggle/input/interbank20/censo_train.csv\", index_col=\"key_value\")\ny_train = pd.read_csv(\"/kaggle/input/interbank20/y_train.csv\", index_col=\"key_value\").target\n\nrcc_test= pd.read_csv(\"/kaggle/input/interbank20/rcc_test.csv\")\nse_test= pd.read_csv(\"/kaggle/input/interbank20/se_test.csv\", index_col=\"key_value\")\ncenso_test= pd.read_csv(\"/kaggle/input/interbank20/censo_test.csv\", index_col=\"key_value\")","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"### Vamos a trabajar ahora con la base de **RCC**:\n* Discretizamos los días de atraso para poder manipularla mejor\n* Hacemos tablas cruzadas sobre key_value y cada variable de interés, utilizando distintas funciones de agregación sobre el saldo del producto"},{"metadata":{"trusted":true},"cell_type":"code","source":"bins = [-1, 0, 10, 20, 30, 60, 90, 180, 360, 720, float(\"inf\")]\nrcc_train[\"condicion\"] = pd.cut(rcc_train.condicion, bins)\nrcc_test[\"condicion\"] = pd.cut(rcc_test.condicion, bins)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"def makeCt(df, c, aggfunc=sum):\n    try:\n        ct = pd.crosstab(df.key_value, df[c].fillna(\"N/A\"), values=df.saldo, aggfunc=aggfunc)\n    except:\n        ct = pd.crosstab(df.key_value, df[c], values=df.saldo, aggfunc=aggfunc)\n    ct.columns = [f\"{c}_{aggfunc.__name__}_{v}\" for v in ct.columns]\n    return ct","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"train = []\ntest = []\naggfuncs = [len, sum, min, max]\nfor c in rcc_train.drop([\"codmes\", \"key_value\", \"saldo\"], axis=1):\n    print(\"haciendo\", c)\n    train.extend([makeCt(rcc_train, c, aggfunc) for aggfunc in aggfuncs])\n    test.extend([makeCt(rcc_test, c, aggfunc) for aggfunc in aggfuncs])","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"import gc\n\ndel rcc_train, rcc_test\ngc.collect()","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"train = pd.concat(train, axis=1)\ntest = pd.concat(test, axis=1)","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"### Incorporamos la Información adicional existente en las tablas socio económicas y del censo. Es un simple join porque ambas tienen key_value únicos\n#### Por el momento no incorporamos la información tributaria porque requiere un tratamiento más complejo que queda para futuras revisiones"},{"metadata":{"trusted":true},"cell_type":"code","source":"train = train.join(censo_train).join(se_train)\ntest = test.join(censo_test).join(se_test)\n\ndel censo_train, se_train, censo_test, se_test\ngc.collect()","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"### Por la naturaleza de las variables creadas, nos aseguramos que solo se utilicen variables existentes en ambos conjuntos de datos (train y test)"},{"metadata":{"trusted":true},"cell_type":"code","source":"keep_cols = list(set(train.columns).intersection(set(test.columns)))\ntrain = train[keep_cols]\ntest = test[keep_cols]\nlen(set(train.columns) - set(test.columns)) , len(set(test.columns) - set(train.columns))","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"test = test.rename(columns = lambda x:re.sub('[^A-Za-z0-9_-]+', '', x))\ntrain = train.rename(columns = lambda x:re.sub('[^A-Za-z0-9_-]+', '', x))","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"folds = [train.index[t] for t, v in KFold(5).split(train)]","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"### Entrenamiento del Modelo\n\nPara entrenar nuestro modelo vamos a usar LightGBM. A diferencia del notebook anterior, esta vez vamos a agregar la optimización de hyper-parámetro. Se usan sólo dos con algunos pocos posibles valores, a modo de ejemplo para que los participantes lo puedan ir mejorando. "},{"metadata":{"trusted":true},"cell_type":"code","source":"from sklearn.model_selection import ParameterGrid\n\nparams = ParameterGrid({\"min_child_samples\": [150, 250, 500, 1000], \"boosting_type\": [\"gbdt\", \"goss\"]})","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"best_score = 0\nbest_probs = []\nfor param in params:\n    test_probs = []\n    train_probs = []\n    p  = \"///\".join([f\"{k}={v}\" for k, v in param.items()])\n    print(\"*\"*10, p, \"*\"*10)\n    for i, idx in enumerate(folds):\n        Xt = train.loc[idx]\n        yt = y_train.loc[Xt.index]\n\n        Xv = train.drop(Xt.index)\n        yv = y_train.loc[Xv.index]\n\n        learner = LGBMClassifier(n_estimators=1000, **param)\n        learner.fit(Xt, yt,  early_stopping_rounds=10, eval_metric=\"auc\",\n                    eval_set=[(Xt, yt), (Xv, yv)], verbose=False)\n        test_probs.append(pd.Series(learner.predict_proba(test)[:, -1], index=test.index, name=\"fold_\" + str(i)))\n        train_probs.append(pd.Series(learner.predict_proba(Xv)[:, -1], index=Xv.index, name=\"probs\"))\n\n    test_probs = pd.concat(test_probs, axis=1).mean(axis=1)\n    train_probs = pd.concat(train_probs)\n    score = roc_auc_score(y_train, train_probs.loc[y_train.index])\n    print(f\"roc auc estimado para {p}: {score}\")\n    if score > best_score:\n        print(\"*\"*10, f\"{p} es el nuevo mejor modelo\", \"*\"*10)\n        best_score = score\n        best_probs = test_probs\n    ","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"### Guardado de las predicciones modelo para hacer la presentación\n\nFinalmente creamos el archivo CSV que podemos subir como nuestra Solución a la competencia"},{"metadata":{"trusted":true},"cell_type":"code","source":"best_probs.name = \"target\"\nbest_probs.to_csv(\"benchmark2.csv\")","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}