{"cells":[{"metadata":{},"cell_type":"markdown","source":"Este script tiene como objetivo crear nuevos features."},{"metadata":{"trusted":true},"cell_type":"code","source":"# Se importan las librerias básicas para el manejo de los DataFrame\nimport pandas as pd\nimport numpy as np\nseed = 99","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"# cargar pageviews\npageviews = pd.concat([ pd.read_csv('../input/banco-galicia-dataton-2019/pageviews.zip', parse_dates=[\"FEC_EVENT\"]),\n                      pd.read_csv('../input/banco-galicia-dataton-2019/pageviews_complemento.zip', parse_dates=[\"FEC_EVENT\"]) ], sort=False)\n\npageviews['mes'] = pageviews['FEC_EVENT'].apply( lambda x : x.month ) # crea la columna mes\npageviews['diasemana'] = pageviews['FEC_EVENT'].apply( lambda x : x.weekday() ) # crea la columna que indica el dia de la semana que hizo la operacion.\n\nprint('Datos iniciales del archivo pageviews:')\npageviews.head()","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"Una vez cargado pageviews que es la data principal, se ve que hay tres features que hacen referencia al CONTENT: (CONTENT_CATEGORY, CONTENT_CATEGORY_TOP, CONTENT_CATEGORY_BOTTOM), donde los últimos dos hacen la construcción del primero, así que solo vamos a cargar el primero y desglosarlo para obtener toda la información adicional que podamos. "},{"metadata":{"trusted":true},"cell_type":"code","source":"# cargar content category\ncontent = pd.read_csv('../input/banco-galicia-dataton-2019/CONTENT_CATEGORY.zip')\n\nprint('Datos iniciales del archivo content category:')\nprint(content.head())\n\n# Realizar reemplazo para alinear la data\ncontent['CONTENT_CATEGORY_descripcion'] = content['CONTENT_CATEGORY_descripcion'].str.replace('ERRORES', 'ERROR')\ncontent['CONTENT_CATEGORY_descripcion'] = content['CONTENT_CATEGORY_descripcion'].str.replace('GALICIA', '')\ncontent['CONTENT_CATEGORY_descripcion'] = content['CONTENT_CATEGORY_descripcion'].str.replace('NO CATEGORY ASSIGNED > UPGRADE DE PAQUETE : CONFIRMACION',\n                                                                                              'NO CATEGORY ASSIGNED > HB:NCA:NCA:NCA:UPGRADEDEPAQUETE : CONFIRMACION')\ncontent['CONTENT_CATEGORY_descripcion'] = content['CONTENT_CATEGORY_descripcion'].str.replace('WEB:RRHH', 'WEB:INSTITUCIONAL:RRHH')\n\n# Realiza split en columnas de la descipcion de content category                                                                                              \ncontent['split'] = content['CONTENT_CATEGORY_descripcion'].str.split(' > :| : | > |:')\n\n# Organizar la data para que quede en una estructura homogénea\nfor i in content.index:\n    if content['split'][i][0] != 'NO CATEGORY ASSIGNED':\n        content['split'][i][0:0] = ['CATEGORY ASSIGNED']\n\nfor i in content.index:\n    if len(content['split'][i]) > 2:\n        if content['split'][i][2] == 'PERSONAS':\n            content['split'][i].insert(2,'ONLINE')\n            content['split'][i].insert(3,'WEB')\n        elif content['split'][i][2] == 'PP':\n            content['split'][i].pop(-1)\n        elif content['split'][i][2] == 'TC':\n            content['split'][i].pop(2)\n        elif content['split'][i][2] == 'UPGRADE':\n            content['split'][i].pop(-1)\n        \nfor i in content.index:\n    if len(content['split'][i]) > 5:\n        if content['split'][i][5] == 'ERROR':\n            content['split'][i].pop()\n            content['split'][i][2] = 'ERROR'\n            \nfor i in content.index:\n    try:\n        if content['split'][i][5].find('BENEFICIOSYPROMO') >= 0:\n            content['split'][i].pop(6)\n        if content['split'][i][5].find('PRODUCTOSYS') >= 0:\n            content['split'][i].pop(6)\n        if content['split'][i][5].find('FICHAS') >= 0:\n            content['split'][i].pop(5)\n        if content['split'][i][5].find('TARJETARURAL') >= 0:\n            content['split'][i].pop(-1)\n    except IndexError:\n        pass\n\n# Separar los datos de content en columnas            \ncontent[['a','b','c','d','e','f','g']] = pd.DataFrame(content['split'].values.tolist(), index= content.index)\n\n# Una vez tenemos los datos organizados, existen varias filas que son idénticas, esta información la podemos agrupar para tener en la tabla original menos valores únicos\n# Crea el diccionario repcontent con el content category para reemplazar en la data\n\ncols_t = ['CONTENT_CATEGORY_descripcion', 'CONTENT_CATEGORY', 'split']\nrepcontent = dict()\ni = 0\nfor npage in list(content[content.drop(cols_t, axis=1).duplicated(keep=False)]['CONTENT_CATEGORY']):\n    i += 1\n    for npage2 in list(content[content.drop(cols_t, axis=1).duplicated(keep=False)]['CONTENT_CATEGORY'])[i:]:\n        n = content[content['CONTENT_CATEGORY'] == npage].drop(cols_t,axis=1).merge(content[content['CONTENT_CATEGORY'] == npage2].drop(cols_t,axis=1)).shape[0]\n        if n == 1:           \n            if (npage == 4) | (npage == 16):\n                continue\n            if npage2 in repcontent:\n                continue\n            else:\n                repcontent[npage2] = npage\n\ncontent.drop(['CONTENT_CATEGORY_descripcion', 'a', 'b', 'c', 'd', 'e', 'f', 'g'],axis=1, inplace=True) # se borran columnas que ya no se necesitan\n\nprint('Datos finales del archivo content category:')\nprint(content.head())","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"Como pueden ver la data de CONTENT_CATEGORY ahora esta mas estructurada. De todos los archivos adicionales PAGE tiene igualmente información complementaria de la acción que realizó el usuario, con el objetivo de unir esta información a de del CONTENT, se procede a realizar una reestructuración de esta data."},{"metadata":{"trusted":true},"cell_type":"code","source":"# cargar archivo page\npage = pd.read_csv('../input/banco-galicia-dataton-2019/PAGE.zip')\n\nprint('Datos iniciales del archivo page:')\nprint(page.head())\n\n# Crear diccionario para remplazar valores con el objetivo de generalizar y limpiar los datos\nreplace_dict = {\n                'HB :  :':'HB:NCA:NCA:NCA:', 'HB :':'HB:NCA:NCA:', 'HC :':'HC:NCA:NCA:NCA:', '^/':'NCA/NCA/NCA/', '^0':'', ' ':'', '(':'',  ')':'', \n                '-':'_', '2018':'', '%C3%A9MINENT':'EMINENT', '%20/%20%3CBR%':'', '%20/%20%3CBR':'', 'A%20PAGAR:%20':'PAGAR','VISAHOME':'TARJETAS', \n                '_VALIDACION':'/VALIDACION',  '/SELECCIONAR_':'/SELECCIONAR/',  'USUARIO_':'USUARIO/',  'UPGRADE_':'UPGRADE/',   '_AVISO':'/AVISO', \n                'TYC_BAJAPRODUCTO':'BAJAPRODUCTO/TYC','_TYC':'TYC','TITULAR_':'TITULAR/','TARJETASAS':'TARJETAS','TADEC':'TAC','2017':'', '15$':'',\n                '_SOLICITAR':'/SOLICITAR',  '/PREGUNTAS_':'/PREGUNTAS/',  '_PREGUNTA_':'/PREGUNTAS_',  'CONFIRMACION':'CONFIRMAR', '_AFIP':'/AFIP',\n                'PRE_CONFIRMAR':'PRECONFIRMAR','OPRECONFIRMAR':'O/PRECONFIRMAR', '_PRECONFIRMACI$':'/PRECONFIRMAR','_PRECONFIRMA$':'/PRECONFIRMAR', \n                '_PRECONFIRMAR':'/PRECONFIRMAR', '_NUMERO':'/NUMERO',  '_NUEVO':'/NUEVO', '_MOTIVO':'/MOTIVO', 'O_MONTO':'O/MONTO', ':HOME':':HOM',\n                'R_MONTO$':'R/MONTO','A_MONTO$':'A/MONTO','_MONEDA':'/MONEDA','_METODO':'/METODO','_INGRESO$':'/INGRESO','_INGRESAR_':'/INGRESAR_',\n                '_IDENTIFI':'/IDENTIFI', 'HIPOTECARIO_':'HIPOTECARIO/', 'HACETEMOVE':'HACETECLIENTE','HACETEGALICIA':'HACETECLIENTE','%20Y%20':'Y',\n                '_FIRMA':'/FIRMA', '_FIMA_':'_FIMA/', '_EXITO':'/EXITO', '_ELECCION':'/ELECCION',  '_DELIVERY':'/DELIVERY',  '_DATOS_P':'/DATOS_P',\n                '_CONTACTO':'/CONTACTO', '_CONFIRMACIO$':'/CONFIRMAR', '_CONFIRMAR':'/CONFIRMAR', '_CONFIR$':'/CONFIRMAR', 'MOVI':'MOV',  'BUP':'',\n                '_CONCEPTO':'/CONCEPTO',  '_CODIGO':'/CODIGO',  'S_CANTIDAD':'S/CANTIDAD',  '_CAJEROS':'/CAJEROS',   '_ADICIONALES':'/ADICIONALES',\n                '/BENEFICIOS':'/BENEFICIOSYPROMOCIONES', '_BENEFICIARIO':'/BENEFICIARIO',  'BANCO':'',  '_AUTORIZADOS':'/AUTORIZADOS',  '/1521':'',\n                '_ALERTA':'/ALERTA', '_ADHERIR':'/ADHERIR', '/PREFER':'/PREFERPREFER', 'WEB:PREFER':'WEB:PREFERPREFER','PROYECTO':'PROYEC', '_':'',\n                'WEB:PERSONAS':'WEB:PERSONASPERSONAS', 'PEDITUSPRODUCTOS':'PEDIDOSHOM', 'OFFICEBANKIN':'', 'WEB:MOVE':'WEB:MOVEMOVE', 'GALICI$':'',\n                'WEB:EMINENT':'WEB:EMINENTEMINENT',  'UNHANDLEDERROR':'ERROR', 'TOMAIL':'TO/MAIL', 'TARJETASR':'TARJETAS/R',  'PAQUETES':'PAQUETE',\n                'FIRMATERMINOSYCONDICIONE':'TYC', 'TERMINOSYCONDICIONES':'TYC','TERMINOSYCONDICIONE':'TYC','TERMINOSYCONDICION':'TYC','/TYC':'TYC', \n                'TYC':'/TYC', 'SW$':'', 'SUCURSAL99':'SUCURSALES','SUCURSAL$':'SUCURSALES','SPOTIF':'SPOTIFY','SOLICITARHIPOTECARIO':'HIPOTECARIO',\n                '/RROR/':'/ERROR/', 'RENOVACIONINICIO':'RENOVACION', 'PRIMER/INGRESO':'PRIMERINGRESO', 'PREFER$':'', 'PERSONAS$':'','MOVIMI':'MOV',\n                'SUCURSALESYCAJEROS':'SUCURSAL', 'PROYECTO':'PROYEC', 'PRECONFIRMARREPOSICION':'REPOSICION',  'CONFIRMARREPOSICION' : 'REPOSICION',\n                'PRECONFIRMAR/NUEVO':'PRECONFIRMAR', 'FONDOS':'FONDO',  'PEDIDOPRESTAMOSPERSONALES':'PRESTAMOS',  'PEDIDOS:':'PEDIDOS', 'MOVE$':'',\n                'OPERACIONES:':'OPERACIONES',  'OBJETIVO$':'OBJETIV','MAS$':'', 'NOMINALES$':'NOMINALE',  'NOLATENES':'NOLARECORDAS',  'GALIC$':'',\n                'NOLARECUERDA':'NOLARECORDAS', 'MONTOOBJETIV$':'MONTO','MOMENTONO':'ERRO', 'MESSAGE':'MENSAJE', 'LOGBB':'LOGIN', 'ERRORES':'ERROR',\n                'JAVASCRIPT:VOID':'JAVASCRIPT', 'INVERSFSIONES':'INVERSIONES','GALI$':'',  'INVERSIONES$':'INVERSION',  'INICIO:RE$':'INICIO:RECU',\n                'INGRESARDOMICILI$':'INGRESARDOMICILIO', 'INICIO:R$':'INICIO:RECU', 'GAL$':'', 'CUENTGALICIA':'CUENTAS', 'FUERADESERVICIO':'ERROR',\n                'GALICIA':'',  'INICIONUEVOCONTACTOC' : 'NUEVOCONTACTO/C',  'FILE/DOWNLOAD':'DOWNLOADFILE',   'FECHANACIMIENTO':'/FECHANACIMIENTO',\n                'FECHAOBJETIV':'/FECHAOBJETIV', 'DECRE':'D',  'ERORIN':'ERROR',  'EGOORROR':'ERROR',  'EMINENT2':'', 'EMINENT$' : '', 'EMINEN$':'',\n                'EMINE$':'', 'EMINET$':'', 'EMI$':'', 'EMAIL':'/EMAIL', 'DETAL$':'DETALLE',  'DETA$':'DETALLE',  'DESCRIPCIONSEGURO':'DESCRIPCION',  \n                'DESCRIPCIONPRESTAMO':'DESCRIPCION','ALERTAS':'ALERTA', 'CONVENIOSRURAL':'CONVENIOS', 'TOCONFIRMAR':'TO/CONFIRMAR', 'CARREFOUR':'', \n                'CONFIRMAR/ALERTA':'CONFIRMAR',  'CARGARMONTOCUENTASPROPIAS':'CUENTASPROPIAS/MONTO',  'BONOSACCIONES':'BONOSYACCIONES',   '\\.$':'',\n                'APERTURADEC':'APERTURAD','APERTURADE':'APERTURAD' #  \n               }\n\n# Realizar reemplazo para arreglar los datos\nfor old, new in replace_dict.items():\n    page['PAGE_descripcion'] = page['PAGE_descripcion'].str.replace(old, new)\n    \n# crea diccionario que corrige el content en la data\nfixpage = dict()\nfor i in page.index:\n    if ('HB' in page['PAGE_descripcion'][i]) and ('ERRO' in page['PAGE_descripcion'][i]):\n        fixpage[i+1] = 5\n    elif ('HB' in page['PAGE_descripcion'][i]) and ('PAQUETE' in page['PAGE_descripcion'][i]):\n        continue\n    elif ('HB' in page['PAGE_descripcion'][i]) and ('PRESTAMOS' in page['PAGE_descripcion'][i]):\n        continue\n    elif 'HB' in page['PAGE_descripcion'][i]:\n        fixpage[i+1] = 4\n\n# realiza split1 en columnas de la descipcion de page\npage['split1'] = page['PAGE_descripcion'].str.split('://|/|:') # check 982\n\n# Organiza los datos de page\nfor i in page.index:\n    \n    if (page['split1'][i][0] == 'WEB' or page['split1'][i][0] == 'RURAL' or page['split1'][i][0] == 'RRHH' or page['split1'][i][0] == 'PREFER' or\n        page['split1'][i][0] == 'PERSONAS' or page['split1'][i][0] == 'PAGINA' or page['split1'][i][0] == 'NEGOCIOSYPYMES' or \n        page['split1'][i][0] == 'MOVE' or page['split1'][i][0] == 'INSTITUCIONAL' or page['split1'][i][0] == 'HB' or page['split1'][i][0] == \n        'EMPRESAS' or page['split1'][i][0] == 'EMINENT' or page['split1'][i][0] == 'CORPORATIVAS' or page['split1'][i][0] == \n        'BUSCADORDECAJEROSYSUCURSALES' or page['split1'][i][0] == 'PRODUCTOSYSERVICIOS' or page['split1'][i][0] == 'BENEFICIOSYPROMOCIONES'):\n        page['split1'][i].pop(0)\n    \n    if page['split1'][i][-1] == '':\n        page['split1'][i].pop(-1)\n    \n    try:\n            \n        if page['split1'][i][0] == 'HC':\n            page['split1'][i].pop(0)\n            if page['split1'][i][0].startswith('STEP') == True:\n                page['split1'][i].pop(0)\n            if page['split1'][i][0] == 'ERROR':\n                page['split1'][i].insert(0,'NCA')\n            if page['split1'][i][4].startswith('PASO') == True:\n                page['split1'][i].pop(4)\n            if page['split1'][i][4] == 'ERROR':\n                page['split1'][i].pop(5) #*# borra las explicaciones del error\n                \n        if page['split1'][i][3].find('INICI') >= 0:\n            page['split1'][i][3] = 'INICIO'\n            \n        if page['split1'][i][3].find('OGIN') >= 0:\n            page['split1'][i][3] = 'LOGIN'\n            \n        if page['split1'][i][3].find('EMPRESA') >= 0:\n            page['split1'][i].pop(0)    \n        if page['split1'][i][3].find('USER') >= 0:\n            page['split1'][i][3] = 'USERS'\n            page['split1'][i].pop(0)\n            if page['split1'][i][3].find('LOGI') >= 0:\n                page['split1'][i][3] = 'LOGIN'\n        if page['split1'][i][3].find('PREFER') >= 0:\n            page['split1'][i].pop(0)  \n            \n        if page['split1'][i][3].find('ERR') >= 0:\n            page['split1'][i][3] = 'ERROR' \n            if page['split1'][i][2] == 'NCA':\n                page['split1'][i][0] = 'ERROR'\n                page['split1'][i].insert(3,'NCA')\n                page['split1'][i].pop(5) #*# borra las explicaciones del error\n            else:\n                page['split1'][i].pop(0)\n                page['split1'][i].insert(2,'NCA')\n        \n        if (page['split1'][i][4].startswith('ERRO') == True) and (page['split1'][i][0] == 'NCA'):\n            page['split1'][i][4] = 'ERROR' \n            page['split1'][i].pop(0)\n            page['split1'][i].pop(4) #*# borra las explicaciones del error   \n            \n        if page['split1'][i][4].startswith('PASO') == True:\n            page['split1'][i].pop(5) #*# borra las explicaciones del paso\n            \n        if page['split1'][i][4].startswith('ALERT') == True:\n            page['split1'][i].pop(5) #*# borra las explicaciones de alertas\n\n        if page['split1'][i][4].find('INICIO') >= 0:\n            page['split1'][i][4] = 'INICIO'\n       \n        if (page['split1'][i][4].startswith('PRECONFIRMAR') == True) and (page['split1'][i][4] != 'PRECONFIRMAR'):\n            page['split1'][i][4] = page['split1'][i][4][12:]\n            page['split1'][i].append('PRECONFIRMAR')\n        \n        if (page['split1'][i][4].startswith('CONFIRMAR') == True) and (page['split1'][i][4] != 'CONFIRMAR'):\n            page['split1'][i][4] = page['split1'][i][4][9:]\n            page['split1'][i].append('CONFIRMAR')\n      \n        if page['split1'][i][5].find('PAGAR') >= 0:\n            page['split1'][i][5] = 'PAGAR'\n\n        if page['split1'][i][-1].isdigit():\n            page['split1'][i].pop(-1)\n            \n        if page['split1'][i][-1] == '':\n            page['split1'][i].pop(-1)\n\n    except IndexError:\n        pass\n\n# Separar los datos de page en columnas    \npage[['a','b','c','d','e','f']] = pd.DataFrame(page['split1'].values.tolist(), index= page.index)\n\n#crea el diccionario reppage con el page para reemplazar en la data valores repetidos\ncols_t = ['PAGE_descripcion', 'PAGE', 'split1'] \nreppage = dict()\ni = 0\nfor npage in list(page[page.drop(cols_t, axis=1).duplicated(keep=False)]['PAGE']):\n    i += 1\n    for npage2 in list(page[page.drop(cols_t, axis=1).duplicated(keep=False)]['PAGE'])[i:]:\n        n = page[page['PAGE'] == npage].drop(cols_t,axis=1).merge(page[page['PAGE'] == npage2].drop(cols_t,axis=1)).shape[0]\n        if n == 1:           \n            if npage2 in reppage:\n                continue\n            else:\n                reppage[npage2] = npage\n\npage.drop(['PAGE_descripcion', 'a', 'b', 'c', 'd', 'e', 'f',],axis=1, inplace=True) # se borran columnas que ya no se necesitan\n\nprint('Datos finales del archivo page:')\nprint(page.head())","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"# Aplicamos los diccionarios que creamos para unificar la data repetida que surgio al organizar la data\nfor i in fixpage:\n    pageviews.loc[pageviews['PAGE'] == i, 'CONTENT_CATEGORY'] = fixpage[i]\n    pageviews.loc[pageviews['PAGE'] == i, 'CONTENT_CATEGORY_BOTTOM'] = fixpage[i]\n\nfor i in repcontent:\n    pageviews.loc[pageviews['CONTENT_CATEGORY'] == i, 'CONTENT_CATEGORY_BOTTOM'] = repcontent[i]\n    pageviews.loc[pageviews['CONTENT_CATEGORY'] == i, 'CONTENT_CATEGORY'] = repcontent[i]\n    \nfor i in reppage:\n    pageviews.loc[pageviews['PAGE'] == i, 'PAGE'] = reppage[i]","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"pageviews = pd.merge(pageviews,content) # se une la columna split a pageviews\npageviews = pd.merge(pageviews,page) # se une la columna split1 a pageviews\npageviews['s_total'] = pageviews['split'] + pageviews['split1'] # se unen la columnas split y split1 en una sola\n# La siguiente línea separa en columnas cada dato de la lista de s_total, aquí se entiende el objetivo de la \n# organización que se realizó, quedando primero si tiene o no categoría definida, luego su tipo (banca, HB, HC, …),\n# luego si fue un error o una acción online, luego esta web que es una constante por lo que más adelante no la \n# tendremos en cuenta, TyPEr define el tipo de usuario (persona, empresa, negocios, …), ACT específica la acción del \n# usuario (login, consulta, pedido de préstamo, …), A1 y A2 especifica información adicional de la acción del usuario.   \npageviews[['Cat','TyCat','on_err','web','TyPer','Act','A1','A2']] = pd.DataFrame(pageviews['s_total'].values.tolist(), index= pageviews.index)\npageviews.drop(['split1','split','web'], axis=1, inplace=True) # Se borran las columnas que ya no se necesitan\npageviews['on_err'].replace(r'^NCA$', 'ONLINE', inplace=True, regex=True)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"# cargar archivo devicedata\ndevicedata = pd.read_csv('../input/banco-galicia-dataton-2019/device_data.zip', parse_dates=[\"FEC_EVENT\"])\n\ndata = pageviews.merge( devicedata, how=\"outer\") # unimos la data de pageviews y devicedata a una nueva variable\ndel(pageviews) # borramos esta variable para liberar RAM en este kernel\n# Existen algunos datos donde un usuario registra evento en un dispositivo pero no en pageviews lo que genera muchas filas con datos nulos que se necesitan borrar\ndata.dropna(axis='rows', thresh=7, inplace=True) \ndata.sort_values(['USER_ID','FEC_EVENT'], inplace=True)\ndata.reset_index(drop=True, inplace=True)\n# Al organizar por fecha podemos agrupar un poco más los datos, en este caso el TyPer donde podemos quitar dos tipos que son muy pequeños y llenar valores faltantes \ndata['TyPer'].replace(r'^NCA$', np.NaN, inplace=True, regex=True)\ndata['TyPer'].replace(r'^MASIVO$', np.NaN, inplace=True, regex=True)\ndata['TyPer'].replace(r'^USERS$', np.NaN, inplace=True, regex=True)\ndata['TyPer'].fillna(method='ffill', inplace=True)\ndata['TyPer'].fillna('EMINENT', inplace = True)\ndata['CONNECTION_SPEED'].fillna(method='ffill', inplace=True)\ndata['IS_MOBILE_DEVICE'].fillna(method='ffill', inplace=True)\ndata['CONNECTION_SPEED'].fillna(1, inplace=True)\ndata['IS_MOBILE_DEVICE'].fillna(1, inplace=True)\ndata.fillna('NCA', inplace=True)\n\ndata.head()","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"data['s_total'] = data['s_total'].apply(', '.join) # pasamos de lista a string\n\n# Transformar los strings a datos categoricos\nfrom sklearn.preprocessing import LabelEncoder\nle = LabelEncoder()\ndata['Cat'] = le.fit_transform(data['Cat'])\ndata['TyCat'] = le.fit_transform(data['TyCat'])\ndata['on_err'] = le.fit_transform(data['on_err'])\ndata['TyPer'] = le.fit_transform(data['TyPer'])\ndata['Act'] = le.fit_transform(data['Act'])\ndata['A1'] = le.fit_transform(data['A1'])\ndata['A2'] = le.fit_transform(data['A2'])\ndata['s_total'] = le.fit_transform(data['s_total'])\n\ndata.head()","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"# cargar archivo conversiones\nconversiones = pd.read_csv('../input/banco-galicia-dataton-2019/conversiones.zip')\ncolumnas = list(data.drop(['FEC_EVENT','CONTENT_CATEGORY_BOTTOM','USER_ID','mes'], axis=1).columns) # Genera lista de las columnas con las que vamos a trabajar\n# Se descarta la columna CONTENT_CATEGORY_BOTTOM ya que es igual a la columna CONTENT_CATEGORY, esto se puede probar con la siguente linea\n#data['CONTENT_CATEGORY'].equals(data['CONTENT_CATEGORY_BOTTOM'])","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"meses = [[1,9,4,12]] # Define los meses para seleccionar la data de entrenamiento [mes de inicio para X, mes de fin para X, mes de inicio para Y, mes de fin para Y]\n# Se puede definir un solo periodo o varios, ej. meses = [[1,6,4,9], [4,9,7,12]]\n\n# Librerias para el entrenamiento\nfrom sklearn import model_selection\nfrom lightgbm import LGBMClassifier\nfrom sklearn.metrics import roc_auc_score\n\n# Organizamos toda la data para realizar la predicción\nalldata = []\nfor c in columnas:\n    temp = pd.crosstab(data.USER_ID, data[c])\n    temp.columns = [c + \"_\" + str(v) for v in temp.columns]\n    alldata.append(temp.apply(lambda x: x / x.sum(), axis=1))\nalldata = pd.concat(alldata, axis=1)\nallcolumns = list(alldata.columns)\n\ntest_probs = [] # Se guardan los resultados de cada predicción\n\n# Genera la data de entrenamiento\nfor i in range(len(meses)):\n    data2 = data[(data['mes'] >= meses[i][0]) & (data['mes'] <= meses[i][1])]\n    y_train = pd.Series(1, conversiones[(conversiones['mes']>=meses[i][2])&(conversiones['mes']<=meses[i][3])]['USER_ID'].sort_values().unique())\n    y_train = y_train.reindex(range(11676),fill_value=0)\n    X_train = []\n    for c in columnas:\n        temp = pd.crosstab(data.USER_ID, data2[c])\n        temp.columns = [c + \"_\" + str(v) for v in temp.columns]\n        X_train.append(temp.apply(lambda x: x / x.sum(), axis=1))\n    X_train = pd.concat(X_train, axis=1)\n    X_train = X_train.reindex(range(11676),columns=allcolumns,fill_value=0)\n    \n    j = 0\n    \n    # Se realiza split sobre la data para tener un modelo mas robusto\n    for train_idx, valid_idx in model_selection.KFold(n_splits=10, shuffle=True, random_state=seed).split(X_train):\n        j += 1\n        Xt = X_train.iloc[train_idx]\n        yt = y_train.iloc[train_idx]\n        \n        Xv = X_train.iloc[valid_idx]\n        yv = y_train.iloc[valid_idx]\n        \n        learner = LGBMClassifier(n_estimators=10000, objective='binary', random_state=seed)\n\n        learner.fit(Xt, yt,  early_stopping_rounds=20, eval_metric=\"auc\", eval_set=[(Xt, yt), (Xv, yv)], verbose=0)\n\n        test_probs.append(pd.Series(learner.predict_proba(alldata)[:, -1], index=alldata.index, name=\"fold_\" + str(j)))\n\ntest_probs = pd.concat(test_probs, axis=1).mean(axis=1) # guardamos el promedio de las predicciones.\ntest_probs.index.name=\"USER_ID\"\ntest_probs.name=\"SCORE\"\ntest_probs.to_csv(\"resultado.csv\", header=True)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"# Resultados\ntest_probs","execution_count":null,"outputs":[]}],"metadata":{"kernelspec":{"display_name":"Python 3","language":"python","name":"python3"},"language_info":{"codemirror_mode":{"name":"ipython","version":3},"file_extension":".py","mimetype":"text/x-python","name":"python","nbconvert_exporter":"python","pygments_lexer":"ipython3","version":"3.7.3"}},"nbformat":4,"nbformat_minor":1}